aboutsummaryrefslogtreecommitdiff
path: root/src/biosvar.h
blob: 369f4ea7ec77861a458058c93ce4942bb6c190fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
// Variable layouts of bios.
//
// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU LGPLv3 license.
#ifndef __BIOSVAR_H
#define __BIOSVAR_H

#include "types.h" // u8
#include "farptr.h" // GET_FARVAR
#include "config.h" // CONFIG_*


/****************************************************************
 * Interupt vector table
 ****************************************************************/

struct rmode_IVT {
    union {
        struct {
            u16 offset;
            u16 seg;
        };
        u32 segoff;
    } ivec[256];
};

#define SET_IVT(vector, seg, off)                                       \
    SET_FARVAR(SEG_IVT, ((struct rmode_IVT *)0)->ivec[vector].segoff, ((seg) << 16) | (off))


/****************************************************************
 * Bios Data Area (BDA)
 ****************************************************************/

struct bios_data_area_s {
    // 40:00
    u16 port_com[4];
    u16 port_lpt[3];
    u16 ebda_seg;
    // 40:10
    u16 equipment_list_flags;
    u8 pad1;
    u16 mem_size_kb;
    u8 pad2;
    u8 ps2_ctrl_flag;
    u8 kbd_flag0;
    u8 kbd_flag1;
    u8 alt_keypad;
    u16 kbd_buf_head;
    u16 kbd_buf_tail;
    // 40:1e
    u8 kbd_buf[32];
    u8 floppy_recalibration_status;
    u8 floppy_motor_status;
    // 40:40
    u8 floppy_motor_counter;
    u8 floppy_last_status;
    u8 floppy_return_status[7];
    u8 video_mode;
    u16 video_cols;
    u16 video_pagesize;
    u16 video_pagestart;
    // 40:50
    u16 cursor_pos[8];
    // 40:60
    u16 cursor_type;
    u8 video_page;
    u16 crtc_address;
    u8 video_msr;
    u8 video_pal;
    u16 jump_ip;
    u16 jump_cs;
    u8 other_6b;
    u32 timer_counter;
    // 40:70
    u8 timer_rollover;
    u8 break_flag;
    u16 soft_reset_flag;
    u8 disk_last_status;
    u8 hdcount;
    u8 disk_control_byte;
    u8 port_disk;
    u8 lpt_timeout[4];
    u8 com_timeout[4];
    // 40:80
    u16 kbd_buf_start_offset;
    u16 kbd_buf_end_offset;
    u8 video_rows;
    u16 char_height;
    u8 video_ctl;
    u8 video_switches;
    u8 modeset_ctl;
    u8 dcc_index;
    u8 floppy_last_data_rate;
    u8 disk_status_controller;
    u8 disk_error_controller;
    u8 disk_interrupt_flag;
    u8 floppy_harddisk_info;
    // 40:90
    u8 floppy_media_state[4];
    u8 floppy_track[2];
    u8 kbd_mode;
    u8 kbd_led;
    u32 ptr_user_wait_complete_flag;
    u32 user_wait_timeout;
    // 40:A0
    u8 rtc_wait_flag;
} PACKED;

// BDA floppy_recalibration_status bitdefs
#define FRS_TIMEOUT (1<<7)

// BDA rtc_wait_flag bitdefs
#define RWS_WAIT_PENDING (1<<0)
#define RWS_WAIT_ELAPSED (1<<7)

// BDA floppy_media_state bitdefs
#define FMS_DRIVE_STATE_MASK        (0x07)
#define FMS_MEDIA_DRIVE_ESTABLISHED (1<<4)
#define FMS_DOUBLE_STEPPING         (1<<5)
#define FMS_DATA_RATE_MASK          (0xc0)

// Accessor functions
#define GET_BDA(var) \
    GET_FARVAR(SEG_BDA, ((struct bios_data_area_s *)0)->var)
#define SET_BDA(var, val) \
    SET_FARVAR(SEG_BDA, ((struct bios_data_area_s *)0)->var, (val))
#define CLEARBITS_BDA(var, val) do {                                    \
        typeof(((struct bios_data_area_s *)0)->var) __val = GET_BDA(var); \
        SET_BDA(var, (__val & ~(val)));                                 \
    } while (0)
