Linux Audio

Check our new training course

Loading...
v3.5.6
  1/*
  2 *  include/asm-s390/processor.h
  3 *
  4 *  S390 version
  5 *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  6 *    Author(s): Hartmut Penner (hp@de.ibm.com),
  7 *               Martin Schwidefsky (schwidefsky@de.ibm.com)
  8 *
  9 *  Derived from "include/asm-i386/processor.h"
 10 *    Copyright (C) 1994, Linus Torvalds
 11 */
 12
 13#ifndef __ASM_S390_PROCESSOR_H
 14#define __ASM_S390_PROCESSOR_H
 15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 16#include <linux/linkage.h>
 17#include <linux/irqflags.h>
 18#include <asm/cpu.h>
 19#include <asm/page.h>
 20#include <asm/ptrace.h>
 21#include <asm/setup.h>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 22
 23/*
 24 * Default implementation of macro that returns current
 25 * instruction pointer ("program counter").
 26 */
 27#define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; })
 28
 29static inline void get_cpu_id(struct cpuid *ptr)
 30{
 31	asm volatile("stidp %0" : "=Q" (*ptr));
 32}
 33
 34extern void s390_adjust_jiffies(void);
 
 
 
 35extern const struct seq_operations cpuinfo_op;
 36extern int sysctl_ieee_emulation_warnings;
 
 37
 38/*
 39 * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit.
 40 */
 41#ifndef CONFIG_64BIT
 42
 43#define TASK_SIZE		(1UL << 31)
 44#define TASK_UNMAPPED_BASE	(1UL << 30)
 45
 46#else /* CONFIG_64BIT */
 47
 48#define TASK_SIZE_OF(tsk)	((tsk)->mm->context.asce_limit)
 
 49#define TASK_UNMAPPED_BASE	(test_thread_flag(TIF_31BIT) ? \
 50					(1UL << 30) : (1UL << 41))
 51#define TASK_SIZE		TASK_SIZE_OF(current)
 
 52
 53#endif /* CONFIG_64BIT */
 54
 55#ifndef CONFIG_64BIT
 56#define STACK_TOP		(1UL << 31)
 57#define STACK_TOP_MAX		(1UL << 31)
 58#else /* CONFIG_64BIT */
 59#define STACK_TOP		(1UL << (test_thread_flag(TIF_31BIT) ? 31:42))
 60#define STACK_TOP_MAX		(1UL << 42)
 61#endif /* CONFIG_64BIT */
 62
 63#define HAVE_ARCH_PICK_MMAP_LAYOUT
 64
 65typedef struct {
 66        __u32 ar4;
 67} mm_segment_t;
 68
 69/*
 70 * Thread structure
 71 */
 72struct thread_struct {
 73	s390_fp_regs fp_regs;
 74	unsigned int  acrs[NUM_ACRS];
 75        unsigned long ksp;              /* kernel stack pointer             */
 
 
 
 76	mm_segment_t mm_segment;
 77	unsigned long gmap_addr;	/* address of last gmap fault. */
 
 
 
 
 78	struct per_regs per_user;	/* User specified PER registers */
 79	struct per_event per_event;	/* Cause of the last PER trap */
 
 
 
 80        /* pfault_wait is used to block the process on a pfault event */
 81	unsigned long pfault_wait;
 82	struct list_head list;
 
 
 
 
 
 
 
 
 83};
 84
 
 
 
 
 
 
 
 
 
 
 85typedef struct thread_struct thread_struct;
 86
 87/*
 88 * Stack layout of a C stack frame.
 89 */
 90#ifndef __PACK_STACK
 91struct stack_frame {
 92	unsigned long back_chain;
 93	unsigned long empty1[5];
 94	unsigned long gprs[10];
 95	unsigned int  empty2[8];
 96};
 97#else
 98struct stack_frame {
 99	unsigned long empty1[5];
100	unsigned int  empty2[8];
101	unsigned long gprs[10];
102	unsigned long back_chain;
103};
104#endif
105
106#define ARCH_MIN_TASKALIGN	8
107
108#define INIT_THREAD {							\
109	.ksp = sizeof(init_stack) + (unsigned long) &init_stack,	\
 
