acpi: arm: Add IORT Support
cover acpi: arm: Add IORT Support
From: Manish Jaggi <[email protected]>
This patch aims to add the support of IORT in Xen. Below is the list of major components which this patchset provides.
a. Add support for parsing the IORT
b. Provides API to populate/query requesterid - streamID mappings and
reuqesterid - deviceid mappings
c. The requesterid - deviceid mappings is used to create the IORT for
hardware domain (which hides smmu nodes from IORT)
d. iort.c fwnode.h fwspec code is imported from linux and modified.
Changes since RFC
- Added more documentation
- Moved code to arch/arm/acpi/ folder
- Lot of fixes for review comments
This patch works with [1] but few modifiations were made
(a) path of acpi_iort.h has changed so fixed to asm/acpi/acpi_iort.h
(b) Macro #define alloc_io_pgtable_ops(f, c, o) in Patch 5 of [1] results in -ENOMEM and need to be fixed.
-[1] https://lists.xenproject.org/archives/html/xen-devel/2018-02/msg00713.html
Manish Jaggi (13):
acpi: arm: API: Populate/query rid-devid rid-sid map.
acpi: arm: query estimated size of hardware domain's IORT.
acpi: arm: Code to generate Hardware Domains IORT
acpi: arm: Copy fwnode / iommu_fwspec code from Linux 4.14
acpi: arm: Import acpi_iort.h verbatim from linux 4.14
acpi: arm: Update acpi_iort.h with xen specific changes
arm: Adding ACPI_IORT in arm Kconfig
asm: arm: pci: Fix the #include label in asm-arm/pci.h
asm: arm: to_pci_dev
asm: arm: add dev_is_pci
asm: arm: add pci_domain_nr
acpi: arm: Provide support for iort iommu configuration hooks
acpi: arm: Add code to parse IORT and prepare rid maps.
xen/arch/arm/Kconfig | 4 + xen/arch/arm/acpi/Makefile | 3 + xen/arch/arm/acpi/gen-iort.c | 400 +++++++++++++++++++++++ xen/arch/arm/acpi/iort.c | 608 +++++++++++++++++++++++++++++++++++ xen/arch/arm/acpi/ridmap.c | 126 ++++++++ xen/arch/arm/domain_build.c | 51 ++- xen/drivers/passthrough/arm/iommu.c | 85 +++++ xen/drivers/passthrough/arm/smmu.c | 3 +- xen/include/asm-arm/acpi.h | 1 + xen/include/asm-arm/acpi/acpi_iort.h | 51 +++ xen/include/asm-arm/acpi/gen-iort.h | 44 +++ xen/include/asm-arm/acpi/ridmap.h | 112 +++++++ xen/include/asm-arm/device.h | 17 +- xen/include/asm-arm/fwnode.h | 128 ++++++++ xen/include/asm-arm/fwspec.h | 38 +++ xen/include/asm-arm/pci.h | 12 +- xen/include/xen/pci.h | 2 + 17 files changed, 1675 insertions(+), 10 deletions(-) create mode 100644 xen/arch/arm/acpi/gen-iort.c create mode 100644 xen/arch/arm/acpi/iort.c create mode 100644 xen/arch/arm/acpi/ridmap.c create mode 100644 xen/include/asm-arm/acpi/acpi_iort.h create mode 100644 xen/include/asm-arm/acpi/gen-iort.h create mode 100644 xen/include/asm-arm/acpi/ridmap.h create mode 100644 xen/include/asm-arm/fwnode.h create mode 100644 xen/include/asm-arm/fwspec.h
Signature · 7 lines
2.14.1 _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
PATCH RESEND 1/13 acpi: arm: API: Populate/query rid-devid rid-sid map.
From: Manish Jaggi <[email protected]>
IORT has a hierarchical structure containing PCIRC nodes, IORT nodes and SMMU nodes. Each node has with it an array of ids and a mapping which maps a range of ids to another node's ids. PCIRC(requesterid)->SMMU(streamid)->ITS(devid) or PCIRC->ITS
IORT is parsed multiple times when streamid(sid) / deviceid(devid) is queried from requesterid (rid).
Xen needs to prepare IORT for hardware domain which might again require parsing. Thus it is prudent to parse IORT once and save mapping information into individual maps namely rid-sid rid-devid.
This patch provides API to add a new mapping and query sid/devid based on rid. Two lists are created rid-sid list, rid-devid list. rid-devid list forms the basis of hardware domains' IORT.
--- xen/arch/arm/acpi/Makefile | 1 + xen/arch/arm/acpi/ridmap.c | 126 ++++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/acpi/ridmap.h | 112 +++++++++++++++++++++++++++++++++ 3 files changed, 239 insertions(+)
xen/arch/arm/acpi/Makefile +1 -0
@@ -1,2 +1,3 @@ obj-y += lib.o obj-y += boot.init.o +obj-y += ridmap.o
xen/arch/arm/acpi/ridmap.c new file +126 -0
126 lines not on this page · raw message
xen/include/asm-arm/acpi/ridmap.h new file +112 -0
112 lines not on this page · raw message
Signature · 7 lines
2.14.1 _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [PATCH resend 01/13] acpi: arm: API: Populate/query rid-devid rid-sid map.
Hi Manish,
Quoted 10 lines · On 03/13/2018 03:20 PM, [email protected] wrote:
From: Manish Jaggi <[email protected]>
IORT has a hierarchical structure containing PCIRC nodes, IORT nodes and SMMU nodes. Each node has with it an array of ids and a mapping which maps a range of ids to another node's ids. PCIRC(requesterid)->SMMU(streamid)->ITS(devid) or
PCIRC->ITSIORT is parsed multiple times when streamid(sid) / deviceid(devid) is queried from requesterid (rid).
Quoted 7 lines
Xen needs to prepare IORT for hardware domain which might again require parsing. Thus it is prudent to parse IORT once and save mapping information into individual maps namely rid-sid rid-devid.
This patch provides API to add a new mapping and query sid/devid based on rid. Two lists are created rid-sid list, rid-devid list. rid-devid list forms the basis of hardware domains' IORT.
Thank you for updating the commit message. However, you stil don't give an idea often those function will get called and whether unsorted list will be fine.
Quoted 41 lines
Signed-off-by Manish Jaggi <[email protected]>--- xen/arch/arm/acpi/Makefile | 1 + xen/arch/arm/acpi/ridmap.c | 126 ++++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/acpi/ridmap.h | 112 +++++++++++++++++++++++++++++++++ 3 files changed, 239 insertions(+)xen/arch/arm/acpi/Makefile +1
-0@@ -1,2 +1,3 @@ obj-y += lib.o obj-y += boot.init.o +obj-y += ridmap.oxen/arch/arm/acpi/ridmap.c new file +19
-0@@ -0,0 +1,126 @@ +/* +* xen/drivers/acpi/arm/ridmap.c +* +* This file implements rid-sid rid-devid mapping API +* +* Manish Jaggi <[email protected]> +* Copyright (c) 2018 Linaro. +* +* Ths program is free software; you can redistribute it and/or +* modify it under the terms and conditions of the GNU General Public +* License, version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <asm/acpi/ridmap.h>
xen/arch/arm/acpi/ridmap.c line 29
Quoted 10 lines
xen/arch/arm/acpi/ridmap.c new file +10
-0+#include <xen/iommu.h> +#include <xen/kernel.h> +#include <xen/list.h> +#include <xen/pci.h> + +LIST_HEAD (rid_sid_list); +LIST_HEAD (rid_devid_list); + +int add_rid_sid_map(struct acpi_iort_node *pcirc_node, + struct acpi_iort_node *smmu_node,
Is there any one that will modify pcirc_node and smmu_node afterwards? If not, then they should be const.
xen/arch/arm/acpi/ridmap.c line 31
Quoted 2 lines
xen/arch/arm/acpi/ridmap.c new file +2
-0+ uint32_t input_base, uint32_t output_base, + uint32_t id_count)
I suggested to put __init in front of that function. But you dismissed it saying it might not be valid and you will add rationale. I don't see any rationale in that patch nor an answer to my question on the previous version.
Quoted 10 lines
xen/arch/arm/acpi/ridmap.c new file +10
-0+{ +struct rid_sid_map *rid_map; + + rid_map = xzalloc(struct rid_sid_map); +if ( !rid_map ) +return -ENOMEM ; + + rid_map->idmap.input_base = input_base; + rid_map->idmap.output_base = output_base; + rid_map->idmap.id_count = id_count;
xen/arch/arm/acpi/ridmap.c line 51
Quoted 10 lines
xen/arch/arm/acpi/ridmap.c new file +10
-0+ rid_map->pcirc_node = pcirc_node; + rid_map->smmu_node = smmu_node; + +list_add_tail (&rid_map->entry, &rid_sid_list); + +return 0 ; +} + +int add_rid_devid_map(struct acpi_iort_node *pcirc_node, + struct acpi_iort_node *its_node,
Same here about const.
xen/arch/arm/acpi/ridmap.c line 53
Quoted 2 lines
xen/arch/arm/acpi/ridmap.c new file +2
-0+ uint32_t input_base, uint32_t output_base, + uint32_t id_count)
Same here about __init.
Quoted 101 lines
xen/arch/arm/acpi/ridmap.c new file +73
-0+{ +struct rid_devid_map *rid_map; + + rid_map = xzalloc(struct rid_devid_map); +if ( !rid_map ) +return -ENOMEM ; + + rid_map->idmap.input_base = input_base; + rid_map->idmap.output_base = output_base; + rid_map->idmap.id_count = id_count; + rid_map->pcirc_node = pcirc_node; + rid_map->its_node = its_node; + +list_add_tail (&rid_map->entry, &rid_devid_list); + +return 0 ; +} + +bool query_sid (struct acpi_iort_node *pcirc_node,uint32_t rid, +uint32_t *sid,struct acpi_iort_node **smmu_node) +{ +struct rid_sid_map *rmap; + +list_for_each_entry (rmap, &rid_sid_list, entry) + { +if ( rmap->pcirc_node == pcirc_node ) + { +if ( (rid >= rmap->idmap.input_base) && + (rid < rmap->idmap.input_base + rmap->idmap.id_count) ) + { + *sid = rid - rmap->idmap.input_base + + rmap->idmap.output_base; + *smmu_node = rmap->smmu_node; + +return 1 ; + } + } + } + +return 0 ; +} + +bool query_devid (struct acpi_iort_node *pcirc_node, +uint32_t rid,uint32_t *devid) +{ +struct rid_devid_map *rmap; + +list_for_each_entry (rmap, &rid_devid_list, entry) + { +if ( rmap->pcirc_node == pcirc_node ) + { +if ( (rid >= rmap->idmap.input_base) && + (rid < rmap->idmap.input_base + rmap->idmap.id_count) ) + { + *devid = rid - rmap->idmap.input_base + + rmap->idmap.output_base; + +return 1 ; + } + } + } + +return 0 ; +} + +/* +* Local variables: +* mode: C +* c-file-style: "BSD" +* c-basic-offset: 4 +* indent-tabs-mode: nil +* End: +*/ xen/include/asm-arm/acpi/ridmap.h new file +22
-0@@ -0,0 +1,112 @@ +/* +* xen/include/acpi/ridmap.h +* +* Manish Jaggi <[email protected]> +* Copyright (c) 2018 Linaro. +* +* Ths program is free software; you can redistribute it and/or +* modify it under the terms and conditions of the GNU General Public +* License, version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#ifndef __ASM_ACPI_RIDMAP_H__ +#define __ASM_ACPI_RIDMAP_H__ + +#include <xen/acpi.h> + +/*
xen/include/asm-arm/acpi/ridmap.h line 32
Quoted 10 lines
xen/include/asm-arm/acpi/ridmap.h new file +10
-0+* List holds requesterid (rid) - streamid (sid) mapping entries. +*/ +extern struct list_head rid_sid_list; +/* +* List holds requesterid (rid) - deviceid (devid) mapping entries. +*/ +extern struct list_head rid_devid_list; + +/* +* structure to hold mapping between requresterid and streamid.
requesterid.
Quoted 26 lines
xen/include/asm-arm/acpi/ridmap.h new file +26
-0+* Note: output_reference and flags members of acpi_iort_id_mapping +* are not used. This is done to avoid creating a new structure for +* same purpose. +* +* smmu node pointer is stored in this structure because, in some places +* smmu_node along with streamid is required based on rid and pcirc_node. +*/ +struct rid_sid_map +{ +struct acpi_iort_node *pcirc_node; +struct acpi_iort_node *smmu_node; +struct acpi_iort_id_mapping idmap; +struct list_head entry; +}; + +/* +* API to add a rid-sid mapping +* This method should be called while parsing each entry in idmap array +* under the pcirc node in IORT. +*/ +int add_rid_sid_map (struct acpi_iort_node *pcirc_node, +struct acpi_iort_node *smmu_node, +uint32_t input_base,uint32_t output_base, +uint32_t id_count); +/* +* API to query sid and smmu_node based on pcirc_node and rid.
xen/include/asm-arm/acpi/ridmap.h line 68
Quoted 10 lines
xen/include/asm-arm/acpi/ridmap.h new file +10
-0+* +* Example of usage: +* int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) +* { +* struct iort_pci_alias_info *info = data; +* ... +* if ( query_sid(info->node, alias, &streamid, &smmu_node) ) +* return iort_iommu_xlate(info->dev, smmu_node, streamid); +* ... +* }
I don't see the benefits of the example usage. If the function is difficult to use, then it much better to describe each argument.
xen/include/asm-arm/acpi/ridmap.h line 75
Quoted 7 lines
xen/include/asm-arm/acpi/ridmap.h new file +7
-0+* +*/ +bool query_sid (struct acpi_iort_node *pcirc_node,uint32_t rid, +uint32_t *sid,struct acpi_iort_node **smmu_node); + +/* +* structure to hold a mapping between requresterid and deviceid.
requesterid
xen/include/asm-arm/acpi/ridmap.h line 86
Quoted 11 lines
xen/include/asm-arm/acpi/ridmap.h new file +11
-0+* Note: output_reference and flags members of acpi_iort_id_mapping +* are not used. This is done to avoid creating a new structure for +* same purpose. +*/ +struct rid_devid_map +{ +struct acpi_iort_node *pcirc_node; +struct acpi_iort_node *its_node; +struct acpi_iort_id_mapping idmap; +struct list_head entry; +};
You could probably merge this structure and rid_sid_map. The only difference is smmu_node, so you could use an union for that.
xen/include/asm-arm/acpi/ridmap.h line 99
Quoted 13 lines
xen/include/asm-arm/acpi/ridmap.h new file +13
-0+ +/* +* API to add a rid-devid mapping +* This method should be called while parsing each entry in idmap array +* under the pcirc node in IORT. +*/ +int add_rid_devid_map (struct acpi_iort_node *pcirc_node, +struct acpi_iort_node *its_node, +uint32_t input_base,uint32_t output_base, +uint32_t id_count); + +/* +* API to query devid based on pcirc_node and rid */
Comment coding style.
Quoted 4 lines
xen/include/asm-arm/acpi/ridmap.h new file +3
-0+bool query_devid (struct acpi_iort_node *pcirc_node,uint32_t rid, +uint32_t *devid); +
xen/include/asm-arm/acpi/ridmap.h line 112
Quoted 10 lines
xen/include/asm-arm/acpi/ridmap.h new file +10
-0+#endif + +/* +* Local variables: +* mode: C +* c-file-style: "BSD" +* c-basic-offset: 4 +* indent-tabs-mode: nil +* End: +*/
Cheers,
Signature · 6 lines
Julien Grall _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [PATCH resend 01/13] acpi: arm: API: Populate/query rid-devid rid-sid map.
Quoted 1 line · Julien Grall
Hi Manish,
Hi Julien,
Quoted 16 lines · On 03/13/2018 03:20 PM, [email protected] wrote:
Quoted 14 lines
From: Manish Jaggi <[email protected]>
IORT has a hierarchical structure containing PCIRC nodes, IORT nodes and SMMU nodes. Each node has with it an array of ids and a mapping which maps a range of ids to another node's ids. PCIRC(requesterid)->SMMU(streamid)->ITS(devid) or
PCIRC->ITSIORT is parsed multiple times when streamid(sid) / deviceid(devid) is queried from requesterid (rid).
Xen needs to prepare IORT for hardware domain which might again require parsing. Thus it is prudent to parse IORT once and save mapping information into individual maps namely rid-sid rid-devid.
Quoted 5 lines
Quoted 3 lines
This patch provides API to add a new mapping and query sid/devid based on rid. Two lists are created rid-sid list, rid-devid list. rid-devid list forms the basis of hardware domains' IORT.
Thank you for updating the commit message. However, you stil don't give an idea often those function will get called and whether unsorted list will be fine.
I have added that in code comments.
Quoted 57 lines
Quoted 44 lines
Signed-off-by Manish Jaggi <[email protected]>---
xen/arch/arm/acpi/Makefile | 1 +
xen/arch/arm/acpi/ridmap.c | 126
++++++++++++++++++++++++++++++++++++++
xen/include/asm-arm/acpi/ridmap.h| 112
+++++++++++++++++++++++++++++++++3 files changed, 239 insertions(+)xen/arch/arm/acpi/Makefile +0
-0@@ -1,2 +1,3 @@obj-y += lib.o
obj-y += boot.init.oxen/arch/arm/acpi/Makefile +1
-0+obj-y += ridmap.oxen/arch/arm/acpi/ridmap.c new file +19
-0@@ -0,0 +1,126 @@ +/* +* xen/drivers/acpi/arm/ridmap.c +* +* This file implements rid-sid rid-devid mapping API +* +* Manish Jaggi <[email protected]> +* Copyright (c) 2018 Linaro. +* +* Ths program is free software; you can redistribute it and/or +* modify it under the terms and conditions of the GNU General Public +* License, version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <asm/acpi/ridmap.h> xen/arch/arm/acpi/ridmap.c line 29
Quoted 10 lines
xen/arch/arm/acpi/ridmap.c new file +10
-0+#include <xen/iommu.h> +#include <xen/kernel.h> +#include <xen/list.h> +#include <xen/pci.h> + +LIST_HEAD (rid_sid_list); +LIST_HEAD (rid_devid_list); + +int add_rid_sid_map(struct acpi_iort_node *pcirc_node, + struct acpi_iort_node *smmu_node,Is there any one that will modify
pcirc_nodeandsmmu_nodeafterwards? If not, then they should be const.
Quoted 5 lines
xen/arch/arm/acpi/ridmap.c line 31
Quoted 2 lines
xen/arch/arm/acpi/ridmap.c new file +2
-0+ uint32_t input_base, uint32_t output_base, + uint32_t id_count)I suggested to put
__initin front of that function. But you dismissed it saying it might not be valid and you will add rationale. I don't see any rationale in that patch nor an answer to my question on the previous version.
Should a public API function be __init ?
Quoted 177 lines
Quoted 10 lines
xen/arch/arm/acpi/ridmap.c new file +10
-0+{ + struct rid_sid_map *rid_map; + + rid_map = xzalloc(struct rid_sid_map); + if ( !rid_map ) + return -ENOMEM; + + rid_map->idmap.input_base = input_base; + rid_map->idmap.output_base = output_base; + rid_map->idmap.id_count = id_count;xen/arch/arm/acpi/ridmap.c line 51
Quoted 10 lines
xen/arch/arm/acpi/ridmap.c new file +10
-0+ rid_map->pcirc_node = pcirc_node; + rid_map->smmu_node = smmu_node; + + list_add_tail(&rid_map->entry, &rid_sid_list); + + return 0; +} + +int add_rid_devid_map(struct acpi_iort_node *pcirc_node, + struct acpi_iort_node *its_node,Same here about const.
xen/arch/arm/acpi/ridmap.c line 53
Quoted 2 lines
xen/arch/arm/acpi/ridmap.c new file +2
-0+ uint32_t input_base, uint32_t output_base, + uint32_t id_count)Same here about
__init.Quoted 103 lines
xen/arch/arm/acpi/ridmap.c new file +29
-0+{ + struct rid_devid_map *rid_map; + + rid_map = xzalloc(struct rid_devid_map); + if ( !rid_map ) + return -ENOMEM; + + rid_map->idmap.input_base = input_base; + rid_map->idmap.output_base = output_base; + rid_map->idmap.id_count = id_count; + rid_map->pcirc_node = pcirc_node; + rid_map->its_node = its_node; + + list_add_tail(&rid_map->entry, &rid_devid_list); + + return 0; +} + +bool query_sid(struct acpi_iort_node *pcirc_node, uint32_t rid, + uint32_t *sid, struct acpi_iort_node **smmu_node) +{ + struct rid_sid_map *rmap; + + list_for_each_entry(rmap, &rid_sid_list, entry) + { + if ( rmap->pcirc_node == pcirc_node ) + { + if ( (rid >= rmap->idmap.input_base) && + (rid < rmap->idmap.input_base +
rmap->idmap.id_count) )
+ {
+ *sid = rid -rmap->idmap.input_base+ +rmap->idmap.output_base; +*smmu_node=rmap->smmu_node;xen/arch/arm/acpi/ridmap.c new file +20
-0+ + return 1; + } + } + } + + return 0; +} + +bool query_devid(struct acpi_iort_node *pcirc_node, + uint32_t rid, uint32_t *devid) +{ + struct rid_devid_map *rmap; + + list_for_each_entry(rmap, &rid_devid_list, entry) + { + if ( rmap->pcirc_node == pcirc_node ) + { + if ( (rid >= rmap->idmap.input_base) && + (rid < rmap->idmap.input_base +
rmap->idmap.id_count) )
+ {
+ *devid = rid -rmap->idmap.input_base+ +rmap->idmap.output_base;xen/arch/arm/acpi/ridmap.c new file +17
-0+ + return 1; + } + } + } + + return 0; +} + +/* +* Local variables: +* mode: C +* c-file-style: "BSD" +* c-basic-offset: 4 +* indent-tabs-mode: nil +* End: +*/ xen/include/asm-arm/acpi/ridmap.h new file +22
-0@@ -0,0 +1,112 @@ +/* +* xen/include/acpi/ridmap.h +* +* Manish Jaggi <[email protected]> +* Copyright (c) 2018 Linaro. +* +* Ths program is free software; you can redistribute it and/or +* modify it under the terms and conditions of the GNU General Public +* License, version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#ifndef __ASM_ACPI_RIDMAP_H__ +#define __ASM_ACPI_RIDMAP_H__ + +#include <xen/acpi.h> + +/* xen/include/asm-arm/acpi/ridmap.h line 32
Quoted 10 lines
xen/include/asm-arm/acpi/ridmap.h new file +10
-0+* List holds requesterid (rid) - streamid (sid) mapping entries. +*/ +extern struct list_head rid_sid_list; +/* +* List holds requesterid (rid) - deviceid (devid) mapping entries. +*/ +extern struct list_head rid_devid_list; + +/* +* structure to hold mapping between requresterid and streamid. requesterid.
Quoted 33 lines
xen/include/asm-arm/acpi/ridmap.h new file +5
-0+* Note: output_reference and flags members of acpi_iort_id_mapping +* are not used. This is done to avoid creating a new structure for +* same purpose. +* +* smmu node pointer is stored in this structure because, in some places
+ *smmu_nodealong with streamid is required based on rid andpcirc_node.
+ */xen/include/asm-arm/acpi/ridmap.h new file +22
-0+struct rid_sid_map +{ + struct acpi_iort_node *pcirc_node; + struct acpi_iort_node *smmu_node; + struct acpi_iort_id_mapping idmap; + struct list_head entry; +}; + +/* +* API to add a rid-sid mapping +* This method should be called while parsing each entry in idmap array +* under the pcirc node in IORT. +*/ +int add_rid_sid_map (struct acpi_iort_node *pcirc_node, + struct acpi_iort_node *smmu_node, + uint32_t input_base, uint32_t output_base, + uint32_t id_count); +/* +* API to query sid and smmu_node based on pcirc_node and rid. +* +* Example of usage: +* int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
+ * {
Quoted 8 lines
Quoted 6 lines
+ * struct
iort_pci_alias_info*info = data;
+ * ...
+ * if (query_sid(info->node, alias, &streamid, &smmu_node))
+ * returniort_iommu_xlate(info->dev, smmu_node, streamid);
+ * ...
+ * }I don't see the benefits of the example usage. If the function is difficult to use, then it much better to describe each argument.
It is not difficult, I was citing an example usecase, as you requested in earlier comments, What is the best place to add it ? commit message / code comments.
Quoted 41 lines
xen/include/asm-arm/acpi/ridmap.h line 75
Quoted 8 lines
+ *
+ */xen/include/asm-arm/acpi/ridmap.h new file +5
-0+bool query_sid (struct acpi_iort_node *pcirc_node,uint32_t rid, + uint32_t *sid, struct acpi_iort_node **smmu_node); + +/* +* structure to hold a mapping between requresterid and deviceid. requesterid
xen/include/asm-arm/acpi/ridmap.h line 86
Quoted 11 lines
+ * Note:
output_referenceand flags members ofacpi_iort_id_mapping
+ * are not used. This is done to avoid creating a new structure for
+ * same purpose.
+ */xen/include/asm-arm/acpi/ridmap.h new file +7
-0+struct rid_devid_map +{ + struct acpi_iort_node *pcirc_node; + struct acpi_iort_node *its_node; + struct acpi_iort_id_mapping idmap; + struct list_head entry; +};You could probably merge this structure and
rid_sid_map. The only difference issmmu_node, so you could use an union for that.xen/include/asm-arm/acpi/ridmap.h line 99
Quoted 13 lines
xen/include/asm-arm/acpi/ridmap.h new file +13
-0+ +/* +* API to add a rid-devid mapping +* This method should be called while parsing each entry in idmap array +* under the pcirc node in IORT. +*/ +int add_rid_devid_map (struct acpi_iort_node *pcirc_node, + struct acpi_iort_node *its_node, + uint32_t input_base, uint32_t output_base, + uint32_t id_count); + +/* +* API to query devid based on pcirc_node and rid */ Comment coding style.
Quoted 17 lines
Quoted 4 lines
xen/include/asm-arm/acpi/ridmap.h new file +3
-0+bool query_devid (struct acpi_iort_node *pcirc_node,uint32_t rid, + uint32_t *devid); +xen/include/asm-arm/acpi/ridmap.h line 112
Quoted 10 lines
xen/include/asm-arm/acpi/ridmap.h new file +10
-0+#endif + +/* +* Local variables: +* mode: C +* c-file-style: "BSD" +* c-basic-offset: 4 +* indent-tabs-mode: nil +* End: +*/ Cheers,
_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [PATCH resend 01/13] acpi: arm: API: Populate/query rid-devid rid-sid map.
Hi,
Quoted 20 lines · Manish Jaggi
Quoted 1 line · Julien Grall
Hi Manish,
Hi Julien,
Quoted 16 lines · On 03/13/2018 03:20 PM, [email protected] wrote:
Quoted 14 lines
From: Manish Jaggi <[email protected]>
IORT has a hierarchical structure containing PCIRC nodes, IORT nodes and SMMU nodes. Each node has with it an array of ids and a mapping which maps a range of ids to another node's ids. PCIRC(requesterid)->SMMU(streamid)->ITS(devid) or
PCIRC->ITSIORT is parsed multiple times when streamid(sid) / deviceid(devid) is queried from requesterid (rid).
Xen needs to prepare IORT for hardware domain which might again require parsing. Thus it is prudent to parse IORT once and save mapping information into individual maps namely rid-sid rid-devid.
Quoted 6 lines
Quoted 5 lines
Quoted 3 lines
This patch provides API to add a new mapping and query sid/devid based on rid. Two lists are created rid-sid list, rid-devid list. rid-devid list forms the basis of hardware domains' IORT.
Thank you for updating the commit message. However, you stil don't give an idea often those function will get called and whether unsorted list will be fine.
I have added that in code comments.
Mind to show where?
[...]
Quoted 14 lines
Quoted 14 lines
xen/arch/arm/acpi/ridmap.c line 29
Quoted 11 lines
xen/arch/arm/acpi/ridmap.c new file +11
-0+#include <asm/acpi/ridmap.h> +#include <xen/iommu.h> +#include <xen/kernel.h> +#include <xen/list.h> +#include <xen/pci.h> + +LIST_HEAD (rid_sid_list); +LIST_HEAD (rid_devid_list); + +int add_rid_sid_map(struct acpi_iort_node *pcirc_node, + struct acpi_iort_node *smmu_node,Is there any one that will modify
pcirc_nodeandsmmu_nodeafterwards? If not, then they should be const.
Quoted 6 lines
Quoted 5 lines
Quoted 2 lines
+
uint32_tinput_base,uint32_toutput_base, +uint32_tid_count)I suggested to put
__initin front of that function. But you dismissed it saying it might not be valid and you will add rationale. I don't see any rationale in that patch nor an answer to my question on the previous version.Should a public API function be
__init?
The question is do you expect this function to be called after Xen has booted. Likely not, so this should be public to shrink down the size of Xen after boot.
[...]
Quoted 24 lines
Quoted 16 lines
Quoted 16 lines
xen/include/asm-arm/acpi/ridmap.h new file +14
-0+/* +* API to add a rid-sid mapping +* This method should be called while parsing each entry in idmap array +* under the pcirc node in IORT. +*/ +int add_rid_sid_map (struct acpi_iort_node *pcirc_node, + struct acpi_iort_node *smmu_node, + uint32_t input_base, uint32_t output_base, + uint32_t id_count); +/* +* API to query sid and smmu_node based on pcirc_node and rid. +* +* Example of usage: +* int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
+ * {Quoted 8 lines
Quoted 6 lines
+ * struct
iort_pci_alias_info*info = data;
+ * ...
+ * if (query_sid(info->node, alias, &streamid, &smmu_node))
+ * returniort_iommu_xlate(info->dev, smmu_node, streamid);
+ * ...
+ * }I don't see the benefits of the example usage. If the function is difficult to use, then it much better to describe each argument.
Quoted 2 lines
It is not difficult, I was citing an example usecase, as you requested in earlier comments, What is the best place to add it ? commit message / code comments.
Use case belongs to the commit message. The comment code should only describe the expected usage or a couple of words for the use case (but that usually part of the description of the function).
Cheers,
Signature · 6 lines
Julien Grall _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [PATCH resend 01/13] acpi: arm: API: Populate/query rid-devid rid-sid map.
In reply to [email protected]Title: Please drop the full stop.
Quoted 284 lines · On 03/13/2018 03:20 PM, [email protected] wrote:
From: Manish Jaggi <[email protected]>
IORT has a hierarchical structure containing PCIRC nodes, IORT nodes and SMMU nodes. Each node has with it an array of ids and a mapping which maps a range of ids to another node's ids. PCIRC(requesterid)->SMMU(streamid)->ITS(devid) or
PCIRC->ITSIORT is parsed multiple times when streamid(sid) / deviceid(devid) is queried from requesterid (rid).
Xen needs to prepare IORT for hardware domain which might again require parsing. Thus it is prudent to parse IORT once and save mapping information into individual maps namely rid-sid rid-devid.
This patch provides API to add a new mapping and query sid/devid based on rid. Two lists are created rid-sid list, rid-devid list. rid-devid list forms the basis of hardware domains' IORT.
Signed-off-by Manish Jaggi <[email protected]>--- xen/arch/arm/acpi/Makefile | 1 + xen/arch/arm/acpi/ridmap.c | 126 ++++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/acpi/ridmap.h | 112 +++++++++++++++++++++++++++++++++ 3 files changed, 239 insertions(+)xen/arch/arm/acpi/Makefile +1
-0@@ -1,2 +1,3 @@ obj-y += lib.o obj-y += boot.init.o +obj-y += ridmap.oxen/arch/arm/acpi/ridmap.c new file +126
-0@@ -0,0 +1,126 @@ +/* +* xen/drivers/acpi/arm/ridmap.c +* +* This file implements rid-sid rid-devid mapping API +* +* Manish Jaggi <[email protected]> +* Copyright (c) 2018 Linaro. +* +* Ths program is free software; you can redistribute it and/or +* modify it under the terms and conditions of the GNU General Public +* License, version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <asm/acpi/ridmap.h> +#include <xen/iommu.h> +#include <xen/kernel.h> +#include <xen/list.h> +#include <xen/pci.h> + +LIST_HEAD (rid_sid_list); +LIST_HEAD (rid_devid_list); + +int add_rid_sid_map (struct acpi_iort_node *pcirc_node, +struct acpi_iort_node *smmu_node, +uint32_t input_base,uint32_t output_base, +uint32_t id_count) +{ +struct rid_sid_map *rid_map; + + rid_map = xzalloc(struct rid_sid_map); +if ( !rid_map ) +return -ENOMEM ; + + rid_map->idmap.input_base = input_base; + rid_map->idmap.output_base = output_base; + rid_map->idmap.id_count = id_count; + rid_map->pcirc_node = pcirc_node; + rid_map->smmu_node = smmu_node; + +list_add_tail (&rid_map->entry, &rid_sid_list); + +return 0 ; +} + +int add_rid_devid_map (struct acpi_iort_node *pcirc_node, +struct acpi_iort_node *its_node, +uint32_t input_base,uint32_t output_base, +uint32_t id_count) +{ +struct rid_devid_map *rid_map; + + rid_map = xzalloc(struct rid_devid_map); +if ( !rid_map ) +return -ENOMEM ; + + rid_map->idmap.input_base = input_base; + rid_map->idmap.output_base = output_base; + rid_map->idmap.id_count = id_count; + rid_map->pcirc_node = pcirc_node; + rid_map->its_node = its_node; + +list_add_tail (&rid_map->entry, &rid_devid_list); + +return 0 ; +} + +bool query_sid (struct acpi_iort_node *pcirc_node,uint32_t rid, +uint32_t *sid,struct acpi_iort_node **smmu_node) +{ +struct rid_sid_map *rmap; + +list_for_each_entry (rmap, &rid_sid_list, entry) + { +if ( rmap->pcirc_node == pcirc_node ) + { +if ( (rid >= rmap->idmap.input_base) && + (rid < rmap->idmap.input_base + rmap->idmap.id_count) ) + { + *sid = rid - rmap->idmap.input_base + + rmap->idmap.output_base; + *smmu_node = rmap->smmu_node; + +return 1 ; + } + } + } + +return 0 ; +} + +bool query_devid (struct acpi_iort_node *pcirc_node, +uint32_t rid,uint32_t *devid) +{ +struct rid_devid_map *rmap; + +list_for_each_entry (rmap, &rid_devid_list, entry) + { +if ( rmap->pcirc_node == pcirc_node ) + { +if ( (rid >= rmap->idmap.input_base) && + (rid < rmap->idmap.input_base + rmap->idmap.id_count) ) + { + *devid = rid - rmap->idmap.input_base + + rmap->idmap.output_base; + +return 1 ; + } + } + } + +return 0 ; +} + +/* +* Local variables: +* mode: C +* c-file-style: "BSD" +* c-basic-offset: 4 +* indent-tabs-mode: nil +* End: +*/ xen/include/asm-arm/acpi/ridmap.h new file +112
-0@@ -0,0 +1,112 @@ +/* +* xen/include/acpi/ridmap.h +* +* Manish Jaggi <[email protected]> +* Copyright (c) 2018 Linaro. +* +* Ths program is free software; you can redistribute it and/or +* modify it under the terms and conditions of the GNU General Public +* License, version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#ifndef __ASM_ACPI_RIDMAP_H__ +#define __ASM_ACPI_RIDMAP_H__ + +#include <xen/acpi.h> + +/* +* List holds requesterid (rid) - streamid (sid) mapping entries. +*/ +extern struct list_head rid_sid_list; +/* +* List holds requesterid (rid) - deviceid (devid) mapping entries. +*/ +extern struct list_head rid_devid_list; + +/* +* structure to hold mapping between requresterid and streamid. +* Note: output_reference and flags members of acpi_iort_id_mapping +* are not used. This is done to avoid creating a new structure for +* same purpose. +* +* smmu node pointer is stored in this structure because, in some places +* smmu_node along with streamid is required based on rid and pcirc_node. +*/ +struct rid_sid_map +{ +struct acpi_iort_node *pcirc_node; +struct acpi_iort_node *smmu_node; +struct acpi_iort_id_mapping idmap; +struct list_head entry; +}; + +/* +* API to add a rid-sid mapping +* This method should be called while parsing each entry in idmap array +* under the pcirc node in IORT. +*/ +int add_rid_sid_map (struct acpi_iort_node *pcirc_node, +struct acpi_iort_node *smmu_node, +uint32_t input_base,uint32_t output_base, +uint32_t id_count); +/* +* API to query sid and smmu_node based on pcirc_node and rid. +* +* Example of usage: +* int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) +* { +* struct iort_pci_alias_info *info = data; +* ... +* if ( query_sid(info->node, alias, &streamid, &smmu_node) ) +* return iort_iommu_xlate(info->dev, smmu_node, streamid); +* ... +* } +* +*/ +bool query_sid (struct acpi_iort_node *pcirc_node,uint32_t rid, +uint32_t *sid,struct acpi_iort_node **smmu_node); + +/* +* structure to hold a mapping between requresterid and deviceid. +* Note: output_reference and flags members of acpi_iort_id_mapping +* are not used. This is done to avoid creating a new structure for +* same purpose. +*/ +struct rid_devid_map +{ +struct acpi_iort_node *pcirc_node; +struct acpi_iort_node *its_node; +struct acpi_iort_id_mapping idmap; +struct list_head entry; +}; + +/* +* API to add a rid-devid mapping +* This method should be called while parsing each entry in idmap array +* under the pcirc node in IORT. +*/ +int add_rid_devid_map (struct acpi_iort_node *pcirc_node, +struct acpi_iort_node *its_node, +uint32_t input_base,uint32_t output_base, +uint32_t id_count); + +/* +* API to query devid based on pcirc_node and rid */ +bool query_devid (struct acpi_iort_node *pcirc_node,uint32_t rid, +uint32_t *devid); + +#endif + +/* +* Local variables: +* mode: C +* c-file-style: "BSD" +* c-basic-offset: 4 +* indent-tabs-mode: nil +* End: +*/
Signature · 6 lines
Julien Grall _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
PATCH RESEND 2/13 acpi: arm: query estimated size of hardware domain's IORT.
In reply to [email protected]From: Manish Jaggi <[email protected]>
Code to query estimated IORT size for hardware domain. IORT for hardware domain is generated using the requesterid and deviceid map. Xen code requires the size to be predeterminded.
--- xen/arch/arm/acpi/Makefile | 1 + xen/arch/arm/acpi/gen-iort.c | 101 ++++++++++++++++++++++++++++++++++++ xen/arch/arm/domain_build.c | 16 ++++-- xen/include/asm-arm/acpi/gen-iort.h | 33 ++++++++++++ 4 files changed, 148 insertions(+), 3 deletions(-)
xen/arch/arm/acpi/Makefile +1 -0
@@ -1,3 +1,4 @@ obj-y += lib.o obj-y += boot.init.o obj-y += ridmap.o +obj-y += gen-iort.o
xen/arch/arm/acpi/gen-iort.c new file +101 -0
101 lines not on this page · raw message
xen/arch/arm/domain_build.c +13 -3
@@ -14,6 +14,7 @@#include <xen/acpi.h> #include <xen/warning.h> #include <acpi/actables.h> +#include <asm/acpi/gen-iort.h> #include <asm/device.h> #include <asm/setup.h> #include <asm/platform.h>
@@ -1801,7 +1802,7 @@ static int acpi_create_fadt(struct domain *d, struct membank tbl_add[])static int estimate_acpi_efi_size (struct domain *d,struct kernel_info *kinfo) { -size_t efi_size, acpi_size, madt_size; +size_t efi_size, acpi_size, table_size;u64 addr;struct acpi_table_rsdp *rsdp_tbl;struct acpi_table_header *table;
@@ -1811,8 +1812,8 @@ static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo) acpi_size =ROUNDUP (sizeof (struct acpi_table_fadt ),8 ); acpi_size +=ROUNDUP (sizeof (struct acpi_table_stao ),8 ); - madt_size =gic_get_hwdom_madt_size (d); - acpi_size +=ROUNDUP (madt_size,8 ); + table_size =gic_get_hwdom_madt_size (d); + acpi_size +=ROUNDUP (table_size,8 ); addr =acpi_os_get_root_pointer ();if ( !addr )
@@ -1842,6 +1843,15 @@ static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo)acpi_os_unmap_memory (table,sizeof (struct acpi_table_header )); acpi_size +=ROUNDUP (sizeof (struct acpi_table_rsdp ),8 ); + +if (estimate_iort_size (&table_size) ) + { +printk ("Unable to get hwdom iort size\n" ); +return -EINVAL ; + } + + acpi_size +=ROUNDUP (table_size,8 ); + d->arch.efi_acpi_len =PAGE_ALIGN (ROUNDUP (efi_size,8 ) +ROUNDUP (acpi_size,8 ));
xen/include/asm-arm/acpi/gen-iort.h new file +33 -0
@@ -0,0 +1,33 @@ +/* +* xen/include/asm-arm/acpi/gen-iort.h +* +* Manish Jaggi <[email protected]> +* Copyright (c) 2018 Linaro. +* +* Ths program is free software; you can redistribute it and/or +* modify it under the terms and conditions of the GNU General Public +* License, version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#ifndef _ACPI_GEN_IORT_H +#define _ACPI_GEN_IORT_H + +/* +* Returns the size of hardware domains IORT +*/ +int estimate_iort_size (size_t *iort_size); + +#endif +/* +* Local variables: +* mode: C +* c-file-style: "BSD" +* c-basic-offset: 4 +* indent-tabs-mode: nil +* End: +*/
Signature · 7 lines
2.14.1 _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [PATCH resend 02/13] acpi: arm: query estimated size of hardware domain's IORT.
Title: Please drop the full stop.
Quoted 5 lines · On 03/13/2018 03:20 PM, [email protected] wrote:
From: Manish Jaggi <[email protected]>
Code to query estimated IORT size for hardware domain. IORT for hardware domain is generated using the requesterid and deviceid map. Xen code requires the size to be predeterminded.
Please expand: "Xen code requires the size to be predeterminded".
Quoted 24 lines
Signed-off-by Manish Jaggi <[email protected]>--- xen/arch/arm/acpi/Makefile | 1 + xen/arch/arm/acpi/gen-iort.c | 101 ++++++++++++++++++++++++++++++++++++ xen/arch/arm/domain_build.c | 16 ++++-- xen/include/asm-arm/acpi/gen-iort.h | 33 ++++++++++++ 4 files changed, 148 insertions(+), 3 deletions(-)xen/arch/arm/acpi/Makefile +1
-0@@ -1,3 +1,4 @@ obj-y += lib.o obj-y += boot.init.o obj-y += ridmap.o +obj-y += gen-iort.oxen/arch/arm/acpi/gen-iort.c new file +0
-0
xen/arch/arm/acpi/gen-iort.c line 5
Quoted 5 lines
xen/arch/arm/acpi/gen-iort.c new file +5
-0@@ -0,0 +1,101 @@ +/* +* xen/arch/arm/acpi/gen-iort.c +* +* Code to generate IORT for hardware domain using the requesterId +* and deviceId map.
Here we go. You again mix upper case and lower case for the same name. To be honest, I would much prefer if you stick with deviceId. I.e first letter of the second word is uppercase.
xen/arch/arm/acpi/gen-iort.c line 7
Quoted 2 lines
xen/arch/arm/acpi/gen-iort.c new file +2
-0+* +* Manish Jaggi <[email protected]>
It is linaro.org.
Quoted 4 lines
xen/arch/arm/acpi/gen-iort.c new file +4
-0+* Copyright (c) 2018 Linaro. +* +* Ths program is free software; you can redistribute it and/or +* modify it under the terms and conditions of the GNU General Public
xen/arch/arm/acpi/gen-iort.c line 21
Quoted 10 lines
xen/arch/arm/acpi/gen-iort.c new file +10
-0+* License, version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <asm/acpi/ridmap.h> +#include <xen/acpi.h>
I am a bit surprised that only those 2 headers are necessary.
xen/arch/arm/acpi/gen-iort.c line 28
Quoted 7 lines
xen/arch/arm/acpi/gen-iort.c new file +7
-0+ +/* +* Size of hardware domains' IORT is calculated based on the number of +* mappings in the requesterid - deviceid mapping list. +* Return value 0: Success +*/ +int estimate_iort_size (size_t *iort_size)
__init.
xen/arch/arm/acpi/gen-iort.c line 32
Quoted 4 lines
xen/arch/arm/acpi/gen-iort.c new file +4
-0+{ +int count =0 ; +int pcirc_count =0 ; +int itsg_count =0 ;
All the 3 variables above should be unsigned int.
xen/arch/arm/acpi/gen-iort.c line 34
Quoted 2 lines
xen/arch/arm/acpi/gen-iort.c new file +2
-0+uint64_t *pcirc_array; +uint64_t *itsg_array;
Again, what is the rationale to store the address directly rather than "void *"? This would avoid the cast in the code.
xen/arch/arm/acpi/gen-iort.c line 35
Quoted 1 line
xen/arch/arm/acpi/gen-iort.c new file +1
-0+struct rid_devid_map *rmap;
I am sorry but I still don't see any comment about my comment on the previous version. For reminder:
"A bit more documention of this function would be appreciated. For instance, the rationale between browsing the list twice for allocation.
I actually do think this might be avoidable by storing a bit more information from the IORT. From the table you can easily deduced the number of root complex and ITS group. They could be store with the rest of information."
xen/arch/arm/acpi/gen-iort.c line 46
Quoted 11 lines
xen/arch/arm/acpi/gen-iort.c new file +11
-0+ +list_for_each_entry (rmap, &rid_devid_list, entry) + count++; + + pcirc_array =xzalloc_bytes (sizeof (uint64_t )*count); +if ( !pcirc_array ) +return -ENOMEM ; + + itsg_array =xzalloc_bytes (sizeof (uint64_t )*count); +if ( !itsg_array ) +return -ENOMEM ;
If the allocation fail, you will leak pcirc_array.
xen/arch/arm/acpi/gen-iort.c line 50
Quoted 4 lines
xen/arch/arm/acpi/gen-iort.c new file +4
-0+ +list_for_each_entry (rmap, &rid_devid_list, entry) + { +int i =0 ;
unsigned.
Quoted 17 lines
xen/arch/arm/acpi/gen-iort.c new file +17
-0+ +for ( i =0 ; i <= pcirc_count; i++ ) + { +if ( pcirc_array[i] == (uint64_t ) rmap->pcirc_node ) +break ; +if ( i == pcirc_count ) + { + pcirc_array[i] = (uint64_t ) rmap->pcirc_node; + pcirc_count++; +break ; + } + } + +for ( i =0 ; i <= itsg_count; i++ ) + { +if ( itsg_array[i] == (uint64_t ) rmap->its_node ) +break ;
xen/arch/arm/acpi/gen-iort.c line 77
Quoted 10 lines
xen/arch/arm/acpi/gen-iort.c new file +10
-0+if ( i == itsg_count ) + { + itsg_array[i] = (uint64_t ) rmap->its_node; + itsg_count++; +break ; + } + } + } + +/* Size of IORT
Coding style.
xen/arch/arm/acpi/gen-iort.c line 87
Quoted 10 lines
xen/arch/arm/acpi/gen-iort.c new file +10
-0+* = Size of IORT Table Header + Size of PCIRC Header Nodes + +* Size of PCIRC nodes + Size of ITS Header nodes + Size of ITS Nodes +* + Size of idmap nodes +*/ + *iort_size =sizeof (struct acpi_table_iort ) + + pcirc_count*( (sizeof (struct acpi_iort_node )-1 ) + +sizeof (struct acpi_iort_root_complex ) ) + + itsg_count*( (sizeof (struct acpi_iort_node )-1 ) + +sizeof (struct acpi_iort_its_group ) ) + + count*(sizeof (struct acpi_iort_id_mapping ) );
Coding style in general:
- No space needed after ( in that cases
- Space before and after +*-
Quoted 27 lines
xen/arch/arm/acpi/gen-iort.c new file +14
-0+ +xfree (itsg_array); +xfree (pcirc_array); + +return 0 ; +} +/* +* Local variables: +* mode: C +* c-file-style: "BSD" +* c-basic-offset: 4 +* indent-tabs-mode: nil +* End: +*/ xen/arch/arm/domain_build.c +1
-0@@ -14,6 +14,7 @@#include <xen/acpi.h> #include <xen/warning.h> #include <acpi/actables.h> +#include <asm/acpi/gen-iort.h> #include <asm/device.h> #include <asm/setup.h> #include <asm/platform.h>
xen/arch/arm/domain_build.c static int acpi_create_fadt(struct domain *d, struct membank tbl_add[]) · line 1805
Quoted 5 lines
xen/arch/arm/domain_build.c +1
-1@@ -1801,7 +1802,7 @@ static int acpi_create_fadt(struct domain *d, struct membank tbl_add[])static int estimate_acpi_efi_size (struct domain *d,struct kernel_info *kinfo) { -size_t efi_size, acpi_size, madt_size; +size_t efi_size, acpi_size, table_size;
I am ok if you keep the renaming in that patch. But you should at least mention it in the commit message.
xen/include/asm-arm/acpi/gen-iort.h
Quoted 35 lines
xen/arch/arm/domain_build.c +11
-2u64 addr;struct acpi_table_rsdp *rsdp_tbl;struct acpi_table_header *table;@@ -1811,8 +1812,8 @@ static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo) acpi_size =ROUNDUP (sizeof (struct acpi_table_fadt ),8 ); acpi_size +=ROUNDUP (sizeof (struct acpi_table_stao ),8 ); - madt_size =gic_get_hwdom_madt_size (d); - acpi_size +=ROUNDUP (madt_size,8 ); + table_size =gic_get_hwdom_madt_size (d); + acpi_size +=ROUNDUP (table_size,8 ); addr =acpi_os_get_root_pointer ();if ( !addr )@@ -1842,6 +1843,15 @@ static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo)acpi_os_unmap_memory (table,sizeof (struct acpi_table_header )); acpi_size +=ROUNDUP (sizeof (struct acpi_table_rsdp ),8 ); + +if (estimate_iort_size (&table_size) ) + { +printk ("Unable to get hwdom iort size\n" ); +return -EINVAL ; + } + + acpi_size +=ROUNDUP (table_size,8 ); + d->arch.efi_acpi_len =PAGE_ALIGN (ROUNDUP (efi_size,8 ) +ROUNDUP (acpi_size,8 ));xen/include/asm-arm/acpi/gen-iort.h new file +0
-0
Is it worth it to have a separate header for gen-iort? How about using acpi.h?
Quoted 25 lines
xen/include/asm-arm/acpi/gen-iort.h new file +23
-0@@ -0,0 +1,33 @@ +/* +* xen/include/asm-arm/acpi/gen-iort.h +* +* Manish Jaggi <[email protected]> +* Copyright (c) 2018 Linaro. +* +* Ths program is free software; you can redistribute it and/or +* modify it under the terms and conditions of the GNU General Public +* License, version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#ifndef _ACPI_GEN_IORT_H +#define _ACPI_GEN_IORT_H + +/* +* Returns the size of hardware domains IORT +*/ +int estimate_iort_size (size_t *iort_size);
xen/include/asm-arm/acpi/gen-iort.h line 33
Quoted 10 lines
xen/include/asm-arm/acpi/gen-iort.h new file +10
-0+ +#endif +/* +* Local variables: +* mode: C +* c-file-style: "BSD" +* c-basic-offset: 4 +* indent-tabs-mode: nil +* End: +*/
Cheers,
Signature · 6 lines
Julien Grall _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [PATCH resend 02/13] acpi: arm: query estimated size of hardware domain's IORT.
Hi Julien,
Quoted 5 lines · Julien Grall
Title: Please drop the full stop.
On 03/13/2018 03:20 PM, [email protected] wrote:
...
Quoted 7 lines
Quoted 1 line
+ struct
rid_devid_map*rmap;I am sorry but I still don't see any comment about my comment on the previous version. For reminder:
"A bit more documention of this function would be appreciated. For instance, the rationale between browsing the list twice for allocation.
I actually do think this might be avoidable by storing a bit more information from the IORT. From the table you can easily deduced the number of root complex and ITS group.
That will still require parsing of all IORT nodes.
I am add one more api to return total mappings, which would basically return a counter which is updated when add_rid_deviceid_map is called. This would replace
+ list_for_each_entry(rmap, &rid_devid_list, entry) + count++;
+
Sounds good?
Quoted 2 lines
They could be store with the rest of information."
_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
PATCH RESEND 3/13 acpi: arm: Code to generate Hardware Domains IORT
In reply to [email protected]From: Manish Jaggi <[email protected]>
Structure of Hardware domain's (hwdom) IORT
hwdom's IORT will only have PCIRC nodes and ITS group nodes in the following order. SMMU nodes as they are hidden from hardware domain.
[IORT Header]
[ITS Group 1 ]
...
[ITS Group n ]
[PCIRC Node 1]
[PCIRC IDMAP entry 1]
...
[PCIRC IDMAP entry m]
...
[PCIRC Node p]
[PCIRC IDMAP entry 1]
...
[PCIRC IDMAP entry q]
...
*n,m,p are variable.
requesterid-deviceid mapping list (rid_devid_list) populated by parsing IORT is used to generate hwdom IORT.
As the rid_devid_list is populated from firmware IORT, IDMAP entry would have output references offsets based on firmware's IORT. It is required to fixup node offset of ITS Group Nodes in the PCIRC idmap (output_reference)
First write all the ITS group nodes in the hwdom's IORT. For this write_hwits_nodes is called, which parses the rid_devid_list and for each unique its_node in firmware IORT create a its_node in hwdom's IORT and also creates and entry in fwits_hwits_map.
fwits_hwits_map is a mapping between firmware IORT's its node and the node offset of the corresponding its_node stored in the hwdom's IORT.
This map can later be used to set output reference value in hwdom's pcirc node's idmap entries.
--- xen/arch/arm/acpi/gen-iort.c | 299 ++++++++++++++++++++++++++++++++++++ xen/arch/arm/domain_build.c | 35 +++++ xen/include/asm-arm/acpi.h | 1 + xen/include/asm-arm/acpi/gen-iort.h | 11 ++ 4 files changed, 346 insertions(+)
xen/arch/arm/acpi/gen-iort.c +299 -0
@@ -19,6 +19,305 @@#include <asm/acpi/ridmap.h> #include <xen/acpi.h> +#include <acpi/actables.h> + +/* +* Structure of Hardware domain's (hwdom) IORT +* ----------------------------------- +* +* hwdom's IORT will only have PCIRC nodes and ITS group nodes +* in the following order. +* +* [IORT Header] +* [ITS Group 1 ] +* ... +* [ITS Group N ] +* [PCIRC Node 1] +* [PCIRC IDMAP entry 1] +* ... +* [PCIRC IDMAP entry N] +* ... +* [PCIRC Node N] +* +* requesterid-deviceid mapping list (rid_devid_list) populated by parsing IORT +* is used to generate hwdom IORT. +* +* One of the challanges is to fixup node offset of ITS Group Nodes +* in the PCIRC idmap (output_reference) +* +* In rid_devid_map firmware IORT's ITS group node pointer in stored. +* +* We first write all the ITS group nodes in the hwdom's IORT. For this +* write_hwits_nodes is called, which parses the rid_devid_list and for +* each unique its_node in firmware IORT create a its_node in hwdom's IORT +* and also creates and entry in fwits_hwits_map. +* +* fwits_hwits_map is a mapping between firmware IORT's its node +* and the node offset of the corresponding its_node stored in the +* hwdom's IORT. +* +* This map can be later used to set output reference value in hwdom's +* pcirc node's idmap entries. +* +*/ + +/* +* Stores the mapping between firmware tables its group node +* to the offset of the equivalent its node to be stored in +* hwdom's IORT. +*/ +struct fwits_hwits_map +{ +struct acpi_iort_node *fwits_node; +unsigned int hwitsnode_offset; +struct list_head entry; +}; + +LIST_HEAD (fwits_hwits_list); + +/* +* is_uniq_fwits_node +* +* returns 1 - if fwits_node is not already in the its_map_list +* 0 - if it is present already +* +* fwits_node - ITS Node pointer in Firmware IORT +* offset - offset of the equivalent its node to be stored in +* hwdom's IORT +*/ +static int is_uniq_fwits_node (struct acpi_iort_node *fwits_node, +unsigned int offset) +{ +struct fwits_hwits_map *map; + +list_for_each_entry (map, &fwits_hwits_list, entry) + { +if ( map->fwits_node == fwits_node ) +return 0 ; + } + + map = xzalloc(struct fwits_hwits_map); +if ( !map ) +return -ENOMEM ; + + map->fwits_node = fwits_node; + map->hwitsnode_offset = offset; +list_add_tail (&map->entry, &fwits_hwits_list); + +return 1 ; +} + +/* +* Returns the offset of corresponding its node to fwits_node +* written in hwdom's IORT. +* +* This function would be used when write hwdoms pcirc nodes' idmap +* entries. +*/ +static +unsigned int hwitsnode_offset_from_map (struct acpi_iort_node *fwits_node) +{ +struct fwits_hwits_map *map; + +list_for_each_entry (map, &fwits_hwits_list, entry) + { +if ( map->fwits_node == fwits_node ) +return map->hwitsnode_offset; + } + +return 0 ; +} + +static void write_hwits_nodes (u8 *iort,unsigned int *offset, +unsigned int *num_nodes) +{ +struct rid_devid_map *rmap; +unsigned int of = *offset; +int n =0 ; + +/* +* rid_devid_list is iterated to get unique its group nodes +* Each unique ITS group node is written in hardware domains IORT +* by using some values from the firmware ITS group node. +*/ +list_for_each_entry (rmap, &rid_devid_list, entry) + { +struct acpi_iort_node *node; +struct acpi_iort_its_group *grp; +struct acpi_iort_its_group *fw_grp; + +/* save its_node_offset_map in a list uniquely */ +if (is_uniq_fwits_node (rmap->its_node, of) ==1 ) + { + node = (struct acpi_iort_node *) &iort[of]; + grp = (struct acpi_iort_its_group *)(&node->node_data); + + node->type =ACPI_IORT_NODE_ITS_GROUP ; + node->length =sizeof (struct acpi_iort_node ) + +sizeof (struct acpi_iort_its_group ) - +sizeof (node->node_data); + + node->revision = rmap->its_node->revision; + node->reserved =0 ; + node->mapping_count =0 ; + node->mapping_offset=0 ; + + fw_grp = (struct acpi_iort_its_group *)(&rmap->its_node->node_data); + +/* Copy its_count and identifiers from firmware iort's its_node */ + grp->its_count = fw_grp->its_count; + grp->identifiers[0 ] = fw_grp->identifiers[0 ]; + + of += node->length; + n++; + } + } + *offset = of; + *num_nodes = n; +} + +static void write_hwpcirc_nodes (u8 *iort,unsigned int *pos, +unsigned int *num_nodes) +{ +struct acpi_iort_node *opcirc_node, *pcirc_node; +struct acpi_iort_node *hwdom_pcirc_node =NULL ; +struct rid_devid_map *rmap; +struct acpi_iort_id_mapping *idmap; +int num_idmap =0 , n =0 ; +unsigned int old_pos = *pos; + + opcirc_node =NULL ; +/* Iterate rid_map_devid list */ +list_for_each_entry (rmap, &rid_devid_list, entry) + { +struct acpi_iort_root_complex *rc; +struct acpi_iort_root_complex *rc_fw; +int add_node =0 ; + + pcirc_node = rmap->pcirc_node; + +if ( opcirc_node ==NULL )/* First entry */ + { + add_node =1 ; + } +else if ( opcirc_node != pcirc_node )/* another pci_rc_node found*/ + { +/* All the idmaps of a pcirc are written, now update node info*/ + hwdom_pcirc_node->length = num_idmap * +sizeof (struct acpi_iort_id_mapping ) + +sizeof (struct acpi_iort_node ) + +sizeof (struct acpi_iort_root_complex ) - +sizeof (pcirc_node->node_data); + + hwdom_pcirc_node->mapping_count = num_idmap; + hwdom_pcirc_node->mapping_offset =sizeof (struct acpi_iort_node ) + +sizeof (struct acpi_iort_root_complex ) - +sizeof (pcirc_node->node_data); + old_pos += hwdom_pcirc_node->length; + add_node =1 ; + } + +if ( add_node )/* create the pcirc node */ + { + opcirc_node = pcirc_node; + hwdom_pcirc_node = (struct acpi_iort_node *)&iort[old_pos]; + hwdom_pcirc_node->type =ACPI_IORT_NODE_PCI_ROOT_COMPLEX ; + hwdom_pcirc_node->mapping_offset =sizeof (struct acpi_iort_node ) + +sizeof (struct acpi_iort_root_complex ) - +sizeof (hwdom_pcirc_node->node_data); + + rc = (struct acpi_iort_root_complex *) + &hwdom_pcirc_node->node_data; + + rc_fw = (struct acpi_iort_root_complex *) + &pcirc_node->node_data; + + rc->pci_segment_number = rc_fw->pci_segment_number; + rc->ats_attribute = rc_fw->ats_attribute; + rc->memory_properties = rc_fw->memory_properties; + + idmap = ACPI_ADD_PTR(struct acpi_iort_id_mapping, + hwdom_pcirc_node, + hwdom_pcirc_node->mapping_offset); + n++; + num_idmap =0 ; + } + + idmap->input_base = rmap->idmap.input_base; + idmap->id_count = rmap->idmap.id_count; + idmap->output_base = rmap->idmap.output_base; + idmap->output_reference =hwitsnode_offset_from_map (rmap->its_node); +BUG_ON (!idmap->output_reference); + + idmap->flags =0 ; + idmap++; + num_idmap++; + } + +if ( hwdom_pcirc_node )/* if no further PCIRC nodes found */ + { +/* All the idmaps of a pcirc are written, now update node info*/ + hwdom_pcirc_node->length = num_idmap * +sizeof (struct acpi_iort_id_mapping ) + +sizeof (struct acpi_iort_node ) + +sizeof (struct acpi_iort_root_complex )-1 ; + + hwdom_pcirc_node->mapping_count = num_idmap; + old_pos += hwdom_pcirc_node->length; + } + + *pos = old_pos; + *num_nodes = n; +} + +bool is_iort_available (void ) +{ +struct acpi_table_iort *iort; + +if (acpi_get_table (ACPI_SIG_IORT ,0 , + (struct acpi_table_header **)&iort) ) +return 0 ; + +return 1 ; +} + +int prepare_hwdom_iort (struct acpi_table_iort *hwdom_iort,unsigned int *iort_size) +{ +struct acpi_table_iort *fw_iort; +unsigned int num_nodes =0 ; +unsigned int pos; + + pos =sizeof (struct acpi_table_iort ); + +if (acpi_get_table (ACPI_SIG_IORT ,0 , + (struct acpi_table_header **)&fw_iort) ) + { +printk ("Failed to get IORT table\n" ); +return -ENODEV ; + } + +/* Write IORT header */ +ACPI_MEMCPY (hwdom_iort, fw_iort,sizeof (struct acpi_table_iort )); + hwdom_iort->node_offset = pos; + hwdom_iort->node_count =0 ; + +/* Write its group nodes */ +write_hwits_nodes ((u8 *)hwdom_iort, &pos, &num_nodes); + hwdom_iort->node_count = num_nodes; + +/* Write pcirc_nodes */ +write_hwpcirc_nodes ((u8 *)hwdom_iort, &pos, &num_nodes); + +/* Update IORT Size in IORT header */ + hwdom_iort->node_count += num_nodes; + hwdom_iort->header.length = pos; + hwdom_iort->header.checksum =acpi_tb_checksum ( +ACPI_CAST_PTR (u8, hwdom_iort), + pos); + *iort_size = hwdom_iort->header.length; + +return 0 ; +}/* * Size of hardware domains' IORT is calculated based on the number of
xen/arch/arm/domain_build.c +35 -0
@@ -1656,6 +1656,8 @@ static int acpi_create_xsdt(struct domain *d, struct membank tbl_add[]) ACPI_SIG_FADT, tbl_add[TBL_FADT].start);acpi_xsdt_modify_entry (xsdt->table_offset_entry, entry_count,ACPI_SIG_MADT , tbl_add[TBL_MADT ].start); +acpi_xsdt_modify_entry (xsdt->table_offset_entry, entry_count, +ACPI_SIG_IORT , tbl_add[TBL_IORT ].start); xsdt->table_offset_entry[entry_count] = tbl_add[TBL_STAO ].start; xsdt->header.length = table_size;
@@ -1706,6 +1708,35 @@ static int acpi_create_stao(struct domain *d, struct membank tbl_add[])return 0 ; } +static int acpi_create_iort (struct domain *d,struct membank tbl_add[]) +{ +struct acpi_table_iort *hwdom_table; +unsigned int size =0 ; + +if (is_iort_available () ) + { + tbl_add[TBL_IORT ].start = d->arch.efi_acpi_gpa + +acpi_get_table_offset (tbl_add,TBL_IORT ); + hwdom_table = d->arch.efi_acpi_table + +acpi_get_table_offset (tbl_add,TBL_IORT ); + +if (prepare_hwdom_iort (hwdom_table, &size) ) + { +printk ("Failed to write IORT table\n" ); +return -EINVAL ; + } + + tbl_add[TBL_IORT ].size = size; + } +else + { + tbl_add[TBL_IORT ].start =0 ; + tbl_add[TBL_IORT ].size =0 ; + } + +return 0 ; +} +static int acpi_create_madt (struct domain *d,struct membank tbl_add[]) {struct acpi_table_header *table =NULL ;
@@ -1901,6 +1932,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)if ( rc !=0 )return rc; + rc =acpi_create_iort (d, tbl_add); +if ( rc !=0 ) +return rc; + rc =acpi_create_xsdt (d, tbl_add);if ( rc !=0 )return rc;
xen/include/asm-arm/acpi.h +1 -0
@@ -36,6 +36,7 @@ typedef enum {TBL_FADT ,TBL_MADT ,TBL_STAO , +TBL_IORT ,TBL_XSDT ,TBL_RSDP , TBL_EFIT,
xen/include/asm-arm/acpi/gen-iort.h +11 -0
@@ -22,6 +22,17 @@*/ int estimate_iort_size (size_t *iort_size); +/* +* Checks if IORT is present in ACPI tables. +*/ +bool is_iort_available (void ); + +/* +* Prepares IORT in buffer hwdom_iort and updates iort_size +*/ +int prepare_hwdom_iort (struct acpi_table_iort *hwdom_iort, +unsigned int *iort_size); +#endif /* * Local variables:
Signature · 7 lines
2.14.1 _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [PATCH resend 03/13] acpi: arm: Code to generate Hardware Domains IORT
Hi Manish,
Quoted 74 lines · On 03/13/2018 03:20 PM, [email protected] wrote:
From: Manish Jaggi <[email protected]>
Structure of Hardware domain's (hwdom) IORT
hwdom's IORT will only have PCIRC nodes and ITS group nodes in the following order. SMMU nodes as they are hidden from hardware domain.
[IORT Header]
[ITS Group 1 ]
...
[ITS Group n ]
[PCIRC Node 1]
[PCIRC IDMAP entry 1]
...
[PCIRC IDMAP entry m]
...
[PCIRC Node p]
[PCIRC IDMAP entry 1]
...
[PCIRC IDMAP entry q]
...
*n,m,p are variable.requesterid-deviceid mapping list (
rid_devid_list) populated by parsing IORT is used to generate hwdom IORT.As the
rid_devid_listis populated from firmware IORT, IDMAP entry would have output references offsets based on firmware's IORT. It is required to fixup node offset of ITS Group Nodes in the PCIRC idmap (output_reference)First write all the ITS group nodes in the hwdom's IORT. For this
write_hwits_nodesis called, which parses therid_devid_listand for each uniqueits_nodein firmware IORT create aits_nodein hwdom's IORT and also creates and entry infwits_hwits_map.
fwits_hwits_mapis a mapping between firmware IORT's its node and the node offset of the correspondingits_nodestored in the hwdom's IORT.This map can later be used to set output reference value in hwdom's pcirc node's idmap entries.
Signed-off-by Manish Jaggi <[email protected]>--- xen/arch/arm/acpi/gen-iort.c | 299 ++++++++++++++++++++++++++++++++++++ xen/arch/arm/domain_build.c | 35 +++++ xen/include/asm-arm/acpi.h | 1 + xen/include/asm-arm/acpi/gen-iort.h | 11 ++ 4 files changed, 346 insertions(+)xen/arch/arm/acpi/gen-iort.c +14
-0@@ -19,6 +19,305 @@#include <asm/acpi/ridmap.h> #include <xen/acpi.h> +#include <acpi/actables.h> + +/* +* Structure of Hardware domain's (hwdom) IORT +* ----------------------------------- +* +* hwdom's IORT will only have PCIRC nodes and ITS group nodes +* in the following order. +* +* [IORT Header] +* [ITS Group 1 ] +* ... +* [ITS Group N ] +* [PCIRC Node 1]
xen/arch/arm/acpi/gen-iort.c line 45
Quoted 10 lines
xen/arch/arm/acpi/gen-iort.c +10
-0+* [PCIRC IDMAP entry 1] +* ... +* [PCIRC IDMAP entry N] +* ... +* [PCIRC Node N] +* +* requesterid-deviceid mapping list (rid_devid_list) populated by parsing IORT +* is used to generate hwdom IORT. +* +* One of the challanges is to fixup node offset of ITS Group Nodes
s/challanges/challenges/
Quoted 21 lines
xen/arch/arm/acpi/gen-iort.c +21
-0+* in the PCIRC idmap (output_reference) +* +* In rid_devid_map firmware IORT's ITS group node pointer in stored. +* +* We first write all the ITS group nodes in the hwdom's IORT. For this +* write_hwits_nodes is called, which parses the rid_devid_list and for +* each unique its_node in firmware IORT create a its_node in hwdom's IORT +* and also creates and entry in fwits_hwits_map. +* +* fwits_hwits_map is a mapping between firmware IORT's its node +* and the node offset of the corresponding its_node stored in the +* hwdom's IORT. +* +* This map can be later used to set output reference value in hwdom's +* pcirc node's idmap entries. +* +*/ + +/* +* Stores the mapping between firmware tables its group node +* to the offset of the equivalent its node to be stored in
xen/arch/arm/acpi/gen-iort.c line 76
Quoted 10 lines
xen/arch/arm/acpi/gen-iort.c +10
-0+* hwdom's IORT. +*/ +struct fwits_hwits_map +{ +struct acpi_iort_node *fwits_node; +unsigned int hwitsnode_offset; +struct list_head entry; +}; + +LIST_HEAD (fwits_hwits_list);
As said in the previous version, I think this should be static.
xen/arch/arm/acpi/gen-iort.c line 82
Quoted 6 lines
xen/arch/arm/acpi/gen-iort.c +6
-0+ +/* +* is_uniq_fwits_node +* +* returns 1 - if fwits_node is not already in the its_map_list +* 0 - if it is present already
It also returns -ENOMEM when you can't allocate memory.
xen/arch/arm/acpi/gen-iort.c line 88
Quoted 6 lines
xen/arch/arm/acpi/gen-iort.c +6
-0+* +* fwits_node - ITS Node pointer in Firmware IORT +* offset - offset of the equivalent its node to be stored in +* hwdom's IORT +*/ +static int is_uniq_fwits_node(struct acpi_iort_node *fwits_node,
The name is a bit odd given that you add the ITS node. On the previous version, I requested to document that behavior...
But you likely want to rename the function to add_fwits_node(...) or something similar.
xen/arch/arm/acpi/gen-iort.c line 99
Quoted 11 lines
xen/arch/arm/acpi/gen-iort.c +11
-0+ unsigned int offset) +{ +struct fwits_hwits_map *map; + +list_for_each_entry (map, &fwits_hwits_list, entry) + { +if ( map->fwits_node == fwits_node ) +return 0 ; + } + + map = xzalloc(struct fwits_hwits_map);
Where this memory is going to be freed?
Quoted 19 lines
xen/arch/arm/acpi/gen-iort.c +19
-0+if ( !map ) +return -ENOMEM ; + + map->fwits_node = fwits_node; + map->hwitsnode_offset = offset; +list_add_tail (&map->entry, &fwits_hwits_list); + +return 1 ; +} + +/* +* Returns the offset of corresponding its node to fwits_node +* written in hwdom's IORT. +* +* This function would be used when write hwdoms pcirc nodes' idmap +* entries. +*/ +static +unsigned int hwitsnode_offset_from_map (struct acpi_iort_node *fwits_node)
xen/arch/arm/acpi/gen-iort.c line 128
Quoted 10 lines
xen/arch/arm/acpi/gen-iort.c +10
-0+{ +struct fwits_hwits_map *map; + +list_for_each_entry (map, &fwits_hwits_list, entry) + { +if ( map->fwits_node == fwits_node ) +return map->hwitsnode_offset; + } + +return 0 ;
0 could never be a valid offset, right?
xen/arch/arm/acpi/gen-iort.c line 131
Quoted 3 lines
xen/arch/arm/acpi/gen-iort.c +3
-0+} + +static void write_hwits_nodes(u8 *iort, unsigned int *offset,
Please avoid using u* and use uint_* instead. I expect that you fix all of for the next version.
Here, I think you want to use void *.
xen/arch/arm/acpi/gen-iort.c line 135
Quoted 4 lines
xen/arch/arm/acpi/gen-iort.c +4
-0+ unsigned int *num_nodes) +{ +struct rid_devid_map *rmap; +unsigned int of = *offset;
Please name it off. This is clearer that it is an offset. But as I said on the previous version, why can't you just re-use offset?
Quoted 5 lines
xen/arch/arm/acpi/gen-iort.c +5
-0+int n =0 ; + +/* +* rid_devid_list is iterated to get unique its group nodes +* Each unique ITS group node is written in hardware domains IORT
xen/arch/arm/acpi/gen-iort.c line 150
Quoted 10 lines
xen/arch/arm/acpi/gen-iort.c +10
-0+* by using some values from the firmware ITS group node. +*/ +list_for_each_entry (rmap, &rid_devid_list, entry) + { +struct acpi_iort_node *node; +struct acpi_iort_its_group *grp; +struct acpi_iort_its_group *fw_grp; + +/* save its_node_offset_map in a list uniquely */ +if (is_uniq_fwits_node (rmap->its_node, of) ==1 )
If the function is returning -ENOMEM, then you will ignore the node without a warning. That's going to be a real pain to find out a ITS node is not present if that happen.
Here, you should propagate error if something wrong is going.
xen/arch/arm/acpi/gen-iort.c line 158
Quoted 8 lines
xen/arch/arm/acpi/gen-iort.c +8
-0+ { + node = (struct acpi_iort_node *) &iort[of]; + grp = (struct acpi_iort_its_group *)(&node->node_data); + + node->type =ACPI_IORT_NODE_ITS_GROUP ; + node->length =sizeof (struct acpi_iort_node ) + +sizeof (struct acpi_iort_its_group ) - +sizeof (node->node_data);
While the substraction is good, this is odd enough to warrant a comment. But likely But likely you want to provide macros for defining the length. This will clean a lot the code.
xen/arch/arm/acpi/gen-iort.c line 160
Quoted 2 lines
xen/arch/arm/acpi/gen-iort.c +2
-0+ + node->revision = rmap->its_node->revision;
I am not sure this is right. You rewrite the IORT based on a given revision. Imagine the host IORT get updated to a newer spec but not Xen. Then you would end up to have the wrong revision number here.
xen/arch/arm/acpi/gen-iort.c line 169
Quoted 9 lines
xen/arch/arm/acpi/gen-iort.c +9
-0+ node->reserved =0 ; + node->mapping_count =0 ; + node->mapping_offset=0 ; + + fw_grp = (struct acpi_iort_its_group *)(&rmap->its_node->node_data); + +/* Copy its_count and identifiers from firmware iort's its_node */ + grp->its_count = fw_grp->its_count; + grp->identifiers[0 ] = fw_grp->identifiers[0 ];
Hmmm, here you will only copy the first identifier. What if you have multiple one?
It would also be good that somewhere (maybe at the top of the file) that you rely on the number of ITS and identifiers for the hwdom is the same as the host.
Quoted 16 lines
xen/arch/arm/acpi/gen-iort.c +16
-0+ + of += node->length; + n++; + } + } + *offset = of; + *num_nodes = n; +} + +static void write_hwpcirc_nodes (u8 *iort,unsigned int *pos, +unsigned int *num_nodes) +{ +struct acpi_iort_node *opcirc_node, *pcirc_node; +struct acpi_iort_node *hwdom_pcirc_node =NULL ; +struct rid_devid_map *rmap; +struct acpi_iort_id_mapping *idmap;
xen/arch/arm/acpi/gen-iort.c line 195
Quoted 10 lines
xen/arch/arm/acpi/gen-iort.c +10
-0+int num_idmap =0 , n =0 ; +unsigned int old_pos = *pos; + + opcirc_node =NULL ; +/* Iterate rid_map_devid list */ +list_for_each_entry (rmap, &rid_devid_list, entry) + { +struct acpi_iort_root_complex *rc; +struct acpi_iort_root_complex *rc_fw; +int add_node =0 ;
This should be bool.
I am going to stop the review here because I feel I am just repeating all my comments from the first version and new ones. So please go through *all* my e-mails from the previous version, answer to my question, and respin it.
Cheers,
Signature · 6 lines
Julien Grall _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [PATCH resend 03/13] acpi: arm: Code to generate Hardware Domains IORT
Quoted 135 lines · Julien Grall
Hi Manish,
Quoted 81 lines · On 03/13/2018 03:20 PM, [email protected] wrote:
From: Manish Jaggi <[email protected]>
Structure of Hardware domain's (hwdom) IORT
hwdom's IORT will only have PCIRC nodes and ITS group nodes in the following order. SMMU nodes as they are hidden from hardware domain.
[IORT Header]
[ITS Group 1 ]
...
[ITS Group n ]
[PCIRC Node 1]
[PCIRC IDMAP entry 1]
...
[PCIRC IDMAP entry m]
...
[PCIRC Node p]
[PCIRC IDMAP entry 1]
...
[PCIRC IDMAP entry q]
...
*n,m,p are variable.requesterid-deviceid mapping list (
rid_devid_list) populated by parsing IORT is used to generate hwdom IORT.As the
rid_devid_listis populated from firmware IORT, IDMAP entry would have output references offsets based on firmware's IORT. It is required to fixup node offset of ITS Group Nodes in the PCIRC idmap (output_reference)First write all the ITS group nodes in the hwdom's IORT. For this
write_hwits_nodesis called, which parses therid_devid_listand for each uniqueits_nodein firmware IORT create aits_nodein hwdom's IORT and also creates and entry infwits_hwits_map.
fwits_hwits_mapis a mapping between firmware IORT's its node and the node offset of the correspondingits_nodestored in the hwdom's IORT.This map can later be used to set output reference value in hwdom's pcirc node's idmap entries.
Signed-off-by Manish Jaggi <[email protected]>---
xen/arch/arm/acpi/gen-iort.c | 299
++++++++++++++++++++++++++++++++++++
xen/arch/arm/domain_build.c | 35 +++++
xen/include/asm-arm/acpi.h | 1 +
xen/include/asm-arm/acpi/gen-iort.h| 11 ++4 files changed, 346 insertions(+)xen/arch/arm/acpi/gen-iort.c +21
-0@@ -19,6 +19,305 @@ #include <asm/acpi/ridmap.h> #include <xen/acpi.h> +#include <acpi/actables.h> + +/* +* Structure of Hardware domain's (hwdom) IORT +* ----------------------------------- +* +* hwdom's IORT will only have PCIRC nodes and ITS group nodes +* in the following order. +* +* [IORT Header] +* [ITS Group 1 ] +* ... +* [ITS Group N ] +* [PCIRC Node 1] +* [PCIRC IDMAP entry 1] +* ... +* [PCIRC IDMAP entry N] +* ... +* [PCIRC Node N] +* +* requesterid-deviceid mapping list (rid_devid_list) populated by Quoted 4 lines
parsing IORT
+ * is used to generate hwdom IORT.
+ *
+ * One of the challanges is to fixup node offset of ITS Group Nodess/challanges/challenges/
Quoted 22 lines
+ * in the PCIRC idmap (
output_reference)
+ *
+ * Inrid_devid_mapfirmware IORT's ITS group node pointer in stored.
+ *
+ * We first write all the ITS group nodes in the hwdom's IORT. For this
+ *write_hwits_nodesis called, which parses therid_devid_listand for
+ * each uniqueits_nodein firmware IORT create aits_nodein hwdom's IORT
+ * and also creates and entry infwits_hwits_map.
+ *
+ *fwits_hwits_mapis a mapping between firmware IORT's its node
+ * and the node offset of the correspondingits_nodestored in the
+ * hwdom's IORT.
+ *
+ * This map can be later used to set output reference value in hwdom's
+ * pcirc node's idmap entries.
+ *
+ */xen/arch/arm/acpi/gen-iort.c +4
-0+ +/* +* Stores the mapping between firmware tables its group node +* to the offset of the equivalent its node to be stored in xen/arch/arm/acpi/gen-iort.c line 76
Quoted 10 lines
xen/arch/arm/acpi/gen-iort.c +10
-0+* hwdom's IORT. +*/ +struct fwits_hwits_map +{ + struct acpi_iort_node *fwits_node; + unsigned int hwitsnode_offset; + struct list_head entry; +}; + +LIST_HEAD (fwits_hwits_list);As said in the previous version, I think this should be static.
xen/arch/arm/acpi/gen-iort.c line 82
Quoted 6 lines
xen/arch/arm/acpi/gen-iort.c +6
-0+ +/* +* is_uniq_fwits_node +* +* returns 1 - if fwits_node is not already in the its_map_list +* 0 - if it is present already It also returns
-ENOMEMwhen you can't allocate memory.
Quoted 8 lines
Quoted 6 lines
+ *
+ *fwits_node- ITS Node pointer in Firmware IORT
+ * offset - offset of the equivalent its node to be stored in
+ * hwdom's IORT
+ */
+static int is_uniq_fwits_node(structacpi_iort_node*fwits_node,The name is a bit odd given that you add the ITS node. On the previous version, I requested to document that behavior...
I think the name is quite appropriate. Also in this patch I have added description of the flow so this should be fairly intuitive. Could you please let me know the specific point you dont understand, I can explain that.
Quoted 2 lines
But you likely want to rename the function to
add_fwits_node(...)or something similar.
I think name is quite appropriate.
Quoted 15 lines
xen/arch/arm/acpi/gen-iort.c line 99
Quoted 12 lines
+ unsigned int offset)
xen/arch/arm/acpi/gen-iort.c +10
-0+{ + struct fwits_hwits_map *map; + + list_for_each_entry(map, &fwits_hwits_list, entry) + { + if ( map->fwits_node == fwits_node ) + return 0; + } + + map = xzalloc(struct fwits_hwits_map);Where this memory is going to be freed?
Since this list can be used multiple times even after creation of IORT for dom0, say thinking ahead for domUs.
Quoted 24 lines
Quoted 24 lines
+ if ( !map )
+ return-ENOMEM;xen/arch/arm/acpi/gen-iort.c +17
-0+ + map->fwits_node = fwits_node; + map->hwitsnode_offset = offset; + list_add_tail(&map->entry, &fwits_hwits_list); + + return 1; +} + +/* +* Returns the offset of corresponding its node to fwits_node +* written in hwdom's IORT. +* +* This function would be used when write hwdoms pcirc nodes' idmap +* entries. +*/ +static +unsigned int hwitsnode_offset_from_map(struct acpi_iort_node
*fwits_node)xen/arch/arm/acpi/gen-iort.c +4
-0+{ + struct fwits_hwits_map *map; + + list_for_each_entry(map, &fwits_hwits_list, entry)
Quoted 8 lines
Quoted 6 lines
+ {
+ if (map->fwits_node==fwits_node)
+ returnmap->hwitsnode_offset;
+ }
+
+ return 0;0 could never be a valid offset, right?
Yes
See a bug_on when it is used.
Quoted 7 lines
xen/arch/arm/acpi/gen-iort.c line 131
Quoted 4 lines
xen/arch/arm/acpi/gen-iort.c +3
-0+} + +static void write_hwits_nodes(u8 *iort, unsigned int *offset,Please avoid using u* and use uint_* instead. I expect that you fix all of for the next version.
Quoted 8 lines
Here, I think you want to use void *.
Quoted 4 lines
+ unsigned int
*num_nodes) +{
+ structrid_devid_map*rmap;
+ unsigned int of = *offset;Please name it off. This is clearer that it is an offset. But as I said on the previous version, why can't you just re-use offset?
I will change it to off, will not break anything.
Quoted 19 lines
Quoted 6 lines
+ int n = 0;
xen/arch/arm/acpi/gen-iort.c +4
-0+ + /* +* rid_devid_list is iterated to get unique its group nodes +* Each unique ITS group node is written in hardware domains IORT xen/arch/arm/acpi/gen-iort.c line 150
Quoted 10 lines
xen/arch/arm/acpi/gen-iort.c +10
-0+* by using some values from the firmware ITS group node. +*/ + list_for_each_entry(rmap, &rid_devid_list, entry) + { + struct acpi_iort_node *node; + struct acpi_iort_its_group *grp; + struct acpi_iort_its_group *fw_grp; + + /* save its_node_offset_map in a list uniquely */ + if ( is_uniq_fwits_node(rmap->its_node, of) == 1 )If the function is returning
-ENOMEM, then you will ignore the node without a warning. That's going to be a real pain to find out a ITS node is not present if that happen.
Quoted 1 line
Here, you should propagate error if something wrong is going.
ok.
Quoted 10 lines
Quoted 9 lines
+ {
+ node = (structacpi_iort_node*) &iort[of]; + grp = (structacpi_iort_its_group*)(&node->node_data); +
+node->type=ACPI_IORT_NODE_ITS_GROUP;
+node->length=sizeof(struct acpi_iort_node)+ +sizeof(struct acpi_iort_its_group)- +sizeof(node->node_data);
Quoted 6 lines
While the substraction is good, this is odd enough to warrant a comment. But likely But likely you want to provide macros for defining the length. This will clean a lot the code.
Quoted 2 lines
+
+node->revision=rmap->its_node->revision;I am not sure this is right. You rewrite the IORT based on a given revision. Imagine the host IORT get updated to a newer spec but not Xen.
Not sure if I follow your comment here.
Xen gets host IORT from firmware, how will it get updated?
Quoted 16 lines
Then you would end up to have the wrong revision number here.
Quoted 11 lines
+
node->reserved= 0;
+node->mapping_count= 0;
+ node->mapping_offset= 0;
+
+fw_grp= (structacpi_iort_its_group*)(&rmap->its_node->node_data);
+
+ /* Copyits_countand identifiers from firmware iort'sits_node*/
+grp->its_count=fw_grp->its_count;
+ grp->identifiers[0] = fw_grp->identifiers[0];Hmmm, here you will only copy the first identifier. What if you have multiple one?
Quoted 2 lines
It would also be good that somewhere (maybe at the top of the file) that you rely on the number of ITS and identifiers for the hwdom is the same as the host.
ok
Quoted 29 lines
Quoted 16 lines
xen/arch/arm/acpi/gen-iort.c +16
-0+ + of += node->length; + n++; + } + } + *offset = of; + *num_nodes = n; +} + +static void write_hwpcirc_nodes (u8 *iort,unsigned int *pos, + unsigned int *num_nodes) +{ + struct acpi_iort_node *opcirc_node, *pcirc_node; + struct acpi_iort_node *hwdom_pcirc_node = NULL; + struct rid_devid_map *rmap; + struct acpi_iort_id_mapping *idmap;xen/arch/arm/acpi/gen-iort.c line 195
Quoted 10 lines
xen/arch/arm/acpi/gen-iort.c +10
-0+ int num_idmap = 0, n = 0; + unsigned int old_pos = *pos; + + opcirc_node = NULL; + /* Iterate rid_map_devid list */ + list_for_each_entry(rmap, &rid_devid_list, entry) + { + struct acpi_iort_root_complex *rc; + struct acpi_iort_root_complex *rc_fw; + int add_node = 0;This should be bool.
Quoted 2 lines
I am going to stop the review here because I feel I am just repeating all my comments from the first version and new ones. So please go through *all* my e-mails from the previous version, answer to my question, and respin it.
Could you please have a look at other patches and if there is functionality related change that I need to make, i can add that in my next rev.
Quoted 2 lines
Cheers,
_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [PATCH resend 03/13] acpi: arm: Code to generate Hardware Domains IORT
Hi,
Quoted 9 lines · Manish Jaggi
Quoted 8 lines · Julien Grall
Quoted 6 lines · On 03/13/2018 03:20 PM, [email protected] wrote:
+ *
+ *fwits_node- ITS Node pointer in Firmware IORT
+ * offset - offset of the equivalent its node to be stored in
+ * hwdom's IORT
+ */
+static int is_uniq_fwits_node(structacpi_iort_node*fwits_node,
Quoted 3 lines
Quoted 1 line
The name is a bit odd given that you add the ITS node. On the previous version, I requested to document that behavior...
I think the name is quite appropriate. Also in this patch I have added description of the flow so this should be fairly intuitive. Could you please let me know the specific point you dont understand, I can explain that.
The fact that a function calling is_* will add the element to the list. An is_* function should only check the element is in the list.
So yes, it is not intuitive for me.
Quoted 3 lines
Quoted 2 lines
But you likely want to rename the function to
add_fwits_node(...)or something similar.I think name is quite appropriate.
See above.
Quoted 15 lines
Quoted 15 lines
xen/arch/arm/acpi/gen-iort.c line 99
Quoted 12 lines
+ unsigned int offset)
xen/arch/arm/acpi/gen-iort.c +10
-0+{ + struct fwits_hwits_map *map; + + list_for_each_entry(map, &fwits_hwits_list, entry) + { + if ( map->fwits_node == fwits_node ) + return 0; + } + + map = xzalloc(struct fwits_hwits_map);Where this memory is going to be freed?
Quoted 1 line
Since this list can be used multiple times even after creation of IORT for dom0, say thinking ahead for domUs.
IORT for DomU will not rely on the host firmware and will be created by the toolstack. It does not make sense to keep that around.
Quoted 32 lines
Quoted 24 lines
Quoted 24 lines
+ if ( !map )
+ return-ENOMEM;xen/arch/arm/acpi/gen-iort.c +17
-0+ + map->fwits_node = fwits_node; + map->hwitsnode_offset = offset; + list_add_tail(&map->entry, &fwits_hwits_list); + + return 1; +} + +/* +* Returns the offset of corresponding its node to fwits_node +* written in hwdom's IORT. +* +* This function would be used when write hwdoms pcirc nodes' idmap +* entries. +*/ +static +unsigned int hwitsnode_offset_from_map(struct acpi_iort_node
*fwits_node)xen/arch/arm/acpi/gen-iort.c +4
-0+{ + struct fwits_hwits_map *map; + + list_for_each_entry(map, &fwits_hwits_list, entry)Quoted 8 lines
Quoted 6 lines
+ {
+ if (map->fwits_node==fwits_node)
+ returnmap->hwitsnode_offset;
+ }
+
+ return 0;0 could never be a valid offset, right?
Quoted 2 lines
Yes
See abug_onwhen it is used.
I don't much care about the BUG_ON()... I was only checking what the spec says here.
But... you document the return really well on the previous function and here it is seems to be forgotten.
Quoted 9 lines
Quoted 9 lines
xen/arch/arm/acpi/gen-iort.c line 131
Quoted 4 lines
xen/arch/arm/acpi/gen-iort.c +3
-0+} + +static void write_hwits_nodes(u8 *iort, unsigned int *offset,Please avoid using u* and use uint_* instead. I expect that you fix all of for the next version.
Here, I think you want to use void *.
Quoted 7 lines
Quoted 6 lines
Quoted 4 lines
+ unsigned int
*num_nodes) +{
+ structrid_devid_map*rmap;
+ unsigned int of = *offset;Please name it off. This is clearer that it is an offset. But as I said on the previous version, why can't you just re-use offset?
I will change it to off, will not break anything.
It does not answer my question.
Quoted 31 lines
Quoted 19 lines
Quoted 6 lines
+ int n = 0;
xen/arch/arm/acpi/gen-iort.c +4
-0+ + /* +* rid_devid_list is iterated to get unique its group nodes +* Each unique ITS group node is written in hardware domains IORT xen/arch/arm/acpi/gen-iort.c line 150
Quoted 10 lines
xen/arch/arm/acpi/gen-iort.c +10
-0+* by using some values from the firmware ITS group node. +*/ + list_for_each_entry(rmap, &rid_devid_list, entry) + { + struct acpi_iort_node *node; + struct acpi_iort_its_group *grp; + struct acpi_iort_its_group *fw_grp; + + /* save its_node_offset_map in a list uniquely */ + if ( is_uniq_fwits_node(rmap->its_node, of) == 1 )If the function is returning
-ENOMEM, then you will ignore the node without a warning. That's going to be a real pain to find out a ITS node is not present if that happen.Quoted 1 line
Here, you should propagate error if something wrong is going.
ok.
Quoted 10 lines
Quoted 9 lines
+ {
+ node = (structacpi_iort_node*) &iort[of]; + grp = (structacpi_iort_its_group*)(&node->node_data); +
+node->type=ACPI_IORT_NODE_ITS_GROUP;
+node->length=sizeof(struct acpi_iort_node)+ +sizeof(struct acpi_iort_its_group)- +sizeof(node->node_data);
Quoted 8 lines
Quoted 6 lines
While the substraction is good, this is odd enough to warrant a comment. But likely But likely you want to provide macros for defining the length. This will clean a lot the code.
Quoted 2 lines
+
+node->revision=rmap->its_node->revision;I am not sure this is right. You rewrite the IORT based on a given revision. Imagine the host IORT get updated to a newer spec but not Xen.
Not sure if I follow your comment here.
Xen gets host IORT from firmware, how will it get updated?
The host IORT will be built on top of a revision X. For the hwdom IORT, at the moment, you are always building on top of revision 0.
While today X == 0, this may change in the future and will prevent proper booting.
Quoted 29 lines
Quoted 29 lines
Quoted 16 lines
xen/arch/arm/acpi/gen-iort.c +16
-0+ + of += node->length; + n++; + } + } + *offset = of; + *num_nodes = n; +} + +static void write_hwpcirc_nodes (u8 *iort,unsigned int *pos, + unsigned int *num_nodes) +{ + struct acpi_iort_node *opcirc_node, *pcirc_node; + struct acpi_iort_node *hwdom_pcirc_node = NULL; + struct rid_devid_map *rmap; + struct acpi_iort_id_mapping *idmap;xen/arch/arm/acpi/gen-iort.c line 195
Quoted 10 lines
xen/arch/arm/acpi/gen-iort.c +10
-0+ int num_idmap = 0, n = 0; + unsigned int old_pos = *pos; + + opcirc_node = NULL; + /* Iterate rid_map_devid list */ + list_for_each_entry(rmap, &rid_devid_list, entry) + { + struct acpi_iort_root_complex *rc; + struct acpi_iort_root_complex *rc_fw; + int add_node = 0;This should be bool.
Quoted 3 lines
Quoted 2 lines
I am going to stop the review here because I feel I am just repeating all my comments from the first version and new ones. So please go through *all* my e-mails from the previous version, answer to my question, and respin it.
Could you please have a look at other patches and if there is functionality related change that I need to make, i can add that in my next rev.
I am afraid I am not going to have time reviewing for the next couple of weeks.
Cheers,
Signature · 6 lines
Julien Grall _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
PATCH RESEND 4/13 acpi: arm: Copy fwnode / iommu_fwspec code from Linux 4.14
In reply to [email protected]From: Manish Jaggi <[email protected]>
fwnode is firmware device node object handle type definition. This can be used either for device tree node or ACPI table node. However in the context of this patchset it is used mainly for ACPI nodes.
iommu_fwspec defines set of opeations associated with fwnode.
This patch does not directly imports the code files from linux, rahter copies only the relavant parts of code required for Xen.
--- xen/drivers/passthrough/arm/iommu.c | 85 ++++++++++++++++++++++++ xen/include/asm-arm/device.h | 1 + xen/include/asm-arm/fwnode.h | 128 ++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/fwspec.h | 38 +++++++++++ 4 files changed, 252 insertions(+)
xen/drivers/passthrough/arm/iommu.c +85 -0
@@ -19,6 +19,8 @@#include <xen/iommu.h> #include <xen/device_tree.h> #include <asm/device.h> +#include <asm/fwnode.h> +#include <asm/fwspec.h> static const struct iommu_ops *iommu_ops;
@@ -73,3 +75,86 @@ int arch_iommu_populate_page_table(struct domain *d)/* The IOMMU shares the p2m with the CPU */ return -ENOSYS ; } + +/** +* fwnode_handle_put - Drop reference to a device node +* @fwnode: Pointer to the device node to drop the reference to. +* +* To be used when terminating device_for_each_child_node() iteration with +* break / return to prevent stale device node references being left behind +*/ +void fwnode_handle_put (struct fwnode_handle *fwnode) +{ +fwnode_call_void_op (fwnode, put); +} + +const struct iommu_ops *iommu_ops_from_fwnode (struct fwnode_handle *fwnode) +{ +return iommu_get_ops (); +} + +int iommu_fwspec_init (struct device *dev,struct fwnode_handle *iommu_fwnode, +const struct iommu_ops *ops) +{ +struct iommu_fwspec *fwspec = dev->iommu_fwspec; + +if ( fwspec ) +return ops == fwspec->ops ?0 : -EINVAL ; + + fwspec =xzalloc_bytes (sizeof (*fwspec)); +if ( !fwspec ) +return -ENOMEM ; +#if 0 +of_node_get (to_of_node (iommu_fwnode));/* TODO */ +#endif + fwspec->iommu_fwnode = iommu_fwnode; + fwspec->ops = ops; + dev->iommu_fwspec = fwspec; + +return 0 ; +} + +void iommu_fwspec_free (struct device *dev) +{ +struct iommu_fwspec *fwspec = dev->iommu_fwspec; + +if ( fwspec ) + { +fwnode_handle_put (fwspec->iommu_fwnode); +xfree (fwspec); + dev->iommu_fwspec =NULL ; + } +} + +int iommu_fwspec_add_ids (struct device *dev,u32 *ids,int num_ids) +{ +struct iommu_fwspec *fwspec_n; +struct iommu_fwspec *fwspec = dev->iommu_fwspec; +size_t size, size_n; +int i; + +if ( !fwspec ) +return -EINVAL ; + + size = offsetof(struct iommu_fwspec, ids[fwspec->num_ids]); + size_n = offsetof(struct iommu_fwspec, ids[fwspec->num_ids + num_ids]); +if ( size_n > size ) + { + fwspec_n =_xzalloc (size_n,sizeof (void *)); +if ( !fwspec_n ) +return -ENOMEM ; + +memcpy (fwspec_n, fwspec, size); +xfree (fwspec); + fwspec = fwspec_n; + } + +for ( i =0 ; i < num_ids; i++ ) + fwspec->ids[fwspec->num_ids + i] = ids[i]; + + fwspec->num_ids += num_ids; + dev->iommu_fwspec = fwspec; + +return 0 ; +} +
xen/include/asm-arm/device.h +1 -0
@@ -20,6 +20,7 @@ struct devicestruct dt_device_node *of_node;/* Used by drivers imported from Linux */ #endif struct dev_archdata archdata; +struct iommu_fwspec *iommu_fwspec; };typedef struct device device_t ;
xen/include/asm-arm/fwnode.h new file +128 -0
128 lines not on this page · raw message
xen/include/asm-arm/fwspec.h new file +38 -0
@@ -0,0 +1,38 @@ +/* +* +* Copyright (C) 2015, Intel Corporation +* Author: Rafael J. Wysocki <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* Xen Modifications: Manish Jaggi +*/ + +#ifndef _ASM_FWSPEC_H +#define _ASM_FWSPEC_H + +/** +* struct iommu_fwspec - per-device IOMMU instance data +* @ops: ops for this device's IOMMU +* @iommu_fwnode: firmware handle for this device's IOMMU +* @iommu_priv: IOMMU driver private data for this device +* @num_ids: number of associated device IDs +* @ids: IDs which this device may present to the IOMMU +*/ +struct iommu_fwspec { +const struct iommu_ops *ops; +struct fwnode_handle *iommu_fwnode; +void *iommu_priv; +unsigned int num_ids; +u32 ids[1 ]; +}; + +int iommu_fwspec_init (struct device *dev,struct fwnode_handle *iommu_fwnode, +const struct iommu_ops *ops); +void iommu_fwspec_free (struct device *dev); +int iommu_fwspec_add_ids (struct device *dev,u32 *ids,int num_ids); +const struct iommu_ops *iommu_ops_from_fwnode (struct fwnode_handle *fwnode); + +#endif
Signature · 7 lines
2.14.1 _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
PATCH RESEND 5/13 acpi: arm: Import acpi_iort.h verbatim from linux 4.14
In reply to [email protected]From: Manish Jaggi <[email protected]>
Import acpi_iort.h verbatim from linux 4.14
--- xen/include/asm-arm/acpi/acpi_iort.h | 57 ++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+)
xen/include/asm-arm/acpi/acpi_iort.h new file +57 -0
@@ -0,0 +1,57 @@ +/* +* Copyright (C) 2016, Semihalf +* Author: Tomasz Nowicki <[email protected]> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along with +* this program; if not, write to the Free Software Foundation, Inc., 59 Temple +* Place - Suite 330, Boston, MA 02111-1307 USA. +*/ + +#ifndef __ACPI_IORT_H__ +#define __ACPI_IORT_H__ + +#include <linux/acpi.h> +#include <linux/fwnode.h> +#include <linux/irqdomain.h> + +#define IORT_IRQ_MASK (irq) (irq & 0xffffffffULL) +#define IORT_IRQ_TRIGGER_MASK (irq) ((irq >> 32) & 0xffffffffULL) + +int iort_register_domain_token (int trans_id,struct fwnode_handle *fw_node); +void iort_deregister_domain_token (int trans_id); +struct fwnode_handle *iort_find_domain_token (int trans_id); +#ifdef CONFIG_ACPI_IORT +void acpi_iort_init (void ); +u32 iort_msi_map_rid (struct device *dev,u32 req_id); +struct irq_domain *iort_get_device_domain (struct device *dev,u32 req_id); +void acpi_configure_pmsi_domain (struct device *dev); +int iort_pmsi_get_dev_id (struct device *dev,u32 *dev_id); +/* IOMMU interface */ +void iort_dma_setup (struct device *dev,u64 *dma_addr,u64 *size); +const struct iommu_ops *iort_iommu_configure (struct device *dev); +#else +static inline void acpi_iort_init (void ) { } +static inline u32 iort_msi_map_rid (struct device *dev,u32 req_id) +{return req_id; } +static inline struct irq_domain *iort_get_device_domain (struct device *dev, +u32 req_id) +{return NULL ; } +static inline void acpi_configure_pmsi_domain (struct device *dev) { } +/* IOMMU interface */ +static inline void iort_dma_setup (struct device *dev,u64 *dma_addr, +u64 *size) { } +static inline +const struct iommu_ops *iort_iommu_configure (struct device *dev) +{return NULL ; } +#endif + +#endif /* __ACPI_IORT_H__ */
Signature · 7 lines
2.14.1 _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
PATCH RESEND 6/13 acpi: arm: Update acpi_iort.h with xen specific changes
In reply to [email protected]From: Manish Jaggi <[email protected]>
Remove the parts of acpi_iort.h which are not required for Xen.
--- xen/include/asm-arm/acpi/acpi_iort.h | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
xen/include/asm-arm/acpi/acpi_iort.h +2 -8
@@ -19,18 +19,13 @@#ifndef __ACPI_IORT_H__#define __ACPI_IORT_H__ -#include <linux/acpi.h> -#include <linux/fwnode.h> -#include <linux/irqdomain.h> +#include <asm/device.h> +#include <xen/acpi.h> #define IORT_IRQ_MASK (irq) (irq & 0xffffffffULL)#define IORT_IRQ_TRIGGER_MASK (irq) ((irq >> 32) & 0xffffffffULL) -int iort_register_domain_token (int trans_id,struct fwnode_handle *fw_node); -void iort_deregister_domain_token (int trans_id); -struct fwnode_handle *iort_find_domain_token (int trans_id);#ifdef CONFIG_ACPI_IORT -void acpi_iort_init (void );u32 iort_msi_map_rid (struct device *dev,u32 req_id);struct irq_domain *iort_get_device_domain (struct device *dev,u32 req_id);void acpi_configure_pmsi_domain (struct device *dev);
@@ -39,7 +34,6 @@ int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);void iort_dma_setup (struct device *dev,u64 *dma_addr,u64 *size);const struct iommu_ops *iort_iommu_configure (struct device *dev);#else -static inline void acpi_iort_init (void ) { }static inline u32 iort_msi_map_rid (struct device *dev,u32 req_id) {return req_id; } static inline struct irq_domain *iort_get_device_domain(struct device *dev,
Signature · 7 lines
2.14.1 _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
PATCH RESEND 7/13 arm: Adding ACPI_IORT in arm Kconfig
In reply to [email protected]From: Manish Jaggi <[email protected]>
--- xen/arch/arm/Kconfig | 4 ++++ 1 file changed, 4 insertions(+)
xen/arch/arm/Kconfig +4 -0
@@ -59,6 +59,10 @@ config SBSA_VUART_CONSOLE endmenu +config ACPI_IORT + depends on ACPI + def_bool y + menu "ARM errata workaround via the alternative framework" depends on HAS_ALTERNATIVE
Signature · 7 lines
2.14.1 _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
PATCH RESEND 8/13 asm: arm: pci: Fix the #include label in asm-arm/pci.h
In reply to [email protected]From: Manish Jaggi <[email protected]>
asm-arm/pci.h has an incorrect #ifndef label.
Fixing it to ARM
--- xen/include/asm-arm/pci.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
xen/include/asm-arm/pci.h +3 -3
@@ -1,7 +1,7 @@ -#ifndef __X86_PCI_H__ -#define __X86_PCI_H__ +#ifndef __ASM_ARM_PCI_H__ +#define __ASM_ARM_PCI_H__struct arch_pci_dev { }; -#endif /* __X86_PCI_H__ */ +#endif /* __ASM_ARM_PCI_H__ */
Signature · 7 lines
2.14.1 _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
PATCH RESEND 9/13 asm: arm: to_pci_dev
In reply to [email protected]From: Manish Jaggi <[email protected]>
to_pci_dev for ARM was todo till now.
Provide definition for this macro.
--- xen/drivers/passthrough/arm/smmu.c | 3 ++- xen/include/asm-arm/pci.h | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-)
xen/drivers/passthrough/arm/smmu.c +2 -1
@@ -46,10 +46,12 @@#include <xen/rbtree.h> #include <xen/sched.h> #include <xen/sizes.h> +#include <xen/pci.h> #include <asm/atomic.h> #include <asm/device.h> #include <asm/io.h> #include <asm/platform.h> +#include <asm/pci.h> /* Xen: The below defines are redefined within the file. Undef it */ #undef SCTLR_AFE
@@ -181,7 +183,6 @@ static void __iomem *devm_ioremap_resource(struct device *dev,* Xen: PCI functions * TODO: It should be implemented when PCI will be supported */ -#define to_pci_dev (dev) (NULL) static inline int pci_for_each_dma_alias(struct pci_dev *pdev, int (*fn) (struct pci_dev *pdev, u16 alias, void *data),
xen/include/asm-arm/pci.h +6 -0
@@ -2,6 +2,12 @@#define __ASM_ARM_PCI_H__struct arch_pci_dev { +struct device dev; }; +#define to_pci_dev (d) container_of( \ + container_of(d, struct arch_pci_dev, dev), \ + struct pci_dev,\ + arch\ + )#endif /* __ASM_ARM_PCI_H__ */
Signature · 7 lines
2.14.1 _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
PATCH RESEND 10/13 asm: arm: add dev_is_pci
In reply to [email protected]From: Manish Jaggi <[email protected]>
dev_is_pci for ARM was todo till now.
Provide definition for this macro.
--- xen/include/asm-arm/device.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
xen/include/asm-arm/device.h +2 -2
@@ -6,6 +6,7 @@enum device_type {DEV_DT , +DEV_PCI , };struct dev_archdata {
@@ -27,8 +28,7 @@ typedef struct device device_t;#include <xen/device_tree.h> -/* TODO: Correctly implement dev_is_pci when PCI is supported on ARM */ -#define dev_is_pci (dev) ((void)(dev), 0) +#define dev_is_pci (dev) ((dev->type == DEV_PCI))#define dev_is_dt (dev) ((dev->type == DEV_DT)enum device_class
Signature · 7 lines
2.14.1 _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
PATCH RESEND 11/13 asm: arm: add pci_domain_nr
In reply to [email protected]From: Manish Jaggi <[email protected]>
Provide definition for this macro.
--- xen/include/xen/pci.h | 2 ++ 1 file changed, 2 insertions(+)
xen/include/xen/pci.h +2 -0
@@ -114,6 +114,8 @@ struct pci_dev {u64 vf_rlen[6 ]; }; +#define pci_domain_nr (pdev) pdev->seg +#define for_each_pdev (domain, pdev) \ list_for_each_entry(pdev, &(domain->arch.pdev_list), domain_list)
Signature · 7 lines
2.14.1 _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
PATCH RESEND 12/13 acpi: arm: Provide support for iort iommu configuration hooks
In reply to [email protected]From: Manish Jaggi <[email protected]>
This patch copies the basic code from linux (iort.c) required to parse IORT and
hooks for iommu configuration and initializes smmu device.
Provides a top level initcall acpi_iort_init which would call parse_iort (next patch) to parse and prepare the rid-devid and rid-sid maps.
This patch is dependent on next patch. The code is cleanly split into two patches
--- xen/arch/arm/acpi/Makefile | 1 + xen/arch/arm/acpi/iort.c | 401 +++++++++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/device.h | 12 +- 3 files changed, 413 insertions(+), 1 deletion(-)
xen/arch/arm/acpi/Makefile +1 -0
@@ -2,3 +2,4 @@ obj-y += lib.o obj-y += boot.init.o obj-y += ridmap.o obj-y += gen-iort.o +obj-y += iort.o
xen/arch/arm/acpi/iort.c new file +401 -0
401 lines not on this page · raw message
xen/include/asm-arm/device.h +11 -1
@@ -7,6 +7,7 @@ enum device_type {DEV_DT ,DEV_PCI , + DEV_ACPI, }; struct dev_archdata {
@@ -18,9 +19,18 @@ struct device {enum device_type type;#ifdef CONFIG_HAS_DEVICE_TREE -struct dt_device_node *of_node;/* Used by drivers imported from Linux */ +/* +* TODO: of_node is redundant by addition of fwnode. +* Will be cleaned in future, kept here for compatability +* with smmuv2 driver +*/ +struct dt_device_node *of_node; +#endif +#ifdef CONFIG_ACPI +void *acpi_node;#endif struct dev_archdata archdata; +struct fwnode_handle *fwnode;struct iommu_fwspec *iommu_fwspec; };
Signature · 7 lines
2.14.1 _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel
PATCH RESEND 13/13 Add code to parse IORT and prepare rid maps.
In reply to [email protected]From: Manish Jaggi <[email protected]>
This patch adds code to parse the pci_rc, idmaps and smmu nodes to
- prepare idmaps (rid-sid rid-devid)
While resolving the ipmap from pcirc->smmu->its some fixup is required this is done by fixup_rid_devid_map.
--- xen/arch/arm/acpi/iort.c | 207 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+)
xen/arch/arm/acpi/iort.c +207 -0
@@ -379,6 +379,212 @@ static inline struct fwnode_handle *acpi_alloc_fwnode_static(void)return fwnode; } +static inline bool __must_check IS_ERR_OR_NULL (__force const void *ptr) +{ +return unlikely (!ptr) ||IS_ERR_VALUE ((unsigned long )ptr); +} + +static inline bool is_acpi_static_node (const struct fwnode_handle *fwnode) +{ +return !IS_ERR_OR_NULL (fwnode) && + fwnode->ops == &acpi_static_fwnode_ops; +} + +static inline void acpi_free_fwnode_static (struct fwnode_handle *fwnode) +{ +if (WARN_ON (!is_acpi_static_node (fwnode))) +return ; + +xfree (fwnode); +} + +int fixup_rid_devid_map (struct acpi_iort_node *inode, +struct acpi_iort_id_mapping *pci_idmap, +struct acpi_iort_node *smmu_node) +{ + +unsigned int p_input_base, p_output_base, p_id_count; +unsigned int s_input_base, s_output_base, s_id_count; +unsigned int delta, i; +int ret =0 ; +struct acpi_iort_id_mapping *smmu_idmap =NULL ; +struct acpi_iort_node *its_node; +struct acpi_table_iort *iort; + + iort = (struct acpi_table_iort *) iort_table; + + p_input_base = pci_idmap->input_base; + p_output_base = pci_idmap->output_base; + p_id_count = pci_idmap->id_count; + + smmu_idmap = (struct acpi_iort_id_mapping *) ((u8 *) smmu_node + + smmu_node->mapping_offset); + +for ( i =0 ; i < smmu_node->mapping_count; i++, smmu_idmap++ ) + { + s_input_base = smmu_idmap->input_base; + s_output_base = smmu_idmap->output_base; + s_id_count = smmu_idmap->id_count; + its_node = ACPI_ADD_PTR(struct acpi_iort_node, iort, + smmu_idmap->output_reference); + +if (s_input_base <= p_output_base) + { +int count; +if (s_input_base + s_id_count < p_output_base) +continue ; + + delta = p_output_base - s_input_base; + count = s_input_base + s_id_count <= p_output_base + + p_id_count ? s_id_count - delta : p_id_count; + + ret =add_rid_devid_map (inode, its_node, + p_input_base, + s_output_base + delta, + count); +if (ret) +return ret; + } +else + { +int count; +if ( p_output_base + p_id_count < s_input_base ) +continue ; + + delta = s_input_base - p_output_base; + count = s_input_base + s_id_count < p_output_base + + p_id_count ? s_id_count : p_id_count - delta; + + ret =add_rid_devid_map (inode, its_node, + p_input_base + delta, + s_output_base, count); + +if ( ret ) +return ret; + } + } + +return ret; +} + +void parse_pcirc_node (struct acpi_iort_node *iort_node) +{ +int j, ret; +struct acpi_iort_id_mapping *idmap; +struct acpi_iort_node *onode; +struct acpi_table_iort *iort; + + iort = (struct acpi_table_iort *) iort_table; + idmap = ACPI_ADD_PTR(struct acpi_iort_id_mapping, iort_node, + iort_node->mapping_offset); + +/* iterate over idmap */ +for ( j =0 ; j < iort_node->mapping_count; j++ ) + { +struct acpi_iort_node *its_node; +struct acpi_iort_node *smmu_node; + onode = ACPI_ADD_PTR(struct acpi_iort_node, iort, + idmap->output_reference); + +switch (onode->type) + { +case ACPI_IORT_NODE_ITS_GROUP : + + its_node = ACPI_ADD_PTR(struct acpi_iort_node, iort, + idmap->output_reference); + + ret =add_rid_devid_map (iort_node, its_node, + idmap->input_base, + idmap->output_base, + idmap->id_count); +if ( ret ) + { +printk ("%s: add_rid_devid_map" +"failed with ret=%d \r\n" , + __func__, ret); +break ; + } +break ; + +case ACPI_IORT_NODE_SMMU : +case ACPI_IORT_NODE_SMMU_V3 : + + smmu_node = ACPI_ADD_PTR(struct acpi_iort_node, + iort_table, + idmap->output_reference); + + ret =add_rid_sid_map (iort_node, + smmu_node, + idmap->input_base, + idmap->output_base, + idmap->id_count); +if ( ret ) + { +printk ("%s: add_rid_sid_map" +"failed with ret=%d \r\n" , + __func__, ret); +break ; + } + + ret =fixup_rid_devid_map (iort_node, idmap, onode); +if ( ret ) + { +printk ("%s: fixup_rid_devid_map" +"failed with ret=%d \r\n" , + __func__, ret); +break ; + } +break ; + } + idmap++; + } +} + +void parse_smmu_node (struct acpi_iort_node *iort_node) +{ +int ret; +struct fwnode_handle *fwnode; + fwnode =acpi_alloc_fwnode_static (); +if ( !fwnode ) +return ; + +iort_set_fwnode (iort_node, fwnode); + ret =iort_add_smmu_platform_device (iort_node); +if ( ret ) +acpi_free_fwnode_static (fwnode); +} + +void parse_iort (void ) +{ +struct acpi_iort_node *iort_node, *iort_end; +struct acpi_table_iort *iort; +int i; + + iort = (struct acpi_table_iort *) iort_table; + iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort, + iort->node_offset); + iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort, + iort->header.length); + +for (i =0 ; i < iort->node_count; i++) + { +if ( iort_node >= iort_end ) + { +printk ("iort node pointer overflows, bad table\n" ); +return ; + } + +if ( iort_node->type ==ACPI_IORT_NODE_PCI_ROOT_COMPLEX ) +parse_pcirc_node (iort_node); +else if ( (iort_node->type ==ACPI_IORT_NODE_SMMU || + iort_node->type ==ACPI_IORT_NODE_SMMU_V3 ) ) +parse_smmu_node (iort_node); + + iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node, + iort_node->length); + } +} +int __init acpi_iort_init (void ) {acpi_status status;
@@ -396,6 +602,7 @@ int __init acpi_iort_init(void)return -1 ; } +parse_iort ();return 0 ; }__initcall (acpi_iort_init);
Signature · 7 lines
2.14.1 _______________________________________________ Xen-devel mailing list [email protected] https://lists.xenproject.org/mailman/listinfo/xen-devel