1 // Variable layouts of bios.
3 // Copyright (C) 2008,2009 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)
29 /****************************************************************
30 * Bios Data Area (BDA)
31 ****************************************************************/
33 struct bios_data_area_s {
39 u16 equipment_list_flags;
51 u8 floppy_recalibration_status;
52 u8 floppy_motor_status;
54 u8 floppy_motor_counter;
55 u8 floppy_last_status;
56 u8 floppy_return_status[7];
83 u16 kbd_buf_start_offset;
84 u16 kbd_buf_end_offset;
91 u8 floppy_last_data_rate;
92 u8 disk_status_controller;
93 u8 disk_error_controller;
94 u8 disk_interrupt_flag;
95 u8 floppy_harddisk_info;
97 u8 floppy_media_state[4];
101 struct segoff_s user_wait_complete_flag;
102 u32 user_wait_timeout;
106 struct segoff_s video_savetable;
113 // BDA floppy_recalibration_status bitdefs
114 #define FRS_TIMEOUT (1<<7)
116 // BDA rtc_wait_flag bitdefs
117 #define RWS_WAIT_PENDING (1<<0)
118 #define RWS_WAIT_ELAPSED (1<<7)
120 // BDA floppy_media_state bitdefs
121 #define FMS_DRIVE_STATE_MASK (0x07)
122 #define FMS_MEDIA_DRIVE_ESTABLISHED (1<<4)
123 #define FMS_DOUBLE_STEPPING (1<<5)
124 #define FMS_DATA_RATE_MASK (0xc0)
126 // Accessor functions
127 #define GET_BDA(var) \
128 GET_FARVAR(SEG_BDA, ((struct bios_data_area_s *)0)->var)
129 #define SET_BDA(var, val) \
130 SET_FARVAR(SEG_BDA, ((struct bios_data_area_s *)0)->var, (val))
131 #define CLEARBITS_BDA(var, val) do { \
132 typeof(((struct bios_data_area_s *)0)->var) __val = GET_BDA(var); \
133 SET_BDA(var, (__val & ~(val))); \
135 #define SETBITS_BDA(var, val) do { \
136 typeof(((struct bios_data_area_s *)0)->var) __val = GET_BDA(var); \
137 SET_BDA(var, (__val | (val))); \
141 /****************************************************************
142 * Extended Bios Data Area (EBDA)
143 ****************************************************************/
161 // ElTorito Device Emulation data
163 struct drive_s *emulated_drive_gf;
170 u8 emulated_extdrive;
183 u8 drive_control_byte;
202 struct extended_bios_data_area_s {
205 struct segoff_s far_call_pointer;
213 struct fdpt_s fdpt[2];
218 // 0x121 - Begin custom storage.
220 struct usbkeyinfo usbkey_last;
224 // El Torito Emulation data
225 struct cdemu_s cdemu;
227 // Buffer for disk DPTE table
230 // Locks for removable devices
231 u8 cdrom_locks[CONFIG_MAX_EXTDRIVE];
235 // Stack space available for code that needs it.
236 u8 extra_stack[512] __aligned(8);
238 u8 cdemu_buf[2048 * !!CONFIG_CDROM_EMU];
241 // The initial size and location of EBDA
242 #define EBDA_SIZE_START \
243 DIV_ROUND_UP(sizeof(struct extended_bios_data_area_s), 1024)
244 #define EBDA_SEGMENT_START \
245 FLATPTR_TO_SEG(BUILD_LOWRAM_END - EBDA_SIZE_START*1024)
247 // Accessor functions
248 static inline u16 get_ebda_seg(void) {
249 return GET_BDA(ebda_seg);
251 static inline struct extended_bios_data_area_s *
255 return MAKE_FLATPTR(get_ebda_seg(), 0);
257 #define GET_EBDA2(eseg, var) \
258 GET_FARVAR(eseg, ((struct extended_bios_data_area_s *)0)->var)
259 #define SET_EBDA2(eseg, var, val) \
260 SET_FARVAR(eseg, ((struct extended_bios_data_area_s *)0)->var, (val))
261 #define GET_EBDA(var) \
262 GET_EBDA2(get_ebda_seg(), var)
263 #define SET_EBDA(var, val) \
264 SET_EBDA2(get_ebda_seg(), var, (val))
266 #define EBDA_OFFSET_TOP_STACK \
267 offsetof(struct extended_bios_data_area_s, extra_stack[ \
268 FIELD_SIZEOF(struct extended_bios_data_area_s \
272 /****************************************************************
274 ****************************************************************/
276 #if MODE16 == 0 && MODESEGMENT == 1
277 // In 32bit segmented mode %cs may not be readable and the code may be
278 // relocated. The entry code sets up %gs with a readable segment and
279 // the code offset can be determined by get_global_offset().
280 #define GLOBAL_SEGREG GS
281 static inline u32 __attribute_const get_global_offset(void) {
290 #define GLOBAL_SEGREG CS
291 static inline u32 __attribute_const get_global_offset(void) {
295 static inline u16 get_global_seg(void) {
296 return GET_SEG(GLOBAL_SEGREG);
298 #define GET_GLOBAL(var) \
299 GET_VAR(GLOBAL_SEGREG, *(typeof(&(var)))((void*)&(var) \
300 + get_global_offset()))
301 #define SET_GLOBAL(var, val) do { \
306 #define GLOBALFLAT2GLOBAL(var) ((typeof(var))((void*)(var) - BUILD_BIOS_ADDR))
308 #define GLOBALFLAT2GLOBAL(var) (var)
310 // Access a "flat" pointer known to point to the f-segment.
311 #define GET_GLOBALFLAT(var) GET_GLOBAL(*GLOBALFLAT2GLOBAL(&(var)))
314 /****************************************************************
316 ****************************************************************/
318 struct bios_config_table_s {
323 u8 feature1, feature2, feature3, feature4, feature5;
326 extern struct bios_config_table_s BIOS_CONFIG_TABLE __aligned(1);
328 #endif // __BIOSVAR_H