(Redoing check-in lost by SourceForge's failure.)
authorMichael Brown <mcb30@etherboot.org>
Sat, 13 May 2006 11:11:55 +0000 (11:11 +0000)
committerMichael Brown <mcb30@etherboot.org>
Sat, 13 May 2006 11:11:55 +0000 (11:11 +0000)
Use .text16.data section with "aw" attributes, to avoid section type
conflicts when placing both code and data into .text16.

Add __from_{text16,data16}.

src/arch/i386/include/libkir.h
src/arch/i386/include/librm.h
src/arch/i386/include/realmode.h
src/arch/i386/transitions/librm.S

index 28db830..0923e22 100644 (file)
@@ -15,6 +15,8 @@
 #define __text16( variable ) variable
 #define __use_data16( variable ) variable
 #define __use_text16( variable ) variable
+#define __from_data16( variable ) variable
+#define __from_text16( variable ) variable
 
 /* Copy to/from base memory */
 
index 3a5d946..4301ff5 100644 (file)
@@ -25,7 +25,7 @@ extern char *text16;
 
 #define __text16( variable )                                           \
        _text16_ ## variable __asm__ ( #variable )                      \
-       __attribute__ (( section ( ".text16" ) ))
+       __attribute__ (( section ( ".text16.data" ) ))
 
 #define __use_data16( variable )                                       \
        ( * ( ( typeof ( _data16_ ## variable ) * )                     \
@@ -35,6 +35,14 @@ extern char *text16;
        ( * ( ( typeof ( _text16_ ## variable ) * )                     \
              & ( text16 [ ( size_t ) & ( _text16_ ## variable ) ] ) ) )
 
+#define __from_data16( variable )                                      \
+       ( * ( ( typeof ( variable ) * )                                 \
+             ( ( ( void * ) &(variable) ) - ( ( void * ) data16 ) ) ) )
+
+#define __from_text16( variable )                                      \
+       ( * ( ( typeof ( variable ) * )                                 \
+             ( ( ( void * ) &(variable) ) - ( ( void * ) text16 ) ) ) )
+
 /* Variables in librm.S, present in the normal data segment */
 extern uint16_t rm_sp;
 extern uint16_t rm_ss;
@@ -58,13 +66,14 @@ extern void gateA20_set ( void );
 #define VIRTUAL(x,y) ( phys_to_virt ( ( ( x ) << 4 ) + ( y ) ) )
 
 /* Copy to/from base memory */
-static inline void copy_to_real_librm ( uint16_t dest_seg, uint16_t dest_off,
-                                       void *src, size_t n ) {
+static inline __attribute__ (( always_inline )) void
+copy_to_real_librm ( unsigned int dest_seg, unsigned int dest_off,
+                    void *src, size_t n ) {
        memcpy ( VIRTUAL ( dest_seg, dest_off ), src, n );
 }
-static inline void copy_from_real_librm ( void *dest,
-                                         uint16_t src_seg, uint16_t src_off,
-                                         size_t n ) {
+static inline __attribute__ (( always_inline )) void
+copy_from_real_librm ( void *dest, unsigned int src_seg,
+                      unsigned int src_off, size_t n ) {
        memcpy ( dest, VIRTUAL ( src_seg, src_off ), n );
 }
 #define put_real_librm( var, dest_seg, dest_off )                            \
index fa8c786..07d41e5 100644 (file)
 /* Segment:offset structure.  Note that the order within the structure
  * is offset:segment.
  */
-typedef struct {
+struct segoff {
        uint16_t offset;
        uint16_t segment;
-} __attribute__ (( packed )) segoff_t;
+} __attribute__ (( packed ));
+
+typedef struct segoff segoff_t;
 
 /* Macro hackery needed to stringify bits of inline assembly */
 #define RM_XSTR(x) #x
@@ -50,8 +52,8 @@ typedef struct {
  *   extern uint32_t __data16 ( bar );
  *   #define bar __use_data16 ( bar );
  *
- *   extern long __data16 ( baz ) = 0xff000000UL;
- *   #define bar __use_data16 ( baz );
+ *   static long __data16 ( baz ) = 0xff000000UL;
+ *   #define baz __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> )
@@ -83,6 +85,12 @@ typedef struct {
  * Variables may also be placed in .text16 using __text16 and
  * __use_text16.  Some variables (e.g. chained interrupt vectors) fit
  * most naturally in .text16; most should be in .data16.
+ *
+ * If you have only a pointer to a magic symbol within .data16 or
+ * .text16, rather than the symbol itself, you can attempt to extract
+ * the underlying symbol name using __from_data16() or
+ * __from_text16().  This is not for the faint-hearted; check the
+ * assembler output to make sure that it's doing the right thing.
  */
 
 /*
index daa2e12..3dca53a 100644 (file)
@@ -19,7 +19,9 @@
 #define SIZEOF_I386_ALL_REGS   ( SIZEOF_REAL_MODE_REGS + SIZEOF_I386_FLAGS )
        
        .arch i386
-       .section ".text16", "awx", @progbits
+       .section ".text16", "ax", @progbits
+       .section ".text16.data", "aw", @progbits
+       .section ".data16", "aw", @progbits
 
 /****************************************************************************
  * Global descriptor table
@@ -45,7 +47,7 @@
 #else
 #define RM_LIMIT_16_19__AVL__SIZE__GRANULARITY 0x00
 #endif
-       .section ".data16", "aw", @progbits
+       .section ".data16"
        .align 16
 gdt:
 gdt_limit:             .word gdt_length - 1
@@ -308,7 +310,7 @@ p2r_jump_target:
 p2r_jump_vector:
        .word   p2r_jump_target
 rm_cs: .word 0
-       .section ".text16"
+       .section ".text16.data"
 rm_ds: .word 0
        
 /****************************************************************************