1 // Misc utility functions.
3 // Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
5 // This file may be distributed under the terms of the GNU LGPLv3 license.
7 #include "util.h" // usleep
8 #include "bregs.h" // struct bregs
9 #include "config.h" // SEG_BIOS
10 #include "farptr.h" // GET_FARPTR
11 #include "biosvar.h" // get_ebda_seg
13 // Call a function with a specified register state. Note that on
14 // return, the interrupt enable/disable flag may be altered.
16 call16(struct bregs *callregs)
22 "calll __call16_from32\n"
24 : "+a" (callregs), "+m" (*callregs)
26 : "ebx", "ecx", "edx", "esi", "edi", "ebp", "cc", "memory");
30 call16big(struct bregs *callregs)
32 extern void __force_link_error__call16big_only_in_32bit_mode();
34 __force_link_error__call16big_only_in_32bit_mode();
37 "calll __call16big_from32\n"
38 : "+a" (callregs), "+m" (*callregs)
40 : "ebx", "ecx", "edx", "esi", "edi", "ebp", "cc", "memory");
44 __call16_int(struct bregs *callregs, u16 offset)
46 callregs->cs = SEG_BIOS;
47 callregs->ip = offset;
52 call16_simpint(int nr, u32 *eax, u32 *flags)
54 extern void __force_link_error__call16_simpint_only_in_16bit_mode();
56 __force_link_error__call16_simpint_only_in_16bit_mode();
65 : "+a"(*eax), "=r"(*flags)
70 // Switch to the extra stack in ebda and call a function.
72 stack_hop(u32 eax, u32 edx, u32 ecx, void *func)
74 extern void __force_link_error__stack_hop_only_in_16bit_mode();
76 __force_link_error__stack_hop_only_in_16bit_mode();
78 u16 ebda_seg = get_ebda_seg(), bkup_ss;
81 // Backup current %ss/%esp values.
84 // Copy ebda seg to %ds/%ss and set %esp
90 // Restore segments and stack
94 : "+a" (eax), "+d" (edx), "+c" (ecx), "=&r" (bkup_ss), "=&r" (bkup_esp)
95 : "i" (EBDA_OFFSET_TOP_STACK), "r" (ebda_seg), "m" (*(u8*)func)
100 // Sum the bytes in the specified area.
102 checksum(u8 *far_data, u32 len)
106 for (i=0; i<len; i++)
107 sum += GET_FARPTR(far_data[i]);
112 memset(void *s, int c, size_t n)
115 ((char *)s)[--n] = c;
120 memcpy_far(void *far_d1, const void *far_s1, size_t len)
126 SET_FARPTR(*d, GET_FARPTR(*s));
135 memcpy(void *d1, const void *s1, size_t len)
137 u8 *d = (u8*)d1, *s = (u8*)s1;
144 memmove(void *d, const void *s, size_t len)
147 return memcpy(d, s, len);
152 *(char*)d = *(char*)s;