blob: ec52eac7acc1b5fff1120e157ee0909b5bf427c4 [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'Connor06ad44e2008-04-05 19:30:02 -040035static inline void cpu_relax(void)
36{
37 asm volatile("rep ; nop": : :"memory");
38}
39
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050040static inline void nop(void)
41{
42 asm volatile("nop");
43}
44
Kevin O'Connor95b2f782008-03-05 19:52:06 -050045static inline void hlt(void)
46{
47 asm volatile("hlt");
48}
49
Kevin O'Connor5e4235f2008-04-12 09:00:04 -040050void *memset(void *s, int c, size_t n);
Kevin O'Connor567e4e32008-04-05 11:37:51 -040051void *memcpy(void *d1, const void *s1, size_t len);
Kevin O'Connora4d35762008-03-08 15:43:03 -050052
Kevin O'Connor4b60c002008-02-25 22:29:55 -050053static inline void
54eoi_master_pic()
55{
56 outb(PIC1_IRQ5, PORT_PIC1);
57}
58
59static inline void
60eoi_both_pics()
61{
62 outb(PIC2_IRQ13, PORT_PIC2);
63 eoi_master_pic();
64}
65
Kevin O'Connor7a558e42008-03-11 20:38:33 -040066// Call a function with a specified register state. Note that on
67// return, the interrupt enable/disable flag may be altered.
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050068static inline
69void call16(struct bregs *callregs)
70{
71 asm volatile(
Kevin O'Connor3a47a312008-03-01 14:46:37 -050072#ifdef MODE16
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050073 "calll __call16\n"
Kevin O'Connor3a47a312008-03-01 14:46:37 -050074#else
75 "calll __call16_from32\n"
76#endif
Kevin O'Connor8ce2cd82008-03-02 08:48:05 -050077 : "+a" (callregs), "+m" (*callregs)
78 :
Kevin O'Connor7a558e42008-03-11 20:38:33 -040079 : "ebx", "ecx", "edx", "esi", "edi", "ebp", "cc");
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
Kevin O'Connor567e4e32008-04-05 11:37:51 -0400102void BX_PANIC(const char *fmt, ...)
103 __attribute__ ((format (printf, 1, 2)))
104 __attribute__ ((noreturn));
105void BX_INFO(const char *fmt, ...)
106 __attribute__ ((format (printf, 1, 2)));
107void printf(const char *fmt, ...)
108 __attribute__ ((format (printf, 1, 2)));
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500109void __debug_enter(const char *fname, struct bregs *regs);
Kevin O'Connor6c781222008-03-09 12:19:23 -0400110void __debug_fail(const char *fname, struct bregs *regs);
Kevin O'Connor4ce6a492008-02-29 00:21:27 -0500111void __debug_stub(const char *fname, struct bregs *regs);
Kevin O'Connored128492008-03-11 11:14:59 -0400112void __debug_isr(const char *fname);
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500113#define debug_enter(regs) \
114 __debug_enter(__func__, regs)
Kevin O'Connor4ce6a492008-02-29 00:21:27 -0500115#define debug_stub(regs) \
116 __debug_stub(__func__, regs)
Kevin O'Connorc65a3802008-03-02 13:58:23 -0500117#define debug_isr(regs) \
Kevin O'Connored128492008-03-11 11:14:59 -0400118 __debug_isr(__func__)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500119
Kevin O'Connor6c781222008-03-09 12:19:23 -0400120// Frequently used return codes
121#define RET_EUNSUPPORTED 0x86
122static inline void
123set_success(struct bregs *regs)
124{
125 set_cf(regs, 0);
126}
127
128static inline void
129set_code_success(struct bregs *regs)
130{
131 regs->ah = 0;
132 set_cf(regs, 0);
133}
134
Kevin O'Connor567e4e32008-04-05 11:37:51 -0400135void __set_fail(const char *fname, struct bregs *regs);
136void __set_code_fail(const char *fname, struct bregs *regs, u8 code);
Kevin O'Connor6c781222008-03-09 12:19:23 -0400137
Kevin O'Connor567e4e32008-04-05 11:37:51 -0400138#define set_fail(regs) \
139 __set_fail(__func__, (regs))
140#define set_code_fail(regs, code) \
141 __set_code_fail(__func__, (regs), (code))
Kevin O'Connor6c781222008-03-09 12:19:23 -0400142
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500143// kbd.c
144void handle_15c2(struct bregs *regs);
Kevin O'Connorbdce35f2008-02-26 21:33:14 -0500145
Kevin O'Connor913cc2e2008-04-13 17:31:45 -0400146// serial.c
147void serial_setup();
148void lpt_setup();
149
Kevin O'Connorbdce35f2008-02-26 21:33:14 -0500150// clock.c
151void handle_1583(struct bregs *regs);
152
Kevin O'Connor95b2f782008-03-05 19:52:06 -0500153// apm.c
Kevin O'Connor44d65302008-03-08 11:34:46 -0500154void VISIBLE16 handle_1553(struct bregs *regs);
Kevin O'Connor95b2f782008-03-05 19:52:06 -0500155
Kevin O'Connora0dc2962008-03-16 14:29:32 -0400156// pcibios.c
157void handle_1ab1(struct bregs *regs);
158
Kevin O'Connora4d35762008-03-08 15:43:03 -0500159// util.c
Kevin O'Connor2e7ab8b2008-03-29 14:29:35 -0400160u8 checksum(u8 *far_data, u32 len);
Kevin O'Connora4d35762008-03-08 15:43:03 -0500161void usleep(u32 count);
162
163// rombios32.c
164void rombios32_init(void);
165
Kevin O'Connore0113c92008-04-05 15:51:12 -0400166// boot.c
167void printf_bootdev(u16 bootdev);
168
169// post_menu.c
170void interactive_bootmenu();
171
Kevin O'Connor786502d2008-02-27 10:41:41 -0500172#endif // util.h