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

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: 
1.1.1.2   root       37: unsigned char manage_flash_buffer[BUFSIZE*2];
1.1       root       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: 
1.1.1.3 ! root      219: static void
1.1       root      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);
1.1.1.2   root      256:                uint64_t *destPtr = (uint64_t *)manage_flash_buffer;
1.1       root      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();
1.1.1.2   root      336:        rtas_args->args[rtas_args->nargs] = result;
1.1       root      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.