Subversion Repositories HelenOS

Rev

Rev 1965 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2005 Jakub Jermar
  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.  
  29. #ifndef __ia64_ASM_H__
  30. #define __ia64_ASM_H__
  31.  
  32. #include <config.h>
  33. #include <arch/types.h>
  34. #include <arch/register.h>
  35.  
  36. /** Return base address of current stack
  37.  *
  38.  * Return the base address of the current stack.
  39.  * The stack is assumed to be STACK_SIZE long.
  40.  * The stack must start on page boundary.
  41.  */
  42. static inline __address get_stack_base(void)
  43. {
  44.     __u64 v;
  45.  
  46.     __asm__ volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1)));
  47.    
  48.     return v;
  49. }
  50.  
  51. /** Return Processor State Register.
  52.  *
  53.  * @return PSR.
  54.  */
  55. static inline __u64 psr_read(void)
  56. {
  57.     __u64 v;
  58.    
  59.     __asm__ volatile ("mov %0 = psr\n" : "=r" (v));
  60.    
  61.     return v;
  62. }
  63.  
  64. /** Read IVA (Interruption Vector Address).
  65.  *
  66.  * @return Return location of interruption vector table.
  67.  */
  68. static inline __u64 iva_read(void)
  69. {
  70.     __u64 v;
  71.    
  72.     __asm__ volatile ("mov %0 = cr.iva\n" : "=r" (v));
  73.    
  74.     return v;
  75. }
  76.  
  77. /** Write IVA (Interruption Vector Address) register.
  78.  *
  79.  * @param New location of interruption vector table.
  80.  */
  81. static inline void iva_write(__u64 v)
  82. {
  83.     __asm__ volatile ("mov cr.iva = %0\n" : : "r" (v));
  84. }
  85.  
  86.  
  87. /** Read IVR (External Interrupt Vector Register).
  88.  *
  89.  * @return Highest priority, pending, unmasked external interrupt vector.
  90.  */
  91. static inline __u64 ivr_read(void)
  92. {
  93.     __u64 v;
  94.    
  95.     __asm__ volatile ("mov %0 = cr.ivr\n" : "=r" (v));
  96.    
  97.     return v;
  98. }
  99.  
  100. /** Write ITC (Interval Timer Counter) register.
  101.  *
  102.  * @param New counter value.
  103.  */
  104. static inline void itc_write(__u64 v)
  105. {
  106.     __asm__ volatile ("mov ar.itc = %0\n" : : "r" (v));
  107. }
  108.  
  109. /** Read ITC (Interval Timer Counter) register.
  110.  *
  111.  * @return Current counter value.
  112.  */
  113. static inline __u64 itc_read(void)
  114. {
  115.     __u64 v;
  116.    
  117.     __asm__ volatile ("mov %0 = ar.itc\n" : "=r" (v));
  118.    
  119.     return v;
  120. }
  121.  
  122. /** Write ITM (Interval Timer Match) register.
  123.  *
  124.  * @param New match value.
  125.  */
  126. static inline void itm_write(__u64 v)
  127. {
  128.     __asm__ volatile ("mov cr.itm = %0\n" : : "r" (v));
  129. }
  130.  
  131. /** Read ITM (Interval Timer Match) register.
  132.  *
  133.  * @return Match value.
  134.  */
  135. static inline __u64 itm_read(void)
  136. {
  137.     __u64 v;
  138.    
  139.     __asm__ volatile ("mov %0 = cr.itm\n" : "=r" (v));
  140.    
  141.     return v;
  142. }
  143.  
  144. /** Read ITV (Interval Timer Vector) register.
  145.  *
  146.  * @return Current vector and mask bit.
  147.  */
  148. static inline __u64 itv_read(void)
  149. {
  150.     __u64 v;
  151.    
  152.     __asm__ volatile ("mov %0 = cr.itv\n" : "=r" (v));
  153.    
  154.     return v;
  155. }
  156.  
  157. /** Write ITV (Interval Timer Vector) register.
  158.  *
  159.  * @param New vector and mask bit.
  160.  */
  161. static inline void itv_write(__u64 v)
  162. {
  163.     __asm__ volatile ("mov cr.itv = %0\n" : : "r" (v));
  164. }
  165.  
  166. /** Write EOI (End Of Interrupt) register.
  167.  *
  168.  * @param This value is ignored.
  169.  */
  170. static inline void eoi_write(__u64 v)
  171. {
  172.     __asm__ volatile ("mov cr.eoi = %0\n" : : "r" (v));
  173. }
  174.  
  175. /** Read TPR (Task Priority Register).
  176.  *
  177.  * @return Current value of TPR.
  178.  */
  179. static inline __u64 tpr_read(void)
  180. {
  181.     __u64 v;
  182.  
  183.     __asm__ volatile ("mov %0 = cr.tpr\n"  : "=r" (v));
  184.    
  185.     return v;
  186. }
  187.  
  188. /** Write TPR (Task Priority Register).
  189.  *
  190.  * @param New value of TPR.
  191.  */
  192. static inline void tpr_write(__u64 v)
  193. {
  194.     __asm__ volatile ("mov cr.tpr = %0\n" : : "r" (v));
  195. }
  196.  
  197. /** Disable interrupts.
  198.  *
  199.  * Disable interrupts and return previous
  200.  * value of PSR.
  201.  *
  202.  * @return Old interrupt priority level.
  203.  */
  204. static ipl_t interrupts_disable(void)
  205. {
  206.     __u64 v;
  207.    
  208.     __asm__ volatile (
  209.         "mov %0 = psr\n"
  210.         "rsm %1\n"
  211.         : "=r" (v)
  212.         : "i" (PSR_I_MASK)
  213.     );
  214.    
  215.     return (ipl_t) v;
  216. }
  217.  
  218. /** Enable interrupts.
  219.  *
  220.  * Enable interrupts and return previous
  221.  * value of PSR.
  222.  *
  223.  * @return Old interrupt priority level.
  224.  */
  225. static ipl_t interrupts_enable(void)
  226. {
  227.     __u64 v;
  228.    
  229.     __asm__ volatile (
  230.         "mov %0 = psr\n"
  231.         "ssm %1\n"
  232.         ";;\n"
  233.         "srlz.d\n"
  234.         : "=r" (v)
  235.         : "i" (PSR_I_MASK)
  236.     );
  237.    
  238.     return (ipl_t) v;
  239. }
  240.  
  241. /** Restore interrupt priority level.
  242.  *
  243.  * Restore PSR.
  244.  *
  245.  * @param ipl Saved interrupt priority level.
  246.  */
  247. static inline void interrupts_restore(ipl_t ipl)
  248. {
  249.     if (ipl & PSR_I_MASK)
  250.         (void) interrupts_enable();
  251.     else
  252.         (void) interrupts_disable();
  253. }
  254.  
  255. /** Return interrupt priority level.
  256.  *
  257.  * @return PSR.
  258.  */
  259. static inline ipl_t interrupts_read(void)
  260. {
  261.     return (ipl_t) psr_read();
  262. }
  263.  
  264. /** Disable protection key checking. */
  265. static inline void pk_disable(void)
  266. {
  267.     __asm__ volatile ("rsm %0\n" : : "i" (PSR_PK_MASK));
  268. }
  269.  
  270. extern void cpu_halt(void);
  271. extern void cpu_sleep(void);
  272. extern void asm_delay_loop(__u32 t);
  273.  
  274. extern void switch_to_userspace(__address entry, __address sp, __address bsp, __address uspace_uarg, __u64 ipsr, __u64 rsc);
  275.  
  276. #endif
  277.