#define SETBITS_BDA(var, val) do {                                      \
        typeof(((struct bios_data_area_s *)0)->var) __val = GET_BDA(var); \
        SET_BDA(var, (__val | (val)));                                  \
    } while (0)


/****************************************************************
 * Extended Bios Data Area (EBDA)
 ****************************************************************/

// DPTE definition
struct dpte_s {
    u16 iobase1;
    u16 iobase2;
    u8  prefix;
    u8  unused;
    u8  irq;
    u8  blkcount;
    u8  dma;
    u8  pio;
    u16 options;
    u16 reserved;
    u8  revision;
    u8  checksum;
};

// ElTorito Device Emulation data
struct cdemu_s {
    u8  active;
    u8  media;
    u8  emulated_drive;
    u8  controller_index;
    u16 device_spec;
    u32 ilba;
    u16 buffer_segment;
    u16 load_segment;
    u16 sector_count;

    // Virtual device
    u16 heads;
    u16 cylinders;
    u16 spt;
};

struct fdpt_s {
    u16 cylinders;
    u8 heads;
    u8 a0h_signature;
    u8 phys_sectors;
    u16 precompensation;
    u8 reserved;
    u8 drive_control_byte;
    u16 phys_cylinders;
    u8 phys_heads;
    u16 landing_zone;
    u8 sectors;
    u8 checksum;
} PACKED;

struct extended_bios_data_area_s {
    u8 size;
    u8 reserved1[0x21];
    u32 far_call_pointer;
    u8 mouse_flag1;
    u8 mouse_flag2;
    u8 mouse_data[0x08];
    // 0x30
    u8 other1[0x0d];

    // 0x3d
    struct fdpt_s fdpt[2];

    // 0x5d
    u8 other2[0xC4];

    // 0x121 - Begin custom storage.
    u8 ps2ctr;

    // El Torito Emulation data
    struct cdemu_s cdemu;

    // Count of transferred sectors and bytes to/from disk
    u16 sector_count;

    // Buffer for disk DPTE table
    struct dpte_s dpte;

    // Locks for removable devices
    u8 cdrom_locks[CONFIG_MAX_ATA_DEVICES];

    u16 boot_sequence;

    // Stack space available for code that needs it.
    u8 extra_stack[512] __aligned(8);
} PACKED;

// Accessor functions
static inline u16 get_ebda_seg() {
    return GET_BDA(ebda_seg);
}
static inline struct extended_bios_data_area_s *
get_ebda_ptr()
{
    extern void *__force_link_error__get_ebda_ptr_only_in_32bit();
    if (MODE16)
        return __force_link_error__get_ebda_ptr_only_in_32bit();
    return MAKE_FLATPTR(get_ebda_seg(), 0);
}
#define GET_EBDA2(eseg, var)                                            \
    GET_FARVAR(eseg, ((struct extended_bios_data_area_s *)0)->var)
#define SET_EBDA2(eseg, var, val)                                       \
    SET_FARVAR(eseg, ((struct extended_bios_data_area_s *)0)->var, (val))
#define GET_EBDA(var)                           \
    GET_EBDA2(get_ebda_seg(), var)
#define SET_EBDA(var, val)                      \
    SET_EBDA2(get_ebda_seg(), var, (val))

#define EBDA_OFFSET_TOP_STACK                                   \
    offsetof(struct extended_bios_data_area_s, extra_stack[     \
                 FIELD_SIZEOF(struct extended_bios_data_area_s  \
                              , extra_stack)])


/****************************************************************
 * Global variables
 ****************************************************************/

#define GLOBAL_SEGREG CS
static inline u16 get_global_seg() {
    return GET_SEG(GLOBAL_SEGREG);
}
#define GET_GLOBAL(var)                         \
    GET_VAR(GLOBAL_SEGREG, (var))
#define SET_GLOBAL(var, val) do {                                       \
        extern void __force_link_error__set_global_only_in_32bit();     \
        if (MODE16)                                                     \
            __force_link_error__set_global_only_in_32bit();             \
        (var) = (val);                                                  \
    } while (0)


/****************************************************************
 * Bios Config Table
 ****************************************************************/

struct bios_config_table_s {
    u16 size;
    u8 model;
    u8 submodel;
    u8 biosrev;
    u8 feature1, feature2, feature3, feature4, feature5;
} PACKED;

extern struct bios_config_table_s BIOS_CONFIG_TABLE __aligned(1);

#endif // __BIOSVAR_H