blob: 36e9a30594e44c00cc70c7156267ead172a71e88 [file] [log] [blame]
Kevin O'Connorf076a3e2008-02-25 22:25:15 -05001// Basic x86 asm functions and function defs.
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.
Kevin O'Connor786502d2008-02-27 10:41:41 -05006#ifndef __UTIL_H
7#define __UTIL_H
Kevin O'Connorf076a3e2008-02-25 22:25:15 -05008
9#include "ioport.h" // outb
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050010#include "biosvar.h" // struct bregs
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050011
Kevin O'Connor786502d2008-02-27 10:41:41 -050012static inline void irq_disable(void)
13{
14 asm volatile("cli": : :"memory");
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050015}
16
Kevin O'Connor786502d2008-02-27 10:41:41 -050017static inline void irq_enable(void)
18{
19 asm volatile("sti": : :"memory");
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050020}
21
22static inline unsigned long irq_save(void)
23{
24 unsigned long flags;
25 asm volatile("pushfl ; popl %0" : "=g" (flags));
26 irq_disable();
27 return flags;
28}
29
30static inline void irq_restore(unsigned long flags)
31{
32 asm volatile("pushl %0 ; popfl" : : "g" (flags) : "memory", "cc");
33}
34
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050035static inline void nop(void)
36{
37 asm volatile("nop");
38}
39
Kevin O'Connor95b2f782008-03-05 19:52:06 -050040static inline void hlt(void)
41{
42 asm volatile("hlt");
43}
44
Kevin O'Connor8ce2cd82008-03-02 08:48:05 -050045#define BX_PANIC(fmt, args...) bprintf(0, fmt , ##args)
Kevin O'Connor4ce6a492008-02-29 00:21:27 -050046#define BX_INFO(fmt, args...) bprintf(0, fmt , ##args)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050047
48static inline void
49memset(void *s, int c, size_t n)
50{
51 while (n)
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050052 ((char *)s)[--n] = c;
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050053}
54
Kevin O'Connora4d35762008-03-08 15:43:03 -050055static inline void *
56memcpy(void *d1, const void *s1, size_t len)
57{
58 u8 *d = d1;
59 const u8 *s = s1;
60
61 while (len--) {
62 *d++ = *s++;
63 }
64 return d1;
65}
66
Kevin O'Connor4b60c002008-02-25 22:29:55 -050067static inline void
68eoi_master_pic()
69{
70 outb(PIC1_IRQ5, PORT_PIC1);
71}
72
73static inline void
74eoi_both_pics()
75{
76 outb(PIC2_IRQ13, PORT_PIC2);
77 eoi_master_pic();
78}
79
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050080static inline
81void call16(struct bregs *callregs)
82{
83 asm volatile(
Kevin O'Connorb8aacb02008-03-01 14:56:07 -050084 "pushl %%ebp\n" // Save state
85 "pushfl\n"
Kevin O'Connor3a47a312008-03-01 14:46:37 -050086#ifdef MODE16
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050087 "calll __call16\n"
Kevin O'Connor3a47a312008-03-01 14:46:37 -050088#else
89 "calll __call16_from32\n"
90#endif
Kevin O'Connorb8aacb02008-03-01 14:56:07 -050091 "popfl\n" // Restore state
92 "popl %%ebp\n"
Kevin O'Connor8ce2cd82008-03-02 08:48:05 -050093 : "+a" (callregs), "+m" (*callregs)
94 :
Kevin O'Connorb8aacb02008-03-01 14:56:07 -050095 : "ebx", "ecx", "edx", "esi", "edi");
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050096}
97
Kevin O'Connor3a47a312008-03-01 14:46:37 -050098static inline
99void __call16_int(struct bregs *callregs, u16 offset)
100{
Kevin O'Connor44c631d2008-03-02 11:24:36 -0500101 callregs->cs = SEG_BIOS;
Kevin O'Connor3a47a312008-03-01 14:46:37 -0500102 callregs->ip = offset;
103 call16(callregs);
104}
105
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500106#ifdef MODE16
Kevin O'Connor3a47a312008-03-01 14:46:37 -0500107#define call16_int(nr, callregs) do { \
108 extern void irq_trampoline_ ##nr (); \
109 __call16_int((callregs), (u16)&irq_trampoline_ ##nr ); \
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500110 } while (0)
111#else
112#include "../out/rom16.offset.auto.h"
Kevin O'Connor3a47a312008-03-01 14:46:37 -0500113#define call16_int(nr, callregs) \
114 __call16_int((callregs), OFFSET_irq_trampoline_ ##nr )
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500115#endif
116
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500117// output.c
118void bprintf(u16 action, const char *fmt, ...)
119 __attribute__ ((format (printf, 2, 3)));
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500120void __debug_enter(const char *fname, struct bregs *regs);
Kevin O'Connor6c781222008-03-09 12:19:23 -0400121void __debug_fail(const char *fname, struct bregs *regs);
Kevin O'Connor4ce6a492008-02-29 00:21:27 -0500122void __debug_stub(const char *fname, struct bregs *regs);
Kevin O'Connorc65a3802008-03-02 13:58:23 -0500123void __debug_isr(const char *fname, struct bregs *regs);
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500124#define debug_enter(regs) \
125 __debug_enter(__func__, regs)
Kevin O'Connor4ce6a492008-02-29 00:21:27 -0500126#define debug_stub(regs) \
127 __debug_stub(__func__, regs)
Kevin O'Connorc65a3802008-03-02 13:58:23 -0500128#define debug_isr(regs) \
129 __debug_isr(__func__, regs)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500130#define printf(fmt, args...) \
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500131 bprintf(1, fmt , ##args )
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500132
Kevin O'Connor6c781222008-03-09 12:19:23 -0400133// Frequently used return codes
134#define RET_EUNSUPPORTED 0x86
135static inline void
136set_success(struct bregs *regs)
137{
138 set_cf(regs, 0);
139}
140
141static inline void
142set_code_success(struct bregs *regs)
143{
144 regs->ah = 0;
145 set_cf(regs, 0);
146}
147
148#define set_fail(regs) do { \
149 __debug_fail(__func__, (regs)); \
150 set_cf((regs), 1); \
151 } while (0)
152
153#define set_code_fail(regs, code) do { \
Kevin O'Connor6c781222008-03-09 12:19:23 -0400154 set_fail(regs); \
Kevin O'Connorf205f9f2008-03-09 16:11:49 -0400155 (regs)->ah = (code); \
Kevin O'Connor6c781222008-03-09 12:19:23 -0400156 } while (0)
157
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500158// kbd.c
159void handle_15c2(struct bregs *regs);
Kevin O'Connorbdce35f2008-02-26 21:33:14 -0500160
161// clock.c
162void handle_1583(struct bregs *regs);
163
Kevin O'Connor95b2f782008-03-05 19:52:06 -0500164// apm.c
Kevin O'Connor44d65302008-03-08 11:34:46 -0500165void VISIBLE16 handle_1553(struct bregs *regs);
Kevin O'Connor95b2f782008-03-05 19:52:06 -0500166
Kevin O'Connora4d35762008-03-08 15:43:03 -0500167// util.c
168void usleep(u32 count);
169
170// rombios32.c
171void rombios32_init(void);
172
Kevin O'Connor786502d2008-02-27 10:41:41 -0500173#endif // util.h