110}
111
112/*
113 * Do necessary setup to start up a new thread.
114 */
115#define start_thread(regs, new_psw, new_stackp) do {			\
116	regs->psw.mask	= psw_user_bits | PSW_MASK_EA | PSW_MASK_BA;	\
117	regs->psw.addr	= new_psw | PSW_ADDR_AMODE;			\
118	regs->gprs[15]	= new_stackp;					\
 
119} while (0)
120
121#define start_thread31(regs, new_psw, new_stackp) do {			\
122	regs->psw.mask	= psw_user_bits | PSW_MASK_BA;			\
123	regs->psw.addr	= new_psw | PSW_ADDR_AMODE;			\
124	regs->gprs[15]	= new_stackp;					\
125	__tlb_flush_mm(current->mm);					\
126	crst_table_downgrade(current->mm, 1UL << 31);			\
127	update_mm(current->mm, current);				\
128} while (0)
129
130/* Forward declaration, a strange C thing */
131struct task_struct;
132struct mm_struct;
133struct seq_file;
134
 
 
 
 
 
 
135/* Free all resources held by a thread. */
136extern void release_thread(struct task_struct *);
137extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
138
139/*
140 * Return saved PC of a blocked thread.
141 */
142extern unsigned long thread_saved_pc(struct task_struct *t);
143
144extern void show_code(struct pt_regs *regs);
145
146unsigned long get_wchan(struct task_struct *p);
147#define task_pt_regs(tsk) ((struct pt_regs *) \
148        (task_stack_page(tsk) + THREAD_SIZE) - 1)
149#define KSTK_EIP(tsk)	(task_pt_regs(tsk)->psw.addr)
150#define KSTK_ESP(tsk)	(task_pt_regs(tsk)->gprs[15])
151
 
 
 
 
 
 
 
 
 
 
 
