blob: 11ca26972f48056c70c69a972e2d380af9c1cb57 [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 (); \
Kevin O'Connor117fc212008-04-13 18:17:02 -040093 __call16_int((callregs), (u32)&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));
Kevin O'Connor567e4e32008-04-05 11:37:51 -0400105void printf(const char *fmt, ...)
106 __attribute__ ((format (printf, 1, 2)));
Kevin O'Connorac8df8c2008-05-24 23:46:33 -0400107void __dprintf(const char *fmt, ...)
108 __attribute__ ((format (printf, 1, 2)));
109#define dprintf(lvl, fmt, args...) do { \
110 if (CONFIG_DEBUG_LEVEL && (lvl) <= CONFIG_DEBUG_LEVEL) \
111 __dprintf((fmt) , ##args ); \
112 } while (0)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500113void __debug_enter(const char *fname, struct bregs *regs);
Kevin O'Connor6c781222008-03-09 12:19:23 -0400114void __debug_fail(const char *fname, struct bregs *regs);
Kevin O'Connor4ce6a492008-02-29 00:21:27 -0500115void __debug_stub(const char *fname, struct bregs *regs);
Kevin O'Connored128492008-03-11 11:14:59 -0400116void __debug_isr(const char *fname);
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500117#define debug_enter(regs) \
118 __debug_enter(__func__, regs)
Kevin O'Connor4ce6a492008-02-29 00:21:27 -0500119#define debug_stub(regs) \
120 __debug_stub(__func__, regs)
Kevin O'Connorc65a3802008-03-02 13:58:23 -0500121#define debug_isr(regs) \
Kevin O'Connored128492008-03-11 11:14:59 -0400122 __debug_isr(__func__)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500123
Kevin O'Connor6c781222008-03-09 12:19:23 -0400124// Frequently used return codes
125#define RET_EUNSUPPORTED 0x86
126static inline void
127set_success(struct bregs *regs)
128{
129 set_cf(regs, 0);
130}
131
132static inline void
133set_code_success(struct bregs *regs)
134{
135 regs->ah = 0;
136 set_cf(regs, 0);
137}
138
Kevin O'Connor567e4e32008-04-05 11:37:51 -0400139void __set_fail(const char *fname, struct bregs *regs);
140void __set_code_fail(const char *fname, struct bregs *regs, u8 code);
Kevin O'Connor6c781222008-03-09 12:19:23 -0400141
Kevin O'Connor567e4e32008-04-05 11:37:51 -0400142#define set_fail(regs) \
143 __set_fail(__func__, (regs))
144#define set_code_fail(regs, code) \
145 __set_code_fail(__func__, (regs), (code))
Kevin O'Connor6c781222008-03-09 12:19:23 -0400146
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500147// kbd.c
148void handle_15c2(struct bregs *regs);
Kevin O'Connorbdce35f2008-02-26 21:33:14 -0500149
Kevin O'Connor913cc2e2008-04-13 17:31:45 -0400150// serial.c
151void serial_setup();
Kevin O'Connor1812e202008-05-07 21:29:50 -0400152void debug_serial_setup();
153void debug_serial(char c);
Kevin O'Connor913cc2e2008-04-13 17:31:45 -0400154void lpt_setup();
155
Kevin O'Connorbdce35f2008-02-26 21:33:14 -0500156// clock.c
Kevin O'Connore6eb3f52008-04-13 17:37:41 -0400157void timer_setup();
Kevin O'Connor5be04902008-05-18 17:12:06 -0400158int usleep(u32 count);
Kevin O'Connorbdce35f2008-02-26 21:33:14 -0500159void handle_1583(struct bregs *regs);
Kevin O'Connor5be04902008-05-18 17:12:06 -0400160void handle_1586(struct bregs *regs);
Kevin O'Connorbdce35f2008-02-26 21:33:14 -0500161
Kevin O'Connor95b2f782008-03-05 19:52:06 -0500162// apm.c
Kevin O'Connor44d65302008-03-08 11:34:46 -0500163void VISIBLE16 handle_1553(struct bregs *regs);
Kevin O'Connor95b2f782008-03-05 19:52:06 -0500164
Kevin O'Connora0dc2962008-03-16 14:29:32 -0400165// pcibios.c
166void handle_1ab1(struct bregs *regs);
167
Kevin O'Connora4d35762008-03-08 15:43:03 -0500168// util.c
Kevin O'Connor2e7ab8b2008-03-29 14:29:35 -0400169u8 checksum(u8 *far_data, u32 len);
Kevin O'Connora4d35762008-03-08 15:43:03 -0500170
171// rombios32.c
172void rombios32_init(void);
173
Kevin O'Connore0113c92008-04-05 15:51:12 -0400174// boot.c
175void printf_bootdev(u16 bootdev);
176
177// post_menu.c
178void interactive_bootmenu();
179
Kevin O'Connor786502d2008-02-27 10:41:41 -0500180#endif // util.h