Annotation of qemu/roms/SLOF/board-js2x/rtas/rtas_flash.c, revision 1.1

1.1     ! root        1: /******************************************************************************
        !             2:  * Copyright (c) 2004, 2008 IBM Corporation
        !             3:  * All rights reserved.
        !             4:  * This program and the accompanying materials
        !             5:  * are made available under the terms of the BSD License
        !             6:  * which accompanies this distribution, and is available at
        !             7:  * http://www.opensource.org/licenses/bsd-license.php
        !             8:  *
        !             9:  * Contributors:
        !            10:  *     IBM Corporation - initial implementation
        !            11:  *****************************************************************************/
        !            12: 
        !            13: #include <cpu.h>
        !            14: #include <string.h>
        !            15: #include <stdio.h>
        !            16: #include <stdint.h>
        !            17: #include <hw.h>
        !            18: #include <rtas.h>
        !            19: #include "rtas_board.h"
        !            20: #include <bmc.h>
        !            21: #include "rtas_flash.h"
        !            22: #include <flash/block_lists.h>
        !            23: #include "product.h"
        !            24: #include "calculatecrc.h"
        !            25: 
        !            26: #undef DEBUG
        !            27: 
        !            28: #ifdef DEBUG
        !            29: #define dprintf(_x ...) printf(_x)
        !            30: #else
        !            31: #define dprintf(_x ...)
        !            32: #endif
        !            33: 
        !            34: static uint64_t size;
        !            35: static uint64_t flashOffset;
        !            36: 
        !            37: unsigned short manage_flash_buffer[BUFSIZE];
        !            38: unsigned long check_flash_image(unsigned long rombase, unsigned long length,
        !            39:                                unsigned long start_crc);
        !            40: 
        !            41: #ifdef DEBUG
        !            42: static void
        !            43: dump_blocklist(uint64_t *bl, int version)
        !            44: {
        !            45:        uint64_t bl_size;
        !            46:        uint8_t *addr = (uint8_t *)bl;
        !            47: 
        !            48:        if (version == 1) {
        !            49:                /* version 1 blocklist */
        !            50:                bl_size = *bl & 0x00FFFFFFFFFFFFFFUL;
        !            51: 
        !            52:        } else {
        !            53:                bl_size = *bl;
        !            54:        }
        !            55: 
        !            56:        printf("\n\rblocklist_dump %lx", bl_size);
        !            57:        while (bl_size) {
        !            58:                unsigned int tmpCnt = bl_size;
        !            59:                unsigned char x;
        !            60:                if (tmpCnt > 8)
        !            61:                        tmpCnt = 8;
        !            62:                printf("\n\r%08x: ", addr);
        !            63:                /* print hex */
        !            64:                while (tmpCnt--) {
        !            65:                        set_ci();
        !            66:                        x = *addr++;
        !            67:                        clr_ci();
        !            68:                        printf("%02x ", x);
        !            69:                }
        !            70:                tmpCnt = bl_size;
        !            71:                if (tmpCnt > 8)
        !            72:                        tmpCnt = 8;
        !            73:                bl_size -= tmpCnt;
        !            74:                /* reset addr ptr to print ascii */
        !            75:                addr = addr - tmpCnt;
        !            76:                /* print ascii */
        !            77:                while (tmpCnt--) {
        !            78:                        set_ci();
        !            79:                        x = *addr++;
        !            80:                        clr_ci();
        !            81:                        if ((x < 32) || (x >= 127)) {
        !            82:                                /* non-printable char */
        !            83:                                x = '.';
        !            84:                        }
        !            85:                        printf("%c", x);
        !            86:                }
        !            87:        }
        !            88:        printf("\r\n");
        !            89: }
        !            90: #endif
        !            91: 
        !            92: void
        !            93: rtas_dump_flash(rtas_args_t *rtas_args)
        !            94: {
        !            95:        int retVal = 0;
        !            96:        unsigned int size = rtas_args->args[0];
        !            97:        unsigned int offset = rtas_args->args[1];
        !            98:        volatile unsigned char *flash = (volatile unsigned char *)FLASH;
        !            99: 
        !           100:        printf("\n\rflash_dump %x %x", size, offset);
        !           101:        flash += offset;
        !           102:        while (size) {
        !           103:                unsigned int tmpCnt = size;
        !           104:                unsigned char x;
        !           105:                if (tmpCnt > 16)
        !           106:                        tmpCnt = 16;
        !           107:                printf("\n\r%p: ", flash);
        !           108:                /* print hex */
        !           109:                while (tmpCnt--) {
        !           110:                        set_ci();
        !           111:                        x = *flash++;
        !           112:                        clr_ci();
        !           113:                        printf("%02x ", x);
        !           114:                }
        !           115:                tmpCnt = size;
        !           116:                if (tmpCnt > 16)
        !           117:                        tmpCnt = 16;
        !           118:                size -= tmpCnt;
        !           119:                /* reset flash ptr to print ascii */
        !           120:                flash = flash - tmpCnt;
        !           121:                /* print ascii */
        !           122:                while (tmpCnt--) {
        !           123:                        set_ci();
        !           124:                        x = *flash++;
        !           125:                        clr_ci();
        !           126:                        if ((x < 32) || (x >= 127)) {
        !           127:                                /* non-printable char */
        !           128:                                x = '.';
        !           129:                        }
        !           130:                        printf("%c", x);
        !           131:                }
        !           132:        }
        !           133:        printf("\r\n");
        !           134:        rtas_args->args[rtas_args->nargs] = retVal;
        !           135: }
        !           136: 
        !           137: 
        !           138: static void
        !           139: print_block(int i)
        !           140: {
        !           141:        int counter = 8;
        !           142: 
        !           143:        while (counter--)
        !           144:                printf("\b");
        !           145:        printf("%08x", i);
        !           146: }
        !           147: 
        !           148: 
        !           149: 
        !           150: /* To enter data mode after flash has been in programming mode
        !           151:  * a 0xFF has to be written */
        !           152: static void
        !           153: enter_data_mode(void)
        !           154: {
        !           155:        volatile unsigned char *flash = (volatile unsigned char *)FLASH;
        !           156: 
        !           157:        set_ci();
        !           158:        *flash = 0xFF;
        !           159:        eieio();
        !           160:        clr_ci();
        !           161: }
        !           162: 
        !           163: 
        !           164: static void
        !           165: erase_flash_block(unsigned long offset)
        !           166: {
        !           167:        volatile unsigned char *flash = (volatile unsigned char *)FLASH;
        !           168: 
        !           169:        flash += offset;
        !           170:        set_ci();
        !           171:        *flash = 0x20;
        !           172:        eieio();
        !           173:        *flash = 0xd0;
        !           174:        eieio();
        !           175:        while (!(*flash & 0x80)) ;
        !           176:        clr_ci();
        !           177: }
        !           178: 
        !           179: 
        !           180: void
        !           181: write_flash(unsigned long offset, unsigned char *data)
        !           182: {
        !           183:        int cnt = 32;
        !           184:        volatile unsigned char *flash = (volatile unsigned char *)FLASH;
        !           185: 
        !           186:        flash += (offset + flashOffset);
        !           187:        set_ci();
        !           188:        while (cnt) {
        !           189:                if (!((uint64_t)flash & 0x1F)) {
        !           190:                        while (cnt) {
        !           191:                                uint64_t tmpcnt = cnt;
        !           192:                                if (tmpcnt > 0x20)
        !           193:                                        tmpcnt = 0x20;
        !           194:                                do {
        !           195:                                        *flash = 0xE8;
        !           196:                                        eieio();
        !           197:                                } while (!(*flash & 0x80));
        !           198:                                cnt -= tmpcnt;
        !           199:                                *flash = tmpcnt - 1;
        !           200:                                while (tmpcnt--) {
        !           201:                                        *flash++ = *data++;
        !           202:                                }
        !           203:                                *flash = 0xD0;
        !           204:                                eieio();
        !           205:                                while (!(*flash & 0x80)) ;
        !           206:                        }
        !           207:                        break;
        !           208:                }
        !           209:                *flash = 0x40;
        !           210:                eieio();
        !           211:                *flash++ = *data++;
        !           212:                eieio();
        !           213:                while (!(*flash & 0x80)) ;
        !           214:                cnt--;
        !           215:        }
        !           216:        clr_ci();
        !           217: }
        !           218: 
        !           219: void
        !           220: write_flash_page(unsigned long offset, unsigned short *data)
        !           221: {
        !           222:        int i = 0;
        !           223: 
        !           224:        for (i = 0; i < BUFSIZE; i += 32, offset += 32) {
        !           225:                write_flash(offset, ((unsigned char *)data + i));
        !           226:        }
        !           227: }
        !           228: 
        !           229: /*
        !           230:  * 0 reject temporary image
        !           231:  * 1 commit temporary image
        !           232:  * */
        !           233: static int
        !           234: copy_flash(short mode)
        !           235: {
        !           236:        volatile unsigned char *flash = (volatile unsigned char *)FLASH;
        !           237:        uint64_t blockCnt;
        !           238:        uint64_t hash = 0;
        !           239:        short notmode = mode ^ 0x1;
        !           240: 
        !           241:        if (bmc_set_flashside(notmode) != notmode) {
        !           242:                return -1;
        !           243:        }
        !           244:        printf("\r\nErasing Flash: 0x        ");
        !           245: 
        !           246:        for (blockCnt = 0; blockCnt <= FLASHSIZE; blockCnt += FLASH_BLOCK_SIZE) {
        !           247:                print_block(blockCnt);
        !           248:                erase_flash_block(blockCnt);
        !           249:        }
        !           250:        enter_data_mode();
        !           251:        progress = FLASHSIZE / 38;
        !           252:        print_writing();
        !           253: 
        !           254:        for (blockCnt = 0; blockCnt <= FLASHSIZE; blockCnt += BUFSIZE) {
        !           255:                uint64_t *srcPtr = (uint64_t *)(flash + blockCnt);
        !           256:                uint64_t *destPtr = (uint64_t *)((void*)manage_flash_buffer);
        !           257:                uint64_t cnt = BUFSIZE / 8;
        !           258:                if (bmc_set_flashside(mode) != mode) {
        !           259:                        return -1;
        !           260:                }
        !           261:                enter_data_mode();
        !           262:                set_ci();
        !           263:                while (cnt--) {
        !           264:                        *destPtr++ = *srcPtr++;
        !           265:                }
        !           266:                clr_ci();
        !           267: 
        !           268:                if (bmc_set_flashside(notmode) != notmode) {
        !           269:                        return -1;
        !           270:                }
        !           271:                write_flash_page(blockCnt,
        !           272:                                 (unsigned short *)manage_flash_buffer);
        !           273: 
        !           274:                /* progress output... */
        !           275:                print_progress();
        !           276:                if (blockCnt > hash * progress) {
        !           277:                        print_hash();
        !           278:                        hash++;
        !           279:                }
        !           280:        }
        !           281:        enter_data_mode();
        !           282:        if (bmc_set_flashside(mode) != mode) {
        !           283:                return -1;
        !           284:        }
        !           285:        printf("\b#\n");
        !           286:        return 0;
        !           287: }
        !           288: 
        !           289: /*
        !           290:  * Function: ibm_manage_flash_image
        !           291:  *     Input:
        !           292:  *             r3:   rtas parm structure
        !           293:  *                     token:  46
        !           294:  *                     in:     1
        !           295:  *                     out:    1
        !           296:  *                     parm0:  0 reject temporary image
        !           297:  *                             1 commit temporary image
        !           298:  *     Output:
        !           299:  *                     parm1:  Status (hw -1, busy -2, parameter error -3
        !           300:  *                                     -9001 cannot overwrite the active firmware image)
        !           301:  *
        !           302:  */
        !           303: 
        !           304: void
        !           305: rtas_ibm_manage_flash_image(rtas_args_t *rtas_args)
        !           306: {
        !           307:        int side;
        !           308:        int result = 0;
        !           309:        short mode = rtas_args->args[0];
        !           310: 
        !           311:        if (mode < 0 || mode > 1) {
        !           312:                rtas_args->args[rtas_args->nargs] = -3;
        !           313:                return;
        !           314:        }
        !           315:        side = bmc_get_flashside();
        !           316:        if (side == 0) {
        !           317:                /* we are on the permanent side */
        !           318:                if (mode != 0) {
        !           319:                        rtas_args->args[rtas_args->nargs] = -9001;
        !           320:                        return;
        !           321:                }
        !           322:        } else if (side == 1) {
        !           323:                /* we are on the temporary side */
        !           324:                if (mode != 1) {
        !           325:                        rtas_args->args[rtas_args->nargs] = -9001;
        !           326:                        return;
        !           327:                }
        !           328:        } else {
        !           329:                rtas_args->args[rtas_args->nargs] = -1;
        !           330:                return;
        !           331:        }
        !           332: 
        !           333:        result = copy_flash(mode);
        !           334:        bmc_set_flashside(mode);
        !           335:        enter_data_mode();
        !           336:        rtas_args->args[rtas_args->nargs] = 0;
        !           337: }
        !           338: 
        !           339: /**
        !           340:  * check, if we find the FLASHFS_MAGIC token in bl
        !           341:  **/
        !           342: static uint8_t
        !           343: check_magic(uint64_t *bl, int version)
        !           344: {
        !           345:        struct stH *pHeader;
        !           346: 
        !           347:        if (version == 1) {
        !           348:                /* version 1 blocklist */
        !           349:                /* if block list size <= 0x10, it is only block list header */
        !           350:                /* and address of block list extension, so look at the extension... */
        !           351:                while ((*bl & 0x00FFFFFFFFFFFFFFUL) <= 0x10)
        !           352:                        bl = (uint64_t *)bl[1];
        !           353: 
        !           354:                /* block list item 2 _should_ be the address of our flashfs image */
        !           355:                pHeader = (struct stH *)(bl[2] + 0x28);
        !           356:                /* printf("FlashFS Magic: \"%#s\"\r\n", pHeader->magic); */
        !           357:                return strncmp(pHeader->magic, FLASHFS_MAGIC, 8);
        !           358:        } else {
        !           359:                /* block list item 1 _should_ be the address of our flashfs image */
        !           360:                pHeader = (struct stH *)(bl[1] + 0x28);
        !           361:                /* printf("FlashFS Magic: \"%#s\"\r\n", pHeader->magic); */
        !           362:                return strncmp(pHeader->magic, FLASHFS_MAGIC, 8);
        !           363:        }
        !           364: }
        !           365: 
        !           366: static void
        !           367: get_image_name(char *buffer, int maxsize)
        !           368: {
        !           369:        volatile struct stH *flash_header = (volatile struct stH *)(SB_FLASH_adr + 0x28);
        !           370:        /* since we cannot read the fh_magic directly from flash as a string, we need to copy it to memory */
        !           371:        uint64_t magic_val = 0;
        !           372:        uint64_t addr;
        !           373: 
        !           374:        /* copy fh_magic to magic_val since, we cannot use it as a string from flash */
        !           375:        magic_val = load64_ci((uint64_t)(flash_header->magic));
        !           376:        if (strncmp((char *)&magic_val, FLASHFS_MAGIC, 8)) {
        !           377:                /* magic does not match */
        !           378:                sprintf(buffer, "Unknown");
        !           379:                buffer[maxsize - 1] = '\0';
        !           380:                return;
        !           381:        }
        !           382:        addr = (uint64_t)flash_header->version;
        !           383:        while (--maxsize) {
        !           384:                *buffer = load8_ci(addr++);
        !           385:                if (!*buffer++)
        !           386:                        return;
        !           387:        }
        !           388:        *buffer = '\0';
        !           389: }
        !           390: 
        !           391: /**
        !           392:  * validate_flash_image
        !           393:  * this function checks if the flash will be updated with the given image
        !           394:  * @param args[0] - buffer with minimum 4K of the image to flash
        !           395:  * @param args[1] - size of the buffer
        !           396:  * @param args[2] - status:
        !           397:  *                           0    success
        !           398:  *                          -1    hw
        !           399:  *                          -2    busy
        !           400:  *                          -3    parameter error
        !           401:  * @param args[3] - update result token
        !           402:  */
        !           403: void
        !           404: rtas_ibm_validate_flash_image(rtas_args_t *rtas_args)
        !           405: {
        !           406:        dprintf("\nrtas_ibm_validate_flash_image\n");
        !           407:        unsigned long new_image = rtas_args->args[0];
        !           408:        char *ret_str = (char *)new_image;
        !           409:        struct stH *flash_header = (struct stH *)(new_image + 0x28);
        !           410:        char current_temp_version[16];
        !           411:        char current_perm_version[16];
        !           412:        char new_version[16];
        !           413:        int side = bmc_get_flashside();
        !           414: 
        !           415:        /* fill args[0] with the current values which is needed
        !           416:         * in an error case */
        !           417: 
        !           418:        bmc_set_flashside(0);
        !           419:        get_image_name(current_perm_version, sizeof(current_perm_version));
        !           420:        bmc_set_flashside(1);
        !           421:        get_image_name(current_temp_version, sizeof(current_temp_version));
        !           422:        bmc_set_flashside(side);
        !           423: 
        !           424:        /* check if the candidate image if valid for this platform */
        !           425:        if (strncmp(flash_header->magic, FLASHFS_MAGIC, 8)) {
        !           426:                /* magic does not match */
        !           427:                rtas_args->args[rtas_args->nargs] = 0;
        !           428:                /* No update done, the candidate image is
        !           429:                 * not valid for this platform */
        !           430:                rtas_args->args[rtas_args->nargs + 1] = 2;
        !           431:                sprintf(ret_str, "MI %s %s\xaMI %s %s",
        !           432:                        current_temp_version, current_perm_version,
        !           433:                        current_temp_version, current_perm_version);
        !           434:                return;
        !           435:        }
        !           436: 
        !           437:        if (strncmp(flash_header->platform_name, (char *)sig_org, 32)) {
        !           438:                /* this image if for a different board */
        !           439:                rtas_args->args[rtas_args->nargs] = 0;
        !           440:                /* No update done, the candidate image is
        !           441:                 * not valid for this platform */
        !           442:                rtas_args->args[rtas_args->nargs + 1] = 2;
        !           443:                sprintf(ret_str, "MI %s %s\xaMI %s %s",
        !           444:                        current_temp_version, current_perm_version,
        !           445:                        current_temp_version, current_perm_version);
        !           446:                return;
        !           447:        }
        !           448: 
        !           449:        /* check header crc */
        !           450:        if (check_flash_image(rtas_args->args[0], 0x88, 0)) {
        !           451:                /* header crc failed */
        !           452:                rtas_args->args[rtas_args->nargs] = 0;
        !           453:                /* No update done, the candidate image is
        !           454:                 * not valid for this platform */
        !           455:                rtas_args->args[rtas_args->nargs + 1] = 2;
        !           456:                sprintf(ret_str, "MI %s %s\xaMI %s %s",
        !           457:                        current_temp_version, current_perm_version,
        !           458:                        current_temp_version, current_perm_version);
        !           459:                return;
        !           460:        }
        !           461:        memcpy(new_version, flash_header->version, 16);
        !           462:        sprintf(ret_str, "MI %s %s\xaMI %s %s", current_temp_version,
        !           463:                current_perm_version, new_version, current_perm_version);
        !           464:        rtas_args->args[rtas_args->nargs] = 0;
        !           465: 
        !           466:        if (strncmp(new_version, current_temp_version, 16) >= 0)
        !           467:                rtas_args->args[rtas_args->nargs + 1] = 0;
        !           468:        else
        !           469:                rtas_args->args[rtas_args->nargs + 1] = 6;
        !           470: }
        !           471: 
        !           472: /*
        !           473:  * Function: ibm_update_flash_64
        !           474:  *     Input:
        !           475:  *             r3:   rtas parm structure
        !           476:  *                     token:  7
        !           477:  *                     in:     1
        !           478:  *                     out:    1
        !           479:  *                     parm0:  A real pointer to a block list
        !           480:  *     Output:
        !           481:  *                     parm1:  Status (hw -1, bad image -3, programming failed -4)
        !           482:  *
        !           483:  *   Description: flash if addresses above 4GB have to be addressed
        !           484:  */
        !           485: void
        !           486: rtas_update_flash(rtas_args_t *rtas_args)
        !           487: {
        !           488:        void *bl = (void *)(uint64_t)rtas_args->args[0];
        !           489:        int version = get_block_list_version((unsigned char *)bl);
        !           490:        uint64_t erase_size;
        !           491:        unsigned int i;
        !           492:        int perm_check = 1;
        !           493: 
        !           494: #ifdef DEBUG
        !           495:        dump_blocklist(bl, version);
        !           496: #endif
        !           497: 
        !           498:        /* from SLOF we pass a second (unofficial) parameter, if this parameter is 1, we do not
        !           499:         * check wether we are on permanent side. Needed for update-flash -c to work! */
        !           500:        if ((rtas_args->nargs > 1) && (rtas_args->args[1] == 1))
        !           501:                perm_check = 0;
        !           502: 
        !           503:        /* check magic string */
        !           504:        printf("\r\nChecking magic string : ");
        !           505:        if (check_magic(bl, version) != 0) {
        !           506:                printf("failed!\n");
        !           507:                rtas_args->args[rtas_args->nargs] = -3; /* bad image */
        !           508:                return;
        !           509:        }
        !           510:        printf("succeeded!\n");
        !           511: 
        !           512:        /* check platform */
        !           513:        printf("Checking platform : ");
        !           514:        if (check_platform(bl, 0x48, version) == -1) {
        !           515:                printf("failed!\n");
        !           516:                rtas_args->args[rtas_args->nargs] = -3; /* bad image */
        !           517:                return;
        !           518:        }
        !           519:        printf("succeeded!\n");
        !           520: 
        !           521:        /* checkcrc */
        !           522:        printf("Checking CRC : ");
        !           523:        /* the actual CRC is included at the end of the flash image, thus the resulting CRC must be 0! */
        !           524:        if (image_check_crc(bl, version) != 0) {
        !           525:                printf("failed!\n");
        !           526:                rtas_args->args[1] = -3;        /* bad image */
        !           527:                return;
        !           528:        }
        !           529:        printf("succeeded!\n");
        !           530: 
        !           531:        /* check if we are running on P
        !           532:         * if so, let's switch to temp and flash temp */
        !           533:        if (bmc_get_flashside() == 0  && perm_check) {
        !           534:                printf("Set flashside: ");
        !           535:                bmc_set_flashside(1);
        !           536:                printf("Temp!\n");
        !           537:        }
        !           538: 
        !           539: #ifdef DEBUG
        !           540:        rtas_args_t ra;
        !           541:        ra.args[0] = 0x100;     /* size; */
        !           542:        ra.args[1] = flashOffset;
        !           543:        ra.nargs = 2;
        !           544: 
        !           545:        rtas_dump_flash(&ra);
        !           546:        printf("\n");
        !           547: #endif
        !           548: 
        !           549:        size = get_size(bl, version);
        !           550:        erase_size = (size + (FLASH_BLOCK_SIZE - 1)) & ~(FLASH_BLOCK_SIZE - 1);
        !           551:        dprintf("Erasing: size: %#x, erase_size: %#x, FLASH_BLOCK_SIZE: %#x\n",
        !           552:                size, erase_size, FLASH_BLOCK_SIZE);
        !           553: 
        !           554:        progress = size / 39;
        !           555:        printf("Erasing : 0x%08x", 0);
        !           556:        for (i = 0; i < erase_size; i += FLASH_BLOCK_SIZE) {
        !           557:                print_block(i);
        !           558:                erase_flash_block(i);
        !           559:        }
        !           560: 
        !           561:        enter_data_mode();
        !           562: #ifdef DEBUG
        !           563:        rtas_dump_flash(&ra);
        !           564:        printf("\n");
        !           565: #endif
        !           566:        print_writing();
        !           567:        write_block_list(bl, version);
        !           568:        printf("\b#\n");
        !           569:        enter_data_mode();
        !           570: 
        !           571: #ifdef DEBUG
        !           572:        rtas_dump_flash(&ra);
        !           573:        printf("\n");
        !           574: #endif
        !           575: 
        !           576:        /* checkcrc */
        !           577:        printf("Recheck CRC : ");
        !           578:        if (check_flash_image(FLASH + flashOffset, size, 0) != 0) {
        !           579:                /* failed */
        !           580:                printf("failed!\n\r");
        !           581:                dprintf("flash_addr: %#x, flashOffset: %#x, size: %#x\n", FLASH,
        !           582:                        flashOffset, size);
        !           583:                dprintf("crc: %#x\n",
        !           584:                        check_flash_image(FLASH + flashOffset, size, 0));
        !           585:                rtas_args->args[rtas_args->nargs] = -4; /* programming failed */
        !           586:                return;
        !           587:        }
        !           588:        printf("succeeded!\n");
        !           589:        rtas_args->args[rtas_args->nargs] = 0;
        !           590: }
        !           591: 
        !           592: /*
        !           593:  * Function: ibm_update_flash_64_and_reboot
        !           594:  *     Input:
        !           595:  *             r3:   rtas parm structure
        !           596:  *                     token:  27
        !           597:  *                     in:     1
        !           598:  *                     out:    1
        !           599:  *                     parm0:  A real pointer to a block list
        !           600:  *     Output:
        !           601:  *                     parm1:  Status (hw -1, bad image -3, programming failed -4)
        !           602:  *                             Currently -4 and -1 are not returned
        !           603:  *
        !           604:  *  Description: flash and reboot if addresses above 4GB have to be addressed
        !           605:  */
        !           606: void
        !           607: rtas_ibm_update_flash_64_and_reboot(rtas_args_t *rtas_args)
        !           608: {
        !           609:        rtas_update_flash(rtas_args);
        !           610:        dprintf("rc: %#d\n", rtas_args->args[rtas_args->nargs]);
        !           611:        if (rtas_args->args[rtas_args->nargs] == 0) {
        !           612:                rtas_system_reboot(rtas_args);
        !           613:        }
        !           614: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.