152static inline unsigned short stap(void)
153{
154	unsigned short cpu_address;
155
156	asm volatile("stap %0" : "=m" (cpu_address));
157	return cpu_address;
158}
159
160/*
161 * Give up the time slice of the virtual PU.
162 */
163static inline void cpu_relax(void)
 
 
 
 
 
 
 
 
164{
165	if (MACHINE_HAS_DIAG44)
166		asm volatile("diag 0,0,68");
167	barrier();
 
 
168}
169
170static inline void psw_set_key(unsigned int key)
171{
172	asm volatile("spka 0(%0)" : : "d" (key));
173}
174
175/*
176 * Set PSW to specified value.
177 */
178static inline void __load_psw(psw_t psw)
179{
180#ifndef CONFIG_64BIT
181	asm volatile("lpsw  %0" : : "Q" (psw) : "cc");
182#else
183	asm volatile("lpswe %0" : : "Q" (psw) : "cc");
184#endif
185}
186
187/*
188 * Set PSW mask to specified value, while leaving the
189 * PSW addr pointing to the next instruction.
190 */
191static inline void __load_psw_mask (unsigned long mask)
192{
193	unsigned long addr;
194	psw_t psw;
195
196	psw.mask = mask;
197
198#ifndef CONFIG_64BIT
199	asm volatile(
200		"	basr	%0,0\n"
201		"0:	ahi	%0,1f-0b\n"
202		"	st	%0,%O1+4(%R1)\n"
203		"	lpsw	%1\n"
204		"1:"
205		: "=&d" (addr), "=Q" (psw) : "Q" (psw) : "memory", "cc");
206#else /* CONFIG_64BIT */
207	asm volatile(
208		"	larl	%0,1f\n"
209		"	stg	%0,%O1+8(%R1)\n"
210		"	lpswe	%1\n"
211		"1:"
212		: "=&d" (addr), "=Q" (psw) : "Q" (psw) : "memory", "cc");
213#endif /* CONFIG_64BIT */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214}
215
216/*
217 * Rewind PSW instruction address by specified number of bytes.
218 */
219static inline unsigned long __rewind_psw(psw_t psw, unsigned long ilc)
220{
221#ifndef CONFIG_64BIT
222	if (psw.addr & PSW_ADDR_AMODE)
223		/* 31 bit mode */
224		return (psw.addr - ilc) | PSW_ADDR_AMODE;
225	/* 24 bit mode */
226	return (psw.addr - ilc) & ((1UL << 24) - 1);
227#else
228	unsigned long mask;
229
230	mask = (psw.mask & PSW_MASK_EA) ? -1UL :
231	       (psw.mask & PSW_MASK_BA) ? (1UL << 31) - 1 :
232					  (1UL << 24) - 1;
233	return (psw.addr - ilc) & mask;
234#endif
235}
236 
 
 
 
 
 
237/*
238 * Function to drop a processor into disabled wait state
239 */
240static inline void __noreturn disabled_wait(unsigned long code)
241{
242        unsigned long ctl_buf;
243        psw_t dw_psw;
244
245	dw_psw.mask = PSW_MASK_BASE | PSW_MASK_WAIT | PSW_MASK_BA | PSW_MASK_EA;
246        dw_psw.addr = code;
247        /* 
248         * Store status and then load disabled wait psw,
249         * the processor is dead afterwards
250         */
251#ifndef CONFIG_64BIT
252	asm volatile(
253		"	stctl	0,0,0(%2)\n"
254		"	ni	0(%2),0xef\n"	/* switch off protection */
255		"	lctl	0,0,0(%2)\n"
256		"	stpt	0xd8\n"		/* store timer */
257		"	stckc	0xe0\n"		/* store clock comparator */
258		"	stpx	0x108\n"	/* store prefix register */
259		"	stam	0,15,0x120\n"	/* store access registers */
260		"	std	0,0x160\n"	/* store f0 */
261		"	std	2,0x168\n"	/* store f2 */
262		"	std	4,0x170\n"	/* store f4 */
263		"	std	6,0x178\n"	/* store f6 */
264		"	stm	0,15,0x180\n"	/* store general registers */
265		"	stctl	0,15,0x1c0\n"	/* store control registers */
266		"	oi	0x1c0,0x10\n"	/* fake protection bit */
267		"	lpsw	0(%1)"
268		: "=m" (ctl_buf)
269		: "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc");
270#else /* CONFIG_64BIT */
271	asm volatile(
272		"	stctg	0,0,0(%2)\n"
273		"	ni	4(%2),0xef\n"	/* switch off protection */
274		"	lctlg	0,0,0(%2)\n"
275		"	lghi	1,0x1000\n"
276		"	stpt	0x328(1)\n"	/* store timer */
277		"	stckc	0x330(1)\n"	/* store clock comparator */
278		"	stpx	0x318(1)\n"	/* store prefix register */
279		"	stam	0,15,0x340(1)\n"/* store access registers */
280		"	stfpc	0x31c(1)\n"	/* store fpu control */
281		"	std	0,0x200(1)\n"	/* store f0 */
282		"	std	1,0x208(1)\n"	/* store f1 */
283		"	std	2,0x210(1)\n"	/* store f2 */
284		"	std	3,0x218(1)\n"	/* store f3 */
285		"	std	4,0x220(1)\n"	/* store f4 */
286		"	std	5,0x228(1)\n"	/* store f5 */
287		"	std	6,0x230(1)\n"	/* store f6 */
288		"	std	7,0x238(1)\n"	/* store f7 */
289		"	std	8,0x240(1)\n"	/* store f8 */
290		"	std	9,0x248(1)\n"	/* store f9 */
291		"	std	10,0x250(1)\n"	/* store f10 */
292		"	std	11,0x258(1)\n"	/* store f11 */
293		"	std	12,0x260(1)\n"	/* store f12 */
294		"	std	13,0x268(1)\n"	/* store f13 */
295		"	std	14,0x270(1)\n"	/* store f14 */
296		"	std	15,0x278(1)\n"	/* store f15 */
297		"	stmg	0,15,0x280(1)\n"/* store general registers */
298		"	stctg	0,15,0x380(1)\n"/* store control registers */
299		"	oi	0x384(1),0x10\n"/* fake protection bit */
300		"	lpswe	0(%1)"
301		: "=m" (ctl_buf)
302		: "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc", "0", "1");
303#endif /* CONFIG_64BIT */
304	while (1);
305}
306
307/*
308 * Use to set psw mask except for the first byte which
309 * won't be changed by this function.
310 */
311static inline void
312__set_psw_mask(unsigned long mask)
313{
314	__load_psw_mask(mask | (arch_local_save_flags() & ~(-1UL >> 8)));
315}
316
317#define local_mcck_enable() \
318	__set_psw_mask(psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK)
319#define local_mcck_disable() \
320	__set_psw_mask(psw_kernel_bits | PSW_MASK_DAT)
321
322/*
323 * Basic Machine Check/Program Check Handler.
324 */
325
326extern void s390_base_mcck_handler(void);
327extern void s390_base_pgm_handler(void);
328extern void s390_base_ext_handler(void);
329
330extern void (*s390_base_mcck_handler_fn)(void);
331extern void (*s390_base_pgm_handler_fn)(void);
332extern void (*s390_base_ext_handler_fn)(void);
333
334#define ARCH_LOW_ADDRESS_LIMIT	0x7fffffffUL
335
336/*
337 * Helper macro for exception table entries
338 */
339#ifndef CONFIG_64BIT
340#define EX_TABLE(_fault,_target)			\
341	".section __ex_table,\"a\"\n"			\
342	"	.align 4\n"				\
343	"	.long  " #_fault "," #_target "\n"	\
344	".previous\n"
345#else
346#define EX_TABLE(_fault,_target)			\
347	".section __ex_table,\"a\"\n"			\
348	"	.align 8\n"				\
349	"	.quad  " #_fault "," #_target "\n"	\
350	".previous\n"
351#endif
352
353#endif                                 /* __ASM_S390_PROCESSOR_H           */
v4.10.11
  1/*
 
 
  2 *  S390 version
  3 *    Copyright IBM Corp. 1999
  4 *    Author(s): Hartmut Penner (hp@de.ibm.com),
  5 *               Martin Schwidefsky (schwidefsky@de.ibm.com)
  6 *
  7 *  Derived from "include/asm-i386/processor.h"
  8 *    Copyright (C) 1994, Linus Torvalds
  9 */
 10
 11#ifndef __ASM_S390_PROCESSOR_H
 12#define __ASM_S390_PROCESSOR_H
 13
 14#include <linux/const.h>
 15
 16#define CIF_MCCK_PENDING	0	/* machine check handling is pending */
 17#define CIF_ASCE		1	/* user asce needs fixup / uaccess */
 18#define CIF_NOHZ_DELAY		2	/* delay HZ disable for a tick */
 19#define CIF_FPU			3	/* restore FPU registers */
 20#define CIF_IGNORE_IRQ		4	/* ignore interrupt (for udelay) */
 21#define CIF_ENABLED_WAIT	5	/* in enabled wait state */
 22
 23#define _CIF_MCCK_PENDING	_BITUL(CIF_MCCK_PENDING)
 24#define _CIF_ASCE		_BITUL(CIF_ASCE)
 25#define _CIF_NOHZ_DELAY		_BITUL(CIF_NOHZ_DELAY)
 26#define _CIF_FPU		_BITUL(CIF_FPU)
 27#define _CIF_IGNORE_IRQ		_BITUL(CIF_IGNORE_IRQ)
 28#define _CIF_ENABLED_WAIT	_BITUL(CIF_ENABLED_WAIT)
 29
 30#ifndef __ASSEMBLY__
 31
 32#include <linux/linkage.h>
 33#include <linux/irqflags.h>
 34#include <asm/cpu.h>
 35#include <asm/page.h>
 36#include <asm/ptrace.h>
 37#include <asm/setup.h>
 38#include <asm/runtime_instr.h>
 39#include <asm/fpu/types.h>
 40#include <asm/fpu/internal.h>
 41
 42static inline void set_cpu_flag(int flag)
 43{
 44	S390_lowcore.cpu_flags |= (1UL << flag);
 45}
 46
 47static inline void clear_cpu_flag(int flag)
 48{
 49	S390_lowcore.cpu_flags &= ~(1UL << flag);
 50}
 51
 52static inline int test_cpu_flag(int flag)
 53{
 54	return !!(S390_lowcore.cpu_flags & (1UL << flag));
 55}
 56
 57/*
 58 * Test CIF flag of another CPU. The caller needs to ensure that
 59 * CPU hotplug can not happen, e.g. by disabling preemption.
 60 */
 61static inline int test_cpu_flag_of(int flag, int cpu)
 62{
 63	struct lowcore *lc = lowcore_ptr[cpu];
 64	return !!(lc->cpu_flags & (1UL << flag));
 65}
 66
 67#define arch_needs_cpu() test_cpu_flag(CIF_NOHZ_DELAY)
 68
 69/*
 70 * Default implementation of macro that returns current
 71 * instruction pointer ("program counter").
 72 */
 73#define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; })
 74
 75static inline void get_cpu_id(struct cpuid *ptr)
 76{
 77	asm volatile("stidp %0" : "=Q" (*ptr));
 78}
 79
 80void s390_adjust_jiffies(void);
 81void s390_update_cpu_mhz(void);
 82void cpu_detect_mhz_feature(void);
 83
 84extern const struct seq_operations cpuinfo_op;
 85extern int sysctl_ieee_emulation_warnings;
 86extern void execve_tail(void);
 87
 88/*
 89 * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit.
 90 */
 
 
 
 
 
 
 91
 92#define TASK_SIZE_OF(tsk)	((tsk)->mm ? \
 93				 (tsk)->mm->context.asce_limit : TASK_MAX_SIZE)
 94#define TASK_UNMAPPED_BASE	(test_thread_flag(TIF_31BIT) ? \
 95					(1UL << 30) : (1UL << 41))
 96#define TASK_SIZE		TASK_SIZE_OF(current)
 97#define TASK_MAX_SIZE		(1UL << 53)
 98
 
 
 
 
 
 
 99#define STACK_TOP		(1UL << (test_thread_flag(TIF_31BIT) ? 31:42))
