Subversion Repositories HelenOS

Rev

Rev 2082 | Rev 2726 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2082 Rev 2515
1
/*
1
/*
2
 * Copyright (c) 2005 Jakub Jermar
2
 * Copyright (c) 2005 Jakub Jermar
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
13
 *   documentation and/or other materials provided with the distribution.
14
 * - The name of the author may not be used to endorse or promote products
14
 * - The name of the author may not be used to endorse or promote products
15
 *   derived from this software without specific prior written permission.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
/** @addtogroup ia64   
29
/** @addtogroup ia64   
30
 * @{
30
 * @{
31
 */
31
 */
32
/** @file
32
/** @file
33
 */
33
 */
34
 
34
 
35
#ifndef KERN_ia64_ASM_H_
35
#ifndef KERN_ia64_ASM_H_
36
#define KERN_ia64_ASM_H_
36
#define KERN_ia64_ASM_H_
37
 
37
 
38
#include <config.h>
38
#include <config.h>
39
#include <arch/types.h>
39
#include <arch/types.h>
40
#include <arch/register.h>
40
#include <arch/register.h>
41
 
41
 
-
 
42
 
-
 
43
#define IA64_IOSPACE_ADDRESS 0xE0000FFFFC000000ULL
-
 
44
 
-
 
45
static inline void  outb(uint64_t port,uint8_t v)
-
 
46
{
-
 
47
    *((char *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
-
 
48
    asm volatile ("mf\n" ::: "memory");
-
 
49
}
-
 
50
 
-
 
51
 
-
 
52
static inline uint8_t inb(uint64_t port)
-
 
53
{
-
 
54
    asm volatile ("mf\n" ::: "memory");
-
 
55
    return *((char *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 ))));
-
 
56
}
-
 
57
 
-
 
58
 
-
 
59
 
42
/** Return base address of current stack
60
/** Return base address of current stack
43
 *
61
 *
44
 * Return the base address of the current stack.
62
 * Return the base address of the current stack.
45
 * The stack is assumed to be STACK_SIZE long.
63
 * The stack is assumed to be STACK_SIZE long.
46
 * The stack must start on page boundary.
64
 * The stack must start on page boundary.
47
 */
65
 */
48
static inline uintptr_t get_stack_base(void)
66
static inline uintptr_t get_stack_base(void)
49
{
67
{
50
    uint64_t v;
68
    uint64_t v;
51
 
69
 
52
    asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1)));
70
    asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1)));
53
   
71
   
54
    return v;
72
    return v;
55
}
73
}
56
 
74
 
57
/** Return Processor State Register.
75
/** Return Processor State Register.
58
 *
76
 *
59
 * @return PSR.
77
 * @return PSR.
60
 */
78
 */
61
static inline uint64_t psr_read(void)
79
static inline uint64_t psr_read(void)
62
{
80
{
63
    uint64_t v;
81
    uint64_t v;
64
   
82
   
65
    asm volatile ("mov %0 = psr\n" : "=r" (v));
83
    asm volatile ("mov %0 = psr\n" : "=r" (v));
66
   
84
   
67
    return v;
85
    return v;
68
}
86
}
69
 
87
 
70
/** Read IVA (Interruption Vector Address).
88
/** Read IVA (Interruption Vector Address).
71
 *
89
 *
72
 * @return Return location of interruption vector table.
90
 * @return Return location of interruption vector table.
73
 */
91
 */
74
static inline uint64_t iva_read(void)
92
static inline uint64_t iva_read(void)
75
{
93
{
76
    uint64_t v;
94
    uint64_t v;
77
   
95
   
78
    asm volatile ("mov %0 = cr.iva\n" : "=r" (v));
96
    asm volatile ("mov %0 = cr.iva\n" : "=r" (v));
79
   
97
   
80
    return v;
98
    return v;
81
}
99
}
82
 
100
 
83
/** Write IVA (Interruption Vector Address) register.
101
/** Write IVA (Interruption Vector Address) register.
84
 *
102
 *
85
 * @param v New location of interruption vector table.
103
 * @param v New location of interruption vector table.
86
 */
104
 */
87
static inline void iva_write(uint64_t v)
105
static inline void iva_write(uint64_t v)
88
{
106
{
89
    asm volatile ("mov cr.iva = %0\n" : : "r" (v));
107
    asm volatile ("mov cr.iva = %0\n" : : "r" (v));
90
}
108
}
91
 
109
 
92
 
110
 
93
/** Read IVR (External Interrupt Vector Register).
111
/** Read IVR (External Interrupt Vector Register).
94
 *
112
 *
95
 * @return Highest priority, pending, unmasked external interrupt vector.
113
 * @return Highest priority, pending, unmasked external interrupt vector.
96
 */
114
 */
97
static inline uint64_t ivr_read(void)
115
static inline uint64_t ivr_read(void)
98
{
116
{
99
    uint64_t v;
117
    uint64_t v;
100
   
118
   
101
    asm volatile ("mov %0 = cr.ivr\n" : "=r" (v));
119
    asm volatile ("mov %0 = cr.ivr\n" : "=r" (v));
102
   
120
   
103
    return v;
121
    return v;
104
}
122
}
105
 
