From patchwork Tue Oct 25 07:15:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stewart Smith X-Patchwork-Id: 686352 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3t34DS3SNQz9t2n for ; Tue, 25 Oct 2016 18:15:20 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3t34DS0QmJzDvkd for ; Tue, 25 Oct 2016 18:15:20 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3t34DN3YFyzDvkY for ; Tue, 25 Oct 2016 18:15:16 +1100 (AEDT) Received: from pps.filterd (m0098393.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.17/8.16.0.17) with SMTP id u9P7Ekcg033522 for ; Tue, 25 Oct 2016 03:15:14 -0400 Received: from e17.ny.us.ibm.com (e17.ny.us.ibm.com [129.33.205.207]) by mx0a-001b2d01.pphosted.com with ESMTP id 269y01sser-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 25 Oct 2016 03:15:14 -0400 Received: from localhost by e17.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 25 Oct 2016 03:15:13 -0400 Received: from d01dlp03.pok.ibm.com (9.56.250.168) by e17.ny.us.ibm.com (146.89.104.204) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 25 Oct 2016 03:15:11 -0400 Received: from b01cxnp23034.gho.pok.ibm.com (b01cxnp23034.gho.pok.ibm.com [9.57.198.29]) by d01dlp03.pok.ibm.com (Postfix) with ESMTP id 8353EC90048 for ; Tue, 25 Oct 2016 03:14:56 -0400 (EDT) Received: from b01ledav03.gho.pok.ibm.com (b01ledav003.gho.pok.ibm.com [9.57.199.108]) by b01cxnp23034.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u9P7FBTv11796926; Tue, 25 Oct 2016 07:15:11 GMT Received: from b01ledav03.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id EA5DDB2046; Tue, 25 Oct 2016 03:15:10 -0400 (EDT) Received: from birb.localdomain (unknown [9.83.7.67]) by b01ledav03.gho.pok.ibm.com (Postfix) with SMTP id CF80AB204D; Tue, 25 Oct 2016 03:15:09 -0400 (EDT) Received: from ka1.ozlabs.ibm.com (localhost.localdomain [127.0.0.1]) by birb.localdomain (Postfix) with ESMTP id AA7BC229DB2C; Tue, 25 Oct 2016 18:15:05 +1100 (AEDT) From: Stewart Smith To: skiboot@lists.ozlabs.org Date: Tue, 25 Oct 2016 18:15:00 +1100 X-Mailer: git-send-email 2.1.4 In-Reply-To: <1477379702-2376-1-git-send-email-stewart@linux.vnet.ibm.com> References: <1477379702-2376-1-git-send-email-stewart@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16102507-0040-0000-0000-000001AC84A5 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00005974; HX=3.00000240; KW=3.00000007; PH=3.00000004; SC=3.00000188; SDB=6.00772421; UDB=6.00370753; IPR=6.00549241; BA=6.00004831; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00013098; XFM=3.00000011; UTC=2016-10-25 07:15:13 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16102507-0041-0000-0000-0000059F93D9 Message-Id: <1477379702-2376-3-git-send-email-stewart@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-10-25_02:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1609300000 definitions=main-1610250121 Subject: [Skiboot] [PATCH 2/4] core/flash-subpartition: compute partition size from subpartition struct X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" From the subpartition structure, we have the ability to compute the full partition size. Do that. This lets us only read the amount of a subpartition that is valid and needed to be read, rather than having to read the entire thing. We continue the current behaviour of loading flash partitions though. Based-on-patch-by: Claudio Carvalho Signed-off-by: Stewart Smith --- core/flash-subpartition.c | 86 +++++++++++++++++++++++--------------- core/flash.c | 2 +- core/test/run-flash-subpartition.c | 6 ++- include/skiboot.h | 3 +- 4 files changed, 60 insertions(+), 37 deletions(-) diff --git a/core/flash-subpartition.c b/core/flash-subpartition.c index ba7f0a37829a..1e91c1bd06e6 100644 --- a/core/flash-subpartition.c +++ b/core/flash-subpartition.c @@ -31,16 +31,24 @@ struct flash_hostboot_header { struct flash_hostboot_toc toc[FLASH_HOSTBOOT_TOC_MAX_ENTRIES]; }; -int flash_subpart_info(void *part_header, uint32_t part_size, uint32_t subid, - uint32_t *offset, uint32_t *size) +int flash_subpart_info(void *part_header, uint32_t header_len, + uint32_t part_size, uint32_t *part_actual, + uint32_t subid, uint32_t *offset, uint32_t *size) { struct flash_hostboot_header *header; char eyecatcher[5]; - uint32_t i, ec; + uint32_t i, ec, o, s, toc; + bool subpart_found; - if (!part_header || !offset || !size) { - prlog(PR_ERR, "FLASH: invalid parameters: " - "ph %p of %p sz %p\n", part_header, offset, size); + if (!part_header || ( !offset && !size && !part_actual)) { + prlog(PR_ERR, "FLASH: invalid parameters: ph %p of %p sz %p " + "tsz %p\n", part_header, offset, size, part_actual); + return OPAL_PARAMETER; + } + + if (header_len < FLASH_SUBPART_HEADER_SIZE) { + prlog(PR_ERR, "FLASH: subpartition header too small 0x%x\n", + header_len); return OPAL_PARAMETER; } @@ -50,53 +58,63 @@ int flash_subpart_info(void *part_header, uint32_t part_size, uint32_t subid, i = be32_to_cpu(header->version); if (i != 1) { prerror("FLASH: flash subpartition TOC version unknown %i\n", i); - goto end; + return OPAL_RESOURCE; } /* NULL terminate eyecatcher */ strncpy(eyecatcher, header->eyecatcher, 4); eyecatcher[4] = '\0'; prlog(PR_DEBUG, "FLASH: flash subpartition eyecatcher %s\n", - eyecatcher); + eyecatcher); + subpart_found = false; + *part_actual = 0; + toc = sizeof(header->eyecatcher) + sizeof(header->version); for (i = 0; i < FLASH_HOSTBOOT_TOC_MAX_ENTRIES; i++) { ec = be32_to_cpu(header->toc[i].ec); - *offset = be32_to_cpu(header->toc[i].offset); - *size = be32_to_cpu(header->toc[i].size); + o = be32_to_cpu(header->toc[i].offset); + s = be32_to_cpu(header->toc[i].size); /* Check for null terminating entry */ - if (!ec && !*offset && !*size) { - prerror("FLASH: flash subpartition not found.\n"); - goto end; - } - - if (ec != subid) - continue; + if (!ec && !o && !s) + break; /* Sanity check the offset and size. */ - if (*offset + *size > part_size) { + if (o + s > part_size) { prerror("FLASH: flash subpartition too big: %i\n", i); - goto end; + return OPAL_RESOURCE; } - if (!*size) { + if (!s) { prerror("FLASH: flash subpartition zero size: %i\n", i); - goto end; + return OPAL_RESOURCE; } - if (*offset < FLASH_SUBPART_HEADER_SIZE) { - prerror("FLASH: flash subpartition " - "offset too small: %i\n", i); - goto end; + if (o < FLASH_SUBPART_HEADER_SIZE) { + prerror("FLASH: flash subpartition offset too small: " + "%i\n", i); + return OPAL_RESOURCE; } + /* + * Subpartitions content are different, but multiple toc entries + * may point to the same subpartition. + */ + if (ALIGN_UP(o + s, FLASH_SUBPART_HEADER_SIZE) > *part_actual) + *part_actual = ALIGN_UP(o + s, FLASH_SUBPART_HEADER_SIZE); - prlog(PR_DEBUG, "FLASH: flash found subpartition: " - "%i size: %i offset %i\n", - i, *size, *offset); - - return OPAL_SUCCESS; + if (ec == subid) { + if (offset) + *offset += o; + if (size) + *size = s; + if (!part_actual) + return OPAL_SUCCESS; + subpart_found = true; + } + toc += sizeof(struct flash_hostboot_toc); + } + if (!subpart_found && (offset || size)) { + prerror("FLASH: flash subpartition not found.\n"); + return OPAL_RESOURCE; } -end: - *size = 0; - *offset = 0; - return OPAL_RESOURCE; + return OPAL_SUCCESS; } diff --git a/core/flash.c b/core/flash.c index 4b7f4b38ea46..2299f45c814c 100644 --- a/core/flash.c +++ b/core/flash.c @@ -459,7 +459,7 @@ static int flash_find_subpartition(struct blocklevel_device *bl, uint32_t subid, goto end; } - rc = flash_subpart_info(header, partsize, subid, &offset, &size); + rc = flash_subpart_info(header, partsize, partsize, NULL, subid, &offset, &size); if (rc) goto end; diff --git a/core/test/run-flash-subpartition.c b/core/test/run-flash-subpartition.c index 169362ef72cb..419de887e050 100644 --- a/core/test/run-flash-subpartition.c +++ b/core/test/run-flash-subpartition.c @@ -35,20 +35,24 @@ char capp[4096] = {0x43, 0x41, 0x50, 0x50, 0x00, 0x00, 0x00, 0x01, int main(void) { int rc; + uint32_t part_actual; uint32_t offset; uint32_t size; uint32_t subids[] = { 0x100ea, 0x200ea, 0x200ef, 0x201ef, 0x100d3 }; for (int i = 0; i < sizeof(subids)/sizeof(uint32_t); i++) { offset = 0; - rc = flash_subpart_info(capp, 0x24000, subids[i], + rc = flash_subpart_info(capp, sizeof(capp), 0x24000, + &part_actual, subids[i], &offset, &size); printf("\nsubid %x\n", subids[i]); + printf("part_actual %u\n", part_actual); printf("offset %u\n", offset); printf("size %u\n", size); assert (rc == 0); assert (size == 36432); assert (offset == 4096); + assert (part_actual == 40960); } return 0; diff --git a/include/skiboot.h b/include/skiboot.h index 30149a1ac999..75c5207f9c1f 100644 --- a/include/skiboot.h +++ b/include/skiboot.h @@ -227,7 +227,8 @@ extern bool flash_reserve(void); extern void flash_release(void); #define FLASH_SUBPART_ALIGNMENT 0x1000 #define FLASH_SUBPART_HEADER_SIZE FLASH_SUBPART_ALIGNMENT -extern int flash_subpart_info(void *part_header, uint32_t part_size, +extern int flash_subpart_info(void *part_header, uint32_t header_len, + uint32_t part_size, uint32_t *part_actual, uint32_t subid, uint32_t *offset, uint32_t *size); /* NVRAM support */