From patchwork Tue Jan 2 09:28:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manish Jaggi X-Patchwork-Id: 123097 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp8754982qgn; Tue, 2 Jan 2018 01:31:02 -0800 (PST) X-Google-Smtp-Source: ACJfBotcBiuJlPFISaQsI0FXqIsv73vJCJ7594qLYraxnoO4dG0ALR0oBKQ7oeZLUXHAPc/vXlHi X-Received: by 10.36.44.19 with SMTP id i19mr57352135iti.143.1514885462704; Tue, 02 Jan 2018 01:31:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1514885462; cv=none; d=google.com; s=arc-20160816; b=ODS0xPgm5+VlH4/uLvAwC6ktN0bW5ahQ2bBRj8NwyXIxMjC7RlodvPnj6c1UEBE8wR NGjqFvWSXn0SuSYGMsRzDgs1ReXYR729D6M2ITyZzLfMVqh3v+jPl3HkOW7cbZbRmBE0 UEEG9Xkn358XHRJ3hw8etj82PerTys1DH7B/NxcQD2f7I9F5rZdSPURsxUqbzyKlp9Md nCJIS3RJMhXD83mhfNFiLUdR1ETv4VQaejIqCb3t4/CrPGeWlNfRvET7wKOtkr/XClBF cdq1jSQTiCa8ouhvoOt2UnzXGCFB5ivYBWZFNNDRaQe414dfNFHGyscHO0stAQAaVZ+/ eqzg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:cc:references:in-reply-to:message-id:date:to :from:dkim-signature:arc-authentication-results; bh=1W5buUkC2xlZxgMl63SRWl6pLpKpvekTAZbqum53hIk=; b=ogaO3UJjLQDa/iAau+Cmo2vxgKuszh/2UTCXNb40qRA2PEWqspobRCz5pgjpPJxPne ntZyRmA2HK6RYwj3JmY+Gew10ZNlF4qNLMrCyWy7r80WTfP4bC8Yb/kaDV51t6GWAEtk jfX4Pil9K1142HWkSDfjJJJ8TccfT7GRShLss/+LHrZfzHURr62YbnfPbwdS92c4QaEe OhJntSj8GI6HlRz/88ZQrHA9Be8xdhks4dRqc2ul+/Wfslf3W4O/mGN/FB7miFexr59p Or44+wRRZwM6/7pr85ZD69qGzvSAWaYQnmWeb8pi1XbkoHg008a/vjUTlrdS4BQn5GXW dqCQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=Wu5XIcc1; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id n13si12767962ioc.62.2018.01.02.01.31.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 02 Jan 2018 01:31:02 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=Wu5XIcc1; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eWIsD-0002SA-Mi; Tue, 02 Jan 2018 09:28:41 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eWIsC-0002Rl-VQ for xen-devel@lists.xenproject.org; Tue, 02 Jan 2018 09:28:41 +0000 X-Inumbo-ID: 296ead3a-ef9f-11e7-b4a6-bc764e045a96 Received: from mail-pf0-x242.google.com (unknown [2607:f8b0:400e:c00::242]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id 296ead3a-ef9f-11e7-b4a6-bc764e045a96; Tue, 02 Jan 2018 10:27:33 +0100 (CET) Received: by mail-pf0-x242.google.com with SMTP id c204so25455901pfc.13 for ; Tue, 02 Jan 2018 01:28:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4KznkXKP3t2gdgLtkOpjefulVYHUYBh6Eys/vxpazQk=; b=Wu5XIcc1H05YFUAU3wIHJLDrIKHCfHif9jnkZDqJXVkSEKKD20rV5bwxfbTXNv6WpZ E24iIi9x+EJdTqJ2Oxn7x6ATVbGmZwtbDiOeb5CQievLgixFAxdFeQ6MwuxjjVgnM166 ykKRxSbNI18wgwA2wZdGyF9tyoY01yjrhZVSI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=4KznkXKP3t2gdgLtkOpjefulVYHUYBh6Eys/vxpazQk=; b=oX0KaGCFiF/jz42ITytC4mOA3aGqc33QWRDYAlWWkpqJZWPesS7ZgikgZnG67A/JGA 4PtT7Wvm9pa/gOl1GJafvY+ZyOqnJrVzBFaY+ZVWIggAAjWTFVsntfb+WfAxUgUjOZ8Q hZQRMnW8UCdQQOp4AMVl82Sap+bh9G3e4133mkO+bVVDwFV08F0lwV2ISNy9JPhXnhCx 1HZ+Uwxx13Py7VUNpg1TWVOLscZyUqsgmp4S56gPg5oqVnRcpdqK9n9hlxP35fyPCnSs n+MZTKMFmUlMkx4tSN0hC+xmcvP3G/oJdo1V/Ag53+jXHzVRx9I/d7W3Ot/3rFrgjqjb qJLw== X-Gm-Message-State: AKGB3mIVgRnovFHWZ/rOTORjui8ogaml2iS1zv8lFowigA4CjQQkaZvO +vBrxI6yOjioUXXUlp6X79IyV5JbGEQ= X-Received: by 10.98.144.141 with SMTP id q13mr45269583pfk.140.1514885318704; Tue, 02 Jan 2018 01:28:38 -0800 (PST) Received: from thunder-dev-box.domain.name ([111.93.218.67]) by smtp.gmail.com with ESMTPSA id e8sm22065207pgs.44.2018.01.02.01.28.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 02 Jan 2018 01:28:38 -0800 (PST) From: manish.jaggi@linaro.org To: xen-devel@lists.xenproject.org, julien.grall@linaro.org, sameer.goel@linaro.org, andre.przywara@linaro.org Date: Tue, 2 Jan 2018 14:58:01 +0530 Message-Id: <20180102092809.1841-4-manish.jaggi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180102092809.1841-1-manish.jaggi@linaro.org> References: <20180102092809.1841-1-manish.jaggi@linaro.org> Cc: Manish Jaggi , manish.jaggi@cavium.com Subject: [Xen-devel] [RFC 03/11] acpi: arm: Code to generate Hardware Domains IORT X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" From: Manish Jaggi Singed-off-by: Manish Jaggi --- xen/arch/arm/domain_build.c | 28 +++++ xen/drivers/acpi/arm/gen-iort.c | 253 +++++++++++++++++++++++++++++++++++++++- xen/include/acpi/gen-iort.h | 1 + xen/include/asm-arm/acpi.h | 1 + 4 files changed, 282 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index f5d5e3d271..9831943147 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -1654,6 +1654,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; @@ -1704,6 +1706,28 @@ 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; + + 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_iort(hwdom_table, &size) ) + { + printk("Failed to write IORT table\n"); + return -EINVAL; + } + printk("%s %d %d \r\n", __func__, __LINE__, size); + + tbl_add[TBL_IORT].size = size; + printk("%s %d %d \r\n", __func__, __LINE__, size); + return 0; +} + static int acpi_create_madt(struct domain *d, struct membank tbl_add[]) { struct acpi_table_header *table = NULL; @@ -1899,6 +1923,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; diff --git a/xen/drivers/acpi/arm/gen-iort.c b/xen/drivers/acpi/arm/gen-iort.c index 3fc32959c6..f368000753 100644 --- a/xen/drivers/acpi/arm/gen-iort.c +++ b/xen/drivers/acpi/arm/gen-iort.c @@ -21,6 +21,257 @@ #include #include +/* + * Structure of Hardware domain's IORT + * ----------------------------------- + * + * Below is the structure of the IORT which this code generates. + * + * [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 poplated by parsing IORT is used + * to create nodes and idmaps. + * We have one small problem, how to resolve the its grooup node offset from + * the firmware iort to the ones in hardware domains IORT. + * + * Since the ITS group node pointer stored with the rid-devid map is used + * to populate the ITS Group nodes in the hardware domains' IORT. + * We create another map to save the offset of the ITS group node written + * in the hardware domain IORT with the ITS node pointer in the firmware IORT. + * + * This offset is later used when writing pcirc idmaps output_reference. + */ +struct its_node_offset_map +{ + struct acpi_iort_node *its_node; + unsigned int offset; + struct list_head entry; +}; +struct list_head its_map_list; + +int set_its_node_offset(struct acpi_iort_node *its_node, unsigned int offset) +{ + struct its_node_offset_map *its_map; + list_for_each_entry(its_map, &its_map_list, entry) + { + if ( its_map->its_node == its_node ) + return 0; + } + + its_map = xzalloc(struct its_node_offset_map); + if ( !its_map ) + return -ENOMEM; + + its_map->its_node = its_node; + its_map->offset = offset; + list_add_tail(&its_map->entry, &its_map_list); + + return 0; +} +/* + * This method would be used in write_pcirc_nodes when writing idmaps + */ +unsigned int get_its_node_offset(struct acpi_iort_node *its_node) +{ + struct its_node_offset_map *its_map; + list_for_each_entry(its_map, &its_map_list, entry) + { + if ( its_map->its_node == its_node ) + return its_map->offset; + } + + return 0; +} + +void free_its_node_offset_list(void) +{ + + struct its_node_offset_map *its_map; + list_for_each_entry(its_map, &its_map_list, entry) + xfree(its_map); + + list_del(&its_map_list); +} + +void write_its_group(u8 *iort, unsigned int *offset, unsigned int *num_nodes) +{ + struct rid_deviceid_map *rmap; + unsigned int of = *offset; + int n=0; + INIT_LIST_HEAD(&its_map_list); + /* + * rid_deviceid_map_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_deviceid_map_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 ( !set_its_node_offset(rmap->its_node, of) ) + { + 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); + + grp->its_count = fw_grp->its_count; + grp->identifiers[0] = fw_grp->identifiers[0]; + + of += node->length; + n++; + } + } + *offset = of; + *num_nodes = n; +} + +/* It is assumed that rid_map_devid is sorted by pcirc_nodes */ +void write_pcirc_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_deviceid_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_deviceid_map_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 = get_its_node_offset(rmap->its_node); + 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; +} + +int prepare_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_its_group((u8*)hwdom_iort, &pos, &num_nodes); + hwdom_iort->node_count = num_nodes; + /* Write pcirc_nodes*/ + write_pcirc_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 = 0; /* TODO */ + + *iort_size = hwdom_iort->header.length; + + return 0; +} + /* * Size of hardware domains iort is calulcated based on the number of * mappings in the requesterId - deviceId mapping list. @@ -49,7 +300,7 @@ int estimate_iort_size(size_t *iort_size) { int i = 0; - for (i=0; i <= pcirc_count; i++) + for ( i=0; i <= pcirc_count; i++ ) { if ( pcirc_array[i] == (uint64_t)rmap->pcirc_node ) break; diff --git a/xen/include/acpi/gen-iort.h b/xen/include/acpi/gen-iort.h index 68e666fdce..4de31b7b9f 100644 --- a/xen/include/acpi/gen-iort.h +++ b/xen/include/acpi/gen-iort.h @@ -2,5 +2,6 @@ #define _GEN_IORT_H int estimate_iort_size(size_t *iort_size); +int prepare_iort(struct acpi_table_iort *hwdom_iort, unsigned int *iort_size); #endif diff --git a/xen/include/asm-arm/acpi.h b/xen/include/asm-arm/acpi.h index c183b6bb6e..f8b5254621 100644 --- a/xen/include/asm-arm/acpi.h +++ b/xen/include/asm-arm/acpi.h @@ -36,6 +36,7 @@ typedef enum { TBL_FADT, TBL_MADT, TBL_STAO, + TBL_IORT, TBL_XSDT, TBL_RSDP, TBL_EFIT,