bios.o: bios/bios.bin bios/bios-rom.h
bios/bios.bin.elf: bios/entry.S bios/e820.c bios/int10.c bios/int15.c bios/rom.ld.S
+ $(E) " CC bios/memcpy.o"
+ $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/memcpy.c -o bios/memcpy.o
$(E) " CC bios/e820.o"
$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/e820.c -o bios/e820.o
$(E) " CC bios/int10.o"
$(E) " CC bios/entry.o"
$(Q) $(CC) $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/entry.S -o bios/entry.o
$(E) " LD " $@
- $(Q) ld -T bios/rom.ld.S -o bios/bios.bin.elf bios/entry.o bios/e820.o bios/int10.o bios/int15.o
+ $(Q) ld -T bios/rom.ld.S -o bios/bios.bin.elf bios/memcpy.o bios/entry.o bios/e820.o bios/int10.o bios/int15.o
bios/bios.bin: bios/bios.bin.elf
$(E) " OBJCOPY " $@
.macro SAVE_BIOSREGS
pushl %fs
pushl %es
+ pushl %ds
pushl %edi
pushl %esi
pushl %ebp
popl %ebp
popl %esi
popl %edi
+ popl %ds
popl %es
popl %fs
.endm
#include "kvm/bios.h"
#include "kvm/util.h"
#include "kvm/vesa.h"
+
+#include "bios/memcpy.h"
+
#include <stdint.h>
#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24))
static void vbe_get_info(struct biosregs *args)
{
- struct vesa_general_info *info = (struct vesa_general_info *) args->edi;
+ struct vesa_general_info *infop = (struct vesa_general_info *) args->edi;
+ struct vesa_general_info info;
- *info = (struct vesa_general_info) {
+ info = (struct vesa_general_info) {
.signature = VESA_MAGIC,
.version = 0x102,
- .vendor_string = &info->oem_string,
+ .vendor_string = &infop->oem_string,
.capabilities = 0x10,
- .video_mode_ptr = &info->modes,
+ .video_mode_ptr = &infop->modes,
.total_memory = (4 * VESA_WIDTH * VESA_HEIGHT) / 0x10000,
.oem_string = "KVM VESA",
.modes = { 0x0112, 0xffff },
};
+
+ memcpy16(args->es, infop, args->ds, &info, sizeof(info));
}
#define VBE_STATUS_OK 0x004F
--- /dev/null
+#include "bios/memcpy.h"
+
+/*
+ * Copy memory area in 16-bit real mode.
+ */
+void memcpy16(u16 dst_seg, void *dst, u16 src_seg, const void *src, size_t len)
+{
+ __asm__ __volatile__ (
+ "pushw %%ds \n"
+ "pushw %%es \n"
+ "movw %[src_seg], %%ds \n"
+ "movw %[dst_seg], %%es \n"
+ "rep movsb %%ds:(%%si), %%es:(%%di) \n"
+ "popw %%es \n"
+ "popw %%ds \n"
+ :
+ : "S"(src),
+ "D"(dst),
+ "c"(len),
+ [src_seg] "r"(src_seg),
+ [dst_seg] "r"(dst_seg)
+ : "cc", "memory");
+}
--- /dev/null
+#ifndef KVM_BIOS_MEMCPY_H
+#define KVM_BIOS_MEMCPY_H
+
+#include <linux/types.h>
+#include <stddef.h>
+
+void memcpy16(u16 dst_seg, void *dst, u16 src_seg, const void *src, size_t len);
+
+#endif /* KVM_BIOS_MEMCPY_H */
u32 ebp;
u32 esi;
u32 edi;
+ u32 ds;
u32 es;
u32 fs;
u32 eip;