diff options
author | Michael Brown | 2006-05-04 19:00:20 +0200 |
---|---|---|
committer | Michael Brown | 2006-05-04 19:00:20 +0200 |
commit | f4429533a6d2174e5f5e7674159090a63032be1a (patch) | |
tree | 76baf4d689ee0dbbe040598df18ccee92a7a9dd0 /src | |
parent | BSS is now zeroed by libprefix (along with the otherwise non-zeroable (diff) | |
download | ipxe-f4429533a6d2174e5f5e7674159090a63032be1a.tar.gz ipxe-f4429533a6d2174e5f5e7674159090a63032be1a.tar.xz ipxe-f4429533a6d2174e5f5e7674159090a63032be1a.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/i386/include/libkir.h | 4 | ||||
-rw-r--r-- | src/arch/i386/include/librm.h | 11 | ||||
-rw-r--r-- | src/arch/i386/include/realmode.h | 44 |
3 files changed, 59 insertions, 0 deletions
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 @@ -39,6 +39,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 <name> __use_data16 ( <name> ) + * + * 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 ) * void copy_from_real ( void *dest, uint16_t src_seg, uint16_t src_off, |