Subversion Repositories HelenOS

Rev

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