Call option roms in "big real mode".
[seabios.git] / src / util.c
1 // Misc utility functions.
2 //
3 // Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
4 //
5 // This file may be distributed under the terms of the GNU GPLv3 license.
6
7 #include "util.h" // usleep
8 #include "bregs.h" // struct bregs
9 #include "config.h" // SEG_BIOS
10 #include "farptr.h" // GET_FARPTR
11
12 // Call a function with a specified register state.  Note that on
13 // return, the interrupt enable/disable flag may be altered.
14 inline void
15 call16(struct bregs *callregs)
16 {
17     asm volatile(
18 #if MODE16 == 1
19         "calll __call16\n"
20 #else
21         "calll __call16_from32\n"
22 #endif
23         : "+a" (callregs), "+m" (*callregs)
24         :
25         : "ebx", "ecx", "edx", "esi", "edi", "ebp", "cc");
26 }
27
28 inline void
29 call16big(struct bregs *callregs)
30 {
31 #if MODE16 == 1
32     extern void __force_link_error__only_in_32bit_mode();
33     __force_link_error__only_in_32bit_mode();
34 #endif
35     asm volatile(
36         "calll __call16big_from32\n"
37         : "+a" (callregs), "+m" (*callregs)
38         :
39         : "ebx", "ecx", "edx", "esi", "edi", "ebp", "cc");
40 }
41
42 inline void
43 __call16_int(struct bregs *callregs, u16 offset)
44 {
45     callregs->cs = SEG_BIOS;
46     callregs->ip = offset;
47     call16(callregs);
48 }
49
50 // Sum the bytes in the specified area.
51 u8
52 checksum(u8 *far_data, u32 len)
53 {
54     u32 i;
55     u8 sum = 0;
56     for (i=0; i<len; i++)
57         sum += GET_FARPTR(far_data[i]);
58     return sum;
59 }
60
61 void *
62 memset(void *s, int c, size_t n)
63 {
64     while (n)
65         ((char *)s)[--n] = c;
66     return s;
67 }
68
69 void *
70 memcpy_far(void *far_d1, const void *far_s1, size_t len)
71 {
72     u8 *d = far_d1;
73     u8 *s = (u8*)far_s1;
74
75     while (len--) {
76         SET_FARPTR(*d, GET_FARPTR(*s));
77         d++;
78         s++;
79     }
80
81     return far_d1;
82 }
83
84 void *
85 memcpy(void *d1, const void *s1, size_t len)
86 {
87     u8 *d = (u8*)d1, *s = (u8*)s1;
88     while (len--)
89         *d++ = *s++;
90     return d1;
91 }
92
93 void *
94 memmove(void *d, const void *s, size_t len)
95 {
96     if (s >= d)
97         return memcpy(d, s, len);
98
99     d += len-1;
100     s += len-1;
101     while (len--) {
102         *(char*)d = *(char*)s;
103         d--;
104         s--;
105     }
106
107     return d;
108 }