diff options
Diffstat (limited to 'qemu/roms/SLOF/board-js2x/rtas/rtas_flash.c')
-rw-r--r-- | qemu/roms/SLOF/board-js2x/rtas/rtas_flash.c | 614 |
1 files changed, 0 insertions, 614 deletions
diff --git a/qemu/roms/SLOF/board-js2x/rtas/rtas_flash.c b/qemu/roms/SLOF/board-js2x/rtas/rtas_flash.c deleted file mode 100644 index 189878da9..000000000 --- a/qemu/roms/SLOF/board-js2x/rtas/rtas_flash.c +++ /dev/null @@ -1,614 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <cpu.h> -#include <string.h> -#include <stdio.h> -#include <stdint.h> -#include <hw.h> -#include <rtas.h> -#include "rtas_board.h" -#include <bmc.h> -#include "rtas_flash.h" -#include <flash/block_lists.h> -#include "product.h" -#include "calculatecrc.h" - -#undef DEBUG - -#ifdef DEBUG -#define dprintf(_x ...) printf(_x) -#else -#define dprintf(_x ...) -#endif - -static uint64_t size; -static uint64_t flashOffset; - -unsigned char manage_flash_buffer[BUFSIZE*2]; -unsigned long check_flash_image(unsigned long rombase, unsigned long length, - unsigned long start_crc); - -#ifdef DEBUG -static void -dump_blocklist(uint64_t *bl, int version) -{ - uint64_t bl_size; - uint8_t *addr = (uint8_t *)bl; - - if (version == 1) { - /* version 1 blocklist */ - bl_size = *bl & 0x00FFFFFFFFFFFFFFUL; - - } else { - bl_size = *bl; - } - - printf("\n\rblocklist_dump %lx", bl_size); - while (bl_size) { - unsigned int tmpCnt = bl_size; - unsigned char x; - if (tmpCnt > 8) - tmpCnt = 8; - printf("\n\r%08x: ", addr); - /* print hex */ - while (tmpCnt--) { - set_ci(); - x = *addr++; - clr_ci(); - printf("%02x ", x); - } - tmpCnt = bl_size; - if (tmpCnt > 8) - tmpCnt = 8; - bl_size -= tmpCnt; - /* reset addr ptr to print ascii */ - addr = addr - tmpCnt; - /* print ascii */ - while (tmpCnt--) { - set_ci(); - x = *addr++; - clr_ci(); - if ((x < 32) || (x >= 127)) { - /* non-printable char */ - x = '.'; - } - printf("%c", x); - } - } - printf("\r\n"); -} -#endif - -void -rtas_dump_flash(rtas_args_t *rtas_args) -{ - int retVal = 0; - unsigned int size = rtas_args->args[0]; - unsigned int offset = rtas_args->args[1]; - volatile unsigned char *flash = (volatile unsigned char *)FLASH; - - printf("\n\rflash_dump %x %x", size, offset); - flash += offset; - while (size) { - unsigned int tmpCnt = size; - unsigned char x; - if (tmpCnt > 16) - tmpCnt = 16; - printf("\n\r%p: ", flash); - /* print hex */ - while (tmpCnt--) { - set_ci(); - x = *flash++; - clr_ci(); - printf("%02x ", x); - } - tmpCnt = size; - if (tmpCnt > 16) - tmpCnt = 16; - size -= tmpCnt; - /* reset flash ptr to print ascii */ - flash = flash - tmpCnt; - /* print ascii */ - while (tmpCnt--) { - set_ci(); - x = *flash++; - clr_ci(); - if ((x < 32) || (x >= 127)) { - /* non-printable char */ - x = '.'; - } - printf("%c", x); - } - } - printf("\r\n"); - rtas_args->args[rtas_args->nargs] = retVal; -} - - -static void -print_block(int i) -{ - int counter = 8; - - while (counter--) - printf("\b"); - printf("%08x", i); -} - - - -/* To enter data mode after flash has been in programming mode - * a 0xFF has to be written */ -static void -enter_data_mode(void) -{ - volatile unsigned char *flash = (volatile unsigned char *)FLASH; - - set_ci(); - *flash = 0xFF; - eieio(); - clr_ci(); -} - - -static void -erase_flash_block(unsigned long offset) -{ - volatile unsigned char *flash = (volatile unsigned char *)FLASH; - - flash += offset; - set_ci(); - *flash = 0x20; - eieio(); - *flash = 0xd0; - eieio(); - while (!(*flash & 0x80)) ; - clr_ci(); -} - - -void -write_flash(unsigned long offset, unsigned char *data) -{ - int cnt = 32; - volatile unsigned char *flash = (volatile unsigned char *)FLASH; - - flash += (offset + flashOffset); - set_ci(); - while (cnt) { - if (!((uint64_t)flash & 0x1F)) { - while (cnt) { - uint64_t tmpcnt = cnt; - if (tmpcnt > 0x20) - tmpcnt = 0x20; - do { - *flash = 0xE8; - eieio(); - } while (!(*flash & 0x80)); - cnt -= tmpcnt; - *flash = tmpcnt - 1; - while (tmpcnt--) { - *flash++ = *data++; - } - *flash = 0xD0; - eieio(); - while (!(*flash & 0x80)) ; - } - break; - } - *flash = 0x40; - eieio(); - *flash++ = *data++; - eieio(); - while (!(*flash & 0x80)) ; - cnt--; - } - clr_ci(); -} - -static void -write_flash_page(unsigned long offset, unsigned short *data) -{ - int i = 0; - - for (i = 0; i < BUFSIZE; i += 32, offset += 32) { - write_flash(offset, ((unsigned char *)data + i)); - } -} - -/* - * 0 reject temporary image - * 1 commit temporary image - * */ -static int -copy_flash(short mode) -{ - volatile unsigned char *flash = (volatile unsigned char *)FLASH; - uint64_t blockCnt; - uint64_t hash = 0; - short notmode = mode ^ 0x1; - - if (bmc_set_flashside(notmode) != notmode) { - return -1; - } - printf("\r\nErasing Flash: 0x "); - - for (blockCnt = 0; blockCnt <= FLASHSIZE; blockCnt += FLASH_BLOCK_SIZE) { - print_block(blockCnt); - erase_flash_block(blockCnt); - } - enter_data_mode(); - progress = FLASHSIZE / 38; - print_writing(); - - for (blockCnt = 0; blockCnt <= FLASHSIZE; blockCnt += BUFSIZE) { - uint64_t *srcPtr = (uint64_t *)(flash + blockCnt); - uint64_t *destPtr = (uint64_t *)manage_flash_buffer; - uint64_t cnt = BUFSIZE / 8; - if (bmc_set_flashside(mode) != mode) { - return -1; - } - enter_data_mode(); - set_ci(); - while (cnt--) { - *destPtr++ = *srcPtr++; - } - clr_ci(); - - if (bmc_set_flashside(notmode) != notmode) { - return -1; - } - write_flash_page(blockCnt, - (unsigned short *)manage_flash_buffer); - - /* progress output... */ - print_progress(); - if (blockCnt > hash * progress) { - print_hash(); - hash++; - } - } - enter_data_mode(); - if (bmc_set_flashside(mode) != mode) { - return -1; - } - printf("\b#\n"); - return 0; -} - -/* - * Function: ibm_manage_flash_image - * Input: - * r3: rtas parm structure - * token: 46 - * in: 1 - * out: 1 - * parm0: 0 reject temporary image - * 1 commit temporary image - * Output: - * parm1: Status (hw -1, busy -2, parameter error -3 - * -9001 cannot overwrite the active firmware image) - * - */ - -void -rtas_ibm_manage_flash_image(rtas_args_t *rtas_args) -{ - int side; - int result = 0; - short mode = rtas_args->args[0]; - - if (mode < 0 || mode > 1) { - rtas_args->args[rtas_args->nargs] = -3; - return; - } - side = bmc_get_flashside(); - if (side == 0) { - /* we are on the permanent side */ - if (mode != 0) { - rtas_args->args[rtas_args->nargs] = -9001; - return; - } - } else if (side == 1) { - /* we are on the temporary side */ - if (mode != 1) { - rtas_args->args[rtas_args->nargs] = -9001; - return; - } - } else { - rtas_args->args[rtas_args->nargs] = -1; - return; - } - - result = copy_flash(mode); - bmc_set_flashside(mode); - enter_data_mode(); - rtas_args->args[rtas_args->nargs] = result; -} - -/** - * check, if we find the FLASHFS_MAGIC token in bl - **/ -static uint8_t -check_magic(uint64_t *bl, int version) -{ - struct stH *pHeader; - - if (version == 1) { - /* version 1 blocklist */ - /* if block list size <= 0x10, it is only block list header */ - /* and address of block list extension, so look at the extension... */ - while ((*bl & 0x00FFFFFFFFFFFFFFUL) <= 0x10) - bl = (uint64_t *)bl[1]; - - /* block list item 2 _should_ be the address of our flashfs image */ - pHeader = (struct stH *)(bl[2] + 0x28); - /* printf("FlashFS Magic: \"%#s\"\r\n", pHeader->magic); */ - return strncmp(pHeader->magic, FLASHFS_MAGIC, 8); - } else { - /* block list item 1 _should_ be the address of our flashfs image */ - pHeader = (struct stH *)(bl[1] + 0x28); - /* printf("FlashFS Magic: \"%#s\"\r\n", pHeader->magic); */ - return strncmp(pHeader->magic, FLASHFS_MAGIC, 8); - } -} - -static void -get_image_name(char *buffer, int maxsize) -{ - volatile struct stH *flash_header = (volatile struct stH *)(SB_FLASH_adr + 0x28); - /* since we cannot read the fh_magic directly from flash as a string, we need to copy it to memory */ - uint64_t magic_val = 0; - uint64_t addr; - - /* copy fh_magic to magic_val since, we cannot use it as a string from flash */ - magic_val = load64_ci((uint64_t)(flash_header->magic)); - if (strncmp((char *)&magic_val, FLASHFS_MAGIC, 8)) { - /* magic does not match */ - sprintf(buffer, "Unknown"); - buffer[maxsize - 1] = '\0'; - return; - } - addr = (uint64_t)flash_header->version; - while (--maxsize) { - *buffer = load8_ci(addr++); - if (!*buffer++) - return; - } - *buffer = '\0'; -} - -/** - * validate_flash_image - * this function checks if the flash will be updated with the given image - * @param args[0] - buffer with minimum 4K of the image to flash - * @param args[1] - size of the buffer - * @param args[2] - status: - * 0 success - * -1 hw - * -2 busy - * -3 parameter error - * @param args[3] - update result token - */ -void -rtas_ibm_validate_flash_image(rtas_args_t *rtas_args) -{ - dprintf("\nrtas_ibm_validate_flash_image\n"); - unsigned long new_image = rtas_args->args[0]; - char *ret_str = (char *)new_image; - struct stH *flash_header = (struct stH *)(new_image + 0x28); - char current_temp_version[16]; - char current_perm_version[16]; - char new_version[16]; - int side = bmc_get_flashside(); - - /* fill args[0] with the current values which is needed - * in an error case */ - - bmc_set_flashside(0); - get_image_name(current_perm_version, sizeof(current_perm_version)); - bmc_set_flashside(1); - get_image_name(current_temp_version, sizeof(current_temp_version)); - bmc_set_flashside(side); - - /* check if the candidate image if valid for this platform */ - if (strncmp(flash_header->magic, FLASHFS_MAGIC, 8)) { - /* magic does not match */ - rtas_args->args[rtas_args->nargs] = 0; - /* No update done, the candidate image is - * not valid for this platform */ - rtas_args->args[rtas_args->nargs + 1] = 2; - sprintf(ret_str, "MI %s %s\xaMI %s %s", - current_temp_version, current_perm_version, - current_temp_version, current_perm_version); - return; - } - - if (strncmp(flash_header->platform_name, (char *)sig_org, 32)) { - /* this image if for a different board */ - rtas_args->args[rtas_args->nargs] = 0; - /* No update done, the candidate image is - * not valid for this platform */ - rtas_args->args[rtas_args->nargs + 1] = 2; - sprintf(ret_str, "MI %s %s\xaMI %s %s", - current_temp_version, current_perm_version, - current_temp_version, current_perm_version); - return; - } - - /* check header crc */ - if (check_flash_image(rtas_args->args[0], 0x88, 0)) { - /* header crc failed */ - rtas_args->args[rtas_args->nargs] = 0; - /* No update done, the candidate image is - * not valid for this platform */ - rtas_args->args[rtas_args->nargs + 1] = 2; - sprintf(ret_str, "MI %s %s\xaMI %s %s", - current_temp_version, current_perm_version, - current_temp_version, current_perm_version); - return; - } - memcpy(new_version, flash_header->version, 16); - sprintf(ret_str, "MI %s %s\xaMI %s %s", current_temp_version, - current_perm_version, new_version, current_perm_version); - rtas_args->args[rtas_args->nargs] = 0; - - if (strncmp(new_version, current_temp_version, 16) >= 0) - rtas_args->args[rtas_args->nargs + 1] = 0; - else - rtas_args->args[rtas_args->nargs + 1] = 6; -} - -/* - * Function: ibm_update_flash_64 - * Input: - * r3: rtas parm structure - * token: 7 - * in: 1 - * out: 1 - * parm0: A real pointer to a block list - * Output: - * parm1: Status (hw -1, bad image -3, programming failed -4) - * - * Description: flash if addresses above 4GB have to be addressed - */ -void -rtas_update_flash(rtas_args_t *rtas_args) -{ - void *bl = (void *)(uint64_t)rtas_args->args[0]; - int version = get_block_list_version((unsigned char *)bl); - uint64_t erase_size; - unsigned int i; - int perm_check = 1; - -#ifdef DEBUG - dump_blocklist(bl, version); -#endif - - /* from SLOF we pass a second (unofficial) parameter, if this parameter is 1, we do not - * check wether we are on permanent side. Needed for update-flash -c to work! */ - if ((rtas_args->nargs > 1) && (rtas_args->args[1] == 1)) - perm_check = 0; - - /* check magic string */ - printf("\r\nChecking magic string : "); - if (check_magic(bl, version) != 0) { - printf("failed!\n"); - rtas_args->args[rtas_args->nargs] = -3; /* bad image */ - return; - } - printf("succeeded!\n"); - - /* check platform */ - printf("Checking platform : "); - if (check_platform(bl, 0x48, version) == -1) { - printf("failed!\n"); - rtas_args->args[rtas_args->nargs] = -3; /* bad image */ - return; - } - printf("succeeded!\n"); - - /* checkcrc */ - printf("Checking CRC : "); - /* the actual CRC is included at the end of the flash image, thus the resulting CRC must be 0! */ - if (image_check_crc(bl, version) != 0) { - printf("failed!\n"); - rtas_args->args[1] = -3; /* bad image */ - return; - } - printf("succeeded!\n"); - - /* check if we are running on P - * if so, let's switch to temp and flash temp */ - if (bmc_get_flashside() == 0 && perm_check) { - printf("Set flashside: "); - bmc_set_flashside(1); - printf("Temp!\n"); - } - -#ifdef DEBUG - rtas_args_t ra; - ra.args[0] = 0x100; /* size; */ - ra.args[1] = flashOffset; - ra.nargs = 2; - - rtas_dump_flash(&ra); - printf("\n"); -#endif - - size = get_size(bl, version); - erase_size = (size + (FLASH_BLOCK_SIZE - 1)) & ~(FLASH_BLOCK_SIZE - 1); - dprintf("Erasing: size: %#x, erase_size: %#x, FLASH_BLOCK_SIZE: %#x\n", - size, erase_size, FLASH_BLOCK_SIZE); - - progress = size / 39; - printf("Erasing : 0x%08x", 0); - for (i = 0; i < erase_size; i += FLASH_BLOCK_SIZE) { - print_block(i); - erase_flash_block(i); - } - - enter_data_mode(); -#ifdef DEBUG - rtas_dump_flash(&ra); - printf("\n"); -#endif - print_writing(); - write_block_list(bl, version); - printf("\b#\n"); - enter_data_mode(); - -#ifdef DEBUG - rtas_dump_flash(&ra); - printf("\n"); -#endif - - /* checkcrc */ - printf("Recheck CRC : "); - if (check_flash_image(FLASH + flashOffset, size, 0) != 0) { - /* failed */ - printf("failed!\n\r"); - dprintf("flash_addr: %#x, flashOffset: %#x, size: %#x\n", FLASH, - flashOffset, size); - dprintf("crc: %#x\n", - check_flash_image(FLASH + flashOffset, size, 0)); - rtas_args->args[rtas_args->nargs] = -4; /* programming failed */ - return; - } - printf("succeeded!\n"); - rtas_args->args[rtas_args->nargs] = 0; -} - -/* - * Function: ibm_update_flash_64_and_reboot - * Input: - * r3: rtas parm structure - * token: 27 - * in: 1 - * out: 1 - * parm0: A real pointer to a block list - * Output: - * parm1: Status (hw -1, bad image -3, programming failed -4) - * Currently -4 and -1 are not returned - * - * Description: flash and reboot if addresses above 4GB have to be addressed - */ -void -rtas_ibm_update_flash_64_and_reboot(rtas_args_t *rtas_args) -{ - rtas_update_flash(rtas_args); - dprintf("rc: %#d\n", rtas_args->args[rtas_args->nargs]); - if (rtas_args->args[rtas_args->nargs] == 0) { - rtas_system_reboot(rtas_args); - } -} |