diff options
author | Yang Zhang <yang.z.zhang@intel.com> | 2015-08-28 09:58:54 +0800 |
---|---|---|
committer | Yang Zhang <yang.z.zhang@intel.com> | 2015-09-01 12:44:00 +0800 |
commit | e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch) | |
tree | 66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/SLOF/board-js2x/rtas | |
parent | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff) |
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5
Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/roms/SLOF/board-js2x/rtas')
-rw-r--r-- | qemu/roms/SLOF/board-js2x/rtas/Makefile | 89 | ||||
-rw-r--r-- | qemu/roms/SLOF/board-js2x/rtas/i2c_bmc.oco | bin | 0 -> 22608 bytes | |||
-rw-r--r-- | qemu/roms/SLOF/board-js2x/rtas/ipmi_oem.oco | bin | 0 -> 5432 bytes | |||
-rw-r--r-- | qemu/roms/SLOF/board-js2x/rtas/rtas_board.c | 218 | ||||
-rw-r--r-- | qemu/roms/SLOF/board-js2x/rtas/rtas_board.h | 45 | ||||
-rw-r--r-- | qemu/roms/SLOF/board-js2x/rtas/rtas_flash.c | 614 | ||||
-rw-r--r-- | qemu/roms/SLOF/board-js2x/rtas/rtas_flash.h | 20 | ||||
-rw-r--r-- | qemu/roms/SLOF/board-js2x/rtas/rtas_i2c_bmc.h | 27 | ||||
-rw-r--r-- | qemu/roms/SLOF/board-js2x/rtas/rtas_ipmi_bmc.h | 21 | ||||
-rw-r--r-- | qemu/roms/SLOF/board-js2x/rtas/rtas_out.c | 120 | ||||
-rw-r--r-- | qemu/roms/SLOF/board-js2x/rtas/rtas_pci.c | 116 | ||||
-rw-r--r-- | qemu/roms/SLOF/board-js2x/rtas/rtas_table.c | 45 |
12 files changed, 1315 insertions, 0 deletions
diff --git a/qemu/roms/SLOF/board-js2x/rtas/Makefile b/qemu/roms/SLOF/board-js2x/rtas/Makefile new file mode 100644 index 000000000..5ab5c34c7 --- /dev/null +++ b/qemu/roms/SLOF/board-js2x/rtas/Makefile @@ -0,0 +1,89 @@ +# ***************************************************************************** +# * 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 ../Makefile.dirs + +include $(TOPBRDDIR)/config +include $(TOPCMNDIR)/make.rules + + +LDFLAGS = -nostdlib +CPPFLAGS = -I. -I$(LIBCMNDIR)/libc/include -I$(LIBCMNDIR)/libipmi -I$(INCLBRDDIR) \ + -I$(INCLCMNDIR) -I$(RTASCMNDIR) -I$(INCLCMNDIR)/$(CPUARCH) +ASFLAGS = -Wa,-mregnames $(FLAG) +CFLAGS += -Wall -Wextra -O2 -msoft-float -ffreestanding $(FLAG) + +# Board specific RTAS files: +BOARD_SRC_ASM = +BOARD_SRC_C = rtas_flash.c rtas_board.c rtas_pci.c \ + rtas_out.c rtas_table.c +BOARD_SRCS = $(BOARD_SRC_ASM) $(BOARD_SRC_C) +BOARD_OBJ = $(BOARD_SRC_ASM:%.S=%.o) $(BOARD_SRC_C:%.c=%.o) $(BOARD_OCO:%.oco=%.o) +BOARD_OCO = i2c_bmc.oco ipmi_oem.oco + + +# Common RTAS files (from $(RTASCMNDIR) directory): +RTAS_SRC_ASM = rtas_entry.S rtas_common.S reloc.S +RTAS_SRC_C = rtas_call.c +RTAS_SRCS = $(RTAS_SRC_ASM) $(RTAS_SRC_C) +RTAS_OBJ = $(RTAS_SRC_ASM:%.S=%.o) $(RTAS_SRC_C:%.c=%.o) + +RTAS_FLASH_SRC = block_lists.c +RTAS_FLASH_OBJ = $(RTAS_FLASH_SRC:%.c=$(RTASCMNDIR)/flash/%.o) + +# Additional object files: +EXTRA_OBJ = ../llfw/hw.o ../../lib/libc.a ../../lib/libipmi.a + +OBJS = $(RTAS_OBJ:%=$(RTASCMNDIR)/%) $(BOARD_OBJ) $(EXTRA_OBJ) \ + $(RTAS_FLASH_OBJ) + + +all: Makefile.dep rtas.bin + +rtas.bin: rtas + $(OBJCOPY) -O binary $< $@ + +rtas: $(RTASCMNDIR)/rtas.lds $(OBJS) reloc_table.o + $(LD) $(LDFLAGS) -o $@ -T $(RTASCMNDIR)/rtas.lds $(OBJS) reloc_table.o + +reloc_table.o: $(TOOLSDIR)/gen_reloc_table $(OBJS) + $(TOOLSDIR)/create_reloc_table.sh --ld "$(ONLY_LD)" --ldflags "$(LDFLAGS)" \ + --lds "$(RTASCMNDIR)/rtas.lds" --objcopy "$(OBJCOPY)" $(OBJS) + +$(TOOLSDIR)/gen_reloc_table: $(TOOLSDIR)/gen_reloc_table.c + $(MAKE) -C $(TOOLSDIR) gen_reloc_table + +../../lib/libc.a: + $(MAKE) -C ../../lib + +clean: + $(MAKE) -C ../../lib clean + rm -f $(OBJS) reloc_table.o rtas rtas.bin + +distclean : clean + rm -f Makefile.dep + + +# Rules for creating the dependency file: +depend: + $(CC) -MM $(CPPFLAGS) $(CFLAGS) $(BOARD_SRCS) > Makefile.dep + $(CC) -MM $(CPPFLAGS) $(CFLAGS) $(RTAS_SRCS:%=$(RTASCMNDIR)/%) \ + | sed -e '/:/s,^,$(RTASCMNDIR)/,' >> Makefile.dep +Makefile.dep: + $(MAKE) depend + +# Include dependency file if available: +ifneq (,$(wildcard Makefile.dep)) +include Makefile.dep +endif +%.o: %.oco + cp -f $< $@ diff --git a/qemu/roms/SLOF/board-js2x/rtas/i2c_bmc.oco b/qemu/roms/SLOF/board-js2x/rtas/i2c_bmc.oco Binary files differnew file mode 100644 index 000000000..004e7f2e5 --- /dev/null +++ b/qemu/roms/SLOF/board-js2x/rtas/i2c_bmc.oco diff --git a/qemu/roms/SLOF/board-js2x/rtas/ipmi_oem.oco b/qemu/roms/SLOF/board-js2x/rtas/ipmi_oem.oco Binary files differnew file mode 100644 index 000000000..ae401eafe --- /dev/null +++ b/qemu/roms/SLOF/board-js2x/rtas/ipmi_oem.oco diff --git a/qemu/roms/SLOF/board-js2x/rtas/rtas_board.c b/qemu/roms/SLOF/board-js2x/rtas/rtas_board.c new file mode 100644 index 000000000..7f7409d9f --- /dev/null +++ b/qemu/roms/SLOF/board-js2x/rtas/rtas_board.c @@ -0,0 +1,218 @@ +/****************************************************************************** + * 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 <stdint.h> +#include <rtas.h> +#include "rtas_board.h" +#include <bmc.h> +#include <rtas_i2c_bmc.h> +#include <rtas_ipmi_bmc.h> +#include "libipmi.h" +#include <hw.h> + +void io_init(void); +short reg_get_flashside(void); +void rtas_init(void); + +typedef struct { + uint64_t r3; + uint64_t addr; + volatile uint64_t id; +} slave_t; + +volatile slave_t rtas_slave_interface; + +static void +rtas_slave_loop(volatile slave_t * pIface) +{ + uint64_t mask = pIface->id; + pIface->id = 0; + while (pIface->id != mask); { + int dly = 0x1000; + while (dly--); + } + pIface->id = 0; + asm volatile (" mr 3,%0 ; mtctr %1 ; bctr " + ::"r"(pIface->r3), "r"(pIface->addr)); +} + +void +rtas_fetch_slaves(rtas_args_t * pArgs) +{ + int retVal = 0; + int idx = 0; + uint32_t mask = pArgs->args[0] & 0xFFFFFFFE; + uint64_t *rtas_slave_loop_ptr = (uint64_t *)rtas_slave_loop; + while (mask) { + if (mask & 0x1) { + rtas_slave_interface.id = idx | 0x100; + *(int *) 0x3fc0 = (int)(unsigned long) &rtas_slave_interface; // r3 + *(int *) 0x3f80 = *rtas_slave_loop_ptr; // addr + *(int *) 0x3fa0 = idx | 0x100; // pid + while (rtas_slave_interface.id); + } + mask >>= 1; + idx++; + } + pArgs->args[pArgs->nargs] = retVal; +} + +void +rtas_start_cpu(rtas_args_t * pArgs) +{ + int retVal = 0; + int idx = pArgs->args[0]; // pid + rtas_slave_interface.r3 = pArgs->args[2]; // r3 + rtas_slave_interface.addr = pArgs->args[1]; // addr + asm(" sync "); + rtas_slave_interface.id = idx | 0x100; // pid + while (rtas_slave_interface.id); + pArgs->args[pArgs->nargs] = retVal; +} + +void +rtas_read_vpd(rtas_args_t * pArgs) +{ + pArgs->args[pArgs->nargs] = + bmc_read_vpd((uint8_t *) (uint64_t) pArgs->args[2], pArgs->args[1], + pArgs->args[0]); +} + +void +rtas_write_vpd(rtas_args_t * pArgs) +{ + pArgs->args[pArgs->nargs] = + bmc_write_vpd((uint8_t *) (uint64_t) pArgs->args[2], pArgs->args[1], + pArgs->args[0]); +} + +void +rtas_set_indicator(rtas_args_t * pArgs) +{ + pArgs->args[pArgs->nargs] = -1; +} + +void +rtas_event_scan(rtas_args_t * pArgs) +{ + pArgs->args[pArgs->nargs] = -1; +} + +void +rtas_stop_bootwatchdog(rtas_args_t * pArgs) +{ + pArgs->args[pArgs->nargs] = bmc_stop_bootwatchdog(); +} + +void +rtas_set_bootwatchdog(rtas_args_t * pArgs) +{ + pArgs->args[pArgs->nargs] = bmc_set_bootwatchdog(pArgs->args[0]); +} + +void +rtas_set_flashside(rtas_args_t * pArgs) +{ + pArgs->args[pArgs->nargs] = bmc_set_flashside(pArgs->args[0]); +} + +void +rtas_get_flashside(rtas_args_t * pArgs) +{ + int retVal = bmc_get_flashside(); + pArgs->args[pArgs->nargs] = retVal; +} + +void +rtas_flash_test(rtas_args_t * pArgs) +{ + pArgs->args[pArgs->nargs] = -1; +} + +void +rtas_system_reboot(rtas_args_t * pArgs) +{ + bmc_system_reboot(); + pArgs->args[pArgs->nargs] = -1; +} + +void +rtas_power_off(rtas_args_t * pArgs) +{ + bmc_power_off(); + pArgs->args[pArgs->nargs] = -1; +} + +void +rtas_get_blade_descr(rtas_args_t * pArgs) +{ + uint8_t *buffer = (uint8_t *) (uint64_t) pArgs->args[0]; + uint32_t maxlen = pArgs->args[1]; + uint32_t retlen = 0; + uint32_t retval = bmc_get_blade_descr(buffer, maxlen, &retlen); + pArgs->args[pArgs->nargs] = retlen; + pArgs->args[pArgs->nargs + 1] = retval; +} + +// for JS20 cannot read blade descr +static uint32_t +dummy_get_blade_descr(uint8_t *dst, uint32_t maxlen, uint32_t *len) +{ + // to not have a warning we need to do _something_ with *dst and maxlen... + *dst = *dst; + maxlen = maxlen; + *len = 0; + return -1; +} + +/* read flashside from register */ +short +reg_get_flashside(void) +{ + short retVal; + uint8_t val = load8_ci(0xf4003fe3); + if (val & 0x80) { + // temp + retVal = 1; + } else { + // perm + retVal = 0; + } + return retVal; +} + +void +rtas_init(void) +{ + io_init(); + if (u4Flag) { + bmc_system_reboot = ipmi_system_reboot; + bmc_power_off = ipmi_power_off; + bmc_set_flashside = ipmi_set_flashside; + bmc_get_flashside = reg_get_flashside; + bmc_stop_bootwatchdog = ipmi_oem_stop_bootwatchdog; + bmc_set_bootwatchdog = ipmi_oem_set_bootwatchdog; + bmc_read_vpd = ipmi_oem_read_vpd; + bmc_write_vpd = ipmi_oem_write_vpd; + bmc_get_blade_descr = ipmi_oem_get_blade_descr; + } else { + bmc_system_reboot = i2c_system_reboot; + bmc_power_off = i2c_power_off; + bmc_set_flashside = i2c_set_flashside; + bmc_get_flashside = i2c_get_flashside; + bmc_stop_bootwatchdog = i2c_stop_bootwatchdog; + bmc_set_bootwatchdog = i2c_set_bootwatchdog; + bmc_read_vpd = i2c_read_vpd; + bmc_write_vpd = i2c_write_vpd; + bmc_get_blade_descr = dummy_get_blade_descr; + } +} diff --git a/qemu/roms/SLOF/board-js2x/rtas/rtas_board.h b/qemu/roms/SLOF/board-js2x/rtas/rtas_board.h new file mode 100644 index 000000000..06766e143 --- /dev/null +++ b/qemu/roms/SLOF/board-js2x/rtas/rtas_board.h @@ -0,0 +1,45 @@ +/****************************************************************************** + * 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 + *****************************************************************************/ + +#ifndef __RTAS_BOARD_H +#define __RTAS_BOARD_H + +#include <stddef.h> + +extern volatile unsigned char u4Flag; + +void rtas_ibm_read_pci_config(rtas_args_t * pArgs); +void rtas_ibm_write_pci_config(rtas_args_t * pArgs); +void rtas_read_pci_config(rtas_args_t * pArgs); +void rtas_write_pci_config(rtas_args_t * pArgs); +void rtas_system_reboot(rtas_args_t * pArgs); +void rtas_power_off(rtas_args_t * pArgs); +void rtas_display_character(rtas_args_t * pArgs); +void rtas_flash_test(rtas_args_t * pArgs); +void rtas_ibm_update_flash_64_and_reboot(rtas_args_t * pArgs); +void rtas_set_indicator(rtas_args_t * pArgs); +void rtas_event_scan(rtas_args_t * pArgs); +void rtas_ibm_manage_flash_image(rtas_args_t * pArgs); +void rtas_ibm_validate_flash_image(rtas_args_t * pArgs); +void rtas_update_flash(rtas_args_t * pArgs); +void rtas_set_flashside(rtas_args_t * pArgs); +void rtas_get_flashside(rtas_args_t * pArgs); +void rtas_dump_flash(rtas_args_t * pArgs); +void rtas_start_cpu(rtas_args_t * pArgs); +void rtas_read_vpd(rtas_args_t * pArgs); +void rtas_write_vpd(rtas_args_t * pArgs); +void rtas_fetch_slaves(rtas_args_t * pArgs); +void rtas_stop_bootwatchdog(rtas_args_t * pArgs); +void rtas_get_blade_descr(rtas_args_t * pArgs); +void rtas_set_bootwatchdog(rtas_args_t * pArgs); + +#endif /* __RTAS_BOARD_H */ diff --git a/qemu/roms/SLOF/board-js2x/rtas/rtas_flash.c b/qemu/roms/SLOF/board-js2x/rtas/rtas_flash.c new file mode 100644 index 000000000..189878da9 --- /dev/null +++ b/qemu/roms/SLOF/board-js2x/rtas/rtas_flash.c @@ -0,0 +1,614 @@ +/****************************************************************************** + * 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); + } +} diff --git a/qemu/roms/SLOF/board-js2x/rtas/rtas_flash.h b/qemu/roms/SLOF/board-js2x/rtas/rtas_flash.h new file mode 100644 index 000000000..3eec45d27 --- /dev/null +++ b/qemu/roms/SLOF/board-js2x/rtas/rtas_flash.h @@ -0,0 +1,20 @@ +/****************************************************************************** + * 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 <southbridge.h> + +#define FLASHSIZE FLASH_LENGTH +#define FLASH SB_FLASH_adr +#define BUFSIZE 4096 +#define FLASH_BLOCK_SIZE 0x20000 + +void write_flash(unsigned long offset, unsigned char *data); diff --git a/qemu/roms/SLOF/board-js2x/rtas/rtas_i2c_bmc.h b/qemu/roms/SLOF/board-js2x/rtas/rtas_i2c_bmc.h new file mode 100644 index 000000000..e46de880e --- /dev/null +++ b/qemu/roms/SLOF/board-js2x/rtas/rtas_i2c_bmc.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * 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 + *****************************************************************************/ + +#ifndef __RTAS_I2C_BMC_H +#define __RTAS_I2C_BMC_H + +#include <stddef.h> + +void i2c_system_reboot (void); +void i2c_power_off (void); +short i2c_set_flashside (short mode); +short i2c_get_flashside (void); +int i2c_stop_bootwatchdog (void); +uint32_t i2c_read_vpd (uint8_t *dst, uint32_t len, uint32_t offset); +uint32_t i2c_write_vpd (uint8_t *src, uint32_t len, uint32_t offset); +int i2c_set_bootwatchdog(unsigned short seconds); + +#endif /* __RTAS_I2C_BMC_H */ diff --git a/qemu/roms/SLOF/board-js2x/rtas/rtas_ipmi_bmc.h b/qemu/roms/SLOF/board-js2x/rtas/rtas_ipmi_bmc.h new file mode 100644 index 000000000..00532d4c9 --- /dev/null +++ b/qemu/roms/SLOF/board-js2x/rtas/rtas_ipmi_bmc.h @@ -0,0 +1,21 @@ +/****************************************************************************** + * 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 + *****************************************************************************/ + +#ifndef __RTAS_IPMI_BMC_H +#define __RTAS_IPMI_BMC_H + +#include <stddef.h> + +short ipmi_set_flashside (short mode); +short ipmi_get_flashside (void); + +#endif /* __RTAS_IPMI_BMC_H */ diff --git a/qemu/roms/SLOF/board-js2x/rtas/rtas_out.c b/qemu/roms/SLOF/board-js2x/rtas/rtas_out.c new file mode 100644 index 000000000..ce4c00bd2 --- /dev/null +++ b/qemu/roms/SLOF/board-js2x/rtas/rtas_out.c @@ -0,0 +1,120 @@ +/****************************************************************************** + * 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 <stdlib.h> +#include <stdint.h> +#include <unistd.h> +#include <rtas.h> +#include <hw.h> +#include "rtas_board.h" + +volatile unsigned char *uart; +volatile unsigned char u4Flag; + +void io_init(void); +unsigned long check_flash_image(unsigned long rombase, unsigned long length, + unsigned long start_crc); + +void +io_init(void) +{ + // read ID register: only if it is a PC87427, enable serial2 + store8_ci(0xf400002e, 0x20); + if (load8_ci(0xf400002f) != 0xf2) { + uart = (volatile unsigned char *) 0xf40003f8; + u4Flag = 0; + } else { + uart = (volatile unsigned char *) 0xf40002f8; + u4Flag = 1; + } +} + +static void +display_char(char ch) +{ + volatile int i = 0; + volatile unsigned char *uart = (volatile unsigned char *) 0xf40002f8; + int cnt = 2; + while (cnt--) { + set_ci(); + while (!(uart[5] & 0x20)) { + i++; + } + uart[0] = ch; + clr_ci(); + uart += 0x100; + } +} + +ssize_t +write(int fd __attribute((unused)), const void *buf, size_t cnt) +{ + while (cnt--) { + display_char(*(char *) buf); + if (*(char *) buf++ == '\n') + display_char('\r'); + } + return 0; +} + +void * +sbrk(int incr __attribute((unused))) +{ + return (void *) -1; +} + + + +void +rtas_display_character(rtas_args_t * pArgs) +{ + int retVal = 0; + display_char((char) pArgs->args[0]); + pArgs->args[1] = retVal; +} + +unsigned long +check_flash_image(unsigned long rombase, unsigned long length, + unsigned long start_crc) +{ + const uint32_t CrcTableHigh[16] = { + 0x00000000, 0x4C11DB70, 0x9823B6E0, 0xD4326D90, + 0x34867077, 0x7897AB07, 0xACA5C697, 0xE0B41DE7, + 0x690CE0EE, 0x251D3B9E, 0xF12F560E, 0xBD3E8D7E, + 0x5D8A9099, 0x119B4BE9, 0xC5A92679, 0x89B8FD09 + }; + const uint32_t CrcTableLow[16] = { + 0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, + 0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005, + 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61, + 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD + }; + + char *Buffer = (char *) rombase; + uint32_t AccumCRC = start_crc; + char val; + uint32_t Temp; + while (length-- > 0) { + set_ci(); + val = *Buffer; + clr_ci(); + Temp = ((AccumCRC >> 24) ^ val) & 0x000000ff; + AccumCRC <<= 8; + AccumCRC ^= CrcTableHigh[Temp / 16]; + AccumCRC ^= CrcTableLow[Temp % 16]; + ++Buffer; + } + return AccumCRC; +} diff --git a/qemu/roms/SLOF/board-js2x/rtas/rtas_pci.c b/qemu/roms/SLOF/board-js2x/rtas/rtas_pci.c new file mode 100644 index 000000000..55dbf5336 --- /dev/null +++ b/qemu/roms/SLOF/board-js2x/rtas/rtas_pci.c @@ -0,0 +1,116 @@ +/****************************************************************************** + * 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 <stdint.h> +#include <rtas.h> +#include <hw.h> +#include "rtas_board.h" + +void +rtas_ibm_read_pci_config (rtas_args_t *rtas_args) +{ + int retVal = 0; + uint64_t addr = ((uint64_t) rtas_args->args[1]) << 32; // high 32 bits of PHB UID + addr |= (rtas_args->args[2] & 0xFFFFFFFF); // low 32 bits of PHB UID + addr |= (rtas_args->args[0] & 0x00FFFFFF); // bus, devfn, offset + unsigned int size = rtas_args->args[3]; + + /* Check for bus != 0 on PCI/PCI-X (PHB UID = 0xf2000000) */ + if (((addr & 0xf2000000) == 0xf2000000) && (addr & 0xff0000)) + addr += 0x1000000; + + if (size == 1) + rtas_args->args[5] = load8_ci(addr); + else if (size == 2) + rtas_args->args[5] = bswap16_load(addr); + else if (size == 4) + rtas_args->args[5] = bswap32_load(addr); + else + retVal = -3; /* Bad arguments */ + + rtas_args->args[4] = retVal; +} + +void +rtas_ibm_write_pci_config (rtas_args_t *rtas_args) +{ + int retVal = 0; + uint64_t addr = ((uint64_t) rtas_args->args[1]) << 32; // high 32 bits of PHB UID + addr |= (rtas_args->args[2] & 0xFFFFFFFF); // low 32 bits of PHB UID + addr |= (rtas_args->args[0] & 0x00FFFFFF); // bus, devfn, offset + unsigned int size = rtas_args->args[3]; + + addr |= 0xf2000000; + + /* Check for bus != 0 on PCI/PCI-X (PHB UID = 0xf2000000) */ + if (((addr & 0xf2000000) == 0xf2000000) && (addr & 0xff0000)) + addr += 0x1000000; + + if (size == 1) + store8_ci(addr, rtas_args->args[4]); + else if (size == 2) + bswap16_store(addr, rtas_args->args[4]); + else if (size == 4) + bswap32_store(addr, rtas_args->args[4]); + else + retVal = -3; /* Bad arguments */ + + rtas_args->args[5] = retVal; +} + +void +rtas_read_pci_config (rtas_args_t *rtas_args) +{ + int retVal = 0; + unsigned long addr = rtas_args->args[0]; + unsigned int size = rtas_args->args[1]; + addr |= 0xf2000000; + + /* Check for bus != 0 */ + if (addr & 0xff0000) + addr += 0x1000000; + + if (size == 1) + rtas_args->args[3] = load8_ci(addr); + else if (size == 2) + rtas_args->args[3] = bswap16_load(addr); + else if (size == 4) + rtas_args->args[3] = bswap32_load(addr); + else + retVal = -3; /* Bad arguments */ + + rtas_args->args[2] = retVal; +} + +void +rtas_write_pci_config (rtas_args_t *rtas_args) +{ + int retVal = 0; + unsigned long addr = rtas_args->args[0]; + unsigned int size = rtas_args->args[1]; + + addr |= 0xf2000000; + + /* Check for bus != 0 */ + if (addr & 0xff0000) + addr += 0x1000000; + + if (size == 1) + store8_ci(addr, rtas_args->args[2]); + else if (size == 2) + bswap16_store(addr, rtas_args->args[2]); + else if (size == 4) + bswap32_store(addr, rtas_args->args[2]); + else + retVal = -3; /* Bad arguments */ + + rtas_args->args[3] = retVal; +} diff --git a/qemu/roms/SLOF/board-js2x/rtas/rtas_table.c b/qemu/roms/SLOF/board-js2x/rtas/rtas_table.c new file mode 100644 index 000000000..fed4032af --- /dev/null +++ b/qemu/roms/SLOF/board-js2x/rtas/rtas_table.c @@ -0,0 +1,45 @@ +/****************************************************************************** + * 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 <stdint.h> +#include <rtas.h> +#include "rtas_table.h" +#include "rtas_board.h" + +const rtas_funcdescr_t rtas_func_tab[] = { + {"ibm,read-pci-config", rtas_ibm_read_pci_config, 0}, + {"ibm,write-pci-config", rtas_ibm_write_pci_config, 0}, + {"system-reboot", rtas_system_reboot, 0}, + {"power-off", rtas_power_off, 0}, + {"set-indicator", rtas_set_indicator, 0}, + {"rtas-flash-test", rtas_flash_test, RTAS_TBLFLG_INTERNAL}, + {"ibm,update-flash-64-and-reboot", rtas_ibm_update_flash_64_and_reboot, 0}, + {"display-character", rtas_display_character, 0}, + {"event-scan", rtas_event_scan, 0}, + {"ibm,manage-flash-image", rtas_ibm_manage_flash_image, 0}, + {"ibm,validate-flash-image", rtas_ibm_validate_flash_image, 0}, + {"ibm,update-flash-64", rtas_update_flash, 0}, + {"rtas-set-flashside", rtas_set_flashside, 0}, + {"rtas-get-flashside", rtas_get_flashside, 0}, + {"rtas-dump-flash", rtas_dump_flash, RTAS_TBLFLG_INTERNAL}, + {"start-cpu", rtas_start_cpu, 0}, + {"msg-read-vpd", rtas_read_vpd, RTAS_TBLFLG_INTERNAL}, + {"msg-write-vpd", rtas_write_vpd, RTAS_TBLFLG_INTERNAL}, + {"read-pci-config", rtas_read_pci_config, 0}, + {"write-pci-config", rtas_write_pci_config, 0}, + {"rtas-fetch-slaves", rtas_fetch_slaves, RTAS_TBLFLG_INTERNAL}, + {"rtas-stop-bootwatchdog", rtas_stop_bootwatchdog, RTAS_TBLFLG_INTERNAL}, + {"rtas-set-bootwatchdog", rtas_set_bootwatchdog, RTAS_TBLFLG_INTERNAL}, + {"rtas-get-blade-descr", rtas_get_blade_descr, RTAS_TBLFLG_INTERNAL}, +}; + +const int rtas_func_tab_size = sizeof(rtas_func_tab) / sizeof(rtas_func_tab[0]); |