diff options
| author | fishsoupisgood <github@madingley.org> | 2019-04-29 01:17:54 +0100 | 
|---|---|---|
| committer | fishsoupisgood <github@madingley.org> | 2019-05-27 03:43:43 +0100 | 
| commit | 3f2546b2ef55b661fd8dd69682b38992225e86f6 (patch) | |
| tree | 65ca85f13617aee1dce474596800950f266a456c /roms/SLOF/llfw | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip  | |
Diffstat (limited to 'roms/SLOF/llfw')
| -rw-r--r-- | roms/SLOF/llfw/boot_abort.S | 95 | ||||
| -rw-r--r-- | roms/SLOF/llfw/boot_abort.h | 37 | ||||
| -rw-r--r-- | roms/SLOF/llfw/clib/Makefile.inc | 42 | ||||
| -rw-r--r-- | roms/SLOF/llfw/clib/iolib.c | 47 | ||||
| -rw-r--r-- | roms/SLOF/llfw/clib/iolib.h | 26 | ||||
| -rw-r--r-- | roms/SLOF/llfw/io_generic/Makefile.inc | 38 | ||||
| -rw-r--r-- | roms/SLOF/llfw/io_generic/io_generic.S | 129 | ||||
| -rw-r--r-- | roms/SLOF/llfw/nvramlog.S | 350 | ||||
| -rw-r--r-- | roms/SLOF/llfw/romfs.S | 362 | ||||
| -rw-r--r-- | roms/SLOF/llfw/romfs_wrap.c | 22 | 
10 files changed, 1148 insertions, 0 deletions
diff --git a/roms/SLOF/llfw/boot_abort.S b/roms/SLOF/llfw/boot_abort.S new file mode 100644 index 00000000..996bdd78 --- /dev/null +++ b/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/roms/SLOF/llfw/boot_abort.h b/roms/SLOF/llfw/boot_abort.h new file mode 100644 index 00000000..b7082063 --- /dev/null +++ b/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/roms/SLOF/llfw/clib/Makefile.inc b/roms/SLOF/llfw/clib/Makefile.inc new file mode 100644 index 00000000..70037989 --- /dev/null +++ b/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/roms/SLOF/llfw/clib/iolib.c b/roms/SLOF/llfw/clib/iolib.c new file mode 100644 index 00000000..7f14b512 --- /dev/null +++ b/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/roms/SLOF/llfw/clib/iolib.h b/roms/SLOF/llfw/clib/iolib.h new file mode 100644 index 00000000..91450058 --- /dev/null +++ b/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/roms/SLOF/llfw/io_generic/Makefile.inc b/roms/SLOF/llfw/io_generic/Makefile.inc new file mode 100644 index 00000000..b6607252 --- /dev/null +++ b/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/roms/SLOF/llfw/io_generic/io_generic.S b/roms/SLOF/llfw/io_generic/io_generic.S new file mode 100644 index 00000000..9c1db41a --- /dev/null +++ b/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/roms/SLOF/llfw/nvramlog.S b/roms/SLOF/llfw/nvramlog.S new file mode 100644 index 00000000..3ad2de75 --- /dev/null +++ b/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/roms/SLOF/llfw/romfs.S b/roms/SLOF/llfw/romfs.S new file mode 100644 index 00000000..325f79e5 --- /dev/null +++ b/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/roms/SLOF/llfw/romfs_wrap.c b/roms/SLOF/llfw/romfs_wrap.c new file mode 100644 index 00000000..323d9752 --- /dev/null +++ b/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); +}  | 
