changeset 86:cc10ad44c2c2

merge
author Jonathan Pevarnek <pevarnj@gmail.com>
date Wed, 27 Apr 2011 22:11:51 -0400
parents 2fb2138d8c83 (current diff) e7b9148156c4 (diff)
children 480f5685b3c2
files Makefile
diffstat 9 files changed, 326 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Wed Apr 27 20:52:56 2011 -0400
+++ b/Makefile	Wed Apr 27 22:11:51 2011 -0400
@@ -17,7 +17,8 @@
 dynamic_OBJS=src/dynamic.o src/std.o src/stack.o arch/arch.a
 testFS_OBJS=src/testFS.o src/std.o src/fs.o arch/arch.a
 
-ARCH_OBJS=arch/io.o arch/cons.o arch/ebcdic.o arch/fba.o arch/ioint.o
+ARCH_OBJS=arch/io.o arch/cons.o arch/ebcdic.o arch/fba.o arch/ioint.o \
+	  arch/svc.o arch/svcint.o
 
 .PHONY: all build clean tags
 
@@ -48,7 +49,7 @@
 	$(AR) rc $@ $^
 
 %.o: %.S
-	$(AS) -m64 -o $@ $<
+	$(CC) $(CFLAGS) -c -o $@ $<
 
 %.o: %.c
 	$(CC) $(CFLAGS) -include include/system.h -c -o $@ $<
