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/llfw | |
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/llfw')
-rw-r--r-- | qemu/roms/SLOF/llfw/boot_abort.S | 95 | ||||
-rw-r--r-- | qemu/roms/SLOF/llfw/boot_abort.h | 37 | ||||
-rw-r--r-- | qemu/roms/SLOF/llfw/clib/Makefile.inc | 42 | ||||
-rw-r--r-- | qemu/roms/SLOF/llfw/clib/iolib.c | 47 | ||||
-rw-r--r-- | qemu/roms/SLOF/llfw/clib/iolib.h | 26 | ||||
-rw-r--r-- | qemu/roms/SLOF/llfw/io_generic/Makefile.inc | 38 | ||||
-rw-r--r-- | qemu/roms/SLOF/llfw/io_generic/io_generic.S | 129 | ||||
-rw-r--r-- | qemu/roms/SLOF/llfw/nvramlog.S | 350 | ||||
-rw-r--r-- | qemu/roms/SLOF/llfw/romfs.S | 362 | ||||
-rw-r--r-- | qemu/roms/SLOF/llfw/romfs_wrap.c | 22 |
10 files changed, 1148 insertions, 0 deletions
diff --git a/qemu/roms/SLOF/llfw/boot_abort.S b/qemu/roms/SLOF/llfw/boot_abort.S new file mode 100644 index 000000000..996bdd78a --- /dev/null +++ b/qemu/roms/SLOF/llfw/boot_abort.S @@ -0,0 +1,95 @@ +/****************************************************************************** + * 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 "macros.h" +#include "termctrl.h" +#include "boot_abort.h" +#include <cpu.h> + +#define MSG_LOOK_HDR TERM_CTRL_BRIGHT, TERM_BG_RED, TERM_FG_WHITE + +ASM_ENTRY(msg_e_crc) + .ascii MSG_LOOK_HDR + .ascii "\n\r\n\rE1001 - Boot ROM CRC failure\n\r" + .ascii TERM_CTRL_RESET, "\0" + .align 2 + +ASM_ENTRY(msg_e_nomem) + .ascii MSG_LOOK_HDR + .ascii "\n\r\n\rE1002 - Memory could not be initialized\n\r" + .ascii TERM_CTRL_RESET, "\0" + .align 2 + +ASM_ENTRY(msg_e_nofile) + .ascii MSG_LOOK_HDR + .ascii "\n\r\n\rE1003 - Firmware image incomplete" + .ascii TERM_CTRL_RESET + .ascii "\n\r internal FLS1-FFS-0.\0" + .align 2 + +ASM_ENTRY(msg_e_ierror) + .ascii MSG_LOOK_HDR + .ascii "\n\r\n\rE1004 - Unspecified Internal Firmware Error" + .ascii TERM_CTRL_RESET + .ascii "\n\r internal FLSX-SE-0.\0" + .align 2 + +/* E1005 : used in memory init code */ + +/***************************************************************************** + * Boot Abort Handler + * + * Input: + * R3 - capability informatin (i/o etc.) + * R4 - handling suggestion + * R5 - error string reference + * R6 - error number + * + * Return: + * if possible input to H8 and NVRAM log and console , then reboot/halt + * + * Input definitions: + * + * R3 bits: 63 (h8/console possible) ... add more + * R4 bits: 63 (do not attempt reboot) + * R5 reference to error message string + * R6 32-bit error enumerator + * + ******************************************************************************/ +ASM_ENTRY(boot_abort) + /* save arguments */ + mr r31, r3 + mr r30, r4 + mr r29, r5 + mr r28, r6 + + /* check if i/o is possible, if yes then print message */ + li r10, ABORT_CANIO + andi. r3, r31, r10 + bne abort_noio + + /* use i/o ..., first print reference message */ + /* then add internal number if != 0 */ + mr r3, r29 + mfspr r4, HSPRG0 /* get runbase */ + or r3, r3, r4 + bl io_print + mr r3, r28 + li r28, 0 + cmpd r3, r28 + beq 0f + bl io_printhex32 +0: + + abort_noio: + b $ // FIXME + /* never reached */ + diff --git a/qemu/roms/SLOF/llfw/boot_abort.h b/qemu/roms/SLOF/llfw/boot_abort.h new file mode 100644 index 000000000..b7082063c --- /dev/null +++ b/qemu/roms/SLOF/llfw/boot_abort.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * 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 BOOT_ABORT_H +#define BOOT_ABORT_H + +/* boot abort function suitable for assembly */ +#define BOOT_ABORT(cap, action, msg, numhint) \ + li r3, cap; \ + li r4, action; \ + LOAD32(r5, msg); \ + LOAD32(r6, numhint); \ + bl boot_abort + +/* boot abort function suitable called from c (takes r3 as hint) */ +#define BOOT_ABORT_R3HINT(cap, action, msg) \ + mr r6, r3; \ + li r3, cap; \ + li r4, action; \ + LOAD32(r5, msg); \ + bl boot_abort + +#define ABORT_CANIO (1 << 0) +#define ABORT_NOIO (1 << 1) + +#define ALTBOOT (1 << 0) +#define HALT (1 << 1) + +#endif diff --git a/qemu/roms/SLOF/llfw/clib/Makefile.inc b/qemu/roms/SLOF/llfw/clib/Makefile.inc new file mode 100644 index 000000000..70037989e --- /dev/null +++ b/qemu/roms/SLOF/llfw/clib/Makefile.inc @@ -0,0 +1,42 @@ +# ***************************************************************************** +# * 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 ../../make.rules + +CFLAGS_COMLIB = -pedantic -std=gnu99 -O0 +ASFLAGS_COMLIB = + + +COMLIBDIR = $(LLFWCMNDIR)/clib + +COMLIB_SRC_ASM = +COMLIB_SRC_C = iolib.c + +COMLIB_SRCS = $(COMLIB_SRC_ASM:%=$(COMLIBDIR)/%) \ + $(COMLIB_SRC_C:%=$(COMLIBDIR)/%) +COMLIB_OBJ_ASM = $(COMLIB_SRC_ASM:%.S=%.o) +COMLIB_OBJ_C = $(COMLIB_SRC_C:%.c=%.o) + + +comlib.o: $(COMLIB_OBJ_C) $(COMLIB_OBJ_ASM) + $(LD) $(LDFLAGS) $^ -o $@ -r + +%.o: $(LLFWCMNDIR)/clib/%.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_COMLIB) -c $< -o $@ + +%.o: $(LLFWCMNDIR)/clib/%.S + $(CC) $(CPPFLAGS) $(ASFLAGS) $(ASFLAGS_COMLIB) -c $< -o $@ + +LLFW_CLEAN_TARGETS += clean_clib +.PHONY : clean_clib +clean_clib: + rm -f $(COMLIB_OBJ_C) $(COMLIB_OBJ_ASM) comlib.o diff --git a/qemu/roms/SLOF/llfw/clib/iolib.c b/qemu/roms/SLOF/llfw/clib/iolib.c new file mode 100644 index 000000000..7f14b512d --- /dev/null +++ b/qemu/roms/SLOF/llfw/clib/iolib.c @@ -0,0 +1,47 @@ +/****************************************************************************** + * 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 <stddef.h> +#include <unistd.h> +#include "iolib.h" + +void uart_send_byte(unsigned char b) +{ + asm volatile ("":::"3","4","5","6","7"); + io_putchar(b); +} + +/** + * Standard write function for the libc. + * + * @param fd file descriptor (should always be 1 or 2) + * @param buf pointer to the array with the output characters + * @param count number of bytes to be written + * @return the number of bytes that have been written successfully + */ +ssize_t write(int fd, const void *buf, size_t count) +{ + size_t i; + char *ptr = (char *)buf; + + if (fd != 1 && fd != 2) + return 0; + + for (i = 0; i < count; i++) { + if (*ptr == '\n') + uart_send_byte('\r'); + uart_send_byte(*ptr++); + } + + return i; +} diff --git a/qemu/roms/SLOF/llfw/clib/iolib.h b/qemu/roms/SLOF/llfw/clib/iolib.h new file mode 100644 index 000000000..91450058c --- /dev/null +++ b/qemu/roms/SLOF/llfw/clib/iolib.h @@ -0,0 +1,26 @@ +/****************************************************************************** + * 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 IOLIB_H +#define IOLIB_H + +#include <stdint.h> + +#define addr_t volatile unsigned int +#define addr8_t volatile unsigned char + +extern void halt_sys (unsigned int); + +extern void uart_send_byte(unsigned char b); +extern void io_putchar(unsigned char); + +#endif diff --git a/qemu/roms/SLOF/llfw/io_generic/Makefile.inc b/qemu/roms/SLOF/llfw/io_generic/Makefile.inc new file mode 100644 index 000000000..b6607252f --- /dev/null +++ b/qemu/roms/SLOF/llfw/io_generic/Makefile.inc @@ -0,0 +1,38 @@ +# ***************************************************************************** +# * 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 +# ****************************************************************************/ + +IOGENERICDIR = $(LLFWCMNDIR)/io_generic + +IO_GENERIC_SRC_ASM = io_generic.S +IO_GENERIC_SRC_C = + +IO_GENERIC_SRCS = $(IO_GENERIC_SRC_ASM:%=$(IOGENERICDIR)/%) \ + $(IO_GENERIC_SRC_C:%=$(IOGENERICDIR)/%) +IO_GENERIC_OBJ_ASM = $(IO_GENERIC_SRC_ASM:%.S=%.o) +IO_GENERIC_OBJ_C = $(IO_GENERIC_SRC_C:%.c=%.o) + + +io_generic_lib.o: $(IO_GENERIC_OBJ_ASM) $(IO_GENERIC_OBJ_C) + $(LD) $(LDFLAGS) $^ -o $@ -r + + +%.o: $(IOGENERICDIR)/%.c + $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ + +%.o: $(IOGENERICDIR)/%.S + $(CC) $(CPPFLAGS) $(ASFLAGS) -c $< -o $@ + + +LLFW_CLEAN_TARGETS += clean_io_generic +.PHONY : clean_io_generic +clean_io_generic: + rm -f $(IO_GENERIC_OBJ_C) $(IO_GENERIC_OBJ_ASM) io_generic_lib.o diff --git a/qemu/roms/SLOF/llfw/io_generic/io_generic.S b/qemu/roms/SLOF/llfw/io_generic/io_generic.S new file mode 100644 index 000000000..9c1db41a1 --- /dev/null +++ b/qemu/roms/SLOF/llfw/io_generic/io_generic.S @@ -0,0 +1,129 @@ +/****************************************************************************** + * 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 "macros.h" +#include "calculatecrc.h" +#include "calculatecrc.h" + + .text + +/**************************************************************************** + * prints a 0-terminated string to serial console + * + * Input: + * R3 - pointer to string in memory + * + * Returns: - + * + * Modifies Registers: + * R3, R4, R5, R6, R7, R8, R9 + ****************************************************************************/ +ASM_ENTRY(io_print) + mflr r8 + mr r9, r3 + +0: + lbz r3, 0(r9) + cmpwi r3, 0 + beq 1f + bl io_putchar + addi r9, r9, 1 + b 0b +1: + mtlr r8 + blr + +/**************************************************************************** + * prints Hex integer to the UART and the NVRAM (using board io_putchar) + * + * Input: + * R3 - integer to print + * + * Returns: - + * + * Modifies Registers: + * R3, R4, R5, R6, R7, R8, R9 + ****************************************************************************/ +#define _io_gen_print_nib(reg, src, shift) \ + srdi reg, src, shift; \ + andi. reg, reg, 0x0F; \ + cmpwi reg, 0x0A; \ + blt 0f; \ + addi reg, reg, ('A'-'0'-10); \ +0:; \ + addi reg, reg, '0'; \ + bl io_putchar + +ASM_ENTRY(io_printhex64) + mflr r8 + mr r9, r3 + +_io_printhex64: + _io_gen_print_nib(r3, r9, 60) + _io_gen_print_nib(r3, r9, 56) + _io_gen_print_nib(r3, r9, 52) + _io_gen_print_nib(r3, r9, 48) + _io_gen_print_nib(r3, r9, 44) + _io_gen_print_nib(r3, r9, 40) + _io_gen_print_nib(r3, r9, 36) + _io_gen_print_nib(r3, r9, 32) +_io_printhex32: + _io_gen_print_nib(r3, r9, 28) + _io_gen_print_nib(r3, r9, 24) + _io_gen_print_nib(r3, r9, 20) + _io_gen_print_nib(r3, r9, 16) +_io_printhex16: + _io_gen_print_nib(r3, r9, 12) + _io_gen_print_nib(r3, r9, 8) +_io_printhex8: + _io_gen_print_nib(r3, r9, 4) + _io_gen_print_nib(r3, r9, 0) + + mtlr r8 + blr + +ASM_ENTRY(io_printhex32) + mflr r8 + mr r9, r3 + b _io_printhex32 + +ASM_ENTRY(io_printhex16) + mflr r8 + mr r9, r3 + b _io_printhex16 + +ASM_ENTRY(io_printhex8) + mflr r8 + mr r9, r3 + b _io_printhex8 + + +/**************************************************************************** + * print the address and its contents as 64-bit hex values + * + * Input: + * R3 - Address to read from + * + * Returns: - + * + * Modifies Registers: + * R3, R4, R5, R6, R7, R8, R9, R10 + ****************************************************************************/ +#if 0 /* currently unused */ +ASM_ENTRY(io_dump) + mflr r10 + bl io_printhex64 + li r3,':' + bl io_putchar + ld r9,0(r9) + mr r8,r10 + b _io_printhex64 +#endif diff --git a/qemu/roms/SLOF/llfw/nvramlog.S b/qemu/roms/SLOF/llfw/nvramlog.S new file mode 100644 index 000000000..3ad2de754 --- /dev/null +++ b/qemu/roms/SLOF/llfw/nvramlog.S @@ -0,0 +1,350 @@ +/****************************************************************************** + * 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 <macros.h> +#include <nvramlog.h> +#include <southbridge.h> +#include <calculatecrc.h> + +#if !defined(DISABLE_NVRAM) && !defined(RTAS_NVRAM) + +// detect overflow: if(a<b) return a else return 0 +#define NVRAM_LOG_DATA_OVERFLOW( a, b) \ + cmpd 7, a, b; \ + blt+ 7, 0f; \ + li a, 0; \ + 0: + +// get Pointer(pointer) to next byte in NVRAM data section +// and size of this data sechtion (modulo) +// modifies register pointer, modulo +#define NVRAM_POINTER_DATASIZE_BE0(pointer, modulo, address) \ + LOAD64( modulo, LLFW_LOG_BE0_LENGTH); \ + lwz pointer, LLFW_LOG_POS_POINTER(address); \ + sldi modulo, modulo, 4; \ + addi modulo, modulo,-LLFW_LOG_BE0_DATA_OFFSET +#define NVRAM_POINTER_DATASIZE_BE1(pointer, modulo, address) \ + LOAD64( modulo, LLFW_LOG_BE1_LENGTH); \ + lwz pointer, LLFW_LOG_POS_POINTER(address); \ + sldi modulo, modulo, 4; \ + addi modulo, modulo,-LLFW_LOG_BE1_DATA_OFFSET + +/**************************************************************************** + * checkLogHeaderData + * compare the fixed values in the header if any change was done since + * last initialisation. + * Flags are not checked! + * + * Retrun 0 if no manimulation was found 1 else + * + * input: + * r3 - NVRAM Base Address + * + * output: + * r3 - status: 0 = ok, 1 = corrupt + * r4 - NVRAM Base Address + * + ***************************************************************************/ +ASM_ENTRY(checkLogHeaderData) + li r4, 0 // init error flag + lbz r5, 0(r3) // check signature + addi r5, r5, -LLFW_LOG_BE0_SIGNATURE + add r4, r4, r5 + + lhz r5, LLFW_LOG_POS_LENGTH(r3) // check length + addi r5, r5, -LLFW_LOG_BE0_LENGTH + add r4, r4, r5 + + lwz r5, LLFW_LOG_POS_NAME(r3) // check name prefix + LOAD64( r6, LLFW_LOG_BE0_NAME_PREFIX) + subf r5, r6, r5 + add r4, r4, r5 + + ld r5, (LLFW_LOG_POS_NAME+4)(r3) // check name + LOAD64( r6, LLFW_LOG_BE0_NAME) + subf r5, r6, r5 + add r4, r4, r5 + + lhz r5, LLFW_LOG_POS_DATA_OFFSET(r3) //check data offset + addi r5, r5, -LLFW_LOG_BE0_DATA_OFFSET + add r4, r4, r5 + + lhz r5, LLFW_LOG_POS_FLAGS(r3) //check flags + addi r5, r5, -LLFW_LOG_BE0_FLAGS + add r4, r4, r5 + + cmpldi 7, r4, 0 + beq+ 7, 0f + li r4, 1 +0: + mr r5, r3 + mr r3, r4 + mr r4, r5 + blr +/***************************************************************************** + * checkLogPartition: check Partition Header entries and Checksum + * check also the NVRAM-Log-Partition CRC + * if Partition is not ok set the following bits to 1 + * bit 1: if Partiton Header Checksum is corrupt + * bit 2: if CRC is corrupt + * bit 3: if Header entries are corrupt + * + * input: + * r3 - NVRAM log address (BASE + NVRAM_LOG_OFFSET) + * + * output: + * r3 - CRC status + * r4 - NVRAM log address + * + * Modifies Register: R3, R4, R5, R6, R7, R8, R9 + ****************************************************************************/ +ASM_ENTRY(.checkLogPartition) + mflr r8 + mr r4, r3 // emulate "bl updateCRC_NVRAM" + li r3, 0 // with successful CRC check + li r7, 0 + cmpwi 7, r3, 0 + beq+ 7, 0f + li r7, 2 +0: + mr r3, r4 + bl .calPartitionHeaderChecksum // r3=checksum, r4=NVARM addr + lbz r6, LLFW_LOG_POS_CHECKSUM(r4) + cmpw 7, r3, r6 + beq+ 7, 0f // cal checksum must eq checksum + ori r7, r7, 1 +0: + cmpwi 7, r3, 0 + bne+ 7, 0f + ori r7, r7, 1 // 0 as checksum is invalid +0: + mr r3, r4 + bl checkLogHeaderData + cmpdi 7, r3, 0 + beq+ 7, 0f + ori r7, r7, 4 +0: + mr r3, r7 + mtlr r8 + blr +/***************************************************************************** + * checkinitLog: check the NVRAM Log Partition Header + * initialize the NVRAM if the Header was modified + * + * input: + * r3 - NVRAM BASE address + * + * output: + * r3 - 0 = check ok, no new header written + * r3 - 1 = check not ok, header and NVRAM initialized + * r4 - NVRAM log address + * + * Modifies Register: R3, R4, R5, R6, R7, r8, r9 + ****************************************************************************/ +// init is done if checkLogPartiton returns not 0 (= check failed) +ASM_ENTRY(.checkinitLog) +ASM_ENTRY(checkinitLog) + mflr r9 + bl .checkLogPartition //r3..r8, r4_out = r3_in + mtlr r9 + + cmpwi 7, r3, 0 + mr r3, r4 // r3=NVRAM_LOG address + bne- 7, .initLog // if header is not ok, init header + li r3, 0 + blr // header OK, return 0 + + +/* this is basically just a copy of .initLog + registers used: r3, r4, r5, r6, r7, r9*/ +init_log_2nd_be: + mflr r9 + li r6, LLFW_LOG_BE0_LENGTH + mulli r6, r6, 0x10 + add r6, r7, r6 + li r5, LLFW_LOG_BE1_SIGNATURE + li r4, LLFW_LOG_BE1_LENGTH + stb r5, 0(r6) + sth r4, LLFW_LOG_POS_LENGTH(r6) + li r5, LLFW_LOG_BE1_DATA_OFFSET + li r4, LLFW_LOG_BE1_FLAGS + sth r5, LLFW_LOG_POS_DATA_OFFSET(r6) + sth r4, LLFW_LOG_POS_FLAGS(r6) + li r5, 1 + + LOAD32( r4, LLFW_LOG_BE1_NAME_PREFIX) + stw r5, LLFW_LOG_POS_POINTER(r6) + stw r4, (LLFW_LOG_POS_NAME+0x00)(r6) + LOAD64( r5, LLFW_LOG_BE1_NAME) + std r5, (LLFW_LOG_POS_NAME+0x04)(r6) + mr r3, r6 + bl .calPartitionHeaderChecksum + stb r3, LLFW_LOG_POS_CHECKSUM(r6) + mtlr r9 + blr +/***************************************************************************** + * initLog: initialize the NVRAM with 0 + * write a new NVRAM Log-Partition-Header + * + * input: + * r3 - NVRAM BASE address + * + * output: + * r3 - 0 = check ok, no new header written + * r3 - 1 = check not ok, header and NVRAM initialized + * r4 - NVRAM log address + * + * Modifies Register: R3, R4, R5, R6, R7, r8, r9 + ****************************************************************************/ +ASM_ENTRY(.initLog) + mflr r8 + mr r7, r3 + + bl clearNVRAM +0: + li r5, LLFW_LOG_BE0_SIGNATURE + li r4, LLFW_LOG_BE0_LENGTH + stb r5, 0(r7) + sth r4, LLFW_LOG_POS_LENGTH(r7) + li r5, LLFW_LOG_BE0_DATA_OFFSET + li r4, LLFW_LOG_BE0_FLAGS + sth r5, LLFW_LOG_POS_DATA_OFFSET(r7) + sth r4, LLFW_LOG_POS_FLAGS(r7) + li r5, 1 + + LOAD32( r4, LLFW_LOG_BE0_NAME_PREFIX) + stw r5, LLFW_LOG_POS_POINTER(r7) + stw r4, (LLFW_LOG_POS_NAME+0x00)(r7) + LOAD64( r5, LLFW_LOG_BE0_NAME) + std r5, (LLFW_LOG_POS_NAME+0x04)(r7) + bl .calPartitionHeaderChecksum + stb r3, LLFW_LOG_POS_CHECKSUM(r7) + bl init_log_2nd_be // create a second log partition for BE1 + mr r4, r7 + li r3, 1 + mtlr r8 + blr +/***************************************************************************** + * clearNVRAM: set all not used NVRAM memory to zero + * + * + * input: + * R3 - NVRAM BASE ADDRESS + * + * output: + * R3 - NVARM END ADDRESS + * + * Modifies Register: r4, r5 + ****************************************************************************/ +ASM_ENTRY(clearNVRAM) + LOAD64( r4, NVRAM_LENGTH) + srdi r4, r4, 3 + mtctr r4 + li r5, 0x0 + LOAD64( r4, NVRAM_EMPTY_PATTERN) +0: + stdx r4, r3,r5 + addi r5, r5, 8 + bdnz+ 0b + blr +/***************************************************************************** + * writeNVRAMbyte: write next log into NVRAM + * + * + * input: + * R3 - byte to be written + * R4 - NVRAM Base Address + * + * output: + * R3 - byte that was written + * R4 - NVRAM Base Address + * + * Modifies Register: R3, R4, R5, R6 + ****************************************************************************/ +ASM_ENTRY(.writeNVRAMbyte) +ENTRY(writeLogByte) + NVRAM_POINTER_DATASIZE_BE0( r5, r6, r4) // get pointer,size of data + NVRAM_LOG_DATA_OVERFLOW( r5, r6) // check for overflow + addi r5, r5, 1 // increment pointer + stw r5, LLFW_LOG_POS_POINTER(r4) // store pointer + addi r5, r5, -1 // restore old pointer + add r6, r4, r5 // byte address in data section + + stb r3, LLFW_LOG_BE0_DATA_OFFSET(r6) + blr + +/***************************************************************************** + * writeNVRAMbyte: write next log into NVRAM + * + * + * input: + * R3 - byte to be written + * R4 - NVRAM Base Address + * + * output: + * R3 - byte that was written + * R4 - NVRAM Base Address + * + * Modifies Register: R3, R4, R5, R6 + ****************************************************************************/ +ENTRY(writeLogByteBE1) + li r6, LLFW_LOG_BE0_LENGTH + mulli r6, r6, 0x10 + add r4, r6, r4 + NVRAM_POINTER_DATASIZE_BE1( r5, r6, r4) // get pointer,size of data + NVRAM_LOG_DATA_OVERFLOW( r5, r6) // check for overflow + addi r5, r5, 1 // increment pointer + stw r5, LLFW_LOG_POS_POINTER(r4) // store pointer + addi r5, r5, -1 // restore old pointer + add r6, r4, r5 // byte address in data section + + stb r3, LLFW_LOG_BE1_DATA_OFFSET(r6) + blr + +/***************************************************************************** + * calPartitionHeaderChecksum: calculate the Checksum of the + * Partition Header as described in .... + * + * input: r3 - NVRAM BASE adresse + * + * output: R3 - the calculated checksum as 8 bit value + * R4 - NVRAM log address + * + * Modifies Register: R3, R4, R5, R6 + ****************************************************************************/ +ASM_ENTRY(.calPartitionHeaderChecksum) + mr r6, r3 + lbz r3,0(r6) // load first byte + LOAD64( r4, LLFW_LOG_POS_LENGTH) // load position of 3rd byte +.L6: + lbzx r5, r4, r6 // r5 nexed byte + addi r4, r4, 1 // r4++ (index) + add r5, r5, r3 // r5 new sum =sum + nexed byte + rldicl r5, r5, 0, 56 + cmpld 7, r5, r3 + cmpldi 6, r4, LLFW_LOG_POS_DATA_OFFSET + bge+ 7,.L5 // if new sum > sum + addi r5, r5, 1 // new sum ++ + rldicl r5, r5, 0, 56 +.L5: + mr r3,r5 // sum = new sum + blt+ 6,.L6 + + mr r4, r6 + blr + +#else /* defined(DISABLE_NVRAM) || defined(RTAS_NVRAM) */ + +ASM_ENTRY(.writeNVRAMbyte) + ENTRY(writeLogByte) + blr + +#endif diff --git a/qemu/roms/SLOF/llfw/romfs.S b/qemu/roms/SLOF/llfw/romfs.S new file mode 100644 index 000000000..325f79e5e --- /dev/null +++ b/qemu/roms/SLOF/llfw/romfs.S @@ -0,0 +1,362 @@ +/****************************************************************************** + * 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 "macros.h" +#include "romfs.h" + +/******************************************************************* + * Wrapper for romfs_lookup. + * + * Input: + * R3 = address of filename string + * R4 = address of struct romfs_t + * 0: file size (return) + * 8: flags (return) + * 10: fileaddr (return and input: tells if first search) + * 18: nextfile (return) + * 20: namep (return) + * + * Find File Procedure + * - set filename and rombase, on return 0 file properties are stored + * in romfs_t else struct not valid + * + * Listing procedure + * - clear romfs_t (important!) + * - set filename = NULL and rombase and call returns first file + * with properties in romfs_t including next-file pointer + * - if nextpointer is non-zero then just the next file is returned + * + * Returns: + * <Success>: + * R3 = 0 + * romfs_t is updated + * <FileNotFound>: + * R3 = 1 + * romfs_t not touched + * + * Potentially modifies the following registers: + * + + Example usage from C: + + int list_bootrom() + { + struct romfs_t rfs; + int i; + + printf("Build: "__TIME__" "__DATE__" \n"); + + i = 0; + memset((void*) &rfs, 0, sizeof(struct romfs_t)); + printf(" No. File Data Size Name\n"); + + while (romfs_stat(NULL, &rfs) == 0) { + i++; + printf(" %02d: %08X %08X %7d %s\n", + i, rfs.fileaddr, rfs.datap, + rfs.size, rfs.namep); + } + if (0 == i) { + printf("Error in reading ROMFS\n"); + return 1; + } + return 0; + } + *******************************************************************/ +#define RFS_T_SIZE 0x00 +#define RFS_T_FLAGS 0x08 +#define RFS_T_FILEADDR 0x10 +#define RFS_T_NEXT 0x18 +#define RFS_T_NAME 0x20 +#define RFS_T_DATA 0x28 + +#define RFS_H_NEXT 0x00 +#define RFS_H_SIZE 0x08 +#define RFS_H_FLAGS 0x10 +#define RFS_H_DATA 0x18 +#define RFS_H_NAME 0x20 + +ENTRY(romfs_stat_file) + /* save link register and romfs_t pointer */ + mflr r15 + mr r16, r4 + + /* if filename R3 is 0 then its a listing request */ + /* if not then just continue to lookup name */ + /* save R4 to R8 which is the address of header */ + li r7, 0 + cmpd r3, r7 + beq romfs_list + bl romfs_lookup + mfsprg r8, 1 + + /* if file found then go to romfs_fill_properties */ + /* else return 1 to caller */ + cmpwi r3, 0 + beq romfs_fill_properties + b romfs_stat_end + + romfs_list: + /* check if fileaddr == 0, in this case its */ + /* the first search on this handle, so return all */ + /* info for file at rombase (R8=R4) */ + ld r6, RFS_T_FILEADDR(r4) + mfsprg r8, 1 + li r7, 0 + cmpd r7, r6 + beq romfs_fill_properties + + /* check if next file != 0 by looking into */ + /* romfs_t, if not then return (next = 0) 1 */ + li r7, 0 + ld r4, RFS_T_NEXT(r4) + cmpd r7, r4 + li r3, 1 + beq romfs_stat_end + + /* now next file is available so move R8 to next */ + /* file address */ + mr r8, r4 + + romfs_fill_properties: + /* set properties in romfs_t takes R8 as address */ + /* to file header and R16 as address of romfs_t */ + mfsprg r3, 1 + std r8, RFS_T_FILEADDR(r16) + + ld r4, RFS_H_NEXT(r8) + li r7, 0 + cmpd r7, r4 + beq $ + (2 * 4) /* =0 so add no rombase */ + add r4, r4, r3 + std r4, RFS_T_NEXT(r16) + + ld r4, RFS_H_SIZE(r8) + std r4, RFS_T_SIZE(r16) + ld r4, RFS_H_FLAGS(r8) + std r4, RFS_T_FLAGS(r16) + + ld r4, RFS_H_DATA(r8) + add r4, r4, r3 + std r4, RFS_T_DATA(r16) + + addi r4, r8, RFS_H_NAME + std r4, RFS_T_NAME(r16) + + li r3, 0 + + /* restore romfs_t pointer and link register */ + romfs_stat_end: + mr r5, r16 + mtlr r15 + blr + +/******************************************************************* + * Copies the data of file referenced by name string to address + * requires root address of filesystem. + * FIXME: ignores flags + * + * Input: + * R3 = address of filename string + * R4 = ROMBASE + * R5 = destination address + * + * Returns: + * <Success>: R3 = 0, R6 = size, <FileNotFound>: R3 = 1 + * R5 is kept + * + * Potentially modifies the following registers: + * ctr, r15, r16, r17, r18 + * + * Uses the following calls with subsequent register modification: + * - romfs_lookup + *******************************************************************/ +ASM_ENTRY(romfs_load) + mflr r15 + + /* save R5 twice */ + /* lookup file, input regs */ + /* are already set */ + /* if not found, just return */ + mr r16, r5 + mr r17, r5 + bl romfs_lookup + cmpwi r3, 1 + bne 0f + mtlr r15 + blr /* abort, not found */ + + /* save data size for return */ + /* found, copy data */ + /* data size is in R6 */ +0: + //mr r3, r6 + mtctr r6 + addi r16, r16, -1 /* dest */ + addi r5, r5, -1 /* source*/ + + /* data is expected to be */ + /* 8 byte aligned */ + /* copy loop */ +0: lbzu r18, 1(r5) + stbu r18, 1(r16) + bdnz 0b + + /* restore size, keep padding */ + /* restore target address */ + /* return */ + mr r5, r17 + mtlr r15 + blr + +/******************************************************************* + * looks up a file based on filename + * + * Input: + * R3 = address of filename string + * R4 = ROMBASE + * + * Returns: + * <Success>: + * R3 = 0 + * R4 = address of file header + * R5 = address of data (real address) + * R6 = size of data + * R7 = flags for file + * <FileNotFound>: + * R3 = 1 + * + * Potentially modifies the following registers: + * R3, R4, R5, R6, R7, R8, R9 + * + * Uses the following calls with subsequent register modification: + * - romfs_namematch + *******************************************************************/ +ASM_ENTRY(romfs_lookup) + mflr r9 + + romfs_lookup_next: + /* save current file base */ + mr r8, r4 + /* name to look for */ + mr r10, r3 + /* name of file */ + mr r5, r4 + addi r5, r5, (4 /* elems */ * 8 /* elem-size */) + mr r11, r5 /* for namematch */ + /* compare */ + bl romfs_namematch + cmpwi r12, 1 + bne romfs_lookup_match + + /* load next pointer */ + /* check if next is 0 */ + /* apply root-offset */ + ld r5, 0(r4) + cmpwi r5, 0 + add r4, r4, r5 + bne romfs_lookup_next + /* last file reached, abort */ + li r3, 1 + mtlr r9 + blr + + /* here the name did match */ + /* r4 is still usable here and */ + /* pointing to the initial file */ + /* load r5 with data ptr */ + /* load r6 with data size */ + /* load r7 with flags */ + /* get abs addr of data */ + romfs_lookup_match: + li r3, 0 + ld r5, (3 * 8)(r4) /* data */ + ld r6, (1 * 8)(r4) /* len */ + ld r7, (2 * 8)(r4) /* flags */ + add r5, r5, r8 + mtlr r9 + blr + +/******************************************************************* + * compares two strings in memory, + * both must be null-terminated and 8-byte aligned + * + * Input: + * R10 = string 1 + * R11 = string 2 + * + * Returns: + * <Match>: R12 = 0 <NoMatch>: R12 = 1 + * + * Potentially modifies the following registers: + * R10, R11, r12, r13, r14 + *******************************************************************/ +romfs_namematch: + subi r10, r10, 8 + subi r11, r11, 8 + + /* + * load chars as 8byte chunk from current pos, name is + * always 8 byte aligned :) + */ + romfs_cmp_loop: + ldu r13, 8(r10) /* A */ + ldu r14, 8(r11) /* B */ + + cmpd r13, r14 + li r12, 1 + beq 1f + blr + +1: andi. r14, r14, 0xff + bne romfs_cmp_loop + + li r12, 0 + blr + +/******************************************************************* + * wrapper for romfs_lookup + * this function saves the registers from r13 - r15 on the stack + * calls romfs_lookup + * restores the saved registers + * + * the return parameters are copied to (r5) and (r5) has to + * be 0x20 big + *******************************************************************/ +ENTRY(c_romfs_lookup) + stdu r1,-0x50(r1) # allocate space on stack + + mflr r0 # save link register + std r0,0x30(r1) + + std r15,0x38(r1) # save r15 + std r14,0x40(r1) # save r14 + std r13,0x48(r1) # and r13 + + mr r15,r5 # save the pointer for the return value + + bl romfs_lookup # do the thing + + ld r0,0x30(r1) # restore link register + mtlr r0 + + std r4,0x00(r15) # copy return values + std r5,0x08(r15) # to the return pointer + std r6,0x10(r15) + std r7,0x18(r15) + + ld r13,0x48(r1) # restore registers from stack + ld r14,0x40(r1) + ld r15,0x38(r1) + + addi r1,r1,0x50 # cleanup stack + + blr diff --git a/qemu/roms/SLOF/llfw/romfs_wrap.c b/qemu/roms/SLOF/llfw/romfs_wrap.c new file mode 100644 index 000000000..323d97525 --- /dev/null +++ b/qemu/roms/SLOF/llfw/romfs_wrap.c @@ -0,0 +1,22 @@ +/****************************************************************************** + * 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 <romfs.h> + +int romfs_stat(char *filename, struct romfs_t *hnd) +{ + asm volatile ("":::"3","4","5","6","7","9","10"); + asm volatile ("":::"11","12"); + asm volatile ("":::"13","14","15","16","17","18"); + + return romfs_stat_file(filename, hnd); +} |