1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef __ASM_S390_PROCESSOR_H
14#define __ASM_S390_PROCESSOR_H
15
16#include <asm/page.h>
17#include <asm/ptrace.h>
18
19#ifdef __KERNEL__
20
21
22
23
24#define current_text_addr() ({ void *pc; __asm__("basr %0,0":"=a"(pc)); pc; })
25
26
27
28
29
30
31
32typedef struct
33{
34 unsigned int version : 8;
35 unsigned int ident : 24;
36 unsigned int machine : 16;
37 unsigned int unused : 16;
38} __attribute__ ((packed)) cpuid_t;
39
40struct cpuinfo_S390
41{
42 cpuid_t cpu_id;
43 unsigned long loops_per_jiffy;
44 unsigned long *pgd_quick;
45 unsigned long *pmd_quick;
46 unsigned long *pte_quick;
47 unsigned long pgtable_cache_sz;
48 __u16 cpu_addr;
49 __u16 cpu_nr;
50 __u16 pad[2];
51};
52
53extern void print_cpu_info(struct cpuinfo_S390 *);
54
55extern void show_trace(unsigned long* esp);
56
57
58extern struct task_struct *last_task_used_math;
59
60#define S390_FLAG_31BIT 0x01UL
61
62
63
64
65#define TASK_SIZE (0x20000000000UL)
66#define TASK31_SIZE (0x80000000UL)
67
68
69
70
71#define TASK_UNMAPPED_BASE ((current->thread.flags & S390_FLAG_31BIT) ? \
72 (TASK31_SIZE / 2) : (TASK_SIZE / 2))
73
74#define THREAD_SIZE (4*PAGE_SIZE)
75
76typedef struct {
77 __u32 ar4;
78} mm_segment_t;
79
80
81
82
83
84struct thread_struct
85 {
86 s390_fp_regs fp_regs;
87 __u32 ar2;
88 __u32 ar4;
89 addr_t ksp;
90 addr_t user_seg;
91 addr_t prot_addr;
92 __u32 error_code;
93 __u32 trap_no;
94 per_struct per_info;
95
96 addr_t ieee_instruction_pointer;
97 unsigned long flags;
98
99 addr_t pfault_wait;
100};
101
102typedef struct thread_struct thread_struct;
103
104#define INIT_THREAD {{0,{{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}, \
105 {0},{0},{0},{0},{0},{0}}}, \
106 0, 0, \
107 sizeof(init_stack) + (addr_t) &init_stack, \
108 (__pa((addr_t) &swapper_pg_dir[0]) + _REGION_TABLE),\
109 0,0,0, \
110 (per_struct) {{{{0,}}},0,0,0,0,{{0,}}}, \
111 0, 0, 0 \
112}
113
114
115#define start_thread(regs, new_psw, new_stackp) do { \
116 regs->psw.mask = _USER_PSW_MASK; \
117 regs->psw.addr = new_psw; \
118 regs->gprs[15] = new_stackp; \
119} while (0)
120
121#define start_thread31(regs, new_psw, new_stackp) do { \
122 regs->psw.mask = _USER_PSW_MASK & ~(1L << 32); \
123 regs->psw.addr = new_psw; \
124 regs->gprs[15] = new_stackp; \
125} while (0)
126
127
128
129struct mm_struct;
130
131
132extern void release_thread(struct task_struct *);
133extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
134
135
136#define copy_segments(nr, mm) do { } while (0)
137#define release_segments(mm) do { } while (0)
138
139
140
141
142
143
144
145
146
147extern inline unsigned long thread_saved_pc(struct thread_struct *t)
148{
149 unsigned long bc;
150 bc = *((unsigned long *) t->ksp);
151 return *((unsigned long *) (bc+112));
152}
153
154unsigned long get_wchan(struct task_struct *p);
155#define __KSTK_PTREGS(tsk) ((struct pt_regs *) \
156 (((unsigned long) tsk + THREAD_SIZE - sizeof(struct pt_regs)) & -8L))
157#define KSTK_EIP(tsk) (__KSTK_PTREGS(tsk)->psw.addr)
158#define KSTK_ESP(tsk) (__KSTK_PTREGS(tsk)->gprs[15])
159
160
161extern struct task_struct *alloc_task_struct(void);
162extern void free_task_struct(struct task_struct *tsk);
163extern void get_task_struct(struct task_struct *tsk);
164
165#define init_task (init_task_union.task)
166#define init_stack (init_task_union.stack)
167
168#define cpu_relax() do { } while (0)
169
170
171
172
173
174#define PSW_MASK_DEBUGCHANGE 0x0000300000000000UL
175
176#define PSW_ADDR_DEBUGCHANGE 0xFFFFFFFFFFFFFFFFUL
177#define PSW_ADDR_MASK 0xFFFFFFFFFFFFFFFFUL
178
179#define PSW_PER_MASK 0x4000000000000000UL
180#define USER_STD_MASK 0x0000000000000080UL
181#define PSW_PROBLEM_STATE 0x0001000000000000UL
182
183
184
185
186
187
188static inline void __load_psw_mask (unsigned long mask)
189{
190 unsigned long addr;
191
192 psw_t psw;
193 psw.mask = mask;
194
195 asm volatile (
196 " larl %0,1f\n"
197 " stg %0,8(%1)\n"
198 " lpswe 0(%1)\n"
199 "1:"
200 : "=&d" (addr) : "a" (&psw) : "memory", "cc" );
201}
202
203
204
205
206static inline void enabled_wait(void)
207{
208 unsigned long reg;
209 psw_t wait_psw;
210
211 wait_psw.mask = 0x0706000180000000;
212 asm volatile (
213 " larl %0,0f\n"
214 " stg %0,8(%1)\n"
215 " lpswe 0(%1)\n"
216 "0:"
217 : "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" );
218}
219
220
221
222
223
224static inline void disabled_wait(addr_t code)
225{
226 char psw_buffer[2*sizeof(psw_t)];
227 char ctl_buf[8];
228 psw_t *dw_psw = (psw_t *)(((unsigned long) &psw_buffer+sizeof(psw_t)-1)
229 & -sizeof(psw_t));
230
231 dw_psw->mask = 0x0002000180000000;
232 dw_psw->addr = code;
233
234
235
236
237 asm volatile (" stctg 0,0,0(%1)\n"
238 " ni 4(%1),0xef\n"
239 " lctlg 0,0,0(%1)\n"
240 " lghi 1,0x1000\n"
241 " stpt 0x328(1)\n"
242 " stckc 0x330(1)\n"
243 " stpx 0x318(1)\n"
244 " stam 0,15,0x340(1)\n"
245 " stfpc 0x31c(1)\n"
246 " std 0,0x200(1)\n"
247 " std 1,0x208(1)\n"
248 " std 2,0x210(1)\n"
249 " std 3,0x218(1)\n"
250 " std 4,0x220(1)\n"
251 " std 5,0x228(1)\n"
252 " std 6,0x230(1)\n"
253 " std 7,0x238(1)\n"
254 " std 8,0x240(1)\n"
255 " std 9,0x248(1)\n"
256 " std 10,0x250(1)\n"
257 " std 11,0x258(1)\n"
258 " std 12,0x260(1)\n"
259 " std 13,0x268(1)\n"
260 " std 14,0x270(1)\n"
261 " std 15,0x278(1)\n"
262 " stmg 0,15,0x280(1)\n"
263 " stctg 0,15,0x380(1)\n"
264 " oi 0x384(1),0x10\n"
265 " lpswe 0(%0)"
266 : : "a" (dw_psw), "a" (&ctl_buf) : "cc", "0", "1");
267}
268
269#endif
270
271#endif
272
273