From e5f325fec5b48ae705c89522923ba5a2e37cd5c7 Mon Sep 17 00:00:00 2001 From: Shinya Kuribayashi Date: Sun, 21 Oct 2007 10:55:36 +0900 Subject: [PATCH 1/6] [MIPS] u-boot.lds: Remove duplicated .sdata section Signed-off-by: Shinya Kuribayashi --- board/dbau1x00/u-boot.lds | 3 --- board/gth2/u-boot.lds | 3 --- board/incaip/u-boot.lds | 3 --- board/pb1x00/u-boot.lds | 3 --- board/purple/u-boot.lds | 3 --- board/tb0229/u-boot.lds | 3 --- examples/mips.lds | 3 --- 7 files changed, 21 deletions(-) diff --git a/board/dbau1x00/u-boot.lds b/board/dbau1x00/u-boot.lds index 10c9917..75a3af6 100644 --- a/board/dbau1x00/u-boot.lds +++ b/board/dbau1x00/u-boot.lds @@ -43,9 +43,6 @@ SECTIONS . = ALIGN(4); .data : { *(.data) } - . = ALIGN(4); - .sdata : { *(.sdata) } - _gp = ALIGN(16); __got_start = .; diff --git a/board/gth2/u-boot.lds b/board/gth2/u-boot.lds index 8ba0b6d..69c8c9d 100644 --- a/board/gth2/u-boot.lds +++ b/board/gth2/u-boot.lds @@ -43,9 +43,6 @@ SECTIONS . = ALIGN(4); .data : { *(.data) } - . = ALIGN(4); - .sdata : { *(.sdata) } - _gp = ALIGN(16); __got_start = .; diff --git a/board/incaip/u-boot.lds b/board/incaip/u-boot.lds index 10c9917..75a3af6 100644 --- a/board/incaip/u-boot.lds +++ b/board/incaip/u-boot.lds @@ -43,9 +43,6 @@ SECTIONS . = ALIGN(4); .data : { *(.data) } - . = ALIGN(4); - .sdata : { *(.sdata) } - _gp = ALIGN(16); __got_start = .; diff --git a/board/pb1x00/u-boot.lds b/board/pb1x00/u-boot.lds index a2d19a8..865be77 100644 --- a/board/pb1x00/u-boot.lds +++ b/board/pb1x00/u-boot.lds @@ -43,9 +43,6 @@ SECTIONS . = ALIGN(4); .data : { *(.data) } - . = ALIGN(4); - .sdata : { *(.sdata) } - _gp = ALIGN(16); __got_start = .; diff --git a/board/purple/u-boot.lds b/board/purple/u-boot.lds index 1bdac1f..6b3783f 100644 --- a/board/purple/u-boot.lds +++ b/board/purple/u-boot.lds @@ -53,9 +53,6 @@ SECTIONS . = ALIGN(4); .data : { *(.data) } - . = ALIGN(4); - .sdata : { *(.sdata) } - _gp = ALIGN(16); __got_start = .; diff --git a/board/tb0229/u-boot.lds b/board/tb0229/u-boot.lds index 30a2bc5..26d8c81 100644 --- a/board/tb0229/u-boot.lds +++ b/board/tb0229/u-boot.lds @@ -43,9 +43,6 @@ SECTIONS . = ALIGN(4); .data : { *(.data) } - . = ALIGN(4); - .sdata : { *(.sdata) } - _gp = ALIGN(16); __got_start = .; diff --git a/examples/mips.lds b/examples/mips.lds index 9d9849b..6f31eb7 100644 --- a/examples/mips.lds +++ b/examples/mips.lds @@ -39,9 +39,6 @@ SECTIONS . = ALIGN(4); .data : { *(.data) } - . = ALIGN(4); - .sdata : { *(.sdata) } - _gp = ALIGN(16); __got_start = .; From cbf2323b5b8285ea01acba7bbb905a3162d9b021 Mon Sep 17 00:00:00 2001 From: Shinya Kuribayashi Date: Sun, 21 Oct 2007 10:55:36 +0900 Subject: [PATCH 2/6] [MIPS] u-boot.lds: Fix __got_start and __got_end Ensure that __got_start points to top of the `.got', and __got_end points to bottom as well, so that we never fail to count num_got_entries. Signed-off-by: Shinya Kuribayashi --- board/dbau1x00/u-boot.lds | 8 +++++--- board/gth2/u-boot.lds | 8 +++++--- board/incaip/u-boot.lds | 8 +++++--- board/pb1x00/u-boot.lds | 8 +++++--- board/purple/u-boot.lds | 8 +++++--- board/tb0229/u-boot.lds | 8 +++++--- examples/mips.lds | 8 +++++--- 7 files changed, 35 insertions(+), 21 deletions(-) diff --git a/board/dbau1x00/u-boot.lds b/board/dbau1x00/u-boot.lds index 75a3af6..9c71ef7 100644 --- a/board/dbau1x00/u-boot.lds +++ b/board/dbau1x00/u-boot.lds @@ -45,9 +45,11 @@ SECTIONS _gp = ALIGN(16); - __got_start = .; - .got : { *(.got) } - __got_end = .; + .got : { + __got_start = .; + *(.got) + __got_end = .; + } .sdata : { *(.sdata) } diff --git a/board/gth2/u-boot.lds b/board/gth2/u-boot.lds index 69c8c9d..0ab42db 100644 --- a/board/gth2/u-boot.lds +++ b/board/gth2/u-boot.lds @@ -45,9 +45,11 @@ SECTIONS _gp = ALIGN(16); - __got_start = .; - .got : { *(.got) } - __got_end = .; + .got : { + __got_start = .; + *(.got) + __got_end = .; + } .sdata : { *(.sdata) } diff --git a/board/incaip/u-boot.lds b/board/incaip/u-boot.lds index 75a3af6..9c71ef7 100644 --- a/board/incaip/u-boot.lds +++ b/board/incaip/u-boot.lds @@ -45,9 +45,11 @@ SECTIONS _gp = ALIGN(16); - __got_start = .; - .got : { *(.got) } - __got_end = .; + .got : { + __got_start = .; + *(.got) + __got_end = .; + } .sdata : { *(.sdata) } diff --git a/board/pb1x00/u-boot.lds b/board/pb1x00/u-boot.lds index 865be77..7329e6a 100644 --- a/board/pb1x00/u-boot.lds +++ b/board/pb1x00/u-boot.lds @@ -45,9 +45,11 @@ SECTIONS _gp = ALIGN(16); - __got_start = .; - .got : { *(.got) } - __got_end = .; + .got : { + __got_start = .; + *(.got) + __got_end = .; + } .sdata : { *(.sdata) } diff --git a/board/purple/u-boot.lds b/board/purple/u-boot.lds index 6b3783f..aa51cbf 100644 --- a/board/purple/u-boot.lds +++ b/board/purple/u-boot.lds @@ -55,9 +55,11 @@ SECTIONS _gp = ALIGN(16); - __got_start = .; - .got : { *(.got) } - __got_end = .; + .got : { + __got_start = .; + *(.got) + __got_end = .; + } .sdata : { *(.sdata) } diff --git a/board/tb0229/u-boot.lds b/board/tb0229/u-boot.lds index 26d8c81..148f5e6 100644 --- a/board/tb0229/u-boot.lds +++ b/board/tb0229/u-boot.lds @@ -45,9 +45,11 @@ SECTIONS _gp = ALIGN(16); - __got_start = .; - .got : { *(.got) } - __got_end = .; + .got : { + __got_start = .; + *(.got) + __got_end = .; + } .sdata : { *(.sdata) } diff --git a/examples/mips.lds b/examples/mips.lds index 6f31eb7..3bd573c 100644 --- a/examples/mips.lds +++ b/examples/mips.lds @@ -41,9 +41,11 @@ SECTIONS _gp = ALIGN(16); - __got_start = .; - .got : { *(.got) } - __got_end = .; + .got : { + __got_start = .; + *(.got) + __got_end = .; + } .sdata : { *(.sdata) } From 22069215eb7adf5a3888bf7c7784ea9d70a72cd0 Mon Sep 17 00:00:00 2001 From: Shinya Kuribayashi Date: Sun, 21 Oct 2007 10:55:36 +0900 Subject: [PATCH 3/6] [MIPS] Fix $gp usage Now we load $gp with _GLOBAL_OFFSET_TABLE_, but this is incorrect use. As a general principle, we should use _gp for $gp. Thanks to linker script's help we fortunately have _gp which equals to _GLOBAL_OFFSET_TABLE_. But once _gp gets out of alignment, we will not be able to access to GOT entires, global variables and procedure entry points. The right thing to do is to use _gp. This patch also introduce a new symbol `.gpword _GLOBAL_OFFSET_TABLE_' which holds the offset from _gp. When updating GOT entries, we use this offset and _gp to calculate the final _GLOBAL_OFFSET_TABLE_. This patch is originally submitted by Vlad Lungu , then I made some change to leave over num_got_entries. Signed-off-by: Shinya Kuribayashi Cc: Vlad Lungu --- cpu/mips/start.S | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/cpu/mips/start.S b/cpu/mips/start.S index e91e213..074d01d 100644 --- a/cpu/mips/start.S +++ b/cpu/mips/start.S @@ -234,11 +234,11 @@ reset: li t0, CONF_CM_UNCACHED mtc0 t0, CP0_CONFIG - /* Initialize GOT pointer. + /* Initialize $gp. */ bal 1f nop - .word _GLOBAL_OFFSET_TABLE_ + .word _gp 1: move gp, ra lw t1, 0(ra) @@ -306,9 +306,9 @@ relocate_code: move t1, a2 /* - * Fix GOT pointer: + * Fix $gp: * - * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address + * New $gp = (Old $gp - CFG_MONITOR_BASE) + Destination Address */ move t6, gp sub gp, CFG_MONITOR_BASE @@ -341,15 +341,22 @@ relocate_code: j t0 nop + .gpword _GLOBAL_OFFSET_TABLE_ /* _GLOBAL_OFFSET_TABLE_ - _gp */ .word uboot_end_data .word uboot_end .word num_got_entries in_ram: - /* Now we want to update GOT. + /* + * Now we want to update GOT. + * + * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object + * generated by GNU ld. Skip these reserved entries from relocation. */ lw t3, -4(t0) /* t3 <-- num_got_entries */ - addi t4, gp, 8 /* Skipping first two entries. */ + lw t4, -16(t0) /* t4 <-- (_GLOBAL_OFFSET_TABLE_ - _gp) */ + add t4, t4, gp /* t4 now holds _GLOBAL_OFFSET_TABLE_ */ + addi t4, t4, 8 /* Skipping first two entries. */ li t2, 2 1: lw t1, 0(t4) From eb700636db017d310edaeb559b13d82588560674 Mon Sep 17 00:00:00 2001 From: Shinya Kuribayashi Date: Sun, 21 Oct 2007 10:55:37 +0900 Subject: [PATCH 4/6] [MIPS] u-boot.lds: Define _gp in a standard manner Signed-off-by: Shinya Kuribayashi --- board/dbau1x00/u-boot.lds | 3 ++- board/gth2/u-boot.lds | 3 ++- board/incaip/u-boot.lds | 3 ++- board/pb1x00/u-boot.lds | 3 ++- board/purple/u-boot.lds | 3 ++- board/tb0229/u-boot.lds | 3 ++- examples/mips.lds | 3 ++- 7 files changed, 14 insertions(+), 7 deletions(-) diff --git a/board/dbau1x00/u-boot.lds b/board/dbau1x00/u-boot.lds index 9c71ef7..9639b81 100644 --- a/board/dbau1x00/u-boot.lds +++ b/board/dbau1x00/u-boot.lds @@ -43,7 +43,8 @@ SECTIONS . = ALIGN(4); .data : { *(.data) } - _gp = ALIGN(16); + . = .; + _gp = ALIGN(16) + 0x7ff0; .got : { __got_start = .; diff --git a/board/gth2/u-boot.lds b/board/gth2/u-boot.lds index 0ab42db..90432cb 100644 --- a/board/gth2/u-boot.lds +++ b/board/gth2/u-boot.lds @@ -43,7 +43,8 @@ SECTIONS . = ALIGN(4); .data : { *(.data) } - _gp = ALIGN(16); + . = .; + _gp = ALIGN(16) + 0x7ff0; .got : { __got_start = .; diff --git a/board/incaip/u-boot.lds b/board/incaip/u-boot.lds index 9c71ef7..9639b81 100644 --- a/board/incaip/u-boot.lds +++ b/board/incaip/u-boot.lds @@ -43,7 +43,8 @@ SECTIONS . = ALIGN(4); .data : { *(.data) } - _gp = ALIGN(16); + . = .; + _gp = ALIGN(16) + 0x7ff0; .got : { __got_start = .; diff --git a/board/pb1x00/u-boot.lds b/board/pb1x00/u-boot.lds index 7329e6a..363d974 100644 --- a/board/pb1x00/u-boot.lds +++ b/board/pb1x00/u-boot.lds @@ -43,7 +43,8 @@ SECTIONS . = ALIGN(4); .data : { *(.data) } - _gp = ALIGN(16); + . = .; + _gp = ALIGN(16) + 0x7ff0; .got : { __got_start = .; diff --git a/board/purple/u-boot.lds b/board/purple/u-boot.lds index aa51cbf..e7ec012 100644 --- a/board/purple/u-boot.lds +++ b/board/purple/u-boot.lds @@ -53,7 +53,8 @@ SECTIONS . = ALIGN(4); .data : { *(.data) } - _gp = ALIGN(16); + . = .; + _gp = ALIGN(16) + 0x7ff0; .got : { __got_start = .; diff --git a/board/tb0229/u-boot.lds b/board/tb0229/u-boot.lds index 148f5e6..b2fa9f2 100644 --- a/board/tb0229/u-boot.lds +++ b/board/tb0229/u-boot.lds @@ -43,7 +43,8 @@ SECTIONS . = ALIGN(4); .data : { *(.data) } - _gp = ALIGN(16); + . = .; + _gp = ALIGN(16) + 0x7ff0; .got : { __got_start = .; diff --git a/examples/mips.lds b/examples/mips.lds index 3bd573c..a770728 100644 --- a/examples/mips.lds +++ b/examples/mips.lds @@ -39,7 +39,8 @@ SECTIONS . = ALIGN(4); .data : { *(.data) } - _gp = ALIGN(16); + . = .; + _gp = ALIGN(16) + 0x7ff0; .got : { __got_start = .; From 00101dd7a32d12f698150123e47e4b3420279f86 Mon Sep 17 00:00:00 2001 From: Shinya Kuribayashi Date: Sun, 21 Oct 2007 21:30:42 +0900 Subject: [PATCH 5/6] [MIPS] Add PIC-related switches to PLATFORM_{CPP,LD}FLAGS and cleanup Signed-off-by: Shinya Kuribayashi --- cpu/mips/config.mk | 2 +- mips_config.mk | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/cpu/mips/config.mk b/cpu/mips/config.mk index b29986e..487c4eb 100644 --- a/cpu/mips/config.mk +++ b/cpu/mips/config.mk @@ -35,6 +35,6 @@ else ENDIANNESS = -EB endif -MIPSFLAGS += $(ENDIANNESS) -mabicalls +MIPSFLAGS += $(ENDIANNESS) PLATFORM_CPPFLAGS += $(MIPSFLAGS) diff --git a/mips_config.mk b/mips_config.mk index d8aa5fa..67fb67d 100644 --- a/mips_config.mk +++ b/mips_config.mk @@ -22,3 +22,28 @@ # PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__MIPS__ + +# +# From Linux arch/mips/Makefile +# +# GCC uses -G 0 -mabicalls -fpic as default. We don't want PIC in the kernel +# code since it only slows down the whole thing. At some point we might make +# use of global pointer optimizations but their use of $28 conflicts with +# the current pointer optimization. +# +# The DECStation requires an ECOFF kernel for remote booting, other MIPS +# machines may also. Since BFD is incredibly buggy with respect to +# crossformat linking we rely on the elf2ecoff tool for format conversion. +# +# cflags-y += -G 0 -mno-abicalls -fno-pic -pipe +# cflags-y += -msoft-float +# LDFLAGS_vmlinux += -G 0 -static -n -nostdlib +# MODFLAGS += -mlong-calls +# + +# +# Meanwhile, U-Boot rely on PIC. We add proper switches explicitly. +# +PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic -pipe +PLATFORM_CPPFLAGS += -msoft-float +PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib From de9a738faa7c2f47286119c3bfebc3dfbfe7d86d Mon Sep 17 00:00:00 2001 From: Vlad Lungu Date: Sun, 21 Oct 2007 22:10:10 +0900 Subject: [PATCH 6/6] [MIPS] Fix UNCACHED_SDRAM PHYSADDR is for physical address, KSEG1ADDR is for uncached. Signed-off-by: Vlad Lungu Signed-off-by: Shinya Kuribayashi --- include/asm-mips/addrspace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-mips/addrspace.h b/include/asm-mips/addrspace.h index b8214b1..0e6abd7 100644 --- a/include/asm-mips/addrspace.h +++ b/include/asm-mips/addrspace.h @@ -49,7 +49,7 @@ cannot access physical memory directly from core */ #define UNCACHED_SDRAM(a) (((unsigned long)(a)) | 0x20000000) #else /* !CONFIG_AU1X00 */ -#define UNCACHED_SDRAM(a) PHYSADDR(a) +#define UNCACHED_SDRAM(a) KSEG1ADDR(a) #endif /* CONFIG_AU1X00 */ #endif /* __ASSEMBLY__ */ /*