Subversion Repositories HelenOS

Rev

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