Subversion Repositories HelenOS

Rev

Rev 2071 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2006 Martin Decky
  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. #ifndef KERN_ia32xen_HYPERCALL_H_
  30. #define KERN_ia32xen_HYPERCALL_H_
  31.  
  32. #ifndef __ASM__
  33. #   include <arch/types.h>
  34. #   include <macros.h>
  35. #endif
  36.  
  37. #define GUEST_CMDLINE   1024
  38. #define VIRT_CPUS   32
  39. #define START_INFO_SIZE 1104
  40.  
  41. #define BOOT_OFFSET     0x0000
  42. #define TEMP_STACK_SIZE 0x1000
  43.  
  44. #define XEN_VIRT_START  0xFC000000
  45. #define XEN_CS          0xe019
  46.  
  47. #define XEN_ELFNOTE_INFO            0
  48. #define XEN_ELFNOTE_ENTRY           1
  49. #define XEN_ELFNOTE_HYPERCALL_PAGE  2
  50. #define XEN_ELFNOTE_VIRT_BASE       3
  51. #define XEN_ELFNOTE_PADDR_OFFSET    4
  52. #define XEN_ELFNOTE_XEN_VERSION     5
  53. #define XEN_ELFNOTE_GUEST_OS        6
  54. #define XEN_ELFNOTE_GUEST_VERSION   7
  55. #define XEN_ELFNOTE_LOADER          8
  56. #define XEN_ELFNOTE_PAE_MODE        9
  57. #define XEN_ELFNOTE_FEATURES        10
  58. #define XEN_ELFNOTE_BSD_SYMTAB      11
  59.  
  60. #define mp_map ((pfn_t *) XEN_VIRT_START)
  61.  
  62. #define SIF_PRIVILEGED  (1 << 0)  /**< Privileged domain */
  63. #define SIF_INITDOMAIN  (1 << 1)  /**< Iinitial control domain */
  64.  
  65. #define XEN_CONSOLE_VGA     0x03
  66. #define XEN_CONSOLE_VESA    0x23
  67.  
  68. #define XEN_SET_TRAP_TABLE      0
  69. #define XEN_MMU_UPDATE          1
  70. #define XEN_SET_CALLBACKS       4
  71. #define XEN_UPDATE_VA_MAPPING   14
  72. #define XEN_EVENT_CHANNEL_OP    16
  73. #define XEN_VERSION             17
  74. #define XEN_CONSOLE_IO          18
  75. #define XEN_MMUEXT_OP           26
  76.  
  77.  
  78. /*
  79.  * Commands for XEN_CONSOLE_IO
  80.  */
  81. #define CONSOLE_IO_WRITE    0
  82. #define CONSOLE_IO_READ     1
  83.  
  84.  
  85. #define MMUEXT_PIN_L1_TABLE      0
  86. #define MMUEXT_PIN_L2_TABLE      1
  87. #define MMUEXT_PIN_L3_TABLE      2
  88. #define MMUEXT_PIN_L4_TABLE      3
  89. #define MMUEXT_UNPIN_TABLE       4
  90. #define MMUEXT_NEW_BASEPTR       5
  91. #define MMUEXT_TLB_FLUSH_LOCAL   6
  92. #define MMUEXT_INVLPG_LOCAL      7
  93. #define MMUEXT_TLB_FLUSH_MULTI   8
  94. #define MMUEXT_INVLPG_MULTI      9
  95. #define MMUEXT_TLB_FLUSH_ALL    10
  96. #define MMUEXT_INVLPG_ALL       11
  97. #define MMUEXT_FLUSH_CACHE      12
  98. #define MMUEXT_SET_LDT          13
  99. #define MMUEXT_NEW_USER_BASEPTR 15
  100.  
  101.  
  102. #define EVTCHNOP_SEND           4
  103.  
  104.  
  105. #define UVMF_NONE               0        /**< No flushing at all */
  106. #define UVMF_TLB_FLUSH          1        /**< Flush entire TLB(s) */
  107. #define UVMF_INVLPG             2        /**< Flush only one entry */
  108. #define UVMF_FLUSHTYPE_MASK     3
  109. #define UVMF_MULTI              0        /**< Flush subset of TLBs */
  110. #define UVMF_LOCAL              0        /**< Flush local TLB */
  111. #define UVMF_ALL                (1 << 2) /**< Flush all TLBs */
  112.  
  113.  
  114. #define DOMID_SELF (0x7FF0U)
  115. #define DOMID_IO   (0x7FF1U)
  116.  
  117. #ifndef __ASM__
  118.  
  119. typedef uint16_t domid_t;
  120. typedef uint32_t evtchn_t;
  121.  
  122. typedef struct {
  123.     uint32_t version;
  124.     uint32_t pad0;
  125.     uint64_t tsc_timestamp;   /**< TSC at last update of time vals */
  126.     uint64_t system_time;     /**< Time, in nanosecs, since boot */
  127.     uint32_t tsc_to_system_mul;
  128.     int8_t tsc_shift;
  129.     int8_t pad1[3];
  130. } vcpu_time_info_t;
  131.  
  132. typedef struct {
  133.     uint32_t cr2;
  134.     uint32_t pad[5];
  135. } arch_vcpu_info_t;
  136.  
  137. typedef struct arch_shared_info {
  138.     pfn_t max_pfn;                  /**< max pfn that appears in table */
  139.     uint32_t pfn_to_mfn_frame_list_list;
  140.     uint32_t nmi_reason;
  141. } arch_shared_info_t;
  142.  
  143. typedef struct {
  144.     uint8_t evtchn_upcall_pending;
  145.     ipl_t evtchn_upcall_mask;
  146.     evtchn_t evtchn_pending_sel;
  147.     arch_vcpu_info_t arch;
  148.     vcpu_time_info_t time;
  149. } vcpu_info_t;
  150.  
  151. typedef struct {
  152.     vcpu_info_t vcpu_info[VIRT_CPUS];
  153.     evtchn_t evtchn_pending[32];
  154.     evtchn_t evtchn_mask[32];
  155.    
  156.     uint32_t wc_version;                  /**< Version counter */
  157.     uint32_t wc_sec;                      /**< Secs  00:00:00 UTC, Jan 1, 1970 */
  158.     uint32_t wc_nsec;                     /**< Nsecs 00:00:00 UTC, Jan 1, 1970 */
  159.    
  160.     arch_shared_info_t arch;
  161. } shared_info_t;
  162.  
  163. typedef struct {
  164.     int8_t magic[32];           /**< "xen-<version>-<platform>" */
  165.     uint32_t frames;            /**< Available frames */
  166.     shared_info_t *shared_info; /**< Shared info structure (machine address) */
  167.     uint32_t flags;             /**< SIF_xxx flags */
  168.     pfn_t store_mfn;            /**< Shared page (machine page) */
  169.     evtchn_t store_evtchn;      /**< Event channel for store communication */
  170.    
  171.     union {
  172.         struct {
  173.             pfn_t mfn;          /**< Console page (machine page) */
  174.             evtchn_t evtchn;    /**< Event channel for console messages */
  175.         } domU;
  176.        
  177.         struct {
  178.             uint32_t info_off;  /**< Offset of console_info struct */
  179.             uint32_t info_size; /**< Size of console_info struct from start */
  180.         } dom0;
  181.     } console;
  182.    
  183.     pte_t *ptl0;                /**< Boot PTL0 (kernel address) */
  184.     uint32_t pt_frames;         /**< Number of bootstrap page table frames */
  185.     pfn_t *pm_map;              /**< Physical->machine frame map (kernel address) */
  186.     void *mod_start;            /**< Modules start (kernel address) */
  187.     uint32_t mod_len;           /**< Modules size (bytes) */
  188.     int8_t cmd_line[GUEST_CMDLINE];
  189. } start_info_t;
  190.  
  191. typedef struct {
  192.     uint8_t video_type;  
  193.  
  194.     union {
  195.         struct {
  196.             uint16_t font_height;
  197.             uint16_t cursor_x;
  198.             uint16_t cursor_y;
  199.             uint16_t rows;
  200.             uint16_t columns;
  201.         } vga;
  202.  
  203.         struct {
  204.             uint16_t width;
  205.             uint16_t height;
  206.             uint16_t bytes_per_line;
  207.             uint16_t bits_per_pixel;
  208.             uint32_t lfb_base;
  209.             uint32_t lfb_size;
  210.             uint8_t red_pos;
  211.             uint8_t red_size;
  212.             uint8_t green_pos;
  213.             uint8_t green_size;
  214.             uint8_t blue_pos;
  215.             uint8_t blue_size;
  216.             uint8_t rsvd_pos;
  217.             uint8_t rsvd_size;
  218.         } vesa_lfb;
  219.     } info;
  220. } console_info_t;
  221.  
  222. typedef struct {
  223.     pfn_t start;
  224.     pfn_t size;
  225.     pfn_t reserved;
  226. } memzone_t;
  227.  
  228. extern start_info_t start_info;
  229. extern shared_info_t shared_info;
  230. extern memzone_t meminfo;
  231.  
  232. typedef struct {
  233.     uint8_t vector;     /**< Exception vector */
  234.     uint8_t flags;      /**< 0-3: privilege level; 4: clear event enable */
  235.     uint16_t cs;        /**< Code selector */
  236.     void *address;      /**< Code offset */
  237. } trap_info_t;
  238.  
  239. typedef struct {
  240.     evtchn_t port;
  241. } evtchn_send_t;
  242.  
  243. typedef struct {
  244.     uint32_t cmd;
  245.     union {
  246.         evtchn_send_t send;
  247.     };
  248. } evtchn_op_t;
  249.  
  250. #define force_evtchn_callback() ((void) xen_version(0, 0))
  251.  
  252. #define hypercall0(id)  \
  253.     ({  \
  254.         unative_t ret;  \
  255.         asm volatile (  \
  256.             "call hypercall_page + (" STRING(id) " * 32)\n" \
  257.             : "=a" (ret)    \
  258.             :   \
  259.             : "memory"  \
  260.         );  \
  261.         ret;    \
  262.     })
  263.  
  264. #define hypercall1(id, p1)  \
  265.     ({  \
  266.         unative_t ret, __ign1;  \
  267.         asm volatile (  \
  268.             "call hypercall_page + (" STRING(id) " * 32)\n" \
  269.             : "=a" (ret), \
  270.               "=b" (__ign1) \
  271.             : "1" (p1)  \
  272.             : "memory"  \
  273.         );  \
  274.         ret;    \
  275.     })
  276.  
  277. #define hypercall2(id, p1, p2)  \
  278.     ({  \
  279.         unative_t ret, __ign1, __ign2;  \
  280.         asm volatile (  \
  281.             "call hypercall_page + (" STRING(id) " * 32)\n" \
  282.             : "=a" (ret), \
  283.               "=b" (__ign1),    \
  284.               "=c" (__ign2) \
  285.             : "1" (p1), \
  286.               "2" (p2)  \
  287.             : "memory"  \
  288.         );  \
  289.         ret;    \
  290.     })
  291.  
  292. #define hypercall3(id, p1, p2, p3)  \
  293.     ({  \
  294.         unative_t ret, __ign1, __ign2, __ign3;  \
  295.         asm volatile (  \
  296.             "call hypercall_page + (" STRING(id) " * 32)\n" \
  297.             : "=a" (ret), \
  298.               "=b" (__ign1),    \
  299.               "=c" (__ign2),    \
  300.               "=d" (__ign3) \
  301.             : "1" (p1), \
  302.               "2" (p2), \
  303.               "3" (p3)  \
  304.             : "memory"  \
  305.         );  \
  306.         ret;    \
  307.     })
  308.  
  309. #define hypercall4(id, p1, p2, p3, p4)  \
  310.     ({  \
  311.         unative_t ret, __ign1, __ign2, __ign3, __ign4;  \
  312.         asm volatile (  \
  313.             "call hypercall_page + (" STRING(id) " * 32)\n" \
  314.             : "=a" (ret), \
  315.               "=b" (__ign1),    \
  316.               "=c" (__ign2),    \
  317.               "=d" (__ign3),    \
  318.               "=S" (__ign4) \
  319.             : "1" (p1), \
  320.               "2" (p2), \
  321.               "3" (p3), \
  322.               "4" (p4)  \
  323.             : "memory"  \
  324.         );  \
  325.         ret;    \
  326.     })
  327.  
  328. #define hypercall5(id, p1, p2, p3, p4, p5)  \
  329.     ({  \
  330.         unative_t ret, __ign1, __ign2, __ign3, __ign4, __ign5;  \
  331.         asm volatile (  \
  332.             "call hypercall_page + (" STRING(id) " * 32)\n" \
  333.             : "=a" (ret), \
  334.               "=b" (__ign1),    \
  335.               "=c" (__ign2),    \
  336.               "=d" (__ign3),    \
  337.               "=S" (__ign4),    \
  338.               "=D" (__ign5) \
  339.             : "1" (p1), \
  340.               "2" (p2), \
  341.               "3" (p3), \
  342.               "4" (p4), \
  343.               "5" (p5)  \
  344.             : "memory"  \
  345.         );  \
  346.         ret;    \
  347.     })
  348.  
  349.  
  350. static inline int xen_console_io(const unsigned int cmd, const unsigned int count, const char *str)
  351. {
  352.     return hypercall3(XEN_CONSOLE_IO, cmd, count, str);
  353. }
  354.  
  355. static inline int xen_set_callbacks(const unsigned int event_selector, const void *event_address, const unsigned int failsafe_selector, void *failsafe_address)
  356. {
  357.     return hypercall4(XEN_SET_CALLBACKS, event_selector, event_address, failsafe_selector, failsafe_address);
  358. }
  359.  
  360. static inline int xen_set_trap_table(const trap_info_t *table)
  361. {
  362.     return hypercall1(XEN_SET_TRAP_TABLE, table);
  363. }
  364.  
  365. static inline int xen_version(const unsigned int cmd, const void *arg)
  366. {
  367.     return hypercall2(XEN_VERSION, cmd, arg);
  368. }
  369.  
  370. static inline int xen_notify_remote(evtchn_t channel)
  371. {
  372.     evtchn_op_t op;
  373.    
  374.     op.cmd = EVTCHNOP_SEND;
  375.     op.send.port = channel;
  376.     return hypercall1(XEN_EVENT_CHANNEL_OP, &op);
  377. }
  378.  
  379. #endif
  380.  
  381. #endif
  382.