summaryrefslogtreecommitdiffstats
path: root/qemu/roms/SLOF/board-js2x/rtas/rtas_flash.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/SLOF/board-js2x/rtas/rtas_flash.c')
-rw-r--r--qemu/roms/SLOF/board-js2x/rtas/rtas_flash.c614
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);
- }
-}