{"action":"created","issue":{"url":"https://api.github.com/repos/Bareflank/hypervisor/issues/690","repository_url":"https://api.github.com/repos/Bareflank/hypervisor","labels_url":"https://api.github.com/repos/Bareflank/hypervisor/issues/690/labels{/name}","comments_url":"https://api.github.com/repos/Bareflank/hypervisor/issues/690/comments","events_url":"https://api.github.com/repos/Bareflank/hypervisor/issues/690/events","html_url":"https://github.com/Bareflank/hypervisor/issues/690","id":334256827,"node_id":"MDU6SXNzdWUzMzQyNTY4Mjc=","number":690,"title":"[RFC]: VT-d IOMMU Intrinsics","user":{"login":"JaredWright","id":13487832,"node_id":"MDQ6VXNlcjEzNDg3ODMy","avatar_url":"https://avatars0.githubusercontent.com/u/13487832?v=4","gravatar_id":"","url":"https://api.github.com/users/JaredWright","html_url":"https://github.com/JaredWright","followers_url":"https://api.github.com/users/JaredWright/followers","following_url":"https://api.github.com/users/JaredWright/following{/other_user}","gists_url":"https://api.github.com/users/JaredWright/gists{/gist_id}","starred_url":"https://api.github.com/users/JaredWright/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JaredWright/subscriptions","organizations_url":"https://api.github.com/users/JaredWright/orgs","repos_url":"https://api.github.com/users/JaredWright/repos","events_url":"https://api.github.com/users/JaredWright/events{/privacy}","received_events_url":"https://api.github.com/users/JaredWright/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":{"login":"JaredWright","id":13487832,"node_id":"MDQ6VXNlcjEzNDg3ODMy","avatar_url":"https://avatars0.githubusercontent.com/u/13487832?v=4","gravatar_id":"","url":"https://api.github.com/users/JaredWright","html_url":"https://github.com/JaredWright","followers_url":"https://api.github.com/users/JaredWright/followers","following_url":"https://api.github.com/users/JaredWright/following{/other_user}","gists_url":"https://api.github.com/users/JaredWright/gists{/gist_id}","starred_url":"https://api.github.com/users/JaredWright/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JaredWright/subscriptions","organizations_url":"https://api.github.com/users/JaredWright/orgs","repos_url":"https://api.github.com/users/JaredWright/repos","events_url":"https://api.github.com/users/JaredWright/events{/privacy}","received_events_url":"https://api.github.com/users/JaredWright/received_events","type":"User","site_admin":false},"assignees":[{"login":"JaredWright","id":13487832,"node_id":"MDQ6VXNlcjEzNDg3ODMy","avatar_url":"https://avatars0.githubusercontent.com/u/13487832?v=4","gravatar_id":"","url":"https://api.github.com/users/JaredWright","html_url":"https://github.com/JaredWright","followers_url":"https://api.github.com/users/JaredWright/followers","following_url":"https://api.github.com/users/JaredWright/following{/other_user}","gists_url":"https://api.github.com/users/JaredWright/gists{/gist_id}","starred_url":"https://api.github.com/users/JaredWright/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JaredWright/subscriptions","organizations_url":"https://api.github.com/users/JaredWright/orgs","repos_url":"https://api.github.com/users/JaredWright/repos","events_url":"https://api.github.com/users/JaredWright/events{/privacy}","received_events_url":"https://api.github.com/users/JaredWright/received_events","type":"User","site_admin":false}],"milestone":null,"comments":4,"created_at":"2018-06-20T21:30:14Z","updated_at":"2018-06-22T16:28:07Z","closed_at":"2018-06-22T16:28:07Z","author_association":"CONTRIBUTOR","body":"## Overview\r\n\r\nThis RFC proposes additional intrinsics to add support for Intel® VT-d to Bareflank.\r\n\r\n## Background\r\n\r\nRFC #679 added intrinsics to manipulate the numerous translation table structures listed in Chapter 9 of the [Intel® Virtualization Technology for Directed I/O Architecture Specification](https://software.intel.com/sites/default/files/managed/c5/15/vt-directed-io-spec.pdf). This RFC proposes adding more intrinsics to manipulate the register's of a hardware remapping unit (IOMMU) on the intel platform, listed in Chapter 10 of the [same spec](https://software.intel.com/sites/default/files/managed/c5/15/vt-directed-io-spec.pdf).\r\n\r\n## Proposed Changes\r\n\r\nOn the Intel platform, an IOMMU is accessed via memory-mapped IO at a location defined by the platform's ACPI tables (specifically, DRHD). Since this base address will vary across systems, a small class will be created to wrap the IOMMU's base address, and provide read/write primitives for accessing each register by its offset (defined in the spec):\r\n\r\n* bfintrinsics/include/arch/intel_x64/vtd/phys_iommu.h\r\n\r\n```\r\nclass phys_iommu\r\n{\r\n\r\npublic:\r\n\r\n    phys_iommu(uintptr_t base) : m_base(base) { }\r\n\r\n    ~phys_iommu() = default;\r\n\r\n    inline uint32_t read_32(uint32_t offset)\r\n    { return *reinterpret_cast<uint32_t *>(m_base + offset); }\r\n\r\n    inline uint64_t read_64(uint64_t offset)\r\n    { return *reinterpret_cast<uint64_t *>(m_base + offset); }\r\n\r\n    inline void write_32(uint32_t offset, uint32_t val)\r\n    { *reinterpret_cast<uint32_t *>(m_base + offset) = val; }\r\n\r\n    inline void write_32_preserved(uint32_t offset, uint32_t val, uint32_t mask)\r\n    { write_32(offset, (read_32(offset) & mask) | (val & ~mask )); }\r\n\r\n    inline void write_64(uint64_t offset, uint64_t val)\r\n    { *reinterpret_cast<uint64_t *>(m_base + offset) = val; }\r\n\r\n    inline void write_64_preserved(uint64_t offset, uint64_t val, uint64_t mask)\r\n    { write_64(offset, (read_64(offset) & mask) | (val & ~mask )); }\r\n\r\nprivate:\r\n\r\n    uintptr_t m_base;\r\n\r\n};\r\n```\r\n\r\nIn addition, intrinsics will be added to a new file bfintrinsics/include/arch/intel_x64/vtd/iommu.h. Only the *appropriate* accessors will be included for each register and field defined in the spec according to the register/field's defined permissions (read-only, read-write, write-only, etc). The C++ namespaces that will represent each register and field will be *exactly* as they appear in the manual (i.e. the initialism for the register), while the \"name\" constants in each namespace will use the non-initial name for printing/debugging. For example:\r\n\r\n```\r\nnamespace ver_reg\r\n{\r\n\tconstexpr const auto name = \"version_register\";\r\n\tconstexpr const auto offset = 0x000;\r\n\r\n\tusing value_type = uint32_t;\r\n\r\n\tinline auto get(const gsl::not_null<phys_iommu *> iommu) noexcept\r\n\t{ return iommu->read_32(offset); }\r\n\r\n\tnamespace min\r\n\t{\r\n\t\tconstexpr const auto mask = 0xFULL;\r\n\t\tconstexpr const auto from = 0ULL;\r\n\t\tconstexpr const auto name = \"minor_version_number\";\r\n\r\n\t\tinline auto get(const gsl::not_null<phys_iommu *> iommu) noexcept\r\n\t\t{ return get_bits(iommu->read_32(offset), mask) >> from; }\r\n\r\n\t\tinline auto get(const value_type &ver_reg) noexcept\r\n\t\t{ return get_bits(ver_reg, mask) >> from; }\r\n\r\n\t\tinline void dump(int level, const value_type &ver_reg, std::string *msg = nullptr)\r\n\t\t{ bfdebug_subnhex(level, name, get(ver_reg), msg); }\r\n\t}\r\n\r\n\tnamespace max\r\n\t{\r\n\t\tconstexpr const auto mask = 0xF0ULL;\r\n\t\tconstexpr const auto from = 4ULL;\r\n\t\tconstexpr const auto name = \"major_version_number\";\r\n\r\n\t\tinline auto get(const gsl::not_null<phys_iommu *> iommu) noexcept\r\n\t\t{ return get_bits(iommu->read_32(offset), mask) >> from; }\r\n\r\n\t\tinline auto get(const value_type &ver_reg) noexcept\r\n\t\t{ return get_bits(ver_reg, mask) >> from; }\r\n\r\n\t\tinline void dump(int level, const value_type &ver_reg, std::string *msg = nullptr)\r\n\t\t{ bfdebug_subnhex(level, name, get(ver_reg), msg); }\r\n\t}\r\n\r\n\tinline void dump(int level, const value_type &ver_reg, std::string *msg = nullptr)\r\n\t{\r\n\t\tbfdebug_nhex(level, name, ver_reg, msg);\r\n\r\n\t\tmin::dump(level, ver_reg, msg);\r\n\t\tmax::dump(level, ver_reg, msg);\r\n\t}\r\n\r\n\tinline void dump(int level, const gsl::not_null<phys_iommu *> iommu, std::string *msg = nullptr)\r\n\t{\r\n\t\tauto reg_val = get(iommu);\r\n\t\tdump(level, reg_val, msg);\r\n\t}\r\n}\r\n```\r\n\r\n## Questions and Comments\r\n\r\n* The phys_iommu class maintains state (a single pointer), and therefore arguably doesn't belong under the bfintrinsics folder. However, I can't think of a better place to put it. Any suggestions?"},"comment":{"url":"https://api.github.com/repos/Bareflank/hypervisor/issues/comments/399501369","html_url":"https://github.com/Bareflank/hypervisor/issues/690#issuecomment-399501369","issue_url":"https://api.github.com/repos/Bareflank/hypervisor/issues/690","id":399501369,"node_id":"MDEyOklzc3VlQ29tbWVudDM5OTUwMTM2OQ==","user":{"login":"JaredWright","id":13487832,"node_id":"MDQ6VXNlcjEzNDg3ODMy","avatar_url":"https://avatars0.githubusercontent.com/u/13487832?v=4","gravatar_id":"","url":"https://api.github.com/users/JaredWright","html_url":"https://github.com/JaredWright","followers_url":"https://api.github.com/users/JaredWright/followers","following_url":"https://api.github.com/users/JaredWright/following{/other_user}","gists_url":"https://api.github.com/users/JaredWright/gists{/gist_id}","starred_url":"https://api.github.com/users/JaredWright/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JaredWright/subscriptions","organizations_url":"https://api.github.com/users/JaredWright/orgs","repos_url":"https://api.github.com/users/JaredWright/repos","events_url":"https://api.github.com/users/JaredWright/events{/privacy}","received_events_url":"https://api.github.com/users/JaredWright/received_events","type":"User","site_admin":false},"created_at":"2018-06-22T16:28:07Z","updated_at":"2018-06-22T16:28:07Z","author_association":"CONTRIBUTOR","body":"Merged"}}
{"actor":{"display_login":"JaredWright"}}