123
 
106
/** Write ITC (Interval Timer Counter) register.
124
/** Write ITC (Interval Timer Counter) register.
107
 *
125
 *
108
 * @param v New counter value.
126
 * @param v New counter value.
109
 */
127
 */
110
static inline void itc_write(uint64_t v)
128
static inline void itc_write(uint64_t v)
111
{
129
{
112
    asm volatile ("mov ar.itc = %0\n" : : "r" (v));
130
    asm volatile ("mov ar.itc = %0\n" : : "r" (v));
113
}
131
}
114
 
132
 
115
/** Read ITC (Interval Timer Counter) register.
133
/** Read ITC (Interval Timer Counter) register.
116
 *
134
 *
117
 * @return Current counter value.
135
 * @return Current counter value.
118
 */
136
 */
119
static inline uint64_t itc_read(void)
137
static inline uint64_t itc_read(void)
120
{
138
{
121
    uint64_t v;
139
    uint64_t v;
122
   
140
   
123
    asm volatile ("mov %0 = ar.itc\n" : "=r" (v));
141
    asm volatile ("mov %0 = ar.itc\n" : "=r" (v));
124
   
142
   
125
    return v;
143
    return v;
126
}
144
}
127
 
145
 
128
/** Write ITM (Interval Timer Match) register.
146
/** Write ITM (Interval Timer Match) register.
129
 *
147
 *
130
 * @param v New match value.
148
 * @param v New match value.
131
 */
149
 */
132
static inline void itm_write(uint64_t v)
150
static inline void itm_write(uint64_t v)
133
{
151
{
134
    asm volatile ("mov cr.itm = %0\n" : : "r" (v));
152
    asm volatile ("mov cr.itm = %0\n" : : "r" (v));
135
}
153
}
136
 
154
 
137
/** Read ITM (Interval Timer Match) register.
155
/** Read ITM (Interval Timer Match) register.
138
 *
156
 *
139
 * @return Match value.
157
 * @return Match value.
140
 */
158
 */
141
static inline uint64_t itm_read(void)
159
static inline uint64_t itm_read(void)
142
{
160
{
143
    uint64_t v;
161
    uint64_t v;
144
   
162
   
145
    asm volatile ("mov %0 = cr.itm\n" : "=r" (v));
163
    asm volatile ("mov %0 = cr.itm\n" : "=r" (v));
146
   
164
   
147
    return v;
165
    return v;
148
}
166
}
149
 
167
 
150
/** Read ITV (Interval Timer Vector) register.
168
/** Read ITV (Interval Timer Vector) register.
151
 *
169
 *
152
 * @return Current vector and mask bit.
170
 * @return Current vector and mask bit.
153
 */
171
 */
154
static inline uint64_t itv_read(void)
172
static inline uint64_t itv_read(void)
155
{
173
{
156
    uint64_t v;
174
    uint64_t v;
157
   
175
   
158
    asm volatile ("mov %0 = cr.itv\n" : "=r" (v));
176
    asm volatile ("mov %0 = cr.itv\n" : "=r" (v));
159
   
177
   
160
    return v;
178
    return v;
161
}
179
}
162
 
180
 
163
/** Write ITV (Interval Timer Vector) register.
181
/** Write ITV (Interval Timer Vector) register.
164
 *
182
 *
165
 * @param v New vector and mask bit.
183
 * @param v New vector and mask bit.
166
 */
184
 */
167
static inline void itv_write(uint64_t v)
185
static inline void itv_write(uint64_t v)
168
{
186
{
169
    asm volatile ("mov cr.itv = %0\n" : : "r" (v));
187
    asm volatile ("mov cr.itv = %0\n" : : "r" (v));
170
}
188
}
171
 
189
 
172
/** Write EOI (End Of Interrupt) register.
190
/** Write EOI (End Of Interrupt) register.
173
 *
191
 *
174
 * @param v This value is ignored.
192
 * @param v This value is ignored.
175
 */
193
 */
176
static inline void eoi_write(uint64_t v)
194
static inline void eoi_write(uint64_t v)
177
{
195
{
178
    asm volatile ("mov cr.eoi = %0\n" : : "r" (v));
196
    asm volatile ("mov cr.eoi = %0\n" : : "r" (v));
179
}
197
}
180
 
198
 
181
/** Read TPR (Task Priority Register).
199
/** Read TPR (Task Priority Register).
182
 *
200
 *
183
 * @return Current value of TPR.
201
 * @return Current value of TPR.
184
 */
202
 */
185
static inline uint64_t tpr_read(void)
203
static inline uint64_t tpr_read(void)
186
{
204
{
187
    uint64_t v;
205
    uint64_t v;
188
 
206
 
189
    asm volatile ("mov %0 = cr.tpr\n"  : "=r" (v));
207
    asm volatile ("mov %0 = cr.tpr\n"  : "=r" (v));
190
   
208
   
191
    return v;
209
    return v;
192
}
210
}
193
 
211
 
