1 // Structure layout of cpu registers that the bios uses.
2 //
3 // Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
4 //
5 // This file may be distributed under the terms of the GNU LGPLv3 license.
6 
7 #ifndef __BREGS_H
8 #define __BREGS_H
9 
10 #include "types.h" // u16
11 #include "x86.h" // F_CF
12 
13 
14 /****************************************************************
15  * Registers saved/restored in romlayout.S
16  ****************************************************************/
17 
18 #define UREG(ER, R, RH, RL) union { u32 ER; struct { u16 R; u16 R ## _hi; }; struct { u8 RL; u8 RH; u8 R ## _hilo; u8 R ## _hihi; }; }
19 
20 // Layout of registers passed in to irq handlers.  Note that this
21 // layout corresponds to code in romlayout.S - don't change it here
22 // without also updating the assembler code.
23 struct bregs {
24     u16 ds;
25     u16 es;
26     UREG(edi, di, di8u, di8l);
27     UREG(esi, si, si8u, si8l);
28     UREG(ebp, bp, bp8u, bp8l);
29     UREG(ebx, bx, bh, bl);
30     UREG(edx, dx, dh, dl);
31     UREG(ecx, cx, ch, cl);
32     UREG(eax, ax, ah, al);
33     struct segoff_s code;
34     u16 flags;
35 } PACKED;
36 
37 
38 /****************************************************************
39  * Helper functions
40  ****************************************************************/
41 
42 static inline void
set_cf(struct bregs * regs,int cond)43 set_cf(struct bregs *regs, int cond)
44 {
45     if (cond)
46         regs->flags |= F_CF;
47     else
48         regs->flags &= ~F_CF;
49 }
50 
51 // Frequently used return codes
52 #define RET_EUNSUPPORTED 0x86
53 
54 static inline void
set_success(struct bregs * regs)55 set_success(struct bregs *regs)
56 {
57     set_cf(regs, 0);
58 }
59 
60 static inline void
set_code_success(struct bregs * regs)61 set_code_success(struct bregs *regs)
62 {
63     regs->ah = 0;
64     set_cf(regs, 0);
65 }
66 
67 static inline void
set_invalid_silent(struct bregs * regs)68 set_invalid_silent(struct bregs *regs)
69 {
70     set_cf(regs, 1);
71 }
72 
73 static inline void
set_code_invalid_silent(struct bregs * regs,u8 code)74 set_code_invalid_silent(struct bregs *regs, u8 code)
75 {
76     regs->ah = code;
77     set_cf(regs, 1);
78 }
79 
80 #endif // bregs.h
81