From 06da5d99f3200ae02678a269909e20883770d2cd Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Sun, 13 Apr 2003 21:27:39 -0700 Subject: [PATCH] [PATCH] s390/s390x unification (7/7) Merge s390x and s390 to one architecture. --- include/asm-s390/posix_types.h | 47 ++- include/asm-s390/processor.h | 162 ++++++-- include/asm-s390/ptrace.h | 234 ++++++++--- include/asm-s390/qdio.h | 4 +- include/asm-s390/rwsem.h | 81 ++++ include/asm-s390/sembuf.h | 6 +- include/asm-s390/setup.h | 24 +- include/asm-s390/shmbuf.h | 8 +- include/asm-s390/sigcontext.h | 21 +- include/asm-s390/signal.h | 6 + include/asm-s390/sigp.h | 28 +- include/asm-s390/smp.h | 4 + include/asm-s390/spinlock.h | 100 ++++- include/asm-s390/stat.h | 30 +- include/asm-s390/statfs.h | 13 + include/asm-s390/string.h | 53 ++- include/asm-s390/system.h | 102 ++++- include/asm-s390/thread_info.h | 28 +- include/asm-s390/tlbflush.h | 12 +- include/asm-s390/types.h | 28 +- include/asm-s390/uaccess.h | 712 ++++++++++++++++++--------------- include/asm-s390/unistd.h | 109 ++++- 22 files changed, 1320 insertions(+), 492 deletions(-) diff --git a/include/asm-s390/posix_types.h b/include/asm-s390/posix_types.h index ebfa4b7a24006..9359c22e38e28 100644 --- a/include/asm-s390/posix_types.h +++ b/include/asm-s390/posix_types.h @@ -15,18 +15,9 @@ * assume GCC is being used. */ -typedef unsigned short __kernel_dev_t; -typedef unsigned long __kernel_ino_t; -typedef unsigned short __kernel_mode_t; -typedef unsigned short __kernel_nlink_t; typedef long __kernel_off_t; typedef int __kernel_pid_t; -typedef unsigned short __kernel_ipc_pid_t; -typedef unsigned short __kernel_uid_t; -typedef unsigned short __kernel_gid_t; typedef unsigned long __kernel_size_t; -typedef int __kernel_ssize_t; -typedef int __kernel_ptrdiff_t; typedef long __kernel_time_t; typedef long __kernel_suseconds_t; typedef long __kernel_clock_t; @@ -36,15 +27,45 @@ typedef int __kernel_daddr_t; typedef char * __kernel_caddr_t; typedef unsigned short __kernel_uid16_t; typedef unsigned short __kernel_gid16_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +#ifndef __s390x__ + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; typedef unsigned int __kernel_uid32_t; typedef unsigned int __kernel_gid32_t; - typedef unsigned short __kernel_old_uid_t; typedef unsigned short __kernel_old_gid_t; -#ifdef __GNUC__ -typedef long long __kernel_loff_t; -#endif +#else /* __s390x__ */ + +typedef unsigned int __kernel_dev_t; +typedef unsigned int __kernel_ino_t; +typedef unsigned int __kernel_mode_t; +typedef unsigned int __kernel_nlink_t; +typedef int __kernel_ipc_pid_t; +typedef unsigned int __kernel_uid_t; +typedef unsigned int __kernel_gid_t; +typedef long __kernel_ssize_t; +typedef long __kernel_ptrdiff_t; +typedef unsigned long __kernel_sigset_t; /* at least 32 bits */ +typedef __kernel_uid_t __kernel_old_uid_t; +typedef __kernel_gid_t __kernel_old_gid_t; +typedef __kernel_uid_t __kernel_uid32_t; +typedef __kernel_gid_t __kernel_gid32_t; + +#endif /* __s390x__ */ typedef struct { #if defined(__KERNEL__) || defined(__USE_ALL) diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h index c03823e9a6fd2..d4264a43d0722 100644 --- a/include/asm-s390/processor.h +++ b/include/asm-s390/processor.h @@ -44,6 +44,9 @@ struct cpuinfo_S390 __u16 cpu_nr; unsigned long loops_per_jiffy; unsigned long *pgd_quick; +#ifdef __s390x__ + unsigned long *pmd_quick; +#endif /* __s390x__ */ unsigned long *pte_quick; unsigned long pgtable_cache_sz; }; @@ -54,58 +57,90 @@ extern void print_cpu_info(struct cpuinfo_S390 *); extern struct task_struct *last_task_used_math; /* - * User space process size: 2GB (default). + * User space process size: 2GB for 31 bit, 4TB for 64 bit. */ -#define TASK_SIZE (0x80000000) -/* This decides where the kernel will search for a free chunk of vm - * space during mmap's. - */ -#define TASK_UNMAPPED_BASE (TASK_SIZE / 2) +#ifndef __s390x__ + +# define TASK_SIZE (0x80000000UL) +# define TASK_UNMAPPED_BASE (TASK_SIZE / 2) + +#else /* __s390x__ */ + +# define TASK_SIZE (0x20000000000UL) +# define TASK31_SIZE (0x80000000UL) +# define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ + (TASK31_SIZE / 2) : (TASK_SIZE / 2)) + +#endif /* __s390x__ */ typedef struct { __u32 ar4; } mm_segment_t; -/* if you change the thread_struct structure, you must - * update the _TSS_* defines in entry.S +/* + * Thread structure */ - -struct thread_struct - { +struct thread_struct { s390_fp_regs fp_regs; - __u32 ar2; /* kernel access register 2 */ - __u32 ar4; /* kernel access register 4 */ - __u32 ksp; /* kernel stack pointer */ - __u32 user_seg; /* HSTD */ - __u32 error_code; /* error-code of last prog-excep. */ - __u32 prot_addr; /* address of protection-excep. */ - __u32 trap_no; - per_struct per_info;/* Must be aligned on an 4 byte boundary*/ + unsigned int ar2; /* kernel access register 2 */ + unsigned int ar4; /* kernel access register 4 */ + unsigned long ksp; /* kernel stack pointer */ + unsigned long user_seg; /* HSTD */ + unsigned long prot_addr; /* address of protection-excep. */ + unsigned int error_code; /* error-code of last prog-excep. */ + unsigned int trap_no; + per_struct per_info; /* Used to give failing instruction back to user for ieee exceptions */ - addr_t ieee_instruction_pointer; + unsigned long ieee_instruction_pointer; /* pfault_wait is used to block the process on a pfault event */ - addr_t pfault_wait; + unsigned long pfault_wait; }; typedef struct thread_struct thread_struct; -#define INIT_THREAD {{0,{{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}, \ - {0},{0},{0},{0},{0},{0}}}, \ - 0, 0, \ - sizeof(init_stack) + (__u32) &init_stack, \ - (__pa((__u32) &swapper_pg_dir[0]) + _SEGMENT_TABLE),\ - 0,0,0, \ - (per_struct) {{{{0,}}},0,0,0,0,{{0,}}}, \ - 0, 0 \ -} +#ifndef __s390x__ +# define __SWAPPER_PG_DIR __pa(&swapper_pg_dir[0]) + _SEGMENT_TABLE +#else /* __s390x__ */ +# define __SWAPPER_PG_DIR __pa(&swapper_pg_dir[0]) + _REGION_TABLE +#endif /* __s390x__ */ + +#define INIT_THREAD {{0,{{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}, \ + {0},{0},{0},{0},{0},{0}}}, \ + 0, 0, \ + sizeof(init_stack) + (unsigned long) &init_stack, \ + __SWAPPER_PG_DIR, \ + 0,0,0, \ + (per_struct) {{{{0,}}},0,0,0,0,{{0,}}}, \ + 0, 0 \ +} + +/* + * Do necessary setup to start up a new thread. + */ +#ifndef __s390x__ -/* need to define ... */ #define start_thread(regs, new_psw, new_stackp) do { \ regs->psw.mask = PSW_USER_BITS; \ - regs->psw.addr = new_psw | PSW_ADDR_AMODE31; \ + regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ regs->gprs[15] = new_stackp ; \ } while (0) +#else /* __s390x__ */ + +#define start_thread(regs, new_psw, new_stackp) do { \ + regs->psw.mask = PSW_USER_BITS; \ + regs->psw.addr = new_psw; \ + regs->gprs[15] = new_stackp; \ +} while (0) + +#define start_thread31(regs, new_psw, new_stackp) do { \ + regs->psw.mask = PSW_USER32_BITS; \ + regs->psw.addr = new_psw; \ + regs->gprs[15] = new_stackp; \ +} while (0) + +#endif /* __s390x__ */ + /* Forward declaration, a strange C thing */ struct task_struct; struct mm_struct; @@ -129,14 +164,19 @@ extern char *task_show_regs(struct task_struct *task, char *buffer); unsigned long get_wchan(struct task_struct *p); #define __KSTK_PTREGS(tsk) ((struct pt_regs *) \ - (((addr_t) tsk->thread_info + THREAD_SIZE - sizeof(struct pt_regs)) & -8L)) + (((unsigned long) tsk->thread_info + THREAD_SIZE - sizeof(struct pt_regs)) & -8L)) #define KSTK_EIP(tsk) (__KSTK_PTREGS(tsk)->psw.addr) #define KSTK_ESP(tsk) (__KSTK_PTREGS(tsk)->gprs[15]) /* * Give up the time slice of the virtual PU. */ -#define cpu_relax() asm volatile ("diag 0,0,68" : : : "memory") +#ifndef __s390x__ +# define cpu_relax() asm volatile ("diag 0,0,68" : : : "memory") +#else /* __s390x__ */ +# define cpu_relax() \ + asm volatile ("ex 0,%0" : : "i" (__LC_DIAG44_OPCODE) : "memory") +#endif /* __s390x__ */ /* * Set PSW mask to specified value, while leaving the @@ -150,13 +190,22 @@ static inline void __load_psw_mask (unsigned long mask) psw_t psw; psw.mask = mask; +#ifndef __s390x__ asm volatile ( " basr %0,0\n" "0: ahi %0,1f-0b\n" - " st %0,4(%1)\n" + " st %0,4(%1)\n" " lpsw 0(%1)\n" "1:" : "=&d" (addr) : "a" (&psw) : "memory", "cc" ); +#else /* __s390x__ */ + asm volatile ( + " larl %0,1f\n" + " stg %0,8(%1)\n" + " lpswe 0(%1)\n" + "1:" + : "=&d" (addr) : "a" (&psw) : "memory", "cc" ); +#endif /* __s390x__ */ } /* @@ -169,6 +218,7 @@ static inline void enabled_wait(void) wait_psw.mask = PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | PSW_MASK_WAIT; +#ifndef __s390x__ asm volatile ( " basr %0,0\n" "0: la %0,1f-0b(%0)\n" @@ -177,6 +227,14 @@ static inline void enabled_wait(void) " lpsw 0(%1)\n" "1:" : "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" ); +#else /* __s390x__ */ + asm volatile ( + " larl %0,0f\n" + " stg %0,8(%1)\n" + " lpswe 0(%1)\n" + "0:" + : "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" ); +#endif /* __s390x__ */ } /* @@ -196,7 +254,7 @@ static inline void disabled_wait(unsigned long code) * Store status and then load disabled wait psw, * the processor is dead afterwards */ - +#ifndef __s390x__ asm volatile (" stctl 0,0,0(%1)\n" " ni 0(%1),0xef\n" /* switch off protection */ " lctl 0,0,0(%1)\n" @@ -213,6 +271,38 @@ static inline void disabled_wait(unsigned long code) " oi 0(%1),0x10\n" /* fake protection bit */ " lpsw 0(%0)" : : "a" (dw_psw), "a" (&ctl_buf) : "cc" ); +#else /* __s390x__ */ + asm volatile (" stctg 0,0,0(%1)\n" + " ni 4(%1),0xef\n" /* switch off protection */ + " lctlg 0,0,0(%1)\n" + " lghi 1,0x1000\n" + " stpt 0x328(1)\n" /* store timer */ + " stckc 0x330(1)\n" /* store clock comparator */ + " stpx 0x318(1)\n" /* store prefix register */ + " stam 0,15,0x340(1)\n" /* store access registers */ + " stfpc 0x31c(1)\n" /* store fpu control */ + " std 0,0x200(1)\n" /* store f0 */ + " std 1,0x208(1)\n" /* store f1 */ + " std 2,0x210(1)\n" /* store f2 */ + " std 3,0x218(1)\n" /* store f3 */ + " std 4,0x220(1)\n" /* store f4 */ + " std 5,0x228(1)\n" /* store f5 */ + " std 6,0x230(1)\n" /* store f6 */ + " std 7,0x238(1)\n" /* store f7 */ + " std 8,0x240(1)\n" /* store f8 */ + " std 9,0x248(1)\n" /* store f9 */ + " std 10,0x250(1)\n" /* store f10 */ + " std 11,0x258(1)\n" /* store f11 */ + " std 12,0x260(1)\n" /* store f12 */ + " std 13,0x268(1)\n" /* store f13 */ + " std 14,0x270(1)\n" /* store f14 */ + " std 15,0x278(1)\n" /* store f15 */ + " stmg 0,15,0x280(1)\n" /* store general registers */ + " stctg 0,15,0x380(1)\n" /* store control registers */ + " oi 0x384(1),0x10\n" /* fake protection bit */ + " lpswe 0(%0)" + : : "a" (dw_psw), "a" (&ctl_buf) : "cc", "0", "1"); +#endif /* __s390x__ */ } #endif diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h index 48f6cc28044ec..36d77a6fe7e0c 100644 --- a/include/asm-s390/ptrace.h +++ b/include/asm-s390/ptrace.h @@ -13,6 +13,8 @@ * Offsets in the user_regs_struct. They are used for the ptrace * system call and in entry.S */ +#ifndef __s390x__ + #define PT_PSWMASK 0x00 #define PT_PSWADDR 0x04 #define PT_GPR0 0x08 @@ -92,18 +94,89 @@ #define PT_LASTOFF PT_IEEE_IP #define PT_ENDREGS 0x140-1 +#define GPR_SIZE 4 +#define CR_SIZE 4 + +#define STACK_FRAME_OVERHEAD 96 /* size of minimum stack frame */ + +#else /* __s390x__ */ + +#define PT_PSWMASK 0x00 +#define PT_PSWADDR 0x08 +#define PT_GPR0 0x10 +#define PT_GPR1 0x18 +#define PT_GPR2 0x20 +#define PT_GPR3 0x28 +#define PT_GPR4 0x30 +#define PT_GPR5 0x38 +#define PT_GPR6 0x40 +#define PT_GPR7 0x48 +#define PT_GPR8 0x50 +#define PT_GPR9 0x58 +#define PT_GPR10 0x60 +#define PT_GPR11 0x68 +#define PT_GPR12 0x70 +#define PT_GPR13 0x78 +#define PT_GPR14 0x80 +#define PT_GPR15 0x88 +#define PT_ACR0 0x90 +#define PT_ACR1 0x94 +#define PT_ACR2 0x98 +#define PT_ACR3 0x9C +#define PT_ACR4 0xA0 +#define PT_ACR5 0xA4 +#define PT_ACR6 0xA8 +#define PT_ACR7 0xAC +#define PT_ACR8 0xB0 +#define PT_ACR9 0xB4 +#define PT_ACR10 0xB8 +#define PT_ACR11 0xBC +#define PT_ACR12 0xC0 +#define PT_ACR13 0xC4 +#define PT_ACR14 0xC8 +#define PT_ACR15 0xCC +#define PT_ORIGGPR2 0xD0 +#define PT_FPC 0xD8 +#define PT_FPR0 0xE0 +#define PT_FPR1 0xE8 +#define PT_FPR2 0xF0 +#define PT_FPR3 0xF8 +#define PT_FPR4 0x100 +#define PT_FPR5 0x108 +#define PT_FPR6 0x110 +#define PT_FPR7 0x118 +#define PT_FPR8 0x120 +#define PT_FPR9 0x128 +#define PT_FPR10 0x130 +#define PT_FPR11 0x138 +#define PT_FPR12 0x140 +#define PT_FPR13 0x148 +#define PT_FPR14 0x150 +#define PT_FPR15 0x158 +#define PT_CR_9 0x160 +#define PT_CR_10 0x168 +#define PT_CR_11 0x170 +#define PT_IEEE_IP 0x1A8 +#define PT_LASTOFF PT_IEEE_IP +#define PT_ENDREGS 0x1B0-1 + +#define GPR_SIZE 8 +#define CR_SIZE 8 + +#define STACK_FRAME_OVERHEAD 160 /* size of minimum stack frame */ + +#endif /* __s390x__ */ + #define NUM_GPRS 16 #define NUM_FPRS 16 #define NUM_CRS 16 #define NUM_ACRS 16 -#define GPR_SIZE 4 + #define FPR_SIZE 8 #define FPC_SIZE 4 #define FPC_PAD_SIZE 4 /* gcc insists on aligning the fpregs */ -#define CR_SIZE 4 #define ACR_SIZE 4 -#define STACK_FRAME_OVERHEAD 96 /* size of minimum stack frame */ #define PTRACE_OLDSETOPTIONS 21 @@ -113,13 +186,39 @@ #include #include +typedef union +{ + float f; + double d; + __u64 ui; + struct + { + __u32 hi; + __u32 lo; + } fp; +} freg_t; + +typedef struct +{ + __u32 fpc; + freg_t fprs[NUM_FPRS]; +} s390_fp_regs; + +#define FPC_EXCEPTION_MASK 0xF8000000 +#define FPC_FLAGS_MASK 0x00F80000 +#define FPC_DXC_MASK 0x0000FF00 +#define FPC_RM_MASK 0x00000003 +#define FPC_VALID_MASK 0xF8F8FF03 + /* this typedef defines how a Program Status Word looks like */ typedef struct { - __u32 mask; - __u32 addr; + unsigned long mask; + unsigned long addr; } __attribute__ ((aligned(8))) psw_t; +#ifndef __s390x__ + #define PSW_MASK_PER 0x40000000UL #define PSW_MASK_DAT 0x04000000UL #define PSW_MASK_IO 0x02000000UL @@ -132,7 +231,7 @@ typedef struct #define PSW_MASK_CC 0x00003000UL #define PSW_MASK_PM 0x00000F00UL -#define PSW_ADDR_AMODE31 0x80000000UL +#define PSW_ADDR_AMODE 0x80000000UL #define PSW_ADDR_INSN 0x7FFFFFFFUL #define PSW_BASE_BITS 0x00080000UL @@ -142,34 +241,41 @@ typedef struct #define PSW_ASC_SECONDARY 0x00008000UL #define PSW_ASC_HOME 0x0000C000UL -#define PSW_KERNEL_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY) -#define PSW_USER_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \ +#else /* __s390x__ */ + +#define PSW_MASK_PER 0x4000000000000000UL +#define PSW_MASK_DAT 0x0400000000000000UL +#define PSW_MASK_IO 0x0200000000000000UL +#define PSW_MASK_EXT 0x0100000000000000UL +#define PSW_MASK_KEY 0x00F0000000000000UL +#define PSW_MASK_MCHECK 0x0004000000000000UL +#define PSW_MASK_WAIT 0x0002000000000000UL +#define PSW_MASK_PSTATE 0x0001000000000000UL +#define PSW_MASK_ASC 0x0000C00000000000UL +#define PSW_MASK_CC 0x0000300000000000UL +#define PSW_MASK_PM 0x00000F0000000000UL + +#define PSW_ADDR_AMODE 0x0000000000000000UL +#define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL + +#define PSW_BASE_BITS 0x0000000180000000UL +#define PSW_BASE32_BITS 0x0000000080000000UL + +#define PSW_ASC_PRIMARY 0x0000000000000000UL +#define PSW_ASC_ACCREG 0x0000400000000000UL +#define PSW_ASC_SECONDARY 0x0000800000000000UL +#define PSW_ASC_HOME 0x0000C00000000000UL + +#define PSW_USER32_BITS (PSW_BASE32_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \ PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \ PSW_MASK_PSTATE) -typedef union -{ - float f; - double d; - __u64 ui; - struct - { - __u32 hi; - __u32 lo; - } fp; -} freg_t; - -typedef struct -{ - __u32 fpc; - freg_t fprs[NUM_FPRS]; -} s390_fp_regs; +#endif /* __s390x__ */ -#define FPC_EXCEPTION_MASK 0xF8000000 -#define FPC_FLAGS_MASK 0x00F80000 -#define FPC_DXC_MASK 0x0000FF00 -#define FPC_RM_MASK 0x00000003 -#define FPC_VALID_MASK 0xF8F8FF03 +#define PSW_KERNEL_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY) +#define PSW_USER_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \ + PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \ + PSW_MASK_PSTATE) /* * The first entries in pt_regs and user_regs_struct @@ -180,9 +286,9 @@ typedef struct typedef struct { psw_t psw; - __u32 gprs[NUM_GPRS]; - __u32 acrs[NUM_ACRS]; - __u32 orig_gpr2; + unsigned long gprs[NUM_GPRS]; + unsigned int acrs[NUM_ACRS]; + unsigned long orig_gpr2; } s390_regs; /* @@ -192,24 +298,27 @@ typedef struct struct pt_regs { psw_t psw; - __u32 gprs[NUM_GPRS]; - __u32 acrs[NUM_ACRS]; - __u32 orig_gpr2; - __u32 trap; -}; + unsigned long gprs[NUM_GPRS]; + unsigned int acrs[NUM_ACRS]; + unsigned long orig_gpr2; + unsigned int trap; +} __attribute__ ((packed)); /* * Now for the program event recording (trace) definitions. */ typedef struct { - __u32 cr[3]; + unsigned long cr[3]; } per_cr_words; -#define PER_EM_MASK 0xE8000000 +#define PER_EM_MASK 0xE8000000UL typedef struct { +#ifdef __s390x__ + unsigned : 32; +#endif /* __s390x__ */ unsigned em_branching : 1; unsigned em_instruction_fetch : 1; /* @@ -224,33 +333,34 @@ typedef struct unsigned : 1; unsigned storage_alt_space_ctl : 1; unsigned : 21; - addr_t starting_addr; - addr_t ending_addr; + unsigned long starting_addr; + unsigned long ending_addr; } per_cr_bits; typedef struct { - __u16 perc_atmid; /* 0x096 */ - __u32 address; /* 0x098 */ - __u8 access_id; /* 0x0a1 */ + unsigned short perc_atmid; + unsigned long address; + unsigned char access_id; } per_lowcore_words; typedef struct { - unsigned perc_branching : 1; /* 0x096 */ + unsigned perc_branching : 1; unsigned perc_instruction_fetch : 1; unsigned perc_storage_alteration : 1; unsigned perc_gpr_alt_unused : 1; unsigned perc_store_real_address : 1; - unsigned : 4; + unsigned : 3; + unsigned atmid_psw_bit_31 : 1; unsigned atmid_validity_bit : 1; unsigned atmid_psw_bit_32 : 1; unsigned atmid_psw_bit_5 : 1; unsigned atmid_psw_bit_16 : 1; unsigned atmid_psw_bit_17 : 1; unsigned si : 2; - addr_t address; /* 0x098 */ - unsigned : 4; /* 0x0a1 */ + unsigned long address; + unsigned : 4; unsigned access_id : 4; } per_lowcore_bits; @@ -272,8 +382,8 @@ typedef struct * These addresses are copied into cr10 & cr11 if single * stepping is switched off */ - __u32 starting_addr; - __u32 ending_addr; + unsigned long starting_addr; + unsigned long ending_addr; union { per_lowcore_words words; per_lowcore_bits bits; @@ -282,9 +392,9 @@ typedef struct typedef struct { - __u32 len; - addr_t kernel_addr; - addr_t process_addr; + unsigned int len; + unsigned long kernel_addr; + unsigned long process_addr; } ptrace_area; /* @@ -313,9 +423,9 @@ typedef enum typedef struct { - addr_t lowaddr; - addr_t hiaddr; - ptprot_flags prot; + unsigned long lowaddr; + unsigned long hiaddr; + ptprot_flags prot; } ptprot_area; /* Sequence of bytes for breakpoint illegal instruction. */ @@ -331,9 +441,9 @@ typedef struct struct user_regs_struct { psw_t psw; - __u32 gprs[NUM_GPRS]; - __u32 acrs[NUM_ACRS]; - __u32 orig_gpr2; + unsigned long gprs[NUM_GPRS]; + unsigned int acrs[NUM_ACRS]; + unsigned long orig_gpr2; s390_fp_regs fp_regs; /* * These per registers are in here so that gdb can modify them @@ -341,13 +451,13 @@ struct user_regs_struct * watchpoints. This is the way intel does it. */ per_struct per_info; - addr_t ieee_instruction_pointer; + unsigned long ieee_instruction_pointer; /* Used to give failing instruction back to user for ieee exceptions */ }; #ifdef __KERNEL__ #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) -#define instruction_pointer(regs) ((regs)->psw.addr & PSW_MASK_INSN) +#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) extern void show_regs(struct pt_regs * regs); #endif diff --git a/include/asm-s390/qdio.h b/include/asm-s390/qdio.h index d327f67573508..dc7e569ed3144 100644 --- a/include/asm-s390/qdio.h +++ b/include/asm-s390/qdio.h @@ -20,9 +20,9 @@ #define QDIO_NAME "qdio " -#ifndef CONFIG_ARCH_S390X +#ifndef __s390x__ #define QDIO_32_BIT -#endif /* CONFIG_ARCH_S390X */ +#endif /* __s390x__ */ /**** CONSTANTS, that are relied on without using these symbols *****/ #define QDIO_MAX_QUEUES_PER_IRQ 32 /* used in width of unsigned int */ diff --git a/include/asm-s390/rwsem.h b/include/asm-s390/rwsem.h index dec5c522ff7ef..ef612dd92ca56 100644 --- a/include/asm-s390/rwsem.h +++ b/include/asm-s390/rwsem.h @@ -63,10 +63,17 @@ struct rw_semaphore { struct list_head wait_list; }; +#ifndef __s390x__ #define RWSEM_UNLOCKED_VALUE 0x00000000 #define RWSEM_ACTIVE_BIAS 0x00000001 #define RWSEM_ACTIVE_MASK 0x0000ffff #define RWSEM_WAITING_BIAS (-0x00010000) +#else /* __s390x__ */ +#define RWSEM_UNLOCKED_VALUE 0x0000000000000000L +#define RWSEM_ACTIVE_BIAS 0x0000000000000001L +#define RWSEM_ACTIVE_MASK 0x00000000ffffffffL +#define RWSEM_WAITING_BIAS (-0x0000000100000000L) +#endif /* __s390x__ */ #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) @@ -94,11 +101,19 @@ static inline void __down_read(struct rw_semaphore *sem) signed long old, new; __asm__ __volatile__( +#ifndef __s390x__ " l %0,0(%2)\n" "0: lr %1,%0\n" " ahi %1,%3\n" " cs %0,%1,0(%2)\n" " jl 0b" +#else /* __s390x__ */ + " lg %0,0(%2)\n" + "0: lgr %1,%0\n" + " aghi %1,%3\n" + " csg %0,%1,0(%2)\n" + " jl 0b" +#endif /* __s390x__ */ : "=&d" (old), "=&d" (new) : "a" (&sem->count), "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory" ); @@ -114,6 +129,7 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) signed long old, new; __asm__ __volatile__( +#ifndef __s390x__ " l %0,0(%2)\n" "0: ltr %1,%0\n" " jm 1f\n" @@ -121,6 +137,15 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) " cs %0,%1,0(%2)\n" " jl 0b\n" "1:" +#else /* __s390x__ */ + " lg %0,0(%2)\n" + "0: ltgr %1,%0\n" + " jm 1f\n" + " aghi %1,%3\n" + " csg %0,%1,0(%2)\n" + " jl 0b\n" + "1:" +#endif /* __s390x__ */ : "=&d" (old), "=&d" (new) : "a" (&sem->count), "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory" ); @@ -136,11 +161,19 @@ static inline void __down_write(struct rw_semaphore *sem) tmp = RWSEM_ACTIVE_WRITE_BIAS; __asm__ __volatile__( +#ifndef __s390x__ " l %0,0(%2)\n" "0: lr %1,%0\n" " a %1,%3\n" " cs %0,%1,0(%2)\n" " jl 0b" +#else /* __s390x__ */ + " lg %0,0(%2)\n" + "0: lgr %1,%0\n" + " ag %1,%3\n" + " csg %0,%1,0(%2)\n" + " jl 0b" +#endif /* __s390x__ */ : "=&d" (old), "=&d" (new) : "a" (&sem->count), "m" (tmp) : "cc", "memory" ); @@ -156,11 +189,19 @@ static inline int __down_write_trylock(struct rw_semaphore *sem) signed long old; __asm__ __volatile__( +#ifndef __s390x__ " l %0,0(%1)\n" "0: ltr %0,%0\n" " jnz 1f\n" " cs %0,%2,0(%1)\n" " jl 0b\n" +#else /* __s390x__ */ + " lg %0,0(%1)\n" + "0: ltgr %0,%0\n" + " jnz 1f\n" + " csg %0,%2,0(%1)\n" + " jl 0b\n" +#endif /* __s390x__ */ "1:" : "=&d" (old) : "a" (&sem->count), "d" (RWSEM_ACTIVE_WRITE_BIAS) @@ -176,11 +217,19 @@ static inline void __up_read(struct rw_semaphore *sem) signed long old, new; __asm__ __volatile__( +#ifndef __s390x__ " l %0,0(%2)\n" "0: lr %1,%0\n" " ahi %1,%3\n" " cs %0,%1,0(%2)\n" " jl 0b" +#else /* __s390x__ */ + " lg %0,0(%2)\n" + "0: lgr %1,%0\n" + " aghi %1,%3\n" + " csg %0,%1,0(%2)\n" + " jl 0b" +#endif /* __s390x__ */ : "=&d" (old), "=&d" (new) : "a" (&sem->count), "i" (-RWSEM_ACTIVE_READ_BIAS) : "cc", "memory" ); @@ -198,11 +247,19 @@ static inline void __up_write(struct rw_semaphore *sem) tmp = -RWSEM_ACTIVE_WRITE_BIAS; __asm__ __volatile__( +#ifndef __s390x__ " l %0,0(%2)\n" "0: lr %1,%0\n" " a %1,%3\n" " cs %0,%1,0(%2)\n" " jl 0b" +#else /* __s390x__ */ + " lg %0,0(%2)\n" + "0: lgr %1,%0\n" + " ag %1,%3\n" + " csg %0,%1,0(%2)\n" + " jl 0b" +#endif /* __s390x__ */ : "=&d" (old), "=&d" (new) : "a" (&sem->count), "m" (tmp) : "cc", "memory" ); @@ -220,11 +277,19 @@ static inline void __downgrade_write(struct rw_semaphore *sem) tmp = -RWSEM_WAITING_BIAS; __asm__ __volatile__( +#ifndef __s390x__ " l %0,0(%2)\n" "0: lr %1,%0\n" " a %1,%3\n" " cs %0,%1,0(%2)\n" " jl 0b" +#else /* __s390x__ */ + " lg %0,0(%2)\n" + "0: lgr %1,%0\n" + " ag %1,%3\n" + " csg %0,%1,0(%2)\n" + " jl 0b" +#endif /* __s390x__ */ : "=&d" (old), "=&d" (new) : "a" (&sem->count), "m" (tmp) : "cc", "memory" ); @@ -240,11 +305,19 @@ static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) signed long old, new; __asm__ __volatile__( +#ifndef __s390x__ " l %0,0(%2)\n" "0: lr %1,%0\n" " ar %1,%3\n" " cs %0,%1,0(%2)\n" " jl 0b" +#else /* __s390x__ */ + " lg %0,0(%2)\n" + "0: lgr %1,%0\n" + " agr %1,%3\n" + " csg %0,%1,0(%2)\n" + " jl 0b" +#endif /* __s390x__ */ : "=&d" (old), "=&d" (new) : "a" (&sem->count), "d" (delta) : "cc", "memory" ); @@ -258,11 +331,19 @@ static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) signed long old, new; __asm__ __volatile__( +#ifndef __s390x__ " l %0,0(%2)\n" "0: lr %1,%0\n" " ar %1,%3\n" " cs %0,%1,0(%2)\n" " jl 0b" +#else /* __s390x__ */ + " lg %0,0(%2)\n" + "0: lgr %1,%0\n" + " agr %1,%3\n" + " csg %0,%1,0(%2)\n" + " jl 0b" +#endif /* __s390x__ */ : "=&d" (old), "=&d" (new) : "a" (&sem->count), "d" (delta) : "cc", "memory" ); diff --git a/include/asm-s390/sembuf.h b/include/asm-s390/sembuf.h index 15c9e25ff46ce..32626b0cac4bb 100644 --- a/include/asm-s390/sembuf.h +++ b/include/asm-s390/sembuf.h @@ -7,16 +7,20 @@ * between kernel and user space. * * Pad space is left for: - * - 64-bit time_t to solve y2038 problem + * - 64-bit time_t to solve y2038 problem (for !__s390x__) * - 2 miscellaneous 32-bit values */ struct semid64_ds { struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ __kernel_time_t sem_otime; /* last semop time */ +#ifndef __s390x__ unsigned long __unused1; +#endif /* ! __s390x__ */ __kernel_time_t sem_ctime; /* last change time */ +#ifndef __s390x__ unsigned long __unused2; +#endif /* ! __s390x__ */ unsigned long sem_nsems; /* no. of semaphores in array */ unsigned long __unused3; unsigned long __unused4; diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h index 2cfb6d137d7e2..205e81469ac14 100644 --- a/include/asm-s390/setup.h +++ b/include/asm-s390/setup.h @@ -15,9 +15,15 @@ #ifndef __ASSEMBLY__ +#ifndef __s390x__ #define IPL_DEVICE (*(unsigned long *) (0x10404)) #define INITRD_START (*(unsigned long *) (0x1040C)) #define INITRD_SIZE (*(unsigned long *) (0x10414)) +#else /* __s390x__ */ +#define IPL_DEVICE (*(unsigned long *) (0x10400)) +#define INITRD_START (*(unsigned long *) (0x10408)) +#define INITRD_SIZE (*(unsigned long *) (0x10410)) +#endif /* __s390x__ */ #define COMMAND_LINE ((char *) (0x10480)) /* @@ -26,10 +32,18 @@ extern unsigned long machine_flags; #define MACHINE_IS_VM (machine_flags & 1) -#define MACHINE_HAS_IEEE (machine_flags & 2) #define MACHINE_IS_P390 (machine_flags & 4) -#define MACHINE_HAS_CSP (machine_flags & 8) #define MACHINE_HAS_MVPG (machine_flags & 16) +#define MACHINE_HAS_DIAG44 (machine_flags & 32) + +#ifndef __s390x__ +#define MACHINE_HAS_IEEE (machine_flags & 2) +#define MACHINE_HAS_CSP (machine_flags & 8) +#else /* __s390x__ */ +#define MACHINE_HAS_IEEE (1) +#define MACHINE_HAS_CSP (1) +#endif /* __s390x__ */ + #define MACHINE_HAS_SCLP (!MACHINE_IS_P390) @@ -50,9 +64,15 @@ extern unsigned int console_irq; #else +#ifndef __s390x__ #define IPL_DEVICE 0x10404 #define INITRD_START 0x1040C #define INITRD_SIZE 0x10414 +#else /* __s390x__ */ +#define IPL_DEVICE 0x10400 +#define INITRD_START 0x10408 +#define INITRD_SIZE 0x10410 +#endif /* __s390x__ */ #define COMMAND_LINE 0x10480 #endif diff --git a/include/asm-s390/shmbuf.h b/include/asm-s390/shmbuf.h index aae94fd5bc6c0..eed2e280ce37a 100644 --- a/include/asm-s390/shmbuf.h +++ b/include/asm-s390/shmbuf.h @@ -7,7 +7,7 @@ * between kernel and user space. * * Pad space is left for: - * - 64-bit time_t to solve y2038 problem + * - 64-bit time_t to solve y2038 problem (for !__s390x__) * - 2 miscellaneous 32-bit values */ @@ -15,11 +15,17 @@ struct shmid64_ds { struct ipc64_perm shm_perm; /* operation perms */ size_t shm_segsz; /* size of segment (bytes) */ __kernel_time_t shm_atime; /* last attach time */ +#ifndef __s390x__ unsigned long __unused1; +#endif /* ! __s390x__ */ __kernel_time_t shm_dtime; /* last detach time */ +#ifndef __s390x__ unsigned long __unused2; +#endif /* ! __s390x__ */ __kernel_time_t shm_ctime; /* last change time */ +#ifndef __s390x__ unsigned long __unused3; +#endif /* ! __s390x__ */ __kernel_pid_t shm_cpid; /* pid of creator */ __kernel_pid_t shm_lpid; /* pid of last operator */ unsigned long shm_nattch; /* no. of current attaches */ diff --git a/include/asm-s390/sigcontext.h b/include/asm-s390/sigcontext.h index eb7cc38df7bbc..d57bc0cebdcec 100644 --- a/include/asm-s390/sigcontext.h +++ b/include/asm-s390/sigcontext.h @@ -12,13 +12,24 @@ #define __NUM_FPRS 16 #define __NUM_ACRS 16 -/* - Has to be at least _NSIG_WORDS from asm/signal.h - */ -#define _SIGCONTEXT_NSIG 64 -#define _SIGCONTEXT_NSIG_BPW 32 +#ifndef __s390x__ + +/* Has to be at least _NSIG_WORDS from asm/signal.h */ +#define _SIGCONTEXT_NSIG 64 +#define _SIGCONTEXT_NSIG_BPW 32 /* Size of stack frame allocated when calling signal handler. */ #define __SIGNAL_FRAMESIZE 96 + +#else /* __s390x__ */ + +/* Has to be at least _NSIG_WORDS from asm/signal.h */ +#define _SIGCONTEXT_NSIG 64 +#define _SIGCONTEXT_NSIG_BPW 64 +/* Size of stack frame allocated when calling signal handler. */ +#define __SIGNAL_FRAMESIZE 160 + +#endif /* __s390x__ */ + #define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW) #define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS) diff --git a/include/asm-s390/signal.h b/include/asm-s390/signal.h index 0186302515dcc..fe2263b3ee0d1 100644 --- a/include/asm-s390/signal.h +++ b/include/asm-s390/signal.h @@ -171,9 +171,15 @@ struct sigaction { __sighandler_t _sa_handler; void (*_sa_sigaction)(int, struct siginfo *, void *); } _u; +#ifndef __s390x__ /* lovely */ sigset_t sa_mask; unsigned long sa_flags; void (*sa_restorer)(void); +#else /* __s390x__ */ + unsigned long sa_flags; + void (*sa_restorer)(void); + sigset_t sa_mask; +#endif /* __s390x__ */ }; #define sa_handler _u._sa_handler diff --git a/include/asm-s390/sigp.h b/include/asm-s390/sigp.h index 77c783b3510da..fa78e05a19c5d 100644 --- a/include/asm-s390/sigp.h +++ b/include/asm-s390/sigp.h @@ -72,10 +72,17 @@ signal_processor(__u16 cpu_addr, sigp_order_code order_code) sigp_ccode ccode; __asm__ __volatile__( +#ifndef __s390x__ " sr 1,1\n" /* parameter=0 in gpr 1 */ " sigp 1,%1,0(%2)\n" " ipm %0\n" " srl %0,28\n" +#else /* __s390x__ */ + " sgr 1,1\n" /* parameter=0 in gpr 1 */ + " sigp 1,%1,0(%2)\n" + " ipm %0\n" + " srl %0,28" +#endif /* __s390x__ */ : "=d" (ccode) : "d" (__cpu_logical_map[cpu_addr]), "a" (order_code) : "cc" , "memory", "1" ); @@ -86,15 +93,23 @@ signal_processor(__u16 cpu_addr, sigp_order_code order_code) * Signal processor with parameter */ extern __inline__ sigp_ccode -signal_processor_p(__u32 parameter,__u16 cpu_addr,sigp_order_code order_code) +signal_processor_p(unsigned long parameter,__u16 cpu_addr, + sigp_order_code order_code) { sigp_ccode ccode; __asm__ __volatile__( +#ifndef __s390x__ " lr 1,%1\n" /* parameter in gpr 1 */ " sigp 1,%2,0(%3)\n" " ipm %0\n" " srl %0,28\n" +#else /* __s390x__ */ + " lgr 1,%1\n" /* parameter in gpr 1 */ + " sigp 1,%2,0(%3)\n" + " ipm %0\n" + " srl %0,28\n" +#endif /* __s390x__ */ : "=d" (ccode) : "d" (parameter), "d" (__cpu_logical_map[cpu_addr]), "a" (order_code) @@ -106,18 +121,27 @@ signal_processor_p(__u32 parameter,__u16 cpu_addr,sigp_order_code order_code) * Signal processor with parameter and return status */ extern __inline__ sigp_ccode -signal_processor_ps(__u32 *statusptr, __u32 parameter, +signal_processor_ps(__u32 *statusptr, unsigned long parameter, __u16 cpu_addr, sigp_order_code order_code) { sigp_ccode ccode; __asm__ __volatile__( +#ifndef __s390x__ " sr 2,2\n" /* clear status so it doesn't contain rubbish if not saved. */ " lr 3,%2\n" /* parameter in gpr 3 */ " sigp 2,%3,0(%4)\n" " st 2,%1\n" " ipm %0\n" " srl %0,28\n" +#else /* __s390x__ */ + " sgr 2,2\n" /* clear status so it doesn't contain rubbish if not saved. */ + " lgr 3,%2\n" /* parameter in gpr 3 */ + " sigp 2,%3,0(%4)\n" + " stg 2,%1\n" + " ipm %0\n" + " srl %0,28\n" +#endif /* __s390x__ */ : "=d" (ccode), "=m" (*statusptr) : "d" (parameter), "d" (__cpu_logical_map[cpu_addr]), "a" (order_code) diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h index 3c3b11d91c818..532ad996326e6 100644 --- a/include/asm-s390/smp.h +++ b/include/asm-s390/smp.h @@ -52,7 +52,11 @@ extern volatile unsigned long cpu_possible_map; extern inline unsigned int num_online_cpus(void) { +#ifndef __s390x__ return hweight32(cpu_online_map); +#else /* __s390x__ */ + return hweight64(cpu_online_map); +#endif /* __s390x__ */ } extern inline int any_online_cpu(unsigned int mask) diff --git a/include/asm-s390/spinlock.h b/include/asm-s390/spinlock.h index 0b1a24611457e..586a13bb4f0a3 100644 --- a/include/asm-s390/spinlock.h +++ b/include/asm-s390/spinlock.h @@ -11,6 +11,22 @@ #ifndef __ASM_SPINLOCK_H #define __ASM_SPINLOCK_H +#ifdef __s390x__ +/* + * Grmph, take care of %&#! user space programs that include + * asm/spinlock.h. The diagnose is only available in kernel + * context. + */ +#ifdef __KERNEL__ +#include +#define __DIAG44_INSN "ex" +#define __DIAG44_OPERAND __LC_DIAG44_OPCODE +#else +#define __DIAG44_INSN "#" +#define __DIAG44_OPERAND 0 +#endif +#endif /* __s390x__ */ + /* * Simple spin lock operations. There are two variants, one clears IRQ's * on the local processor, one does not. @@ -19,8 +35,13 @@ */ typedef struct { +#ifndef __s390x__ volatile unsigned long lock; } spinlock_t; +#else /* __s390x__ */ + volatile unsigned int lock; +} __attribute__ ((aligned (4))) spinlock_t; +#endif /* __s390x__ */ #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } #define spin_lock_init(lp) do { (lp)->lock = 0; } while(0) @@ -29,6 +50,7 @@ typedef struct { extern inline void _raw_spin_lock(spinlock_t *lp) { +#ifndef __s390x__ unsigned int reg1, reg2; __asm__ __volatile(" bras %0,1f\n" "0: diag 0,0,68\n" @@ -37,11 +59,26 @@ extern inline void _raw_spin_lock(spinlock_t *lp) " jl 0b\n" : "=&d" (reg1), "=&d" (reg2), "+m" (lp->lock) : "a" (&lp->lock) : "cc" ); +#else /* __s390x__ */ + unsigned long reg1, reg2; + __asm__ __volatile(" bras %1,1f\n" + "0: " __DIAG44_INSN " 0,%4\n" + "1: slr %0,%0\n" + " cs %0,%1,0(%3)\n" + " jl 0b\n" + : "=&d" (reg1), "=&d" (reg2), "+m" (lp->lock) + : "a" (&lp->lock), "i" (__DIAG44_OPERAND) + : "cc" ); +#endif /* __s390x__ */ } extern inline int _raw_spin_trylock(spinlock_t *lp) { +#ifndef __s390x__ unsigned long result, reg; +#else /* __s390x__ */ + unsigned int result, reg; +#endif /* __s390x__ */ __asm__ __volatile(" slr %0,%0\n" " basr %1,0\n" "0: cs %0,%1,0(%3)" @@ -80,6 +117,7 @@ typedef struct { #define rwlock_is_locked(x) ((x)->lock != 0) +#ifndef __s390x__ #define _raw_read_lock(rw) \ asm volatile(" l 2,0(%1)\n" \ " j 1f\n" \ @@ -90,7 +128,21 @@ typedef struct { " jl 0b" \ : "+m" ((rw)->lock) : "a" (&(rw)->lock) \ : "2", "3", "cc" ) +#else /* __s390x__ */ +#define _raw_read_lock(rw) \ + asm volatile(" lg 2,0(%1)\n" \ + " j 1f\n" \ + "0: " __DIAG44_INSN " 0,%2\n" \ + "1: nihh 2,0x7fff\n" /* clear high (=write) bit */ \ + " la 3,1(2)\n" /* one more reader */ \ + " csg 2,3,0(%1)\n" /* try to write new value */ \ + " jl 0b" \ + : "+m" ((rw)->lock) \ + : "a" (&(rw)->lock), "i" (__DIAG44_OPERAND) \ + : "2", "3", "cc" ) +#endif /* __s390x__ */ +#ifndef __s390x__ #define _raw_read_unlock(rw) \ asm volatile(" l 2,0(%1)\n" \ " j 1f\n" \ @@ -101,7 +153,21 @@ typedef struct { " jl 0b" \ : "+m" ((rw)->lock) : "a" (&(rw)->lock) \ : "2", "3", "cc" ) +#else /* __s390x__ */ +#define _raw_read_unlock(rw) \ + asm volatile(" lg 2,0(%1)\n" \ + " j 1f\n" \ + "0: " __DIAG44_INSN " 0,%2\n" \ + "1: lgr 3,2\n" \ + " bctgr 3,0\n" /* one less reader */ \ + " csg 2,3,0(%1)\n" \ + " jl 0b" \ + : "+m" ((rw)->lock) \ + : "a" (&(rw)->lock), "i" (__DIAG44_OPERAND) \ + : "2", "3", "cc" ) +#endif /* __s390x__ */ +#ifndef __s390x__ #define _raw_write_lock(rw) \ asm volatile(" lhi 3,1\n" \ " sll 3,31\n" /* new lock value = 0x80000000 */ \ @@ -112,7 +178,20 @@ typedef struct { " jl 0b" \ : "+m" ((rw)->lock) : "a" (&(rw)->lock) \ : "2", "3", "cc" ) +#else /* __s390x__ */ +#define _raw_write_lock(rw) \ + asm volatile(" llihh 3,0x8000\n" /* new lock value = 0x80...0 */ \ + " j 1f\n" \ + "0: " __DIAG44_INSN " 0,%2\n" \ + "1: slgr 2,2\n" /* old lock value must be 0 */ \ + " csg 2,3,0(%1)\n" \ + " jl 0b" \ + : "+m" ((rw)->lock) \ + : "a" (&(rw)->lock), "i" (__DIAG44_OPERAND) \ + : "2", "3", "cc" ) +#endif /* __s390x__ */ +#ifndef __s390x__ #define _raw_write_unlock(rw) \ asm volatile(" slr 3,3\n" /* new lock value = 0 */ \ " j 1f\n" \ @@ -123,15 +202,34 @@ typedef struct { " jl 0b" \ : "+m" ((rw)->lock) : "a" (&(rw)->lock) \ : "2", "3", "cc" ) +#else /* __s390x__ */ +#define _raw_write_unlock(rw) \ + asm volatile(" slgr 3,3\n" /* new lock value = 0 */ \ + " j 1f\n" \ + "0: " __DIAG44_INSN " 0,%2\n" \ + "1: llihh 2,0x8000\n" /* old lock value must be 0x8..0 */\ + " csg 2,3,0(%1)\n" \ + " jl 0b" \ + : "+m" ((rw)->lock) \ + : "a" (&(rw)->lock), "i" (__DIAG44_OPERAND) \ + : "2", "3", "cc" ) +#endif /* __s390x__ */ extern inline int _raw_write_trylock(rwlock_t *rw) { unsigned int result, reg; - __asm__ __volatile__(" lhi %0,1\n" + __asm__ __volatile__( +#ifndef __s390x__ + " lhi %0,1\n" " sll %0,31\n" " basr %1,0\n" "0: cs %0,%1,0(%3)\n" +#else /* __s390x__ */ + " llihh %0,0x8000\n" + " basr %1,0\n" + "0: csg %0,%1,0(%3)\n" +#endif /* __s390x__ */ : "=&d" (result), "=&d" (reg), "+m" (rw->lock) : "a" (&rw->lock) : "cc" ); return !result; diff --git a/include/asm-s390/stat.h b/include/asm-s390/stat.h index 9761b12216a31..d92959eebb65b 100644 --- a/include/asm-s390/stat.h +++ b/include/asm-s390/stat.h @@ -9,6 +9,7 @@ #ifndef _S390_STAT_H #define _S390_STAT_H +#ifndef __s390x__ struct __old_kernel_stat { unsigned short st_dev; unsigned short st_ino; @@ -46,8 +47,6 @@ struct stat { unsigned long __unused5; }; -#define STAT_HAVE_NSEC 1 - /* This matches struct stat64 in glibc2.1, hence the absolutely * insane amounts of padding around dev_t's. */ @@ -76,4 +75,31 @@ struct stat64 { unsigned long long st_ino; }; +#else /* __s390x__ */ + +struct stat { + unsigned long st_dev; + unsigned long st_ino; + unsigned long st_nlink; + unsigned int st_mode; + unsigned int st_uid; + unsigned int st_gid; + unsigned int __pad1; + unsigned long st_rdev; + unsigned long st_size; + unsigned long st_atime; + unsigned long st_atime_nsec; + unsigned long st_mtime; + unsigned long st_mtime_nsec; + unsigned long st_ctime; + unsigned long st_ctime_nsec; + unsigned long st_blksize; + long st_blocks; + unsigned long __unused[3]; +}; + +#endif /* __s390x__ */ + +#define STAT_HAVE_NSEC 1 + #endif diff --git a/include/asm-s390/statfs.h b/include/asm-s390/statfs.h index c395867599f2a..f1c45a786b8f7 100644 --- a/include/asm-s390/statfs.h +++ b/include/asm-s390/statfs.h @@ -18,6 +18,7 @@ typedef __kernel_fsid_t fsid_t; #endif struct statfs { +#ifndef __s390x__ long f_type; long f_bsize; long f_blocks; @@ -28,6 +29,18 @@ struct statfs { __kernel_fsid_t f_fsid; long f_namelen; long f_spare[6]; +#else /* __s390x__ */ + int f_type; + int f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; + __kernel_fsid_t f_fsid; + int f_namelen; + int f_spare[6]; +#endif /* __s390x__ */ }; #endif diff --git a/include/asm-s390/string.h b/include/asm-s390/string.h index 304979b839c93..d8739b639ed77 100644 --- a/include/asm-s390/string.h +++ b/include/asm-s390/string.h @@ -49,13 +49,24 @@ static inline void * memchr(const void * cs,int c,size_t count) { void *ptr; - __asm__ __volatile__ (" lr 0,%2\n" + __asm__ __volatile__ ( +#ifndef __s390x__ + " lr 0,%2\n" " lr 1,%1\n" " la %0,0(%3,%1)\n" "0: srst %0,1\n" " jo 0b\n" " brc 13,1f\n" " slr %0,%0\n" +#else /* __s390x__ */ + " lgr 0,%2\n" + " lgr 1,%1\n" + " la %0,0(%3,%1)\n" + "0: srst %0,1\n" + " jo 0b\n" + " brc 13,1f\n" + " slgr %0,%0\n" +#endif /* __s390x__ */ "1:" : "=&a" (ptr) : "a" (cs), "d" (c), "d" (count) : "cc", "0", "1" ); @@ -66,9 +77,16 @@ static __inline__ char *strcpy(char *dest, const char *src) { char *tmp = dest; - __asm__ __volatile__ (" sr 0,0\n" + __asm__ __volatile__ ( +#ifndef __s390x__ + " sr 0,0\n" "0: mvst %0,%1\n" " jo 0b" +#else /* __s390x__ */ + " slgr 0,0\n" + "0: mvst %0,%1\n" + " jo 0b" +#endif /* __s390x__ */ : "+&a" (dest), "+&a" (src) : : "cc", "memory", "0" ); return tmp; @@ -78,12 +96,22 @@ static __inline__ size_t strlen(const char *s) { size_t len; - __asm__ __volatile__ (" sr 0,0\n" + __asm__ __volatile__ ( +#ifndef __s390x__ + " sr 0,0\n" " lr %0,%1\n" "0: srst 0,%0\n" " jo 0b\n" " lr %0,0\n" " sr %0,%1" +#else /* __s390x__ */ + " slgr 0,0\n" + " lgr %0,%1\n" + "0: srst 0,%0\n" + " jo 0b\n" + " lgr %0,0\n" + " sgr %0,%1" +#endif /* __s390x__ */ : "=&a" (len) : "a" (s) : "cc", "0" ); return len; @@ -93,25 +121,30 @@ static __inline__ char *strcat(char *dest, const char *src) { char *tmp = dest; - __asm__ __volatile__ (" sr 0,0\n" + __asm__ __volatile__ ( +#ifndef __s390x__ + " sr 0,0\n" "0: srst 0,%0\n" " jo 0b\n" " lr %0,0\n" " sr 0,0\n" "1: mvst %0,%1\n" " jo 1b" +#else /* __s390x__ */ + " slgr 0,0\n" + "0: srst 0,%0\n" + " jo 0b\n" + " lgr %0,0\n" + " slgr 0,0\n" + "1: mvst %0,%1\n" + " jo 1b" +#endif /* __s390x__ */ : "+&a" (dest), "+&a" (src) : : "cc", "memory", "0" ); return tmp; } extern void *alloca(size_t); - #endif /* __KERNEL__ */ #endif /* __S390_STRING_H_ */ - - - - - diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h index 0d19bdb36a432..2412f09825b05 100644 --- a/include/asm-s390/system.h +++ b/include/asm-s390/system.h @@ -23,6 +23,15 @@ struct task_struct; extern struct task_struct *resume(void *, void *); +#ifdef __s390x__ +#define __FLAG_SHIFT 56 +extern void __misaligned_u16(void); +extern void __misaligned_u32(void); +extern void __misaligned_u64(void); +#else /* __s390x__ */ +#define __FLAG_SHIFT 24 +#endif /* __s390x__ */ + static inline void save_fp_regs(s390_fp_regs *fpregs) { asm volatile ( @@ -88,7 +97,7 @@ static inline void restore_fp_regs(s390_fp_regs *fpregs) #define nop() __asm__ __volatile__ ("nop") #define xchg(ptr,x) \ - ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) + ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(void *)(ptr),sizeof(*(ptr)))) static inline unsigned long __xchg(unsigned long x, void * ptr, int size) { @@ -137,6 +146,17 @@ static inline unsigned long __xchg(unsigned long x, void * ptr, int size) : "memory", "cc", "0" ); x = old; break; +#ifdef __s390x__ + case 8: + asm volatile ( + " lg %0,0(%2)\n" + "0: csg %0,%1,0(%2)\n" + " jl 0b\n" + : "=&d" (old) : "d" (x), "a" (ptr) + : "memory", "cc", "0" ); + x = old; + break; +#endif /* __s390x__ */ } return x; } @@ -208,6 +228,14 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) : "=&d" (prev) : "0" (old), "d" (new), "a" (ptr) : "memory", "cc" ); return prev; +#ifdef __s390x__ + case 8: + asm volatile ( + " csg %0,%2,0(%3)\n" + : "=&d" (prev) : "0" (old), "d" (new), "a" (ptr) + : "memory", "cc" ); + return prev; +#endif /* __s390x__ */ } return old; } @@ -241,15 +269,15 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) /* interrupt control.. */ #define local_irq_enable() ({ \ - __u8 __dummy; \ + unsigned long __dummy; \ __asm__ __volatile__ ( \ "stosm 0(%1),0x03" : "=m" (__dummy) : "a" (&__dummy) ); \ }) #define local_irq_disable() ({ \ - __u32 __flags; \ + unsigned long __flags; \ __asm__ __volatile__ ( \ - "stnsm 0(%1),0xFC" : "=m" (__flags) : "a" (&__flags) ); \ + "stnsm 0(%1),0xfc" : "=m" (__flags) : "a" (&__flags) ); \ __flags; \ }) @@ -263,9 +291,70 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) ({ \ unsigned long flags; \ local_save_flags(flags); \ - !((flags >> 24) & 3); \ + !((flags >> __FLAG_SHIFT) & 3); \ }) +#ifdef __s390x__ + +#define __load_psw(psw) \ + __asm__ __volatile__("lpswe 0(%0)" : : "a" (&psw) : "cc" ); + +#define __ctl_load(array, low, high) ({ \ + __asm__ __volatile__ ( \ + " la 1,%0\n" \ + " bras 2,0f\n" \ + " lctlg 0,0,0(1)\n" \ + "0: ex %1,0(2)" \ + : : "m" (array), "a" (((low)<<4)+(high)) : "1", "2" ); \ + }) + +#define __ctl_store(array, low, high) ({ \ + __asm__ __volatile__ ( \ + " la 1,%0\n" \ + " bras 2,0f\n" \ + " stctg 0,0,0(1)\n" \ + "0: ex %1,0(2)" \ + : "=m" (array) : "a" (((low)<<4)+(high)): "1", "2" ); \ + }) + +#define __ctl_set_bit(cr, bit) ({ \ + __u8 __dummy[24]; \ + __asm__ __volatile__ ( \ + " la 1,%0\n" /* align to 8 byte */ \ + " aghi 1,7\n" \ + " nill 1,0xfff8\n" \ + " bras 2,0f\n" /* skip indirect insns */ \ + " stctg 0,0,0(1)\n" \ + " lctlg 0,0,0(1)\n" \ + "0: ex %1,0(2)\n" /* execute stctl */ \ + " lg 0,0(1)\n" \ + " ogr 0,%2\n" /* set the bit */ \ + " stg 0,0(1)\n" \ + "1: ex %1,6(2)" /* execute lctl */ \ + : "=m" (__dummy) : "a" (cr*17), "a" (1L<<(bit)) \ + : "cc", "0", "1", "2"); \ + }) + +#define __ctl_clear_bit(cr, bit) ({ \ + __u8 __dummy[24]; \ + __asm__ __volatile__ ( \ + " la 1,%0\n" /* align to 8 byte */ \ + " aghi 1,7\n" \ + " nill 1,0xfff8\n" \ + " bras 2,0f\n" /* skip indirect insns */ \ + " stctg 0,0,0(1)\n" \ + " lctlg 0,0,0(1)\n" \ + "0: ex %1,0(2)\n" /* execute stctl */ \ + " lg 0,0(1)\n" \ + " ngr 0,%2\n" /* set the bit */ \ + " stg 0,0(1)\n" \ + "1: ex %1,6(2)" /* execute lctl */ \ + : "=m" (__dummy) : "a" (cr*17), "a" (~(1L<<(bit))) \ + : "cc", "0", "1", "2"); \ + }) + +#else /* __s390x__ */ + #define __load_psw(psw) \ __asm__ __volatile__("lpsw 0(%0)" : : "a" (&psw) : "cc" ); @@ -273,7 +362,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) __asm__ __volatile__ ( \ " la 1,%0\n" \ " bras 2,0f\n" \ - " lctl 0,0,0(1)\n" \ + " lctl 0,0,0(1)\n" \ "0: ex %1,0(2)" \ : : "m" (array), "a" (((low)<<4)+(high)) : "1", "2" ); \ }) @@ -324,6 +413,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) : "=m" (__dummy) : "a" (cr*17), "a" (~(1<<(bit))) \ : "cc", "0", "1", "2"); \ }) +#endif /* __s390x__ */ /* For spinlocks etc */ #define local_irq_save(x) ((x) = local_irq_disable()) diff --git a/include/asm-s390/thread_info.h b/include/asm-s390/thread_info.h index eb131fa3a4704..a46e8fd2c7aca 100644 --- a/include/asm-s390/thread_info.h +++ b/include/asm-s390/thread_info.h @@ -13,6 +13,7 @@ #ifndef __ASSEMBLY__ #include +#include /* * low level task data that entry.S needs immediate access to @@ -46,26 +47,35 @@ struct thread_info { #define init_thread_info (init_thread_union.thread_info) #define init_stack (init_thread_union.stack) +/* + * Size of kernel stack for each process + */ +#ifndef __s390x__ +#define THREAD_ORDER 1 +#define ASYNC_ORDER 1 +#else /* __s390x__ */ +#define THREAD_ORDER 2 +#define ASYNC_ORDER 2 +#endif /* __s390x__ */ + +#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) +#define ASYNC_SIZE (PAGE_SIZE << ASYNC_ORDER) + /* how to get the thread information struct from C */ static inline struct thread_info *current_thread_info(void) { - return (struct thread_info *)((*(unsigned long *) 0xc40)-8192); + return (struct thread_info *)((*(unsigned long *) __LC_KERNEL_STACK)-THREAD_SIZE); } /* thread information allocation */ #define alloc_thread_info() ((struct thread_info *) \ - __get_free_pages(GFP_KERNEL,1)) -#define free_thread_info(ti) free_pages((unsigned long) (ti), 1) + __get_free_pages(GFP_KERNEL,THREAD_ORDER)) +#define free_thread_info(ti) free_pages((unsigned long) (ti),THREAD_ORDER) #define get_thread_info(ti) get_task_struct((ti)->task) #define put_thread_info(ti) put_task_struct((ti)->task) #endif -/* - * Size of kernel stack for each process - */ -#define THREAD_SIZE (2*PAGE_SIZE) - /* * thread information flags bit numbers */ @@ -77,6 +87,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ +#define TIF_31BIT 18 /* 32bit process */ #define _TIF_SYSCALL_TRACE (1< */ #define __syscall_return(type, res) \ @@ -279,10 +364,10 @@ type name(void) { \ register long __svcres asm("2"); \ long __res; \ __asm__ __volatile__ ( \ - " .if %b1 < 256\n" \ + " .if %1 < 256\n" \ " svc %b1\n" \ " .else\n" \ - " lhi %%r1,%b1\n" \ + " la %%r1,%1\n" \ " svc 0\n" \ " .endif" \ : "=d" (__svcres) \ @@ -298,10 +383,10 @@ type name(type1 arg1) { \ register long __svcres asm("2"); \ long __res; \ __asm__ __volatile__ ( \ - " .if %b1 < 256\n" \ + " .if %1 < 256\n" \ " svc %b1\n" \ " .else\n" \ - " lhi %%r1,%b1\n" \ + " la %%r1,%1\n" \ " svc 0\n" \ " .endif" \ : "=d" (__svcres) \ @@ -319,10 +404,10 @@ type name(type1 arg1, type2 arg2) { \ register long __svcres asm("2"); \ long __res; \ __asm__ __volatile__ ( \ - " .if %b1 < 256\n" \ + " .if %1 < 256\n" \ " svc %b1\n" \ " .else\n" \ - " lhi %%r1,%b1\n" \ + " la %%r1,%1\n" \ " svc 0\n" \ " .endif" \ : "=d" (__svcres) \ @@ -342,10 +427,10 @@ type name(type1 arg1, type2 arg2, type3 arg3) { \ register long __svcres asm("2"); \ long __res; \ __asm__ __volatile__ ( \ - " .if %b1 < 256\n" \ + " .if %1 < 256\n" \ " svc %b1\n" \ " .else\n" \ - " lhi %%r1,%b1\n" \ + " la %%r1,%1\n" \ " svc 0\n" \ " .endif" \ : "=d" (__svcres) \ @@ -368,10 +453,10 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ register long __svcres asm("2"); \ long __res; \ __asm__ __volatile__ ( \ - " .if %b1 < 256\n" \ + " .if %1 < 256\n" \ " svc %b1\n" \ " .else\n" \ - " lhi %%r1,%b1\n" \ + " la %%r1,%1\n" \ " svc 0\n" \ " .endif" \ : "=d" (__svcres) \ @@ -397,10 +482,10 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ register long __svcres asm("2"); \ long __res; \ __asm__ __volatile__ ( \ - " .if %b1 < 256\n" \ + " .if %1 < 256\n" \ " svc %b1\n" \ " .else\n" \ - " lhi %%r1,%b1\n" \ + " la %%r1,%1\n" \ " svc 0\n" \ " .endif" \ : "=d" (__svcres) \ -- 2.53.0