Subversion Repositories HelenOS

Rev

Rev 2071 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1813 decky 1
/*
2071 jermar 2
 * Copyright (c) 2006 Martin Decky
1813 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
 
1952 jermar 29
#ifndef KERN_ia32xen_HYPERCALL_H_
30
#define KERN_ia32xen_HYPERCALL_H_
1813 decky 31
 
2089 decky 32
#ifndef __ASM__
33
#   include <arch/types.h>
34
#   include <macros.h>
35
#endif
1813 decky 36
 
2089 decky 37
#define GUEST_CMDLINE   1024
38
#define VIRT_CPUS   32
39
#define START_INFO_SIZE 1104
1817 decky 40
 
2089 decky 41
#define BOOT_OFFSET     0x0000
42
#define TEMP_STACK_SIZE 0x1000
1829 decky 43
 
2089 decky 44
#define XEN_VIRT_START  0xFC000000
45
#define XEN_CS          0xe019
1829 decky 46
 
2089 decky 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
1831 decky 59
 
2089 decky 60
#define mp_map ((pfn_t *) XEN_VIRT_START)
1831 decky 61
 
2089 decky 62
#define SIF_PRIVILEGED  (1 << 0)  /**< Privileged domain */
63
#define SIF_INITDOMAIN  (1 << 1)  /**< Iinitial control domain */
1831 decky 64
 
2089 decky 65
#define XEN_CONSOLE_VGA     0x03
66
#define XEN_CONSOLE_VESA    0x23
67
 
1829 decky 68
#define XEN_SET_TRAP_TABLE      0
1824 decky 69
#define XEN_MMU_UPDATE          1
1829 decky 70
#define XEN_SET_CALLBACKS       4
1824 decky 71
#define XEN_UPDATE_VA_MAPPING   14
1831 decky 72
#define XEN_EVENT_CHANNEL_OP    16
1830 decky 73
#define XEN_VERSION             17
1824 decky 74
#define XEN_CONSOLE_IO          18
75
#define XEN_MMUEXT_OP           26
1817 decky 76
 
77
 
1816 decky 78
/*
79
 * Commands for XEN_CONSOLE_IO
80
 */
81
#define CONSOLE_IO_WRITE    0
82
#define CONSOLE_IO_READ     1
83
 
84
 
1817 decky 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
 
1831 decky 102
#define EVTCHNOP_SEND           4
103
 
104
 
1824 decky 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
 
1817 decky 114
#define DOMID_SELF (0x7FF0U)
115
#define DOMID_IO   (0x7FF1U)
116
 
2089 decky 117
#ifndef __ASM__
1817 decky 118
 
2089 decky 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
 
1830 decky 250
#define force_evtchn_callback() ((void) xen_version(0, 0))
251
 
1813 decky 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), \
1816 decky 303
              "3" (p3)  \
1813 decky 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), \
1816 decky 322
              "4" (p4)  \
1813 decky 323
            : "memory"  \
324
        );  \
325
        ret;    \
326
    })
327
 
328
#define hypercall5(id, p1, p2, p3, p4, p5)  \
329
    ({  \
1816 decky 330
        unative_t ret, __ign1, __ign2, __ign3, __ign4, __ign5;  \
1813 decky 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), \
1816 decky 343
              "5" (p5)  \
1813 decky 344
            : "memory"  \
345
        );  \
346
        ret;    \
347
    })
348
 
349
 
1817 decky 350
static inline int xen_console_io(const unsigned int cmd, const unsigned int count, const char *str)
1813 decky 351
{
352
    return hypercall3(XEN_CONSOLE_IO, cmd, count, str);
353
}
354
 
1829 decky 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
 
1830 decky 365
static inline int xen_version(const unsigned int cmd, const void *arg)
366
{
367
    return hypercall2(XEN_VERSION, cmd, arg);
368
}
369
 
1831 decky 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
 
1813 decky 379
#endif
2089 decky 380
 
381
#endif