blob: c4f61c5a92eb08e47b7072e1661f9a74e1e9a5a9 [file] [log] [blame]
Kevin O'Connor9521e262008-07-04 13:04:29 -04001// 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
Kevin O'Connora4d35762008-03-08 15:43:03 -05007#include "util.h" // usleep
Kevin O'Connor9521e262008-07-04 13:04:29 -04008#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.
14inline void
15call16(struct bregs *callregs)
16{
17 asm volatile(
18#ifdef MODE16
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
28inline void
29__call16_int(struct bregs *callregs, u16 offset)
30{
31 callregs->cs = SEG_BIOS;
32 callregs->ip = offset;
33 call16(callregs);
34}
Kevin O'Connora4d35762008-03-08 15:43:03 -050035
Kevin O'Connor2e7ab8b2008-03-29 14:29:35 -040036// Sum the bytes in the specified area.
37u8
38checksum(u8 *far_data, u32 len)
39{
40 u32 i;
41 u8 sum = 0;
42 for (i=0; i<len; i++)
43 sum += GET_FARPTR(far_data[i]);
44 return sum;
45}
46
Kevin O'Connor5e4235f2008-04-12 09:00:04 -040047void *
Kevin O'Connor567e4e32008-04-05 11:37:51 -040048memset(void *s, int c, size_t n)
49{
50 while (n)
51 ((char *)s)[--n] = c;
Kevin O'Connor5e4235f2008-04-12 09:00:04 -040052 return s;
Kevin O'Connor567e4e32008-04-05 11:37:51 -040053}
54
55void *
Kevin O'Connore0113c92008-04-05 15:51:12 -040056memcpy(void *far_d1, const void *far_s1, size_t len)
Kevin O'Connor567e4e32008-04-05 11:37:51 -040057{
Kevin O'Connore0113c92008-04-05 15:51:12 -040058 u8 *d = far_d1;
59 u8 *s = (u8*)far_s1;
Kevin O'Connor567e4e32008-04-05 11:37:51 -040060
Kevin O'Connore0113c92008-04-05 15:51:12 -040061 while (len--) {
62 SET_FARPTR(*d, GET_FARPTR(*s));
63 d++;
64 s++;
65 }
Kevin O'Connor567e4e32008-04-05 11:37:51 -040066
Kevin O'Connore0113c92008-04-05 15:51:12 -040067 return far_d1;
Kevin O'Connor567e4e32008-04-05 11:37:51 -040068}
69
Kevin O'Connorc7812932008-06-08 23:08:12 -040070void *
71memmove(void *d, const void *s, size_t len)
72{
73 if (s >= d)
74 return memcpy(d, s, len);
75
76 d += len-1;
77 s += len-1;
78 while (len--) {
79 *(char*)d = *(char*)s;
80 d--;
81 s--;
82 }
83
84 return d;
85}
86
Kevin O'Connor567e4e32008-04-05 11:37:51 -040087void
88__set_fail(const char *fname, struct bregs *regs)
89{
90 __debug_fail(fname, regs);
Kevin O'Connordb9e65e2008-06-07 14:41:21 -040091 set_fail_silent(regs);
Kevin O'Connor567e4e32008-04-05 11:37:51 -040092}
93
94void
95__set_code_fail(const char *fname, struct bregs *regs, u8 code)
96{
Kevin O'Connordb9e65e2008-06-07 14:41:21 -040097 __debug_fail(fname, regs);
98 set_code_fail_silent(regs, code);
Kevin O'Connor567e4e32008-04-05 11:37:51 -040099}