Index: dev/pci/cz.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/cz.c,v retrieving revision 1.48 diff -u -r1.48 cz.c --- dev/pci/cz.c 10 Apr 2008 19:13:36 -0000 1.48 +++ dev/pci/cz.c 5 May 2008 13:29:05 -0000 @@ -87,6 +87,7 @@ #include #include #include +#include #include @@ -480,20 +481,26 @@ const struct zfirm_header *zfh; const struct zfirm_config *zfc; const struct zfirm_block *zfb, *zblocks; - const u_int8_t *cp; + const u_int8_t *cp, *data; const char *board; u_int32_t fid; int i, j, nconfigs, nblocks, nbytes; + blob_t blob; + size_t sz; - zfh = (const struct zfirm_header *) cycladesz_firmware; + sz = sizeof(cycladesz_firmware); + blob = blob_open(cycladesz_firmware, &sz); + zfh = blob_data(blob); + data = blob_data(blob); /* Find the config header. */ if (le32toh(zfh->zfh_configoff) & (sizeof(u_int32_t) - 1)) { aprint_error_dev(&cz->cz_dev, "bad ZFIRM config offset: 0x%x\n", le32toh(zfh->zfh_configoff)); + blob_close(blob); return (EIO); } - zfc = (const struct zfirm_config *)(cycladesz_firmware + + zfc = (const struct zfirm_config *)(data + le32toh(zfh->zfh_configoff)); nconfigs = le32toh(zfh->zfh_nconfig); @@ -505,11 +512,12 @@ } if (i == nconfigs) { aprint_error_dev(&cz->cz_dev, "unable to locate config header\n"); + blob_close(blob); return (EIO); } nblocks = le32toh(zfc->zfc_nblocks); - zblocks = (const struct zfirm_block *)(cycladesz_firmware + + zblocks = (const struct zfirm_block *)(data + le32toh(zfh->zfh_blockoff)); /* @@ -530,8 +538,7 @@ zfb = &zblocks[le32toh(zfc->zfc_blocklist[i])]; if (le32toh(zfb->zfb_type) == ZFB_TYPE_FPGA) { nbytes = le32toh(zfb->zfb_size); - cp = &cycladesz_firmware[ - le32toh(zfb->zfb_fileoff)]; + cp = &data[le32toh(zfb->zfb_fileoff)]; for (j = 0; j < nbytes; j++, cp++) { bus_space_write_1(cz->cz_win_st, cz->cz_win_sh, 0, *cp); @@ -555,8 +562,7 @@ const u_int32_t *lp; u_int32_t ro = le32toh(zfb->zfb_ramoff); nbytes = le32toh(zfb->zfb_size); - lp = (const u_int32_t *) - &cycladesz_firmware[le32toh(zfb->zfb_fileoff)]; + lp = (const u_int32_t *)&data[le32toh(zfb->zfb_fileoff)]; for (j = 0; j < nbytes; j += 4, lp++) { bus_space_write_4(cz->cz_win_st, cz->cz_win_sh, ro + j, le32toh(*lp)); @@ -588,6 +594,7 @@ */ aprint_error_dev(&cz->cz_dev, "MIPS halted; possible power supply " "problem\n"); + blob_close(blob); return (EIO); } else { #ifdef CZ_DEBUG @@ -608,6 +615,7 @@ aprint_error_dev(&cz->cz_dev, "FPGA ID 0x%08x, FPGA version 0x%08x\n", CZ_FPGA_READ(cz, FPGA_ID), CZ_FPGA_READ(cz, FPGA_VERSION)); + blob_close(blob); return (EIO); } @@ -655,6 +663,7 @@ aprint_normal("firmware %x.%x.%x\n", (fid >> 8) & 0xf, (fid >> 4) & 0xf, fid & 0xf); + blob_close(blob); return (0); } --- /dev/null 2008-05-05 14:28:57.000000000 +0100 +++ sys/blob.h 2008-05-04 17:44:45.000000000 +0100 @@ -0,0 +1,38 @@ +/* $NetBSD: lwpctl.h,v 1.4 2008/04/28 20:24:10 martin Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#if !defined(_SYS_BLOB_H_) +#define _SYS_BLOB_H_ + +typedef struct blob *blob_t; + +blob_t blob_open(const void *, size_t *); +void blob_close(blob_t); +void *blob_data(blob_t); + +#endif /* !_SYS_BLOB_H_ */ --- /dev/null 2008-05-05 14:28:57.000000000 +0100 +++ kern/kern_blob.c 2008-05-05 00:44:10.000000000 +0100 @@ -0,0 +1,113 @@ +/* $NetBSD: subr_debug.c,v 1.7 2008/04/30 20:20:53 ad Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Decompression of embedded firmware images. See dev/microcode/tools. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: subr_debug.c,v 1.7 2008/04/30 20:20:53 ad Exp $"); + +#include +#include +#include +#include +#include +#include + +#define SIG 0x424c4f42 + +struct blob { + size_t b_size; + uint8_t b_data[1]; +}; + +/* + * blob_open: + * + * Open a compressed image that resides in memory. 'sz' must + * contain the size of the containing memory area, and on return + * will contain the decompressed size of the image. The image + * is decompressed to a seperate memory area. + */ +blob_t +blob_open(const void *image, size_t *sz) +{ + const u_int32_t *p; + blob_t blob; + u_long dlen; + int rv; + + p = image; + + KASSERT(*sz > 0); /* basic sanity */ + KASSERT(p[0] == SIG); /* basic sanity */ + KASSERT(p[1] > 0); /* original length != 0 */ + KASSERT(p[2] > 0); /* compressed length != 0 */ + KASSERT(p[2] < *sz); /* compressed len < padded */ + + blob = kmem_alloc(p[1] + sizeof(*blob), KM_SLEEP); + blob->b_size = p[1] + sizeof(*blob); + dlen = p[1]; + rv = uncompress(blob->b_data, &dlen, (const uint8_t *)&p[3], p[2]); + if (rv != Z_OK) { + panic("blob_decompress: image corrupted?"); + } + + KASSERT(dlen == p[1]); + + *sz = (size_t)p[1]; + + return blob; +} + +/* + * blob_close: + * + * Done with a blob, free used resources. + */ +void +blob_close(blob_t blob) +{ + + kmem_free(blob, blob->b_size); +} + +/* + * blob_data: + * + * Return a pointer to the decompressed image. blob_open() must be + * called first, and cannot be used after the compressed image has + * been closed. + */ +void * +blob_data(blob_t blob) +{ + + return blob->b_data; +}