diff options
Diffstat (limited to 'roms/SLOF/clients/net-snk/kernel')
| -rw-r--r-- | roms/SLOF/clients/net-snk/kernel/Makefile | 31 | ||||
| -rw-r--r-- | roms/SLOF/clients/net-snk/kernel/crt0.c | 78 | ||||
| -rw-r--r-- | roms/SLOF/clients/net-snk/kernel/entry.S | 127 | ||||
| -rw-r--r-- | roms/SLOF/clients/net-snk/kernel/init.c | 67 | ||||
| -rw-r--r-- | roms/SLOF/clients/net-snk/kernel/systemcall.c | 176 | ||||
| -rw-r--r-- | roms/SLOF/clients/net-snk/kernel/timer.c | 39 | 
6 files changed, 518 insertions, 0 deletions
diff --git a/roms/SLOF/clients/net-snk/kernel/Makefile b/roms/SLOF/clients/net-snk/kernel/Makefile new file mode 100644 index 00000000..c4b8164c --- /dev/null +++ b/roms/SLOF/clients/net-snk/kernel/Makefile @@ -0,0 +1,31 @@ +# ***************************************************************************** +# * 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 TOP +  TOP = $(shell while ! test -e make.rules; do cd ..  ; done; pwd) +  export TOP +endif +include $(TOP)/make.rules + +OBJS =  init.o systemcall.o crt0.o timer.o +OBJS2 = entry.o + +all: kernel.o  + +kernel.o: $(OBJS) $(OBJS2) +		$(LD) $(LDFLAGS) $(OBJS) $(OBJS2) -o $@ -r + +clean:		 +		$(RM) -f *.o *.a *.i + +include $(TOP)/make.depend diff --git a/roms/SLOF/clients/net-snk/kernel/crt0.c b/roms/SLOF/clients/net-snk/kernel/crt0.c new file mode 100644 index 00000000..a292273b --- /dev/null +++ b/roms/SLOF/clients/net-snk/kernel/crt0.c @@ -0,0 +1,78 @@ +/****************************************************************************** + * 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 <stdlib.h> +#include <string.h> + +extern int main (int, char**); +extern int callback (int, char **); + +int _start(char *arg_string, long len); +unsigned long callback_entry(void *base, unsigned long len); + + +#define MAX_ARGV 10 +static int +gen_argv(const char *arg_string, int len, char* argv[]) +{ +  const char *str, *str_end, *arg_string_end = arg_string + len; +  int i; + +  str = arg_string; +  for (i = 0; i < MAX_ARGV; i++) +    { +      str_end = str; + +      while((*str_end++ != ' ') && (str_end <= arg_string_end)); + +      argv[i] = malloc(str_end-str); + +      memcpy (argv[i], str, str_end-str-1); +      argv[i][str_end-str-1] = '\0'; +      str = str_end-1; +      while(*(++str) == ' '); +      if (str >= arg_string_end) +	break; +    } +  return i+1; +} + + + +int +_start(char * arg_string, long len) +{ +    int rc; +    int argc; +    char* argv[MAX_ARGV]; + +    argc = gen_argv(arg_string, len, argv); + +    rc = main(argc, argv); + +    return rc; +} + +/* + * Takes a Forth representation of a string and generates an argument array, + * then calls callback(). + */ +unsigned long +callback_entry(void *base, unsigned long len) { +	char *argv[MAX_ARGV]; +	int argc; + +	argc = gen_argv(base, len, argv); + +	return (callback(argc, argv)); +} + diff --git a/roms/SLOF/clients/net-snk/kernel/entry.S b/roms/SLOF/clients/net-snk/kernel/entry.S new file mode 100644 index 00000000..8849fb9d --- /dev/null +++ b/roms/SLOF/clients/net-snk/kernel/entry.S @@ -0,0 +1,127 @@ +/****************************************************************************** + * 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 + *****************************************************************************/ + +#define STACKSIZE 0x100000 +#include <macros.h> + + +	.section	".toc","aw"	# TOC entries are needed for relocation +.exception_stack_frame_toc: +	.tc		exception_stack_frame[TC],exception_stack_frame +.exit_sp_toc: +	.tc		_exit_sp[TC],_exit_sp +.prom_entry_toc: +	.tc		_prom_entry[TC],_prom_entry + +	.previous + + +/* +Function:	 +	Input: +		r3:    +		r4:    +		r5:   prom entry	  +	Output:		 + +Decription: Main entry point, called from OF +	 +*/ +C_ENTRY(_entry) +	mr	r3, r6	# parm 0 passed in r6 +	mr	r4, r7	# parm 1 passed in r7	 +	mr	r6, r1	# save stack pointer	 +	mflr	r7	# save link register +	bcl	20,31,over	# branch after pointer table +base:	 +	.align  3 +.LCgot:		.quad   _got-base+0x8000 +.LCstack:	.quad   _stack+STACKSIZE-0x80-base +over:	 +	mflr	r8		# gpr 8 is the base +	ld	r1,.LCstack-base(r8)	# load new stack pointer +	add	r1, r1, r8		# add base +	std	r2, 64(r1)		# save got +	std	r7, 56(r1)		# save link register +	ld	r2, .LCgot-base(r8)	# load got pointer +	add	r2, r2, r8		# add base +	std	r6, 0(r1)		# save stack pointer + +	ld	r6, .prom_entry_toc@toc(r2) +	std	r5, 0(r6)		# Save prom handle + +	ld	r10, .exit_sp_toc@toc(r2)  # save stack pointer for exit call +	std	r1, 0(r10) + +	bl	._start_kernel		# call kernel init code + +the_end: +	ld	r4, 56(r1)		# Restore link register +	mtlr	r4 +	ld	r2, 64(r1)		# restore got +	ld	r1, 0(r1) + +	blr + +/* + * Function: _callback_entry + * Input:   r6  start address of parameter string + *          r7  length of parameter string. + * + * Description: If a client application wants to register a callback function, + *  this function is registered w/ SLOF, not the application's function. SLOF + *  passes the parameter string in Forth representation in R6 and R7. This + *  function moves R6 to R3 and R7 to R4 and then calls callback_entry(). + * + */ +C_ENTRY(_callback_entry) +	# Save the LR +	mflr	r0 +	std	r0, 16(r1) + +	# Reserve stack space +	stdu	r1,	-32(r1) + +	# SLOF passes the parameters in Registers R6 and R7 but the target +	# wants them in registers R3 and R4 +	mr	r3, r6 +	mr	r4, r7 + +	# Branch to the callback_entry function +	bl	.callback_entry + +	# Destroy stack frame +	ld	r1,	0(r1) + +	# Restore LR +	ld	r0, 16(r1) +	mtlr	r0 + +	# Return to caller +	blr + +	.section	".bss" + +_exit_sp:	.quad 0 + +.global		_prom_entry +_prom_entry:	.quad 0 + +	.section	".text" + +C_ENTRY(_exit) +	ld	r1, .exit_sp_toc@toc(r2) +	ld	r1, 0(r1) +	b	the_end + + +       .lcomm  _stack,STACKSIZE,16 diff --git a/roms/SLOF/clients/net-snk/kernel/init.c b/roms/SLOF/clients/net-snk/kernel/init.c new file mode 100644 index 00000000..1376b647 --- /dev/null +++ b/roms/SLOF/clients/net-snk/kernel/init.c @@ -0,0 +1,67 @@ +/****************************************************************************** + * 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 <string.h> +#include <stdlib.h> /* malloc */ +#include <of.h> +#include <pci.h> +#include <kernel.h> +#include <cpu.h> +#include <fileio.h> + +/* Application entry point .*/ +extern int _start(unsigned char *arg_string, long len); +extern int main(int, char**); +int _start_kernel(unsigned long p0, unsigned long p1); +void * malloc_aligned(size_t size, int align); + +unsigned long exception_stack_frame; + +snk_fileio_t fd_array[FILEIO_MAX]; + +extern uint64_t tb_freq; + +extern char __client_start; +extern char __client_end; + +void * malloc_aligned(size_t size, int align) +{ +	unsigned long p = (unsigned long) malloc(size + align - 1); +	p = p + align - 1; +	p = p & ~(align - 1); + +	return (void *) p; +} + +int _start_kernel(unsigned long p0, unsigned long p1) +{ +	int rc; +	unsigned int timebase; + +	/* initialize all file descriptor by marking them as empty */ +	for(rc=0; rc<FILEIO_MAX; ++rc) +		fd_array[rc].type = FILEIO_TYPE_EMPTY; + +	/* this is step is e.g. resposible to initialize file descriptor 0 and 1 for STDIO */ +	rc = of_glue_init(&timebase, (size_t)(unsigned long)&__client_start, +			  (size_t)(unsigned long)&__client_end - (size_t)(unsigned long)&__client_start); +	if(rc < 0) +		return -1; + +	tb_freq = (uint64_t) timebase; +	rc = _start((unsigned char *) p0, p1); + +	of_glue_release(); +	return rc; +} + diff --git a/roms/SLOF/clients/net-snk/kernel/systemcall.c b/roms/SLOF/clients/net-snk/kernel/systemcall.c new file mode 100644 index 00000000..52c45cad --- /dev/null +++ b/roms/SLOF/clients/net-snk/kernel/systemcall.c @@ -0,0 +1,176 @@ +/****************************************************************************** + * 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 <stdarg.h> +#include <string.h> +#include <fileio.h> +#include <kernel.h> +#include <of.h> +#include <sys/socket.h> + +extern int vsprintf(char *, const char *, va_list); +extern void _exit(int status); + +void exit(int status); + +int open(const char* name, int flags) +{ +	int fd; + +	/* search free file descriptor */ +	for (fd=0; fd<FILEIO_MAX; ++fd) { +		if(fd_array[fd].type == FILEIO_TYPE_EMPTY) { +			break; +		} +	} +	if (fd == FILEIO_MAX) { +		printf("Can not open \"%s\" because file descriptor list is full\n", name); +		/* there is no free file descriptor available */ +		return -2; +	} + +	fd_array[fd].ih = of_open(name); +	if (fd_array[fd].ih == 0) +		return -1; + +	fd_array[fd].type = FILEIO_TYPE_FILE; + +	return fd; +} + +int pre_open_ih(int fd, ihandle_t ih) +{ +	if (fd_array[fd].type != FILEIO_TYPE_EMPTY) +		return -2; +	fd_array[fd].ih = ih; +	fd_array[fd].type = FILEIO_TYPE_FILE; + +	return fd; +} + +int socket(int domain, int type, int proto, char *mac_addr) +{ +	uint8_t tmpbuf[8]; +	int fd; +	phandle_t ph; + +	/* search free file descriptor */ +	for (fd=0; fd<FILEIO_MAX; ++fd) { +		if(fd_array[fd].type == FILEIO_TYPE_EMPTY) { +			break; +		} +	} +	if (fd == FILEIO_MAX) { +		printf("Can not open socket, file descriptor list is full\n"); +		/* there is no free file descriptor available */ +		return -2; +	} + +	fd_array[fd].ih = of_interpret_1("my-parent", tmpbuf); +	if (fd_array[fd].ih == 0) { +		printf("Can not open socket, no parent instance\n"); +		return -1; +	} +	ph = of_instance_to_package(fd_array[fd].ih); +	if (ph == -1) { +		printf("Can not open socket, no parent package\n"); +		return -1; +	} +	if (of_get_mac(ph, mac_addr) < 0) { +		printf("Can not open socket, no MAC address\n"); +		return -1; +	} +	fd_array[fd].type = FILEIO_TYPE_SOCKET; + +	return fd; +} + +int close(int fd) +{ +	if (fd < 0 || fd >= FILEIO_MAX || +	    fd_array[fd].type == FILEIO_TYPE_EMPTY) +		return -1; +	if (fd_array[fd].type == FILEIO_TYPE_FILE) +		of_close(fd_array[fd].ih); +	fd_array[fd].type = FILEIO_TYPE_EMPTY; +	return 0; +} + +ssize_t read(int fd, void *buf, size_t len) +{ +	if (fd < 0 || fd >= FILEIO_MAX || +	    fd_array[fd].type == FILEIO_TYPE_EMPTY) +		return -1; + +	return of_read(fd_array[fd].ih, buf, len); +} + +ssize_t write (int fd, const void *buf, size_t len) +{ +	char dest_buf[512]; +	char *dest_buf_ptr; +	const char *dbuf = buf; +	int i; + +	if (fd == 1 || fd == 2) { +		dest_buf_ptr = &dest_buf[0]; +		for (i = 0; i < len && i < 256; i++) +			{ +				*dest_buf_ptr++ = *dbuf++; +				if (dbuf[-1] == '\n') +					*dest_buf_ptr++ = '\r'; +			} +		len = dest_buf_ptr - &dest_buf[0]; +		buf = &dest_buf[0]; +	} + +	if(fd < 0 || fd >= FILEIO_MAX || +	   fd_array[fd].type == FILEIO_TYPE_EMPTY) +		return -1; + +	return of_write(fd_array[fd].ih, (void *)buf, len); +} + +ssize_t lseek (int fd, long offset, int whence) +{ +	return 0; // this syscall is unused !!! +#if 0 +    if (whence != 0) +	return -1; + +    of_seek (fd_array[fd], (unsigned int) (offset>>32), (unsigned int) (offset & 0xffffffffULL)); + +    return offset; +#endif +} + +int recv(int fd, void *packet, int packet_len, int flags) +{ +	return read(fd, packet, packet_len); +} + +int send(int fd, const void *packet, int packet_len, int flags) +{ +	return write(fd, packet, packet_len); +} + +int sendto(int fd, const void *packet, int packet_len, int flags, +	   const void *sock_addr, int sock_addr_len) +{ +	return send(fd, packet, packet_len, flags); +} + +void exit(int status) +{ +	_exit(status); +} diff --git a/roms/SLOF/clients/net-snk/kernel/timer.c b/roms/SLOF/clients/net-snk/kernel/timer.c new file mode 100644 index 00000000..2d870589 --- /dev/null +++ b/roms/SLOF/clients/net-snk/kernel/timer.c @@ -0,0 +1,39 @@ +/****************************************************************************** + * 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 "kernel.h" + +//******************************************************************* +// variable "tb_freq" contains the frequency in Hz +// and is read from the device tree (setup by LLFW) in "init.c" +uint64_t tb_freq; + +//------------------------------------------------------------------- +// Read the current timebase +uint64_t get_time(void) +{ +    uint64_t act; + +    __asm__ __volatile__(  +        "0:     mftbu   %0 ;\ +                mftbl   %%r0 ; \ +                mftbu   %%r4 ; \ +                cmpw    %0,%%r4 ; \ +                bne     0b; \ +                sldi    %0,%0,32; \ +                or      %0,%0,%%r0" +        : "=r"(act) +        : /* no inputs */ +        : "r0", "r4"); +    return act; +}  | 
