Subversion Repositories HelenOS

Rev

Rev 1821 | Rev 1829 | Go to most recent revision | 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 <config.h>
  42.  
  43. extern uint32_t interrupt_handler_size;
  44.  
  45. extern void interrupt_handlers(void);
  46.  
  47. extern void enable_l_apic_in_msr(void);
  48.  
  49.  
  50. extern void asm_delay_loop(uint32_t t);
  51. extern void asm_fake_loop(uint32_t t);
  52.  
  53.  
  54. /** Halt CPU
  55.  *
  56.  * Halt the current CPU until interrupt event.
  57.  */
  58. #define cpu_halt() ((void) 0)
  59. #define cpu_sleep() ((void) 0)
  60.  
  61. #define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \
  62.     { \
  63.     unative_t res; \
  64.     __asm__ volatile ("movl %%" #reg ", %0" : "=r" (res) ); \
  65.     return res; \
  66.     }
  67.  
  68. #define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \
  69.     { \
  70.     __asm__ volatile ("movl %0, %%" #reg : : "r" (regn)); \
  71.     }
  72.  
  73. GEN_READ_REG(cr0);
  74. GEN_READ_REG(cr2);
  75.  
  76. GEN_READ_REG(dr0);
  77. GEN_READ_REG(dr1);
  78. GEN_READ_REG(dr2);
  79. GEN_READ_REG(dr3);
  80. GEN_READ_REG(dr6);
  81. GEN_READ_REG(dr7);
  82.  
  83. GEN_WRITE_REG(dr0);
  84. GEN_WRITE_REG(dr1);
  85. GEN_WRITE_REG(dr2);
  86. GEN_WRITE_REG(dr3);
  87. GEN_WRITE_REG(dr6);
  88. GEN_WRITE_REG(dr7);
  89.  
  90. /** Byte to port
  91.  *
  92.  * Output byte to port
  93.  *
  94.  * @param port Port to write to
  95.  * @param val Value to write
  96.  */
  97. static inline void outb(uint16_t port, uint8_t val) { __asm__ volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port) ); }
  98.  
  99. /** Word to port
  100.  *
  101.  * Output word to port
  102.  *
  103.  * @param port Port to write to
  104.  * @param val Value to write
  105.  */
  106. static inline void outw(uint16_t port, uint16_t val) { __asm__ volatile ("outw %w0, %w1\n" : : "a" (val), "d" (port) ); }
  107.  
  108. /** Double word to port
  109.  *
  110.  * Output double word to port
  111.  *
  112.  * @param port Port to write to
  113.  * @param val Value to write
  114.  */
  115. static inline void outl(uint16_t port, uint32_t val) { __asm__ volatile ("outl %l0, %w1\n" : : "a" (val), "d" (port) ); }
  116.  
  117. /** Byte from port
  118.  *
  119.  * Get byte from port
  120.  *
  121.  * @param port Port to read from
  122.  * @return Value read
  123.  */
  124. static inline uint8_t inb(uint16_t port) { uint8_t val; __asm__ volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port) ); return val; }
  125.  
  126. /** Word from port
  127.  *
  128.  * Get word from port
  129.  *
  130.  * @param port Port to read from
  131.  * @return Value read
  132.  */
  133. static inline uint16_t inw(uint16_t port) { uint16_t val; __asm__ volatile ("inw %w1, %w0 \n" : "=a" (val) : "d" (port) ); return val; }
  134.  
  135. /** Double word from port
  136.  *
  137.  * Get double word from port
  138.  *
  139.  * @param port Port to read from
  140.  * @return Value read
  141.  */
  142. static inline uint32_t inl(uint16_t port) { uint32_t val; __asm__ volatile ("inl %w1, %l0 \n" : "=a" (val) : "d" (port) ); return val; }
  143.  
  144. /** Enable interrupts.
  145.  *
  146.  * Enable interrupts and return previous
  147.  * value of EFLAGS.
  148.  *
  149.  * @return Old interrupt priority level.
  150.  */
  151. static inline ipl_t interrupts_enable(void)
  152. {
  153.     ipl_t v = 0;
  154. /*  __asm__ volatile (
  155.         "pushf\n\t"
  156.         "popl %0\n\t"
  157.         "sti\n"
  158.         : "=r" (v)
  159.     );*/
  160.     return v;
  161. }
  162.  
  163. /** Disable interrupts.
  164.  *
  165.  * Disable interrupts and return previous
  166.  * value of EFLAGS.
  167.  *
  168.  * @return Old interrupt priority level.
  169.  */
  170. static inline ipl_t interrupts_disable(void)
  171. {
  172.     ipl_t v = 0;
  173. /*  __asm__ volatile (
  174.         "pushf\n\t"
  175.         "popl %0\n\t"
  176.         "cli\n"
  177.         : "=r" (v)
  178.     );*/
  179.     return v;
  180. }
  181.  
  182. /** Restore interrupt priority level.
  183.  *
  184.  * Restore EFLAGS.
  185.  *
  186.  * @param ipl Saved interrupt priority level.
  187.  */
  188. static inline void interrupts_restore(ipl_t ipl)
  189. {
  190. /*  __asm__ volatile (
  191.         "pushl %0\n\t"
  192.         "popf\n"
  193.         : : "r" (ipl)
  194.     );*/
  195. }
  196.  
  197. /** Return interrupt priority level.
  198.  *
  199.  * @return EFLAFS.
  200.  */
  201. static inline ipl_t interrupts_read(void)
  202. {
  203.     ipl_t v = 0;
  204. /*  __asm__ volatile (
  205.         "pushf\n\t"
  206.         "popl %0\n"
  207.         : "=r" (v)
  208.     );*/
  209.     return v;
  210. }
  211.  
  212. /** Return base address of current stack
  213.  *
  214.  * Return the base address of the current stack.
  215.  * The stack is assumed to be STACK_SIZE bytes long.
  216.  * The stack must start on page boundary.
  217.  */
  218. static inline uintptr_t get_stack_base(void)
  219. {
  220.     uintptr_t v;
  221.    
  222.     __asm__ volatile ("andl %%esp, %0\n" : "=r" (v) : "0" (~(STACK_SIZE-1)));
  223.    
  224.     return v;
  225. }
  226.  
  227. static inline uint64_t rdtsc(void)
  228. {
  229.     uint64_t v;
  230.    
  231.     __asm__ volatile("rdtsc\n" : "=A" (v));
  232.    
  233.     return v;
  234. }
  235.  
  236. /** Return current IP address */
  237. static inline uintptr_t * get_ip()
  238. {
  239.     uintptr_t *ip;
  240.  
  241.     __asm__ volatile (
  242.         "mov %%eip, %0"
  243.         : "=r" (ip)
  244.         );
  245.     return ip;
  246. }
  247.  
  248. /** Invalidate TLB Entry.
  249.  *
  250.  * @param addr Address on a page whose TLB entry is to be invalidated.
  251.  */
  252. static inline void invlpg(uintptr_t addr)
  253. {
  254.     __asm__ volatile ("invlpg %0\n" :: "m" (*(unative_t *)addr));
  255. }
  256.  
  257. /** Load GDTR register from memory.
  258.  *
  259.  * @param gdtr_reg Address of memory from where to load GDTR.
  260.  */
  261. static inline void gdtr_load(ptr_16_32_t *gdtr_reg)
  262. {
  263.     __asm__ volatile ("lgdtl %0\n" : : "m" (*gdtr_reg));
  264. }
  265.  
  266. /** Store GDTR register to memory.
  267.  *
  268.  * @param gdtr_reg Address of memory to where to load GDTR.
  269.  */
  270. static inline void gdtr_store(ptr_16_32_t *gdtr_reg)
  271. {
  272.     __asm__ volatile ("sgdtl %0\n" : : "m" (*gdtr_reg));
  273. }
  274.  
  275. /** Load IDTR register from memory.
  276.  *
  277.  * @param idtr_reg Address of memory from where to load IDTR.
  278.  */
  279. static inline void idtr_load(ptr_16_32_t *idtr_reg)
  280. {
  281.     __asm__ volatile ("lidtl %0\n" : : "m" (*idtr_reg));
  282. }
  283.  
  284. /** Load TR from descriptor table.
  285.  *
  286.  * @param sel Selector specifying descriptor of TSS segment.
  287.  */
  288. static inline void tr_load(uint16_t sel)
  289. {
  290.     __asm__ volatile ("ltr %0" : : "r" (sel));
  291. }
  292.  
  293. #endif
  294.  
  295. /** @}
  296.  */
  297.