100#define STACK_TOP_MAX		(1UL << 42)
 
101
102#define HAVE_ARCH_PICK_MMAP_LAYOUT
103
104typedef struct {
105        __u32 ar4;
106} mm_segment_t;
107
108/*
109 * Thread structure
110 */
111struct thread_struct {
 
112	unsigned int  acrs[NUM_ACRS];
113        unsigned long ksp;              /* kernel stack pointer             */
114	unsigned long user_timer;	/* task cputime in user space */
115	unsigned long system_timer;	/* task cputime in kernel space */
116	unsigned long sys_call_table;	/* system call table address */
117	mm_segment_t mm_segment;
118	unsigned long gmap_addr;	/* address of last gmap fault. */
119	unsigned int gmap_write_flag;	/* gmap fault write indication */
120	unsigned int gmap_int_code;	/* int code of last gmap fault */
121	unsigned int gmap_pfault;	/* signal of a pending guest pfault */
122	/* Per-thread information related to debugging */
123	struct per_regs per_user;	/* User specified PER registers */
124	struct per_event per_event;	/* Cause of the last PER trap */
125	unsigned long per_flags;	/* Flags to control debug behavior */
126	unsigned int system_call;	/* system call number in signal */
127	unsigned long last_break;	/* last breaking-event-address. */
128        /* pfault_wait is used to block the process on a pfault event */
129	unsigned long pfault_wait;
130	struct list_head list;
131	/* cpu runtime instrumentation */
132	struct runtime_instr_cb *ri_cb;
133	unsigned char trap_tdb[256];	/* Transaction abort diagnose block */
134	/*
135	 * Warning: 'fpu' is dynamically-sized. It *MUST* be at
136	 * the end.
137	 */
138	struct fpu fpu;			/* FP and VX register save area */
139};
140
141/* Flag to disable transactions. */
142#define PER_FLAG_NO_TE			1UL
143/* Flag to enable random transaction aborts. */
144#define PER_FLAG_TE_ABORT_RAND		2UL
145/* Flag to specify random transaction abort mode:
146 * - abort each transaction at a random instruction before TEND if set.
147 * - abort random transactions at a random instruction if cleared.
148 */
149#define PER_FLAG_TE_ABORT_RAND_TEND	4UL
150
151typedef struct thread_struct thread_struct;
152
153/*
154 * Stack layout of a C stack frame.
155 */
156#ifndef __PACK_STACK
157struct stack_frame {
158	unsigned long back_chain;
159	unsigned long empty1[5];
160	unsigned long gprs[10];
161	unsigned int  empty2[8];
162};
163#else
164struct stack_frame {
165	unsigned long empty1[5];
166	unsigned int  empty2[8];
167	unsigned long gprs[10];
168	unsigned long back_chain;
169};
170#endif
171
172#define ARCH_MIN_TASKALIGN	8
173
174#define INIT_THREAD {							\
175	.ksp = sizeof(init_stack) + (unsigned long) &init_stack,	\
176	.fpu.regs = (void *) init_task.thread.fpu.fprs,			\
177}
178
179/*
180 * Do necessary setup to start up a new thread.
181 */
182#define start_thread(regs, new_psw, new_stackp) do {			\
183	regs->psw.mask	= PSW_USER_BITS | PSW_MASK_EA | PSW_MASK_BA;	\
184	regs->psw.addr	= new_psw;					\
185	regs->gprs[15]	= new_stackp;					\
186	execve_tail();							\
187} while (0)
188
189#define start_thread31(regs, new_psw, new_stackp) do {			\
190	regs->psw.mask	= PSW_USER_BITS | PSW_MASK_BA;			\
191	regs->psw.addr	= new_psw;					\
192	regs->gprs[15]	= new_stackp;					\
193	crst_table_downgrade(current->mm);				\
194	execve_tail();							\
 
