| /* |
| * 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"); |
| } |