aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2014-01-16 10:54:02 -0800
committerH. Peter Anvin <hpa@zytor.com>2014-01-16 10:56:29 -0800
commit1d01a26f07910da394a733421f1308830d490e94 (patch)
tree243fefe7d518fd4217879f419134c7aa9cc5d86e
parent9ab3608ba4a51e234f251d84f764f39f20e4ded3 (diff)
downloadhdt-1d01a26f07910da394a733421f1308830d490e94.tar.gz
hdt-1d01a26f07910da394a733421f1308830d490e94.tar.xz
hdt-1d01a26f07910da394a733421f1308830d490e94.zip
dos: We cannot use memset() for a far object, introduce memset_sl()
We started using memset() on the extents buffer in ldlinux.sys, which doesn't reside in the main segment, which worked on all the installer platforms except DOS. Fix DOS by introducing memset_sl() for this case. Reported-by: Ady <ady-sf@hotmail.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--dos/getsetsl.c17
-rw-r--r--libinstaller/syslxint.h2
-rw-r--r--libinstaller/syslxmod.c2
3 files changed, 20 insertions, 1 deletions
diff --git a/dos/getsetsl.c b/dos/getsetsl.c
index fadef438..5260a2a1 100644
--- a/dos/getsetsl.c
+++ b/dos/getsetsl.c
@@ -123,3 +123,20 @@ void memcpy_from_sl(void *dst, const void *src, size_t 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");
+}
diff --git a/libinstaller/syslxint.h b/libinstaller/syslxint.h
index 59e3e5ef..ce9cb209 100644
--- a/libinstaller/syslxint.h
+++ b/libinstaller/syslxint.h
@@ -134,6 +134,7 @@ void set_32_sl(uint32_t * p, uint32_t v);
void set_64_sl(uint64_t * p, uint64_t v);
void memcpy_to_sl(void *dst, const void *src, size_t len);
void memcpy_from_sl(void *dst, const void *src, size_t len);
+void memset_sl(void *dst, int c, size_t len);
#else
@@ -148,6 +149,7 @@ void memcpy_from_sl(void *dst, const void *src, size_t len);
#define set_64_sl(x,y) set_64(x,y)
#define memcpy_to_sl(d,s,l) memcpy(d,s,l)
#define memcpy_from_sl(d,s,l) memcpy(d,s,l)
+#define memset_sl(d,c,l) memset(d,c,l)
#endif
diff --git a/libinstaller/syslxmod.c b/libinstaller/syslxmod.c
index 98e2710a..197261ca 100644
--- a/libinstaller/syslxmod.c
+++ b/libinstaller/syslxmod.c
@@ -41,7 +41,7 @@ static void generate_extents(struct syslinux_extent *ex, int nptrs,
base = addr;
len = lba = 0;
- memset(ex, 0, nptrs * sizeof *ex);
+ memset_sl(ex, 0, nptrs * sizeof *ex);
while (nsect) {
sect = *sectp++;