Subversion Repositories HelenOS

Rev

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