|
|
1.1 root 1: // Basic x86 asm functions and function defs.
2: //
1.1.1.5 root 3: // Copyright (C) 2008-2010 Kevin O'Connor <[email protected]>
1.1 root 4: //
5: // This file may be distributed under the terms of the GNU LGPLv3 license.
6: #ifndef __UTIL_H
7: #define __UTIL_H
8:
9: #include "types.h" // u32
10:
11: static inline void irq_disable(void)
12: {
13: asm volatile("cli": : :"memory");
14: }
15:
16: static inline void irq_enable(void)
17: {
18: asm volatile("sti": : :"memory");
19: }
20:
1.1.1.7 ! root 21: static inline u32 save_flags(void)
1.1 root 22: {
1.1.1.7 ! root 23: u32 flags;
! 24: asm volatile("pushfl ; popl %0" : "=rm" (flags));
1.1 root 25: return flags;
26: }
27:
1.1.1.7 ! root 28: static inline void restore_flags(u32 flags)
1.1 root 29: {
30: asm volatile("pushl %0 ; popfl" : : "g" (flags) : "memory", "cc");
31: }
32:
33: static inline void cpu_relax(void)
34: {
35: asm volatile("rep ; nop": : :"memory");
36: }
37:
38: static inline void nop(void)
39: {
40: asm volatile("nop");
41: }
42:
43: static inline void hlt(void)
44: {
1.1.1.3 root 45: asm volatile("hlt": : :"memory");
1.1 root 46: }
47:
48: static inline void wbinvd(void)
49: {
1.1.1.3 root 50: asm volatile("wbinvd": : :"memory");
1.1 root 51: }
52:
1.1.1.7 ! root 53: #define CPUID_TSC (1 << 4)
1.1 root 54: #define CPUID_MSR (1 << 5)
55: #define CPUID_APIC (1 << 9)
56: #define CPUID_MTRR (1 << 12)
1.1.1.7 ! root 57: static inline void __cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
1.1 root 58: {
59: asm("cpuid"
60: : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
61: : "0" (index));
62: }
63:
1.1.1.6 root 64: static inline u32 getcr0(void) {
65: u32 cr0;
66: asm("movl %%cr0, %0" : "=r"(cr0));
67: return cr0;
68: }
69: static inline void setcr0(u32 cr0) {
70: asm("movl %0, %%cr0" : : "r"(cr0));
71: }
72:
1.1 root 73: static inline u64 rdmsr(u32 index)
74: {
75: u64 ret;
76: asm ("rdmsr" : "=A"(ret) : "c"(index));
77: return ret;
78: }
79:
80: static inline void wrmsr(u32 index, u64 val)
81: {
82: asm volatile ("wrmsr" : : "c"(index), "A"(val));
83: }
84:
85: static inline u64 rdtscll(void)
86: {
87: u64 val;
88: asm volatile("rdtsc" : "=A" (val));
89: return val;
90: }
91:
92: static inline u32 __ffs(u32 word)
93: {
94: asm("bsf %1,%0"
95: : "=r" (word)
96: : "rm" (word));
97: return word;
98: }
99: static inline u32 __fls(u32 word)
100: {
101: asm("bsr %1,%0"
102: : "=r" (word)
103: : "rm" (word));
104: return word;
105: }
106:
1.1.1.3 root 107: static inline u16 __htons_constant(u16 val) {
108: return (val<<8) | (val>>8);
109: }
110: static inline u32 __htonl_constant(u32 val) {
111: return (val<<24) | ((val&0xff00)<<8) | ((val&0xff0000)>>8) | (val>>24);
112: }
113: static inline u32 __htonl(u32 val) {
114: asm("bswapl %0" : "+r"(val));
115: return val;
116: }
117: #define htonl(x) (__builtin_constant_p((u32)(x)) ? __htonl_constant(x) : __htonl(x))
118: #define ntohl(x) htonl(x)
119: #define htons(x) __htons_constant(x)
120: #define ntohs(x) htons(x)
121:
1.1.1.4 root 122: static inline u16 cpu_to_le16(u16 x)
123: {
124: return x;
125: }
126:
127: static inline u32 cpu_to_le32(u32 x)
128: {
129: return x;
130: }
131:
1.1.1.7 ! root 132: static inline u32 le32_to_cpu(u32 x)
! 133: {
! 134: return x;
! 135: }
! 136:
1.1.1.2 root 137: static inline u32 getesp(void) {
1.1 root 138: u32 esp;
139: asm("movl %%esp, %0" : "=rm"(esp));
140: return esp;
141: }
142:
143: static inline void writel(void *addr, u32 val) {
144: *(volatile u32 *)addr = val;
145: }
146: static inline void writew(void *addr, u16 val) {
147: *(volatile u16 *)addr = val;
148: }
149: static inline void writeb(void *addr, u8 val) {
150: *(volatile u8 *)addr = val;
151: }
152: static inline u32 readl(const void *addr) {
153: return *(volatile const u32 *)addr;
154: }
155: static inline u16 readw(const void *addr) {
156: return *(volatile const u16 *)addr;
157: }
158: static inline u8 readb(const void *addr) {
159: return *(volatile const u8 *)addr;
160: }
161:
162: #define call16_simpint(nr, peax, pflags) do { \
163: ASSERT16(); \
164: asm volatile( \
1.1.1.3 root 165: "pushl %%ebp\n" \
166: "sti\n" \
1.1 root 167: "stc\n" \
168: "int %2\n" \
169: "pushfl\n" \
170: "popl %1\n" \
171: "cli\n" \
1.1.1.3 root 172: "cld\n" \
173: "popl %%ebp" \
174: : "+a"(*peax), "=c"(*pflags) \
1.1 root 175: : "i"(nr) \
1.1.1.3 root 176: : "ebx", "edx", "esi", "edi", "cc", "memory"); \
1.1 root 177: } while (0)
178:
1.1.1.4 root 179: // GDT bits
1.1 root 180: #define GDT_CODE (0x9bULL << 40) // Code segment - P,R,A bits also set
181: #define GDT_DATA (0x93ULL << 40) // Data segment - W,A bits also set
182: #define GDT_B (0x1ULL << 54) // Big flag
183: #define GDT_G (0x1ULL << 55) // Granularity flag
1.1.1.4 root 184: // GDT bits for segment base
185: #define GDT_BASE(v) ((((u64)(v) & 0xff000000) << 32) \
186: | (((u64)(v) & 0x00ffffff) << 16))
187: // GDT bits for segment limit (0-1Meg)
188: #define GDT_LIMIT(v) ((((u64)(v) & 0x000f0000) << 32) \
189: | (((u64)(v) & 0x0000ffff) << 0))
190: // GDT bits for segment limit (0-4Gig in 4K chunks)
191: #define GDT_GRANLIMIT(v) (GDT_G | GDT_LIMIT((v) >> 12))
1.1 root 192:
193: struct descloc_s {
194: u16 length;
195: u32 addr;
196: } PACKED;
197:
198: // util.c
1.1.1.7 ! root 199: void cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx);
1.1 root 200: struct bregs;
201: inline void call16(struct bregs *callregs);
202: inline void call16big(struct bregs *callregs);
203: inline void __call16_int(struct bregs *callregs, u16 offset);
204: #define call16_int(nr, callregs) do { \
205: extern void irq_trampoline_ ##nr (); \
206: __call16_int((callregs), (u32)&irq_trampoline_ ##nr ); \
207: } while (0)
208: u8 checksum_far(u16 buf_seg, void *buf_far, u32 len);
209: u8 checksum(void *buf, u32 len);
210: size_t strlen(const char *s);
211: int memcmp(const void *s1, const void *s2, size_t n);
212: int strcmp(const char *s1, const char *s2);
213: inline void memset_far(u16 d_seg, void *d_far, u8 c, size_t len);
214: inline void memset16_far(u16 d_seg, void *d_far, u16 c, size_t len);
215: void *memset(void *s, int c, size_t n);
1.1.1.5 root 216: void memset_fl(void *ptr, u8 val, size_t size);
1.1 root 217: inline void memcpy_far(u16 d_seg, void *d_far
218: , u16 s_seg, const void *s_far, size_t len);
1.1.1.3 root 219: void memcpy_fl(void *d_fl, const void *s_fl, size_t len);
1.1 root 220: void *memcpy(void *d1, const void *s1, size_t len);
1.1.1.2 root 221: #if MODESEGMENT == 0
1.1 root 222: #define memcpy __builtin_memcpy
223: #endif
224: void iomemcpy(void *d, const void *s, u32 len);
225: void *memmove(void *d, const void *s, size_t len);
226: char *strtcpy(char *dest, const char *src, size_t len);
1.1.1.5 root 227: char *strchr(const char *s, int c);
228: void nullTrailingSpace(char *buf);
1.1 root 229: int get_keystroke(int msec);
230:
231: // stacks.c
1.1.1.5 root 232: u32 call32(void *func, u32 eax, u32 errret);
1.1.1.3 root 233: inline u32 stack_hop(u32 eax, u32 edx, void *func);
1.1 root 234: extern struct thread_info MainThread;
1.1.1.6 root 235: extern int CanPreempt;
1.1.1.2 root 236: struct thread_info *getCurThread(void);
237: void yield(void);
1.1.1.3 root 238: void wait_irq(void);
1.1 root 239: void run_thread(void (*func)(void*), void *data);
1.1.1.2 root 240: void wait_threads(void);
1.1.1.3 root 241: struct mutex_s { u32 isLocked; };
242: void mutex_lock(struct mutex_s *mutex);
243: void mutex_unlock(struct mutex_s *mutex);
1.1.1.2 root 244: void start_preempt(void);
245: void finish_preempt(void);
1.1.1.3 root 246: int wait_preempt(void);
1.1.1.2 root 247: void check_preempt(void);
1.1 root 248:
249: // output.c
1.1.1.2 root 250: void debug_serial_setup(void);
1.1 root 251: void panic(const char *fmt, ...)
1.1.1.2 root 252: __attribute__ ((format (printf, 1, 2))) __noreturn;
1.1 root 253: void printf(const char *fmt, ...)
254: __attribute__ ((format (printf, 1, 2)));
255: int snprintf(char *str, size_t size, const char *fmt, ...)
256: __attribute__ ((format (printf, 3, 4)));
1.1.1.5 root 257: char * znprintf(size_t size, const char *fmt, ...)
258: __attribute__ ((format (printf, 2, 3)));
1.1.1.3 root 259: void __dprintf(const char *fmt, ...)
260: __attribute__ ((format (printf, 1, 2)));
261: void __debug_enter(struct bregs *regs, const char *fname);
262: void __debug_isr(const char *fname);
263: void __debug_stub(struct bregs *regs, int lineno, const char *fname);
264: void __warn_invalid(struct bregs *regs, int lineno, const char *fname);
265: void __warn_unimplemented(struct bregs *regs, int lineno, const char *fname);
266: void __warn_internalerror(int lineno, const char *fname);
267: void __warn_noalloc(int lineno, const char *fname);
268: void __warn_timeout(int lineno, const char *fname);
269: void __set_invalid(struct bregs *regs, int lineno, const char *fname);
270: void __set_unimplemented(struct bregs *regs, int lineno, const char *fname);
271: void __set_code_invalid(struct bregs *regs, u32 linecode, const char *fname);
272: void __set_code_unimplemented(struct bregs *regs, u32 linecode
273: , const char *fname);
274: void hexdump(const void *d, int len);
275:
1.1 root 276: #define dprintf(lvl, fmt, args...) do { \
277: if (CONFIG_DEBUG_LEVEL && (lvl) <= CONFIG_DEBUG_LEVEL) \
278: __dprintf((fmt) , ##args ); \
279: } while (0)
280: #define debug_enter(regs, lvl) do { \
281: if ((lvl) && (lvl) <= CONFIG_DEBUG_LEVEL) \
282: __debug_enter((regs), __func__); \
283: } while (0)
284: #define debug_isr(lvl) do { \
285: if ((lvl) && (lvl) <= CONFIG_DEBUG_LEVEL) \
286: __debug_isr(__func__); \
287: } while (0)
288: #define debug_stub(regs) \
289: __debug_stub((regs), __LINE__, __func__)
1.1.1.3 root 290: #define warn_invalid(regs) \
291: __warn_invalid((regs), __LINE__, __func__)
292: #define warn_unimplemented(regs) \
293: __warn_unimplemented((regs), __LINE__, __func__)
294: #define warn_internalerror() \
295: __warn_internalerror(__LINE__, __func__)
296: #define warn_noalloc() \
297: __warn_noalloc(__LINE__, __func__)
298: #define warn_timeout() \
299: __warn_timeout(__LINE__, __func__)
300: #define set_invalid(regs) \
301: __set_invalid((regs), __LINE__, __func__)
302: #define set_code_invalid(regs, code) \
303: __set_code_invalid((regs), (code) | (__LINE__ << 8), __func__)
304: #define set_unimplemented(regs) \
305: __set_unimplemented((regs), __LINE__, __func__)
306: #define set_code_unimplemented(regs, code) \
307: __set_code_unimplemented((regs), (code) | (__LINE__ << 8), __func__)
1.1 root 308:
309: // kbd.c
1.1.1.2 root 310: void kbd_setup(void);
1.1 root 311: void handle_15c2(struct bregs *regs);
312: void process_key(u8 key);
313:
314: // mouse.c
1.1.1.2 root 315: void mouse_setup(void);
1.1 root 316: void process_mouse(u8 data);
317:
318: // system.c
319: extern u32 RamSize;
320: extern u64 RamSizeOver4G;
1.1.1.2 root 321: void mathcp_setup(void);
1.1 root 322:
323: // serial.c
1.1.1.2 root 324: void serial_setup(void);
325: void lpt_setup(void);
1.1 root 326:
327: // clock.c
1.1.1.3 root 328: #define PIT_TICK_RATE 1193180 // Underlying HZ of PIT
329: #define PIT_TICK_INTERVAL 65536 // Default interval for 18.2Hz timer
1.1.1.7 ! root 330: int check_tsc(u64 end);
1.1.1.2 root 331: void timer_setup(void);
1.1 root 332: void ndelay(u32 count);
333: void udelay(u32 count);
334: void mdelay(u32 count);
335: void nsleep(u32 count);
336: void usleep(u32 count);
337: void msleep(u32 count);
338: u64 calc_future_tsc(u32 msecs);
339: u64 calc_future_tsc_usec(u32 usecs);
1.1.1.3 root 340: u32 calc_future_timer_ticks(u32 count);
341: u32 calc_future_timer(u32 msecs);
342: int check_timer(u32 end);
1.1 root 343: void handle_1583(struct bregs *regs);
344: void handle_1586(struct bregs *regs);
1.1.1.2 root 345: void useRTC(void);
346: void releaseRTC(void);
1.1 root 347:
348: // apm.c
1.1.1.5 root 349: void apm_shutdown(void);
1.1.1.2 root 350: void handle_1553(struct bregs *regs);
1.1 root 351:
352: // pcibios.c
353: void handle_1ab1(struct bregs *regs);
1.1.1.2 root 354: void bios32_setup(void);
1.1 root 355:
356: // shadow.c
1.1.1.2 root 357: void make_bios_writable(void);
358: void make_bios_readonly(void);
1.1.1.5 root 359: void qemu_prep_reset(void);
1.1.1.4 root 360:
1.1 root 361: // pciinit.c
1.1.1.3 root 362: extern const u8 pci_irqs[4];
1.1 root 363: void pci_setup(void);
364:
365: // smm.c
1.1.1.2 root 366: void smm_init(void);
1.1 root 367:
368: // smp.c
369: extern u32 CountCPUs;
370: extern u32 MaxCountCPUs;
371: void wrmsr_smp(u32 index, u64 val);
372: void smp_probe(void);
373:
374: // coreboot.c
1.1.1.6 root 375: extern const char *CBvendor, *CBpart;
1.1 root 376: struct cbfs_file;
1.1.1.3 root 377: struct cbfs_file *cbfs_finddatafile(const char *fname);
1.1 root 378: struct cbfs_file *cbfs_findprefix(const char *prefix, struct cbfs_file *last);
379: u32 cbfs_datasize(struct cbfs_file *file);
380: const char *cbfs_filename(struct cbfs_file *file);
381: int cbfs_copyfile(struct cbfs_file *file, void *dst, u32 maxlen);
382: void cbfs_run_payload(struct cbfs_file *file);
1.1.1.2 root 383: void coreboot_copy_biostable(void);
1.1.1.5 root 384: void cbfs_payload_setup(void);
1.1.1.2 root 385: void coreboot_setup(void);
1.1 root 386:
1.1.1.6 root 387: // biostable.c
388: void copy_pir(void *pos);
389: void copy_mptable(void *pos);
390: void copy_acpi_rsdp(void *pos);
391: void copy_smbios(void *pos);
392:
1.1 root 393: // vgahooks.c
1.1.1.2 root 394: void handle_155f(struct bregs *regs);
1.1.1.6 root 395: struct pci_device;
396: void vgahook_setup(struct pci_device *pci);
1.1 root 397:
398: // optionroms.c
399: void call_bcv(u16 seg, u16 ip);
1.1.1.2 root 400: void optionrom_setup(void);
401: void vga_setup(void);
402: void s3_resume_vga_init(void);
1.1 root 403: extern u32 RomEnd;
1.1.1.6 root 404: extern int ScreenAndDebug;
1.1 root 405:
1.1.1.3 root 406: // bootsplash.c
407: void enable_vga_console(void);
1.1.1.4 root 408: void enable_bootsplash(void);
1.1.1.3 root 409: void disable_bootsplash(void);
410:
1.1 root 411: // resume.c
1.1.1.6 root 412: extern int HaveRunPost;
1.1.1.2 root 413: void init_dma(void);
1.1 root 414:
415: // pnpbios.c
416: #define PNP_SIGNATURE 0x506e5024 // $PnP
1.1.1.2 root 417: u16 get_pnp_offset(void);
418: void pnp_setup(void);
1.1 root 419:
420: // pmm.c
421: extern struct zone_s ZoneLow, ZoneHigh, ZoneFSeg, ZoneTmpLow, ZoneTmpHigh;
1.1.1.2 root 422: void malloc_setup(void);
1.1.1.6 root 423: void malloc_fixupreloc(void);
1.1.1.2 root 424: void malloc_finalize(void);
1.1 root 425: void *pmm_malloc(struct zone_s *zone, u32 handle, u32 size, u32 align);
426: int pmm_free(void *data);
1.1.1.2 root 427: void pmm_setup(void);
428: void pmm_finalize(void);
1.1 root 429: #define PMM_DEFAULT_HANDLE 0xFFFFFFFF
430: // Minimum alignment of malloc'd memory
431: #define MALLOC_MIN_ALIGN 16
432: // Helper functions for memory allocation.
433: static inline void *malloc_low(u32 size) {
434: return pmm_malloc(&ZoneLow, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN);
435: }
436: static inline void *malloc_high(u32 size) {
437: return pmm_malloc(&ZoneHigh, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN);
438: }
439: static inline void *malloc_fseg(u32 size) {
440: return pmm_malloc(&ZoneFSeg, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN);
441: }
1.1.1.4 root 442: static inline void *malloc_tmplow(u32 size) {
443: return pmm_malloc(&ZoneTmpLow, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN);
444: }
1.1 root 445: static inline void *malloc_tmphigh(u32 size) {
446: return pmm_malloc(&ZoneTmpHigh, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN);
447: }
1.1.1.3 root 448: static inline void *malloc_tmp(u32 size) {
449: void *ret = malloc_tmphigh(size);
450: if (ret)
451: return ret;
1.1.1.4 root 452: return malloc_tmplow(size);
1.1.1.3 root 453: }
1.1 root 454: static inline void *memalign_low(u32 align, u32 size) {
455: return pmm_malloc(&ZoneLow, PMM_DEFAULT_HANDLE, size, align);
456: }
457: static inline void *memalign_high(u32 align, u32 size) {
458: return pmm_malloc(&ZoneHigh, PMM_DEFAULT_HANDLE, size, align);
459: }
1.1.1.5 root 460: static inline void *memalign_tmplow(u32 align, u32 size) {
461: return pmm_malloc(&ZoneTmpLow, PMM_DEFAULT_HANDLE, size, align);
462: }
1.1 root 463: static inline void *memalign_tmphigh(u32 align, u32 size) {
464: return pmm_malloc(&ZoneTmpHigh, PMM_DEFAULT_HANDLE, size, align);
465: }
1.1.1.5 root 466: static inline void *memalign_tmp(u32 align, u32 size) {
467: void *ret = memalign_tmphigh(align, size);
468: if (ret)
469: return ret;
470: return memalign_tmplow(align, size);
471: }
1.1 root 472: static inline void free(void *data) {
473: pmm_free(data);
474: }
475:
476: // mtrr.c
477: void mtrr_setup(void);
478:
479: // romlayout.S
1.1.1.2 root 480: void reset_vector(void) __noreturn;
1.1 root 481:
482: // misc.c
483: extern u8 BiosChecksum;
484:
485: // version (auto generated file out/version.c)
486: extern const char VERSION[];
487:
488: #endif // util.h
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.