Mercurial > sarpn
changeset 23:e7b9148156c4
arch: hopefully the rest of the SVC related code
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Wed, 27 Apr 2011 14:48:56 -0400 |
parents | 5f3618fbf9ae |
children | f9ae64d35e81 |
files | Makefile arch/svc.c arch/svcint.h include/svc.h include/svc_prog.h |
diffstat | 5 files changed, 132 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Wed Apr 27 13:00:16 2011 -0400 +++ b/Makefile Wed Apr 27 14:48:56 2011 -0400 @@ -40,7 +40,7 @@ $(AR) rc $@ $^ %.o: %.S - $(AS) -m64 -o $@ $< + $(CC) $(CFLAGS) -c -o $@ $< %.o: %.c $(CC) $(CFLAGS) -include include/system.h -c -o $@ $<
--- a/arch/svc.c Wed Apr 27 13:00:16 2011 -0400 +++ b/arch/svc.c Wed Apr 27 14:48:56 2011 -0400 @@ -20,14 +20,29 @@ 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)); }
--- a/arch/svcint.h Wed Apr 27 13:00:16 2011 -0400 +++ b/arch/svcint.h Wed Apr 27 14:48:56 2011 -0400 @@ -1,10 +1,16 @@ #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)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/svc.h Wed Apr 27 14:48:56 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 14:48:56 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