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
18static 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 */
28uint8_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
38uint16_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
47uint32_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 */
57uint64_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 */
69void 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
76void 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
82void 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
88void 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
95void 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
112void 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
129void 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