diff options
author | dwilder <dwilder> | 2006-10-19 18:37:15 +0000 |
---|---|---|
committer | dwilder <dwilder> | 2006-10-19 18:37:15 +0000 |
commit | 24cb8c3b07c5fed086555b54f9f753bb78df6837 (patch) | |
tree | 9cdfcd666b46b16944ad23f41686cf7bfebfaafb /runtime | |
parent | 0b951e7c1aa8653655d63bda882d392f0c2216c8 (diff) | |
download | systemtap-steved-24cb8c3b07c5fed086555b54f9f753bb78df6837.tar.gz systemtap-steved-24cb8c3b07c5fed086555b54f9f753bb78df6837.tar.xz systemtap-steved-24cb8c3b07c5fed086555b54f9f753bb78df6837.zip |
Adding s390x support
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/arith.c | 7 | ||||
-rw-r--r-- | runtime/copy.c | 5 | ||||
-rw-r--r-- | runtime/current.c | 33 | ||||
-rw-r--r-- | runtime/loc2c-runtime.h | 158 | ||||
-rw-r--r-- | runtime/regs.h | 9 | ||||
-rw-r--r-- | runtime/stack-s390.c | 82 | ||||
-rw-r--r-- | runtime/stack.c | 2 |
7 files changed, 296 insertions, 0 deletions
diff --git a/runtime/arith.c b/runtime/arith.c index fea7421a..97121ae8 100644 --- a/runtime/arith.c +++ b/runtime/arith.c @@ -25,6 +25,13 @@ long long _div64 (long long u, long long v); long long _mod64 (long long u, long long v); #endif +/* 31 bit s390 suupport is not yet included, it may never be. +#ifdef __s390__ +long long _div64 (long long u, long long v); +long long _mod64 (long long u, long long v); +#endif +*/ + /** Divide x by y. In case of division-by-zero, * set context error string, and return 0 */ diff --git a/runtime/copy.c b/runtime/copy.c index f4d906b3..4d716861 100644 --- a/runtime/copy.c +++ b/runtime/copy.c @@ -88,6 +88,11 @@ do { \ #elif defined (__powerpc64__) || defined (__ia64__) #define __stp_strncpy_from_user(dst,src,count,res) \ do { res = __strncpy_from_user(dst, src, count); } while(0) + +#elif defined (__s390__) || defined (__s390x__) +#define __stp_strncpy_from_user(dst,src,count,res) \ + do { res = strncpy_from_user(dst, src, count); } while(0) + #endif /** Copy a NULL-terminated string from userspace. diff --git a/runtime/current.c b/runtime/current.c index 5dbc06ef..809f253b 100644 --- a/runtime/current.c +++ b/runtime/current.c @@ -44,6 +44,8 @@ unsigned long _stp_ret_addr (struct pt_regs *regs) return REG_LINK(regs); #elif defined (__ia64__) return regs->b0; +#elif defined (__s390__) || defined (__s390x__) + return regs->gprs[14]; #else #error Unimplemented architecture #endif @@ -208,6 +210,37 @@ void _stp_sprint_regs(String str, struct pt_regs * regs) _stp_string_cat(str, "\n"); } +#elif defined (__s390x__) || defined (__s390__) + +#ifdef __s390x__ +#define GPRSIZE "%016lX " +#else /* s390 */ +#define GPRSIZE "%08lX " +#endif + +void _stp_sprint_regs(String str, struct pt_regs * regs) +{ + char *mode; + int i; + + mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl"; + _stp_sprintf(str,"%s PSW : ["GPRSIZE"] ["GPRSIZE"]", + mode, (void *) regs->psw.mask, + (void *) regs->psw.addr); + +#ifdef CONFIG_SMP + _stp_sprintf(str, " CPU: %d", smp_processor_id()); +#endif /* CONFIG_SMP */ + + for (i = 0; i < 16; i++) { + if ((i % 4) == 0) { + _stp_sprintf(str, "\n GPRS%02d: ", i); + } + _stp_sprintf(str, GPRSIZE, regs->gprs[i]); + } + _stp_string_cat(str, "\n"); +} + #endif /** Print the registers. diff --git a/runtime/loc2c-runtime.h b/runtime/loc2c-runtime.h index c88ad97e..493f0193 100644 --- a/runtime/loc2c-runtime.h +++ b/runtime/loc2c-runtime.h @@ -112,6 +112,12 @@ #define fetch_register(regno) ((intptr_t) c->regs->gpr[regno]) #define store_register(regno) (c->regs->gpr[regno] = (value)) +#elif defined (__s390__) || defined (__s390x__) +#undef fetch_register +#undef store_register +#define fetch_register(regno) ((intptr_t) c->regs->gprs[regno]) +#define store_register(regno) (c->regs->gprs[regno] = (value)) + #endif #if defined __i386__ || defined __x86_64__ @@ -254,8 +260,160 @@ goto deref_fault; \ }) +#elif defined (__s390__) || defined (__s390x__) + +#if defined __s390__ +#define __stp_get_asm(x, addr, err, size) \ +({ \ + asm volatile( \ + "0: mvc 0(%2,%4),0(%3)\n" \ + "1:\n" \ + ".section .fixup,\"ax\"\n" \ + "2: lhi %0,%5\n" \ + " bras 1,3f\n" \ + " .long 1b\n" \ + "3: l 1,0(1)\n" \ + " br 1\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,2b\n" \ + ".previous" \ + : "+&d" (err), "=m" (x) \ + : "i" (size),"a"(addr), \ + "a" (&(x)),"K" (-EFAULT) \ + : "cc", "1" ); \ +}) + +#define __stp_put_asm(x, addr, err, size) \ +({ \ + asm volatile( \ + "0: mvc 0(%1,%2),0(%3)\n" \ + "1:\n" \ + ".section .fixup,\"ax\"\n" \ + "2: lhi %0,%5\n" \ + " bras 1,3f\n" \ + " .long 1b\n" \ + "3: l 1,0(1)\n" \ + " br 1\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 0b,2b\n" \ + ".previous" \ + : "+&d" (err) \ + : "i" (size), "a" (addr), \ + "a" (&(x)),"K" (-EFAULT) \ + : "cc", "1"); \ +}) + +#else /* s390x */ + +#define __stp_get_asm(x, addr, err, size) \ +({ \ + asm volatile( \ + "0: mvc 0(%2,%4),0(%3)\n" \ + "1:\n" \ + ".section .fixup,\"ax\"\n" \ + "2: lghi %0,%5\n" \ + " jg 1b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 8\n" \ + " .quad 0b,2b\n" \ + ".previous" \ + : "+&d" (err), "=m" (x) \ + : "i" (size),"a"(addr), \ + "a" (&(x)),"K" (-EFAULT) \ + : "cc"); \ +}) + +#define __stp_put_asm(x, addr, err, size) \ +({ \ + asm volatile( \ + "0: mvc 0(%1,%2),0(%3)\n" \ + "1:\n" \ + ".section .fixup,\"ax\"\n" \ + "2: lghi %0,%4\n" \ + " jg 1b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 8\n" \ + " .quad 0b,2b\n" \ + ".previous" \ + : "+&d" (err) \ + : "i" (size),"a"(addr), \ + "a"(&(x)),"K"(-EFAULT) \ + : "cc"); \ +}) #endif +#define deref(size, addr) \ +({ \ + u8 _b; u16 _w; u32 _l; u64 _q; \ + int _bad = 0; \ + intptr_t _v = 0; \ + switch (size) { \ + case 1: { \ + __stp_get_asm(_b, addr, _bad, 1); \ + _v = _b; \ + break; \ + }; \ + case 2: { \ + __stp_get_asm(_w, addr, _bad, 2); \ + _v = _w; \ + break; \ + }; \ + case 4: { \ + __stp_get_asm(_l, addr, _bad, 4); \ + _v = _l; \ + break; \ + }; \ + case 8: { \ + __stp_get_asm(_q, addr, _bad, 8); \ + _v = _q; \ + break; \ + }; \ + default: \ + _bad = -EFAULT; \ + } \ + if (_bad) \ + goto deref_fault; \ + _v; \ +}) + +#define deref_store(size, addr, value) \ +({ \ + int _bad = 0; \ + switch (size) { \ + case 1:{ \ + u8 _x = value; \ + __stp_put_asm(_x, addr, _bad,1); \ + break; \ + }; \ + case 2:{ \ + u16 _x = value; \ + __stp_put_asm(_x, addr, _bad,2); \ + break; \ + }; \ + case 4:{ \ + u32 _x = value; \ + __stp_put_asm(_x, addr, _bad,4); \ + break; \ + }; \ + case 8: { \ + u64 _x = value; \ + __stp_put_asm(_x, addr, _bad,8); \ + break; \ + }; \ + default: \ + break; \ + } \ + if (_bad) \ + goto deref_fault; \ +}) +#endif /* (s390) || (s390x) */ + #define deref_string(dst, addr, maxbytes) \ ({ \ uintptr_t _addr; \ diff --git a/runtime/regs.h b/runtime/regs.h index 0e759d1d..48487c4d 100644 --- a/runtime/regs.h +++ b/runtime/regs.h @@ -32,6 +32,15 @@ #define REG_SP(regs) regs->gpr[1] #define REG_LINK(regs) regs->link +#elif defined (__s390__) || defined (__s390x__) +#ifndef __s390x__ +#define PSW_ADDR_AMODE 0x80000000UL +#else /* __s390x__ */ +#define PSW_ADDR_AMODE 0x0000000000000000UL +#endif /* __s390x__ */ +#define REG_IP(regs) ((regs)->psw.addr) | PSW_ADDR_AMODE +#define REG_SP(regs) (regs)->gprs[15] + #else #error "Unimplemented architecture" #endif diff --git a/runtime/stack-s390.c b/runtime/stack-s390.c new file mode 100644 index 00000000..c65de741 --- /dev/null +++ b/runtime/stack-s390.c @@ -0,0 +1,82 @@ +/* -*- linux-c -*- + * ppc64 stack tracing functions + * + * This file is part of systemtap, and is free software. You can + * redistribute it and/or modify it under the terms of the GNU General + * Public License (GPL); either version 2, or (at your option) any + * later version. + */ + +static unsigned long +__stp_show_stack (String str, unsigned long sp, unsigned long low, + unsigned long high, int verbose) +{ + + struct stack_frame *sf; + struct pt_regs *regs; + unsigned long ip; + + while (1) { + sp = sp & PSW_ADDR_INSN; + /* fixme: verify this is a kernel stack */ + if (sp < low || sp > high - sizeof(*sf)) + return sp; + sf = (struct stack_frame *) sp; + ip = sf->gprs[8] & PSW_ADDR_INSN; + if (verbose) { + _stp_sprintf(str, "[%016lx] [%016lx] ", sp, ip); + _stp_symbol_sprint(str, ip); + _stp_string_cat(str, "\n"); + }else{ + _stp_sprintf(str,"%lx ", ip); + } + /* Follow the back_chain */ + while (1) { + low = sp; + sp = sf->back_chain & PSW_ADDR_INSN; + if (!sp) + break; + if (sp <= low || sp > high - sizeof(*sf)) + return sp; + sf = (struct stack_frame *) sp; + ip = sf->gprs[8] & PSW_ADDR_INSN; + if (verbose) { + _stp_sprintf(str, "[%016lx] [%016lx] ", sp, ip); + _stp_symbol_sprint(str, ip); + _stp_string_cat(str, "\n"); + }else{ + _stp_sprintf(str,"%lx ", ip); + } + } + /* Zero backchain detected, check for interrupt frame. */ + sp = (unsigned long) (sf + 1); + if (sp <= low || sp > high - sizeof(*regs)) + return sp; + regs = (struct pt_regs *) sp; + if (verbose) { + _stp_sprintf(str, "[%016lx] [%016lx] ", sp, ip); + _stp_symbol_sprint(str, ip); + _stp_string_cat(str, "\n"); + }else{ + _stp_sprintf(str,"%lx ", ip); + } + low = sp; + sp = regs->gprs[15]; + } +} + +static void __stp_stack_sprint (String str, struct pt_regs *regs, + int verbose, int levels) +{ + unsigned long *_sp = (unsigned long *)®_SP(regs); + unsigned long sp = (unsigned long)_sp; + // unsigned long sp = (unsigned long)*_sp; + + sp = __stp_show_stack(str, sp, + S390_lowcore.async_stack - ASYNC_SIZE, + S390_lowcore.async_stack,verbose); + + __stp_show_stack(str, sp, + S390_lowcore.thread_info, + S390_lowcore.thread_info + THREAD_SIZE,verbose); +} diff --git a/runtime/stack.c b/runtime/stack.c index a52dbfee..72a57e19 100644 --- a/runtime/stack.c +++ b/runtime/stack.c @@ -34,6 +34,8 @@ static int _stp_kta(unsigned long addr); #include "stack-i386.c" #elif defined (__powerpc64__) #include "stack-ppc64.c" +#elif defined (__s390__) || defined (__s390x__) +#include "stack-s390.c" #else #error "Unsupported architecture" #endif |