From patchwork Fri Jun 9 06:55:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Brown X-Patchwork-Id: 773686 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wkY4l06RPz9s8F for ; Fri, 9 Jun 2017 16:57:11 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Wymkw8cZ"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3wkY4k5Tk4zDqMF for ; Fri, 9 Jun 2017 16:57:10 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Wymkw8cZ"; dkim-atps=neutral X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from mail-pg0-x244.google.com (mail-pg0-x244.google.com [IPv6:2607:f8b0:400e:c05::244]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3wkY463KSvzDqN3 for ; Fri, 9 Jun 2017 16:56:38 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Wymkw8cZ"; dkim-atps=neutral Received: by mail-pg0-x244.google.com with SMTP id a70so6865295pge.0 for ; Thu, 08 Jun 2017 23:56:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=jfR3zfzdZ+WOBLVVv1vkmMTsxUKaRg4rYJwyMiJvZFQ=; b=Wymkw8cZlFVWymI99Mju+o73oSVMdEeMGODFrzPCkdxUfeQPrjMgr9XIK/5bJZ/m3a V3+dgnJ06Q9wKDzNkcP7vdIuuwNA5WDjBcVvlRreUUMQS0sMmhfu9ro1ZtucrN73xhAj B3teugKk8sQhVqc5WMIJb+6oEiqY7kUEdVx9Z/Liu5Cyq87k4UdTVg1IwgmEFVWpmG9Y KBvxv7d4VmAZ3uYXJ+mdwGxHMAaK8wNCDeirA3HOiy1QC4m/CTbscvgVLsRev4q952Aq MOqeg7EBvScYuhEMbYHCsK+nGmhJB6hxZfpst7W9PhzL7aqEy8CHMdwlOCXhFxbn7HuD dubw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=jfR3zfzdZ+WOBLVVv1vkmMTsxUKaRg4rYJwyMiJvZFQ=; b=NoPZSQkiVOVcwtPbyGWFIBTUVhmrjCuwHZt5uWSiUxe9/+ZglUbqXWEgcI/Y6mL1Xz EDd7DNJh5To4zDjyIGrSoMYVPP0+VdBE3agGIKDneZb6vhPZVh1b9PYaZG+lBN3Syj6z DKsA48D4D0xAuDa7YkWksITE2JALqHY6+qXGOYEm2hDAbMYjfUlmclYxwc+rEd2sIMif Czu+JTArehBlNypSgL4psuLDvkt5lDg3o40U7rKamcsSovg8/qO2dGmR+CzwodfuUgnM UVn5cAPWRuJ1sK01/TBBWK9mDFUZbpyeXtQC0dLKGQK0aJCUePhRKltYm7kAnrDaW7wJ v/Fg== X-Gm-Message-State: AODbwcCmbsHhL2yqQddqTpbXFIotVF6u9d71ecB+PeRXu4U7segVc5xC yAf7AVipDiwcRSuJ X-Received: by 10.84.212.137 with SMTP id e9mr39608107pli.115.1496991396616; Thu, 08 Jun 2017 23:56:36 -0700 (PDT) Received: from matt.ozlabs.ibm.com ([122.99.82.10]) by smtp.gmail.com with ESMTPSA id 81sm653535pge.46.2017.06.08.23.56.35 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Jun 2017 23:56:36 -0700 (PDT) From: Matt Brown To: skiboot@lists.ozlabs.org Date: Fri, 9 Jun 2017 16:55:40 +1000 Message-Id: <20170609065546.28963-4-matthew.brown.dev@gmail.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170609065546.28963-1-matthew.brown.dev@gmail.com> References: <20170609065546.28963-1-matthew.brown.dev@gmail.com> Subject: [Skiboot] [PATCH 04/10] core: Add generic XZ decoding function 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" This adds a simple function to decode any given XZ data area. The uncomp_len value is optional. Unfortunately we cannot calculate the uncompressed size of the XZ region before decompressing it. We can pass in the value if this is known, otherwise we allocate a region 10x the original size. Which may be significantly more than necessary. Signed-off-by: Matt Brown --- core/Makefile.inc | 2 +- core/decode-xz.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++ include/platform.h | 2 + 3 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 core/decode-xz.c diff --git a/core/Makefile.inc b/core/Makefile.inc index b09c30c..7f376bd 100644 --- a/core/Makefile.inc +++ b/core/Makefile.inc @@ -8,7 +8,7 @@ CORE_OBJS += pci-opal.o fast-reboot.o device.o exceptions.o trace.o affinity.o CORE_OBJS += vpd.o hostservices.o platform.o nvram.o nvram-format.o hmi.o CORE_OBJS += console-log.o ipmi.o time-utils.o pel.o pool.o errorlog.o CORE_OBJS += timer.o i2c.o rtc.o flash.o sensor.o ipmi-opal.o -CORE_OBJS += flash-subpartition.o bitmap.o buddy.o pci-quirk.o +CORE_OBJS += flash-subpartition.o bitmap.o buddy.o pci-quirk.o decode-xz.o ifeq ($(SKIBOOT_GCOV),1) CORE_OBJS += gcov-profiling.o diff --git a/core/decode-xz.c b/core/decode-xz.c new file mode 100644 index 0000000..4855e9b --- /dev/null +++ b/core/decode-xz.c @@ -0,0 +1,112 @@ +/* Copyright 2017 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + + +#define HEADER_MAGIC "\3757zXZ" +#define HEADER_MAGIC_SIZE 6 +/* + * decode_resource_xz + * Decodes any xz compressed memory region. + * + * @buf : pointer to memory region pointer + * @len : pointer to length of compressed region + * @uncomp_len: pointer to uncompressed length (optional) + * + * Returns 1 - successful or 0 - failed + */ +int decode_resource_xz(void **buf, size_t *len, size_t *uncomp_len) +{ + struct xz_dec *file; + struct xz_buf bufs; + char *input_header; + uint64_t *out_len; + enum xz_ret rc; + + uint8_t *r_buf = (uint8_t *)(*buf); + size_t r_len = *len; + + /* Check if input header matched XZ encoding signature */ + input_header = malloc(HEADER_MAGIC_SIZE); + if (!input_header) + return 0; + + memcpy(input_header, r_buf, HEADER_MAGIC_SIZE); + if (strcmp(input_header, HEADER_MAGIC)){ + prlog(PR_PRINTF, "DECODE: resource header magic does not match\ + xz format\n"); + free(input_header); + return 0; + } + + + /* Set up decoder */ + file = xz_dec_init(XZ_SINGLE, 0x100000); + + if (!file) { + /* Allocation failed */ + prlog(PR_PRINTF, "DECODE: xz_dec_init allocation error\n "); + free(input_header); + return 0; + } + + out_len = (uint64_t *)malloc(sizeof(uint64_t)); + if (!uncomp_len) + *out_len = (r_len) * 10; + else + *out_len = *uncomp_len; + + bufs.in = (const uint8_t *)r_buf; + bufs.in_pos = 0; + bufs.in_size = r_len; + bufs.out = (uint8_t *)local_alloc(0, *out_len, 0x10000); + bufs.out_pos = 0; + bufs.out_size = *(size_t *)out_len; + + if (bufs.out == NULL) { + /* Buffer allocation failed */ + prlog(PR_PRINTF, "DECODE: bufs.out allocation error\n "); + free(out_len); + free(input_header); + return 0; + } + + rc = xz_dec_run(file, &bufs); + + if (rc != XZ_STREAM_END) { + prlog(PR_ALERT, "DECODE: XZ decompression failed rc:%d\n", rc); + free(bufs.out); + free(out_len); + free(input_header); + return 0; + } + + /* Redefine resource base and size */ + *buf = (void *)bufs.out; + *len = (size_t)*out_len; + + prlog(PR_PRINTF, "DECODE: decode_resource_xz base: %p, len: %llu \ + remote: %p\n", bufs.out, *out_len, *buf); + + xz_dec_end(file); + free(out_len); + free(input_header); + + return 1; +} diff --git a/include/platform.h b/include/platform.h index e8848ca..0c41c35 100644 --- a/include/platform.h +++ b/include/platform.h @@ -234,4 +234,6 @@ extern void set_bmc_platform(const struct bmc_platform *bmc); extern struct cpu_job* start_async_load(struct boot_resources *r); +/* XZ decoding*/ +extern int decode_resource_xz(void **buf, size_t *len, size_t *uncomp_len); #endif /* __PLATFORM_H */