diff --git a/repos/base/run/platform_drv.inc b/repos/base/run/platform_drv.inc
index 53b22cb643..24aaa7b6ed 100644
--- a/repos/base/run/platform_drv.inc
+++ b/repos/base/run/platform_drv.inc
@@ -7,6 +7,7 @@ proc append_platform_drv_build_components {} {
lappend_if [have_platform_drv] build_components drivers/platform
lappend_if [have_spec acpi] build_components drivers/acpi
+ lappend_if [have_spec acpi] build_components server/report_rom
lappend_if [have_spec pci] build_components drivers/pci
}
@@ -15,6 +16,7 @@ proc append_platform_drv_boot_modules {} {
lappend_if [have_platform_drv] boot_modules platform_drv
lappend_if [have_spec acpi] boot_modules acpi_drv
+ lappend_if [have_spec acpi] boot_modules report_rom
lappend_if [have_spec pci] boot_modules pci_drv
lappend_if [have_spec nova] boot_modules pci_device_pd
}
@@ -37,7 +39,6 @@ proc append_platform_drv_config {} {
if {[have_platform_drv]} {
append config {
-
@@ -50,41 +51,78 @@ proc append_platform_drv_config {} {
if {[have_spec acpi]} {
- append config "
+ append config "
"
- append config {
-
+ append config {
+
+
+
+
+
+
+
+ }
+
+ append config "
+ "
+
+ append config {
+
+
-
-
+
+
-
- }
-
- append config [platform_drv_policy]
-
- append config {
+
+
+
+
+
+
+
}
}
- if {[expr ![have_spec acpi] && [have_spec pci]]} {
+ if {[have_spec pci]} {
- append config "
+ append config "
"
- append config {
+ append config {
-
+ }
+
+ if {[have_spec acpi]} {
+ append config {
+
+
+ }
+ }
+
+ append config {
+
+ }
+
+ if {[have_spec acpi]} {
+
+ append config {
}
- append config [platform_drv_policy]
+ } else {
- append config {
+ append config {
+ }
+
+ }
+
+ append config [platform_drv_policy]
+
+ append config {
}
diff --git a/repos/dde_linux/run/usb_hid.run b/repos/dde_linux/run/usb_hid.run
index 70d45eebd1..deac8a581a 100644
--- a/repos/dde_linux/run/usb_hid.run
+++ b/repos/dde_linux/run/usb_hid.run
@@ -9,11 +9,10 @@ set build_components {
test/input
}
-lappend_if [have_spec acpi] build_components drivers/acpi
-lappend_if [have_spec pci] build_components drivers/pci
-lappend_if [have_spec pci] build_components drivers/pci/device_pd
-lappend_if [have_spec platform_arndale] build_components drivers/platform
-lappend_if [have_spec gpio] build_components drivers/gpio
+lappend_if [have_spec gpio] build_components drivers/gpio
+
+source ${genode_dir}/repos/base/run/platform_drv.inc
+append_platform_drv_build_components
build $build_components
@@ -42,12 +41,6 @@ append config {
}
-append_if [have_spec platform_arndale] config {
-
-
-
- }
-
append_if [have_spec gpio] config {
@@ -55,33 +48,7 @@ append_if [have_spec gpio] config {
}
-append_if [have_spec acpi] config {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- }
-
-append_if [expr ![have_spec acpi] && [have_spec pci]] config {
-
-
-
- }
+append_platform_drv_config
append config {
@@ -111,12 +78,10 @@ set boot_modules {
core init timer usb_drv test-input
}
-lappend_if [have_spec acpi] boot_modules acpi_drv
-lappend_if [have_spec pci] boot_modules pci_drv
-lappend_if [have_spec nova] boot_modules pci_device_pd
-lappend_if [have_spec platform_arndale] boot_modules platform_drv
lappend_if [have_spec gpio] boot_modules gpio_drv
+append_platform_drv_boot_modules
+
build_boot_image $boot_modules
append qemu_args " -m 256 -usb -usbdevice mouse -usbdevice keyboard"
diff --git a/repos/os/include/platform/irq_proxy.h b/repos/os/include/platform/irq_proxy.h
index 11d6c04c1b..ca3ed45bf5 100644
--- a/repos/os/include/platform/irq_proxy.h
+++ b/repos/os/include/platform/irq_proxy.h
@@ -49,7 +49,7 @@ class Genode::Irq_proxy : public THREAD,
char _name[32];
Lock _startup_lock;
- long _irq_number;
+ unsigned _irq_number;
Lock _mutex; /* protects this object */
int _num_sharers; /* number of clients sharing this IRQ */
@@ -86,9 +86,9 @@ class Genode::Irq_proxy : public THREAD,
** Implementation **
********************/
- const char *_construct_name(long irq_number)
+ const char *_construct_name(unsigned irq_number)
{
- snprintf(_name, sizeof(_name), "irqproxy%02lx", irq_number);
+ snprintf(_name, sizeof(_name), "irqproxy%02x", irq_number);
return _name;
}
@@ -128,7 +128,7 @@ class Genode::Irq_proxy : public THREAD,
public:
- Irq_proxy(long irq_number)
+ Irq_proxy(unsigned irq_number)
:
THREAD(_construct_name(irq_number)),
_startup_lock(Lock::LOCKED), _irq_number(irq_number),
@@ -186,7 +186,7 @@ class Genode::Irq_proxy : public THREAD,
s->notify();
}
- long irq_number() const { return _irq_number; }
+ unsigned irq_number() const { return _irq_number; }
virtual bool add_sharer(Irq_sigh *s)
{
@@ -217,7 +217,10 @@ class Genode::Irq_proxy : public THREAD,
}
template
- static PROXY *get_irq_proxy(long irq_number, Range_allocator *irq_alloc = 0)
+ static PROXY *get_irq_proxy(unsigned irq_number,
+ Range_allocator *irq_alloc = 0,
+ Genode::Irq_session::Trigger trigger = Genode::Irq_session::TRIGGER_UNCHANGED,
+ Genode::Irq_session::Polarity polarity = Genode::Irq_session::POLARITY_UNCHANGED)
{
static List proxies;
static Lock proxies_lock;
@@ -233,7 +236,8 @@ class Genode::Irq_proxy : public THREAD,
if (!irq_alloc || irq_alloc->alloc_addr(1, irq_number).is_error())
return 0;
- PROXY *new_proxy = new (env()->heap()) PROXY(irq_number);
+ PROXY *new_proxy = new (env()->heap()) PROXY(irq_number, trigger,
+ polarity);
proxies.insert(new_proxy);
return new_proxy;
}
diff --git a/repos/os/run/input.run b/repos/os/run/input.run
index 76c99c57ab..a00feeddd1 100644
--- a/repos/os/run/input.run
+++ b/repos/os/run/input.run
@@ -2,6 +2,8 @@
# Build
#
+assert_spec x86
+
set build_components {
core init
drivers/input
@@ -46,6 +48,9 @@ append config {
+
+
+
@@ -58,6 +63,8 @@ append config {
+
+
@@ -93,6 +100,7 @@ set boot_modules {
test-input
}
+# platform-specific modules
append_platform_drv_boot_modules
build_boot_image $boot_modules
diff --git a/repos/os/src/drivers/acpi/acpi.cc b/repos/os/src/drivers/acpi/acpi.cc
index ab3a1fe4c9..b938636240 100644
--- a/repos/os/src/drivers/acpi/acpi.cc
+++ b/repos/os/src/drivers/acpi/acpi.cc
@@ -1,6 +1,7 @@
/*
* \brief ACPI parsing and PCI rewriting code
* \author Sebastian Sumpf
+ * \author Alexander Boettcher
* \date 2012-02-25
*
* This code parses the DSDT and SSDT-ACPI tables and extracts the PCI-bridge
@@ -10,15 +11,17 @@
*/
/*
- * Copyright (C) 2009-2013 Genode Labs GmbH
+ * Copyright (C) 2009-2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
+/* base includes */
#include
-#include
-#include
+
+/* os includes */
+#include
#include
#include "acpi.h"
@@ -165,7 +168,7 @@ class Irq_override : public List::Element
return &_list;
}
- bool match(uint32_t irq) const { return irq == _irq; }
+ uint32_t irq() const { return _irq; }
uint32_t gsi() const { return _gsi; }
uint32_t flags() const { return _flags; }
};
@@ -373,8 +376,9 @@ class Pci_routing : public List::Element
/**
* Accessors
*/
- uint32_t pin() const { return _pin; }
- uint32_t gsi() const { return _gsi; }
+ uint32_t pin() const { return _pin; }
+ uint32_t gsi() const { return _gsi; }
+ uint32_t device() const { return _adr >> 16; }
/* debug */
void dump() { if (verbose) PDBG("Pci: adr %x pin %x gsi: %u", _adr, _pin, _gsi); }
@@ -818,7 +822,6 @@ class Element : public List::Element
}
}
- bool is_device() { return _type == SUB_DEVICE; }
bool is_device_name() { return _type == DEVICE_NAME; }
/**
@@ -852,6 +855,9 @@ class Element : public List::Element
uint32_t size_len() const { return _size_len; }
uint8_t const *data() const { return _data; }
bool valid() const { return _valid; }
+ uint32_t bdf() const { return _bdf; }
+ bool is_device() const { return _type == SUB_DEVICE; }
+
static bool supported_acpi_format()
{
@@ -996,44 +1002,6 @@ class Element : public List::Element
}
throw -1;
}
-
- static void create_config_file(char * text, size_t max)
- {
- Pci_config_space *e = Pci_config_space::list()->first();
-
- int len = snprintf(text, max, "");
- text += len;
- max -= len;
- for (; e; e = e->next())
- {
- using namespace Genode;
- len = snprintf(text, max, "%u", e->_bdf_start);
- text += len;
- max -= len;
- len = snprintf(text, max, "%u" , e->_func_count);
- text += len;
- max -= len;
- len = snprintf(text, max, "0x%lx" , e->_base);
- text += len;
- max -= len;
- }
-
- Attached_rom_dataspace rom("config");
- char * rom_text = rom.local_addr();
- size_t rom_len = strlen(rom_text);
-
- if (max > rom_len - 9) {
- rom_text += 9;
- rom_len -= 9;
- memcpy(text, rom_text, rom_len);
- text += rom_len;
- max -= rom_len;
- } else
- PERR("could not add pci_drv policy");
-
- if (max < 2)
- PERR("config file could not be generated, buffer to small");
- }
};
@@ -1215,157 +1183,6 @@ class Acpi_table
};
-/**
- * Pci::Device_client extensions identifies bridges and adds IRQ line re-write
- */
-class Pci_client : public ::Pci::Device_client
-{
- public:
-
- Pci_client(Pci::Device_capability &cap) : ::Pci::Device_client(cap) { }
-
- /**
- * Return true if this is a PCI-PCI bridge
- */
- bool is_bridge()
- {
- enum { BRIDGE_CLASS = 0x6 };
- if ((class_code() >> 16) != BRIDGE_CLASS)
- return false;
-
- /* see PCI bridge spec (3.2) */
- enum { BRIDGE = 0x1 };
- uint16_t header = config_read(0xe, ::Pci::Device::ACCESS_16BIT);
-
- /* skip multi function flag 0x80) */
- return ((header & 0x3f) != BRIDGE) ? false : true;
- }
-
- /**
- * Return bus-device function of this device
- */
- uint32_t bdf()
- {
- uint8_t bus, dev, func;
- bus_address(&bus, &dev, &func);
- return (bus << 8) | ((dev & 0x1f) << 3) | (func & 0x7);
- }
-
- /**
- * Return IRQ pin
- */
- uint32_t irq_pin()
- {
- return ((config_read(0x3c, ::Pci::Device::ACCESS_32BIT) >> 8) & 0xf);
- }
-
- /**
- * Return IRQ line
- */
- uint8_t irq_line()
- {
- return (config_read(0x3c, ::Pci::Device::ACCESS_8BIT));
- }
-
- /**
- * Write line to config space
- */
- void irq_line(uint32_t gsi)
- {
- config_write(0x3c, gsi, ::Pci::Device::ACCESS_8BIT);
- }
-};
-
-
-/**
- * List of PCI-bridge devices
- */
-class Pci_bridge : public List::Element
-{
- private:
-
- /* PCI config space fields of bridge */
- uint32_t _bdf;
- uint32_t _secondary_bus;
- uint32_t _subordinate_bus;
-
- Pci_bridge(Pci_client &client) : _bdf(client.bdf())
- {
- /* PCI bridge spec 3.2.5.3, 3.2.5.4 */
- uint32_t bus = client.config_read(0x18, ::Pci::Device::ACCESS_32BIT);
- _secondary_bus = (bus >> 8) & 0xff;
- _subordinate_bus = (bus >> 16) & 0xff;
-
- if (verbose)
- PDBG("New bridge: bdf %x se: %u su: %u", _bdf, _secondary_bus, _subordinate_bus);
- }
-
- static List *_list()
- {
- static List list;
- return &list;
- }
-
- public:
-
- /**
- * Scan PCI bus for bridges
- */
- Pci_bridge(Pci::Session_capability &session)
- {
- Pci::Session_client pci(session);
- Pci::Device_capability device_cap = pci.first_device(), prev_device_cap;
-
- /* search for bridges */
- while (device_cap.valid()) {
- prev_device_cap = device_cap;
- Pci_client device(device_cap);
-
- if (device.is_bridge())
- _list()->insert(new (env()->heap()) Pci_bridge(device));
-
- device_cap = pci.next_device(device_cap);
- pci.release_device(prev_device_cap);
- }
- }
-
- /**
- * Locate BDF of bridge belonging to given bdf
- */
- static uint32_t bridge_bdf(uint32_t bdf)
- {
- Pci_bridge *bridge = _list()->first();
- uint32_t bus = bdf >> 8;
-
- for (; bridge; bridge = bridge->next())
- if (bridge->_secondary_bus <= bus && bridge->_subordinate_bus >= bus)
- return bridge->_bdf;
-
- return 0;
- }
-
-};
-
-
-/**
- * Debugging
- */
-static void dump_bdf(uint32_t a, uint32_t b, uint32_t pin)
-{
- if (verbose)
- PDBG("Device bdf %02x:%02x.%u (%x) bridge %02x:%02x.%u (%x) Pin: %u",
- (a >> 8), (a >> 3) & 0x1f, (a & 0x7), a,
- (b >> 8), (b >> 3) & 0x1f, (b & 0x7), b, pin);
-}
-
-
-static void dump_rewrite(uint32_t bdf, uint8_t line, uint8_t gsi)
-{
- PINF("Rewriting %02x:%02x.%u IRQ: %02u -> GSI: %02u",
- (bdf >> 8), (bdf >> 3) & 0x1f, (bdf & 0x7), line, gsi);
-}
-
-
/**
* Parse acpi table
*/
@@ -1375,73 +1192,64 @@ static void init_acpi_table()
}
-/**
- * Create config file for pci_drv
- */
-void Acpi::create_pci_config_file(char * config_space,
- Genode::size_t config_space_max)
+void Acpi::generate_report()
{
init_acpi_table();
- Element::create_config_file(config_space, config_space_max);
-}
+ enum { REPORT_SIZE = 4 * 4096 };
+ static Reporter acpi("acpi", REPORT_SIZE);
+ acpi.enabled(true);
-/**
- * Rewrite GSIs of PCI config space
- */
-void Acpi::configure_pci_devices(Pci::Session_capability &session)
-{
- init_acpi_table();
- static Pci_bridge bridge(session);
+ Genode::Reporter::Xml_generator xml(acpi, [&] () {
+ for (Pci_config_space *e = Pci_config_space::list()->first(); e;
+ e = e->next())
+ {
+ xml.node("bdf", [&] () {
+ char number[20];
+ Genode::snprintf(number, sizeof(number), "%u", e->_bdf_start);
+ xml.attribute("start", number);
+ Genode::snprintf(number, sizeof(number), "%u", e->_func_count);
+ xml.attribute("count", number);
+ Genode::snprintf(number, sizeof(number), "0x%lx", e->_base);
+ xml.attribute("base", number);
+ });
+ }
- /* if no _PIC method could be found don't rewrite */
- bool acpi_rewrite = Element::supported_acpi_format();
+ for (Irq_override *i = Irq_override::list()->first(); i; i = i->next())
+ {
+ xml.node("irq_override", [&] () {
+ char number[8];
+ Genode::snprintf(number, sizeof(number), "%u", i->irq());
+ xml.attribute("irq", number);
+ Genode::snprintf(number, sizeof(number), "%u", i->gsi());
+ xml.attribute("gsi", number);
+ Genode::snprintf(number, sizeof(number), "0x%x", i->flags());
+ xml.attribute("flags", number);
+ });
+ }
- if (acpi_rewrite)
- PINF("ACPI table format is supported - rewrite GSIs");
- else
- PWRN("ACPI table format not supported - will not rewrite GSIs");
+ {
+ Element *e = Element::list()->first();
- Pci::Session_client pci(session);
- Pci::Device_capability device_cap = pci.first_device(), prev_device_cap;
+ for (; e; e = e->next()) {
+ if (!e->is_device())
+ continue;
- while (device_cap.valid()) {
- prev_device_cap = device_cap;
- Pci_client device(device_cap);
-
- /* rewrite IRQs */
- if (acpi_rewrite && !device.is_bridge()) {
- uint32_t device_bdf = device.bdf();
- uint32_t bridge_bdf = Pci_bridge::bridge_bdf(device_bdf);
- uint32_t irq_pin = device.irq_pin();
- if (irq_pin) {
- dump_bdf(device_bdf, bridge_bdf, irq_pin - 1);
- try {
- uint8_t gsi = Element::search_gsi(device_bdf, bridge_bdf, irq_pin - 1);
- dump_rewrite(device_bdf, device.irq_line(), gsi);
- device.irq_line(gsi);
- } catch (...) { }
+ Pci_routing *r = e->pci_list()->first();
+ for (; r; r = r->next()) {
+ xml.node("routing", [&] () {
+ char number[8];
+ Genode::snprintf(number, sizeof(number), "0x%x", r->gsi());
+ xml.attribute("gsi", number);
+ Genode::snprintf(number, sizeof(number), "0x%x", e->bdf());
+ xml.attribute("bridge_bdf", number);
+ Genode::snprintf(number, sizeof(number), "0x%x", r->device());
+ xml.attribute("device", number);
+ Genode::snprintf(number, sizeof(number), "0x%x", r->pin());
+ xml.attribute("device_pin", number);
+ });
+ }
}
}
-
- device_cap = pci.next_device(device_cap);
- pci.release_device(prev_device_cap);
- }
-
-}
-
-
-/**
- * Search override structures
- */
-unsigned Acpi::override(unsigned irq, unsigned *mode)
-{
- for (Irq_override *i = Irq_override::list()->first(); i; i = i->next())
- if (i->match(irq)) {
- *mode = i->flags();
- return i->gsi();
- }
-
- *mode = 0;
- return irq;
+ });
}
diff --git a/repos/os/src/drivers/acpi/acpi.h b/repos/os/src/drivers/acpi/acpi.h
index dfd0fd16d1..3f17115433 100644
--- a/repos/os/src/drivers/acpi/acpi.h
+++ b/repos/os/src/drivers/acpi/acpi.h
@@ -14,26 +14,12 @@
#ifndef _ACPI_H_
#define _ACPI_H_
-#include
-
namespace Acpi
{
/**
- * Generate config file for pci_drv containing pointers to the
- * extended PCI config space (since PCI Express)
+ * Generate report rom
*/
- void create_pci_config_file(char * config_space,
- Genode::size_t config_space_max);
-
- /**
- * Rewrite PCI-config space with GSIs found in ACPI tables.
- */
- void configure_pci_devices(Pci::Session_capability &session);
-
- /**
- * Return override GSI for IRQ
- */
- unsigned override(unsigned irq, unsigned *mode);
+ void generate_report();
}
#endif /* _ACPI_H_ */
diff --git a/repos/os/src/drivers/acpi/main.cc b/repos/os/src/drivers/acpi/main.cc
index 672d1b2943..e577ce870a 100644
--- a/repos/os/src/drivers/acpi/main.cc
+++ b/repos/os/src/drivers/acpi/main.cc
@@ -2,321 +2,36 @@
* \brief Service and session interface
* \author Sebastian Sumpf
* \date 2012-02-25
- *
- * The 'acpi_drv' provides the 'PCI' after rewriting the IRQ information of PCI
- * devices. For this it uses the 'pci_drv' as a client and forwards the session
- * capability of the 'pci_drv' afterwards
*/
/*
- * Copyright (C) 2009-2013 Genode Labs GmbH
+ * Copyright (C) 2009-2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
-#include
#include
-#include
#include
-#include
-#include
-#include
-#include
+
+#include
#include "acpi.h"
-/**
- * IRQ service
- */
-namespace Irq {
-
- typedef Genode::Rpc_object > Irq_session;
-
- /**
- * Root interface of IRQ service
- */
- class Root : public Irq_session
- {
- private:
-
- Genode::Irq_session::Trigger _mode2trigger(unsigned mode)
- {
- enum { EDGE = 0x4, LEVEL = 0xc };
-
- switch (mode & 0xc) {
- case EDGE:
- return Genode::Irq_session::TRIGGER_EDGE;
- case LEVEL:
- return Genode::Irq_session::TRIGGER_LEVEL;
- default:
- return Genode::Irq_session::TRIGGER_UNCHANGED;
- }
- }
-
- Genode::Irq_session::Polarity _mode2polarity(unsigned mode)
- {
- using namespace Genode;
- enum { HIGH = 0x1, LOW = 0x3 };
-
- switch (mode & 0x3) {
- case HIGH:
- return Genode::Irq_session::POLARITY_HIGH;
- case LOW:
- return Genode::Irq_session::POLARITY_LOW;
- default:
- return Genode::Irq_session::POLARITY_UNCHANGED;
- }
- }
-
- public:
-
- /**
- * Remap IRQ number and create IRQ session at parent
- */
- Genode::Session_capability session(Root::Session_args const &args,
- Genode::Affinity const &)
- {
- using namespace Genode;
-
- if (!args.is_valid_string()) throw Root::Invalid_args();
-
- long irq_number = Arg_string::find_arg(args.string(), "irq_number").long_value(-1);
- long msi = Arg_string::find_arg(args.string(), "device_config_phys").long_value(0);
-
- /* check for 'MADT' overrides */
- unsigned mode;
- long irq_legacy = Acpi::override(irq_number, &mode);
- /* rewrite IRQ solely if this is not a MSI request */
- if (!msi)
- irq_number = irq_legacy;
-
- /* allocate IRQ at parent*/
- try {
- Irq_connection irq(irq_number, _mode2trigger(mode),
- _mode2polarity(mode), msi);
- irq.on_destruction(Irq_connection::KEEP_OPEN);
- return irq.cap();
- } catch (...) { throw Root::Unavailable(); }
- }
-
- /**
- * Close session at parent
- */
- void close(Genode::Session_capability session) {
- Genode::env()->parent()->close(session); }
-
- void upgrade(Genode::Session_capability session, Upgrade_args const &args) { }
- };
-}
-
-
-namespace Pci {
-
- struct Provider
- {
- bool ready_to_use() { return root().valid(); }
-
- virtual Genode::Root_capability root() = 0;
- };
-
- /**
- * Root interface of PCI service
- */
- class Root : public Genode::Rpc_object >
- {
- private:
-
- Provider &_pci_provider;
- Genode::Ram_session_capability _slave_ram_cap;
-
- public:
-
- Root(Provider &pci_provider,
- Genode::Ram_session_capability ram_cap)
- : _pci_provider(pci_provider), _slave_ram_cap(ram_cap) { }
-
- Genode::Session_capability session(Session_args const &args,
- Genode::Affinity const &affinity)
- {
- if (!args.is_valid_string()) throw Invalid_args();
-
- if (!_pci_provider.ready_to_use())
- throw Unavailable();
-
- try {
- return Genode::Root_client(_pci_provider.root())
- .session(args.string(), affinity);
- } catch (...) {
- throw Unavailable();
- }
- }
-
- void close(Genode::Session_capability session) {
- Genode::Root_client(_pci_provider.root()).close(session); }
-
- void upgrade(Genode::Session_capability s,
- Upgrade_args const & args)
- {
- if (!s.valid() || !args.is_valid_string() ||
- !_slave_ram_cap.valid())
- throw Invalid_args();
-
- using namespace Genode;
-
- size_t ram_quota = Arg_string::find_arg(args.string(), "ram_quota").ulong_value(0);
- Ram_session_client acpi_ram(env()->ram_session_cap());
- if (acpi_ram.transfer_quota(_slave_ram_cap, ram_quota))
- throw Invalid_args();
-
- try { Root_client(_pci_provider.root()).upgrade(s, args); }
- catch (...) {
- PDBG("notification about upgrade failed");
- throw Invalid_args();
- }
- }
- };
-}
-
-
-static Irq::Root irq_root;
-static Genode::Local_service local_irq("IRQ", &irq_root);
-
-
-class Pci_policy : public Genode::Slave_policy, public Pci::Provider
-{
- private:
-
- Genode::Root_capability _cap;
- Genode::Rpc_entrypoint &_pci_ep;
- Genode::Rpc_entrypoint &_irq_ep;
- Genode::Lock _lock;
-
- protected:
-
- Genode::Service *resolve_session_request(const char *service_name,
- const char *args) override
- {
- if (!Genode::strcmp(service_name, "IRQ"))
- return &local_irq;
-
- return Genode::Slave_policy::resolve_session_request(service_name,
- args);
- }
-
- char const **_permitted_services() const
- {
- static char const *permitted_services[] = { "CPU", "CAP", "RM",
- "LOG", "IO_PORT", "PD",
- "ROM", "RAM", "SIGNAL",
- "IO_MEM", 0 };
- return permitted_services;
- }
-
- /**
- * Parse ACPI tables and announce slave PCI service
- */
- void _acpi_session(Genode::Ram_session_capability ram_cap)
- {
- Pci::Session_capability session;
- const char *args = "label=\"acpi_drv\", ram_quota=16K";
-
- try {
- using namespace Genode;
- session = static_cap_cast(Root_client(_cap)
- .session(args, Genode::Affinity()));
- } catch (...) { return; }
-
- Acpi::configure_pci_devices(session);
-
- /* announce PCI/IRQ services to parent */
- static Pci::Root pci_root(*this, ram_cap);
-
- Genode::env()->parent()->announce(_pci_ep.manage(&pci_root));
- Genode::env()->parent()->announce(_irq_ep.manage(&irq_root));
-
- Genode::Root_client(_cap).close(session);
- }
-
- public:
-
- Pci_policy(Genode::Rpc_entrypoint &slave_ep,
- Genode::Rpc_entrypoint &pci_ep,
- Genode::Rpc_entrypoint &irq_ep)
- :
- Slave_policy("pci_drv", slave_ep, Genode::env()->ram_session()),
- _pci_ep(pci_ep), _irq_ep(irq_ep), _lock(Genode::Lock::LOCKED)
- { }
-
- bool announce_service(const char *service_name,
- Genode::Root_capability root,
- Genode::Allocator *alloc,
- Genode::Server *server)
- {
- /* wait for 'pci_drv' to announce the PCI service */
- if (Genode::strcmp(service_name, "PCI"))
- return false;
-
- _cap = root;
-
- /* unblock main thread blocked in wait_for_pci_drv */
- _lock.unlock();
-
- return true;
- }
-
- void wait_for_pci_drv(Genode::Ram_session_capability slave_ram_cap)
- {
- /* wait until pci drv is ready */
- _lock.lock();
-
- /* connect session and start ACPI parsing */
- _acpi_session(slave_ram_cap);
- }
-
- Genode::Root_capability root() { return _cap; }
-};
-
-
int main(int argc, char **argv)
{
using namespace Genode;
- enum { STACK_SIZE = 2*4096, ACPI_MEMORY_SIZE = 2 * 1024 * 1024 };
-
- /* reserve portion for acpi and give rest to pci_drv */
- Genode::addr_t avail_size = Genode::env()->ram_session()->avail();
- if (avail_size < ACPI_MEMORY_SIZE) {
- PERR("not enough memory");
- return 1;
+ try {
+ Acpi::generate_report();
+ } catch (Genode::Xml_generator::Buffer_exceeded) {
+ PERR("ACPI report too large - failure");
+ throw;
+ } catch (...) {
+ PERR("Unknown exception occured - failure");
+ throw;
}
- avail_size -= ACPI_MEMORY_SIZE;
- PINF("available memory for ACPI %d kiB, for PCI_DRV %lu kiB",
- ACPI_MEMORY_SIZE / 1024, avail_size / 1024);
-
- static Cap_connection cap;
- static Rpc_entrypoint ep(&cap, STACK_SIZE, "acpi_ep");
-
- /* IRQ service */
- static Cap_connection irq_cap;
- static Rpc_entrypoint irq_ep(&irq_cap, STACK_SIZE, "acpi_irq_ep");
-
- /* use 'pci_drv' as slave service */
- static Rpc_entrypoint pci_ep(&cap, STACK_SIZE, "pci_slave");
- static Pci_policy pci_policy(pci_ep, ep, irq_ep);
-
- /* generate config file for pci_drv */
- char buf[1024];
- Acpi::create_pci_config_file(buf, sizeof(buf));
- pci_policy.configure(buf);
-
- /* use 'pci_drv' as slave service */
- static Genode::Slave pci_slave(pci_ep, pci_policy, avail_size);
-
- /* wait until pci drv is online and then make the acpi work */
- pci_policy.wait_for_pci_drv(pci_slave.ram().cap());
Genode::sleep_forever();
return 0;
}
-
diff --git a/repos/os/src/drivers/pci/irq.cc b/repos/os/src/drivers/pci/irq.cc
index 23df9b4878..2bcdceef28 100644
--- a/repos/os/src/drivers/pci/irq.cc
+++ b/repos/os/src/drivers/pci/irq.cc
@@ -20,6 +20,7 @@
/* PCI driver include */
#include "irq.h"
+#include "pci_session_component.h"
namespace Pci {
@@ -194,10 +195,13 @@ class Pci::Irq_component : public Proxy
public:
- Irq_component(unsigned gsi)
+ Irq_component(unsigned gsi, Genode::Irq_session::Trigger trigger,
+ Genode::Irq_session::Polarity polarity)
:
- Proxy(gsi), _irq(gsi), _irq_dispatcher(irq_thread.sig_rec(), *this,
- &::Proxy::notify_about_irq),
+ Proxy(gsi),
+ _irq(gsi, trigger, polarity),
+ _irq_dispatcher(irq_thread.sig_rec(), *this,
+ &::Proxy::notify_about_irq),
_associated(false)
{ }
};
@@ -234,7 +238,7 @@ Pci::Irq_session_component::Irq_session_component(unsigned irq,
_gsi(irq)
{
/* invalid irq number for pci_devices */
- if (irq >= INVALID_IRQ)
+ if (_gsi >= INVALID_IRQ)
return;
if (pci_config_space != ~0UL) {
@@ -262,9 +266,20 @@ Pci::Irq_session_component::Irq_session_component(unsigned irq,
}
}
+ Genode::Irq_session::Trigger trigger;
+ Genode::Irq_session::Polarity polarity;
+
+ _gsi = Pci::Irq_override::irq_override(_gsi, trigger, polarity);
+ if (_gsi != irq || trigger != Genode::Irq_session::TRIGGER_UNCHANGED ||
+ polarity != Genode::Irq_session::POLARITY_UNCHANGED)
+ PINF("IRQ override %u->%u trigger mode=%s polarity=%s", irq, _gsi,
+ trigger == Genode::Irq_session::TRIGGER_LEVEL ? "LEVEL" : trigger == Genode::Irq_session::TRIGGER_EDGE ? "EDGE" : "UNCHANGED",
+ polarity == Genode::Irq_session::POLARITY_HIGH ? "HIGH" : polarity == Genode::Irq_session::POLARITY_LOW ? "LOW" : "UNCHANGED");
+
try {
/* check if shared IRQ object was used before */
- if (Proxy::get_irq_proxy(_gsi, &irq_alloc))
+ if (Proxy::get_irq_proxy(_gsi, &irq_alloc, trigger,
+ polarity))
return;
} catch (Genode::Parent::Service_denied) { }
@@ -319,3 +334,15 @@ void Pci::Irq_session_component::sigh(Genode::Signal_context_capability sigh)
if (!old.valid() && sigh.valid())
irq_obj->add_sharer(&_irq_sigh);
}
+
+
+unsigned short Pci::Irq_routing::rewrite(unsigned char bus, unsigned char dev,
+ unsigned char func, unsigned char pin)
+{
+ for (Irq_routing *i = list()->first(); i; i = i->next())
+ if ((dev == i->_device) && (pin - 1 == i->_device_pin) &&
+ (i->_bridge_bdf == Pci::bridge_bdf(bus)))
+ return i->_gsi;
+
+ return 0;
+}
diff --git a/repos/os/src/drivers/pci/irq.h b/repos/os/src/drivers/pci/irq.h
index 5984c60f4d..d73cfb5d96 100644
--- a/repos/os/src/drivers/pci/irq.h
+++ b/repos/os/src/drivers/pci/irq.h
@@ -24,7 +24,11 @@
#include
-namespace Pci { class Irq_session_component; }
+namespace Pci {
+ class Irq_session_component;
+ class Irq_override;
+ class Irq_routing;
+}
class Pci::Irq_session_component : public Genode::Rpc_object,
@@ -64,3 +68,113 @@ class Pci::Irq_session_component : public Genode::Rpc_object::Element
+{
+ private:
+
+ unsigned short _irq; /* source IRQ */
+ unsigned short _gsi; /* target GSI */
+ Genode::Irq_session::Trigger _trigger; /* interrupt trigger mode */
+ Genode::Irq_session::Polarity _polarity; /* interrupt polarity */
+
+ Genode::Irq_session::Trigger _mode2trigger(unsigned mode)
+ {
+ enum { EDGE = 0x4, LEVEL = 0xc };
+
+ switch (mode & 0xc) {
+ case EDGE:
+ return Genode::Irq_session::TRIGGER_EDGE;
+ case LEVEL:
+ return Genode::Irq_session::TRIGGER_LEVEL;
+ default:
+ return Genode::Irq_session::TRIGGER_UNCHANGED;
+ }
+ }
+
+ Genode::Irq_session::Polarity _mode2polarity(unsigned mode)
+ {
+ using namespace Genode;
+ enum { HIGH = 0x1, LOW = 0x3 };
+
+ switch (mode & 0x3) {
+ case HIGH:
+ return Genode::Irq_session::POLARITY_HIGH;
+ case LOW:
+ return Genode::Irq_session::POLARITY_LOW;
+ default:
+ return Genode::Irq_session::POLARITY_UNCHANGED;
+ }
+ }
+
+ public:
+
+ Irq_override(unsigned irq, unsigned gsi, unsigned mode)
+ :
+ _irq(irq), _gsi(gsi),
+ _trigger(_mode2trigger(mode)), _polarity(_mode2polarity(mode))
+ { }
+
+ static Genode::List *list()
+ {
+ static Genode::List _list;
+ return &_list;
+ }
+
+ unsigned short irq() const { return _irq; }
+ unsigned short gsi() const { return _gsi; }
+ Genode::Irq_session::Trigger trigger() const { return _trigger; }
+ Genode::Irq_session::Polarity polarity() const { return _polarity; }
+
+ static unsigned irq_override (unsigned irq,
+ Genode::Irq_session::Trigger &trigger,
+ Genode::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 = Genode::Irq_session::TRIGGER_UNCHANGED;
+ polarity = Genode::Irq_session::POLARITY_UNCHANGED;
+ return irq;
+ }
+};
+
+
+/**
+ * List that holds interrupt rewrite information
+ */
+class Pci::Irq_routing : public Genode::List::Element
+{
+ private:
+
+ unsigned short _gsi;
+ unsigned short _bridge_bdf;
+ unsigned short _device;
+ unsigned char _device_pin;
+
+ public:
+
+ static Genode::List *list()
+ {
+ static Genode::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(unsigned char bus, unsigned char dev,
+ unsigned char func, unsigned char pin);
+};
diff --git a/repos/os/src/drivers/pci/main.cc b/repos/os/src/drivers/pci/main.cc
index 5db22e2817..7074c2de11 100644
--- a/repos/os/src/drivers/pci/main.cc
+++ b/repos/os/src/drivers/pci/main.cc
@@ -17,6 +17,7 @@
#include
#include
+#include
#include "pci_session_component.h"
#include "pci_device_config.h"
@@ -106,14 +107,44 @@ int main(int argc, char **argv)
*/
static Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session());
+
+ /**
+ * If we are running with ACPI support, wait for the first report_rom
+ */
+ bool wait_for_acpi = true;
+ char * report_addr = nullptr;
+
+ try {
+ char yesno[4];
+ Genode::config()->xml_node().attribute("acpi").value(yesno, sizeof(yesno));
+ wait_for_acpi = strcmp(yesno, "no");
+ } catch (...) { }
+
+ if (wait_for_acpi) {
+ static Attached_rom_dataspace acpi_rom("acpi");
+
+ Signal_receiver sig_rec;
+ Signal_context sig_ctx;
+ Signal_context_capability sig_cap = sig_rec.manage(&sig_ctx);
+
+ acpi_rom.sigh(sig_cap);
+
+ while (!acpi_rom.is_valid()) {
+ sig_rec.wait_for_signal();
+ acpi_rom.update();
+ }
+ report_addr = acpi_rom.local_addr();
+ sig_rec.dissolve(&sig_ctx);
+ }
+
/*
* Let the entry point serve the PCI root interface
*/
static Pci::Root root(&ep, &sliced_heap, PCI_DEVICE_PD_RAM_QUOTA,
- device_pd_root);
+ device_pd_root, report_addr);
env()->parent()->announce(ep.manage(&root));
- sleep_forever();
+ Genode::sleep_forever();
return 0;
}
diff --git a/repos/os/src/drivers/pci/pci_bridge.h b/repos/os/src/drivers/pci/pci_bridge.h
new file mode 100644
index 0000000000..a955d87c3b
--- /dev/null
+++ b/repos/os/src/drivers/pci/pci_bridge.h
@@ -0,0 +1,56 @@
+/*
+ * \brief PCI bridge discovery
+ * \author Sebastian Sumpf
+ * \date 2012-02-25
+ */
+
+ /*
+ * Copyright (C) 2009-2015 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+
+#pragma once
+
+namespace Pci { class Bridge; }
+
+#include
+
+
+/**
+ * List of PCI-bridge devices
+ */
+class Pci::Bridge : public Genode::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;
+ }
+};
diff --git a/repos/os/src/drivers/pci/pci_device.cc b/repos/os/src/drivers/pci/pci_device.cc
index 73ab7844f7..c2e04a6ad5 100644
--- a/repos/os/src/drivers/pci/pci_device.cc
+++ b/repos/os/src/drivers/pci/pci_device.cc
@@ -83,11 +83,6 @@ void Pci::Device_component::config_write(unsigned char address, unsigned value,
case 0xd: /* Latency timer */
if (size == Access_size::ACCESS_8BIT)
break;
- case PCI_IRQ_LINE:
- /* permitted up to now solely for acpi driver */
- if (address == PCI_IRQ_LINE && _rewrite_irq_line &&
- size == Access_size::ACCESS_8BIT)
- break;
default:
PWRN("%x:%x:%x write access to address=%x value=0x%x "
" size=0x%x got dropped", _device_config.bus_number(),
diff --git a/repos/os/src/drivers/pci/pci_device_component.h b/repos/os/src/drivers/pci/pci_device_component.h
index 221c38214e..cc0438f574 100644
--- a/repos/os/src/drivers/pci/pci_device_component.h
+++ b/repos/os/src/drivers/pci/pci_device_component.h
@@ -42,7 +42,6 @@ class Pci::Device_component : public Genode::Rpc_object,
Pci::Session_component *_session;
unsigned short _irq_line;
Irq_session_component _irq_session;
- bool _rewrite_irq_line;
enum {
IO_BLOCK_SIZE = sizeof(Genode::Io_port_connection) *
@@ -107,16 +106,34 @@ class Pci::Device_component : public Genode::Rpc_object,
/**
* Disable MSI if already enabled.
*/
- unsigned _disable_msi(unsigned irq)
+ unsigned _configure_irq(unsigned irq)
{
using Genode::uint16_t;
using Genode::uint8_t;
- uint8_t has_irq = _device_config.read(&_config_access, PCI_IRQ_PIN,
- Pci::Device::ACCESS_8BIT);
- if (!has_irq)
+ uint8_t pin = _device_config.read(&_config_access, PCI_IRQ_PIN,
+ Pci::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.bus_number(),
+ _device_config.device_number(),
+ _device_config.function_number(),
+ pin);
+ if (irq_r) {
+ PINF("%x:%x.%x rewriting IRQ: %u -> %u",
+ _device_config.bus_number(),
+ _device_config.device_number(),
+ _device_config.function_number(), irq, irq_r);
+
+ if (_irq_line != irq_r)
+ _device_config.write(&_config_access, PCI_IRQ_LINE, irq_r,
+ Pci::Device::ACCESS_8BIT);
+
+ _irq_line = irq = irq_r;
+ }
+
uint16_t cap = _msi_cap();
if (!cap)
return irq;
@@ -163,14 +180,13 @@ class Pci::Device_component : public Genode::Rpc_object,
Device_component(Device_config device_config, Genode::addr_t addr,
Genode::Rpc_entrypoint *ep,
Pci::Session_component * session,
- bool rewrite_irq_line, bool use_msi)
+ bool use_msi)
:
_device_config(device_config), _config_space(addr),
_ep(ep), _session(session),
_irq_line(_device_config.read(&_config_access, PCI_IRQ_LINE,
Pci::Device::ACCESS_8BIT)),
- _irq_session(_disable_msi(_irq_line), (!use_msi || !_msi_cap()) ? ~0UL : _config_space),
- _rewrite_irq_line(rewrite_irq_line),
+ _irq_session(_configure_irq(_irq_line), (!use_msi || !_msi_cap()) ? ~0UL : _config_space),
_slab_ioport(0, &_slab_ioport_block),
_slab_iomem(0, &_slab_iomem_block)
{
@@ -350,10 +366,12 @@ class Pci::Device_component : public Genode::Rpc_object,
msi_64 ? "64bit" : "32bit",
_irq_session.msi_data(), _irq_session.msi_address());
else
- PINF("%x:%x.%x uses IRQ, vector 0x%x",
+ PINF("%x:%x.%x uses IRQ, vector 0x%x%s",
_device_config.bus_number(),
_device_config.device_number(),
- _device_config.function_number(), _irq_line);
+ _device_config.function_number(), _irq_line,
+ msi_cap ? (msi_64 ? ", MSI 64bit capable" :
+ ", MSI 32bit capable") : "");
return _irq_session.cap();
}
diff --git a/repos/os/src/drivers/pci/pci_session_component.h b/repos/os/src/drivers/pci/pci_session_component.h
index 22af4ecc13..7e3d1183de 100644
--- a/repos/os/src/drivers/pci/pci_session_component.h
+++ b/repos/os/src/drivers/pci/pci_session_component.h
@@ -25,7 +25,6 @@
/* os */
#include
-#include
#include
#include
@@ -36,6 +35,7 @@
namespace Pci {
bool bus_valid(int bus = 0);
+ unsigned short bridge_bdf(unsigned char bus);
}
namespace Pci {
@@ -59,6 +59,7 @@ namespace Pci {
static Genode::Bit_array bdf_in_use;
+
/**
* Scan PCI buses for a device
*
@@ -530,8 +531,7 @@ namespace Pci {
* device and return its capability.
*/
try {
- Device_component * dev = new (_device_slab) Device_component(config, config_space, _ep, this,
- !Genode::strcmp(_label.string(), "acpi_drv"), msi_usage());
+ Device_component * dev = new (_device_slab) Device_component(config, config_space, _ep, this, msi_usage());
/* if more than one driver uses the device - warn about */
if (bdf_in_use.get(Device_config::MAX_BUSES * bus +
@@ -658,35 +658,62 @@ namespace Pci {
/* Ram_session for allocation of dma capable dataspaces */
Genode::Ram_connection _ram;
- void _parse_config()
+ void _parse_report_rom(const char * acpi_rom)
{
using namespace Genode;
- /* check for config file first */
- try { config(); } catch (...) { return; }
-
try {
+ Xml_node xml_acpi(acpi_rom);
+ if (!xml_acpi.has_type("acpi"))
+ throw 1;
+
unsigned i;
- for (i = 0; i < config()->xml_node().num_sub_nodes(); i++)
+ for (i = 0; i < xml_acpi.num_sub_nodes(); i++)
{
- Xml_node node = config()->xml_node().sub_node(i);
+ Xml_node node = xml_acpi.sub_node(i);
- if (!node.has_type("bdf"))
- continue;
+ if (node.has_type("bdf")) {
- uint32_t bdf_start = 0;
- uint32_t func_count = 0;
- addr_t base = 0;
- node.sub_node("start").value(&bdf_start);
- node.sub_node("count").value(&func_count);
- node.sub_node("base").value(&base);
+ uint32_t bdf_start = 0;
+ uint32_t func_count = 0;
+ addr_t base = 0;
- PINF("%2u BDF start %x, functions: 0x%x, physical base "
- "0x%lx", i, bdf_start, func_count, base);
+ node.attribute("start").value(&bdf_start);
+ node.attribute("count").value(&func_count);
+ node.attribute("base").value(&base);
- Session_component::add_config_space(bdf_start,
- func_count, base);
+ Session_component::add_config_space(bdf_start,
+ func_count,
+ base);
+ }
+
+ if (node.has_type("irq_override")) {
+ unsigned irq = 0xff;
+ unsigned gsi = 0xff;
+ unsigned flags = 0xff;
+
+ node.attribute("irq").value(&irq);
+ node.attribute("gsi").value(&gsi);
+ node.attribute("flags").value(&flags);
+
+ using Pci::Irq_override;
+ Irq_override::list()->insert(new (env()->heap()) Irq_override(irq, gsi, flags));
+ }
+
+ if (node.has_type("routing")) {
+ unsigned gsi;
+ unsigned bridge_bdf;
+ unsigned device;
+ unsigned device_pin;
+
+ node.attribute("gsi").value(&gsi);
+ node.attribute("bridge_bdf").value(&bridge_bdf);
+ node.attribute("device").value(&device);
+ node.attribute("device_pin").value(&device_pin);
+
+ Irq_routing::list()->insert(new (env()->heap()) Irq_routing(gsi, bridge_bdf, device, device_pin));
+ }
}
} catch (...) {
PERR("PCI config space data could not be parsed.");
@@ -728,7 +755,8 @@ namespace Pci {
*/
Root(Genode::Rpc_entrypoint *ep, Genode::Allocator *md_alloc,
Genode::size_t pci_device_pd_ram_quota,
- Genode::Root_capability &device_pd_root)
+ Genode::Root_capability &device_pd_root,
+ const char *acpi_rom)
:
Genode::Root_component(ep, md_alloc),
_device_pd_root(device_pd_root),
@@ -736,14 +764,15 @@ namespace Pci {
_ram("dma", 0, (device_pd_root.valid() && sizeof(void *) == 4) ?
0xc0000000UL : 0x100000000ULL)
{
- _parse_config();
+ /* enforce initial bus scan */
+ bus_valid();
+
+ if (acpi_rom)
+ _parse_report_rom(acpi_rom);
/* associate _ram session with ram_session of process */
_ram.ref_account(Genode::env()->ram_session_cap());
Genode::env()->ram_session()->transfer_quota(_ram.cap(), 0x1000);
-
- /* enforce initial bus scan */
- bus_valid();
}
};
diff --git a/repos/os/src/drivers/pci/session.cc b/repos/os/src/drivers/pci/session.cc
index 3cb9d72fbb..ca81345a78 100644
--- a/repos/os/src/drivers/pci/session.cc
+++ b/repos/os/src/drivers/pci/session.cc
@@ -12,6 +12,27 @@
*/
#include "pci_session_component.h"
+#include "pci_bridge.h"
+
+
+static Genode::List *bridges()
+{
+ static Genode::List list;
+ return &list;
+}
+
+
+unsigned short Pci::bridge_bdf(unsigned char bus)
+{
+ for (Pci::Bridge *bridge = bridges()->first(); bridge;
+ bridge = bridge->next())
+ {
+ if (bridge->part_of(bus))
+ return bridge->bdf();
+ }
+ return 0;
+}
+
/**
* Check if given PCI bus was found on initial scan
@@ -24,7 +45,7 @@ bool Pci::bus_valid(int bus)
{
bool valid[Device_config::MAX_BUSES];
- void scan_bus(Config_access &config_access, int bus = 0)
+ void scan_bus(Config_access &config_access, unsigned char bus = 0)
{
for (int dev = 0; dev < Device_config::MAX_DEVICES; ++dev) {
for (int fun = 0; fun < Device_config::MAX_FUNCTIONS; ++fun) {
@@ -43,9 +64,15 @@ bool Pci::bus_valid(int bus)
/* scan behind bridge */
if (config.is_pci_bridge()) {
- int sub_bus = config.read(&config_access,
+ /* PCI bridge spec 3.2.5.3, 3.2.5.4 */
+ unsigned char sec_bus = config.read(&config_access,
0x19, Device::ACCESS_8BIT);
- scan_bus(config_access, sub_bus);
+ unsigned char sub_bus = config.read(&config_access,
+ 0x20, Device::ACCESS_8BIT);
+
+ bridges()->insert(new (Genode::env()->heap()) Bridge(bus, dev, fun, sec_bus, sub_bus));
+
+ scan_bus(config_access, sec_bus);
}
}
}
diff --git a/repos/ports/run/netperf.inc b/repos/ports/run/netperf.inc
index be1766b0c2..31a0772657 100644
--- a/repos/ports/run/netperf.inc
+++ b/repos/ports/run/netperf.inc
@@ -214,6 +214,7 @@ append_if $use_wifi_driver config {
+
}
diff --git a/repos/ports/run/noux_net_netcat.run b/repos/ports/run/noux_net_netcat.run
index c557b8d3ce..6eae3d4fc7 100644
--- a/repos/ports/run/noux_net_netcat.run
+++ b/repos/ports/run/noux_net_netcat.run
@@ -57,7 +57,7 @@ append config {
-
+
@@ -67,7 +67,10 @@ append config {
append_if [have_include "power_on/qemu"] config {
-
+
+
+
+
diff --git a/repos/ports/run/noux_tool_chain.inc b/repos/ports/run/noux_tool_chain.inc
index c960f29123..d7c06a4a05 100644
--- a/repos/ports/run/noux_tool_chain.inc
+++ b/repos/ports/run/noux_tool_chain.inc
@@ -107,7 +107,7 @@ append config {
-
+
diff --git a/repos/ports/run/vbox_auto_win7_share.run b/repos/ports/run/vbox_auto_win7_share.run
index 1db4adbf0e..867ef7f57a 100644
--- a/repos/ports/run/vbox_auto_win7_share.run
+++ b/repos/ports/run/vbox_auto_win7_share.run
@@ -214,7 +214,8 @@ append config_of_app {
- }
+
+ }
append_if [expr $use_ram_fs] config_of_app {
diff --git a/repos/ports/run/vbox_win.inc b/repos/ports/run/vbox_win.inc
index 9fe7b61227..a70cc2a51a 100644
--- a/repos/ports/run/vbox_win.inc
+++ b/repos/ports/run/vbox_win.inc
@@ -86,6 +86,7 @@ append config_of_app {
+
@@ -156,6 +157,7 @@ append config_of_app {
+
diff --git a/repos/ports/run/virtualbox_auto.inc b/repos/ports/run/virtualbox_auto.inc
index 71e8b8a6cf..19438979b6 100644
--- a/repos/ports/run/virtualbox_auto.inc
+++ b/repos/ports/run/virtualbox_auto.inc
@@ -124,6 +124,7 @@ append_if [expr $use_usb] config {
+