#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 */
#define __text16( variable ) \
_text16_ ## variable __asm__ ( #variable ) \
- __attribute__ (( section ( ".text16" ) ))
+ __attribute__ (( section ( ".text16.data" ) ))
#define __use_data16( variable ) \
( * ( ( typeof ( _data16_ ## variable ) * ) \
( * ( ( 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;
#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 ) \
/* 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
* 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> )
* 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.
*/
/*
#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
#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
p2r_jump_vector:
.word p2r_jump_target
rm_cs: .word 0
- .section ".text16"
+ .section ".text16.data"
rm_ds: .word 0
/****************************************************************************