aboutsummaryrefslogtreecommitdiffstats
path: root/dos/getsetsl.c
blob: c6e6ae73292c593821816c1248281c6fcb70302c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
 * Special handling for the MS-DOS derivative: syslinux_ldlinux
 * is a "far" object...
 */

#define _XOPEN_SOURCE 500	/* Required on glibc 2.x */
#define _BSD_SOURCE
/* glibc 2.20 deprecates _BSD_SOURCE in favour of _DEFAULT_SOURCE */
#define _DEFAULT_SOURCE 1
#include <inttypes.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>

#include "syslxint.h"
#include "mystuff.h"

static inline void *set_fs_sl(const void *p)
{
    uint16_t seg;

    seg = ds() + ((size_t) p >> 4);
    set_fs(seg);
    return (void *)((size_t) p & 0xf);
}

#if 0				/* unused */
uint8_t get_8_sl(const uint8_t * p)
{
    uint8_t v;

    p = set_fs_sl(p);
    asm volatile("movb %%fs:%1,%0":"=q" (v):"m"(*p));
    return v;
}
#endif

uint16_t get_16_sl(const uint16_t * p)
{
    uint16_t v;

    p = set_fs_sl(p);
    asm volatile("movw %%fs:%1,%0":"=r" (v):"m"(*p));
    return v;
}

uint32_t get_32_sl(const uint32_t * p)
{
    uint32_t v;

    p = set_fs_sl(p);
    asm volatile("movl %%fs:%1,%0":"=r" (v):"m"(*p));
    return v;
}

#if 0				/* unused */
uint64_t get_64_sl(const uint64_t * p)
{
    uint32_t v0, v1;
    const uint32_t *pp = (const uint32_t *)set_fs_sl(p);

    asm volatile("movl %%fs:%1,%0" : "=r" (v0) : "m" (pp[0]));
    asm volatile("movl %%fs:%1,%0" : "=r" (v1) : "m" (pp[1]));
    return v0 + ((uint64_t)v1 << 32);
}
#endif

#if 0				/* unused */
void set_8_sl(uint8_t * p, uint8_t v)
{
    p = set_fs_sl(p);
    asm volatile("movb %1,%%fs:%0":"=m" (*p):"qi"(v));
}
#endif

void set_16_sl(uint16_t * p, uint16_t v)
{
    p = set_fs_sl(p);
    asm volatile("movw %1,%%fs:%0":"=m" (*p):"ri"(v));
}

void set_32_sl(uint32_t * p, uint32_t v)
{
    p = set_fs_sl(p);
    asm volatile("movl %1,%%fs:%0":"=m" (*p):"ri"(v));
}

void set_64_sl(uint64_t * p, uint64_t v)
{
    uint32_t *pp = (uint32_t *)set_fs_sl(p);
    asm volatile("movl %1,%%fs:%0" : "=m" (pp[0]) : "ri"((uint32_t)v));
    asm volatile("movl %1,%%fs:%0" : "=m" (pp[1]) : "ri"((uint32_t)(v >> 32)));
}

void memcpy_to_sl(void *dst, const void *src, size_t len)
{
    uint16_t seg;
    uint16_t off;

    seg = ds() + ((size_t)dst >> 4);
    off = (size_t)dst & 15;

    asm volatile("pushw %%es ; "
		 "movw %3,%%es ; "
		 "rep ; movsb ; "
		 "popw %%es"
		 : "+D" (off), "+S" (src), "+c" (len)
		 : "r" (seg)
		 : "memory");
}

void memcpy_from_sl(void *dst, const void *src, size_t len)
{
    uint16_t seg;
    uint16_t off;

    seg = ds() + ((size_t)src >> 4);
    off = (size_t)src & 15;

    asm volatile("pushw %%ds ; "
		 "movw %3,%%ds ; "
		 "rep ; movsb ; "
		 "popw %%ds"
		 : "+D" (dst), "+S" (off), "+c" (len)
		 : "r" (seg)
		 : "memory");
}

void memset_sl(void *dst, int c, size_t len)
{
    uint16_t seg;
    uint16_t off;

    seg = ds() + ((size_t)dst >> 4);
    off = (size_t)dst & 15;

    asm volatile("pushw %%es ; "
		 "movw %3,%%es ; "
		 "rep ; stosb ; "
		 "popw %%es"
		 : "+D" (off), "+c" (len)
		 : "a" (c), "r" (seg)
		 : "memory");
}