Kevin O'Connor | f076a3e | 2008-02-25 22:25:15 -0500 | [diff] [blame] | 1 | // Basic x86 asm functions and function defs. |
| 2 | // |
Kevin O'Connor | 244caf8 | 2010-09-15 21:48:16 -0400 | [diff] [blame] | 3 | // Copyright (C) 2008-2010 Kevin O'Connor <kevin@koconnor.net> |
Kevin O'Connor | f076a3e | 2008-02-25 22:25:15 -0500 | [diff] [blame] | 4 | // |
Kevin O'Connor | b1b7c2a | 2009-01-15 20:52:58 -0500 | [diff] [blame] | 5 | // This file may be distributed under the terms of the GNU LGPLv3 license. |
Kevin O'Connor | 786502d | 2008-02-27 10:41:41 -0500 | [diff] [blame] | 6 | #ifndef __UTIL_H |
| 7 | #define __UTIL_H |
Kevin O'Connor | f076a3e | 2008-02-25 22:25:15 -0500 | [diff] [blame] | 8 | |
Kevin O'Connor | 9521e26 | 2008-07-04 13:04:29 -0400 | [diff] [blame] | 9 | #include "types.h" // u32 |
Kevin O'Connor | f076a3e | 2008-02-25 22:25:15 -0500 | [diff] [blame] | 10 | |
Kevin O'Connor | 786502d | 2008-02-27 10:41:41 -0500 | [diff] [blame] | 11 | static inline void irq_disable(void) |
| 12 | { |
| 13 | asm volatile("cli": : :"memory"); |
Kevin O'Connor | f076a3e | 2008-02-25 22:25:15 -0500 | [diff] [blame] | 14 | } |
| 15 | |
Kevin O'Connor | 786502d | 2008-02-27 10:41:41 -0500 | [diff] [blame] | 16 | static inline void irq_enable(void) |
| 17 | { |
| 18 | asm volatile("sti": : :"memory"); |
Kevin O'Connor | f076a3e | 2008-02-25 22:25:15 -0500 | [diff] [blame] | 19 | } |
| 20 | |
Kevin O'Connor | 9eb2100 | 2012-01-29 13:30:56 -0500 | [diff] [blame] | 21 | static inline u32 save_flags(void) |
Kevin O'Connor | f076a3e | 2008-02-25 22:25:15 -0500 | [diff] [blame] | 22 | { |
Kevin O'Connor | 9eb2100 | 2012-01-29 13:30:56 -0500 | [diff] [blame] | 23 | u32 flags; |
| 24 | asm volatile("pushfl ; popl %0" : "=rm" (flags)); |
Kevin O'Connor | f076a3e | 2008-02-25 22:25:15 -0500 | [diff] [blame] | 25 | return flags; |
| 26 | } |
| 27 | |
Kevin O'Connor | 9eb2100 | 2012-01-29 13:30:56 -0500 | [diff] [blame] | 28 | static inline void restore_flags(u32 flags) |
Kevin O'Connor | f076a3e | 2008-02-25 22:25:15 -0500 | [diff] [blame] | 29 | { |
| 30 | asm volatile("pushl %0 ; popfl" : : "g" (flags) : "memory", "cc"); |
| 31 | } |
| 32 | |
Kevin O'Connor | 06ad44e | 2008-04-05 19:30:02 -0400 | [diff] [blame] | 33 | static inline void cpu_relax(void) |
| 34 | { |
| 35 | asm volatile("rep ; nop": : :"memory"); |
| 36 | } |
| 37 | |
Kevin O'Connor | 38fcbfe | 2008-02-25 22:30:47 -0500 | [diff] [blame] | 38 | static inline void nop(void) |
| 39 | { |
| 40 | asm volatile("nop"); |
| 41 | } |
| 42 | |
Kevin O'Connor | 95b2f78 | 2008-03-05 19:52:06 -0500 | [diff] [blame] | 43 | static inline void hlt(void) |
| 44 | { |
Kevin O'Connor | 9c447c3 | 2010-05-23 10:24:22 -0400 | [diff] [blame] | 45 | asm volatile("hlt": : :"memory"); |
Kevin O'Connor | 95b2f78 | 2008-03-05 19:52:06 -0500 | [diff] [blame] | 46 | } |
| 47 | |
Kevin O'Connor | da4a648 | 2008-06-08 13:48:06 -0400 | [diff] [blame] | 48 | static inline void wbinvd(void) |
| 49 | { |
Kevin O'Connor | 9c447c3 | 2010-05-23 10:24:22 -0400 | [diff] [blame] | 50 | asm volatile("wbinvd": : :"memory"); |
Kevin O'Connor | da4a648 | 2008-06-08 13:48:06 -0400 | [diff] [blame] | 51 | } |
| 52 | |
Kevin O'Connor | 745de85 | 2012-01-29 14:15:14 -0500 | [diff] [blame] | 53 | #define CPUID_TSC (1 << 4) |
Kevin O'Connor | e97ca7b | 2009-06-21 09:10:28 -0400 | [diff] [blame] | 54 | #define CPUID_MSR (1 << 5) |
| 55 | #define CPUID_APIC (1 << 9) |
| 56 | #define CPUID_MTRR (1 << 12) |
Kevin O'Connor | 9eb2100 | 2012-01-29 13:30:56 -0500 | [diff] [blame] | 57 | static inline void __cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) |
Kevin O'Connor | 84ad59a | 2008-07-04 05:47:26 -0400 | [diff] [blame] | 58 | { |
| 59 | asm("cpuid" |
| 60 | : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) |
| 61 | : "0" (index)); |
| 62 | } |
| 63 | |
Kevin O'Connor | 87b533b | 2011-07-10 22:35:07 -0400 | [diff] [blame] | 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 | |
Kevin O'Connor | e97ca7b | 2009-06-21 09:10:28 -0400 | [diff] [blame] | 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 | |
Kevin O'Connor | bc2aecd | 2008-11-28 16:40:06 -0500 | [diff] [blame] | 85 | static inline u64 rdtscll(void) |
| 86 | { |
| 87 | u64 val; |
| 88 | asm volatile("rdtsc" : "=A" (val)); |
| 89 | return val; |
| 90 | } |
| 91 | |
Kevin O'Connor | 0bf9270 | 2009-08-01 11:45:37 -0400 | [diff] [blame] | 92 | static inline u32 __ffs(u32 word) |
| 93 | { |
| 94 | asm("bsf %1,%0" |
| 95 | : "=r" (word) |
| 96 | : "rm" (word)); |
| 97 | return word; |
| 98 | } |
Kevin O'Connor | 86916ce | 2009-11-14 13:34:27 -0500 | [diff] [blame] | 99 | static inline u32 __fls(u32 word) |
| 100 | { |
| 101 | asm("bsr %1,%0" |
| 102 | : "=r" (word) |
| 103 | : "rm" (word)); |
| 104 | return word; |
| 105 | } |
Kevin O'Connor | 0bf9270 | 2009-08-01 11:45:37 -0400 | [diff] [blame] | 106 | |
Kevin O'Connor | 1ca05b0 | 2010-01-03 17:43:37 -0500 | [diff] [blame] | 107 | static inline u32 getesp(void) { |
Kevin O'Connor | 7cefbfa | 2009-12-10 21:35:49 -0500 | [diff] [blame] | 108 | u32 esp; |
| 109 | asm("movl %%esp, %0" : "=rm"(esp)); |
| 110 | return esp; |
| 111 | } |
| 112 | |
Kevin O'Connor | 91031ed | 2009-10-12 09:49:27 -0400 | [diff] [blame] | 113 | static inline void writel(void *addr, u32 val) { |
| 114 | *(volatile u32 *)addr = val; |
| 115 | } |
| 116 | static inline void writew(void *addr, u16 val) { |
| 117 | *(volatile u16 *)addr = val; |
| 118 | } |
| 119 | static inline void writeb(void *addr, u8 val) { |
| 120 | *(volatile u8 *)addr = val; |
| 121 | } |
| 122 | static inline u32 readl(const void *addr) { |
| 123 | return *(volatile const u32 *)addr; |
| 124 | } |
| 125 | static inline u16 readw(const void *addr) { |
| 126 | return *(volatile const u16 *)addr; |
| 127 | } |
| 128 | static inline u8 readb(const void *addr) { |
| 129 | return *(volatile const u8 *)addr; |
| 130 | } |
| 131 | |
Kevin O'Connor | ae6924d | 2010-07-25 14:46:21 -0400 | [diff] [blame] | 132 | // GDT bits |
Kevin O'Connor | ad90159 | 2009-12-13 11:25:25 -0500 | [diff] [blame] | 133 | #define GDT_CODE (0x9bULL << 40) // Code segment - P,R,A bits also set |
| 134 | #define GDT_DATA (0x93ULL << 40) // Data segment - W,A bits also set |
| 135 | #define GDT_B (0x1ULL << 54) // Big flag |
| 136 | #define GDT_G (0x1ULL << 55) // Granularity flag |
Kevin O'Connor | ae6924d | 2010-07-25 14:46:21 -0400 | [diff] [blame] | 137 | // GDT bits for segment base |
| 138 | #define GDT_BASE(v) ((((u64)(v) & 0xff000000) << 32) \ |
| 139 | | (((u64)(v) & 0x00ffffff) << 16)) |
| 140 | // GDT bits for segment limit (0-1Meg) |
| 141 | #define GDT_LIMIT(v) ((((u64)(v) & 0x000f0000) << 32) \ |
| 142 | | (((u64)(v) & 0x0000ffff) << 0)) |
| 143 | // GDT bits for segment limit (0-4Gig in 4K chunks) |
| 144 | #define GDT_GRANLIMIT(v) (GDT_G | GDT_LIMIT((v) >> 12)) |
Kevin O'Connor | ad90159 | 2009-12-13 11:25:25 -0500 | [diff] [blame] | 145 | |
| 146 | struct descloc_s { |
| 147 | u16 length; |
| 148 | u32 addr; |
| 149 | } PACKED; |
| 150 | |
Kevin O'Connor | a83ff55 | 2009-01-01 21:00:59 -0500 | [diff] [blame] | 151 | // util.c |
Kevin O'Connor | 9eb2100 | 2012-01-29 13:30:56 -0500 | [diff] [blame] | 152 | void cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx); |
Kevin O'Connor | 7cefbfa | 2009-12-10 21:35:49 -0500 | [diff] [blame] | 153 | u8 checksum_far(u16 buf_seg, void *buf_far, u32 len); |
| 154 | u8 checksum(void *buf, u32 len); |
| 155 | size_t strlen(const char *s); |
| 156 | int memcmp(const void *s1, const void *s2, size_t n); |
| 157 | int strcmp(const char *s1, const char *s2); |
| 158 | inline void memset_far(u16 d_seg, void *d_far, u8 c, size_t len); |
| 159 | inline void memset16_far(u16 d_seg, void *d_far, u16 c, size_t len); |
| 160 | void *memset(void *s, int c, size_t n); |
Gerd Hoffmann | 0a80608 | 2010-11-29 09:42:11 +0100 | [diff] [blame] | 161 | void memset_fl(void *ptr, u8 val, size_t size); |
Kevin O'Connor | 7cefbfa | 2009-12-10 21:35:49 -0500 | [diff] [blame] | 162 | inline void memcpy_far(u16 d_seg, void *d_far |
| 163 | , u16 s_seg, const void *s_far, size_t len); |
Kevin O'Connor | 8f59aa3 | 2010-06-06 16:11:45 -0400 | [diff] [blame] | 164 | void memcpy_fl(void *d_fl, const void *s_fl, size_t len); |
Kevin O'Connor | 7cefbfa | 2009-12-10 21:35:49 -0500 | [diff] [blame] | 165 | void *memcpy(void *d1, const void *s1, size_t len); |
Kevin O'Connor | 52a300f | 2009-12-26 23:32:57 -0500 | [diff] [blame] | 166 | #if MODESEGMENT == 0 |
Kevin O'Connor | 7cefbfa | 2009-12-10 21:35:49 -0500 | [diff] [blame] | 167 | #define memcpy __builtin_memcpy |
| 168 | #endif |
| 169 | void iomemcpy(void *d, const void *s, u32 len); |
| 170 | void *memmove(void *d, const void *s, size_t len); |
| 171 | char *strtcpy(char *dest, const char *src, size_t len); |
Kevin O'Connor | 2e109a6 | 2010-12-24 10:39:32 -0500 | [diff] [blame] | 172 | char *strchr(const char *s, int c); |
Kevin O'Connor | 9e881a3 | 2011-01-08 12:06:54 -0500 | [diff] [blame] | 173 | void nullTrailingSpace(char *buf); |
Kevin O'Connor | 9f4e1d9 | 2009-02-08 15:44:08 -0500 | [diff] [blame] | 174 | int get_keystroke(int msec); |
Kevin O'Connor | 38fcbfe | 2008-02-25 22:30:47 -0500 | [diff] [blame] | 175 | |
Kevin O'Connor | 7cefbfa | 2009-12-10 21:35:49 -0500 | [diff] [blame] | 176 | // stacks.c |
Kevin O'Connor | bf2e8c2 | 2012-05-28 12:59:58 -0400 | [diff] [blame] | 177 | extern u8 ExtraStack[], *StackPos; |
Kevin O'Connor | ecdc655 | 2012-05-28 14:25:15 -0400 | [diff] [blame] | 178 | u32 stack_hop(u32 eax, u32 edx, void *func); |
| 179 | u32 stack_hop_back(u32 eax, u32 edx, void *func); |
Kevin O'Connor | e77c705 | 2012-05-28 22:06:42 -0400 | [diff] [blame] | 180 | u32 call32(void *func, u32 eax, u32 errret); |
| 181 | struct bregs; |
| 182 | inline void farcall16(struct bregs *callregs); |
| 183 | inline void farcall16big(struct bregs *callregs); |
| 184 | inline void __call16_int(struct bregs *callregs, u16 offset); |
| 185 | #define call16_int(nr, callregs) do { \ |
| 186 | extern void irq_trampoline_ ##nr (); \ |
| 187 | __call16_int((callregs), (u32)&irq_trampoline_ ##nr ); \ |
| 188 | } while (0) |
Kevin O'Connor | 7cefbfa | 2009-12-10 21:35:49 -0500 | [diff] [blame] | 189 | extern struct thread_info MainThread; |
Kevin O'Connor | 1ca05b0 | 2010-01-03 17:43:37 -0500 | [diff] [blame] | 190 | struct thread_info *getCurThread(void); |
| 191 | void yield(void); |
Kevin O'Connor | 94c749c | 2012-05-28 11:44:02 -0400 | [diff] [blame] | 192 | void yield_toirq(void); |
Kevin O'Connor | 7cefbfa | 2009-12-10 21:35:49 -0500 | [diff] [blame] | 193 | void run_thread(void (*func)(void*), void *data); |
Kevin O'Connor | 1ca05b0 | 2010-01-03 17:43:37 -0500 | [diff] [blame] | 194 | void wait_threads(void); |
Kevin O'Connor | e908665 | 2010-02-27 13:49:47 -0500 | [diff] [blame] | 195 | struct mutex_s { u32 isLocked; }; |
| 196 | void mutex_lock(struct mutex_s *mutex); |
| 197 | void mutex_unlock(struct mutex_s *mutex); |
Kevin O'Connor | 1ca05b0 | 2010-01-03 17:43:37 -0500 | [diff] [blame] | 198 | void start_preempt(void); |
| 199 | void finish_preempt(void); |
Kevin O'Connor | d7eb27e | 2010-03-20 18:17:19 -0400 | [diff] [blame] | 200 | int wait_preempt(void); |
Kevin O'Connor | 1ca05b0 | 2010-01-03 17:43:37 -0500 | [diff] [blame] | 201 | void check_preempt(void); |
Kevin O'Connor | 7cefbfa | 2009-12-10 21:35:49 -0500 | [diff] [blame] | 202 | |
Kevin O'Connor | f076a3e | 2008-02-25 22:25:15 -0500 | [diff] [blame] | 203 | // output.c |
Ian Campbell | 54f3b25 | 2012-06-28 11:08:32 +0100 | [diff] [blame] | 204 | extern u16 DebugOutputPort; |
Kevin O'Connor | d83c87b | 2013-01-21 01:14:12 -0500 | [diff] [blame] | 205 | void debug_serial_preinit(void); |
Kevin O'Connor | e07e18e | 2009-02-08 17:07:29 -0500 | [diff] [blame] | 206 | void panic(const char *fmt, ...) |
Kevin O'Connor | dad41d9 | 2010-01-01 03:04:19 -0500 | [diff] [blame] | 207 | __attribute__ ((format (printf, 1, 2))) __noreturn; |
Kevin O'Connor | 567e4e3 | 2008-04-05 11:37:51 -0400 | [diff] [blame] | 208 | void printf(const char *fmt, ...) |
| 209 | __attribute__ ((format (printf, 1, 2))); |
Kevin O'Connor | 2be312c | 2009-11-24 09:37:53 -0500 | [diff] [blame] | 210 | int snprintf(char *str, size_t size, const char *fmt, ...) |
Kevin O'Connor | 9ed6b62 | 2009-10-07 21:41:08 -0400 | [diff] [blame] | 211 | __attribute__ ((format (printf, 3, 4))); |
Kevin O'Connor | ca2bc1c | 2010-12-29 21:41:19 -0500 | [diff] [blame] | 212 | char * znprintf(size_t size, const char *fmt, ...) |
| 213 | __attribute__ ((format (printf, 2, 3))); |
Kevin O'Connor | cfdc13f | 2010-02-14 13:07:54 -0500 | [diff] [blame] | 214 | void __dprintf(const char *fmt, ...) |
| 215 | __attribute__ ((format (printf, 1, 2))); |
| 216 | void __debug_enter(struct bregs *regs, const char *fname); |
Kevin O'Connor | 1297e5d | 2012-06-02 20:30:58 -0400 | [diff] [blame] | 217 | void __debug_isr(const char *fname); |
Kevin O'Connor | cfdc13f | 2010-02-14 13:07:54 -0500 | [diff] [blame] | 218 | void __debug_stub(struct bregs *regs, int lineno, const char *fname); |
| 219 | void __warn_invalid(struct bregs *regs, int lineno, const char *fname); |
| 220 | void __warn_unimplemented(struct bregs *regs, int lineno, const char *fname); |
Kevin O'Connor | 7fb8ba8 | 2010-02-26 08:45:00 -0500 | [diff] [blame] | 221 | void __warn_internalerror(int lineno, const char *fname); |
Kevin O'Connor | cfdc13f | 2010-02-14 13:07:54 -0500 | [diff] [blame] | 222 | void __warn_noalloc(int lineno, const char *fname); |
| 223 | void __warn_timeout(int lineno, const char *fname); |
| 224 | void __set_invalid(struct bregs *regs, int lineno, const char *fname); |
| 225 | void __set_unimplemented(struct bregs *regs, int lineno, const char *fname); |
| 226 | void __set_code_invalid(struct bregs *regs, u32 linecode, const char *fname); |
| 227 | void __set_code_unimplemented(struct bregs *regs, u32 linecode |
| 228 | , const char *fname); |
| 229 | void hexdump(const void *d, int len); |
| 230 | |
Kevin O'Connor | ac8df8c | 2008-05-24 23:46:33 -0400 | [diff] [blame] | 231 | #define dprintf(lvl, fmt, args...) do { \ |
| 232 | if (CONFIG_DEBUG_LEVEL && (lvl) <= CONFIG_DEBUG_LEVEL) \ |
| 233 | __dprintf((fmt) , ##args ); \ |
| 234 | } while (0) |
Kevin O'Connor | 15c1f22 | 2008-06-12 22:59:43 -0400 | [diff] [blame] | 235 | #define debug_enter(regs, lvl) do { \ |
| 236 | if ((lvl) && (lvl) <= CONFIG_DEBUG_LEVEL) \ |
Kevin O'Connor | 0560034 | 2009-01-02 13:10:58 -0500 | [diff] [blame] | 237 | __debug_enter((regs), __func__); \ |
Kevin O'Connor | 15c1f22 | 2008-06-12 22:59:43 -0400 | [diff] [blame] | 238 | } while (0) |
Kevin O'Connor | 1297e5d | 2012-06-02 20:30:58 -0400 | [diff] [blame] | 239 | #define debug_isr(lvl) do { \ |
| 240 | if ((lvl) && (lvl) <= CONFIG_DEBUG_LEVEL) \ |
| 241 | __debug_isr(__func__); \ |
| 242 | } while (0) |
Kevin O'Connor | 0560034 | 2009-01-02 13:10:58 -0500 | [diff] [blame] | 243 | #define debug_stub(regs) \ |
| 244 | __debug_stub((regs), __LINE__, __func__) |
Kevin O'Connor | cfdc13f | 2010-02-14 13:07:54 -0500 | [diff] [blame] | 245 | #define warn_invalid(regs) \ |
| 246 | __warn_invalid((regs), __LINE__, __func__) |
| 247 | #define warn_unimplemented(regs) \ |
| 248 | __warn_unimplemented((regs), __LINE__, __func__) |
Kevin O'Connor | 7fb8ba8 | 2010-02-26 08:45:00 -0500 | [diff] [blame] | 249 | #define warn_internalerror() \ |
| 250 | __warn_internalerror(__LINE__, __func__) |
Kevin O'Connor | cfdc13f | 2010-02-14 13:07:54 -0500 | [diff] [blame] | 251 | #define warn_noalloc() \ |
| 252 | __warn_noalloc(__LINE__, __func__) |
| 253 | #define warn_timeout() \ |
| 254 | __warn_timeout(__LINE__, __func__) |
| 255 | #define set_invalid(regs) \ |
| 256 | __set_invalid((regs), __LINE__, __func__) |
| 257 | #define set_code_invalid(regs, code) \ |
| 258 | __set_code_invalid((regs), (code) | (__LINE__ << 8), __func__) |
| 259 | #define set_unimplemented(regs) \ |
| 260 | __set_unimplemented((regs), __LINE__, __func__) |
| 261 | #define set_code_unimplemented(regs, code) \ |
| 262 | __set_code_unimplemented((regs), (code) | (__LINE__ << 8), __func__) |
Kevin O'Connor | f076a3e | 2008-02-25 22:25:15 -0500 | [diff] [blame] | 263 | |
| 264 | // kbd.c |
Kevin O'Connor | d83c87b | 2013-01-21 01:14:12 -0500 | [diff] [blame] | 265 | void kbd_init(void); |
Kevin O'Connor | f076a3e | 2008-02-25 22:25:15 -0500 | [diff] [blame] | 266 | void handle_15c2(struct bregs *regs); |
Kevin O'Connor | 114592f | 2009-09-28 21:32:08 -0400 | [diff] [blame] | 267 | void process_key(u8 key); |
Kevin O'Connor | bdce35f | 2008-02-26 21:33:14 -0500 | [diff] [blame] | 268 | |
Kevin O'Connor | f54c150 | 2008-06-14 15:56:16 -0400 | [diff] [blame] | 269 | // mouse.c |
Kevin O'Connor | d83c87b | 2013-01-21 01:14:12 -0500 | [diff] [blame] | 270 | void mouse_init(void); |
Kevin O'Connor | 5787748 | 2009-12-09 21:00:41 -0500 | [diff] [blame] | 271 | void process_mouse(u8 data); |
Kevin O'Connor | f54c150 | 2008-06-14 15:56:16 -0400 | [diff] [blame] | 272 | |
Kevin O'Connor | 913cc2e | 2008-04-13 17:31:45 -0400 | [diff] [blame] | 273 | // serial.c |
Kevin O'Connor | 1ca05b0 | 2010-01-03 17:43:37 -0500 | [diff] [blame] | 274 | void serial_setup(void); |
| 275 | void lpt_setup(void); |
Kevin O'Connor | 913cc2e | 2008-04-13 17:31:45 -0400 | [diff] [blame] | 276 | |
Kevin O'Connor | bdce35f | 2008-02-26 21:33:14 -0500 | [diff] [blame] | 277 | // clock.c |
Kevin O'Connor | 991eaff | 2010-02-13 21:51:47 -0500 | [diff] [blame] | 278 | #define PIT_TICK_RATE 1193180 // Underlying HZ of PIT |
| 279 | #define PIT_TICK_INTERVAL 65536 // Default interval for 18.2Hz timer |
Kevin O'Connor | d83c87b | 2013-01-21 01:14:12 -0500 | [diff] [blame] | 280 | void pmtimer_setup(u16 ioport, u32 khz); |
Kevin O'Connor | 745de85 | 2012-01-29 14:15:14 -0500 | [diff] [blame] | 281 | int check_tsc(u64 end); |
Kevin O'Connor | 1ca05b0 | 2010-01-03 17:43:37 -0500 | [diff] [blame] | 282 | void timer_setup(void); |
Kevin O'Connor | bc2aecd | 2008-11-28 16:40:06 -0500 | [diff] [blame] | 283 | void ndelay(u32 count); |
| 284 | void udelay(u32 count); |
| 285 | void mdelay(u32 count); |
Kevin O'Connor | 10ad799 | 2009-10-24 11:06:08 -0400 | [diff] [blame] | 286 | void nsleep(u32 count); |
| 287 | void usleep(u32 count); |
| 288 | void msleep(u32 count); |
Kevin O'Connor | 4e6c970 | 2008-12-13 10:45:50 -0500 | [diff] [blame] | 289 | u64 calc_future_tsc(u32 msecs); |
Kevin O'Connor | 1c46a54 | 2009-10-17 23:53:32 -0400 | [diff] [blame] | 290 | u64 calc_future_tsc_usec(u32 usecs); |
Kevin O'Connor | b5cc2ca | 2010-05-23 11:38:53 -0400 | [diff] [blame] | 291 | u32 calc_future_timer_ticks(u32 count); |
| 292 | u32 calc_future_timer(u32 msecs); |
| 293 | int check_timer(u32 end); |
Kevin O'Connor | bdce35f | 2008-02-26 21:33:14 -0500 | [diff] [blame] | 294 | void handle_1583(struct bregs *regs); |
Kevin O'Connor | 5be0490 | 2008-05-18 17:12:06 -0400 | [diff] [blame] | 295 | void handle_1586(struct bregs *regs); |
Kevin O'Connor | 1ca05b0 | 2010-01-03 17:43:37 -0500 | [diff] [blame] | 296 | void useRTC(void); |
| 297 | void releaseRTC(void); |
Kevin O'Connor | bdce35f | 2008-02-26 21:33:14 -0500 | [diff] [blame] | 298 | |
Kevin O'Connor | 95b2f78 | 2008-03-05 19:52:06 -0500 | [diff] [blame] | 299 | // apm.c |
Kevin O'Connor | 244caf8 | 2010-09-15 21:48:16 -0400 | [diff] [blame] | 300 | void apm_shutdown(void); |
Kevin O'Connor | c003148 | 2010-01-01 13:03:17 -0500 | [diff] [blame] | 301 | void handle_1553(struct bregs *regs); |
Kevin O'Connor | 95b2f78 | 2008-03-05 19:52:06 -0500 | [diff] [blame] | 302 | |
Kevin O'Connor | a0dc296 | 2008-03-16 14:29:32 -0400 | [diff] [blame] | 303 | // pcibios.c |
| 304 | void handle_1ab1(struct bregs *regs); |
Kevin O'Connor | d83c87b | 2013-01-21 01:14:12 -0500 | [diff] [blame] | 305 | void bios32_init(void); |
Kevin O'Connor | a0dc296 | 2008-03-16 14:29:32 -0400 | [diff] [blame] | 306 | |
Kevin O'Connor | da4a648 | 2008-06-08 13:48:06 -0400 | [diff] [blame] | 307 | // shadow.c |
Kevin O'Connor | 1ca05b0 | 2010-01-03 17:43:37 -0500 | [diff] [blame] | 308 | void make_bios_writable(void); |
| 309 | void make_bios_readonly(void); |
Kevin O'Connor | 244caf8 | 2010-09-15 21:48:16 -0400 | [diff] [blame] | 310 | void qemu_prep_reset(void); |
Kevin O'Connor | da4a648 | 2008-06-08 13:48:06 -0400 | [diff] [blame] | 311 | |
Kevin O'Connor | 0525d29 | 2008-07-04 06:18:30 -0400 | [diff] [blame] | 312 | // pciinit.c |
Kevin O'Connor | 0d6b8d5 | 2010-07-10 13:12:37 -0400 | [diff] [blame] | 313 | extern const u8 pci_irqs[4]; |
Kevin O'Connor | 40f5b5a | 2009-09-13 10:46:57 -0400 | [diff] [blame] | 314 | void pci_setup(void); |
Kevin O'Connor | a4d3576 | 2008-03-08 15:43:03 -0500 | [diff] [blame] | 315 | |
Kevin O'Connor | f7ba6d7 | 2008-07-04 05:05:54 -0400 | [diff] [blame] | 316 | // smm.c |
Kevin O'Connor | cdbac7f | 2013-03-08 19:33:39 -0500 | [diff] [blame] | 317 | void smm_device_setup(void); |
Kevin O'Connor | d83c87b | 2013-01-21 01:14:12 -0500 | [diff] [blame] | 318 | void smm_setup(void); |
Kevin O'Connor | f7ba6d7 | 2008-07-04 05:05:54 -0400 | [diff] [blame] | 319 | |
Kevin O'Connor | e97ca7b | 2009-06-21 09:10:28 -0400 | [diff] [blame] | 320 | // smp.c |
Kevin O'Connor | 603bfc3 | 2009-06-22 20:04:56 -0400 | [diff] [blame] | 321 | extern u32 CountCPUs; |
Kevin O'Connor | 8470585 | 2009-10-08 22:13:15 -0400 | [diff] [blame] | 322 | extern u32 MaxCountCPUs; |
Kevin O'Connor | e97ca7b | 2009-06-21 09:10:28 -0400 | [diff] [blame] | 323 | void wrmsr_smp(u32 index, u64 val); |
Kevin O'Connor | d83c87b | 2013-01-21 01:14:12 -0500 | [diff] [blame] | 324 | void smp_setup(void); |
Eduardo Habkost | 008c1fc | 2012-07-25 15:45:30 -0300 | [diff] [blame] | 325 | int apic_id_is_present(u8 apic_id); |
Kevin O'Connor | 84ad59a | 2008-07-04 05:47:26 -0400 | [diff] [blame] | 326 | |
Kevin O'Connor | c781293 | 2008-06-08 23:08:12 -0400 | [diff] [blame] | 327 | // coreboot.c |
Kevin O'Connor | c1de91b | 2011-07-02 13:50:21 -0400 | [diff] [blame] | 328 | extern const char *CBvendor, *CBpart; |
Kevin O'Connor | 1edc89d | 2009-04-30 21:50:35 -0400 | [diff] [blame] | 329 | struct cbfs_file; |
Kevin O'Connor | 1f83625 | 2009-08-16 20:17:35 -0400 | [diff] [blame] | 330 | void cbfs_run_payload(struct cbfs_file *file); |
Kevin O'Connor | a2a86e2 | 2013-02-13 19:35:12 -0500 | [diff] [blame] | 331 | void coreboot_platform_setup(void); |
Kevin O'Connor | 89a1efd | 2011-01-08 12:24:39 -0500 | [diff] [blame] | 332 | void cbfs_payload_setup(void); |
Kevin O'Connor | d83c87b | 2013-01-21 01:14:12 -0500 | [diff] [blame] | 333 | void coreboot_preinit(void); |
| 334 | void coreboot_cbfs_init(void); |
Kevin O'Connor | c781293 | 2008-06-08 23:08:12 -0400 | [diff] [blame] | 335 | |
Ian Campbell | 1442c31 | 2011-06-01 11:00:28 +0100 | [diff] [blame] | 336 | // biostable.c |
David Woodhouse | 38b24db | 2013-01-25 19:33:58 -0600 | [diff] [blame] | 337 | void copy_smbios(void *pos); |
Kevin O'Connor | 4d053eb | 2012-06-09 13:08:02 -0400 | [diff] [blame] | 338 | void copy_table(void *pos); |
Ian Campbell | 1442c31 | 2011-06-01 11:00:28 +0100 | [diff] [blame] | 339 | |
Kevin O'Connor | cbffa8e | 2008-08-17 11:11:07 -0400 | [diff] [blame] | 340 | // vgahooks.c |
Kevin O'Connor | 1ca05b0 | 2010-01-03 17:43:37 -0500 | [diff] [blame] | 341 | void handle_155f(struct bregs *regs); |
Kevin O'Connor | c1de91b | 2011-07-02 13:50:21 -0400 | [diff] [blame] | 342 | struct pci_device; |
| 343 | void vgahook_setup(struct pci_device *pci); |
Kevin O'Connor | cbffa8e | 2008-08-17 11:11:07 -0400 | [diff] [blame] | 344 | |
Kevin O'Connor | 714325c | 2008-11-01 20:32:27 -0400 | [diff] [blame] | 345 | // optionroms.c |
Kevin O'Connor | 0a92412 | 2009-02-08 19:43:47 -0500 | [diff] [blame] | 346 | void call_bcv(u16 seg, u16 ip); |
Alex Williamson | 7adfd71 | 2013-03-20 10:58:47 -0600 | [diff] [blame] | 347 | int is_pci_vga(struct pci_device *pci); |
Kevin O'Connor | 1ca05b0 | 2010-01-03 17:43:37 -0500 | [diff] [blame] | 348 | void optionrom_setup(void); |
Kevin O'Connor | d83c87b | 2013-01-21 01:14:12 -0500 | [diff] [blame] | 349 | void vgarom_setup(void); |
| 350 | void s3_resume_vga(void); |
Kevin O'Connor | 422263d | 2011-07-05 20:56:07 -0400 | [diff] [blame] | 351 | extern int ScreenAndDebug; |
Kevin O'Connor | 714325c | 2008-11-01 20:32:27 -0400 | [diff] [blame] | 352 | |
Kevin O'Connor | afbed1b | 2010-06-28 07:34:53 -0400 | [diff] [blame] | 353 | // bootsplash.c |
| 354 | void enable_vga_console(void); |
Kevin O'Connor | 9a01a9c | 2010-08-25 21:07:48 -0400 | [diff] [blame] | 355 | void enable_bootsplash(void); |
Kevin O'Connor | afbed1b | 2010-06-28 07:34:53 -0400 | [diff] [blame] | 356 | void disable_bootsplash(void); |
| 357 | |
Kevin O'Connor | 18e38b2 | 2008-12-10 20:40:13 -0500 | [diff] [blame] | 358 | // resume.c |
Kevin O'Connor | 87b533b | 2011-07-10 22:35:07 -0400 | [diff] [blame] | 359 | extern int HaveRunPost; |
Kevin O'Connor | 9e4d41c | 2013-01-21 12:14:29 -0500 | [diff] [blame] | 360 | void dma_setup(void); |
Kevin O'Connor | 18e38b2 | 2008-12-10 20:40:13 -0500 | [diff] [blame] | 361 | |
Kevin O'Connor | 0c3068d | 2008-12-21 17:51:36 -0500 | [diff] [blame] | 362 | // pnpbios.c |
| 363 | #define PNP_SIGNATURE 0x506e5024 // $PnP |
Kevin O'Connor | 1ca05b0 | 2010-01-03 17:43:37 -0500 | [diff] [blame] | 364 | u16 get_pnp_offset(void); |
Kevin O'Connor | d83c87b | 2013-01-21 01:14:12 -0500 | [diff] [blame] | 365 | void pnp_init(void); |
Kevin O'Connor | 0c3068d | 2008-12-21 17:51:36 -0500 | [diff] [blame] | 366 | |
Kevin O'Connor | e54ee38 | 2009-07-26 19:33:13 -0400 | [diff] [blame] | 367 | // pmm.c |
Kevin O'Connor | 415d429 | 2009-08-30 19:19:31 -0400 | [diff] [blame] | 368 | extern struct zone_s ZoneLow, ZoneHigh, ZoneFSeg, ZoneTmpLow, ZoneTmpHigh; |
Kevin O'Connor | 3733f6f | 2013-02-17 12:44:23 -0500 | [diff] [blame] | 369 | u32 rom_get_max(void); |
Kevin O'Connor | 5e01908 | 2012-05-20 21:11:43 -0400 | [diff] [blame] | 370 | u32 rom_get_last(void); |
| 371 | struct rom_header *rom_reserve(u32 size); |
| 372 | int rom_confirm(u32 size); |
David Woodhouse | 118469a | 2013-01-25 19:46:25 -0600 | [diff] [blame] | 373 | void csm_malloc_preinit(u32 low_pmm, u32 low_pmm_size, u32 hi_pmm, |
| 374 | u32 hi_pmm_size); |
Kevin O'Connor | d83c87b | 2013-01-21 01:14:12 -0500 | [diff] [blame] | 375 | void malloc_preinit(void); |
Kevin O'Connor | f85e4bc | 2013-02-19 01:33:45 -0500 | [diff] [blame] | 376 | extern u32 LegacyRamSize; |
Kevin O'Connor | 6afc6f8 | 2013-02-19 01:02:50 -0500 | [diff] [blame] | 377 | void malloc_init(void); |
Kevin O'Connor | d83c87b | 2013-01-21 01:14:12 -0500 | [diff] [blame] | 378 | void malloc_prepboot(void); |
Kevin O'Connor | d948e2b | 2009-10-12 12:54:56 -0400 | [diff] [blame] | 379 | void *pmm_malloc(struct zone_s *zone, u32 handle, u32 size, u32 align); |
| 380 | int pmm_free(void *data); |
Kevin O'Connor | d83c87b | 2013-01-21 01:14:12 -0500 | [diff] [blame] | 381 | void pmm_init(void); |
| 382 | void pmm_prepboot(void); |
Kevin O'Connor | d948e2b | 2009-10-12 12:54:56 -0400 | [diff] [blame] | 383 | #define PMM_DEFAULT_HANDLE 0xFFFFFFFF |
Kevin O'Connor | 0bf9270 | 2009-08-01 11:45:37 -0400 | [diff] [blame] | 384 | // Minimum alignment of malloc'd memory |
| 385 | #define MALLOC_MIN_ALIGN 16 |
Kevin O'Connor | 415d429 | 2009-08-30 19:19:31 -0400 | [diff] [blame] | 386 | // Helper functions for memory allocation. |
Kevin O'Connor | f416fe9 | 2009-09-24 20:51:55 -0400 | [diff] [blame] | 387 | static inline void *malloc_low(u32 size) { |
Kevin O'Connor | d948e2b | 2009-10-12 12:54:56 -0400 | [diff] [blame] | 388 | return pmm_malloc(&ZoneLow, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN); |
Kevin O'Connor | f416fe9 | 2009-09-24 20:51:55 -0400 | [diff] [blame] | 389 | } |
Kevin O'Connor | 415d429 | 2009-08-30 19:19:31 -0400 | [diff] [blame] | 390 | static inline void *malloc_high(u32 size) { |
Kevin O'Connor | d948e2b | 2009-10-12 12:54:56 -0400 | [diff] [blame] | 391 | return pmm_malloc(&ZoneHigh, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN); |
Kevin O'Connor | 415d429 | 2009-08-30 19:19:31 -0400 | [diff] [blame] | 392 | } |
| 393 | static inline void *malloc_fseg(u32 size) { |
Kevin O'Connor | d948e2b | 2009-10-12 12:54:56 -0400 | [diff] [blame] | 394 | return pmm_malloc(&ZoneFSeg, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN); |
Kevin O'Connor | 415d429 | 2009-08-30 19:19:31 -0400 | [diff] [blame] | 395 | } |
Kevin O'Connor | a576c9c | 2010-07-26 22:43:18 -0400 | [diff] [blame] | 396 | static inline void *malloc_tmplow(u32 size) { |
| 397 | return pmm_malloc(&ZoneTmpLow, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN); |
| 398 | } |
Kevin O'Connor | 114592f | 2009-09-28 21:32:08 -0400 | [diff] [blame] | 399 | static inline void *malloc_tmphigh(u32 size) { |
Kevin O'Connor | d948e2b | 2009-10-12 12:54:56 -0400 | [diff] [blame] | 400 | return pmm_malloc(&ZoneTmpHigh, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN); |
Kevin O'Connor | 114592f | 2009-09-28 21:32:08 -0400 | [diff] [blame] | 401 | } |
Kevin O'Connor | 575ffc8 | 2010-02-21 23:20:10 -0500 | [diff] [blame] | 402 | static inline void *malloc_tmp(u32 size) { |
| 403 | void *ret = malloc_tmphigh(size); |
| 404 | if (ret) |
| 405 | return ret; |
Kevin O'Connor | a576c9c | 2010-07-26 22:43:18 -0400 | [diff] [blame] | 406 | return malloc_tmplow(size); |
Kevin O'Connor | 575ffc8 | 2010-02-21 23:20:10 -0500 | [diff] [blame] | 407 | } |
Kevin O'Connor | 9ed6b62 | 2009-10-07 21:41:08 -0400 | [diff] [blame] | 408 | static inline void *memalign_low(u32 align, u32 size) { |
Kevin O'Connor | d948e2b | 2009-10-12 12:54:56 -0400 | [diff] [blame] | 409 | return pmm_malloc(&ZoneLow, PMM_DEFAULT_HANDLE, size, align); |
Kevin O'Connor | 415d429 | 2009-08-30 19:19:31 -0400 | [diff] [blame] | 410 | } |
| 411 | static inline void *memalign_high(u32 align, u32 size) { |
Kevin O'Connor | d948e2b | 2009-10-12 12:54:56 -0400 | [diff] [blame] | 412 | return pmm_malloc(&ZoneHigh, PMM_DEFAULT_HANDLE, size, align); |
Kevin O'Connor | 415d429 | 2009-08-30 19:19:31 -0400 | [diff] [blame] | 413 | } |
Kevin O'Connor | 12fa24a | 2010-09-15 00:25:32 -0400 | [diff] [blame] | 414 | static inline void *memalign_tmplow(u32 align, u32 size) { |
| 415 | return pmm_malloc(&ZoneTmpLow, PMM_DEFAULT_HANDLE, size, align); |
| 416 | } |
Kevin O'Connor | 9ed6b62 | 2009-10-07 21:41:08 -0400 | [diff] [blame] | 417 | static inline void *memalign_tmphigh(u32 align, u32 size) { |
Kevin O'Connor | d948e2b | 2009-10-12 12:54:56 -0400 | [diff] [blame] | 418 | return pmm_malloc(&ZoneTmpHigh, PMM_DEFAULT_HANDLE, size, align); |
| 419 | } |
Kevin O'Connor | 12fa24a | 2010-09-15 00:25:32 -0400 | [diff] [blame] | 420 | static inline void *memalign_tmp(u32 align, u32 size) { |
| 421 | void *ret = memalign_tmphigh(align, size); |
| 422 | if (ret) |
| 423 | return ret; |
| 424 | return memalign_tmplow(align, size); |
| 425 | } |
Kevin O'Connor | d948e2b | 2009-10-12 12:54:56 -0400 | [diff] [blame] | 426 | static inline void free(void *data) { |
| 427 | pmm_free(data); |
Kevin O'Connor | 9ed6b62 | 2009-10-07 21:41:08 -0400 | [diff] [blame] | 428 | } |
Kevin O'Connor | e54ee38 | 2009-07-26 19:33:13 -0400 | [diff] [blame] | 429 | |
Kevin O'Connor | 7061eb6 | 2009-01-04 21:48:22 -0500 | [diff] [blame] | 430 | // mtrr.c |
| 431 | void mtrr_setup(void); |
| 432 | |
Kevin O'Connor | 59d6ca5 | 2012-05-31 00:20:55 -0400 | [diff] [blame] | 433 | // romfile.c |
| 434 | struct romfile_s { |
| 435 | struct romfile_s *next; |
| 436 | char name[128]; |
| 437 | u32 size; |
| 438 | int (*copy)(struct romfile_s *file, void *dest, u32 maxlen); |
Kevin O'Connor | 59d6ca5 | 2012-05-31 00:20:55 -0400 | [diff] [blame] | 439 | }; |
| 440 | void romfile_add(struct romfile_s *file); |
| 441 | struct romfile_s *romfile_findprefix(const char *prefix, struct romfile_s *prev); |
| 442 | struct romfile_s *romfile_find(const char *name); |
| 443 | void *romfile_loadfile(const char *name, int *psize); |
| 444 | u64 romfile_loadint(const char *name, u64 defval); |
| 445 | |
Kevin O'Connor | 18e38b2 | 2008-12-10 20:40:13 -0500 | [diff] [blame] | 446 | // romlayout.S |
Kevin O'Connor | 1ca05b0 | 2010-01-03 17:43:37 -0500 | [diff] [blame] | 447 | void reset_vector(void) __noreturn; |
Kevin O'Connor | 18e38b2 | 2008-12-10 20:40:13 -0500 | [diff] [blame] | 448 | |
Kevin O'Connor | 3085376 | 2009-01-17 18:49:20 -0500 | [diff] [blame] | 449 | // misc.c |
Kevin O'Connor | 3a735ba | 2013-02-10 00:35:01 -0500 | [diff] [blame] | 450 | void mathcp_setup(void); |
Kevin O'Connor | 3085376 | 2009-01-17 18:49:20 -0500 | [diff] [blame] | 451 | extern u8 BiosChecksum; |
| 452 | |
Kevin O'Connor | c95d2ce | 2009-07-29 20:41:39 -0400 | [diff] [blame] | 453 | // version (auto generated file out/version.c) |
| 454 | extern const char VERSION[]; |
| 455 | |
Kevin O'Connor | 786502d | 2008-02-27 10:41:41 -0500 | [diff] [blame] | 456 | #endif // util.h |