On 05/10/2021 23.53, BALATON Zoltan wrote:
[...]
Maybe these 405 boards in QEMU ran with modified firmware where the memory
detection was patched out but it seems to detect the RAM so I wonder where
it gets that from. Maybe by reading the SDRAM controller DCRs
ppc4xx_sdram_init() sets up. Then I'm not sure what it needs the SPD for, I
forgot how this worked on sam460ex. Maybe for the speed calibration, so
could be it detects ram by reading DCRs then tries to get SPD data and
that's where it stops as i2c is not emulated on taihu. This could be
confirmed by checking what it pokes with -d guest_errors that shows accesses
to missing devices but don't know where 405 has the i2c controller and if
it's the same as newer SoCs. If so that could be reused and an i2c bus could
be added with the SPD data like in sam460ex to make u-boot happy or you
could skip this in u-boot.
FWIW, I've just tried the latter (skipping the sdram init in u-boot), and
indeed, I can get to the u-boot prompt now. Binary can be found here:
http://people.redhat.com/~thuth/data/u-boot-taihu-skip-sdram.bin
Christophe, maybe that's already enough for you to boot a Linux kernel with
the "taihu" board? (or do you need the ref405ep board instead?)
I've also attached the patch with my modifications to u-boot.
To build the u-boot firmware:
git clone git://git.denx.de/u-boot.git
cd u-boot
git checkout 123b6cd7a4f75536734a7bff97db6eebce614bd1~1
patch -p1 -i .../u-boot-taihu.patch
make taihu_defconfig CROSS_COMPILE=powerpc-...
make CROSS_COMPILE=powerpc-...
... if the linker complains at the end, remove some features from the
".config" file, like CONFIG_CMD_NFS, and run make again.
Thomas
diff --git a/arch/powerpc/cpu/ppc4xx/sdram.c b/arch/powerpc/cpu/ppc4xx/sdram.c
index d4ef36d39f..729f69f5c2 100644
--- a/arch/powerpc/cpu/ppc4xx/sdram.c
+++ b/arch/powerpc/cpu/ppc4xx/sdram.c
@@ -172,14 +172,13 @@ phys_size_t initdram(int board_type)
/*
* Disable memory controller.
*/
- mtsdram(SDRAM0_CFG, 0x00000000);
-
+// mtsdram(SDRAM0_CFG, 0x00000000);
/*
* Set MB0CF for bank 0.
*/
- mtsdram(SDRAM0_B0CR, mb0cf[i].reg);
- mtsdram(SDRAM0_TR, sdtr1);
- mtsdram(SDRAM0_RTR, compute_rtr(speed, mb0cf[i].rows, 64));
+// mtsdram(SDRAM0_B0CR, mb0cf[i].reg);
+// mtsdram(SDRAM0_TR, sdtr1);
+// mtsdram(SDRAM0_RTR, compute_rtr(speed, mb0cf[i].rows, 64));
udelay(200);
@@ -199,7 +198,7 @@ phys_size_t initdram(int board_type)
* OK, size detected. Enable second bank if
* defined (assumes same type as bank 0)
*/
-#ifdef CONFIG_SDRAM_BANK1
+#if 0 //def CONFIG_SDRAM_BANK1
mtsdram(SDRAM0_CFG, 0x00000000);
mtsdram(SDRAM0_B1CR, mb0cf[i].size | mb0cf[i].reg);
mtsdram(SDRAM0_CFG, 0x80800000);
@@ -230,7 +229,7 @@ phys_size_t initdram(int board_type)
}
}
- return 0;
+ return 128*1024*1024; /* Hack */
}
#else /* CONFIG_440 */
diff --git a/arch/powerpc/cpu/ppc4xx/u-boot.lds b/arch/powerpc/cpu/ppc4xx/u-boot.lds
index 198050853a..55dd4e1300 100644
--- a/arch/powerpc/cpu/ppc4xx/u-boot.lds
+++ b/arch/powerpc/cpu/ppc4xx/u-boot.lds
@@ -46,7 +46,6 @@ SECTIONS
_GOT2_TABLE_ = .;
KEEP(*(.got2))
KEEP(*(.got))
- PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
_FIXUP_TABLE_ = .;
KEEP(*(.fixup))
}
diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h
index a6bcf3c3fe..4aba02a031 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -7,12 +7,14 @@
#include <asm/byteorder.h>
+/*
extern void set_bit(int nr, volatile void *addr);
extern void clear_bit(int nr, volatile void *addr);
extern void change_bit(int nr, volatile void *addr);
extern int test_and_set_bit(int nr, volatile void *addr);
extern int test_and_clear_bit(int nr, volatile void *addr);
extern int test_and_change_bit(int nr, volatile void *addr);
+*/
/*
* Arguably these bit operations don't imply any memory barrier or
@@ -34,7 +36,7 @@ extern int test_and_change_bit(int nr, volatile void *addr);
* These used to be if'd out here because using : "cc" as a constraint
* resulted in errors from egcs. Things may be OK with gcc-2.95.
*/
-extern __inline__ void set_bit(int nr, volatile void * addr)
+static __inline__ void set_bit(int nr, volatile void * addr)
{
unsigned long old;
unsigned long mask = 1 << (nr & 0x1f);
@@ -51,7 +53,7 @@ extern __inline__ void set_bit(int nr, volatile void * addr)
: "cc" );
}
-extern __inline__ void clear_bit(int nr, volatile void *addr)
+static __inline__ void clear_bit(int nr, volatile void *addr)
{
unsigned long old;
unsigned long mask = 1 << (nr & 0x1f);
@@ -68,7 +70,7 @@ extern __inline__ void clear_bit(int nr, volatile void *addr)
: "cc");
}
-extern __inline__ void change_bit(int nr, volatile void *addr)
+static __inline__ void change_bit(int nr, volatile void *addr)
{
unsigned long old;
unsigned long mask = 1 << (nr & 0x1f);
@@ -85,7 +87,7 @@ extern __inline__ void change_bit(int nr, volatile void *addr)
: "cc");
}
-extern __inline__ int test_and_set_bit(int nr, volatile void *addr)
+static __inline__ int test_and_set_bit(int nr, volatile void *addr)
{
unsigned int old, t;
unsigned int mask = 1 << (nr & 0x1f);
@@ -104,7 +106,7 @@ extern __inline__ int test_and_set_bit(int nr, volatile void *addr)
return (old & mask) != 0;
}
-extern __inline__ int test_and_clear_bit(int nr, volatile void *addr)
+static __inline__ int test_and_clear_bit(int nr, volatile void *addr)
{
unsigned int old, t;
unsigned int mask = 1 << (nr & 0x1f);
@@ -123,7 +125,7 @@ extern __inline__ int test_and_clear_bit(int nr, volatile void *addr)
return (old & mask) != 0;
}
-extern __inline__ int test_and_change_bit(int nr, volatile void *addr)
+static __inline__ int test_and_change_bit(int nr, volatile void *addr)
{
unsigned int old, t;
unsigned int mask = 1 << (nr & 0x1f);
@@ -143,7 +145,7 @@ extern __inline__ int test_and_change_bit(int nr, volatile void *addr)
}
#endif /* __INLINE_BITOPS */
-extern __inline__ int test_bit(int nr, __const__ volatile void *addr)
+static __inline__ int test_bit(int nr, __const__ volatile void *addr)
{
__const__ unsigned int *p = (__const__ unsigned int *) addr;
@@ -152,7 +154,7 @@ extern __inline__ int test_bit(int nr, __const__ volatile void *addr)
/* Return the bit position of the most significant 1 bit in a word */
/* - the result is undefined when x == 0 */
-extern __inline__ int __ilog2(unsigned int x)
+static __inline__ int __ilog2(unsigned int x)
{
int lz;
@@ -160,7 +162,7 @@ extern __inline__ int __ilog2(unsigned int x)
return 31 - lz;
}
-extern __inline__ int ffz(unsigned int x)
+static __inline__ int ffz(unsigned int x)
{
if ((x = ~x) == 0)
return 32;
@@ -226,7 +228,7 @@ static inline int ffs64(u64 x)
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
*/
-extern __inline__ int ffs(int x)
+static __inline__ int ffs(int x)
{
return __ilog2(x & -x) + 1;
}
@@ -250,7 +252,7 @@ extern __inline__ int ffs(int x)
#define find_first_zero_bit(addr, size) \
find_next_zero_bit((addr), (size), 0)
-extern __inline__ unsigned long find_next_zero_bit(void * addr,
+static __inline__ unsigned long find_next_zero_bit(void * addr,
unsigned long size, unsigned long offset)
{
unsigned int * p = ((unsigned int *) addr) + (offset >> 5);
@@ -298,7 +300,7 @@ found_middle:
#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr) ^ 0x18, addr)
#else
-extern __inline__ int ext2_set_bit(int nr, void * addr)
+static __inline__ int ext2_set_bit(int nr, void * addr)
{
int mask;
unsigned char *ADDR = (unsigned char *) addr;
@@ -311,7 +313,7 @@ extern __inline__ int ext2_set_bit(int nr, void * addr)
return oldbit;
}
-extern __inline__ int ext2_clear_bit(int nr, void * addr)
+static __inline__ int ext2_clear_bit(int nr, void * addr)
{
int mask;
unsigned char *ADDR = (unsigned char *) addr;
@@ -325,7 +327,7 @@ extern __inline__ int ext2_clear_bit(int nr, void * addr)
}
#endif /* __KERNEL__ */
-extern __inline__ int ext2_test_bit(int nr, __const__ void * addr)
+static __inline__ int ext2_test_bit(int nr, __const__ void * addr)
{
__const__ unsigned char *ADDR = (__const__ unsigned char *) addr;
diff --git a/arch/powerpc/include/asm/byteorder.h b/arch/powerpc/include/asm/byteorder.h
index 3f5bcf63a1..5f57a08d39 100644
--- a/arch/powerpc/include/asm/byteorder.h
+++ b/arch/powerpc/include/asm/byteorder.h
@@ -5,7 +5,7 @@
#ifdef __GNUC__
-extern __inline__ unsigned ld_le16(const volatile unsigned short *addr)
+static __inline__ unsigned ld_le16(const volatile unsigned short *addr)
{
unsigned val;
@@ -13,12 +13,12 @@ extern __inline__ unsigned ld_le16(const volatile unsigned short *addr)
return val;
}
-extern __inline__ void st_le16(volatile unsigned short *addr, const unsigned val)
+static __inline__ void st_le16(volatile unsigned short *addr, const unsigned val)
{
__asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
}
-extern __inline__ unsigned ld_le32(const volatile unsigned *addr)
+static __inline__ unsigned ld_le32(const volatile unsigned *addr)
{
unsigned val;
@@ -26,7 +26,7 @@ extern __inline__ unsigned ld_le32(const volatile unsigned *addr)
return val;
}
-extern __inline__ void st_le32(volatile unsigned *addr, const unsigned val)
+static __inline__ void st_le32(volatile unsigned *addr, const unsigned val)
{
__asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
}
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index a5257e9b62..a54fc468d5 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -163,7 +163,7 @@ static inline void __raw_writel(unsigned int v, volatile void __iomem *addr)
* is actually performed (i.e. the data has come back) before we start
* executing any following instructions.
*/
-extern inline u8 in_8(const volatile unsigned char __iomem *addr)
+static inline u8 in_8(const volatile unsigned char __iomem *addr)
{
u8 ret;
@@ -174,7 +174,7 @@ extern inline u8 in_8(const volatile unsigned char __iomem *addr)
return ret;
}
-extern inline void out_8(volatile unsigned char __iomem *addr, u8 val)
+static inline void out_8(volatile unsigned char __iomem *addr, u8 val)
{
__asm__ __volatile__("sync;\n"
"stb%U0%X0 %1,%0;\n"
@@ -182,7 +182,7 @@ extern inline void out_8(volatile unsigned char __iomem *addr, u8 val)
: "r" (val));
}
-extern inline u16 in_le16(const volatile unsigned short __iomem *addr)
+static inline u16 in_le16(const volatile unsigned short __iomem *addr)
{
u16 ret;
@@ -193,7 +193,7 @@ extern inline u16 in_le16(const volatile unsigned short __iomem *addr)
return ret;
}
-extern inline u16 in_be16(const volatile unsigned short __iomem *addr)
+static inline u16 in_be16(const volatile unsigned short __iomem *addr)
{
u16 ret;
@@ -203,18 +203,18 @@ extern inline u16 in_be16(const volatile unsigned short __iomem *addr)
return ret;
}
-extern inline void out_le16(volatile unsigned short __iomem *addr, u16 val)
+static inline void out_le16(volatile unsigned short __iomem *addr, u16 val)
{
__asm__ __volatile__("sync; sthbrx %1,0,%2" : "=m" (*addr) :
"r" (val), "r" (addr));
}
-extern inline void out_be16(volatile unsigned short __iomem *addr, u16 val)
+static inline void out_be16(volatile unsigned short __iomem *addr, u16 val)
{
__asm__ __volatile__("sync; sth%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
}
-extern inline u32 in_le32(const volatile unsigned __iomem *addr)
+static inline u32 in_le32(const volatile unsigned __iomem *addr)
{
u32 ret;
@@ -225,7 +225,7 @@ extern inline u32 in_le32(const volatile unsigned __iomem *addr)
return ret;
}
-extern inline u32 in_be32(const volatile unsigned __iomem *addr)
+static inline u32 in_be32(const volatile unsigned __iomem *addr)
{
u32 ret;
@@ -235,13 +235,13 @@ extern inline u32 in_be32(const volatile unsigned __iomem *addr)
return ret;
}
-extern inline void out_le32(volatile unsigned __iomem *addr, u32 val)
+static inline void out_le32(volatile unsigned __iomem *addr, u32 val)
{
__asm__ __volatile__("sync; stwbrx %1,0,%2" : "=m" (*addr) :
"r" (val), "r" (addr));
}
-extern inline void out_be32(volatile unsigned __iomem *addr, u32 val)
+static inline void out_be32(volatile unsigned __iomem *addr, u32 val)
{
__asm__ __volatile__("sync; stw%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
}