aboutsummaryrefslogtreecommitdiff
path: root/src/util.h
blob: 6ae7f1929e59232e3e80d493866601fa67999ad4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
// Basic x86 asm functions and function defs.
//
// Copyright (C) 2008,2009  Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU LGPLv3 license.
#ifndef __UTIL_H
#define __UTIL_H

#include "types.h" // u32

static inline void irq_disable(void)
{
    asm volatile("cli": : :"memory");
}

static inline void irq_enable(void)
{
    asm volatile("sti": : :"memory");
}

static inline unsigned long irq_save(void)
{
    unsigned long flags;
    asm volatile("pushfl ; popl %0" : "=g" (flags));
    irq_disable();
    return flags;
}

static inline void irq_restore(unsigned long flags)
{
    asm volatile("pushl %0 ; popfl" : : "g" (flags) : "memory", "cc");
}

static inline void cpu_relax(void)
{
    asm volatile("rep ; nop": : :"memory");
}

static inline void nop(void)
{
    asm volatile("nop");
}

static inline void hlt(void)
{
    asm volatile("hlt");
}

static inline void wbinvd(void)
{
    asm volatile("wbinvd");
}

#define CPUID_MSR (1 << 5)
#define CPUID_APIC (1 << 9)
#define CPUID_MTRR (1 << 12)
static inline void cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
{
    asm("cpuid"
        : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
        : "0" (index));
}

static inline u64 rdmsr(u32 index)
{
    u64 ret;
    asm ("rdmsr" : "=A"(ret) : "c"(index));
    return ret;
}

static inline void wrmsr(u32 index, u64 val)
{
    asm volatile ("wrmsr" : : "c"(index), "A"(val));
}

static inline u64 rdtscll(void)
{
    u64 val;
    asm volatile("rdtsc" : "=A" (val));
    return val;
}

#define call16_simpint(nr, peax, pflags) do {                           \
        ASSERT16();                                                     \
        asm volatile(                                                   \
            "stc\n"                                                     \
            "int %2\n"                                                  \
            "pushfl\n"                                                  \
            "popl %1\n"                                                 \
            "cli\n"                                                     \
            "cld"                                                       \
            : "+a"(*peax), "=r"(*pflags)                                \
            : "i"(nr)                                                   \
            : "cc", "memory");                                          \
    } while (0)

// util.c
inline u32 stack_hop(u32 eax, u32 edx, u32 ecx, void *func);
u8 checksum_far(u16 buf_seg, void *buf_far, u32 len);
u8 checksum(void *buf, u32 len);
int memcmp(const void *s1, const void *s2, size_t n);
size_t strlen(const char *s);
int strcmp(const char *s1, const char *s2);
inline void memset_far(u16 d_seg, void *d_far, u8 c, size_t len);
inline void memset16_far(u16 d_seg, void *d_far, u16 c, size_t len);
void *memset(void *s, int c, size_t n);
void *memcpy(void *d1, const void *s1, size_t len);
#if MODE16 == 0
#define memcpy __builtin_memcpy
#endif
inline void memcpy_far(u16 d_seg, void *d_far
                       , u16 s_seg, const void *s_far, size_t len);
void *memmove(void *d, const void *s, size_t len);
char *strtcpy(char *dest, const char *src, size_t len);
struct bregs;
inline void call16(struct bregs *callregs);
inline void call16big(struct bregs *callregs);
inline void __call16_int(struct bregs *callregs, u16 offset);
#define call16_int(nr, callregs) do {                           \
        extern void irq_trampoline_ ##nr ();                    \
        __call16_int((callregs), (u32)&irq_trampoline_ ##nr );  \
    } while (0)
void usleep(u32 usec);
int get_keystroke(int msec);

// output.c
void debug_serial_setup();
void panic(const char *fmt, ...)
    __attribute__ ((format (printf, 1, 2)))
    __attribute__ ((noreturn));
void printf(const char *fmt, ...)
    __attribute__ ((format (printf, 1, 2)));
void __dprintf(const char *fmt, ...)
    __attribute__ ((format (printf, 1, 2)));
#define dprintf(lvl, fmt, args...) do {                         \
        if (CONFIG_DEBUG_LEVEL && (lvl) <= CONFIG_DEBUG_LEVEL)  \
            __dprintf((fmt) , ##args );                         \
    } while (0)
void __debug_enter(struct bregs *regs, const char *fname);
void __debug_stub(struct bregs *regs, int lineno, const char *fname);
void __debug_isr(const char *fname);
#define debug_enter(regs, lvl) do {                     \
        if ((lvl) && (lvl) <= CONFIG_DEBUG_LEVEL)       \
            __debug_enter((regs), __func__);            \
    } while (0)
#define debug_isr(lvl) do {                             \
        if ((lvl) && (lvl) <= CONFIG_DEBUG_LEVEL)       \
            __debug_isr(__func__);                      \
    } while (0)
#define debug_stub(regs)                        \
    __debug_stub((regs), __LINE__, __func__)
void hexdump(void *d, int len);

// kbd.c
void kbd_setup();
void handle_15c2(struct bregs *regs);

// mouse.c
void mouse_setup();

// system.c
extern u32 RamSize;
extern u64 RamSizeOver4G;
void mathcp_setup();

// serial.c
void serial_setup();
void lpt_setup();

// clock.c
void timer_setup();
void ndelay(u32 count);
void udelay(u32 count);
void mdelay(u32 count);
u64 calc_future_tsc(u32 msecs);
void handle_1583(struct bregs *regs);
void handle_1586(struct bregs *regs);

// apm.c
void VISIBLE16 handle_1553(struct bregs *regs);

// pcibios.c
void handle_1ab1(struct bregs *regs);

// shadow.c
void make_bios_writable();
void make_bios_readonly();

// pciinit.c
void pci_bios_setup(void);

// smm.c
void smm_init();

// smp.c
extern u32 CountCPUs VAR16_32;
void wrmsr_smp(u32 index, u64 val);
void smp_probe(void);
void smp_probe_setup(void);

// smbios.c
void smbios_init(void);

// coreboot.c
const char *cbfs_findNprefix(const char *prefix, int n);
int cbfs_copy_optionrom(void *dst, u32 maxlen, u32 vendev);
void cbfs_run_payload(const char *filename);
struct cbfs_file;
struct cbfs_file *cbfs_copyfile_prefix(void *dst, u32 maxlen, char *prefix
                                       , struct cbfs_file *last);
void coreboot_setup();

// vgahooks.c
void handle_155f();

// optionroms.c
void call_bcv(u16 seg, u16 ip);
void vga_setup();
void optionrom_setup();

// resume.c
void init_dma();

// pnpbios.c
#define PNP_SIGNATURE 0x506e5024 // $PnP
u16 get_pnp_offset();
void pnp_setup();

// mtrr.c
void mtrr_setup(void);

// romlayout.S
void reset_vector() __attribute__ ((noreturn));

// misc.c
extern u8 BiosChecksum;

#endif // util.h