1 // Variable layouts of bios.
3 // Copyright (C) 2008-2010 Kevin O'Connor <kevin@koconnor.net>
5 // This file may be distributed under the terms of the GNU LGPLv3 license.
9 #include "types.h" // u8
10 #include "farptr.h" // GET_FARVAR
11 #include "config.h" // CONFIG_*
12 #include "disk.h" // struct chs_s
15 /****************************************************************
16 * Interupt vector table
17 ****************************************************************/
20 struct segoff_s ivec[256];
23 #define GET_IVT(vector) \
24 GET_FARVAR(SEG_IVT, ((struct rmode_IVT *)0)->ivec[vector])
25 #define SET_IVT(vector, segoff) \
26 SET_FARVAR(SEG_IVT, ((struct rmode_IVT *)0)->ivec[vector], segoff)
28 #define FUNC16(func) ({ \
30 extern void func (void); \
31 SEGOFF(SEG_BIOS, (u32)func - BUILD_BIOS_ADDR); \
35 /****************************************************************
36 * Bios Data Area (BDA)
37 ****************************************************************/
39 struct bios_data_area_s {
45 u16 equipment_list_flags;
57 u8 floppy_recalibration_status;
58 u8 floppy_motor_status;
60 u8 floppy_motor_counter;
61 u8 floppy_last_status;
62 u8 floppy_return_status[7];
89 u16 kbd_buf_start_offset;
90 u16 kbd_buf_end_offset;
97 u8 floppy_last_data_rate;
98 u8 disk_status_controller;
99 u8 disk_error_controller;
100 u8 disk_interrupt_flag;
101 u8 floppy_harddisk_info;
103 u8 floppy_media_state[4];
107 struct segoff_s user_wait_complete_flag;
108 u32 user_wait_timeout;
112 struct segoff_s video_savetable;
120 // BDA floppy_recalibration_status bitdefs
121 #define FRS_TIMEOUT (1<<7)
123 // BDA rtc_wait_flag bitdefs
124 #define RWS_WAIT_PENDING (1<<0)
125 #define RWS_WAIT_ELAPSED (1<<7)
127 // BDA floppy_media_state bitdefs
128 #define FMS_DRIVE_STATE_MASK (0x07)
129 #define FMS_MEDIA_DRIVE_ESTABLISHED (1<<4)
130 #define FMS_DOUBLE_STEPPING (1<<5)
131 #define FMS_DATA_RATE_MASK (0xc0)
133 // Accessor functions
134 #define GET_BDA(var) \
135 GET_FARVAR(SEG_BDA, ((struct bios_data_area_s *)0)->var)
136 #define SET_BDA(var, val) \
137 SET_FARVAR(SEG_BDA, ((struct bios_data_area_s *)0)->var, (val))
138 #define CLEARBITS_BDA(var, val) do { \
139 typeof(((struct bios_data_area_s *)0)->var) __val = GET_BDA(var); \
140 SET_BDA(var, (__val & ~(val))); \
142 #define SETBITS_BDA(var, val) do { \
143 typeof(((struct bios_data_area_s *)0)->var) __val = GET_BDA(var); \
144 SET_BDA(var, (__val | (val))); \
148 /****************************************************************
149 * Extended Bios Data Area (EBDA)
150 ****************************************************************/
168 // ElTorito Device Emulation data
170 struct drive_s *emulated_drive_gf;
177 u8 emulated_extdrive;
190 u8 drive_control_byte;
209 struct extended_bios_data_area_s {
212 struct segoff_s far_call_pointer;
220 struct fdpt_s fdpt[2];
225 // 0x121 - Begin custom storage.
227 struct usbkeyinfo usbkey_last;
231 // El Torito Emulation data
232 struct cdemu_s cdemu;
234 // Buffer for disk DPTE table
237 // Locks for removable devices
238 u8 cdrom_locks[CONFIG_MAX_EXTDRIVE];
242 /* TSC emulation timekeepers */
246 // Stack space available for code that needs it.
247 u8 extra_stack[512] __aligned(8);
250 // The initial size and location of EBDA
251 #define EBDA_SIZE_START \
252 DIV_ROUND_UP(sizeof(struct extended_bios_data_area_s), 1024)
253 #define EBDA_SEGMENT_START \
254 FLATPTR_TO_SEG(BUILD_LOWRAM_END - EBDA_SIZE_START*1024)
256 // Accessor functions
257 static inline u16 get_ebda_seg(void) {
258 return GET_BDA(ebda_seg);
260 static inline struct extended_bios_data_area_s *
264 return MAKE_FLATPTR(get_ebda_seg(), 0);
266 #define GET_EBDA2(eseg, var) \
267 GET_FARVAR(eseg, ((struct extended_bios_data_area_s *)0)->var)
268 #define SET_EBDA2(eseg, var, val) \
269 SET_FARVAR(eseg, ((struct extended_bios_data_area_s *)0)->var, (val))
270 #define GET_EBDA(var) \
271 GET_EBDA2(get_ebda_seg(), var)
272 #define SET_EBDA(var, val) \
273 SET_EBDA2(get_ebda_seg(), var, (val))
275 #define EBDA_OFFSET_TOP_STACK \
276 offsetof(struct extended_bios_data_area_s, extra_stack[ \
277 FIELD_SIZEOF(struct extended_bios_data_area_s \
281 /****************************************************************
283 ****************************************************************/
285 #if MODE16 == 0 && MODESEGMENT == 1
286 // In 32bit segmented mode %cs may not be readable and the code may be
287 // relocated. The entry code sets up %gs with a readable segment and
288 // the code offset can be determined by get_global_offset().
289 #define GLOBAL_SEGREG GS
290 static inline u32 __attribute_const get_global_offset(void) {
299 #define GLOBAL_SEGREG CS
300 static inline u32 __attribute_const get_global_offset(void) {
304 static inline u16 get_global_seg(void) {
305 return GET_SEG(GLOBAL_SEGREG);
307 #define GET_GLOBAL(var) \
308 GET_VAR(GLOBAL_SEGREG, *(typeof(&(var)))((void*)&(var) \
309 + get_global_offset()))
310 #define SET_GLOBAL(var, val) do { \
315 #define GLOBALFLAT2GLOBAL(var) ((typeof(var))((void*)(var) - BUILD_BIOS_ADDR))
317 #define GLOBALFLAT2GLOBAL(var) (var)
319 // Access a "flat" pointer known to point to the f-segment.
320 #define GET_GLOBALFLAT(var) GET_GLOBAL(*GLOBALFLAT2GLOBAL(&(var)))
323 /****************************************************************
325 ****************************************************************/
327 struct bios_config_table_s {
332 u8 feature1, feature2, feature3, feature4, feature5;
335 extern struct bios_config_table_s BIOS_CONFIG_TABLE __aligned(1);
337 #endif // __BIOSVAR_H