blob: 29446b3038dd6dd9fa659194f718295597df3f98 [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'Connor8ce2cd82008-03-02 08:48:05 -050040#define BX_PANIC(fmt, args...) bprintf(0, fmt , ##args)
Kevin O'Connor4ce6a492008-02-29 00:21:27 -050041#define BX_INFO(fmt, args...) bprintf(0, fmt , ##args)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050042
43static inline void
44memset(void *s, int c, size_t n)
45{
46 while (n)
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050047 ((char *)s)[--n] = c;
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050048}
49
Kevin O'Connor4b60c002008-02-25 22:29:55 -050050static inline void
51eoi_master_pic()
52{
53 outb(PIC1_IRQ5, PORT_PIC1);
54}
55
56static inline void
57eoi_both_pics()
58{
59 outb(PIC2_IRQ13, PORT_PIC2);
60 eoi_master_pic();
61}
62
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050063static inline
64void call16(struct bregs *callregs)
65{
66 asm volatile(
Kevin O'Connorb8aacb02008-03-01 14:56:07 -050067 "pushl %%ebp\n" // Save state
68 "pushfl\n"
Kevin O'Connor3a47a312008-03-01 14:46:37 -050069#ifdef MODE16
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050070 "calll __call16\n"
Kevin O'Connor3a47a312008-03-01 14:46:37 -050071#else
72 "calll __call16_from32\n"
73#endif
Kevin O'Connorb8aacb02008-03-01 14:56:07 -050074 "popfl\n" // Restore state
75 "popl %%ebp\n"
Kevin O'Connor8ce2cd82008-03-02 08:48:05 -050076 : "+a" (callregs), "+m" (*callregs)
77 :
Kevin O'Connorb8aacb02008-03-01 14:56:07 -050078 : "ebx", "ecx", "edx", "esi", "edi");
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050079}
80
Kevin O'Connor3a47a312008-03-01 14:46:37 -050081static inline
82void __call16_int(struct bregs *callregs, u16 offset)
83{
Kevin O'Connor44c631d2008-03-02 11:24:36 -050084 callregs->cs = SEG_BIOS;
Kevin O'Connor3a47a312008-03-01 14:46:37 -050085 callregs->ip = offset;
86 call16(callregs);
87}
88
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050089#ifdef MODE16
Kevin O'Connor3a47a312008-03-01 14:46:37 -050090#define call16_int(nr, callregs) do { \
91 extern void irq_trampoline_ ##nr (); \
92 __call16_int((callregs), (u16)&irq_trampoline_ ##nr ); \
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050093 } while (0)
94#else
95#include "../out/rom16.offset.auto.h"
Kevin O'Connor3a47a312008-03-01 14:46:37 -050096#define call16_int(nr, callregs) \
97 __call16_int((callregs), OFFSET_irq_trampoline_ ##nr )
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050098#endif
99
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500100// output.c
101void bprintf(u16 action, const char *fmt, ...)
102 __attribute__ ((format (printf, 2, 3)));
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500103void __debug_enter(const char *fname, struct bregs *regs);
104void __debug_exit(const char *fname, struct bregs *regs);
Kevin O'Connor4ce6a492008-02-29 00:21:27 -0500105void __debug_stub(const char *fname, struct bregs *regs);
Kevin O'Connorc65a3802008-03-02 13:58:23 -0500106void __debug_isr(const char *fname, struct bregs *regs);
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500107#define debug_enter(regs) \
108 __debug_enter(__func__, regs)
109#define debug_exit(regs) \
110 __debug_exit(__func__, regs)
Kevin O'Connor4ce6a492008-02-29 00:21:27 -0500111#define debug_stub(regs) \
112 __debug_stub(__func__, regs)
Kevin O'Connorc65a3802008-03-02 13:58:23 -0500113#define debug_isr(regs) \
114 __debug_isr(__func__, regs)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500115#define printf(fmt, args...) \
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500116 bprintf(1, fmt , ##args )
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500117
118// kbd.c
119void handle_15c2(struct bregs *regs);
Kevin O'Connorbdce35f2008-02-26 21:33:14 -0500120
121// clock.c
122void handle_1583(struct bregs *regs);
123
124// Frequent bios return helper
125#define RET_EUNSUPPORTED 0x86
126static inline void
127handle_ret(struct bregs *regs, u8 code)
128{
129 regs->ah = code;
130 set_cf(regs, code);
131}
Kevin O'Connor786502d2008-02-27 10:41:41 -0500132
133#endif // util.h