summaryrefslogtreecommitdiff
path: root/dos/getsetsl.c
blob: 267a0816f7e400f7fe9a210978ff761866d20f5d (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
/*
 * 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"

#define __noinline __attribute__((noinline))

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

    p = set_fs(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(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(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(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(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(p);
    asm volatile("movw %1,%%fs:%0":"=m" (*p):"ri"(v));
}

void set_32_sl(uint32_t * p, uint32_t v)
{
    p = set_fs(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(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");
}