1 /* 2 * Special handling for the MS-DOS derivative: syslinux_ldlinux 3 * is a "far" object... 4 */ 5 6 #define _XOPEN_SOURCE 500 /* Required on glibc 2.x */ 7 #define _BSD_SOURCE 8 /* glibc 2.20 deprecates _BSD_SOURCE in favour of _DEFAULT_SOURCE */ 9 #define _DEFAULT_SOURCE 1 10 #include <inttypes.h> 11 #include <string.h> 12 #include <stddef.h> 13 #include <stdlib.h> 14 15 #include "syslxint.h" 16 #include "mystuff.h" 17 18 static inline void *set_fs_sl(const void *p) 19 { 20 uint16_t seg; 21 22 seg = ds() + ((size_t) p >> 4); 23 set_fs(seg); 24 return (void *)((size_t) p & 0xf); 25 } 26 27 #if 0 /* unused */ 28 uint8_t get_8_sl(const uint8_t * p) 29 { 30 uint8_t v; 31 32 p = set_fs_sl(p); 33 asm volatile("movb %%fs:%1,%0":"=q" (v):"m"(*p)); 34 return v; 35 } 36 #endif 37 38 uint16_t get_16_sl(const uint16_t * p) 39 { 40 uint16_t v; 41 42 p = set_fs_sl(p); 43 asm volatile("movw %%fs:%1,%0":"=r" (v):"m"(*p)); 44 return v; 45 } 46 47 uint32_t get_32_sl(const uint32_t * p) 48 { 49 uint32_t v; 50 51 p = set_fs_sl(p); 52 asm volatile("movl %%fs:%1,%0":"=r" (v):"m"(*p)); 53 return v; 54 } 55 56 #if 0 /* unused */ 57 uint64_t get_64_sl(const uint64_t * p) 58 { 59 uint32_t v0, v1; 60 const uint32_t *pp = (const uint32_t *)set_fs_sl(p); 61 62 asm volatile("movl %%fs:%1,%0" : "=r" (v0) : "m" (pp[0])); 63 asm volatile("movl %%fs:%1,%0" : "=r" (v1) : "m" (pp[1])); 64 return v0 + ((uint64_t)v1 << 32); 65 } 66 #endif 67 68 #if 0 /* unused */ 69 void set_8_sl(uint8_t * p, uint8_t v) 70 { 71 p = set_fs_sl(p); 72 asm volatile("movb %1,%%fs:%0":"=m" (*p):"qi"(v)); 73 } 74 #endif 75 76 void set_16_sl(uint16_t * p, uint16_t v) 77 { 78 p = set_fs_sl(p); 79 asm volatile("movw %1,%%fs:%0":"=m" (*p):"ri"(v)); 80 } 81 82 void set_32_sl(uint32_t * p, uint32_t v) 83 { 84 p = set_fs_sl(p); 85 asm volatile("movl %1,%%fs:%0":"=m" (*p):"ri"(v)); 86 } 87 88 void set_64_sl(uint64_t * p, uint64_t v) 89 { 90 uint32_t *pp = (uint32_t *)set_fs_sl(p); 91 asm volatile("movl %1,%%fs:%0" : "=m" (pp[0]) : "ri"((uint32_t)v)); 92 asm volatile("movl %1,%%fs:%0" : "=m" (pp[1]) : "ri"((uint32_t)(v >> 32))); 93 } 94 95 void memcpy_to_sl(void *dst, const void *src, size_t len) 96 { 97 uint16_t seg; 98 uint16_t off; 99 100 seg = ds() + ((size_t)dst >> 4); 101 off = (size_t)dst & 15; 102 103 asm volatile("pushw %%es ; " 104 "movw %3,%%es ; " 105 "rep ; movsb ; " 106 "popw %%es" 107 : "+D" (off), "+S" (src), "+c" (len) 108 : "r" (seg) 109 : "memory"); 110 } 111 112 void memcpy_from_sl(void *dst, const void *src, size_t len) 113 { 114 uint16_t seg; 115 uint16_t off; 116 117 seg = ds() + ((size_t)src >> 4); 118 off = (size_t)src & 15; 119 120 asm volatile("pushw %%ds ; " 121 "movw %3,%%ds ; " 122 "rep ; movsb ; " 123 "popw %%ds" 124 : "+D" (dst), "+S" (off), "+c" (len) 125 : "r" (seg) 126 : "memory"); 127 } 128 129 void memset_sl(void *dst, int c, size_t len) 130 { 131 uint16_t seg; 132 uint16_t off; 133 134 seg = ds() + ((size_t)dst >> 4); 135 off = (size_t)dst & 15; 136 137 asm volatile("pushw %%es ; " 138 "movw %3,%%es ; " 139 "rep ; stosb ; " 140 "popw %%es" 141 : "+D" (off), "+c" (len) 142 : "a" (c), "r" (seg) 143 : "memory"); 144 } 145