Be sure to add "void" to all function prototypes that take no args.
[seabios.git] / src / biosvar.h
index 6a789e41a9e216eac664c65765565ec61dcd53b8..b6e061b99cdb311f6c2fc206326b1e06a08d7ad1 100644 (file)
@@ -232,11 +232,11 @@ struct extended_bios_data_area_s {
     FLATPTR_TO_SEG(BUILD_LOWRAM_END - EBDA_SIZE_START*1024)
 
 // Accessor functions
-static inline u16 get_ebda_seg() {
+static inline u16 get_ebda_seg(void) {
     return GET_BDA(ebda_seg);
 }
 static inline struct extended_bios_data_area_s *
-get_ebda_ptr()
+get_ebda_ptr(void)
 {
     ASSERT32FLAT();
     return MAKE_FLATPTR(get_ebda_seg(), 0);
@@ -260,12 +260,31 @@ get_ebda_ptr()
  * Global variables
  ****************************************************************/
 
+#if MODE16 == 0 && MODESEGMENT == 1
+// In 32bit segmented mode %cs may not be readable and the code may be
+// relocated.  The entry code sets up %gs with a readable segment and
+// the code offset can be determined by get_global_offset().
+#define GLOBAL_SEGREG GS
+static inline u32 __attribute_const get_global_offset(void) {
+    u32 ret;
+    asm("  calll 1f\n"
+        "1:popl %0\n"
+        "  subl $1b, %0"
+        : "=r"(ret));
+    return ret;
+}
+#else
 #define GLOBAL_SEGREG CS
-static inline u16 get_global_seg() {
+static inline u32 __attribute_const get_global_offset(void) {
+    return 0;
+}
+#endif
+static inline u16 get_global_seg(void) {
     return GET_SEG(GLOBAL_SEGREG);
 }
-#define GET_GLOBAL(var)                         \
-    GET_VAR(GLOBAL_SEGREG, (var))
+#define GET_GLOBAL(var)                                                 \
+    GET_VAR(GLOBAL_SEGREG, *(typeof(&(var)))((void*)&(var)              \
+                                             + get_global_offset()))
 #define SET_GLOBAL(var, val) do {               \
         ASSERT32FLAT();                         \
         (var) = (val);                          \