This patch against LinuxBIOSv3 enables calls from initram (freely located XIP
code) to stage0 (fixed location code) by forcing gcc to create an absolute call
instruction to stage0. 

Signed-off-by: Stefan Reinauer <stepan@coresystems.de>

Index: include/console.h
===================================================================
--- include/console.h	(revision 503)
+++ include/console.h	(working copy)
@@ -46,7 +46,13 @@
 };
 
 // 
+#ifndef XIP
 int printk(int msg_level, const char *fmt, ...) 
 	__attribute__((format (printf, 2, 3)));
+#else
+int stage0printk(int msg_level, const char *fmt, ...) 
+	__attribute__((format (printf, 2, 3)));
+int (*printk)(int msg_level, const char *fmt, ...) = stage0printk;
+#endif
 
 #endif /* CONSOLE_H */
Index: mainboard/adl/msm800sev/Makefile
===================================================================
--- mainboard/adl/msm800sev/Makefile	(revision 503)
+++ mainboard/adl/msm800sev/Makefile	(working copy)
@@ -32,14 +32,21 @@
 		$(obj)/southbridge/amd/cs5536/smbus_initram.o \
 		$(obj)/arch/x86/geodelx/geodelx.o
 
-# These are possibly not permanent
-INITRAM_OBJ += $(obj)/lib/console.o $(obj)/lib/vtxprintf.o $(obj)/lib/uart8250.o $(obj)/arch/x86/post_code.o
+# Next Quest: Make a single rule out of those:
+$(obj)/mainboard/$(MAINBOARDDIR)/initram.o: $(src)/mainboard/$(MAINBOARDDIR)/initram.c
+	$(Q)$(CC) $(INITCFLAGS) -DXIP -fPIE -c $< -o $@
+$(obj)/northbridge/amd/geodelx/raminit.o: $(src)/northbridge/amd/geodelx/raminit.c
+	$(Q)$(CC) $(INITCFLAGS) -DXIP -fPIE -c $< -o $@
+$(obj)/southbridge/amd/cs5536/smbus_initram.o: $(src)/southbridge/amd/cs5536/smbus_initram.c
+	$(Q)$(CC) $(INITCFLAGS) -DXIP -fPIE -c $< -o $@
+$(obj)/arch/x86/geodelx/geodelx.o: $(src)/arch/x86/geodelx/geodelx.c
+	$(Q)$(CC) $(INITCFLAGS) -DXIP -fPIE -c $< -o $@
 
 $(obj)/linuxbios.initram: $(obj)/stage0.init $(obj)/stage0.o $(INITRAM_OBJ) 
 	$(Q)# initram links against stage0
 	$(Q)printf "  LD      $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)$(LD) -Ttext 0x80000 $(INITRAM_OBJ) \
-		--entry=main -o $(obj)/linuxbios.initram.o
+		-R $(obj)/stage0-prefixed.o --entry=main -o $(obj)/linuxbios.initram.o
 	$(Q)printf "  OBJCOPY $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)$(OBJCOPY) -O binary $(obj)/linuxbios.initram.o \
 		$(obj)/linuxbios.initram
Index: mainboard/amd/norwich/Makefile
===================================================================
--- mainboard/amd/norwich/Makefile	(revision 503)
+++ mainboard/amd/norwich/Makefile	(working copy)
@@ -26,8 +26,15 @@
 		$(obj)/southbridge/amd/cs5536/smbus_initram.o \
 		$(obj)/arch/x86/geodelx/geodelx.o
 
-# These are possibly not permanent
-INITRAM_OBJ += $(obj)/lib/console.o $(obj)/lib/vtxprintf.o $(obj)/lib/uart8250.o $(obj)/arch/x86/post_code.o
+# Next Quest: Make a single rule out of those:
+$(obj)/mainboard/$(MAINBOARDDIR)/initram.o: $(src)/mainboard/$(MAINBOARDDIR)/initram.c
+	$(Q)$(CC) $(INITCFLAGS) -DXIP -fPIE -c $< -o $@
+$(obj)/northbridge/amd/geodelx/raminit.o: $(src)/northbridge/amd/geodelx/raminit.c
+	$(Q)$(CC) $(INITCFLAGS) -DXIP -fPIE -c $< -o $@
+$(obj)/southbridge/amd/cs5536/smbus_initram.o: $(src)/southbridge/amd/cs5536/smbus_initram.c
+	$(Q)$(CC) $(INITCFLAGS) -DXIP -fPIE -c $< -o $@
+$(obj)/arch/x86/geodelx/geodelx.o: $(src)/arch/x86/geodelx/geodelx.c
+	$(Q)$(CC) $(INITCFLAGS) -DXIP -fPIE -c $< -o $@
 
 STAGE2_MAINBOARD_OBJ = 
 
@@ -39,7 +46,7 @@
 	$(Q)# initram links against stage0
 	$(Q)printf "  LD      $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)$(LD) -Ttext 0x80000 $(INITRAM_OBJ) \
-		--entry=main -o $(obj)/linuxbios.initram.o
+		-R $(obj)/stage0-prefixed.o --entry=main -o $(obj)/linuxbios.initram.o
 	$(Q)printf "  OBJCOPY $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)$(OBJCOPY) -O binary $(obj)/linuxbios.initram.o \
 		$(obj)/linuxbios.initram
