1 #include "asm/bios/types.h" 2 #include "kvm/e820.h" 3 4 #include "kvm/bios.h" 5 6 #include <asm/processor-flags.h> 7 flat_to_seg16(u32 address)8static inline u16 flat_to_seg16(u32 address) 9 { 10 return address >> 4; 11 } 12 flat_to_off16(u32 address,u32 segment)13static inline u16 flat_to_off16(u32 address, u32 segment) 14 { 15 return address - (segment << 4); 16 } 17 set_fs(u16 seg)18static inline void set_fs(u16 seg) 19 { 20 asm volatile("movw %0,%%fs" : : "rm" (seg)); 21 } 22 rdfs8(unsigned long addr)23static inline u8 rdfs8(unsigned long addr) 24 { 25 u8 v; 26 27 asm volatile("addr32 movb %%fs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr)); 28 29 return v; 30 } 31 rdfs32(unsigned long addr)32static inline u32 rdfs32(unsigned long addr) 33 { 34 u32 v; 35 36 asm volatile("addr32 movl %%fs:%1,%0" : "=q" (v) : "m" (*(u32 *)addr)); 37 38 return v; 39 } 40 e820_query_map(struct biosregs * regs)41bioscall void e820_query_map(struct biosregs *regs) 42 { 43 struct e820map *e820; 44 u32 map_size; 45 u16 fs_seg; 46 u32 ndx; 47 48 e820 = (struct e820map *)E820_MAP_START; 49 fs_seg = flat_to_seg16(E820_MAP_START); 50 set_fs(fs_seg); 51 52 ndx = regs->ebx; 53 54 map_size = rdfs32(flat_to_off16((u32)&e820->nr_map, fs_seg)); 55 56 if (ndx < map_size) { 57 u32 start; 58 unsigned int i; 59 u8 *p; 60 61 fs_seg = flat_to_seg16(E820_MAP_START); 62 set_fs(fs_seg); 63 64 start = (u32)&e820->map[ndx]; 65 66 p = (void *) regs->edi; 67 68 for (i = 0; i < sizeof(struct e820entry); i++) 69 *p++ = rdfs8(flat_to_off16(start + i, fs_seg)); 70 } 71 72 regs->eax = SMAP; 73 regs->ecx = sizeof(struct e820entry); 74 regs->ebx = ++ndx; 75 76 /* Clear CF to indicate success. */ 77 regs->eflags &= ~X86_EFLAGS_CF; 78 79 if (ndx >= map_size) 80 regs->ebx = 0; /* end of map */ 81 } 82