changeset 83:ca308c8ca41e

beginning of svc support code
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Wed, 27 Apr 2011 12:16:35 -0400
parents 175279b7d3d7
children 5f3618fbf9ae
files Makefile arch/svc.c arch/svcint.S arch/svcint.h arch/svcint.o include/psw.h
diffstat 6 files changed, 103 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Wed Apr 27 10:45:47 2011 -0400
+++ b/Makefile	Wed Apr 27 12:16:35 2011 -0400
@@ -15,7 +15,8 @@
 
 sarpn_OBJS=src/init.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
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arch/svc.c	Wed Apr 27 12:16:35 2011 -0400
@@ -0,0 +1,33 @@
+#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();
+}
+
+u64 _SVC_HANDLER;
+u64 _SVC_STACK;
+
+void set_svc_handler(u64(*f)(u64, u64, u64, u64), void *stack)
+{
+	if (((u64)stack) & 7)
+		die();
+
+	_SVC_HANDLER = (u64) f;
+	_SVC_STACK   = (u64) stack;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arch/svcint.S	Wed Apr 27 12:16:35 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,%r15
+
+	# call into C... f(svc, arg0, arg1, arg2, arg3)
+	larl	%r14,_SVC_HANDLER
+	lg	%r14,%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 12:16:35 2011 -0400
@@ -0,0 +1,11 @@
+#ifndef __SVCINT_H
+#define __SVCINT_H
+
+#define _PSA_SVC_ID	0x88
+#define _PSA_GPRS	0x200
+#define _PSA_PSW_TMP	0x280
+
+#define PSA_GPRS	((u64*) _PSA_GPRS)
+#define PSA_PSW_TMP	((struct psw*) _PSA_PSW_TMP)
+
+#endif
Binary file arch/svcint.o has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/psw.h	Wed Apr 27 12:16:35 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