--- a/README	Wed Apr 27 20:52:56 2011 -0400
+++ b/README	Wed Apr 27 22:11:51 2011 -0400
@@ -5,10 +5,11 @@
 You can safely ignore:
 	ipl/*
 	scripts/*
-	src/io.c
+	arch/*
 
 You can put your code in src/ and your include files in include/.  If you
-add any .c files, you'll have to add them to the OBJS line in the Makefile.
+add any .c files, you'll have to add them to the foo_OBJS line in the
+Makefile.
 
 Building
 --------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arch/svc.c	Wed Apr 27 22:11:51 2011 -0400
@@ -0,0 +1,48 @@
+#include <psw.h>
+#include <die.h>
+
+#include "svcint.h"
+
+void setcontext(struct psw *psw, u64 *regs)
+{
+	__builtin_memcpy(PSA_PSW_TMP, psw, sizeof(struct psw));
+
+	asm volatile(
+		"lmg	%%r0,%%r15,%0\n"	/* load gpr */
+		"lpswe	%1\n"			/* load new psw */
+	: /* output */
+	: /* input */
+	  "m" (*regs),
+	  "m" (*PSA_PSW_TMP)
+	);
+
+	/* unreachable */
+	die();
+}
+
+void savecontext(struct psw *psw, u64 *regs)
+{
+	__builtin_memcpy(psw, PSA_OLD_SVC_PSW, sizeof(struct psw));
+	__builtin_memcpy(regs, PSA_GPRS, 16*sizeof(u64));
+}
+
+extern void *SVCINT;
+u64 _SVC_HANDLER;
+u64 _SVC_STACK;
+
+void set_svc_handler(u64(*f)(u64, u64, u64, u64), void *stack)
+{
+	struct psw psw;
+
+	if (((u64)stack) & 7)
+		die();
+
+	_SVC_HANDLER = (u64) f;
+	_SVC_STACK   = (u64) stack;
+
+	__builtin_memset(&psw, 0, sizeof(struct psw));
+	psw.ea = 1;
+	psw.ba = 1;
+	psw.ptr = (u64) &SVCINT;
+	__builtin_memcpy(PSA_NEW_SVC_PSW, &psw, sizeof(struct psw));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arch/svcint.S	Wed Apr 27 22:11:51 2011 -0400
@@ -0,0 +1,26 @@
+#include "svcint.h"
+
+.text
+	.align	4
+.globl SVCINT
+	.type	SVCINT, @function
+SVCINT:
+	stmg	%r0,%r15,_PSA_GPRS
+
+	xgr	%r2,%r2
+	ic	%r2,_PSA_SVC_ID+3	# r2 = SVC
+	lmg	%r3,%r6,_PSA_GPRS+16	# shift all the args
+	xgr	%r7,%r7			# just to make sure accesses to more
+					# than 4 args fail
+	larl	%r15,_SVC_STACK
+	lg	%r15,0(%r15)
+
+	# call into C... f(svc, arg0, arg1, arg2, arg3)
+	larl	%r14,_SVC_HANDLER
+	lg	%r14,0(%r14)
+	basr	%r14,%r14
+
+	stmg	%r2,%r3,_PSA_GPRS+16	# store the return value
+
+	lmg	%r0,%r15,_PSA_GPRS
+	lpswe	_PSA_OLD_SVC_PSW
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arch/svcint.h	Wed Apr 27 22:11:51 2011 -0400
@@ -0,0 +1,17 @@
+#ifndef __SVCINT_H
+#define __SVCINT_H
+
+#define _PSA_OLD_SVC_PSW	0x140
+#define _PSA_NEW_SVC_PSW	0x1c0
+
+#define _PSA_SVC_ID	0x88
+#define _PSA_GPRS	0x200
+#define _PSA_PSW_TMP	0x280
+
+#define PSA_OLD_SVC_PSW		((struct psw*) _PSA_OLD_SVC_PSW)
+#define PSA_NEW_SVC_PSW		((struct psw*) _PSA_NEW_SVC_PSW)
+
+#define PSA_GPRS	((u64*) _PSA_GPRS)
+#define PSA_PSW_TMP	((struct psw*) _PSA_PSW_TMP)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/elf.h	Wed Apr 27 22:11:51 2011 -0400
@@ -0,0 +1,88 @@
+#ifndef __ELF_H
+#define __ELF_H
+
+#define EI_MAG0		0
+#define EI_MAG1		1
+#define EI_MAG2		2
+#define EI_MAG3		3
+#define EI_CLASS	4
+#define EI_DATA		5
+#define EI_VERSION	6
+#define EI_OSABI	7
+#define EI_ABIVERSION	8
+#define EI_PAD		9
+#define EI_NIDENT	16
+
+#define ELFMAG0		0x7f
+#define ELFMAG1		'E'
+#define ELFMAG2		'L'
+#define ELFMAG3		'F'
+
+#define ELFCLASS64	2
+
+#define ELFDATA2MSB	2
+
+#define EV_CURRENT	1
+
+#define ELFOSABI_NONE	0
+
+#define ET_EXEC		2
+
+#define EM_S390		22
+
+#define PT_NULL		0
+#define PT_LOAD		1
+#define PT_DYNAMIC	2
+#define PT_INTERP	3
+#define PT_NOTE		4
+#define PT_SHLIB	5
+#define PT_PHDR		6
+#define PT_TLS		7
+
+#define PF_X		0x1
+#define PF_W		0x2
+#define PF_R		0x4
+
+typedef u64 Elf64_Addr;
+typedef u64 Elf64_Off;
+typedef u16 Elf64_Half;
+typedef u32 Elf64_Word;
+typedef s32 Elf64_Sword;
+typedef u64 Elf64_Xword;
+typedef s64 Elf64_Sxword;
+
+/*
+ * ELF file header
+ */
+typedef struct {
+	unsigned char   e_ident[EI_NIDENT];	/* ELF identification */
+	Elf64_Half      e_type;			/* Object file type */
+	Elf64_Half      e_machine;		/* Machine type */
+	Elf64_Word      e_version;		/* Object file version */
+	Elf64_Addr      e_entry;		/* Entry point address */
+	Elf64_Off       e_phoff;		/* Program header offset */
+	Elf64_Off       e_shoff;		/* Section header offset */
+	Elf64_Word      e_flags;		/* Processor-specific flags */
+	Elf64_Half      e_ehsize;		/* ELF header size */
+	Elf64_Half      e_phentsize;		/* Size of program header entry */
+	Elf64_Half      e_phnum;		/* Number of program header entries */
+	Elf64_Half      e_shentsize;		/* Size of section header entries */
+	Elf64_Half      e_shnum;		/* Number of section header entries */
+	Elf64_Half      e_shstrndx;		/* Section name string table index */
+} Elf64_Ehdr;
+
+/*
+ * ELF program header
+ */
+typedef struct {
+	Elf64_Word	p_type;			/* Segment type */
+	Elf64_Word	p_flags;		/* Segment file offset */
+	Elf64_Off	p_offset;		/* Segment virt. addr */
+	Elf64_Addr	p_vaddr;		/* <undefined> */
+	Elf64_Addr	p_paddr;		/* Segment size in file */
+	Elf64_Xword	p_filesz;		/* Segment size in mem */
+	Elf64_Xword	p_memsz;		/* Segment flags */
+	Elf64_Xword	p_align;		/* Segment alignment */
+} Elf64_Phdr;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/psw.h	Wed Apr 27 22:11:51 2011 -0400
@@ -0,0 +1,31 @@
+#ifndef __PSW_H
+#define __PSW_H
+
+struct psw {
+	u8 _zero0:1,
+	   r:1,			/* PER Mask (R)			*/
+	   _zero1:3,
+	   t:1,			/* DAT Mode (T)			*/
+	   io:1,		/* I/O Mask (IO)		*/
+	   ex:1;		/* External Mask (EX)		*/
+
+	u8 key:4,		/* Key				*/
+	   _zero2:1,
+	   m:1,			/* Machine-Check Mask (M)	*/
+	   w:1,			/* Wait State (W)		*/
+	   p:1;			/* Problem State (P)		*/
+
+	u8 as:2,		/* Address-Space Control (AS)	*/
+	   cc:2,		/* Condition Code (CC)		*/
+	   prog_mask:4;		/* Program Mask			*/
+
+	u8 _zero3:7,
+	   ea:1;		/* Extended Addressing (EA)	*/
+
+	u32 ba:1,		/* Basic Addressing (BA)	*/
+	    _zero4:31;
+
+	u64 ptr;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/svc.h	Wed Apr 27 22:11:51 2011 -0400
@@ -0,0 +1,10 @@
+#ifndef __SVC_H
+#define __SVC_H
+
+#include <psw.h>
+
+extern void setcontext(struct psw *psw, u64 *regs);
+extern void savecontext(struct psw *psw, u64 *regs);
+extern void set_svc_handler(u64(*f)(u64, u64, u64, u64), void *stack);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/svc_prog.h	Wed Apr 27 22:11:51 2011 -0400
@@ -0,0 +1,100 @@
+#ifndef __SVC_PROG_H
+#define __SVC_PROG_H
+
+/* invokes the specified SVC with 0 to 4 args */
+
+#define invoke_svc0(n) ({ \
+				u64 _ret; \
+				asm volatile( \
+					"svc	%1\n" \
+					"lgr	%0,%%r2\n" \
+				: /* output */ \
+				  "=r" (_ret) \
+				: /* input */ \
+				  "i" (n) \
+				: /* clobber */ \
+				  "cc", "r2", "r3" \
+				); \
+				_ret; \
+			})
+
+#define invoke_svc1(n, a1) ({ \
+				u64 _ret; \
+				asm volatile( \
+					"lgr	%%r2,%2\n" \
+					"svc	%1\n" \
+					"lgr	%0,%%r2\n" \
+				: /* output */ \
+				  "=r" (_ret) \
+				: /* input */ \
+				  "i" (n) \
+				  "d" (a1) \
+				: /* clobber */ \
+				  "cc", "r2", "r3" \
+				); \
+				_ret; \
+			})
+
+#define invoke_svc2(n, a1, a2) ({ \
+				u64 _ret; \
+				asm volatile( \
+					"lgr	%%r2,%2\n" \
+					"lgr	%%r3,%3\n" \
+					"svc	%1\n" \
+					"lgr	%0,%%r2\n" \
+				: /* output */ \
+				  "=r" (_ret) \
+				: /* input */ \
+				  "i" (n) \
+				  "d" (a1) \
+				  "d" (a2) \
+				: /* clobber */ \
+				  "cc", "r2", "r3" \
+				); \
+				_ret; \
+			})
+
+#define invoke_svc3(n, a1, a2, a3) ({ \
+				u64 _ret; \
+				asm volatile( \
+					"lgr	%%r2,%2\n" \
+					"lgr	%%r3,%3\n" \
+					"lgr	%%r4,%4\n" \
+					"svc	%1\n" \
+					"lgr	%0,%%r2\n" \
+				: /* output */ \
+				  "=r" (_ret) \
+				: /* input */ \
+				  "i" (n) \
+				  "d" (a1) \
+				  "d" (a2) \
+				  "d" (a3) \
+				: /* clobber */ \
+				  "cc", "r2", "r3", "r4" \
+				); \
+				_ret; \
+			})
+
+#define invoke_svc4(n, a1, a2, a3, a4) ({ \
+				u64 _ret; \
+				asm volatile( \
+					"lgr	%%r2,%2\n" \
+					"lgr	%%r3,%3\n" \
+					"lgr	%%r4,%4\n" \
+					"lgr	%%r5,%5\n" \
+					"svc	%1\n" \
+					"lgr	%0,%%r2\n" \
+				: /* output */ \
+				  "=r" (_ret) \
+				: /* input */ \
+				  "i" (n) \
+				  "d" (a1) \
+				  "d" (a2) \
+				  "d" (a3) \
+				: /* clobber */ \
+				  "cc", "r2", "r3", "r4", "r5" \
+				); \
+				_ret; \
+			})
+
+#endif