# HG changeset patch # User Josef 'Jeff' Sipek # Date 1303920995 14400 # Node ID ca308c8ca41e53d0b1a034c68ca0c0658b7bc92d # Parent 175279b7d3d78ac9fa9057c0fd7a6bdfbac674f6 beginning of svc support code diff -r 175279b7d3d7 -r ca308c8ca41e Makefile --- 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 diff -r 175279b7d3d7 -r ca308c8ca41e arch/svc.c --- /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 +#include + +#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; +} diff -r 175279b7d3d7 -r ca308c8ca41e arch/svcint.S --- /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 diff -r 175279b7d3d7 -r ca308c8ca41e arch/svcint.h --- /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 diff -r 175279b7d3d7 -r ca308c8ca41e arch/svcint.o Binary file arch/svcint.o has changed diff -r 175279b7d3d7 -r ca308c8ca41e include/psw.h --- /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