diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2008-11-16 18:14:33 -0500 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2008-11-16 18:14:33 -0500 |
commit | 952974e3eccaefc667466e8309e15a7fbb867326 (patch) | |
tree | 3388804ea0ca999a065103e0a1af92542a65cbfa | |
parent | 3eac009553c4ecee2840a1d56358e0bb6bb0bf45 (diff) | |
download | seabios-952974e3eccaefc667466e8309e15a7fbb867326.tar.gz |
Add tool for generating assembler offset definition file.
Replace __call16 hardcoded offsets with auto generated struct offsets.
Also, load/save %ds register in __call16().
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | src/asm-offsets.c | 21 | ||||
-rw-r--r-- | src/gen-defs.h | 19 | ||||
-rw-r--r-- | src/romlayout.S | 39 | ||||
-rwxr-xr-x | tools/gen-offsets.sh | 17 |
5 files changed, 82 insertions, 19 deletions
@@ -86,11 +86,14 @@ $(OUT)%.lds: %.lds.S @echo " Precompiling $<" $(Q)$(CPP) -P -D__ASSEMBLY__ $< -o $@ +$(OUT)asm-offsets.h: $(OUT)asm-offsets.16.s + @echo " Generating offset file $@" + $(Q)./tools/gen-offsets.sh $< $@ $(OUT)blob.16.s: ; $(call whole-compile, $(CFLAGS16) -S, $(addprefix src/, $(SRC16)),$@) TABLEASM=$(addprefix $(OUT), $(patsubst %.c,%.proc.16.s,$(TABLESRC))) -$(OUT)romlayout16.o: romlayout.S $(OUT)blob.16.s $(TABLEASM) +$(OUT)romlayout16.o: romlayout.S $(OUT)blob.16.s $(OUT)asm-offsets.h $(TABLEASM) @echo " Generating 16bit layout of $@" $(Q)$(CC) $(CFLAGS16) -c -D__ASSEMBLY__ $< -o $@ diff --git a/src/asm-offsets.c b/src/asm-offsets.c new file mode 100644 index 00000000..8f17c045 --- /dev/null +++ b/src/asm-offsets.c @@ -0,0 +1,21 @@ +// Generate assembler offsets. + +#include "gen-defs.h" +#include "bregs.h" + +/* workaround for a warning with -Wmissing-prototypes */ +void foo(void) VISIBLE16; + +void foo(void) +{ + OFFSET(BREGS_es, bregs, es); + OFFSET(BREGS_ds, bregs, ds); + OFFSET(BREGS_eax, bregs, eax); + OFFSET(BREGS_ebx, bregs, ebx); + OFFSET(BREGS_ecx, bregs, ecx); + OFFSET(BREGS_edx, bregs, edx); + OFFSET(BREGS_esi, bregs, esi); + OFFSET(BREGS_edi, bregs, edi); + OFFSET(BREGS_flags, bregs, flags); + OFFSET(BREGS_ip, bregs, ip); +} diff --git a/src/gen-defs.h b/src/gen-defs.h new file mode 100644 index 00000000..dabf64cd --- /dev/null +++ b/src/gen-defs.h @@ -0,0 +1,19 @@ +// Tool for building defintions accessible from assembler code. This +// is based on code from the Linux Kernel. +#ifndef __GEN_DEFS_H +#define __GEN_DEFS_H + + +#define DEFINE(sym, val) \ + asm volatile("\n->" #sym " %0 " #val : : "i" (val)) + +#define BLANK() \ + asm volatile("\n->" : : ) + +#define OFFSET(sym, str, mem) \ + DEFINE(sym, offsetof(struct str, mem)) + +#define COMMENT(x) \ + asm volatile("\n->#" x) + +#endif // gen-defs.h diff --git a/src/romlayout.S b/src/romlayout.S index c1148ac5..a6bad458 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -8,6 +8,7 @@ #include "config.h" // CONFIG_* #include "ioport.h" // PORT_A20 #include "bregs.h" // CR0_* +#include "../out/asm-offsets.h" // BREGS_* /**************************************************************** @@ -240,17 +241,18 @@ __call16: // Setup for iretw call pushw $SEG_BIOS pushw $1f // return point - pushw 0x20(%eax) // flags - pushl 0x1c(%eax) // CS:IP + pushw BREGS_flags(%eax) // flags + pushl BREGS_ip(%eax) // CS:IP // Load calling registers. - movl 0x04(%eax), %edi - movl 0x08(%eax), %esi - movl 0x0c(%eax), %ebx - movl 0x10(%eax), %edx - movl 0x14(%eax), %ecx - movw 0x02(%eax), %es // XXX - should load %ds too - movl 0x18(%eax), %eax + movl BREGS_edi(%eax), %edi + movl BREGS_esi(%eax), %esi + movl BREGS_ebx(%eax), %ebx + movl BREGS_edx(%eax), %edx + movl BREGS_ecx(%eax), %ecx + movw BREGS_es(%eax), %es + movw BREGS_ds(%eax), %ds + movl %ss:BREGS_eax(%eax), %eax // Invoke call iretw // XXX - just do a lcalll @@ -259,20 +261,21 @@ __call16: pushfw pushl %eax movl 0x06(%esp), %eax - movl %ecx, %ss:0x14(%eax) // Save %ecx + movl %ecx, %ss:BREGS_ecx(%eax) + movw %ds, %ss:BREGS_ds(%eax) movw %ss, %cx - movw %cx, %ds // Restore %ds == %ss + movw %cx, %ds // Restore %ds == %ss popl %ecx - movl %ecx, 0x18(%eax) // Save %eax + movl %ecx, BREGS_eax(%eax) popw %cx - movw %cx, 0x20(%eax) // Save flags + movw %cx, BREGS_flags(%eax) // Store remaining registers - movw %es, 0x02(%eax) - movl %edi, 0x04(%eax) - movl %esi, 0x08(%eax) - movl %ebx, 0x0c(%eax) - movl %edx, 0x10(%eax) + movw %es, BREGS_es(%eax) + movl %edi, BREGS_edi(%eax) + movl %esi, BREGS_esi(%eax) + movl %ebx, BREGS_ebx(%eax) + movl %edx, BREGS_edx(%eax) // Remove %eax popl %eax diff --git a/tools/gen-offsets.sh b/tools/gen-offsets.sh new file mode 100755 index 00000000..99fdc53c --- /dev/null +++ b/tools/gen-offsets.sh @@ -0,0 +1,17 @@ +: +# Extract definitions from an assembler file. This is based on code +# from the Linux Kernel. +INFILE=$1 +OUTFILE=$2 +cat > "$OUTFILE" <<EOF +// This is an auto-generated file. DO NOT EDIT! +// Generated with "$0 $@" +#ifndef __ASM_OFFSETS_H +#define __ASM_OFFSETS_H +EOF +sed -ne "/^->/{s:->#\(.*\):/* \1 */:; \ + s:^->\([^ ]*\) [\$\#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \ + s:->::; p;}" < "$INFILE" >> "$OUTFILE" +cat >> "$OUTFILE" <<EOF +#endif // asm-offsets.h +EOF |