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
set_fs_sl(const void * p)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
get_16_sl(const uint16_t * p)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
get_32_sl(const uint32_t * p)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
set_16_sl(uint16_t * p,uint16_t v)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
set_32_sl(uint32_t * p,uint32_t v)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
set_64_sl(uint64_t * p,uint64_t v)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
memcpy_to_sl(void * dst,const void * src,size_t len)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
memcpy_from_sl(void * dst,const void * src,size_t len)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
memset_sl(void * dst,int c,size_t len)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