|
|
1.1 ! root 1: // Basic x86 asm functions and function defs. ! 2: // ! 3: // Copyright (C) 2008,2009 Kevin O'Connor <[email protected]> ! 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: ! 21: static inline unsigned long irq_save(void) ! 22: { ! 23: unsigned long flags; ! 24: asm volatile("pushfl ; popl %0" : "=g" (flags)); ! 25: irq_disable(); ! 26: return flags; ! 27: } ! 28: ! 29: static inline void irq_restore(unsigned long flags) ! 30: { ! 31: asm volatile("pushl %0 ; popfl" : : "g" (flags) : "memory", "cc"); ! 32: } ! 33: ! 34: static inline void cpu_relax(void) ! 35: { ! 36: asm volatile("rep ; nop": : :"memory"); ! 37: } ! 38: ! 39: // Atomically enable irqs and sleep until an irq; then re-disable irqs. ! 40: static inline void wait_irq(void) ! 41: { ! 42: asm volatile("sti ; hlt ; cli ; cld": : :"memory"); ! 43: } ! 44: ! 45: static inline void nop(void) ! 46: { ! 47: asm volatile("nop"); ! 48: } ! 49: ! 50: static inline void hlt(void) ! 51: { ! 52: asm volatile("hlt"); ! 53: } ! 54: ! 55: static inline void wbinvd(void) ! 56: { ! 57: asm volatile("wbinvd"); ! 58: } ! 59: ! 60: #define CPUID_MSR (1 << 5) ! 61: #define CPUID_APIC (1 << 9) ! 62: #define CPUID_MTRR (1 << 12) ! 63: static inline void cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) ! 64: { ! 65: asm("cpuid" ! 66: : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) ! 67: : "0" (index)); ! 68: } ! 69: ! 70: static inline u64 rdmsr(u32 index) ! 71: { ! 72: u64 ret; ! 73: asm ("rdmsr" : "=A"(ret) : "c"(index)); ! 74: return ret; ! 75: } ! 76: ! 77: static inline void wrmsr(u32 index, u64 val) ! 78: { ! 79: asm volatile ("wrmsr" : : "c"(index), "A"(val)); ! 80: } ! 81: ! 82: static inline u64 rdtscll(void) ! 83: { ! 84: u64 val; ! 85: asm volatile("rdtsc" : "=A" (val)); ! 86: return val; ! 87: } ! 88: ! 89: static inline u32 __ffs(u32 word) ! 90: { ! 91: asm("bsf %1,%0" ! 92: : "=r" (word) ! 93: : "rm" (word)); ! 94: return word; ! 95: } ! 96: static inline u32 __fls(u32 word) ! 97: { ! 98: asm("bsr %1,%0" ! 99: : "=r" (word) ! 100: : "rm" (word)); ! 101: return word; ! 102: } ! 103: ! 104: static inline u32 getesp() { ! 105: u32 esp; ! 106: asm("movl %%esp, %0" : "=rm"(esp)); ! 107: return esp; ! 108: } ! 109: ! 110: static inline void writel(void *addr, u32 val) { ! 111: *(volatile u32 *)addr = val; ! 112: } ! 113: static inline void writew(void *addr, u16 val) { ! 114: *(volatile u16 *)addr = val; ! 115: } ! 116: static inline void writeb(void *addr, u8 val) { ! 117: *(volatile u8 *)addr = val; ! 118: } ! 119: static inline u32 readl(const void *addr) { ! 120: return *(volatile const u32 *)addr; ! 121: } ! 122: static inline u16 readw(const void *addr) { ! 123: return *(volatile const u16 *)addr; ! 124: } ! 125: static inline u8 readb(const void *addr) { ! 126: return *(volatile const u8 *)addr; ! 127: } ! 128: ! 129: #define call16_simpint(nr, peax, pflags) do { \ ! 130: ASSERT16(); \ ! 131: asm volatile( \ ! 132: "stc\n" \ ! 133: "int %2\n" \ ! 134: "pushfl\n" \ ! 135: "popl %1\n" \ ! 136: "cli\n" \ ! 137: "cld" \ ! 138: : "+a"(*peax), "=r"(*pflags) \ ! 139: : "i"(nr) \ ! 140: : "cc", "memory"); \ ! 141: } while (0) ! 142: ! 143: // GDT bit manipulation ! 144: #define GDT_BASE(v) ((((u64)(v) & 0xff000000) << 32) \ ! 145: | (((u64)(v) & 0x00ffffff) << 16)) ! 146: #define GDT_LIMIT(v) ((((u64)(v) & 0x000f0000) << 32) \ ! 147: | (((u64)(v) & 0x0000ffff) << 0)) ! 148: #define GDT_CODE (0x9bULL << 40) // Code segment - P,R,A bits also set ! 149: #define GDT_DATA (0x93ULL << 40) // Data segment - W,A bits also set ! 150: #define GDT_B (0x1ULL << 54) // Big flag ! 151: #define GDT_G (0x1ULL << 55) // Granularity flag ! 152: ! 153: struct descloc_s { ! 154: u16 length; ! 155: u32 addr; ! 156: } PACKED; ! 157: ! 158: // util.c ! 159: struct bregs; ! 160: inline void call16(struct bregs *callregs); ! 161: inline void call16big(struct bregs *callregs); ! 162: inline void __call16_int(struct bregs *callregs, u16 offset); ! 163: #define call16_int(nr, callregs) do { \ ! 164: extern void irq_trampoline_ ##nr (); \ ! 165: __call16_int((callregs), (u32)&irq_trampoline_ ##nr ); \ ! 166: } while (0) ! 167: void check_irqs(); ! 168: u8 checksum_far(u16 buf_seg, void *buf_far, u32 len); ! 169: u8 checksum(void *buf, u32 len); ! 170: size_t strlen(const char *s); ! 171: int memcmp(const void *s1, const void *s2, size_t n); ! 172: int strcmp(const char *s1, const char *s2); ! 173: inline void memset_far(u16 d_seg, void *d_far, u8 c, size_t len); ! 174: inline void memset16_far(u16 d_seg, void *d_far, u16 c, size_t len); ! 175: void *memset(void *s, int c, size_t n); ! 176: inline void memcpy_far(u16 d_seg, void *d_far ! 177: , u16 s_seg, const void *s_far, size_t len); ! 178: void *memcpy(void *d1, const void *s1, size_t len); ! 179: #if MODE16 == 0 ! 180: #define memcpy __builtin_memcpy ! 181: #endif ! 182: void iomemcpy(void *d, const void *s, u32 len); ! 183: void *memmove(void *d, const void *s, size_t len); ! 184: char *strtcpy(char *dest, const char *src, size_t len); ! 185: void biosusleep(u32 usec); ! 186: int get_keystroke(int msec); ! 187: ! 188: // stacks.c ! 189: inline u32 stack_hop(u32 eax, u32 edx, u32 ecx, void *func); ! 190: extern struct thread_info MainThread; ! 191: void thread_setup(); ! 192: struct thread_info *getCurThread(); ! 193: void yield(); ! 194: void run_thread(void (*func)(void*), void *data); ! 195: void wait_threads(); ! 196: void start_preempt(); ! 197: void finish_preempt(); ! 198: void check_preempt(); ! 199: ! 200: // output.c ! 201: void debug_serial_setup(); ! 202: void panic(const char *fmt, ...) ! 203: __attribute__ ((format (printf, 1, 2))) ! 204: __attribute__ ((noreturn)); ! 205: void printf(const char *fmt, ...) ! 206: __attribute__ ((format (printf, 1, 2))); ! 207: void __dprintf(const char *fmt, ...) ! 208: __attribute__ ((format (printf, 1, 2))); ! 209: int snprintf(char *str, size_t size, const char *fmt, ...) ! 210: __attribute__ ((format (printf, 3, 4))); ! 211: #define dprintf(lvl, fmt, args...) do { \ ! 212: if (CONFIG_DEBUG_LEVEL && (lvl) <= CONFIG_DEBUG_LEVEL) \ ! 213: __dprintf((fmt) , ##args ); \ ! 214: } while (0) ! 215: void __debug_enter(struct bregs *regs, const char *fname); ! 216: void __debug_stub(struct bregs *regs, int lineno, const char *fname); ! 217: void __debug_isr(const char *fname); ! 218: #define debug_enter(regs, lvl) do { \ ! 219: if ((lvl) && (lvl) <= CONFIG_DEBUG_LEVEL) \ ! 220: __debug_enter((regs), __func__); \ ! 221: } while (0) ! 222: #define debug_isr(lvl) do { \ ! 223: if ((lvl) && (lvl) <= CONFIG_DEBUG_LEVEL) \ ! 224: __debug_isr(__func__); \ ! 225: } while (0) ! 226: #define debug_stub(regs) \ ! 227: __debug_stub((regs), __LINE__, __func__) ! 228: void hexdump(const void *d, int len); ! 229: ! 230: // kbd.c ! 231: void kbd_setup(); ! 232: void handle_15c2(struct bregs *regs); ! 233: void process_key(u8 key); ! 234: ! 235: // mouse.c ! 236: void mouse_setup(); ! 237: void process_mouse(u8 data); ! 238: ! 239: // system.c ! 240: extern u32 RamSize; ! 241: extern u64 RamSizeOver4G; ! 242: void mathcp_setup(); ! 243: ! 244: // serial.c ! 245: void serial_setup(); ! 246: void lpt_setup(); ! 247: ! 248: // clock.c ! 249: static inline int check_time(u64 end) { ! 250: return (s64)(rdtscll() - end) > 0; ! 251: } ! 252: void timer_setup(); ! 253: void ndelay(u32 count); ! 254: void udelay(u32 count); ! 255: void mdelay(u32 count); ! 256: void nsleep(u32 count); ! 257: void usleep(u32 count); ! 258: void msleep(u32 count); ! 259: u64 calc_future_tsc(u32 msecs); ! 260: u64 calc_future_tsc_usec(u32 usecs); ! 261: void handle_1583(struct bregs *regs); ! 262: void handle_1586(struct bregs *regs); ! 263: void useRTC(); ! 264: void releaseRTC(); ! 265: ! 266: // apm.c ! 267: void VISIBLE16 handle_1553(struct bregs *regs); ! 268: ! 269: // pcibios.c ! 270: void handle_1ab1(struct bregs *regs); ! 271: ! 272: // shadow.c ! 273: void make_bios_writable(); ! 274: void make_bios_readonly(); ! 275: ! 276: // pciinit.c ! 277: void pci_setup(void); ! 278: ! 279: // smm.c ! 280: void smm_init(); ! 281: ! 282: // smp.c ! 283: extern u32 CountCPUs; ! 284: extern u32 MaxCountCPUs; ! 285: void wrmsr_smp(u32 index, u64 val); ! 286: void smp_probe(void); ! 287: void smp_probe_setup(void); ! 288: ! 289: // coreboot.c ! 290: struct cbfs_file; ! 291: struct cbfs_file *cbfs_findprefix(const char *prefix, struct cbfs_file *last); ! 292: u32 cbfs_datasize(struct cbfs_file *file); ! 293: const char *cbfs_filename(struct cbfs_file *file); ! 294: int cbfs_copyfile(struct cbfs_file *file, void *dst, u32 maxlen); ! 295: int cbfs_copy_optionrom(void *dst, u32 maxlen, u32 vendev); ! 296: void cbfs_run_payload(struct cbfs_file *file); ! 297: ! 298: void coreboot_copy_biostable(); ! 299: void coreboot_setup(); ! 300: ! 301: // vgahooks.c ! 302: extern int VGAbdf; ! 303: void handle_155f(); ! 304: void vgahook_setup(const char *vendor, const char *part); ! 305: ! 306: // optionroms.c ! 307: void call_bcv(u16 seg, u16 ip); ! 308: void optionrom_setup(); ! 309: void vga_setup(); ! 310: void s3_resume_vga_init(); ! 311: extern u32 RomEnd; ! 312: ! 313: // resume.c ! 314: void init_dma(); ! 315: ! 316: // pnpbios.c ! 317: #define PNP_SIGNATURE 0x506e5024 // $PnP ! 318: u16 get_pnp_offset(); ! 319: void pnp_setup(); ! 320: ! 321: // pmm.c ! 322: extern struct zone_s ZoneLow, ZoneHigh, ZoneFSeg, ZoneTmpLow, ZoneTmpHigh; ! 323: void malloc_setup(); ! 324: void malloc_finalize(); ! 325: void *pmm_malloc(struct zone_s *zone, u32 handle, u32 size, u32 align); ! 326: int pmm_free(void *data); ! 327: void pmm_setup(); ! 328: void pmm_finalize(); ! 329: #define PMM_DEFAULT_HANDLE 0xFFFFFFFF ! 330: // Minimum alignment of malloc'd memory ! 331: #define MALLOC_MIN_ALIGN 16 ! 332: // Helper functions for memory allocation. ! 333: static inline void *malloc_low(u32 size) { ! 334: return pmm_malloc(&ZoneLow, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN); ! 335: } ! 336: static inline void *malloc_high(u32 size) { ! 337: return pmm_malloc(&ZoneHigh, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN); ! 338: } ! 339: static inline void *malloc_fseg(u32 size) { ! 340: return pmm_malloc(&ZoneFSeg, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN); ! 341: } ! 342: static inline void *malloc_tmphigh(u32 size) { ! 343: return pmm_malloc(&ZoneTmpHigh, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN); ! 344: } ! 345: static inline void *memalign_low(u32 align, u32 size) { ! 346: return pmm_malloc(&ZoneLow, PMM_DEFAULT_HANDLE, size, align); ! 347: } ! 348: static inline void *memalign_high(u32 align, u32 size) { ! 349: return pmm_malloc(&ZoneHigh, PMM_DEFAULT_HANDLE, size, align); ! 350: } ! 351: static inline void *memalign_tmphigh(u32 align, u32 size) { ! 352: return pmm_malloc(&ZoneTmpHigh, PMM_DEFAULT_HANDLE, size, align); ! 353: } ! 354: static inline void free(void *data) { ! 355: pmm_free(data); ! 356: } ! 357: ! 358: // mtrr.c ! 359: void mtrr_setup(void); ! 360: ! 361: // romlayout.S ! 362: void reset_vector() __attribute__ ((noreturn)); ! 363: ! 364: // misc.c ! 365: extern u8 BiosChecksum; ! 366: ! 367: // version (auto generated file out/version.c) ! 368: extern const char VERSION[]; ! 369: ! 370: // XXX - optimize ! 371: #define ntohl(x) ((((x)&0xff)<<24) | (((x)&0xff00)<<8) | \ ! 372: (((x)&0xff0000) >> 8) | (((x)&0xff000000) >> 24)) ! 373: #define htonl(x) ntohl(x) ! 374: #define ntohs(x) ((((x)&0xff)<<8) | (((x)&0xff00)>>8)) ! 375: #define htons(x) ntohs(x) ! 376: ! 377: #endif // util.h
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.