Index: mainboard/artecgroup/dbe61/Makefile
===================================================================
--- mainboard/artecgroup/dbe61/Makefile	(revision 503)
+++ mainboard/artecgroup/dbe61/Makefile	(working copy)
@@ -30,14 +30,21 @@
 INITRAM_OBJ =   $(obj)/mainboard/$(MAINBOARDDIR)/initram.o \
 		$(obj)/arch/x86/geodelx/geodelx.o
 
-# These are possibly not permanent
-INITRAM_OBJ += $(obj)/lib/console.o $(obj)/lib/vtxprintf.o $(obj)/lib/uart8250.o $(obj)/arch/x86/post_code.o
+# Next Quest: Make a single rule out of those:
+$(obj)/mainboard/$(MAINBOARDDIR)/initram.o: $(src)/mainboard/$(MAINBOARDDIR)/initram.c
+	$(Q)$(CC) $(INITCFLAGS) -DXIP -fPIE -c $< -o $@
+$(obj)/northbridge/amd/geodelx/raminit.o: $(src)/northbridge/amd/geodelx/raminit.c
+	$(Q)$(CC) $(INITCFLAGS) -DXIP -fPIE -c $< -o $@
+$(obj)/southbridge/amd/cs5536/smbus_initram.o: $(src)/southbridge/amd/cs5536/smbus_initram.c
+	$(Q)$(CC) $(INITCFLAGS) -DXIP -fPIE -c $< -o $@
+$(obj)/arch/x86/geodelx/geodelx.o: $(src)/arch/x86/geodelx/geodelx.c
+	$(Q)$(CC) $(INITCFLAGS) -DXIP -fPIE -c $< -o $@
 
 $(obj)/linuxbios.initram: $(obj)/stage0.init $(obj)/stage0.o $(INITRAM_OBJ)
 	$(Q)# initram links against stage0
 	$(Q)printf "  LD      $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)$(LD) -Ttext 0x80000 $(INITRAM_OBJ) \
-		--entry=main -o $(obj)/linuxbios.initram.o
+		-R $(obj)/stage0-prefixed.o --entry=main -o $(obj)/linuxbios.initram.o
 	$(Q)printf "  OBJCOPY $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)$(OBJCOPY) -O binary $(obj)/linuxbios.initram.o \
 		$(obj)/linuxbios.initram
Index: mainboard/emulation/qemu-x86/Makefile
===================================================================
--- mainboard/emulation/qemu-x86/Makefile	(revision 503)
+++ mainboard/emulation/qemu-x86/Makefile	(working copy)
@@ -41,14 +41,15 @@
 #
 
 INITRAM_OBJ = $(obj)/mainboard/$(MAINBOARDDIR)/initram.o
-# These are possibly not permanent
-INITRAM_OBJ += $(obj)/lib/console.o $(obj)/lib/vtxprintf.o $(obj)/lib/uart8250.o $(obj)/arch/x86/post_code.o
 
+$(obj)/mainboard/$(MAINBOARDDIR)/initram.o: $(src)/mainboard/$(MAINBOARDDIR)/initram.c
+	$(Q)$(CC) $(INITCFLAGS) -DXIP -fPIE -c $< -o $@
+
 $(obj)/linuxbios.initram: $(obj)/stage0.init $(obj)/stage0.o $(INITRAM_OBJ)
 	$(Q)# initram links against stage0
 	$(Q)printf "  LD      $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)$(LD)  -Ttext 0x80000 $(INITRAM_OBJ) \
-		--entry=main -o $(obj)/linuxbios.initram.o
+		-R $(obj)/stage0-prefixed.o --entry=main -o $(obj)/linuxbios.initram.o
 	$(Q)printf "  OBJCOPY $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)$(OBJCOPY) -O binary $(obj)/linuxbios.initram.o \
 		$(obj)/linuxbios.initram
Index: arch/x86/ldscript.ld
===================================================================
--- arch/x86/ldscript.ld	(revision 503)
+++ arch/x86/ldscript.ld	(working copy)
@@ -33,10 +33,13 @@
 	.stage0_1 . : {
 		_stage0_1 = .;
 		*(.text);
+		*(.text.*)
+		*(.rodata)
+		*(.rodata.*)
+		*(.got)
+		*(.got.*)
 		*(.data);
 		*(.bss);
-		*(.rodata.*)
-		*(.rodata)
 		_estage0_1 = .;
 	}
 	/DISCARD/ : {
Index: arch/x86/Makefile
===================================================================
--- arch/x86/Makefile	(revision 503)
+++ arch/x86/Makefile	(working copy)
@@ -148,6 +148,9 @@
 	$(Q)printf "  OBJCOPY $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)$(OBJCOPY) -O binary $(obj)/stage0.o $(obj)/stage0.init
 
+	$(Q)printf "  OBJCOPY $(subst $(shell pwd)/,,$(@)) (prefixing stage0)\n"
+	$(Q)$(OBJCOPY) --prefix-symbols=stage0 $(obj)/stage0.o $(obj)/stage0-prefixed.o
+
 	$(Q)printf "  TEST    $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)test `wc -c < $(obj)/stage0.init` -gt 16128 && \
 		printf "Error. Bootblock got too big.\n" || true
