blob: b858e8cb43fb07b2455c6a6186a88e4b9e54274f [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 DEBUGF(fmt, args...) bprintf(0, fmt , ##args)
41#define BX_PANIC(fmt, args...) bprintf(0, fmt , ##args)
Kevin O'Connor4ce6a492008-02-29 00:21:27 -050042#define BX_INFO(fmt, args...) bprintf(0, fmt , ##args)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050043
44static inline void
45memset(void *s, int c, size_t n)
46{
47 while (n)
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050048 ((char *)s)[--n] = c;
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050049}
50
Kevin O'Connor4b60c002008-02-25 22:29:55 -050051static inline void
52eoi_master_pic()
53{
54 outb(PIC1_IRQ5, PORT_PIC1);
55}
56
57static inline void
58eoi_both_pics()
59{
60 outb(PIC2_IRQ13, PORT_PIC2);
61 eoi_master_pic();
62}
63
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050064static inline
65void call16(struct bregs *callregs)
66{
67 asm volatile(
Kevin O'Connorb8aacb02008-03-01 14:56:07 -050068 "pushl %%ebp\n" // Save state
69 "pushfl\n"
Kevin O'Connor3a47a312008-03-01 14:46:37 -050070#ifdef MODE16
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050071 "calll __call16\n"
Kevin O'Connor3a47a312008-03-01 14:46:37 -050072#else
73 "calll __call16_from32\n"
74#endif
Kevin O'Connorb8aacb02008-03-01 14:56:07 -050075 "popfl\n" // Restore state
76 "popl %%ebp\n"
Kevin O'Connor8ce2cd82008-03-02 08:48:05 -050077 : "+a" (callregs), "+m" (*callregs)
78 :
Kevin O'Connorb8aacb02008-03-01 14:56:07 -050079 : "ebx", "ecx", "edx", "esi", "edi");
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050080}
81
Kevin O'Connor3a47a312008-03-01 14:46:37 -050082static inline
83void __call16_int(struct bregs *callregs, u16 offset)
84{
Kevin O'Connor44c631d2008-03-02 11:24:36 -050085 callregs->cs = SEG_BIOS;
Kevin O'Connor3a47a312008-03-01 14:46:37 -050086 callregs->ip = offset;
87 call16(callregs);
88}
89
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050090#ifdef MODE16
Kevin O'Connor3a47a312008-03-01 14:46:37 -050091#define call16_int(nr, callregs) do { \
92 extern void irq_trampoline_ ##nr (); \
93 __call16_int((callregs), (u16)&irq_trampoline_ ##nr ); \
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050094 } while (0)
95#else
96#include "../out/rom16.offset.auto.h"
Kevin O'Connor3a47a312008-03-01 14:46:37 -050097#define call16_int(nr, callregs) \
98 __call16_int((callregs), OFFSET_irq_trampoline_ ##nr )
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050099#endif
100
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500101// output.c
102void bprintf(u16 action, const char *fmt, ...)
103 __attribute__ ((format (printf, 2, 3)));
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500104void __debug_enter(const char *fname, struct bregs *regs);
105void __debug_exit(const char *fname, struct bregs *regs);
Kevin O'Connor4ce6a492008-02-29 00:21:27 -0500106void __debug_stub(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'Connorf076a3e2008-02-25 22:25:15 -0500113#define printf(fmt, args...) \
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500114 bprintf(1, fmt , ##args )
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500115
116// kbd.c
117void handle_15c2(struct bregs *regs);
Kevin O'Connorbdce35f2008-02-26 21:33:14 -0500118
119// clock.c
120void handle_1583(struct bregs *regs);
121
122// Frequent bios return helper
123#define RET_EUNSUPPORTED 0x86
124static inline void
125handle_ret(struct bregs *regs, u8 code)
126{
127 regs->ah = code;
128 set_cf(regs, code);
129}
Kevin O'Connor786502d2008-02-27 10:41:41 -0500130
131#endif // util.h