/* * Copyright (C) 2004-2005 Anders Gavare. 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. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. * * * $Id: sgiprom_to_bin.c,v 1.5 2005/02/21 07:18:10 debug Exp $ * * sgiprom_to_bin.c * * This program takes a textfile containing a SGI PROM memory dump of * the following format: * * >> dump -b 0xBFC00000:0xBFCF0000 * 0xbfc00000: b f0 0 f0 0 0 0 0 * 0xbfc00008: b f0 1 f6 0 0 0 0 * SAME * 0xbfc00200: b f0 3 c9 0 0 0 0 * 0xbfc00208: b f0 1 f6 0 0 0 0 * SAME * 0xbfc00280: b f0 3 cb 0 0 0 0 * .. * * and turns it into a binary image. Input is read from stdin. */ #include #include #include #include #define IP28 #ifdef IP26 /* SGI Power Indigo2 (R8000) */ #define BASE (uint64_t)0x900000001fc00000 #define BITS 64 #elif (defined IP28 || defined IP30) /* SGI Indigo2 R10000, Octane */ #define BASE (uint64_t)0xffffffffbfc00000 #define BITS 64 #else #define BASE (uint64_t)0xbfc00000 #define BITS 32 #endif #define MAX 200 int main(int argc, char *argv[]) { FILE *f; uint32_t previous_line[4]; int same_flag = 0; off_t same_start_offset = 0; if (argc < 2) { fprintf(stderr, "usage: %s output_filename\n", argv[0]); fprintf(stderr, "input is read from stdin\n"); exit(1); } f = fopen(argv[1], "w"); while (!feof(stdin)) { char s[MAX]; s[0] = 0; fgets(s, sizeof(s), stdin); while (s[0] == '\r') { memcpy(s, s+1, sizeof(s)-1); s[MAX-1] = '\0'; } /* * 32bits flavours: * >> dump -w -x 0xbfc00000:0xbfc80000 * 0xbfc00000: bf000f0 0 bf001ef 0 * ... * * 64bits flavours: * >> dump -w -x 0x900000001fc00000:0x900000001fd00000 * 0x900000001fc00000: 40a06800 40 40a06000 40 * 0x900000001fc00010: 0 10000012 3c0c9000 0 * ... */ #if (BITS == 64) if (s[0] == '0' && s[18]==':') { #else if (s[0] == '0' && s[10]==':') { #endif uint64_t x; int i; x = strtoull(s, NULL, 0); if (x < BASE) { printf("x = 0x%016llx, less than 0x%016llx. " "aborting\n", x, BASE); exit(1); } x -= BASE; if (same_flag) { /* * We should fill from same_start_offset to * just before x, using previous_line data. */ off_t ofs; printf("same_flag set, filling until just before 0x%016llx\n", x); fseek(f, same_start_offset, SEEK_SET); for (ofs = same_start_offset; ofs < x; ofs += 4) { fwrite(previous_line, 1, sizeof(previous_line), f); } same_flag = 0; } printf("x = 0x%016llx\n", x); fseek(f, x, SEEK_SET); for (i=0; i<4; i++) { uint32_t w = 0; #if (BITS == 64) char *ptr = s + 22; #else char *ptr = s + 14; #endif ptr += i * 11; ptr[8] = '\0'; if (sscanf(ptr, "%x", &w) != 1) printf("no input\n"); else fwrite(&w, 1, sizeof(w), f); previous_line[i] = w; } printf("\n"); } /* "SAME": */ if (s[0] == 'S' && s[1] == 'A') { /* * This should produce "same" output until the * next normal "0xbfc.." line. */ same_flag = 1; same_start_offset = ftell(f); } } fclose(f); return 0; }