kvm tools: Add ivshmem device
[linux-2.6/next.git] / tools / kvm / bios / e820.c
blob1eafb5b357e544267c76bbecbe92ddc766a04c4f
1 #include "kvm/e820.h"
3 #include "kvm/segment.h"
4 #include "kvm/bios.h"
5 #include "kvm/util.h"
7 #include <asm/processor-flags.h>
8 #include <asm/e820.h>
10 static inline void set_fs(u16 seg)
12 asm volatile("movw %0,%%fs" : : "rm" (seg));
15 static inline u8 rdfs8(unsigned long addr)
17 u8 v;
19 asm volatile("addr32 movb %%fs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr));
21 return v;
24 static inline u32 rdfs32(unsigned long addr)
26 u32 v;
28 asm volatile("addr32 movl %%fs:%1,%0" : "=q" (v) : "m" (*(u32 *)addr));
30 return v;
33 bioscall void e820_query_map(struct biosregs *regs)
35 struct e820map *e820;
36 u32 map_size;
37 u16 fs_seg;
38 u32 ndx;
40 e820 = (struct e820map *)E820_MAP_START;
41 fs_seg = flat_to_seg16(E820_MAP_START);
42 set_fs(fs_seg);
44 ndx = regs->ebx;
46 map_size = rdfs32(flat_to_off16((u32)&e820->nr_map, fs_seg));
48 if (ndx < map_size) {
49 u32 start;
50 unsigned int i;
51 u8 *p;
53 fs_seg = flat_to_seg16(E820_MAP_START);
54 set_fs(fs_seg);
56 start = (u32)&e820->map[ndx];
58 p = (void *) regs->edi;
60 for (i = 0; i < sizeof(struct e820entry); i++)
61 *p++ = rdfs8(flat_to_off16(start + i, fs_seg));
64 regs->eax = SMAP;
65 regs->ecx = sizeof(struct e820entry);
66 regs->ebx = ++ndx;
68 /* Clear CF to indicate success. */
69 regs->eflags &= ~X86_EFLAGS_CF;
71 if (ndx >= map_size)
72 regs->ebx = 0; /* end of map */