summaryrefslogtreecommitdiffstats
path: root/qemu/roms/SLOF/clients/net-snk/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/SLOF/clients/net-snk/kernel')
-rw-r--r--qemu/roms/SLOF/clients/net-snk/kernel/Makefile31
-rw-r--r--qemu/roms/SLOF/clients/net-snk/kernel/crt0.c78
-rw-r--r--qemu/roms/SLOF/clients/net-snk/kernel/entry.S127
-rw-r--r--qemu/roms/SLOF/clients/net-snk/kernel/init.c67
-rw-r--r--qemu/roms/SLOF/clients/net-snk/kernel/systemcall.c176
-rw-r--r--qemu/roms/SLOF/clients/net-snk/kernel/timer.c39
6 files changed, 518 insertions, 0 deletions
diff --git a/qemu/roms/SLOF/clients/net-snk/kernel/Makefile b/qemu/roms/SLOF/clients/net-snk/kernel/Makefile
new file mode 100644
index 000000000..c4b8164ca
--- /dev/null
+++ b/qemu/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/qemu/roms/SLOF/clients/net-snk/kernel/crt0.c b/qemu/roms/SLOF/clients/net-snk/kernel/crt0.c
new file mode 100644
index 000000000..a292273b0
--- /dev/null
+++ b/qemu/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/qemu/roms/SLOF/clients/net-snk/kernel/entry.S b/qemu/roms/SLOF/clients/net-snk/kernel/entry.S
new file mode 100644
index 000000000..8849fb9d1
--- /dev/null
+++ b/qemu/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/qemu/roms/SLOF/clients/net-snk/kernel/init.c b/qemu/roms/SLOF/clients/net-snk/kernel/init.c
new file mode 100644
index 000000000..1376b6474
--- /dev/null
+++ b/qemu/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/qemu/roms/SLOF/clients/net-snk/kernel/systemcall.c b/qemu/roms/SLOF/clients/net-snk/kernel/systemcall.c
new file mode 100644
index 000000000..52c45cad7
--- /dev/null
+++ b/qemu/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/qemu/roms/SLOF/clients/net-snk/kernel/timer.c b/qemu/roms/SLOF/clients/net-snk/kernel/timer.c
new file mode 100644
index 000000000..2d8705895
--- /dev/null
+++ b/qemu/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;
+}