blob: 58bcbcedb216957fa5c066de7f6ef900a423afe5 [file] [log] [blame]
Kevin O'Connor392d2aa2013-09-15 00:14:28 -04001// Memory access to BIOS variables.
Kevin O'Connorf076a3e2008-02-25 22:25:15 -05002//
Kevin O'Connor392d2aa2013-09-15 00:14:28 -04003// Copyright (C) 2008-2013 Kevin O'Connor <kevin@koconnor.net>
Kevin O'Connorf076a3e2008-02-25 22:25:15 -05004//
Kevin O'Connorb1b7c2a2009-01-15 20:52:58 -05005// This file may be distributed under the terms of the GNU LGPLv3 license.
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -05006#ifndef __BIOSVAR_H
7#define __BIOSVAR_H
Kevin O'Connorf076a3e2008-02-25 22:25:15 -05008
Kevin O'Connord3140832012-05-13 22:46:12 -04009#include "config.h" // SEG_BDA
Kevin O'Connor392d2aa2013-09-15 00:14:28 -040010#include "farptr.h" // GET_FARVAR
11#include "std/bda.h" // struct bios_data_area_s
Kevin O'Connorb68ac712009-08-09 17:25:19 -040012
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050013
14/****************************************************************
Kevin O'Connor8c0e3722009-01-02 14:19:43 -050015 * Interupt vector table
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050016 ****************************************************************/
17
Kevin O'Connor3d292132009-05-06 23:20:03 -040018#define GET_IVT(vector) \
19 GET_FARVAR(SEG_IVT, ((struct rmode_IVT *)0)->ivec[vector])
Kevin O'Connor9f985422009-09-09 11:34:39 -040020#define SET_IVT(vector, segoff) \
21 SET_FARVAR(SEG_IVT, ((struct rmode_IVT *)0)->ivec[vector], segoff)
Kevin O'Connor8c0e3722009-01-02 14:19:43 -050022
Kevin O'Connorcc9e1bf2010-07-28 21:31:38 -040023#define FUNC16(func) ({ \
24 ASSERT32FLAT(); \
25 extern void func (void); \
26 SEGOFF(SEG_BIOS, (u32)func - BUILD_BIOS_ADDR); \
27 })
28
Kevin O'Connor8c0e3722009-01-02 14:19:43 -050029
30/****************************************************************
31 * Bios Data Area (BDA)
32 ****************************************************************/
33
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050034// Accessor functions
Kevin O'Connor4b60c002008-02-25 22:29:55 -050035#define GET_BDA(var) \
Kevin O'Connor438f6352008-03-30 21:46:53 -040036 GET_FARVAR(SEG_BDA, ((struct bios_data_area_s *)0)->var)
Kevin O'Connor4b60c002008-02-25 22:29:55 -050037#define SET_BDA(var, val) \
Kevin O'Connor438f6352008-03-30 21:46:53 -040038 SET_FARVAR(SEG_BDA, ((struct bios_data_area_s *)0)->var, (val))
Kevin O'Connore51316d2012-06-10 09:09:22 -040039
40// Helper function to set the bits of the equipment_list_flags variable.
41static inline void set_equipment_flags(u16 clear, u16 set) {
42 u16 eqf = GET_BDA(equipment_list_flags);
43 SET_BDA(equipment_list_flags, (eqf & ~clear) | set);
44}
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050045
46
47/****************************************************************
48 * Extended Bios Data Area (EBDA)
49 ****************************************************************/
50
Kevin O'Connor49553a42009-05-17 10:31:34 -040051// The initial size and location of EBDA
52#define EBDA_SIZE_START \
53 DIV_ROUND_UP(sizeof(struct extended_bios_data_area_s), 1024)
54#define EBDA_SEGMENT_START \
Kevin O'Connorf416fe92009-09-24 20:51:55 -040055 FLATPTR_TO_SEG(BUILD_LOWRAM_END - EBDA_SIZE_START*1024)
Kevin O'Connor49553a42009-05-17 10:31:34 -040056
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050057// Accessor functions
Kevin O'Connor1ca05b02010-01-03 17:43:37 -050058static inline u16 get_ebda_seg(void) {
Kevin O'Connor08815372008-12-29 21:16:31 -050059 return GET_BDA(ebda_seg);
60}
Kevin O'Connor4d7c37e2008-12-26 23:50:17 -050061static inline struct extended_bios_data_area_s *
Kevin O'Connor1ca05b02010-01-03 17:43:37 -050062get_ebda_ptr(void)
Kevin O'Connor4d7c37e2008-12-26 23:50:17 -050063{
Kevin O'Connor52a300f2009-12-26 23:32:57 -050064 ASSERT32FLAT();
Kevin O'Connor35ae7262009-01-19 15:44:44 -050065 return MAKE_FLATPTR(get_ebda_seg(), 0);
Kevin O'Connor4d7c37e2008-12-26 23:50:17 -050066}
Kevin O'Connor4bc49972012-05-13 22:58:08 -040067#define GET_EBDA(eseg, var) \
Kevin O'Connor08815372008-12-29 21:16:31 -050068 GET_FARVAR(eseg, ((struct extended_bios_data_area_s *)0)->var)
Kevin O'Connor4bc49972012-05-13 22:58:08 -040069#define SET_EBDA(eseg, var, val) \
Kevin O'Connor08815372008-12-29 21:16:31 -050070 SET_FARVAR(eseg, ((struct extended_bios_data_area_s *)0)->var, (val))
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050071
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050072
73/****************************************************************
Kevin O'Connor15157a32008-12-13 11:10:37 -050074 * Global variables
75 ****************************************************************/
76
Kevin O'Connor871e0a02009-12-30 12:14:53 -050077#if MODE16 == 0 && MODESEGMENT == 1
78// In 32bit segmented mode %cs may not be readable and the code may be
79// relocated. The entry code sets up %gs with a readable segment and
80// the code offset can be determined by get_global_offset().
81#define GLOBAL_SEGREG GS
82static inline u32 __attribute_const get_global_offset(void) {
83 u32 ret;
84 asm(" calll 1f\n"
85 "1:popl %0\n"
86 " subl $1b, %0"
87 : "=r"(ret));
88 return ret;
89}
90#else
Kevin O'Connor8b267cb2009-01-19 19:25:21 -050091#define GLOBAL_SEGREG CS
Kevin O'Connor871e0a02009-12-30 12:14:53 -050092static inline u32 __attribute_const get_global_offset(void) {
93 return 0;
94}
95#endif
Kevin O'Connor1ca05b02010-01-03 17:43:37 -050096static inline u16 get_global_seg(void) {
Kevin O'Connor8b267cb2009-01-19 19:25:21 -050097 return GET_SEG(GLOBAL_SEGREG);
98}
Kevin O'Connor871e0a02009-12-30 12:14:53 -050099#define GET_GLOBAL(var) \
100 GET_VAR(GLOBAL_SEGREG, *(typeof(&(var)))((void*)&(var) \
101 + get_global_offset()))
Kevin O'Connor52a300f2009-12-26 23:32:57 -0500102#if MODESEGMENT
Kevin O'Connor8f469b92010-02-28 01:28:11 -0500103#define GLOBALFLAT2GLOBAL(var) ((typeof(var))((void*)(var) - BUILD_BIOS_ADDR))
Kevin O'Connor77d227b2009-10-22 21:48:39 -0400104#else
Kevin O'Connor8f469b92010-02-28 01:28:11 -0500105#define GLOBALFLAT2GLOBAL(var) (var)
Kevin O'Connor77d227b2009-10-22 21:48:39 -0400106#endif
Kevin O'Connor8f469b92010-02-28 01:28:11 -0500107// Access a "flat" pointer known to point to the f-segment.
108#define GET_GLOBALFLAT(var) GET_GLOBAL(*GLOBALFLAT2GLOBAL(&(var)))
Kevin O'Connor15157a32008-12-13 11:10:37 -0500109
110
111/****************************************************************
Kevin O'Connor46b82622012-05-13 12:10:30 -0400112 * "Low" memory variables
113 ****************************************************************/
114
Kevin O'Connorc9243442013-02-17 13:58:28 -0500115extern u8 _zonelow_seg, zonelow_base[];
116#define SEG_LOW ((u32)&_zonelow_seg)
Kevin O'Connor46b82622012-05-13 12:10:30 -0400117
118#if MODESEGMENT
119#define GET_LOW(var) GET_FARVAR(SEG_LOW, (var))
120#define SET_LOW(var, val) SET_FARVAR(SEG_LOW, (var), (val))
Kevin O'Connorc9243442013-02-17 13:58:28 -0500121#define LOWFLAT2LOW(var) ((typeof(var))((void*)(var) - (u32)zonelow_base))
Kevin O'Connor46b82622012-05-13 12:10:30 -0400122#else
123#define GET_LOW(var) (var)
124#define SET_LOW(var, val) do { (var) = (val); } while (0)
Kevin O'Connor4f6563e2012-05-19 22:42:51 -0400125#define LOWFLAT2LOW(var) (var)
Kevin O'Connor46b82622012-05-13 12:10:30 -0400126#endif
Kevin O'Connor4f6563e2012-05-19 22:42:51 -0400127#define GET_LOWFLAT(var) GET_LOW(*LOWFLAT2LOW(&(var)))
128#define SET_LOWFLAT(var, val) SET_LOW(*LOWFLAT2LOW(&(var)), (val))
Kevin O'Connor46b82622012-05-13 12:10:30 -0400129
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500130#endif // __BIOSVAR_H