david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

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.
This commit is contained in:
Michael Brown 2006-05-04 17:00:20 +00:00
parent f8f75cef5b
commit f4429533a6
3 changed files with 59 additions and 0 deletions

View File

@ -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,

View File

@ -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;

View File

@ -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 <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 )