From d137f0f2bf05c2f310cc1dbda281abbdc04b673b Mon Sep 17 00:00:00 2001 From: Reto Buerki Date: Tue, 16 Feb 2016 17:08:14 +0100 Subject: [PATCH] hw_x86_64_muen: Extend sinfo API with device info The new Sinfo::get_dev_info function can be used to retrieve information for a PCI device with given source-id (SID). The function returns false if no device information for the specified device exists. --- .../src/core/include/spec/x86_64/muen/sinfo.h | 17 +++++++++++ .../src/core/spec/x86_64/muen/musinfo.h | 15 +++++++++- .../src/core/spec/x86_64/muen/sinfo.cc | 30 +++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/repos/base-hw/src/core/include/spec/x86_64/muen/sinfo.h b/repos/base-hw/src/core/include/spec/x86_64/muen/sinfo.h index e889ea4cf..4e9002999 100644 --- a/repos/base-hw/src/core/include/spec/x86_64/muen/sinfo.h +++ b/repos/base-hw/src/core/include/spec/x86_64/muen/sinfo.h @@ -58,6 +58,15 @@ class Genode::Sinfo bool has_vector; }; + /* Structure holding information about PCI devices */ + struct Dev_info { + uint16_t sid; + uint16_t irte_start; + uint8_t irq_start; + uint8_t ir_count; + bool msi_capable; + }; + /* * Check Muen sinfo Magic. */ @@ -81,6 +90,14 @@ class Genode::Sinfo static bool get_memregion_info(const char * const name, struct Memregion_info *memregion); + /* + * Return information for PCI device with given SID. + * + * The function returns false if no device information for the + * specified device exists. + */ + static bool get_dev_info(const uint16_t sid, struct Dev_info *dev); + /* * Channel callback. * diff --git a/repos/base-hw/src/core/spec/x86_64/muen/musinfo.h b/repos/base-hw/src/core/spec/x86_64/muen/musinfo.h index 34ce743cb..c7d215cad 100644 --- a/repos/base-hw/src/core/spec/x86_64/muen/musinfo.h +++ b/repos/base-hw/src/core/spec/x86_64/muen/musinfo.h @@ -42,18 +42,31 @@ struct resource_type { char padding[6]; } __attribute__((packed, aligned (8))); +struct dev_info_type { + uint16_t sid; + uint16_t irte_start; + uint8_t irq_start; + uint8_t ir_count; + uint8_t flags; + char padding[1]; +} __attribute__((packed, aligned (8))); + +#define DEV_MSI_FLAG (1 << 0) + struct subject_info_type { uint64_t magic; uint8_t resource_count; uint8_t memregion_count; uint8_t channel_info_count; - char padding[5]; + uint8_t dev_info_count; + char padding[4]; uint64_t tsc_khz; uint64_t tsc_schedule_start; uint64_t tsc_schedule_end; struct resource_type resources[MAX_RESOURCE_COUNT]; struct memregion_type memregions[MAX_RESOURCE_COUNT]; struct channel_info_type channels_info[MAX_RESOURCE_COUNT]; + struct dev_info_type dev_info[MAX_RESOURCE_COUNT]; } __attribute__((packed, aligned (8))); #endif /* MUSINFO_H_ */ diff --git a/repos/base-hw/src/core/spec/x86_64/muen/sinfo.cc b/repos/base-hw/src/core/spec/x86_64/muen/sinfo.cc index d93c264ba..27b3c3dcb 100644 --- a/repos/base-hw/src/core/spec/x86_64/muen/sinfo.cc +++ b/repos/base-hw/src/core/spec/x86_64/muen/sinfo.cc @@ -116,6 +116,19 @@ static bool is_channel(const struct resource_type * const resource) } +/* Fill dev struct with data from PCI device info given by index */ +static void fill_dev_data(uint8_t idx, struct Genode::Sinfo::Dev_info *dev) +{ + const struct dev_info_type dev_info = sinfo->dev_info[idx]; + + dev->sid = dev_info.sid; + dev->irte_start = dev_info.irte_start; + dev->irq_start = dev_info.irq_start; + dev->ir_count = dev_info.ir_count; + dev->msi_capable = dev_info.flags & DEV_MSI_FLAG; +} + + Sinfo::Sinfo() { if (!check_magic()) { @@ -176,6 +189,23 @@ bool Sinfo::get_memregion_info(const char * const name, } +bool Sinfo::get_dev_info(const uint16_t sid, struct Dev_info *dev) +{ + int i; + + if (!check_magic()) + return false; + + for (i = 0; i < sinfo->dev_info_count; i++) { + if (sinfo->dev_info[i].sid == sid) { + fill_dev_data(i, dev); + return true; + } + } + return false; +} + + bool Sinfo::for_each_channel(Channel_cb func, void *data) { int i;