From f4429533a6d2174e5f5e7674159090a63032be1a Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Thu, 4 May 2006 17:00:20 +0000 Subject: [PATCH] Added methods for efficiently declaring and accessing variables in .data16. librm will need to supply "char *data16", i.e. the virtual address of the start of .data16. --- src/arch/i386/include/libkir.h | 4 +++ src/arch/i386/include/librm.h | 11 ++++++++ src/arch/i386/include/realmode.h | 44 ++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/src/arch/i386/include/libkir.h b/src/arch/i386/include/libkir.h index 144ea79b..44cb75e2 100644 --- a/src/arch/i386/include/libkir.h +++ b/src/arch/i386/include/libkir.h @@ -10,6 +10,10 @@ * */ +/* Access to variables in .data16, in a way compatible with librm */ +#define __data16( variable ) variable +#define __use_data16( variable ) variable + /* Copy to/from base memory */ static inline void copy_to_real_libkir ( uint16_t dest_seg, uint16_t dest_off, diff --git a/src/arch/i386/include/librm.h b/src/arch/i386/include/librm.h index 76ef8d62..b4970c02 100644 --- a/src/arch/i386/include/librm.h +++ b/src/arch/i386/include/librm.h @@ -15,6 +15,17 @@ * */ +/* Access to variables in .data16 */ +extern char *data16; + +#define __data16( variable ) \ + _data16_ ## variable __asm__ ( #variable ) \ + __attribute__ (( section ( ".data16" ) )) + +#define __use_data16( variable ) \ + ( * ( ( typeof ( _data16_ ## variable ) * ) \ + & ( data16 [ ( size_t ) & ( _data16_ ## variable ) ] ) ) ) + /* Variables in librm.S, present in the normal data segment */ extern uint16_t rm_sp; extern uint16_t rm_ss; diff --git a/src/arch/i386/include/realmode.h b/src/arch/i386/include/realmode.h index f14aae23..b7f0dc9d 100644 --- a/src/arch/i386/include/realmode.h +++ b/src/arch/i386/include/realmode.h @@ -38,6 +38,50 @@ typedef struct { * */ +/* + * Declaration of variables in .data16 + * + * To place a variable in the .data16 segment, declare it using the + * pattern: + * + * int __data16 ( foo ); + * #define foo __use_data16 ( foo ); + * + * extern uint32_t __data16 ( bar ); + * #define bar __use_data16 ( bar ); + * + * extern long __data16 ( baz ) = 0xff000000UL; + * #define bar __use_data16 ( baz ); + * + * i.e. take a normal declaration, add __data16() around the variable + * name, and add a line saying "#define __use_data16 ( ) + * + * You can then access them just like any other variable, for example + * + * int x = foo + bar; + * + * This magic is achieved at a cost of only around 7 extra bytes per + * group of accesses to .data16 variables. When using KEEP_IT_REAL, + * there is no extra cost. + * + * You should place variables in .data16 when they need to be accessed + * by real-mode code. Real-mode assembly (e.g. as created by + * REAL_EXEC()) can access these variables via the usual data segment. + * You can therefore write something like + * + * static uint16_t __data16 ( foo ); + * #define foo __use_data16 ( foo ) + * + * int bar ( void ) { + * REAL_EXEC ( baz, + * "int $0xff\n\t" + * "movw %ax, foo", + * ... ); + * return foo; + * } + * + */ + /* * void copy_to_real ( uint16_t dest_seg, uint16_t dest_off, * void *src, size_t n )