195} while (0)
196
197/* Forward declaration, a strange C thing */
198struct task_struct;
199struct mm_struct;
200struct seq_file;
201
202typedef int (*dump_trace_func_t)(void *data, unsigned long address, int reliable);
203void dump_trace(dump_trace_func_t func, void *data,
204		struct task_struct *task, unsigned long sp);
205
206void show_cacheinfo(struct seq_file *m);
207
208/* Free all resources held by a thread. */
209extern void release_thread(struct task_struct *);
 
210
211/*
212 * Return saved PC of a blocked thread.
213 */
214extern unsigned long thread_saved_pc(struct task_struct *t);
215
 
 
216unsigned long get_wchan(struct task_struct *p);
217#define task_pt_regs(tsk) ((struct pt_regs *) \
218        (task_stack_page(tsk) + THREAD_SIZE) - 1)
219#define KSTK_EIP(tsk)	(task_pt_regs(tsk)->psw.addr)
220#define KSTK_ESP(tsk)	(task_pt_regs(tsk)->gprs[15])
221
222/* Has task runtime instrumentation enabled ? */
223#define is_ri_task(tsk) (!!(tsk)->thread.ri_cb)
224
225static inline unsigned long current_stack_pointer(void)
226{
227	unsigned long sp;
228
229	asm volatile("la %0,0(15)" : "=a" (sp));
230	return sp;
231}
232
233static inline unsigned short stap(void)
234{
235	unsigned short cpu_address;
236
237	asm volatile("stap %0" : "=m" (cpu_address));
238	return cpu_address;
239}
240
241/*
242 * Give up the time slice of the virtual PU.
243 */
244#define cpu_relax_yield cpu_relax_yield
245void cpu_relax_yield(void);
246
247#define cpu_relax() barrier()
248
249#define ECAG_CACHE_ATTRIBUTE	0
250#define ECAG_CPU_ATTRIBUTE	1
251
252static inline unsigned long __ecag(unsigned int asi, unsigned char parm)
253{
254	unsigned long val;
255
256	asm volatile(".insn	rsy,0xeb000000004c,%0,0,0(%1)" /* ecag */
257		     : "=d" (val) : "a" (asi << 8 | parm));
258	return val;
259}
260
261static inline void psw_set_key(unsigned int key)
262{
263	asm volatile("spka 0(%0)" : : "d" (key));
264}
265
266/*
267 * Set PSW to specified value.
268 */
269static inline void __load_psw(psw_t psw)
270{
 
 
 
271	asm volatile("lpswe %0" : : "Q" (psw) : "cc");
 
272}
273
274/*
275 * Set PSW mask to specified value, while leaving the
276 * PSW addr pointing to the next instruction.
277 */
278static inline void __load_psw_mask(unsigned long mask)
279{
280	unsigned long addr;
281	psw_t psw;
282
283	psw.mask = mask;
284
 
 
 
 
 
 
 
 
 
285	asm volatile(
286		"	larl	%0,1f\n"
287		"	stg	%0,%O1+8(%R1)\n"
288		"	lpswe	%1\n"
289		"1:"
290		: "=&d" (addr), "=Q" (psw) : "Q" (psw) : "memory", "cc");
291}
292
293/*
294 * Extract current PSW mask
295 */
296static inline unsigned long __extract_psw(void)
297{
298	unsigned int reg1, reg2;
299
300	asm volatile("epsw %0,%1" : "=d" (reg1), "=a" (reg2));
301	return (((unsigned long) reg1) << 32) | ((unsigned long) reg2);
302}
303
304static inline void local_mcck_enable(void)
305{
306	__load_psw_mask(__extract_psw() | PSW_MASK_MCHECK);
307}
308
309static inline void local_mcck_disable(void)
310{
311	__load_psw_mask(__extract_psw() & ~PSW_MASK_MCHECK);
312}
313
314/*
315 * Rewind PSW instruction address by specified number of bytes.
316 */
317static inline unsigned long __rewind_psw(psw_t psw, unsigned long ilc)
318{
 
 
 
 
 
 
 
319	unsigned long mask;
320
321	mask = (psw.mask & PSW_MASK_EA) ? -1UL :
322	       (psw.mask & PSW_MASK_BA) ? (1UL << 31) - 1 :
323					  (1UL << 24) - 1;
324	return (psw.addr - ilc) & mask;
 
325}
326
327/*
328 * Function to stop a processor until the next interrupt occurs
329 */
330void enabled_wait(void);
331
332/*
333 * Function to drop a processor into disabled wait state
334 */
335static inline void __noreturn disabled_wait(unsigned long code)
336{
337	psw_t psw;
 
338
339	psw.mask = PSW_MASK_BASE | PSW_MASK_WAIT | PSW_MASK_BA | PSW_MASK_EA;
340	psw.addr = code;
341	__load_psw(psw);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
342	while (1);
343}
344
345/*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346 * Basic Machine Check/Program Check Handler.
347 */
348
349extern void s390_base_mcck_handler(void);
350extern void s390_base_pgm_handler(void);
351extern void s390_base_ext_handler(void);
352
353extern void (*s390_base_mcck_handler_fn)(void);
354extern void (*s390_base_pgm_handler_fn)(void);
355extern void (*s390_base_ext_handler_fn)(void);
356
357#define ARCH_LOW_ADDRESS_LIMIT	0x7fffffffUL
358
359extern int memcpy_real(void *, void *, size_t);
360extern void memcpy_absolute(void *, void *, size_t);
361
362#define mem_assign_absolute(dest, val) {			\
363	__typeof__(dest) __tmp = (val);				\
364								\
365	BUILD_BUG_ON(sizeof(__tmp) != sizeof(val));		\
366	memcpy_absolute(&(dest), &__tmp, sizeof(__tmp));	\
367}
368
369#endif /* __ASSEMBLY__ */
 
 
 
 
 
370
371#endif /* __ASM_S390_PROCESSOR_H */