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;
119 // BDA floppy_recalibration_status bitdefs
120 #define FRS_TIMEOUT (1<<7)
122 // BDA rtc_wait_flag bitdefs
123 #define RWS_WAIT_PENDING (1<<0)
124 #define RWS_WAIT_ELAPSED (1<<7)
126 // BDA floppy_media_state bitdefs
127 #define FMS_DRIVE_STATE_MASK (0x07)
128 #define FMS_MEDIA_DRIVE_ESTABLISHED (1<<4)
129 #define FMS_DOUBLE_STEPPING (1<<5)
130 #define FMS_DATA_RATE_MASK (0xc0)
132 // Accessor functions
133 #define GET_BDA(var) \
134 GET_FARVAR(SEG_BDA, ((struct bios_data_area_s *)0)->var)
135 #define SET_BDA(var, val) \
136 SET_FARVAR(SEG_BDA, ((struct bios_data_area_s *)0)->var, (val))
137 #define CLEARBITS_BDA(var, val) do { \
138 typeof(((struct bios_data_area_s *)0)->var) __val = GET_BDA(var); \
139 SET_BDA(var, (__val & ~(val))); \
141 #define SETBITS_BDA(var, val) do { \
142 typeof(((struct bios_data_area_s *)0)->var) __val = GET_BDA(var); \
143 SET_BDA(var, (__val | (val))); \
147 /****************************************************************
148 * Extended Bios Data Area (EBDA)
149 ****************************************************************/
167 // ElTorito Device Emulation data
169 struct drive_s *emulated_drive_gf;
176 u8 emulated_extdrive;
189 u8 drive_control_byte;
208 struct extended_bios_data_area_s {
211 struct segoff_s far_call_pointer;
219 struct fdpt_s fdpt[2];
224 // 0x121 - Begin custom storage.
226 struct usbkeyinfo usbkey_last;
230 // El Torito Emulation data
231 struct cdemu_s cdemu;
233 // Buffer for disk DPTE table
236 // Locks for removable devices
237 u8 cdrom_locks[CONFIG_MAX_EXTDRIVE];
241 // Stack space available for code that needs it.
242 u8 extra_stack[512] __aligned(8);
245 // The initial size and location of EBDA
246 #define EBDA_SIZE_START \
247 DIV_ROUND_UP(sizeof(struct extended_bios_data_area_s), 1024)
248 #define EBDA_SEGMENT_START \
249 FLATPTR_TO_SEG(BUILD_LOWRAM_END - EBDA_SIZE_START*1024)
251 // Accessor functions
252 static inline u16 get_ebda_seg(void) {
253 return GET_BDA(ebda_seg);
255 static inline struct extended_bios_data_area_s *
259 return MAKE_FLATPTR(get_ebda_seg(), 0);
261 #define GET_EBDA2(eseg, var) \
262 GET_FARVAR(eseg, ((struct extended_bios_data_area_s *)0)->var)
263 #define SET_EBDA2(eseg, var, val) \
264 SET_FARVAR(eseg, ((struct extended_bios_data_area_s *)0)->var, (val))
265 #define GET_EBDA(var) \
266 GET_EBDA2(get_ebda_seg(), var)
267 #define SET_EBDA(var, val) \
268 SET_EBDA2(get_ebda_seg(), var, (val))
270 #define EBDA_OFFSET_TOP_STACK \
271 offsetof(struct extended_bios_data_area_s, extra_stack[ \
272 FIELD_SIZEOF(struct extended_bios_data_area_s \
276 /****************************************************************
278 ****************************************************************/
280 #if MODE16 == 0 && MODESEGMENT == 1
281 // In 32bit segmented mode %cs may not be readable and the code may be
282 // relocated. The entry code sets up %gs with a readable segment and
283 // the code offset can be determined by get_global_offset().
284 #define GLOBAL_SEGREG GS
285 static inline u32 __attribute_const get_global_offset(void) {
294 #define GLOBAL_SEGREG CS
295 static inline u32 __attribute_const get_global_offset(void) {
299 static inline u16 get_global_seg(void) {
300 return GET_SEG(GLOBAL_SEGREG);
302 #define GET_GLOBAL(var) \
303 GET_VAR(GLOBAL_SEGREG, *(typeof(&(var)))((void*)&(var) \
304 + get_global_offset()))
305 #define SET_GLOBAL(var, val) do { \
310 #define GLOBALFLAT2GLOBAL(var) ((typeof(var))((void*)(var) - BUILD_BIOS_ADDR))
312 #define GLOBALFLAT2GLOBAL(var) (var)
314 // Access a "flat" pointer known to point to the f-segment.
315 #define GET_GLOBALFLAT(var) GET_GLOBAL(*GLOBALFLAT2GLOBAL(&(var)))
318 /****************************************************************
320 ****************************************************************/
322 struct bios_config_table_s {
327 u8 feature1, feature2, feature3, feature4, feature5;
330 extern struct bios_config_table_s BIOS_CONFIG_TABLE __aligned(1);
332 #endif // __BIOSVAR_H