diff options
Diffstat (limited to 'roms/SLOF/rtas')
| -rw-r--r-- | roms/SLOF/rtas/Makefile.inc | 89 | ||||
| -rw-r--r-- | roms/SLOF/rtas/flash/block_lists.c | 275 | ||||
| -rw-r--r-- | roms/SLOF/rtas/flash/block_lists.h | 23 | ||||
| -rw-r--r-- | roms/SLOF/rtas/flash/tmpXXX.update-comments | 11 | ||||
| -rw-r--r-- | roms/SLOF/rtas/reloc.S | 183 | ||||
| -rw-r--r-- | roms/SLOF/rtas/rtas.lds | 49 | ||||
| -rw-r--r-- | roms/SLOF/rtas/rtas_call.c | 93 | ||||
| -rw-r--r-- | roms/SLOF/rtas/rtas_common.S | 87 | ||||
| -rw-r--r-- | roms/SLOF/rtas/rtas_entry.S | 72 | 
9 files changed, 882 insertions, 0 deletions
diff --git a/roms/SLOF/rtas/Makefile.inc b/roms/SLOF/rtas/Makefile.inc new file mode 100644 index 00000000..4297f86a --- /dev/null +++ b/roms/SLOF/rtas/Makefile.inc @@ -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 +# ****************************************************************************/ + +# Before including this Makefile, you should specify the following variables +# in your Makefile: +# - RTASCMNDIR : Points to the common RTAS directory +# - RTASBRDDIR : Points to the board specific RTAS directory +# - TOOLSDIR : Points to the common tools directory +# - OBJS : A list with all object files that should be linked into rtas.bin +# - BOARD_SRCS : A list with all board specific source code files +#                (needed for "make depend") + + +LDFLAGS		= -nostdlib +CPPFLAGS	+= -I$(RTASBRDDIR) -I$(RTASCMNDIR) \ +		  -I$(INCLCMNDIR) -I$(INCLBRDDIR) \ +		  -I$(LIBCMNDIR)/libc/include \ +		  -I$(INCLCMNDIR)/$(CPUARCH) +ASFLAGS		= -Wa,-mregnames $(FLAG) +CFLAGS		+= -g -nostdinc -ffreestanding -Wall -Wextra -O2 -msoft-float \ +		  -mno-altivec -mabi=no-altivec $(FLAG) + +# Common RTAS files: +RTAS_SRC_ASM	= reloc.S rtas_common.S rtas_entry.S rtas_term.S \ +		  rtas_cpu.S rtas_flash_asm.S rtas_mem.S rtas_ras.S +RTAS_SRC_C	= rtas_call.c rtas_flash_c.c rtas_h8.c \ +		  rtas_nvramlog.c rtas_sensor.c rtas_init.c \ +		  rtas_flash_cfi.c +RTAS_SRCS	= $(RTAS_SRC_ASM) $(RTAS_SRC_C) +RTAS_OBJ_ASM	= $(RTAS_SRC_ASM:%.S=%.o) +RTAS_OBJ_C	= $(RTAS_SRC_C:%.c=%.o) + +# Common build rules: +$(RTAS_OBJ_C): +	$(CC) $(CPPFLAGS) $(CFLAGS) -c $(@:%.o=$(RTASCMNDIR)/%.c) -o $@ + +$(RTAS_OBJ_ASM): +	$(CC) $(CPPFLAGS) $(ASFLAGS) -c $(@:%.o=$(RTASCMNDIR)/%.S) -o $@ + +$(TOOLSDIR)/gen_reloc_table: $(TOOLSDIR)/gen_reloc_table.c +	$(MAKE) -C $(TOOLSDIR) gen_reloc_table + + +# Rules for building rtas.bin: +rtas.bin: rtas +	$(OBJCOPY) -O binary $< $@ + +rtas: $(RTASCMNDIR)/rtas.lds $(OBJS) reloc_table.o $(LIBCMNDIR)/libc.a +	$(LD) $(LDFLAGS) -o $@ -T $(RTASCMNDIR)/rtas.lds $(OBJS) \ +	    reloc_table.o $(LIBCMNDIR)/libc.a + +reloc_table.o: $(TOOLSDIR)/gen_reloc_table $(OBJS) $(LIBCMNDIR)/libc.a +	$(TOOLSDIR)/create_reloc_table.sh --ld "$(ONLY_LD)" --ldflags "$(LDFLAGS)" \ +	  --lds "$(RTASCMNDIR)/rtas.lds" --objcopy "$(OBJCOPY)" $(OBJS)  $(LIBCMNDIR)/libc.a + + +$(LIBCMNDIR)/libc.a: +	$(MAKE) -C $(LIBCMNDIR) libc + + +# Rules for cleaning up: +clean_rtas: +	rm -f $(OBJS) reloc_table.o rtas rtas.bin +	rm -f $(RTASCMNDIR)/*~ $(RTASCMNDIR)/*.o + +distclean_rtas: clean_rtas +	rm -f Makefile.dep + + +# Rules for creating the dependency file: +depend: +	rm -f Makefile.dep +	$(MAKE) Makefile.dep + +Makefile.dep: Makefile $(RTASCMNDIR)/Makefile.inc +	$(CC) -MM $(CPPFLAGS) $(CFLAGS) $(RTAS_SRCS:%=$(RTASCMNDIR)/%) > Makefile.dep +	$(CC) -MM $(CPPFLAGS) $(CFLAGS) $(BOARD_SRCS) >> Makefile.dep + +# Include dependency file if available: +-include Makefile.dep diff --git a/roms/SLOF/rtas/flash/block_lists.c b/roms/SLOF/rtas/flash/block_lists.c new file mode 100644 index 00000000..e632fd0b --- /dev/null +++ b/roms/SLOF/rtas/flash/block_lists.c @@ -0,0 +1,275 @@ +/****************************************************************************** + * 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 <product.h> +#include <stdio.h> +#include "block_lists.h" + +unsigned char sig_org[] = FLASHFS_PLATFORM_MAGIC; + +/* this function is part of the crc_lib assembler code */ +unsigned long check_flash_image(unsigned long, unsigned long, unsigned long); + +/* this functions needs to be implemented by the board specific flash code + * the functions always get 32 bytes and needs to deal with the data */ +void write_flash(unsigned long, unsigned short *); + +int progress = 0; + +int +print_progress(void) +{ +	static int i = 3; +	switch (i--) { +	case 3: +		printf("\b|"); +		break; +	case 2: +		printf("\b/"); +		break; +	case 1: +		printf("\b-"); +		break; +	case 0: +		printf("\b\\"); +	default: +		i = 3; +	} +	return 0; +} + +void +print_hash(void) +{ +	printf("\b# "); +} + +void +print_writing(void) +{ +	int counter = 42; +	printf("\nWriting Flash: |"); +	while (counter--) +		printf(" "); +	printf("|"); +	counter = 41; +	while (counter--) +		printf("\b"); + +} + +int +get_block_list_version(unsigned char *data) +{ +	if (data[0] == 0x01) +		return 1; +	return 0; +} + +static long +get_image_size(unsigned long *data, unsigned long length) +{ +	long size = 0; +	unsigned long i; +	for (i = 0; i < length / 8; i += 2) { +		size += data[1 + i]; +	} +	return size; +} + +static long +get_image_size_v0(unsigned long *data) +{ +	unsigned long bl_size = data[0]; +	return get_image_size(data + 1, bl_size - 8); +} + +static long +get_image_size_v1(unsigned long *data) +{ +	unsigned long *bl_addr = data; +	unsigned long bl_size; +	unsigned long *next; +	long size = 0; +	while (bl_addr) { +		bl_size = bl_addr[0]; +		next = (unsigned long *) bl_addr[1]; +		bl_size = bl_size & 0x00FFFFFFFFFFFFFFUL; +		size += get_image_size(bl_addr + 2, bl_size - 0x10); +		bl_addr = next; +	} +	return size; +} + +long +get_size(unsigned long *data, int version) +{ +	if (version == 1) +		return get_image_size_v1(data); +	return get_image_size_v0(data); +} + +static unsigned long +write_one_block(unsigned long *block, unsigned long length, +		unsigned long offset) +{ +	unsigned long block_addr = (unsigned long) block; +	unsigned long i = 0; +	static unsigned int hash; +	if (offset == 0) +		hash = 0; + +	for (i = 0; i < length; i += 32, offset += 32, block_addr += 32) { +		write_flash(offset, (unsigned short *) block_addr); +		if (offset % 10 == 0) { +			print_progress(); +		} +		if (offset > hash * progress) { +			print_hash(); +			hash++; +		} +	} + +	return offset; +} + +static unsigned long +write_one_list(unsigned long *bl, unsigned long length, unsigned long offset) +{ +	unsigned long i; +	// 0x10: /8 for pointer /2 it has to be done in steps of 2 +	for (i = 0; i < length / 0x10; i++) { +		offset = +		    write_one_block((unsigned long *) *bl, *(bl + 1), offset); +		bl += 2; +	} +	return offset; +} + +void +write_block_list(unsigned long *bl, int version) +{ +	unsigned long offset = 0; +	unsigned long *bl_addr = bl; +	unsigned long bl_size; +	unsigned long *next; + +	if (version == 0) { +		// -8 = removed header length +		write_one_list(bl + 1, *(bl) - 8, offset); +		return; +	} + +	while (bl_addr) { +		bl_size = bl_addr[0]; +		next = (unsigned long *) bl_addr[1]; +		bl_size = bl_size & 0x00FFFFFFFFFFFFFFUL; +		// -0x10 = removed header length +		offset = write_one_list(bl_addr + 2, bl_size - 0x10, offset); +		bl_addr = next; +	} + +} + +static int +check_one_list(unsigned long *bl, unsigned long length, unsigned long crc) +{ +	unsigned long i; +	// 0x10: /8 for pointer /2 it has to be done in steps of 2 +	for (i = 0; i < length / 0x10; i++) { +		crc = check_flash_image((unsigned long) *bl, *(bl + 1), crc); +		bl += 2; +	} +	return crc; +} + +int +image_check_crc(unsigned long *bl, int version) +{ +	unsigned long *bl_addr = bl; +	unsigned long bl_size; +	unsigned long *next; +	unsigned long crc = 0; + +	if (version == 0) { +		// -8 = removed header length +		return check_one_list(bl + 1, *(bl) - 8, crc); +	} + +	while (bl_addr) { +		bl_size = bl_addr[0]; +		next = (unsigned long *) bl_addr[1]; +		bl_size = bl_size & 0x00FFFFFFFFFFFFFFUL; +		// -0x10 = removed header length +		crc = check_one_list(bl_addr + 2, bl_size - 0x10, crc); +		bl_addr = next; +	} +	return crc; +} + +static int +check_platform_one_list(unsigned long *bl, unsigned long bytesec) +{ +	unsigned long pos = bytesec; +	unsigned char *sig_tmp, *sig; +	unsigned long size = 0; +	sig = sig_org; + +	while (size < bytesec) { +		size += bl[1]; + +		while (size > pos) {	// 32 == FLASHFS_PLATFORM_MAGIC length +			sig_tmp = (unsigned char *) (bl[0] + pos); +			if (*sig++ != *sig_tmp) +				return -1; +			if (*sig_tmp == '\0' || (pos == bytesec + 32)) { +				pos = bytesec + 32; +				break; +			} +			pos++; +		} +		if (pos == (bytesec + 32)) +			return 0; +		bl += 2; +	} +	return 0; +} + +int +check_platform(unsigned long *bl, unsigned int bytesec, int version) +{ +	unsigned long *bl_addr = bl; +	unsigned long bl_size; +	unsigned long *next; +	unsigned long *ptr; +	ptr = bl; + +	if (version == 0) { +		ptr += 1;	// -8 = removed header length +		return check_platform_one_list(ptr, bytesec); +	} +	while (bl_addr) { +		ptr = bl_addr + 2;	// -0x10 = removed header length +		bl_size = bl_addr[0]; +		next = (unsigned long *) bl_addr[1]; +		bl_size = bl_size & 0x00FFFFFFFFFFFFFFUL; +		if ((bl_size - 0x10) == 0) { +			bl_addr = next; +			continue; +		} +		if (check_platform_one_list(ptr, bytesec) == 0) +			return 0; + +		bl_addr = next; +	} +	return -1; +} diff --git a/roms/SLOF/rtas/flash/block_lists.h b/roms/SLOF/rtas/flash/block_lists.h new file mode 100644 index 00000000..b24b6506 --- /dev/null +++ b/roms/SLOF/rtas/flash/block_lists.h @@ -0,0 +1,23 @@ +/****************************************************************************** + * 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 + *****************************************************************************/ + +extern int progress; +extern unsigned char sig_org[]; + +int print_progress(void); +void print_hash(void); +int get_block_list_version(unsigned char *); +int image_check_crc(unsigned long *, int); +long get_size(unsigned long *, int); +void print_writing(void); +void write_block_list(unsigned long *, int); +int check_platform(unsigned long *, unsigned int, int); diff --git a/roms/SLOF/rtas/flash/tmpXXX.update-comments b/roms/SLOF/rtas/flash/tmpXXX.update-comments new file mode 100644 index 00000000..cd3d1376 --- /dev/null +++ b/roms/SLOF/rtas/flash/tmpXXX.update-comments @@ -0,0 +1,11 @@ +# ***************************************************************************** +# * 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 +# ****************************************************************************/ diff --git a/roms/SLOF/rtas/reloc.S b/roms/SLOF/rtas/reloc.S new file mode 100644 index 00000000..e24d293d --- /dev/null +++ b/roms/SLOF/rtas/reloc.S @@ -0,0 +1,183 @@ +/****************************************************************************** + * 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 <rtas.h>		 +			 +/* +Function:	 +	Input: +		r3:   Destination to copy rtas code to +		r4:   Configuration	 +	Output:		 +		r3:   Entry point for rtas calls	 +Decription: Called by OpenFirmware to instantiate rtas, needs to copy +	itself to destination, also do a relocations. +	 +*/ + +.extern	rtas_entry +.extern .stack +.extern _got +.extern _got_end +.extern __bss_start +.extern __bss_end +.extern rtas_config + + +	.section        ".rtasstart","ax"; +	.align	3 +	.globl _rtas_start +_rtas_start: +	mflr	r10		# save link register +	bcl	20,31,.over	# branch (always) to .over  + +.base: +	.align  3 + +/* Our Open Firmware needs to know the size of the RTAS binary and the + * size & address of the RTAS function jump table. SLOF always looks for this + * information in the following three quads here at the very beginning of the + * RTAS binary at offset 8. So DO NOT DELETE/MOVE them! */ + +._rtas_size:		.quad	_rtas_end-_rtas_start +._ptr_to_func_tab:	.quad	rtas_func_tab-_rtas_start +._ptr_to_func_tab_size:	.quad	rtas_func_tab_size-_rtas_start + +/* The other variables are not accessed by SLOF anymore: */ + +._rel_offset:		.quad   _reloc_table_start-_rtas_start +._rel_end_offset:	.quad   _reloc_table_end-_rtas_start +._bss_offset:		.quad   __bss_start-_rtas_start +._bss_end_offset:	.quad   __bss_end-_rtas_start +._rtas_entry_offset:	.quad   rtas_entry-_rtas_start +._rtas_config_offset:	.quad   rtas_config-_rtas_start +._rtas_stack:	        .quad   .stack-_rtas_start+RTAS_STACKSIZE-0x60 +._rtas_toc:	        .quad   _got-_rtas_start+0x8000 + +.over:	 +	mflr r8			# gpr 8 is the base +	addi r8,r8,_rtas_start-.base # points to _rtas_start +	mr r11,r4		# Save config value	 +	 +# Copy rtas code +	 +	ld r5,._rtas_size-_rtas_start(r8)  +	mr r4,r8		# Start of rtas +	addi r6,r3,-8		# Destination +	addi r4,r4,-8		# Source +	srdi r5,r5,3		# Count in quads +	mtctr r5 +0:				 +	ldu r0,8(r4)		 +	stdu r0,8(r6) +	bdnz 0b		 + +# Clear bss + +	ld r4,._bss_offset-_rtas_start(r8) +	ld r5,._bss_end_offset-_rtas_start(r8) +	li r0,0 +	add r6,r3,r4		# Address bss in copied code +	addi r6,r6,-8 +	sub r5,r5,r4		# Calculate bss size +	srdi r5,r5,3		# Count in quads +	mtctr r5	 +0:	 +	stdu r0,8(r6) +	bdnz 0b + +# Relocate got + +	ld	r4, ._rel_offset-_rtas_start(r8) +	ld	r5, ._rel_end_offset-_rtas_start(r8) +	sub	r5, r5,r4	# Calculate reloc table size +	cmpdi	r5, 0		# No reloc table ? +	beq	1f + +	add	r4, r4, r3	# Calculate reloc table address +	addi	r4, r4, -4 +	srdi	r5, r5, 2	# Count in words	 +	mtctr	r5 +0:	 +	lwzu	r6, 4(r4)	# Load offset out of reloc table +	ldx	r0, r6, r3	# Load value 	 +	add	r0, r0, r3	# Add relocation offset = load address +	stdx	r0, r6, r3 +	bdnz	0b		 +1:			 + +# Save config data + +	ld r5,._rtas_config_offset-_rtas_start(r8) +	add r5,r5,r3 +	std r11,0(r5) +	 +# Flush to memory +	 +	mr r4,r3		# Destination address +	ld r5,._rtas_size-_rtas_start(r8)  +		 +	add r5,r5,r4 +	addi r5,r5,127 +	rlwinm r4,r4,0,0,24 +	rlwinm r5,r5,0,0,24 +	sub r5,r5,r4 +	srwi r5,r5,7 +	mtctr r5 +0: +	dcbst 0,r4 +	sync +	icbi 0,r4 +	sync +	isync +	addi r4,r4,128 +	bdnz 0b + +# Call init function +	mfmsr	r11			# Switch to 64 bit mode +	mr	r7,r11 +	rotldi	r11,r11,1 +	ori	r11,r11,1 +	rotldi	r11,r11,63 +	mtmsrd	r11 +	isync +	mr	r9,r1			# save old stack pointer +	ld	r1,._rtas_stack-_rtas_start(r8)	# load new stack pointer +	add	r1,r1,r3 +	std	r9,0(r1)		# save stack pointer +	std	r2,64(r1)		# save toc +	std	r7,72(r1)		# save old msr value + +	ld	r2,._rtas_toc-_rtas_start(r8)	# load got pointer +	add	r2,r2,r3 + +	bl	save_regs_r3_r12 +	bl	.rtas_init +	bl	restore_regs_r3_r12 + +	ld	r11,72(r1)		# restore msr value	 +	ld	r2,64(r1)		# restore toc +	ld	r1,0(r1)		# get old stack + +	mtmsrd	r11			# restore msr +	isync + + +# Return rtas entry + +	ld r4,._rtas_entry_offset-_rtas_start(r8) +	add r3,r3,r4 +	mtlr	r10 +	blr	 + + + diff --git a/roms/SLOF/rtas/rtas.lds b/roms/SLOF/rtas/rtas.lds new file mode 100644 index 00000000..a5ba1daa --- /dev/null +++ b/roms/SLOF/rtas/rtas.lds @@ -0,0 +1,49 @@ +/****************************************************************************** + * 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 + *****************************************************************************/ + +OUTPUT_FORMAT("elf64-powerpc", "elf64-powerpc", "elf64-powerpc") +OUTPUT_ARCH(powerpc:common64) + +SECTIONS { +	.text 0: +	{ +	  *(.rtasstart) +	  *(.text .stub .text.* .gnu.linkonce.t.*) +	  *(.sfpr .glink) +	  *(.rodata .rodata.* .gnu.linkonce.r.*) +	  *(.opd) +	} =0x60000000 +	.data : +	{ +	  *(.data .data.* .gnu.linkonce.d.*) +	} +	.got : +	{ +	  _got = .; +	  *(.got .toc) +	}  	 +	.reloc : +	{ +	  . = ALIGN(4); +	  _reloc_table_start = .; +	  *(.reloc) +	  _reloc_table_end = .; +	} +	.bss : +	{ +	  __bss_start = .; +	  *(*COM* .bss .sbss .gnu.linkonce.b.*) +	  __bss_end = .; +	} +	__bss_size = (__bss_end - __bss_start); +	_rtas_end = .; +} diff --git a/roms/SLOF/rtas/rtas_call.c b/roms/SLOF/rtas/rtas_call.c new file mode 100644 index 00000000..8c7532c0 --- /dev/null +++ b/roms/SLOF/rtas/rtas_call.c @@ -0,0 +1,93 @@ +/****************************************************************************** + * 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" + + +//#define _RTAS_TRACE +//#define _RTAS_COUNT_CALLS + + +#ifdef _RTAS_COUNT_CALLS +int rtas_callcount[0x40] __attribute__((aligned (16))); +#endif + +/* rtas_config is used to store the run-time configuration flags (which are + * provided by SLOF during instantiate-rtas) */ +long rtas_config; + + +/* Prototype */ +void rtas_call (rtas_args_t *rtas_args); + + +/*  +Function: rtas_call +	Input: +		rtas_args: pointer to RTAS arguments structure +	Output: +		 +Decription: Handle RTAS call. This C function is called +		from the asm function rtas_entry. +*/ + +void +rtas_call (rtas_args_t *rtas_args) +{ +	int idx; + +#ifdef _RTAS_COUNT_CALLS +	/* Count how often every RTAS function is called. */ +	if (rtas_args->token < (int)(sizeof(rtas_callcount)/sizeof(rtas_callcount[0]))) { +		static int callcount_initialized = 0; +		/* If the array is used the first time, we have to set all entries to 0 */ +		if (!callcount_initialized) { +			unsigned int i; +			callcount_initialized = 1; +			for (i = 0; i < sizeof(rtas_callcount)/sizeof(rtas_callcount[0]); i++) +				rtas_callcount[i] = 0; +		} +		/* Increment the counter of the RTAS call */ +		rtas_callcount[rtas_args->token] += 1; +	} +#endif + +#ifdef _RTAS_TRACE +	unsigned int parCnt = rtas_args->nargs; +	unsigned int *pInt = rtas_args->args; +	printf("\n\r*** rtas_call=0x%x", rtas_args->token); +#ifdef _RTAS_COUNT_CALLS +	printf(" count=0x%x", rtas_callcount[rtas_args->token]); +#endif +	printf(" len=0x%x", parCnt); +	printf("\n\r "); +	while(parCnt--) { +		printf("0x%x ", *pInt++); +	} +#endif + +	idx = rtas_args->token - 1; + +	/* Check if there's a function for the token: */ +	if (idx >= 0 && idx < rtas_func_tab_size +	    && rtas_func_tab[idx].func != NULL) { +		/* Now jump to the RTAS function: */ +		rtas_func_tab[idx].func(rtas_args); +	} +	else { +		/* We didn't find a function - return error code: */ +		rtas_args->args[rtas_args->nargs] = -1; +	} + +} diff --git a/roms/SLOF/rtas/rtas_common.S b/roms/SLOF/rtas/rtas_common.S new file mode 100644 index 00000000..35cd9a9f --- /dev/null +++ b/roms/SLOF/rtas/rtas_common.S @@ -0,0 +1,87 @@ +/****************************************************************************** + * 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 + *****************************************************************************/ + +.globl save_regs_r3_r12 +.globl restore_regs_r3_r12 +.globl save_regs_r13_r25 +.globl restore_regs_r13_r25 + + +save_regs_r3_r12: +	stdu    r1,-0x80(r1)            # allocate space on stack + +	std     r3,0x30(r1) +	std     r4,0x38(r1) +	std     r5,0x40(r1) +	std     r6,0x48(r1) +	std     r7,0x50(r1) +	std     r8,0x58(r1) +	std     r9,0x60(r1) +	std     r10,0x68(r1) +	std     r11,0x70(r1) +	std     r12,0x78(r1) + +	blr +	 +restore_regs_r3_r12: +	ld      r3,0x30(r1) +	ld      r4,0x38(r1) +	ld      r5,0x40(r1) +	ld      r6,0x48(r1) +	ld      r7,0x50(r1) +	ld      r8,0x58(r1) +	ld      r9,0x60(r1) +	ld      r10,0x68(r1) +	ld      r11,0x70(r1) +	ld      r12,0x78(r1) + +	addi    r1,r1,0x80		# cleanup stack + +	blr + +save_regs_r13_r25: +	stdu    r1,-0x98(r1)            # allocate space on stack + +	std     r13,0x30(r1) +	std     r14,0x38(r1) +	std     r15,0x40(r1) +	std     r16,0x48(r1) +	std     r17,0x50(r1) +	std     r18,0x58(r1) +	std     r19,0x60(r1) +	std     r20,0x68(r1) +	std     r21,0x70(r1) +	std     r22,0x78(r1) +	std     r23,0x80(r1) +	std     r24,0x88(r1) +	std     r25,0x90(r1) + +	blr + +restore_regs_r13_r25: +	ld      r13,0x30(r1)            # restore registers from stack +	ld      r14,0x38(r1) +	ld      r15,0x40(r1) +	ld      r16,0x48(r1) +	ld      r17,0x50(r1) +	ld      r18,0x58(r1) +	ld      r19,0x60(r1) +	ld      r20,0x68(r1) +	ld      r21,0x70(r1) +	ld      r22,0x78(r1) +	ld      r23,0x80(r1) +	ld      r24,0x88(r1) +	ld      r25,0x90(r1) + +	addi    r1,r1,0x98		# cleanup stack + +	blr diff --git a/roms/SLOF/rtas/rtas_entry.S b/roms/SLOF/rtas/rtas_entry.S new file mode 100644 index 00000000..74693aa4 --- /dev/null +++ b/roms/SLOF/rtas/rtas_entry.S @@ -0,0 +1,72 @@ +/****************************************************************************** + * 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 <rtas.h>		 + + +/* +Function:	 +	Input: +		r3:   rtas parm structure	 +		r4:   base address +	Output:		 + +Decription: Main entry point, called from OS. Second parameter is not +	used.	 +	 +*/ +	.globl rtas_entry +rtas_entry:	 +	mfmsr	r11		# Get MSR to enable 64-bit mode +	mr	r7,r11 +	rotldi	r11,r11,1 +	ori	r11,r11,1	# Always enable 64-bit mode flag +	rotldi	r11,r11,63 +	mtmsrd	r11		# Switch to 64-bit mode +	isync + +	mr r9,r1		# save old stack pointer +	mflr r10		# save link register +	bcl 20,31,.over		# branch to over  +.base:	 +	.align  3 +..got:			.quad   _got-.base+0x8000 +..stack:		.quad   .stack+RTAS_STACKSIZE-0x60-.base +.over:	 +	mflr r8			# gpr 8 is the base +	ld r1,..stack-.base(r8)	# load new stack pointer +	add r1,r1,r8		# add base +	std r2,64(r1)		# save toc +	ld r2,..got-.base(r8)	# load got pointer +	std r7,72(r1)		# save original msr +	std r10,80(r1)		# save link register +	std r9,0(r1)		# save stack pointer +	add r2,r2,r8		# add base + +	bl save_regs_r3_r12 +	bl .rtas_call +	bl restore_regs_r3_r12 + +rtas_return: +	ld r11,72(r1)		# restore msr value	 +	ld r0,80(r1)		# restore link register value +	ld r2,64(r1)		# restore toc +	ld r1,0(r1)		# get old stack +	mtmsrd r11		# restore msr (32 bit ?) +	isync +	mtlr r0 +	blr + + + +	.globl 	.stack +	.lcomm	.stack,RTAS_STACKSIZE  | 
