Mercurial > sos > sos
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