summaryrefslogtreecommitdiffstats
path: root/src/arch
diff options
context:
space:
mode:
authorMichael Brown2006-05-04 19:00:20 +0200
committerMichael Brown2006-05-04 19:00:20 +0200
commitf4429533a6d2174e5f5e7674159090a63032be1a (patch)
tree76baf4d689ee0dbbe040598df18ccee92a7a9dd0 /src/arch
parentBSS is now zeroed by libprefix (along with the otherwise non-zeroable (diff)
downloadipxe-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/arch')
-rw-r--r--src/arch/i386/include/libkir.h4
-rw-r--r--src/arch/i386/include/librm.h11
-rw-r--r--src/arch/i386/include/realmode.h44
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,