194
/** Write TPR (Task Priority Register).
212
/** Write TPR (Task Priority Register).
195
 *
213
 *
196
 * @param v New value of TPR.
214
 * @param v New value of TPR.
197
 */
215
 */
198
static inline void tpr_write(uint64_t v)
216
static inline void tpr_write(uint64_t v)
199
{
217
{
200
    asm volatile ("mov cr.tpr = %0\n" : : "r" (v));
218
    asm volatile ("mov cr.tpr = %0\n" : : "r" (v));
201
}
219
}
202
 
220
 
203
/** Disable interrupts.
221
/** Disable interrupts.
204
 *
222
 *
205
 * Disable interrupts and return previous
223
 * Disable interrupts and return previous
206
 * value of PSR.
224
 * value of PSR.
207
 *
225
 *
208
 * @return Old interrupt priority level.
226
 * @return Old interrupt priority level.
209
 */
227
 */
210
static ipl_t interrupts_disable(void)
228
static ipl_t interrupts_disable(void)
211
{
229
{
212
    uint64_t v;
230
    uint64_t v;
213
   
231
   
214
    asm volatile (
232
    asm volatile (
215
        "mov %0 = psr\n"
233
        "mov %0 = psr\n"
216
        "rsm %1\n"
234
        "rsm %1\n"
217
        : "=r" (v)
235
        : "=r" (v)
218
        : "i" (PSR_I_MASK)
236
        : "i" (PSR_I_MASK)
219
    );
237
    );
220
   
238
   
221
    return (ipl_t) v;
239
    return (ipl_t) v;
222
}
240
}
223
 
241
 
224
/** Enable interrupts.
242
/** Enable interrupts.
225
 *
243
 *
226
 * Enable interrupts and return previous
244
 * Enable interrupts and return previous
227
 * value of PSR.
245
 * value of PSR.
228
 *
246
 *
229
 * @return Old interrupt priority level.
247
 * @return Old interrupt priority level.
230
 */
248
 */
231
static ipl_t interrupts_enable(void)
249
static ipl_t interrupts_enable(void)
232
{
250
{
233
    uint64_t v;
251
    uint64_t v;
234
   
252
   
235
    asm volatile (
253
    asm volatile (
236
        "mov %0 = psr\n"
254
        "mov %0 = psr\n"
237
        "ssm %1\n"
255
        "ssm %1\n"
238
        ";;\n"
256
        ";;\n"
239
        "srlz.d\n"
257
        "srlz.d\n"
240
        : "=r" (v)
258
        : "=r" (v)
241
        : "i" (PSR_I_MASK)
259
        : "i" (PSR_I_MASK)
242
    );
260
    );
243
   
261
   
244
    return (ipl_t) v;
262
    return (ipl_t) v;
245
}
263
}
246
 
264
 
247
/** Restore interrupt priority level.
265
/** Restore interrupt priority level.
248
 *
266
 *
249
 * Restore PSR.
267
 * Restore PSR.
250
 *
268
 *
251
 * @param ipl Saved interrupt priority level.
269
 * @param ipl Saved interrupt priority level.
252
 */
270
 */
253
static inline void interrupts_restore(ipl_t ipl)
271
static inline void interrupts_restore(ipl_t ipl)
254
{
272
{
255
    if (ipl & PSR_I_MASK)
273
    if (ipl & PSR_I_MASK)
256
        (void) interrupts_enable();
274
        (void) interrupts_enable();
257
    else
275
    else
258
        (void) interrupts_disable();
276
        (void) interrupts_disable();
259
}
277
}
260
 
278
 
261
/** Return interrupt priority level.
279
/** Return interrupt priority level.
262
 *
280
 *
263
 * @return PSR.
281
 * @return PSR.
264
 */
282
 */
265
static inline ipl_t interrupts_read(void)
283
static inline ipl_t interrupts_read(void)
266
{
284
{
267
    return (ipl_t) psr_read();
285
    return (ipl_t) psr_read();
268
}
286
}
269
 
287
 
270
/** Disable protection key checking. */
288
/** Disable protection key checking. */
271
static inline void pk_disable(void)
289
static inline void pk_disable(void)
272
{
290
{
273
    asm volatile ("rsm %0\n" : : "i" (PSR_PK_MASK));
291
    asm volatile ("rsm %0\n" : : "i" (PSR_PK_MASK));
274
}
292
}
275
 
293
 
276
extern void cpu_halt(void);
294
extern void cpu_halt(void);
277
extern void cpu_sleep(void);
295
extern void cpu_sleep(void);
278
extern void asm_delay_loop(uint32_t t);
296
extern void asm_delay_loop(uint32_t t);
279
 
297
 
280
extern void switch_to_userspace(uintptr_t entry, uintptr_t sp, uintptr_t bsp, uintptr_t uspace_uarg, uint64_t ipsr, uint64_t rsc);
298
extern void switch_to_userspace(uintptr_t entry, uintptr_t sp, uintptr_t bsp, uintptr_t uspace_uarg, uint64_t ipsr, uint64_t rsc);
281
 
299
 
282
#endif
300
#endif
283
 
301
 
284
/** @}
302
/** @}
285
 */
303
 */
286
 
304