Subversion Repositories HelenOS

Rev

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

  1. /*
  2.  * Copyright (C) 2001-2004 Jakub Jermar
  3.  * Copyright (C) 2005 Sergey Bondari
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  *
  10.  * - Redistributions of source code must retain the above copyright
  11.  *   notice, this list of conditions and the following disclaimer.
  12.  * - Redistributions in binary form must reproduce the above copyright
  13.  *   notice, this list of conditions and the following disclaimer in the
  14.  *   documentation and/or other materials provided with the distribution.
  15.  * - The name of the author may not be used to endorse or promote products
  16.  *   derived from this software without specific prior written permission.
  17.  *
  18.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  19.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  20.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  21.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  22.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  23.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28.  */
  29.  
  30. /** @addtogroup xen32
  31.  * @{
  32.  */
  33. /** @file
  34.  */
  35.  
  36. #ifndef __xen32_ASM_H__
  37. #define __xen32_ASM_H__
  38.  
  39. #include <arch/pm.h>
  40. #include <arch/types.h>
  41. #include <arch/barrier.h>
  42. #include <config.h>
  43.  
  44. extern void enable_l_apic_in_msr(void);
  45.  
  46.  
  47. extern void asm_delay_loop(uint32_t t);
  48. extern void asm_fake_loop(uint32_t t);
  49.  
  50.  
  51. /** Halt CPU
  52.  *
  53.  * Halt the current CPU until interrupt event.
  54.  */
  55. #define cpu_halt() ((void) 0)
  56. #define cpu_sleep() ((void) 0)
  57.  
  58. #define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \
  59.     { \
  60.     unative_t res; \
  61.     __asm__ volatile ("movl %%" #reg ", %0" : "=r" (res) ); \
  62.     return res; \
  63.     }
  64.  
  65. #define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \
  66.     { \
  67.     __asm__ volatile ("movl %0, %%" #reg : : "r" (regn)); \
  68.     }
  69.  
  70. GEN_READ_REG(cr0);
  71. GEN_READ_REG(cr2);
  72.  
  73. GEN_READ_REG(dr0);
  74. GEN_READ_REG(dr1);
  75. GEN_READ_REG(dr2);
  76. GEN_READ_REG(dr3);
  77. GEN_READ_REG(dr6);
  78. GEN_READ_REG(dr7);
  79.  
  80. GEN_WRITE_REG(dr0);
  81. GEN_WRITE_REG(dr1);
  82. GEN_WRITE_REG(dr2);
  83. GEN_WRITE_REG(dr3);
  84. GEN_WRITE_REG(dr6);
  85. GEN_WRITE_REG(dr7);
  86.  
  87. /** Byte to port
  88.  *
  89.  * Output byte to port
  90.  *
  91.  * @param port Port to write to
  92.  * @param val Value to write
  93.  */
  94. static inline void outb(uint16_t port, uint8_t val) { __asm__ volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port) ); }
  95.  
  96. /** Word to port
  97.  *
  98.  * Output word to port
  99.  *
  100.  * @param port Port to write to
  101.  * @param val Value to write
  102.  */
  103. static inline void outw(uint16_t port, uint16_t val) { __asm__ volatile ("outw %w0, %w1\n" : : "a" (val), "d" (port) ); }
  104.  
  105. /** Double word to port
  106.  *
  107.  * Output double word to port
  108.  *
  109.  * @param port Port to write to
  110.  * @param val Value to write
  111.  */
  112. static inline void outl(uint16_t port, uint32_t val) { __asm__ volatile ("outl %l0, %w1\n" : : "a" (val), "d" (port) ); }
  113.  
  114. /** Byte from port
  115.  *
  116.  * Get byte from port
  117.  *
  118.  * @param port Port to read from
  119.  * @return Value read
  120.  */
  121. static inline uint8_t inb(uint16_t port) { uint8_t val; __asm__ volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port) ); return val; }
  122.  
  123. /** Word from port
  124.  *
  125.  * Get word from port
  126.  *
  127.  * @param port Port to read from
  128.  * @return Value read
  129.  */
  130. static inline uint16_t inw(uint16_t port) { uint16_t val; __asm__ volatile ("inw %w1, %w0 \n" : "=a" (val) : "d" (port) ); return val; }
  131.  
  132. /** Double word from port
  133.  *
  134.  * Get double word from port
  135.  *
  136.  * @param port Port to read from
  137.  * @return Value read
  138.  */
  139. static inline uint32_t inl(uint16_t port) { uint32_t val; __asm__ volatile ("inl %w1, %l0 \n" : "=a" (val) : "d" (port) ); return val; }
  140.  
  141. /** Enable interrupts.
  142.  *
  143.  * Enable interrupts and return previous
  144.  * value of EFLAGS.
  145.  *
  146.  * @return Old interrupt priority level.
  147.  */
  148. static inline ipl_t interrupts_enable(void)
  149. {
  150.     // FIXME SMP
  151.    
  152.     ipl_t v = shared_info.vcpu_info[0].evtchn_upcall_mask;
  153.     write_barrier();
  154.     shared_info.vcpu_info[0].evtchn_upcall_mask = 0;
  155.     write_barrier();
  156.     if (shared_info.vcpu_info[0].evtchn_upcall_pending)
  157.         force_evtchn_callback();
  158.    
  159.     return v;
  160. }
  161.  
  162. /** Disable interrupts.
  163.  *
  164.  * Disable interrupts and return previous
  165.  * value of EFLAGS.
  166.  *
  167.  * @return Old interrupt priority level.
  168.  */
  169. static inline ipl_t interrupts_disable(void)
  170. {
  171.     // FIXME SMP
  172.    
  173.     ipl_t v = shared_info.vcpu_info[0].evtchn_upcall_mask;
  174.     shared_info.vcpu_info[0].evtchn_upcall_mask = 1;
  175.     write_barrier();
  176.    
  177.     return v;
  178. }
  179.  
  180. /** Restore interrupt priority level.
  181.  *
  182.  * Restore EFLAGS.
  183.  *
  184.  * @param ipl Saved interrupt priority level.
  185.  */
  186. static inline void interrupts_restore(ipl_t ipl)
  187. {
  188.     if (ipl == 0)
  189.         interrupts_enable();
  190.     else
  191.         interrupts_disable();
  192. }
  193.  
  194. /** Return interrupt priority level.
  195.  *
  196.  * @return EFLAFS.
  197.  */
  198. static inline ipl_t interrupts_read(void)
  199. {
  200.     // FIXME SMP
  201.    
  202.     return shared_info.vcpu_info[0].evtchn_upcall_mask;
  203. }
  204.  
  205. /** Return base address of current stack
  206.  *
  207.  * Return the base address of the current stack.
  208.  * The stack is assumed to be STACK_SIZE bytes long.
  209.  * The stack must start on page boundary.
  210.  */
  211. static inline uintptr_t get_stack_base(void)
  212. {
  213.     uintptr_t v;
  214.    
  215.     __asm__ volatile ("andl %%esp, %0\n" : "=r" (v) : "0" (~(STACK_SIZE-1)));
  216.    
  217.     return v;
  218. }
  219.  
  220. static inline uint64_t rdtsc(void)
  221. {
  222.     uint64_t v;
  223.    
  224.     __asm__ volatile("rdtsc\n" : "=A" (v));
  225.    
  226.     return v;
  227. }
  228.  
  229. /** Return current IP address */
  230. static inline uintptr_t * get_ip()
  231. {
  232.     uintptr_t *ip;
  233.  
  234.     __asm__ volatile (
  235.         "mov %%eip, %0"
  236.         : "=r" (ip)
  237.         );
  238.     return ip;
  239. }
  240.  
  241. /** Invalidate TLB Entry.
  242.  *
  243.  * @param addr Address on a page whose TLB entry is to be invalidated.
  244.  */
  245. static inline void invlpg(uintptr_t addr)
  246. {
  247.     __asm__ volatile ("invlpg %0\n" :: "m" (*(unative_t *)addr));
  248. }
  249.  
  250. /** Load GDTR register from memory.
  251.  *
  252.  * @param gdtr_reg Address of memory from where to load GDTR.
  253.  */
  254. static inline void gdtr_load(ptr_16_32_t *gdtr_reg)
  255. {
  256.     __asm__ volatile ("lgdtl %0\n" : : "m" (*gdtr_reg));
  257. }
  258.  
  259. /** Store GDTR register to memory.
  260.  *
  261.  * @param gdtr_reg Address of memory to where to load GDTR.
  262.  */
  263. static inline void gdtr_store(ptr_16_32_t *gdtr_reg)
  264. {
  265.     __asm__ volatile ("sgdtl %0\n" : : "m" (*gdtr_reg));
  266. }
  267.  
  268. /** Load TR from descriptor table.
  269.  *
  270.  * @param sel Selector specifying descriptor of TSS segment.
  271.  */
  272. static inline void tr_load(uint16_t sel)
  273. {
  274.     __asm__ volatile ("ltr %0" : : "r" (sel));
  275. }
  276.  
  277. #endif
  278.  
  279. /** @}
  280.  */
  281.