source: mainline/kernel/arch/ia64/include/asm.h@ d8db519

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since d8db519 was d8db519, checked in by Martin Decky <martin@…>, 14 years ago

update syscall prototypes
cleanup includes

  • Property mode set to 100644
File size: 8.9 KB
RevLine 
[361635c]1/*
[df4ed85]2 * Copyright (c) 2005 Jakub Jermar
[361635c]3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
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
15 * derived from this software without specific prior written permission.
16 *
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
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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
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
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
[5bda2f3e]29/** @addtogroup ia64
[b45c443]30 * @{
31 */
32/** @file
33 */
34
[06e1e95]35#ifndef KERN_ia64_ASM_H_
36#define KERN_ia64_ASM_H_
[361635c]37
38#include <config.h>
[c22e964]39#include <typedefs.h>
[0259524]40#include <arch/register.h>
[7a0359b]41#include <trace.h>
[361635c]42
[5bda2f3e]43#define IA64_IOSPACE_ADDRESS 0xE001000000000000ULL
[2a06e2f]44
[86a34d3e]45#define IO_SPACE_BOUNDARY ((void *) (64 * 1024))
46
[7a0359b]47NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
[2a06e2f]48{
[86a34d3e]49 if (port < (ioport8_t *) IO_SPACE_BOUNDARY) {
50 uintptr_t prt = (uintptr_t) port;
[5bda2f3e]51
[86a34d3e]52 *((ioport8_t *) (IA64_IOSPACE_ADDRESS +
53 ((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
54 } else {
55 *port = v;
56 }
[5bda2f3e]57
58 asm volatile (
59 "mf\n"
60 ::: "memory"
61 );
[2a06e2f]62}
63
[7a0359b]64NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
[756f475]65{
[86a34d3e]66 if (port < (ioport16_t *) IO_SPACE_BOUNDARY) {
67 uintptr_t prt = (uintptr_t) port;
[5bda2f3e]68
[86a34d3e]69 *((ioport16_t *) (IA64_IOSPACE_ADDRESS +
70 ((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
71 } else {
72 *port = v;
73 }
[5bda2f3e]74
75 asm volatile (
76 "mf\n"
77 ::: "memory"
78 );
[756f475]79}
80
[7a0359b]81NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
[756f475]82{
[86a34d3e]83 if (port < (ioport32_t *) IO_SPACE_BOUNDARY) {
84 uintptr_t prt = (uintptr_t) port;
[5bda2f3e]85
[86a34d3e]86 *((ioport32_t *) (IA64_IOSPACE_ADDRESS +
87 ((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
88 } else {
89 *port = v;
90 }
[5bda2f3e]91
92 asm volatile (
93 "mf\n"
94 ::: "memory"
95 );
[756f475]96}
97
[7a0359b]98NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
[2a06e2f]99{
[86a34d3e]100 uint8_t v;
101
[5bda2f3e]102 asm volatile (
103 "mf\n"
104 ::: "memory"
105 );
[86a34d3e]106
107 if (port < (ioport8_t *) IO_SPACE_BOUNDARY) {
108 uintptr_t prt = (uintptr_t) port;
109
110 v = *((ioport8_t *) (IA64_IOSPACE_ADDRESS +
111 ((prt & 0xfff) | ((prt >> 2) << 12))));
112 } else {
113 v = *port;
114 }
[5bda2f3e]115
[86a34d3e]116 return v;
[756f475]117}
118
[7a0359b]119NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
[756f475]120{
[86a34d3e]121 uint16_t v;
122
[5bda2f3e]123 asm volatile (
124 "mf\n"
125 ::: "memory"
126 );
[86a34d3e]127
128 if (port < (ioport16_t *) IO_SPACE_BOUNDARY) {
129 uintptr_t prt = (uintptr_t) port;
130
131 v = *((ioport16_t *) (IA64_IOSPACE_ADDRESS +
132 ((prt & 0xfff) | ((prt >> 2) << 12))));
133 } else {
134 v = *port;
135 }
[5bda2f3e]136
[86a34d3e]137 return v;
[756f475]138}
139
[7a0359b]140NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
[756f475]141{
[86a34d3e]142 uint32_t v;
[5bda2f3e]143
144 asm volatile (
145 "mf\n"
146 ::: "memory"
147 );
148
[86a34d3e]149 if (port < (ioport32_t *) IO_SPACE_BOUNDARY) {
150 uintptr_t prt = (uintptr_t) port;
151
152 v = *((ioport32_t *) (IA64_IOSPACE_ADDRESS +
153 ((prt & 0xfff) | ((prt >> 2) << 12))));
154 } else {
155 v = *port;
156 }
157
158 return v;
[2a06e2f]159}
160
[2f23341]161/** Return base address of current memory stack.
[7a0359b]162 *
[2f23341]163 * The memory stack is assumed to be STACK_SIZE / 2 long. Note that there is
164 * also the RSE stack, which takes up the upper half of STACK_SIZE.
165 * The memory stack must start on page boundary.
[1fbbcd6]166 */
[7a0359b]167NO_TRACE static inline uintptr_t get_stack_base(void)
[361635c]168{
[26aafe8]169 uint64_t value;
[1fbbcd6]170
[5bda2f3e]171 asm volatile (
172 "mov %[value] = r12"
[26aafe8]173 : [value] "=r" (value)
[5bda2f3e]174 );
175
[2f23341]176 return (value & (~(STACK_SIZE / 2 - 1)));
[361635c]177}
178
[b994a60]179/** Return Processor State Register.
180 *
181 * @return PSR.
[7a0359b]182 *
[b994a60]183 */
[7a0359b]184NO_TRACE static inline uint64_t psr_read(void)
[b994a60]185{
[7f1c620]186 uint64_t v;
[b994a60]187
[5bda2f3e]188 asm volatile (
189 "mov %[value] = psr\n"
190 : [value] "=r" (v)
191 );
[b994a60]192
193 return v;
194}
195
[e2ec980f]196/** Read IVA (Interruption Vector Address).
197 *
198 * @return Return location of interruption vector table.
[7a0359b]199 *
[e2ec980f]200 */
[7a0359b]201NO_TRACE static inline uint64_t iva_read(void)
[e2ec980f]202{
[7f1c620]203 uint64_t v;
[e2ec980f]204
[5bda2f3e]205 asm volatile (
206 "mov %[value] = cr.iva\n"
207 : [value] "=r" (v)
208 );
[e2ec980f]209
210 return v;
211}
212
213/** Write IVA (Interruption Vector Address) register.
214 *
[abbc16e]215 * @param v New location of interruption vector table.
[7a0359b]216 *
[e2ec980f]217 */
[7a0359b]218NO_TRACE static inline void iva_write(uint64_t v)
[e2ec980f]219{
[5bda2f3e]220 asm volatile (
221 "mov cr.iva = %[value]\n"
222 :: [value] "r" (v)
223 );
[e2ec980f]224}
225
[0259524]226/** Read IVR (External Interrupt Vector Register).
[dbd1059]227 *
[7a0359b]228 * @return Highest priority, pending, unmasked external
229 * interrupt vector.
230 *
[dbd1059]231 */
[7a0359b]232NO_TRACE static inline uint64_t ivr_read(void)
[dbd1059]233{
[7f1c620]234 uint64_t v;
[dbd1059]235
[5bda2f3e]236 asm volatile (
237 "mov %[value] = cr.ivr\n"
238 : [value] "=r" (v)
239 );
[dbd1059]240
[0259524]241 return v;
242}
243
[7a0359b]244NO_TRACE static inline uint64_t cr64_read(void)
[a2a5529]245{
246 uint64_t v;
247
[5bda2f3e]248 asm volatile (
249 "mov %[value] = cr64\n"
250 : [value] "=r" (v)
251 );
[a2a5529]252
253 return v;
254}
255
[0259524]256/** Write ITC (Interval Timer Counter) register.
257 *
[abbc16e]258 * @param v New counter value.
[7a0359b]259 *
[0259524]260 */
[7a0359b]261NO_TRACE static inline void itc_write(uint64_t v)
[0259524]262{
[5bda2f3e]263 asm volatile (
264 "mov ar.itc = %[value]\n"
265 :: [value] "r" (v)
266 );
[0259524]267}
268
269/** Read ITC (Interval Timer Counter) register.
270 *
271 * @return Current counter value.
[7a0359b]272 *
[0259524]273 */
[7a0359b]274NO_TRACE static inline uint64_t itc_read(void)
[0259524]275{
[7f1c620]276 uint64_t v;
[0259524]277
[5bda2f3e]278 asm volatile (
279 "mov %[value] = ar.itc\n"
280 : [value] "=r" (v)
281 );
[0259524]282
283 return v;
284}
285
286/** Write ITM (Interval Timer Match) register.
287 *
[abbc16e]288 * @param v New match value.
[7a0359b]289 *
[0259524]290 */
[7a0359b]291NO_TRACE static inline void itm_write(uint64_t v)
[0259524]292{
[5bda2f3e]293 asm volatile (
294 "mov cr.itm = %[value]\n"
295 :: [value] "r" (v)
296 );
[0259524]297}
298
[98492e8]299/** Read ITM (Interval Timer Match) register.
300 *
301 * @return Match value.
[7a0359b]302 *
[98492e8]303 */
[7a0359b]304NO_TRACE static inline uint64_t itm_read(void)
[98492e8]305{
[7f1c620]306 uint64_t v;
[98492e8]307
[5bda2f3e]308 asm volatile (
309 "mov %[value] = cr.itm\n"
310 : [value] "=r" (v)
311 );
[98492e8]312
313 return v;
314}
315
[05d9dd89]316/** Read ITV (Interval Timer Vector) register.
317 *
318 * @return Current vector and mask bit.
[7a0359b]319 *
[05d9dd89]320 */
[7a0359b]321NO_TRACE static inline uint64_t itv_read(void)
[05d9dd89]322{
[7f1c620]323 uint64_t v;
[05d9dd89]324
[5bda2f3e]325 asm volatile (
326 "mov %[value] = cr.itv\n"
327 : [value] "=r" (v)
328 );
[05d9dd89]329
330 return v;
331}
332
[0259524]333/** Write ITV (Interval Timer Vector) register.
334 *
[abbc16e]335 * @param v New vector and mask bit.
[7a0359b]336 *
[0259524]337 */
[7a0359b]338NO_TRACE static inline void itv_write(uint64_t v)
[0259524]339{
[5bda2f3e]340 asm volatile (
341 "mov cr.itv = %[value]\n"
342 :: [value] "r" (v)
343 );
[0259524]344}
345
346/** Write EOI (End Of Interrupt) register.
347 *
[abbc16e]348 * @param v This value is ignored.
[7a0359b]349 *
[0259524]350 */
[7a0359b]351NO_TRACE static inline void eoi_write(uint64_t v)
[0259524]352{
[5bda2f3e]353 asm volatile (
354 "mov cr.eoi = %[value]\n"
355 :: [value] "r" (v)
356 );
[0259524]357}
358
359/** Read TPR (Task Priority Register).
360 *
361 * @return Current value of TPR.
[7a0359b]362 *
[0259524]363 */
[7a0359b]364NO_TRACE static inline uint64_t tpr_read(void)
[0259524]365{
[7f1c620]366 uint64_t v;
[5bda2f3e]367
368 asm volatile (
369 "mov %[value] = cr.tpr\n"
370 : [value] "=r" (v)
371 );
[0259524]372
373 return v;
[dbd1059]374}
375
[0259524]376/** Write TPR (Task Priority Register).
377 *
[abbc16e]378 * @param v New value of TPR.
[7a0359b]379 *
[0259524]380 */
[7a0359b]381NO_TRACE static inline void tpr_write(uint64_t v)
[0259524]382{
[5bda2f3e]383 asm volatile (
384 "mov cr.tpr = %[value]\n"
385 :: [value] "r" (v)
386 );
[0259524]387}
[9c0a9b3]388
[0259524]389/** Disable interrupts.
390 *
391 * Disable interrupts and return previous
392 * value of PSR.
393 *
394 * @return Old interrupt priority level.
[7a0359b]395 *
[0259524]396 */
[7a0359b]397NO_TRACE static ipl_t interrupts_disable(void)
[0259524]398{
[7f1c620]399 uint64_t v;
[0259524]400
[e7b7be3f]401 asm volatile (
[5bda2f3e]402 "mov %[value] = psr\n"
403 "rsm %[mask]\n"
404 : [value] "=r" (v)
405 : [mask] "i" (PSR_I_MASK)
[0259524]406 );
407
408 return (ipl_t) v;
409}
410
411/** Enable interrupts.
412 *
413 * Enable interrupts and return previous
414 * value of PSR.
415 *
416 * @return Old interrupt priority level.
[7a0359b]417 *
[0259524]418 */
[7a0359b]419NO_TRACE static ipl_t interrupts_enable(void)
[0259524]420{
[7f1c620]421 uint64_t v;
[0259524]422
[e7b7be3f]423 asm volatile (
[5bda2f3e]424 "mov %[value] = psr\n"
425 "ssm %[mask]\n"
[0259524]426 ";;\n"
427 "srlz.d\n"
[5bda2f3e]428 : [value] "=r" (v)
429 : [mask] "i" (PSR_I_MASK)
[0259524]430 );
431
432 return (ipl_t) v;
433}
[9c0a9b3]434
[0259524]435/** Restore interrupt priority level.
436 *
437 * Restore PSR.
438 *
439 * @param ipl Saved interrupt priority level.
[7a0359b]440 *
[0259524]441 */
[7a0359b]442NO_TRACE static inline void interrupts_restore(ipl_t ipl)
[0259524]443{
[2ccd275]444 if (ipl & PSR_I_MASK)
445 (void) interrupts_enable();
446 else
447 (void) interrupts_disable();
[0259524]448}
[9c0a9b3]449
[0259524]450/** Return interrupt priority level.
451 *
452 * @return PSR.
[7a0359b]453 *
[0259524]454 */
[7a0359b]455NO_TRACE static inline ipl_t interrupts_read(void)
[0259524]456{
[b994a60]457 return (ipl_t) psr_read();
[0259524]458}
[60f6b7c]459
[fdb8c17]460/** Check interrupts state.
461 *
462 * @return True if interrupts are disabled.
463 *
464 */
[7a0359b]465NO_TRACE static inline bool interrupts_disabled(void)
[fdb8c17]466{
[dbd5df1b]467 return !(psr_read() & PSR_I_MASK);
[fdb8c17]468}
469
[2a003d5b]470/** Disable protection key checking. */
[7a0359b]471NO_TRACE static inline void pk_disable(void)
[2a003d5b]472{
[5bda2f3e]473 asm volatile (
474 "rsm %[mask]\n"
[8b4cfb9d]475 ";;\n"
476 "srlz.d\n"
[5bda2f3e]477 :: [mask] "i" (PSR_PK_MASK)
478 );
[2a003d5b]479}
480
[82474ef]481extern void cpu_halt(void) __attribute__((noreturn));
[0259524]482extern void cpu_sleep(void);
[7f1c620]483extern void asm_delay_loop(uint32_t t);
[5e2455a]484
[8b4d6cb]485extern void switch_to_userspace(uintptr_t, uintptr_t, uintptr_t, uintptr_t,
486 uint64_t, uint64_t);
[b994a60]487
[361635c]488#endif
[b45c443]489
[06e1e95]490/** @}
[b45c443]491 */
Note: See TracBrowser for help on using the repository browser.