summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ldr_raw.c
diff options
context:
space:
mode:
Diffstat (limited to 'cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ldr_raw.c')
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ldr_raw.c368
1 files changed, 368 insertions, 0 deletions
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ldr_raw.c b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ldr_raw.c
new file mode 100755
index 0000000..eaabf14
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ldr_raw.c
@@ -0,0 +1,368 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * RAW Program Loader File: cfe_ldr_raw.c
+ *
+ * This program reads raw binaries into memory.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR 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), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+#include "lib_types.h"
+#include "lib_string.h"
+#include "lib_queue.h"
+#include "lib_malloc.h"
+#include "lib_printf.h"
+
+#include "cfe_iocb.h"
+#include "cfe_device.h"
+#include "cfe_error.h"
+#include "cfe_devfuncs.h"
+
+#include "cfe.h"
+#include "cfe_fileops.h"
+
+#include "cfe_boot.h"
+#include "cfe_bootblock.h"
+
+#include "cfe_loader.h"
+
+/* *********************************************************************
+ * Externs
+ ********************************************************************* */
+
+int bcm63xx_cfe_rawload(cfe_loadargs_t *la);
+
+const cfe_loader_t rawloader = {
+ "raw",
+ bcm63xx_cfe_rawload,
+ 0};
+
+/* *********************************************************************
+ * cfe_findbootblock(la,fsctx,ref)
+ *
+ * Find the boot block on the specified device.
+ *
+ * Input parameters:
+ * la - loader args (to be filled in)
+ * ops - file operations
+ * ref - reference for open file handle
+ *
+ * Return value:
+ * 0 if ok
+ * else error code
+ ********************************************************************* */
+static int cfe_findbootblock(cfe_loadargs_t *la,
+ fileio_ctx_t *fsctx,
+ void *ref,
+ struct boot_block *bootblock)
+{
+ uint32_t checksum = 0;
+ uint32_t calcsum = 0;
+ uint32_t secsize = 0;
+ uint64_t secoffset = 0;
+ int res;
+ int curblk;
+
+ /*
+ * Search for the boot block. Stop when we find
+ * something with a matching checksum and magic
+ * number.
+ */
+
+ fs_seek(fsctx,ref,0,FILE_SEEK_BEGINNING);
+
+ for (curblk = 0; curblk < BOOT_BLOCK_MAXLOC; curblk++) {
+
+
+ /* Read a block */
+
+ res = fs_read(fsctx,ref,
+ (unsigned char *) bootblock,
+ sizeof(struct boot_block));
+
+ if (res != sizeof(struct boot_block)) {
+ return CFE_ERR_IOERR;
+ }
+
+ /* Verify magic number */
+
+#if defined(CONFIG_MIPS_BRCM)
+ continue;
+#else
+ if (bootblock->bb_magic != BOOT_MAGIC_NUMBER) {
+ continue;
+ }
+#endif
+
+ /* Extract fields from block */
+
+ checksum = ((uint32_t) (bootblock->bb_hdrinfo & BOOT_HDR_CHECKSUM_MASK));
+ bootblock->bb_hdrinfo &= ~BOOT_HDR_CHECKSUM_MASK;
+ secsize = ((uint32_t) (bootblock->bb_secsize & BOOT_SECSIZE_MASK));
+ secoffset = bootblock->bb_secstart;
+
+ /* Verify block's checksum */
+
+ CHECKSUM_BOOT_DATA(&(bootblock->bb_magic),BOOT_BLOCK_SIZE,&calcsum);
+
+ if (checksum == calcsum) {
+ break;
+ }
+ }
+
+ /*
+ * Okay, determine if we were successful.
+ */
+
+#if !defined(CONFIG_MIPS_BRCM)
+ if (bootblock->bb_magic != BOOT_MAGIC_NUMBER) {
+ return CFE_ERR_INVBOOTBLOCK;
+ }
+#endif
+
+ if (checksum != calcsum) {
+ return CFE_ERR_BBCHECKSUM;
+ }
+
+ /*
+ * If we get here, we had a valid boot block.
+ */
+
+ return 0;
+}
+
+
+/* *********************************************************************
+ * cfe_rawload(la)
+ *
+ * Read a raw (unformatted) boot file
+ *
+ * Input parameters:
+ * la - loader args
+ *
+ * Return value:
+ * 0 if ok, else error code
+ ********************************************************************* */
+int bcm63xx_cfe_rawload(cfe_loadargs_t *la)
+{
+ int res;
+ fileio_ctx_t *fsctx;
+ const fileio_dispatch_t *ops;
+ void *ref;
+ int ttlcopy = 0;
+ int findbb;
+ int devinfo;
+ struct boot_block bootblock;
+ uint8_t *ptr;
+ uint8_t *bootcode;
+#if !defined(CONFIG_MIPS_BRCM)
+ uint32_t checksum,calcsum;
+#endif
+ uint64_t secoffset = 0;
+ int32_t maxsize;
+ int amtcopy;
+ int thisamt;
+ uint32_t loadflags;
+ int onedot;
+
+ loadflags = la->la_flags;
+
+ /*
+ * Set starting address and maximum size. You can either
+ * explicitly set this (with LOADFLG_SPECADDR) or
+ * let CFE decide. If CFE decides, the load address
+ * will be BOOT_START_ADDRESS in all cases.
+ * The size is dependant on the device type: block and flash
+ * devices will get this info from the boot block,
+ * and network devices will get the info by reaching EOF
+ * on reads, up to the maximum size of the boot area.
+ */
+
+ if (loadflags & LOADFLG_SPECADDR) {
+ bootcode = (uint8_t *) la->la_address;
+ maxsize = la->la_maxsize;
+ findbb = FALSE; /* don't find a boot block */
+ }
+ else {
+ bootcode = (uint8_t *) BOOT_START_ADDRESS;
+ maxsize = BOOT_AREA_SIZE;
+ findbb = FALSE;
+ devinfo = la->la_device ? cfe_getdevinfo(la->la_device) : 0;
+
+ /*
+ * If the device is either a disk or a flash device,
+ * we will expect to find a boot block.
+ * Serial and network devices do not have boot blocks.
+ */
+ if ((devinfo >= 0) &&
+ ( ((devinfo & CFE_DEV_MASK) == CFE_DEV_DISK) ||
+ ((devinfo & CFE_DEV_MASK) == CFE_DEV_FLASH) )) {
+ findbb = TRUE;
+ }
+ }
+
+
+ /*
+ * merge in any filesystem-specific flags
+ */
+
+ ops = cfe_findfilesys(la->la_filesys);
+ if (!ops) return CFE_ERR_FSNOTAVAIL;
+ loadflags |= ops->loadflags;
+
+ /*
+ * turn off the boot block if requested.
+ */
+
+ if (loadflags & LOADFLG_NOBB) findbb = FALSE;
+
+ /*
+ * Create a file system context
+ */
+
+ res = fs_init(la->la_filesys,&fsctx,la->la_device);
+ if (res != 0) {
+ return res;
+ }
+
+ /*
+ * Turn on compression if we're doing that.
+ */
+
+ if (!findbb && (la->la_flags & LOADFLG_COMPRESSED)) {
+ res = fs_hook(fsctx,"z");
+ if (res != 0) {
+ return res;
+ }
+ }
+
+ /*
+ * Open the boot device
+ */
+
+ res = fs_open(fsctx,&ref,la->la_filename,FILE_MODE_READ);
+ if (res != 0) {
+ fs_uninit(fsctx);
+ return res;
+ }
+
+ /*
+ * If we need to find a boot block, do it now.
+ */
+
+ if (findbb) {
+ res = cfe_findbootblock(la,fsctx,ref,&bootblock);
+
+ /*
+ * If we found the boot block, seek to the part of the
+ * disk where the boot code is.
+ * Otherwise, get out now, since the disk has no boot block.
+ */
+
+ if (res == 0) {
+ maxsize = (int) ((uint32_t) (bootblock.bb_secsize & BOOT_SECSIZE_MASK));
+ secoffset = bootblock.bb_secstart;
+ fs_seek(fsctx,ref,secoffset,FILE_SEEK_BEGINNING);
+ }
+ else {
+ fs_close(fsctx,ref);
+ fs_uninit(fsctx);
+ return res;
+ }
+
+ }
+
+ /*
+ * Okay, go load the boot file.
+ */
+
+ ptr = bootcode;
+ amtcopy = maxsize;
+ ttlcopy = 0;
+
+ onedot = amtcopy / 10; /* ten dots for entire load */
+ if (onedot < 4096) onedot = 4096; /* but minimum 4096 bytes per dot */
+ onedot = (onedot + 1) & ~4095; /* round to multiple of 4096 */
+
+ while (amtcopy > 0) {
+ thisamt = onedot;
+ if (thisamt > amtcopy) thisamt = amtcopy;
+
+ res = fs_read(fsctx,ref,ptr,thisamt);
+ if (la->la_flags & LOADFLG_NOISY) {
+ xprintf(".");
+ }
+ if (res <= 0) break;
+ ptr += res;
+ amtcopy -= res;
+ ttlcopy += res;
+ }
+
+ /*
+ * We're done with the file.
+ */
+
+ fs_close(fsctx,ref);
+ fs_uninit(fsctx);
+
+ /*
+ * Verify the boot loader checksum if we were reading
+ * the disk.
+ */
+
+#if !defined(CONFIG_MIPS_BRCM)
+ if (findbb) {
+ CHECKSUM_BOOT_DATA(bootcode,maxsize,&calcsum);
+ checksum = (uint32_t) ((bootblock.bb_secsize & BOOT_DATA_CHECKSUM_MASK)
+ >> BOOT_DATA_CHECKSUM_SHIFT);
+
+ if (checksum != calcsum) {
+ return CFE_ERR_BOOTPROGCHKSUM;
+ }
+ }
+#endif
+
+ la->la_entrypt = (uintptr_t) bootcode;
+
+ if (la->la_flags & LOADFLG_NOISY) xprintf(" %d bytes read\n",ttlcopy);
+
+ return (res < 0) ? res : ttlcopy;
+
+}