LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Problem with cuImage Linux entry from old U-boot
From: Stephen Horton @ 2008-07-21 20:39 UTC (permalink / raw)
  To: linuxppc-embedded

[-- Attachment #1: Type: text/plain, Size: 8742 bytes --]

Hello folks,

 

As I have posted recently before, in a current work project, I have
inherited a compactPCI board that has an mpc7447/7448 powerpc processor
as well as a Marvell system controller, model mv64462 (stripped down
mv64460). The board has a somewhat working Gentoo Linux port running on
it from long ago and a company far far away (kernel version 2.6.9 built
using arch/ppc). To prepare for an upcoming deployment, I would like to
bring the OS up-to-date on this board with a newer kernel (targeting
2.6.24r3).

 

I have made great strides with help from this mailing list and its
archives. I now have a compiled cuImage ready to boot from my older
working u-boot 1.1.2. I now seem to be stuck at the kernel entry point.
I'm not sure if I'm trying to jump into the kernel at the wrong address,
or if I have a serial console issue that prevents me from seeing anymore
progress. Here is my output:

 

debug> bootm
## Booting image at 00800000 ...
   Image Name:   Linux-2.6.24-gentoo-r3
   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    1515921 Bytes =  1.4 MB
   Load Address: 00400000
   Entry Point:  0040095c
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
## Transferring control to Linux (at address 0040095c) ...
Memory <- <0x0 0x10000000> (256MB)
ENET0: local-mac-address <- 00:a0:d6:62:38:89
CPU clock-frequency <- 0x3b9ac9d8 (1000MHz)
CPU timebase-frequency <- 0x27bc86a (42MHz)
CPU bus-frequency <- 0x9ef21aa (167MHz)

 

zImage starting: loaded at 0x00400000 (sp: 0x0febfa38)
Allocating 0x35f040 bytes for kernel ...
gunzipping (0x00000000 <- 0x0040d000:0x00735db0)...done 0x312b34 bytes

 

Linux/PowerPC load: ip=bootp root=/dev/nfs rw nfsroot=/opt/gentoo
console=ttyMM0,9600n8
Finalizing device tree... flat tree at 0x7423a0

 

------

 

If I run 'nm' on my elf image, I expect to find some entry point address
that corresponds to 0x7423a0, but this is not the case. See nm output
below.  Does anyone know what I might be doing wrong?

 

[root@blade3 boot]# nm cuImage.giganew.elf

00736060 b alloc_min

00736058 b alloc_tbl

00400838 T backwards_memcpy

0073606c b bd

00736000 b bridge_base

00736000 A __bss_start

00736010 b chr1

00736014 b chr2

0040aadc d cmdline

00741ee0 B console_ops

00404620 t copy_val

00736018 b cpcr

00736004 b cpld_base

004060f4 t cpm1_cmd

00406174 t cpm2_cmd

00736028 b cpm_cmd

00405d84 T cpm_console_init

00406440 t cpm_serial_getc

00406334 t cpm_serial_open

004062c0 t cpm_serial_putc

00405d3c t cpm_serial_tstc

00405c60 T cuboot_init

00741c14 b cxt

0040a1e4 d dbase.1092

0040a1a4 d dext.1093

0073603c b disable_port

00741d30 b discard_buf.1378

00409922 d distfix.1169

004022e8 T __div64_32

00736034 b do_cmd

0040c098 A _dtb_end

0040ace0 A _dtb_start

00404c38 T dt_fixup_clock

00404cbc T dt_fixup_cpu_clocks

00404aec T dt_fixup_mac_address

00404b7c T __dt_fixup_mac_addresses

00404dec T dt_fixup_memory

00404500 T dt_get_reg_format

00404584 T dt_is_compatible

00741ef4 B dt_ops

00404684 t dt_xlate

00404a00 T dt_xlate_addr

00404a80 T dt_xlate_reg

00736000 A _edata

00736038 b enable_port

00742000 A _end

00408c98 A _etext

00400108 t exit

00401640 t exit

00402420 t exit

004044c4 t exit

00401cac t fdtm_create_node

00401c10 t fdtm_finalize

00401de4 t fdtm_finddevice

00401c54 t fdtm_find_node_by_prop_value

00401cf4 t fdtm_get_parent

00401bc0 t fdtm_get_path

00401d8c t fdtm_getprop

00401d34 t fdtm_setprop

00400000 t finddevice

00401e28 t finddevice

0040430c t finddevice

004050b8 t find_node_by_devtype

004000b0 t find_node_by_prop_value

0040446c t find_node_by_prop_value

0040092c T flush_cache

004073ac T ft_add_rsvmap

004077d4 T ft_begin

00408024 T ft_begin_node

004078b0 T ft_begin_tree

004080c4 T ft_create_node

004072d8 T ft_del_prop

004069b0 T ft_end_node

00406b7c T ft_end_tree

00407428 T ft_find_descendent

004075ec T ft_find_device

004079f0 T __ft_find_node_by_prop_value

00407af8 T ft_find_node_by_prop_value

00407b88 T __ft_get_parent

00407c74 T ft_get_parent

004078c4 T ft_get_path

00406890 t ft_get_phandle

00406ab4 t __ft_get_prop

00406e4c T ft_get_prop

00401b24 T ft_init

00406f48 t ft_make_space

004069d4 t ft_next

0040690c t ft_node_ph2node

00406938 t ft_node_update_after

004081b4 T ft_nop

00407674 T ft_open

00407cdc T ft_prop

00407f84 T ft_prop_int

00407fc8 T ft_prop_str

00406edc t ft_put_bin

00407e44 T ft_set_prop

00406c78 t ft_shuffle

00404414 t get_parent

00400058 t getprop

00401e80 t getprop

00404364 t getprop

00404fec t getprop

004057e8 t getprop

00405ce4 t getprop

0040820c t getprop

0040023c t giganew_fixups

00400530 t giganew_reset

0040aadc D __got2_end

0040a6e0 D __got2_start

004025dc T gunzip_discard

00402574 T gunzip_exactly

0040251c T gunzip_finish

0040245c T gunzip_partial

0040264c T gunzip_start

007364a4 b gzstate

00408804 T inflate_fast

00736000 A _initrd_end

00736000 A _initrd_start

0040a262 d lbase.1090

004099a2 d lenfix.1168

0040a224 d lext.1091

00741eb0 B loader_info

004008dc T memchr

00400904 T memcmp

00400780 T memcpy

00400778 T memmove

0040071c T memset

0040650c T mpc5200_psc_console_init

00736008 b mpsc_base

004058e8 T mpsc_console_init

00405a68 t mpsc_getc

00405840 t mpsc_get_virtreg_of_phandle

0073600c b mpscintr_base

00405b64 t mpsc_open

00405ae4 t mpsc_putc

00405c14 t mpsc_tstc

00736030 b muram_offset

0073602c b muram_start

0040520c T mv64x60_cfg_read

004052f8 T mv64x60_cfg_write

00405288 T mv64x60_config_cpu2pci_window

004055cc T mv64x60_config_ctlr_windows

00405408 T mv64x60_config_pci_windows

0040a4a4 d mv64x60_cpu2mem

0040a6a0 D mv64x60_cpu2pci_io

0040a6c0 D mv64x60_cpu2pci_mem

0040a59c d mv64x60_dram_selects

0040a5ac d mv64x60_enet2mem

00405134 T mv64x60_get_bridge_base

004051a0 T mv64x60_get_bridge_pbase

0040536c T mv64x60_get_mem_size

0040a60c d mv64x60_idma2mem

00405044 T mv64x60_is_coherent

0040a5dc d mv64x60_mpsc2mem

0040a564 d mv64x60_pci2mem

0040a584 d mv64x60_pci2reg

0040a4d4 d mv64x60_pci_acc

0040a63c d mv64x60_pci_cfgio

00736064 b next_base

00406980 t next_start

004082c0 T ns16550_console_init

004083f0 t ns16550_getc

00408264 t ns16550_open

00408464 t ns16550_putc

00408394 t ns16550_tstc

00400abc t number

004098fc d order.1221

0073601c b param

00402854 T parse_elf32

004027b4 T parse_elf64

00400144 T platform_init

00741ec4 B platform_ops

         w _platform_stack_top

004014c8 T printf

00741db0 b prop_buf

00736048 b psc

00406614 t psc_getc

004064b0 t psc_open

004065b8 t psc_putc

004064c0 t psc_tstc

00736040 B rbdf

0073604c b reg_base

00736050 b reg_base

00736054 b reg_shift

00736024 b scc

00406258 t scc_disable_port

004061f0 t scc_enable_port

00741d1c b serial_cd

00401f84 t serial_close

00401fd4 T serial_console_init

004021a8 t serial_edit_cmdline

00401ed8 t serial_open

00401f20 t serial_write

004015e8 t setprop

004043bc t setprop

0040868c T simple_alloc_init

004085d4 t simple_find_entry

00408658 t simple_free

004084d0 t simple_malloc

00408754 t simple_realloc

00400a78 t skip_atoi

00736020 b smc

0040608c t smc_disable_port

00406024 t smc_enable_port

00736068 b space_left

007360a4 b sprint_buf

00401574 T sprintf

0040167c T start

00400000 A _start

0040aadc A __start___builtin_cmdline

0040acdc A __stop___builtin_cmdline

0040066c T strcat

00400698 T strchr

004006b8 T strcmp

00400628 T strcpy

00400704 T strlen

004006dc T strncmp

00400644 T strncpy

00400a44 T strnlen

00736044 B tbdf

0073605c b tbl_entries

0040a69c D timebase_period_ns

004066c4 T uartlite_console_init

004067d0 t uartlite_getc

00406678 t uartlite_open

00406834 t uartlite_putc

00406784 t uartlite_tstc

00402384 T udelay

004023b0 t .udelay_not_601

00735db0 A _vmlinux_end

0040d000 A _vmlinux_start

00400dd4 T vsprintf

00400968 W _zimage_start

00400968 T _zimage_start_lib

00400958 T _zimage_start_opd

004028f4 t zlib_adler32

00402dc0 T zlib_inflate

00402bb4 T zlib_inflateEnd

00402cf8 T zlib_inflateIncomp

00402b1c T zlib_inflateInit2

00402a90 T zlib_inflateReset

00403dd4 T zlib_inflate_table

00402a7c T zlib_inflate_workspacesize

00402be0 t zlib_updatewindow


[-- Attachment #2: Type: text/html, Size: 42482 bytes --]

^ permalink raw reply

* Re: going to OLS?
From: Sean MacLennan @ 2008-07-21 20:24 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <fa686aa40807211315x56d15c2cocbaa17bc16d46de3@mail.gmail.com>

On Mon, 21 Jul 2008 14:15:53 -0600
"Grant Likely" <grant.likely@secretlab.ca> wrote:

> BTW, if anyone else wants to receive the contact phone list, then send
> me your phone number ASAP.  I'll be sending it out this evening.

My home phone number is 613-728-1680.

Cheers,
  Sean

^ permalink raw reply

* Re: going to OLS?
From: Grant Likely @ 2008-07-21 20:15 UTC (permalink / raw)
  To: Becky Bruce; +Cc: linuxppc-dev list, Gala Kumar, Wolfgang Denk
In-Reply-To: <CC5CD6EB-BE4D-4630-B054-EEA389920714@freescale.com>

Becky Bruce <becky.bruce@freescale.com> wrote:
> On Jul 18, 2008, at 11:33 AM, Wolfgang Denk wrote:
>> BTW: will there a pre-OLS beer evening on Tuesday, or will Stefan and
>> me have to sit alone in some bar?
>
> Gosh, that would be so sad :)
>
> If someone can pick a place and time, and just announce it, maybe we can all
> hook up.  I'd give it a go, but I've only been to Ottawa once, and I'm
> afraid my drinking habits during said trip left me with unreliable memories
> of drinking establishments :)

I'm game, but I'll have to bail sometime around 9:00.

BTW, if anyone else wants to receive the contact phone list, then send
me your phone number ASAP.  I'll be sending it out this evening.

Cheers,
g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* UIO not working on ppc405 onchip registers
From: Markus Brunner @ 2008-07-21 19:52 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: linux-embedded

Hi,

I'm unable to get UIO working on the ppc405ep onchip registers (e.g. gpio/iic) 
however it's working fine on peripherals.
It seems to me to be a problem with UIO on powerpc, because if I change the 
address (and nothing more) to point to a external FPGA it's working fine.
I also tried the generic uio_pdrv which had the same problems.
Sometimes I get a "bus error" sometimes it only produces wrong results. 
The "bus error" occurred when not a full 32 bit register was read (e.g. only a 
byte of it), but I'm not sure if it doesn't occur for other reasons as well.

Here is a simple example against 2.6.26. It should toggle the GPIO pin 0 on 
ppc405ep, but can be changed easily to work on other ppc variants.

Can anyone reproduce this problem, did anyone already succeed in writing a UIO 
driver for the onchip registers? How can I fix this?

Might this be something like commit c9698d6b1a90929e427a165bd8283f803f57d9bd which
added pgprot_noncached() to UIO mmap code to get it work on ppc?

Regards

Markus


diff -upNr linux-2.6.26/drivers/uio-orig/Kconfig linux-2.6.26/drivers/uio/Kconfig
--- linux-2.6.26/drivers/uio-orig/Kconfig	2008-07-18 09:15:51.000000000 +0200
+++ linux-2.6.26/drivers/uio/Kconfig	2008-07-18 09:16:18.000000000 +0200
@@ -39,4 +39,12 @@ config UIO_SMX
 
 	  If you compile this as a module, it will be called uio_smx.
 
+config UIO_GPIO
+	tristate "Driver for PPC_4xx GPIO"
+	depends on UIO
+	default n
+	help
+	  Driver for PPC_4xx GPIO Registers
+
 endif
+
diff -upNr linux-2.6.26/drivers/uio-orig/Makefile linux-2.6.26/drivers/uio/Makefile
--- linux-2.6.26/drivers/uio-orig/Makefile	2008-07-18 09:27:18.000000000 +0200
+++ linux-2.6.26/drivers/uio/Makefile	2008-07-18 09:16:50.000000000 +0200
@@ -1,3 +1,4 @@
 obj-$(CONFIG_UIO)	+= uio.o
 obj-$(CONFIG_UIO_CIF)	+= uio_cif.o
 obj-$(CONFIG_UIO_SMX)	+= uio_smx.o
+obj-$(CONFIG_UIO_GPIO)	+= uio_ppc_4xx-gpio.o
diff -upNr linux-2.6.26/drivers/uio-orig/uio-gpio.c linux-2.6.26/drivers/uio/uio-gpio.c
--- linux-2.6.26/drivers/uio-orig/uio-gpio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.26/drivers/uio/uio-gpio.c	2008-07-18 09:18:56.000000000 +0200
@@ -0,0 +1,59 @@
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+const unsigned long pin_mask( unsigned int pin) { return (0x80000000 >> (pin));}
+
+const char UIO_DEV[]  = "/dev/uio0";
+const unsigned int UIO_SIZE =   0x1000;
+const unsigned int UIO_ADDR = 0xef600700;
+
+const int  or = 0;
+const int tcr = 1;
+
+const unsigned int gpio_pin = 0;        /* What gpio pin do you want to toggle? */
+
+volatile unsigned long *gpio_regs;
+
+int main(int argc, char *argv[])
+{
+	int uiofd = open(UIO_DEV,O_RDWR);
+	if (uiofd < 0)
+		return uiofd;
+
+	unsigned long* map_addr = mmap(NULL,
+				       UIO_SIZE,
+				       PROT_READ | PROT_WRITE,
+				       MAP_SHARED,
+				       uiofd,
+				       0);
+	if (map_addr == ((unsigned long*) -1))
+		return -1;
+        gpio_regs = (volatile unsigned long*) map_addr;
+	printf("Mapped %0lx bytes from %08lx to %08lx\n", UIO_SIZE, UIO_ADDR, (unsigned long)map_addr);
+
+        printf("TCR = %08lx\n", gpio_regs[tcr]);
+        printf("TCR = %08lx\n", gpio_regs[tcr]);
+        printf("setting TCR\n");
+        gpio_regs[tcr] = gpio_regs[tcr] | pin_mask( gpio_pin );     // set tcr for pin to 1
+        printf("TCR = %08lx\n", gpio_regs[tcr]);
+        printf("TCR = %08lx\n", gpio_regs[tcr]);
+
+        printf("OR = %08lx\n", gpio_regs[or]);
+        printf("OR = %08lx\n", gpio_regs[or]);
+        printf("setting OR\n");
+        gpio_regs[or] = gpio_regs[or] | pin_mask( gpio_pin );       // set tcr for pin to 1
+        printf("OR = %08lx\n", gpio_regs[or]);
+        printf("OR = %08lx\n", gpio_regs[or]);
+        sleep( 3 );
+        printf("setting OR\n");
+        gpio_regs[or] = gpio_regs[or] & ~pin_mask( gpio_pin );      // set tcr for pin to 0
+        printf("OR = %08lx\n", gpio_regs[or]);
+        printf("OR = %08lx\n", gpio_regs[or]);
+
+}
diff -upNr linux-2.6.26/drivers/uio-orig/uio_ppc_4xx-gpio.c linux-2.6.26/drivers/uio/uio_ppc_4xx-gpio.c
--- linux-2.6.26/drivers/uio-orig/uio_ppc_4xx-gpio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.26/drivers/uio/uio_ppc_4xx-gpio.c	2008-07-18 09:23:32.000000000 +0200
@@ -0,0 +1,74 @@
+/*
+ * simple UIO GPIO driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/uio_driver.h>
+
+#include <asm/io.h>
+
+static struct uio_info info = {
+	.name = "uio_gpio",
+	.version = "0.0.0",
+	.irq = UIO_IRQ_NONE,
+	.irq_flags = 0,
+        .mem[0].addr = 0xef600700,
+        .mem[0].size = 0x1000,
+	.mem[0].memtype = UIO_MEM_PHYS,
+};
+
+static int __devinit uio_gpio_probe(struct device *dev)
+{
+	if (uio_register_device(dev, &info)){
+		printk(KERN_ERR "uio_gpio: uio_register_device failed\n");
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static int uio_gpio_remove(struct device *dev)
+{
+	uio_unregister_device(&info);
+	info.mem[0].addr = 0;
+	info.mem[0].size = 0;
+	return 0;
+}
+
+static struct platform_device *uio_gpio_device;
+
+static struct device_driver uio_gpio_driver = {
+	.name		= "uio_gpio",
+	.bus		= &platform_bus_type,
+	.probe		= uio_gpio_probe,
+	.remove		= uio_gpio_remove,
+};
+
+
+static int __init uio_gpio_init(void)
+{
+	uio_gpio_device = platform_device_register_simple("uio_gpio", -1,
+							   NULL, 0);
+	if (IS_ERR(uio_gpio_device))
+		return PTR_ERR(uio_gpio_device);
+
+	return driver_register(&uio_gpio_driver);
+}
+
+static void __exit uio_gpio_exit(void)
+{
+	platform_device_unregister(uio_gpio_device);
+	driver_unregister(&uio_gpio_driver);
+}
+
+module_init(uio_gpio_init);
+module_exit(uio_gpio_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Markus Brunner");

^ permalink raw reply

* Re: [RFC v3 PATCH 6/4] Use LOAD_REG_IMMEDIATE macros
From: Mohan Kumar M @ 2008-07-21 19:26 UTC (permalink / raw)
  To: Milton Miller; +Cc: paulus, naren, ppcdev
In-Reply-To: <d8d07a180aaf59d25936ad03c7287f5a@bga.com>

[-- Attachment #1: Type: text/plain, Size: 1 bytes --]



[-- Attachment #2: 0006-Use-LOAD_REG_IMMEDIATE-macros.patch --]
[-- Type: text/x-patch, Size: 3654 bytes --]

Use LOAD_REG_IMMEDIATE macros

This patch changes all LOAD_REG_ADDR macro calls to LOAD_REG_IMMEDIATE
to make sure that we load the correct address.

Signed-off-by: Mohan Kumar M <mohan@in.ibm.com>
---
 arch/powerpc/kernel/entry_64.S          |    4 ++--
 arch/powerpc/mm/hash_low_64.S           |    8 ++++----
 arch/powerpc/mm/slb_low.S               |    2 +-
 arch/powerpc/platforms/pseries/hvCall.S |    2 +-
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 12eb95a..37e5d95 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -714,7 +714,7 @@ _GLOBAL(enter_rtas)
         std	r6,PACASAVEDMSR(r13)
 
 	/* Setup our real return addr */	
-	LOAD_REG_ADDR(r4,.rtas_return_loc)
+	LOAD_REG_IMMEDIATE(r4,.rtas_return_loc)
 	clrldi	r4,r4,2			/* convert to realmode address */
        	mtlr	r4
 
@@ -730,7 +730,7 @@ _GLOBAL(enter_rtas)
 	sync				/* disable interrupts so SRR0/1 */
 	mtmsrd	r0			/* don't get trashed */
 
-	LOAD_REG_ADDR(r4, rtas)
+	LOAD_REG_IMMEDIATE(r4, rtas)
 	ld	r5,RTASENTRY(r4)	/* get the rtas->entry value */
 	ld	r4,RTASBASE(r4)		/* get the rtas->base value */
 	
diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S
index a719f53..e9ba872 100644
--- a/arch/powerpc/mm/hash_low_64.S
+++ b/arch/powerpc/mm/hash_low_64.S
@@ -83,7 +83,7 @@ _GLOBAL(__hash_page_4K)
 	std	r29,STK_REG(r29)(r1)
 	std	r30,STK_REG(r30)(r1)
 	std	r31,STK_REG(r31)(r1)
-	
+
 	/* Step 1:
 	 *
 	 * Check permissions, atomically mark the linux PTE busy
@@ -168,7 +168,7 @@ END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
 	std	r3,STK_PARM(r4)(r1)
 
 	/* Get htab_hash_mask */
-	ld	r4,htab_hash_mask@got(2)
+	LOAD_REG_IMMEDIATE(r4, htab_hash_mask)
 	ld	r27,0(r4)	/* htab_hash_mask -> r27 */
 
 	/* Check if we may already be in the hashtable, in this case, we
@@ -461,7 +461,7 @@ END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
 	std	r3,STK_PARM(r4)(r1)
 
 	/* Get htab_hash_mask */
-	ld	r4,htab_hash_mask@got(2)
+	LOAD_REG_IMMEDIATE(r4, htab_hash_mask)
 	ld	r27,0(r4)	/* htab_hash_mask -> r27 */
 
 	/* Check if we may already be in the hashtable, in this case, we
@@ -792,7 +792,7 @@ END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
 	std	r3,STK_PARM(r4)(r1)
 
 	/* Get htab_hash_mask */
-	ld	r4,htab_hash_mask@got(2)
+	LOAD_REG_IMMEDIATE(r4, htab_hash_mask)
 	ld	r27,0(r4)	/* htab_hash_mask -> r27 */
 
 	/* Check if we may already be in the hashtable, in this case, we
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index bc44dc4..502099e 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -128,7 +128,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_1T_SEGMENT)
 	/* Now get to the array and obtain the sllp
 	 */
 	ld	r11,PACATOC(r13)
-	ld	r11,mmu_psize_defs@got(r11)
+	LOAD_REG_IMMEDIATE(r11, mmu_psize_defs)
 	add	r11,r11,r9
 	ld	r11,MMUPSIZESLLP(r11)
 	ori	r11,r11,SLB_VSID_USER
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index c1427b3..43c18f0 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -55,7 +55,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_PURR);				\
 	/* calculate address of stat structure r4 = opcode */	\
 	srdi	r4,r4,2;		/* index into array */	\
 	mulli	r4,r4,HCALL_STAT_SIZE;				\
-	LOAD_REG_ADDR(r7, per_cpu__hcall_stats);		\
+	LOAD_REG_IMMEDIATE(r7, per_cpu__hcall_stats);		\
 	add	r4,r4,r7;					\
 	ld	r7,PACA_DATA_OFFSET(r13); /* per cpu offset */	\
 	add	r4,r4,r7;					\
-- 
1.5.4


^ permalink raw reply related

* Re: [RFC v3 PATCH 5/4] Relocation support for kdump kernel
From: Mohan Kumar M @ 2008-07-21 19:25 UTC (permalink / raw)
  To: Milton Miller; +Cc: paulus, naren, ppcdev
In-Reply-To: <d8d07a180aaf59d25936ad03c7287f5a@bga.com>

[-- Attachment #1: Type: text/plain, Size: 1 bytes --]



[-- Attachment #2: 0005-Relocation-support-for-kdump-kernels.patch --]
[-- Type: text/x-patch, Size: 7055 bytes --]

Relocation support for kdump kernel

This patch adds relocation support for the kdump kernel path

Signed-off-by: Mohan Kumar M <mohan@in.ibm.com>
---
 arch/powerpc/kernel/crash_dump.c       |   19 +++++++++++++++
 arch/powerpc/kernel/iommu.c            |    7 ++++-
 arch/powerpc/kernel/machine_kexec.c    |    6 ++++
 arch/powerpc/kernel/misc.S             |   40 +++++++++++++++++++++++++------
 arch/powerpc/kernel/prom.c             |   13 +++++++++-
 arch/powerpc/mm/hash_utils_64.c        |    5 ++-
 arch/powerpc/platforms/pseries/iommu.c |    5 +++-
 7 files changed, 81 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index e0debcc..91d5ad2 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -29,7 +29,12 @@
 
 void __init reserve_kdump_trampoline(void)
 {
+#ifdef CONFIG_RELOCATABLE_PPC64
+	if (RELOC(reloc_delta))
+		lmb_reserve(0, KDUMP_RESERVE_LIMIT);
+#else
 	lmb_reserve(0, KDUMP_RESERVE_LIMIT);
+#endif
 }
 
 static void __init create_trampoline(unsigned long addr)
@@ -45,7 +50,11 @@ static void __init create_trampoline(unsigned long addr)
 	 * two instructions it doesn't require any registers.
 	 */
 	patch_instruction(p, PPC_NOP_INSTR);
+#ifndef CONFIG_RELOCATABLE_PPC64
 	patch_branch(++p, addr + PHYSICAL_START, 0);
+#else
+	patch_branch(++p, addr + RELOC(reloc_delta), 0);
+#endif
 }
 
 void __init setup_kdump_trampoline(void)
@@ -54,13 +63,23 @@ void __init setup_kdump_trampoline(void)
 
 	DBG(" -> setup_kdump_trampoline()\n");
 
+#ifdef CONFIG_RELOCATABLE_PPC64
+	if (!RELOC(reloc_delta))
+		return;
+#endif
+
 	for (i = KDUMP_TRAMPOLINE_START; i < KDUMP_TRAMPOLINE_END; i += 8) {
 		create_trampoline(i);
 	}
 
 #ifdef CONFIG_PPC_PSERIES
+#ifndef CONFIG_RELOCATABLE_PPC64
 	create_trampoline(__pa(system_reset_fwnmi) - PHYSICAL_START);
 	create_trampoline(__pa(machine_check_fwnmi) - PHYSICAL_START);
+#else
+	create_trampoline(__pa(system_reset_fwnmi) - RELOC(reloc_delta));
+	create_trampoline(__pa(machine_check_fwnmi) - RELOC(reloc_delta));
+#endif
 #endif /* CONFIG_PPC_PSERIES */
 
 	DBG(" <- setup_kdump_trampoline()\n");
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 0c66366..ccd98c2 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -473,7 +473,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
 	spin_lock_init(&tbl->it_lock);
 
 #ifdef CONFIG_CRASH_DUMP
-	if (ppc_md.tce_get) {
+	if (reloc_delta && ppc_md.tce_get) {
 		unsigned long index;
 		unsigned long tceval;
 		unsigned long tcecount = 0;
@@ -499,7 +499,10 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
 				index < tbl->it_size; index++)
 				__clear_bit(index, tbl->it_map);
 		}
-	}
+	} else
+		/* Clear the hardware table in case firmware left allocations
+		   in it */
+		ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
 #else
 	/* Clear the hardware table in case firmware left allocations in it */
 	ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c
index 29a0e03..f2ed554 100644
--- a/arch/powerpc/kernel/machine_kexec.c
+++ b/arch/powerpc/kernel/machine_kexec.c
@@ -67,6 +67,12 @@ void __init reserve_crashkernel(void)
 	unsigned long long crash_size, crash_base;
 	int ret;
 
+#ifdef CONFIG_RELOCATABLE_PPC64
+	/* Return if its kdump kernel */
+	if (reloc_delta)
+		return;
+#endif
+
 	/* this is necessary because of lmb_phys_mem_size() */
 	lmb_analyze();
 
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S
index 85cb6f3..28718ed 100644
--- a/arch/powerpc/kernel/misc.S
+++ b/arch/powerpc/kernel/misc.S
@@ -20,6 +20,8 @@
 #include <asm/asm-compat.h>
 #include <asm/asm-offsets.h>
 
+#define RELOC_DELTA 0x4000000002000000
+
 	.text
 
 /*
@@ -33,6 +35,17 @@ _GLOBAL(reloc_offset)
 1:	mflr	r3
 	LOAD_REG_IMMEDIATE(r4,1b)
 	subf	r3,r4,r3
+#ifdef CONFIG_RELOCATABLE_PPC64
+	LOAD_REG_IMMEDIATE(r5, RELOC_DELTA)
+	cmpd	r3,r5
+	bne	2f
+	/*
+	 * Don't return the offset if the difference is
+	 * RELOC_DELTA
+	 */
+	li	r3,0
+2:
+#endif
 	mtlr	r0
 	blr
 
@@ -40,14 +53,25 @@ _GLOBAL(reloc_offset)
  * add_reloc_offset(x) returns x + reloc_offset().
  */
 _GLOBAL(add_reloc_offset)
-	mflr	r0
-	bl	1f
-1:	mflr	r5
-	LOAD_REG_IMMEDIATE(r4,1b)
-	subf	r5,r4,r5
-	add	r3,r3,r5
-	mtlr	r0
-	blr
+        mflr    r0
+        bl      1f
+1:      mflr    r5
+        LOAD_REG_IMMEDIATE(r4,1b)
+        subf    r5,r4,r5
+#ifdef CONFIG_RELOCATABLE_PPC64
+	LOAD_REG_IMMEDIATE(r4, RELOC_DELTA)
+	cmpd	r5,r4
+	bne	2f
+	/*
+	 * Don't add the offset if the difference is
+	 * RELOC_DELTA
+	 */
+	li	r5,0
+2:
+#endif
+        add     r3,r3,r5
+        mtlr    r0
+        blr
 
 _GLOBAL(kernel_execve)
 	li	r0,__NR_execve
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 87d83c5..453dc98 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -65,6 +65,9 @@
 static int __initdata dt_root_addr_cells;
 static int __initdata dt_root_size_cells;
 
+unsigned long reloc_delta __attribute__ ((__section__ (".data")));
+unsigned long kernel_base __attribute__ ((__section__ (".data")));
+
 #ifdef CONFIG_PPC64
 int __initdata iommu_is_off;
 int __initdata iommu_force_on;
@@ -1163,8 +1166,16 @@ void __init early_init_devtree(void *params)
 	parse_early_param();
 
 	/* Reserve LMB regions used by kernel, initrd, dt, etc... */
-	lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
 	reserve_kdump_trampoline();
+#ifdef CONFIG_RELOCATABLE_PPC64
+	if (RELOC(kernel_base)) {
+		lmb_reserve(0, KDUMP_RESERVE_LIMIT);
+		lmb_reserve(kernel_base, __pa(klimit) - PHYSICAL_START);
+	} else
+		lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
+#else
+	lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
+#endif
 	reserve_crashkernel();
 	early_reserve_mem();
 	phyp_dump_reserve_mem();
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 8d3b58e..78c7774 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -636,8 +636,9 @@ void __init htab_initialize(void)
 			continue;
 		}
 #endif /* CONFIG_U3_DART */
-		BUG_ON(htab_bolt_mapping(base, base + size, __pa(base),
-				mode_rw, mmu_linear_psize, mmu_kernel_ssize));
+		BUG_ON(htab_bolt_mapping(base + kernel_base, base + size,
+				__pa(base) + kernel_base, mode_rw, mmu_linear_psize,
+							mmu_kernel_ssize));
        }
 
 	/*
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 9a12908..948ad57 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -265,7 +265,10 @@ static void iommu_table_setparms(struct pci_controller *phb,
 
 	tbl->it_base = (unsigned long)__va(*basep);
 
-#ifndef CONFIG_CRASH_DUMP
+#ifdef CONFIG_CRASH_DUMP
+	if (!reloc_delta)
+		memset((void *)tbl->it_base, 0, *sizep);
+#else
 	memset((void *)tbl->it_base, 0, *sizep);
 #endif
 
-- 
1.5.4


^ permalink raw reply related

* Re: [RFC v3 PATCH 4/4] Relocation support
From: Mohan Kumar M @ 2008-07-21 19:23 UTC (permalink / raw)
  To: Milton Miller; +Cc: paulus, naren, ppcdev
In-Reply-To: <d8d07a180aaf59d25936ad03c7287f5a@bga.com>

[-- Attachment #1: Type: text/plain, Size: 179 bytes --]

I split the patch 4: Relocation support into 3 patches

1. Generic kernel support for relocatable
2. Kdump kernel support for relocatable
3. LOAD_REG_IMMEDIATE macro replacement


[-- Attachment #2: 0004-Relocation-support.patch --]
[-- Type: text/x-patch, Size: 9689 bytes --]

Relocation support

Add relocatable kernel support like take care when accessing absolute
symbols in the code by adding the relocation kernel base address.

Signed-off-by: Mohan Kumar M <mohan@in.ibm.com>
---
 arch/powerpc/kernel/head_64.S          |   53 ++++++++++++++++++++++++++++++-
 arch/powerpc/kernel/machine_kexec_64.c |    4 +-
 arch/powerpc/kernel/prom_init.c        |   27 ++++++++++++++--
 arch/powerpc/kernel/prom_init_check.sh |    2 +-
 arch/powerpc/kernel/setup_64.c         |    5 +--
 arch/powerpc/mm/init_64.c              |    7 ++--
 arch/powerpc/mm/mem.c                  |    3 +-
 include/asm-powerpc/prom.h             |    2 +
 include/asm-powerpc/sections.h         |    4 ++-
 include/asm-powerpc/system.h           |    5 +++
 10 files changed, 95 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index ecced1e..8adf3b5 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -102,6 +102,12 @@ __secondary_hold_acknowledge:
 	.llong hvReleaseData-KERNELBASE
 #endif /* CONFIG_PPC_ISERIES */
 
+#ifdef CONFIG_RELOCATABLE_PPC64
+	/* Used as static variable to initialize the reloc_delta */
+__initialized:
+	.long 0x0
+#endif
+
 	. = 0x60
 /*
  * The following code is used to hold secondary processors
@@ -1247,6 +1253,38 @@ _STATIC(__mmu_off)
  *
  */
 _GLOBAL(__start_initialization_multiplatform)
+#ifdef CONFIG_RELOCATABLE_PPC64
+	mr	r21,r3
+	mr	r22,r4
+	mr	r23,r5
+	bl	.reloc_offset
+	mr	r26,r3
+	mr	r3,r21
+	mr	r4,r22
+	mr	r5,r23
+
+	LOAD_REG_IMMEDIATE(r27, __initialized)
+	add	r27,r26,r27
+	ld	r7,0(r27)
+	cmpdi	r7,0
+	bne	4f
+
+	li	r7,1
+	stw	r7,0(r27)
+
+	cmpdi	r6,0
+	beq	4f
+	LOAD_REG_IMMEDIATE(r27, reloc_delta)
+	add	r27,r27,r26
+	std	r6,0(r27)
+
+	LOAD_REG_IMMEDIATE(r27, KERNELBASE)
+	add	r7,r6,r27
+	LOAD_REG_IMMEDIATE(r27, kernel_base)
+	add	r27,r27,r26
+	std	r7,0(r27)
+4:
+#endif
 	/*
 	 * Are we booted from a PROM Of-type client-interface ?
 	 */
@@ -1322,6 +1360,19 @@ _INIT_STATIC(__boot_from_prom)
 	trap
 
 _STATIC(__after_prom_start)
+	bl	.reloc_offset
+	mr	r26,r3
+#ifdef CONFIG_RELOCATABLE_PPC64
+	/*
+	 * If its a relocatable kernel, no need to copy the kernel
+	 * to PHYSICAL_START. Continue running from the same location
+	 */
+	LOAD_REG_IMMEDIATE(r27, reloc_delta)
+	add	r27,r27,r26
+	ld	r28,0(r27)
+	cmpdi	r28,0
+	bne	.start_here_multiplatform
+#endif
 
 /*
  * We need to run with __start at physical address PHYSICAL_START.
@@ -1335,8 +1386,6 @@ _STATIC(__after_prom_start)
  *	r26 == relocation offset
  *	r27 == KERNELBASE
  */
-	bl	.reloc_offset
-	mr	r26,r3
 	LOAD_REG_IMMEDIATE(r27, KERNELBASE)
 
 	LOAD_REG_IMMEDIATE(r3, PHYSICAL_START)	/* target addr */
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index 631dfd6..09ce39d 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -43,7 +43,7 @@ int default_machine_kexec_prepare(struct kimage *image)
 	 * overlaps kernel static data or bss.
 	 */
 	for (i = 0; i < image->nr_segments; i++)
-		if (image->segment[i].mem < __pa(_end))
+		if (image->segment[i].mem < (__pa(_end) + kernel_base))
 			return -ETXTBSY;
 
 	/*
@@ -317,7 +317,7 @@ static void __init export_htab_values(void)
 	if (!node)
 		return;
 
-	kernel_end = __pa(_end);
+	kernel_end = __pa(_end) + kernel_base;
 	prom_add_property(node, &kernel_end_prop);
 
 	/* On machines with no htab htab_address is NULL */
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 1ea8c8d..1b67219 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -91,11 +91,9 @@ extern const struct linux_logo logo_linux_clut224;
  * fortunately don't get interpreted as two arguments).
  */
 #ifdef CONFIG_PPC64
-#define RELOC(x)        (*PTRRELOC(&(x)))
 #define ADDR(x)		(u32) add_reloc_offset((unsigned long)(x))
 #define OF_WORKAROUNDS	0
 #else
-#define RELOC(x)	(x)
 #define ADDR(x)		(u32) (x)
 #define OF_WORKAROUNDS	of_workarounds
 int of_workarounds;
@@ -1073,7 +1071,12 @@ static void __init prom_init_mem(void)
 		}
 	}
 
+#ifndef CONFIG_RELOCATABLE_PPC64
 	RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000);
+#else
+	RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000 +
+							RELOC(reloc_delta));
+#endif
 
 	/* Check if we have an initrd after the kernel, if we do move our bottom
 	 * point to after it
@@ -1337,10 +1340,19 @@ static void __init prom_hold_cpus(void)
 	unsigned int cpu_threads, hw_cpu_num;
 	int propsize;
 	struct prom_t *_prom = &RELOC(prom);
+
+#ifndef CONFIG_RELOCATABLE_PPC64
 	unsigned long *spinloop
 		= (void *) LOW_ADDR(__secondary_hold_spinloop);
 	unsigned long *acknowledge
 		= (void *) LOW_ADDR(__secondary_hold_acknowledge);
+#else
+	unsigned long *spinloop
+		= (void *) &__secondary_hold_spinloop;
+	unsigned long *acknowledge
+		= (void *) &__secondary_hold_acknowledge;
+#endif
+
 #ifdef CONFIG_PPC64
 	/* __secondary_hold is actually a descriptor, not the text address */
 	unsigned long secondary_hold
@@ -2402,8 +2414,15 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
 	/*
 	 * Copy the CPU hold code
 	 */
-	if (RELOC(of_platform) != PLATFORM_POWERMAC)
-		copy_and_flush(0, KERNELBASE + offset, 0x100, 0);
+	if (RELOC(of_platform) != PLATFORM_POWERMAC) {
+#ifdef CONFIG_RELOCATABLE_PPC64
+		if (RELOC(reloc_delta))
+			copy_and_flush(0, KERNELBASE + RELOC(reloc_delta),
+								0x100, 0);
+		else
+#endif
+			copy_and_flush(0, KERNELBASE + offset, 0x100, 0);
+	}
 
 	/*
 	 * Do early parsing of command line
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh
index 2c7e8e8..3cc7e24 100644
--- a/arch/powerpc/kernel/prom_init_check.sh
+++ b/arch/powerpc/kernel/prom_init_check.sh
@@ -20,7 +20,7 @@ WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush
 _end enter_prom memcpy memset reloc_offset __secondary_hold
 __secondary_hold_acknowledge __secondary_hold_spinloop __start
 strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224
-reloc_got2 kernstart_addr"
+reloc_got2 kernstart_addr reloc_delta"
 
 NM="$1"
 OBJ="$2"
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 04d8de9..91fab43 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -208,7 +208,6 @@ void __init early_setup(unsigned long dt_ptr)
 
 	/* Probe the machine type */
 	probe_machine();
-
 	setup_kdump_trampoline();
 
 	DBG("Found, Initializing memory management...\n");
@@ -526,9 +525,9 @@ void __init setup_arch(char **cmdline_p)
 	if (ppc_md.panic)
 		setup_panic();
 
-	init_mm.start_code = (unsigned long)_stext;
+	init_mm.start_code = (unsigned long)_stext + kernel_base;
 	init_mm.end_code = (unsigned long) _etext;
-	init_mm.end_data = (unsigned long) _edata;
+	init_mm.end_data = (unsigned long) _edata + kernel_base;
 	init_mm.brk = klimit;
 	
 	irqstack_early_init();
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 6ef63ca..1b908d4 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -79,10 +79,11 @@ phys_addr_t kernstart_addr;
 
 void free_initmem(void)
 {
-	unsigned long addr;
+	unsigned long long addr, eaddr;
 
-	addr = (unsigned long)__init_begin;
-	for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
+	addr = (unsigned long long )__init_begin + kernel_base;
+	eaddr = (unsigned long long ) __init_end + kernel_base;
+	for (; addr < eaddr; addr += PAGE_SIZE) {
 		memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
 		ClearPageReserved(virt_to_page(addr));
 		init_page_count(virt_to_page(addr));
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 776ba6a..f727de6 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -401,7 +401,8 @@ void __init mem_init(void)
 		}
 	}
 
-	codesize = (unsigned long)&_sdata - (unsigned long)&_stext;
+	codesize = (unsigned long)&_sdata - (unsigned long)&_stext
+						+ kernel_base;
 	datasize = (unsigned long)&_edata - (unsigned long)&_sdata;
 	initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin;
 	bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start;
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index eb3bd2e..4d7aa4f 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -39,6 +39,8 @@
 
 #define OF_DT_VERSION		0x10
 
+extern unsigned long reloc_delta, kernel_base;
+
 /*
  * This is what gets passed to the kernel by prom_init or kexec
  *
diff --git a/include/asm-powerpc/sections.h b/include/asm-powerpc/sections.h
index 916018e..f19dab3 100644
--- a/include/asm-powerpc/sections.h
+++ b/include/asm-powerpc/sections.h
@@ -7,10 +7,12 @@
 #ifdef __powerpc64__
 
 extern char _end[];
+extern unsigned long kernel_base;
 
 static inline int in_kernel_text(unsigned long addr)
 {
-	if (addr >= (unsigned long)_stext && addr < (unsigned long)__init_end)
+	if (addr >= (unsigned long)_stext && addr < (unsigned long)__init_end
+								+ kernel_base)
 		return 1;
 
 	return 0;
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 0c12c66..4f98967 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -534,6 +534,11 @@ extern unsigned long add_reloc_offset(unsigned long);
 extern void reloc_got2(unsigned long);
 
 #define PTRRELOC(x)	((typeof(x)) add_reloc_offset((unsigned long)(x)))
+#ifdef CONFIG_PPC64
+#define RELOC(x)        (*PTRRELOC(&(x)))
+#else
+#define RELOC(x)	(x)
+#endif
 
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 extern void account_system_vtime(struct task_struct *);
-- 
1.5.4


^ permalink raw reply related

* using -initrd with qemu-system-ppc
From: Sureshkumar Kaliannan @ 2008-07-21 19:22 UTC (permalink / raw)
  To: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 8360 bytes --]

Hi,

I'm struggling to get initrd working with qemu-system-ppc. The kernel
doesn't seem to be find  initrd image passed to qemu-system-ppc.

I added printfs in qemu, ppc_rom and in the kernel source code..Looks like
qemu is passing the intird to Hackware and hackware rom seems to be setting
the bootinfos structure with the initrd information but when it comes to the
kernel it doesn't seem to get it.

qemu logs show..it read the initrd image

ppc_prep_init: START linux boot
ppc_prep_init: INSIDE linux boot: /tmp/initrd.img
ppc_prep_init: INSIDE INITRD
ppc_prep_init: INSIDE INITRD filename: /tmp/initrd.img size: 31457280

hackware logs i added also shows initrd is read from nvram and its put in
the bootinfos and passed.

bootinfos..initrd: 31457280
bootinfos..memsize:0x2f400000
Boot: 00040000 32eb1500 00000000 00000000
Bootinfos at : 300000

But the kernel didn;t find the BI_INITRD tag (0x1014). But it found the
BI_CMDLINE and BI_MEMSIZE tags but not initrd.

Now booting the kernel
RAMDISK platform_init..calling boot_info
RAMDISK find_bootinfo
RAMDISK parser_booinfo
RAMDISK BI tag: 0x1010
RAMDISK BI tag: 0x1017
RAMDISK memsize: 0x2f400000
RAMDISK BI tag: 0x1012
RAMDISK cmdline: console=ttyS0 ip=dhcp rw netdev=9,0x300,eth0
netdev=10,0x320,eth1 netdev=11,0x340,eth2 netdev=3,0x360,eth3
netdev=4,0x280,eth4 netdev=5,0x380,eth5
RAMDISK parser_booinfo end
....
....
IP-Config: Got DHCP answer from 10.0.2.2, my address is 10.0.2.15
IP-Config: Complete:
      device=eth0, addr=10.0.2.15, mask=255.255.255.0, gw=10.0.2.2,
     host=10.0.2.15, domain=, nis-domain=(none),
     bootserver=10.0.2.2, rootserver=10.0.2.2, rootpath=
RAMDISK: no file foundi
No filesystem could mount root, tried:  ext3 ext2 iso9660


I'm stumped..May be the kernel is reading a different bootinfos..I'm not
sure where the problem is. I made sure the CONFIG_BLK_DEV_INITRD is enabled
and the printfs I added are outside of the CONFIG_BLK_DEV_INITRD check.

I'm using the 0.9.1 version and the kernel is 2.6.18

Please help me figure this out..I have attached the complete log.

thanks
Suresh
[skaliann@sjc-lds-256
~]$/ws/skaliann/opt/qemu-0.9.1/ppc-softmmu/qemu-system-ppc
-L /users/skaliann/qemu/share/qemu -M prep -kernel /tmp/zImage.prep
-nographic  -m 756 -redir tcp:1122::22 -redir tcp:2345::2345 -initrd
/tmp/initrd.img  -append root=/dev/ram

ppc_prep_init: START linux boot
ppc_prep_init: INSIDE linux boot: /tmp/initrd.img
ppc_prep_init: INSIDE INITRD
ppc_prep_init: INSIDE INITRD filename: /tmp/initrd.img size: 31457280
ppc_prep_init: OUTSIDE base=0x1800000 Size: 31457280NVRAM set: base:
0x1800000 size: 31457280
register PCI host 'pci-bridge' 'pci' '<null>' 'PREP Host PCI Bridge -
Motorola Raven'
register 'pci-bridge' 'pci' '<null>' 'PREP Host PCI Bridge - Motorola Raven'
0x80000000 in 'device-tree' 0xffffffff
Done 582a000 582a900
register pci device 'Qemu VGA' 0000000c 'display' 'VGA' 'Qemu VGA'
register 'Qemu VGA' 'display' 'VGA' 'Qemu VGA' 0x0000000c in 'pci-bridge'
0x80000000
Done 582a900 582aa00
PPC Open Hack'Ware BIOS for qemu version 0.4.1
Build 2008-07-18 22:17:00
Copyright 2003-2005 Jocelyn Mayer

Memory size: 756 MB.
Booting from device m
ide0: drive 0: none
ide0: drive 1: CD-ROM
ERROR: OF_property_copy cannot get property 'cd' for aliases
ERROR: ATAPI TEST_UNIT_READY : status 48 != 0x08
ide1: drive 0: none
ide1: drive 1: none
Probe partitions for device m
ERROR: No MSDOS signature (38 0 0 0)
New bootfile
ERROR: OF_property_copy cannot get property 'alias' for <null>
boot device: 5831080 image 1000000 size 1436466
New bootfile
New bootfile
Fix bootfile
boot device: 5831080
ERROR: Found boot partition : 5831200 582d6c0
ERROR: Not a MACH-O file
ERROR: Not an Apple CHRP boot file !
dest 100000 entry 00000200 => 100200
Load raw file into memory at 100000 1436466 (0015eb32) 0 (00000000)
bootinfos..initrd: 31457280
bootinfos..memsize:0x2f400000
Boot: 00040000 32eb1500 00000000 00000000
Bootinfos at : 300000

Now boot it... (0)

stack: 5bfff80 malloc_base: 0 0x05800000 0x06000000
PREP boot... 100200 100000
loaded at:     00100200 00265D4C
relocated to:  00800000 00965B4C
zimage at:     00805F64 0095CC98
avail ram:     00400000 00800000

Linux/PPC load: decompress_kernel:  new cmd_line='console=ttyS0 ip=dhcp rw
netdev=9,0x300,eth0 netdev=10,0x320,eth1 netdev=11,0x340,eth2
netdev=3,0x360,eth3 netdev=4,0x280,eth4 netdev=5,0x380,eth5 root=/dev/ram'
console=ttyS0 ip=dhcp rw netdev=9,0x300,eth0 netdev=10,0x320,eth1
netdev=11,0x340,eth2 netdev=3,0x360,eth3 netdev=4,0x280,eth4
netdev=5,0x380,eth5 root=/dev/ram
Uncompressing Linux...done.
Now booting the kernel
RAMDISK platform_init..calling boot_info
RAMDISK find_bootinfo
RAMDISK parser_booinfo
RAMDISK BI tag: 0x1010
RAMDISK BI tag: 0x1017
RAMDISK memsize: 0x2f400000
RAMDISK BI tag: 0x1012
RAMDISK cmdline: console=ttyS0 ip=dhcp rw netdev=9,0x300,eth0
netdev=10,0x320,eth1 netdev=11,0x340,eth2 netdev=3,0x360,eth3
netdev=4,0x280,eth4 netdev=5,0x380,eth5 root=/dev/ram
RAMDISK parser_booinfo end
Total memory = 756MB; using 2048kB for hash table (at c0400000)
Linux version 2.6.18.8 (skaliann@sjc-lds-256) (gcc version 3.4.2) #25 Fri
Jul 18 15:47:56 PDT 2008PReP architecture
Built 1 zonelists.  Total pages: 193536
Kernel command line: console=ttyS0 ip=dhcp rw netdev=9,0x300,eth0
netdev=10,0x320,eth1 netdev=11,0x340,eth2 netdev=3,0x360,eth3
netdev=4,0x280,eth4 netdev=5,0x380,eth5 root=/dev/ram
PID hash table entries: 4096 (order: 12, 16384 bytes)
time_init: decrementer frequency = 25.000000 MHz
Console: colour dummy device 80x25
Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)
Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)
Memory: 761600k available (2260k kernel code, 776k data, 156k init, 0k
highmem)
Mount-cache hash table entries: 512
lsmpi_region_init(): 11 pages (6508544 bytes)
NET: Registered protocol family 16
PCI: Probing PCI hardware
Setting PCI interrupts for a "Mesquite cPCI (MCP750)"
Linux Plug and Play Support v0.97 (c) Adam Belay
SCSI subsystem initialized
NET: Registered protocol family 2
IP route cache hash table entries: 32768 (order: 5, 131072 bytes)
TCP established hash table entries: 131072 (order: 7, 524288 bytes)
TCP bind hash table entries: 65536 (order: 6, 262144 bytes)
TCP: Hash tables configured (established 131072 bind 65536)
TCP reno registered
VFS: Disk quotas dquot_6.5.1
Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
Initializing Cryptographic API
io scheduler noop registered
io scheduler deadline registered (default)
isapnp: Scanning for PnP cards...
isapnp: No Plug & Play device found
Generic RTC Driver v1.07
Macintosh non-volatile memory driver v1.1
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled
serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16450
RAMDISK: wrong blocksize 16384, reverting to defaults
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
loop: loaded (max 8 devices)
ne.c:v1.10 9/23/94 Donald Becker (becker@scyld.com)
Last modified Nov 1, 2000 by Paul Gortmaker
NE*000 ethercard probe at 0x300: 52 54 00 12 34 56
eth0: NE2000 found at 0x300, using IRQ 9.
Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2
ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
hda: IRQ probe failed (0x0)
hda: IRQ probe failed (0x0)
hda: IRQ probe failed (0x0)
hda: IRQ probe failed (0x0)
hdb: IRQ probe failed (0x0)
hdb: IRQ probe failed (0x0)
hdb: QEMU CD-ROM, ATAPI CD/DVD-ROM drive
hdb: IRQ probe failed (0x0)
ide0 at 0x1f0-0x1f7,0x3f6 on irq 13
serio: i8042 AUX port at 0x60,0x64 irq 12
serio: i8042 KBD port at 0x60,0x64 irq 1
mice: PS/2 mouse device common for all mice
TCP bic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
NET: Registered protocol family 15
input: AT Raw Set 2 keyboard as /class/input/input0
input: ImExPS/2 Generic Explorer Mouse as /class/input/input1
Sending DHCP requests ., OK
IP-Config: Got DHCP answer from 10.0.2.2, my address is 10.0.2.15
IP-Config: Complete:
      device=eth0, addr=10.0.2.15, mask=255.255.255.0, gw=10.0.2.2,
     host=10.0.2.15, domain=, nis-domain=(none),
     bootserver=10.0.2.2, rootserver=10.0.2.2, rootpath=
RAMDISK: no file foundi
No filesystem could mount root, tried:  ext3 ext2 iso9660
Kernel panic - not syncing: VFS: Unable to mount root fs on
unknown-block(1,0)
 <0>Rebooting in 180 seconds..

[-- Attachment #2: Type: text/html, Size: 10380 bytes --]

^ permalink raw reply

* Re: [RFC v3 PATCH 3/4] Apply relocation
From: Mohan Kumar M @ 2008-07-21 19:21 UTC (permalink / raw)
  To: Milton Miller; +Cc: paulus, naren, ppcdev
In-Reply-To: <d8d07a180aaf59d25936ad03c7287f5a@bga.com>

[-- Attachment #1: Type: text/plain, Size: 1 bytes --]



[-- Attachment #2: 0003-Apply-relocation.patch --]
[-- Type: text/x-patch, Size: 5555 bytes --]

Apply relocation

This code is a wrapper around regular kernel. This checks whether the
kernel is loaded at 32MB, if its not loaded at 32MB, its treated as a
regular kernel and the control is given to the kernel immediately. If
the kernel is loaded at 32MB, it applies relocation delta to each offset
in the list which was generated and appended by patch 1 and 2. After
updating all offsets, control is given to relocatable kernel.

Signed-off-by: Mohan Kumar M <mohan@in.ibm.com>
---
 arch/powerpc/boot/reloc_apply.S |  229 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 229 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/boot/reloc_apply.S

diff --git a/arch/powerpc/boot/reloc_apply.S b/arch/powerpc/boot/reloc_apply.S
new file mode 100644
index 0000000..4049976
--- /dev/null
+++ b/arch/powerpc/boot/reloc_apply.S
@@ -0,0 +1,229 @@
+#include <asm/ppc_asm.h>
+
+#define RELOC_DELTA 0x4000000002000000
+
+#define LOADADDR(rn,name) \
+	lis     rn,name##@highest;	\
+	ori     rn,rn,name##@higher;	\
+	rldicr  rn,rn,32,31;		\
+	oris    rn,rn,name##@h;		\
+	ori     rn,rn,name##@l
+
+
+/*
+ * Layout of vmlinux.reloc file
+ *	Minimal part of relocation applying code +
+ *	vmlinux +
+ *	Rest of the relocation applying code
+ */
+
+.section .text.head
+
+.globl start_wrap
+start_wrap:
+	/* Get relocation offset in r15 */
+	bl	1f
+1:	mflr	r15
+	LOAD_REG_IMMEDIATE(r16,1b)
+	subf	r15,r16,r15
+
+	LOAD_REG_IMMEDIATE(r17, _reloc)
+	add	r17,r17,r15
+	mtctr	r17
+	bctr		/* Jump to start_reloc in section ".text.reloc" */
+
+/* Secondary cpus spin code */
+. = 0x60
+	/* Get relocation offset in r15 */
+	bl	1f
+1:	mflr	r15
+	LOAD_REG_IMMEDIATE(r16,1b)
+	subf	r15,r16,r15
+
+	LOADADDR(r18, __spinloop)
+	add	r18,r18,r15
+100:	ld	r19,0(r18)
+	cmpwi	0,r19,1
+	bne	100b
+
+	LOAD_REG_IMMEDIATE(r17, _reloc)
+	add	r17,r17,r15
+	addi	r17,r17,0x60
+	mtctr	r17
+	/* Jump to start_reloc + 0x60 in section ".text.reloc" */
+	bctr
+
+/*
+ * Layout of vmlinux.reloc file
+ *	Minimal part of relocation applying code +
+ *	vmlinux +
+ *	Rest of the relocation applying code
+ */
+
+
+.section .text.reloc
+
+start_reloc:
+	b	master
+
+.org start_reloc + 0x60
+	LOADADDR(r18, __spinloop)
+	add	r18,r18,r15
+100:	ld	r19,0(r18)
+	cmpwi	0,r19,2
+	bne	100b
+
+	/* Now vmlinux is at _head */
+	LOAD_REG_IMMEDIATE(r17, _head)
+	add	r17,r17,r15
+	addi	r17,r17,0x60
+	mtctr	r17
+	bctr
+
+master:
+	LOAD_REG_IMMEDIATE(r16, output_len)
+	add	r16,r16,r15
+
+	/*
+	 * Load the delimiter to distinguish between different relocation
+	 * types
+	 */
+	LOAD_REG_IMMEDIATE(r24, __delimiter)
+	add	r24,r24,r15
+	ld	r24,0(r24)
+
+	LOAD_REG_IMMEDIATE(r17, _head)
+	LOAD_REG_IMMEDIATE(r21, _ehead)
+	sub	r21,r21,r17	/* Number of bytes in head section */
+
+	sub	r16,r16,r21	/* Original output_len */
+
+	/* Destination address */
+	LOAD_REG_IMMEDIATE(r17, _head) /* KERNELBASE */
+	add	r17,r17,r15
+
+	/* Source address */
+	LOAD_REG_IMMEDIATE(r18, _text) /* Regular vmlinux */
+	add	r18,r18,r15
+
+	/* Number of bytes to copy */
+	LOAD_REG_IMMEDIATE(r19, _etext)
+	add	r19,r19,r15
+	sub	r19,r19,r18
+
+	/* Move cpu spin code to "text.reloc" section */
+	LOADADDR(r23, __spinloop)
+	add	r23,r23,r15
+	li	r25,1
+	stw	r25,0(r23)
+
+	/* Copy vmlinux code to physical address 0 */
+	bl	.copy	/* copy(_head, _text, _etext-_text) */
+
+	/*
+	 * If its not running at 32MB, assume it to be a normal kernel.
+	 * Copy the vmlinux code to KERNELBASE and jump to KERNELBASE
+	 */
+	LOAD_REG_IMMEDIATE(r21, RELOC_DELTA)
+	cmpd	r15,r21
+	beq	apply_relocation
+	li	r6,0
+	b	skip_apply
+apply_relocation:
+
+	/* Kernel is running at 32MB */
+	mr	r22,r15
+	xor	r23,r23,r23
+	addi	r23,r23,16
+	srw	r22,r22,r23
+
+	li	r25,0
+
+	LOAD_REG_IMMEDIATE(r26, _head)
+
+	/*
+	 * Start reading the relocation offset list from end of file
+	 * Based on the relocation type either add the relocation delta
+	 * or do logical ORing the relocation delta
+	 */
+3:
+	addi	r16,r16,-8
+	ld	r18,0(r16)
+	cmpdi	r18,0		/* Processed all offsets */
+	beq	4f		/* Start vmlinux */
+	/* Are we processing reloction type R_PPC64_ADDR16_HI */
+	cmpdi	r25,1
+	beq	rel_hi
+	cmpd	r18,r24
+	beq	set_rel_hi
+	/* Process 64bit absolute relocation update */
+rel_addr64:
+	add	r18,r18,r15
+	ld	r28,0(r18)
+	cmpdi	r28,0
+	beq	next
+	add	r28,r28,r15	/* add relocation offset */
+	add	r28,r28,r26	/* add KERNELBASE */
+	std	r28,0(r18)
+	b	next
+set_rel_hi:			/* Enable R_PPC64_ADDR16_HI flag */
+	addi	r25,r25,1
+	b	3b
+rel_hi:
+	add	r18,r18,r15
+	lhz	r28,0(r18)
+	or	r28,r28,r22
+	sth	r28,0(r18)
+next:
+	b	3b
+4:
+	mr	r6,r15
+
+
+skip_apply:
+	isync
+	sync
+
+	/* Now vmlinux is at _head */
+	LOAD_REG_IMMEDIATE(r17, _head)
+	add	r17,r17,r15
+	mtctr	r17
+
+	/* Move cpu spin code to "text.reloc" section */
+	LOADADDR(r23, __spinloop)
+	add	r23,r23,r15
+	li	r25,2
+	stw	r25,0(r23)
+
+	bctr
+
+/* r17 destination, r18 source, r19 size */
+.copy:
+	addi	r19,r19,-8
+	li	r22,-8
+4:	li	r21,8			/* Use the smallest common	*/
+					/* denominator cache line	*/
+					/* size.  This results in	*/
+					/* extra cache line flushes	*/
+					/* but operation is correct.	*/
+					/* Can't get cache line size	*/
+					/* from NACA as it is being	*/
+					/* moved too.			*/
+
+	mtctr	r21			/* put # words/line in ctr	*/
+3:	addi	r22,r22,8		/* copy a cache line		*/
+	ldx	r21,r22,r18
+	stdx	r21,r22,r17
+	bdnz	3b
+	dcbst	r22,r17			/* write it to memory		*/
+	sync
+	icbi	r22,r17			/* flush the icache line	*/
+	cmpld	0,r22,r19
+	blt	4b
+	sync
+	blr
+
+__delimiter:
+	.llong 0xffffffffffffffff
+__spinloop:
+	.llong	0x0
-- 
1.5.4


^ permalink raw reply related

* Re: [RFC v3 PATCH 2/4] Build files needed for relocation
From: Mohan Kumar M @ 2008-07-21 19:20 UTC (permalink / raw)
  To: Milton Miller; +Cc: paulus, naren, ppcdev
In-Reply-To: <d8d07a180aaf59d25936ad03c7287f5a@bga.com>

[-- Attachment #1: Type: text/plain, Size: 1 bytes --]



[-- Attachment #2: 0002-Build-files-needed-for-relocation.patch --]
[-- Type: text/x-patch, Size: 6643 bytes --]

Build files needed for relocation

This patch builds vmlinux file with relocation sections and contents so
that relocs user space program can extract the required relocation
offsets. This packs final relocatable vmlinux kernel as following:
earlier part of relocation apply code, vmlinux, rest of relocation apply
code.

TODO:
Relocatable vmlinux image is built in arch/powerpc/boot as vmlinux.reloc.
But it should be built in top level directory of kernel source as vmlinux
instead of vmlinux.reloc

Signed-off-by: Mohan Kumar M <mohan@in.ibm.com>
---
 arch/powerpc/Kconfig                |   15 ++++++++++--
 arch/powerpc/Makefile               |    9 ++++++-
 arch/powerpc/boot/Makefile          |   39 ++++++++++++++++++++++++++++++++--
 arch/powerpc/boot/vmlinux.lds.S     |   28 +++++++++++++++++++++++++
 arch/powerpc/boot/vmlinux.reloc.scr |    8 +++++++
 5 files changed, 91 insertions(+), 8 deletions(-)
 create mode 100644 arch/powerpc/boot/vmlinux.lds.S
 create mode 100644 arch/powerpc/boot/vmlinux.reloc.scr

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index f2a0f50..366a622 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -317,6 +317,15 @@ config CRASH_DUMP
 
 	  Don't change this unless you know what you are doing.
 
+config RELOCATABLE_PPC64
+	bool "Build a relocatable kernel (EXPERIMENTAL)"
+	depends on PPC_MULTIPLATFORM && PPC64 && CRASH_DUMP && EXPERIMENTAL
+	help
+	  Build a kernel suitable for use as regular kernel and kdump capture
+	  kernel.
+
+	  Don't change this unless you know what you are doing.
+
 config PHYP_DUMP
 	bool "Hypervisor-assisted dump (EXPERIMENTAL)"
 	depends on PPC_PSERIES && EXPERIMENTAL
@@ -662,7 +671,7 @@ config LOWMEM_SIZE
 	default "0x30000000"
 
 config RELOCATABLE
-	bool "Build a relocatable kernel (EXPERIMENTAL)"
+	bool "Build relocatable kernel (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && ADVANCED_OPTIONS && FLATMEM && FSL_BOOKE
 	help
 	  This builds a kernel image that is capable of running at the
@@ -782,11 +791,11 @@ config PAGE_OFFSET
 	default "0xc000000000000000"
 config KERNEL_START
 	hex
-	default "0xc000000002000000" if CRASH_DUMP
+	default "0xc000000002000000" if CRASH_DUMP && !RELOCATABLE_PPC64
 	default "0xc000000000000000"
 config PHYSICAL_START
 	hex
-	default "0x02000000" if CRASH_DUMP
+	default "0x02000000" if CRASH_DUMP && !RELOCATABLE_PPC64
 	default "0x00000000"
 endif
 
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 59ae7d9..58ccb7f 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -63,7 +63,7 @@ override CC	+= -m$(CONFIG_WORD_SIZE)
 override AR	:= GNUTARGET=elf$(CONFIG_WORD_SIZE)-powerpc $(AR)
 endif
 
-LDFLAGS_vmlinux	:= -Bstatic
+LDFLAGS_vmlinux	:= --emit-relocs
 
 CFLAGS-$(CONFIG_PPC64)	:= -mminimal-toc -mtraceback=none  -mcall-aixdesc
 CFLAGS-$(CONFIG_PPC32)	:= -ffixed-r2 -mmultiple
@@ -146,11 +146,16 @@ core-$(CONFIG_KVM) 		+= arch/powerpc/kvm/
 drivers-$(CONFIG_OPROFILE)	+= arch/powerpc/oprofile/
 
 # Default to zImage, override when needed
+
+ifneq ($(CONFIG_RELOCATABLE_PPC64),y)
 all: zImage
+else
+all: zImage vmlinux.reloc
+endif
 
 CPPFLAGS_vmlinux.lds	:= -Upowerpc
 
-BOOT_TARGETS = zImage zImage.initrd uImage zImage% dtbImage% treeImage.% cuImage.% simpleImage.%
+BOOT_TARGETS = zImage vmlinux.reloc zImage.initrd uImage zImage% dtbImage% treeImage.% cuImage.% simpleImage.%
 
 PHONY += $(BOOT_TARGETS)
 
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 751a6e6..1a62036 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -17,7 +17,7 @@
 #	CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE
 #	in the toplevel makefile.
 
-all: $(obj)/zImage
+all: $(obj)/zImage $(obj)/vmlinux.reloc
 
 BOOTCFLAGS    := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
 		 -fno-strict-aliasing -Os -msoft-float -pipe \
@@ -122,18 +122,51 @@ $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S FORCE
 $(obj)/wrapper.a: $(obj-wlib) FORCE
 	$(call if_changed,bootar)
 
-hostprogs-y	:= addnote addRamDisk hack-coff mktree dtc
+hostprogs-y	:= addnote addRamDisk hack-coff mktree dtc relocs
 
 targets		+= $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a)
 extra-y		:= $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
 		   $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds
 
+ifeq ($(CONFIG_RELOCATABLE_PPC64),y)
+extra-y		+= $(obj)/vmlinux.lds
+endif
+
 dtstree		:= $(srctree)/$(src)/dts
 
 wrapper		:=$(srctree)/$(src)/wrapper
-wrapperbits	:= $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree dtc) \
+wrapperbits	:= $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree dtc relocs) \
 			$(wrapper) FORCE
 
+ifeq ($(CONFIG_RELOCATABLE_PPC64),y)
+
+targets +=  vmlinux.offsets vmlinux.bin vmlinux.bin.all vmlinux.reloc.elf vmlinux.reloc reloc_apply.o vmlinux.lds
+
+OBJCOPYFLAGS_vmlinux.bin :=  -O binary -R .note -R .comment -S
+$(obj)/vmlinux.bin: vmlinux FORCE
+	$(call if_changed,objcopy)
+
+quiet_cmd_relocbin = BUILD   $@
+      cmd_relocbin = cat $(filter-out FORCE,$^) > $@
+
+quiet_cmd_relocs = RELOCS   $@
+    cmd_relocs = $(obj)/relocs $< > $@
+
+$(obj)/vmlinux.offsets: vmlinux $(obj)/relocs FORCE
+	$(call if_changed,relocs)
+
+$(obj)/vmlinux.bin.all: $(obj)/vmlinux.bin $(obj)/vmlinux.offsets FORCE
+	$(call if_changed,relocbin)
+
+LDFLAGS_vmlinux.reloc.elf := -T $(obj)/vmlinux.reloc.scr -r --format binary --oformat elf64-powerpc
+$(obj)/vmlinux.reloc.elf: $(obj)/vmlinux.bin.all FORCE
+	$(call if_changed,ld)
+
+LDFLAGS_vmlinux.reloc := -T $(obj)/vmlinux.lds
+$(obj)/vmlinux.reloc: $(obj)/reloc_apply.o $(obj)/vmlinux.reloc.elf FORCE
+	$(call if_changed,ld)
+endif
+
 #############
 # Bits for building dtc
 # DTC_GENPARSER      := 1    # Uncomment to rebuild flex/bison output
diff --git a/arch/powerpc/boot/vmlinux.lds.S b/arch/powerpc/boot/vmlinux.lds.S
new file mode 100644
index 0000000..245c667
--- /dev/null
+++ b/arch/powerpc/boot/vmlinux.lds.S
@@ -0,0 +1,28 @@
+#include <asm/page.h>
+#include <asm-generic/vmlinux.lds.h>
+
+ENTRY(start_wrap)
+
+OUTPUT_ARCH(powerpc:common64)
+SECTIONS
+{
+	. = KERNELBASE;
+
+/*
+ * Text, read only data and other permanent read-only sections
+ */
+	/* Text and gots */
+	.text : {
+		_head = .;
+		*(.text.head)
+		_ehead = .;
+
+		_text = .;
+		*(.vmlinux)
+		_etext = .;
+
+		_reloc = .;
+		*(.text.reloc)
+		_ereloc = .;
+	}
+}
diff --git a/arch/powerpc/boot/vmlinux.reloc.scr b/arch/powerpc/boot/vmlinux.reloc.scr
new file mode 100644
index 0000000..7240b6b
--- /dev/null
+++ b/arch/powerpc/boot/vmlinux.reloc.scr
@@ -0,0 +1,8 @@
+SECTIONS
+{
+  .vmlinux : {
+	input_len = .;
+	*(.data)
+	output_len = . - 8;
+	}
+}
-- 
1.5.4


^ permalink raw reply related

* Re: [RFC v3 PATCH 1/4] Extract list of relocation offsets
From: Mohan Kumar M @ 2008-07-21 19:17 UTC (permalink / raw)
  To: Milton Miller; +Cc: paulus, naren, ppcdev
In-Reply-To: <d8d07a180aaf59d25936ad03c7287f5a@bga.com>

[-- Attachment #1: Type: text/plain, Size: 248 bytes --]

Hi Milton,

I am resending the patches generated against latest powerpc git tree.

I am facing kdump kernel hang issue with the git tree. It hangs in 
unflatten_devicetree call in prom.c


Note: These patches are not fully tested.

Regards,
Mohan.

[-- Attachment #2: 0001-Extract-list-of-relocation-offsets.patch --]
[-- Type: text/x-patch, Size: 24353 bytes --]

Extract list of relocation offsets

Extract list of offsets in the vmlinux file for which the relocation
delta has to be patched. Currently only following type of relocation
types are considered: R_PPC64_ADDR16_HI, R_PPC64_TOC and R_PPC64_ADDR64

The offsets are sorted according to the relocation type and this
information is appended to the normal vmlinux file by using the patch
relocation_build.patch

Signed-off-by: Mohan Kumar M <mohan@in.ibm.com>
---
 arch/powerpc/boot/relocs.c |  865 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 865 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/boot/relocs.c

diff --git a/arch/powerpc/boot/relocs.c b/arch/powerpc/boot/relocs.c
new file mode 100644
index 0000000..31ca903
--- /dev/null
+++ b/arch/powerpc/boot/relocs.c
@@ -0,0 +1,865 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <elf.h>
+#include <byteswap.h>
+#define USE_BSD
+#include <endian.h>
+
+#define MAX_SHDRS 100
+static Elf64_Ehdr ehdr;
+static Elf64_Shdr shdr[MAX_SHDRS];
+static Elf64_Sym  *symtab[MAX_SHDRS];
+static Elf64_Rel  *reltab[MAX_SHDRS];
+static Elf64_Rela  *reltaba[MAX_SHDRS];
+static char *strtab[MAX_SHDRS];
+static unsigned long reloc_count, reloc_idx;
+
+struct reloc_info {
+	unsigned int rel_type;
+	unsigned long long offset;
+};
+
+static struct reloc_info *relocs;
+
+/*
+ * Following symbols have been audited. There values are constant and do
+ * not change if bzImage is loaded at a different physical address than
+ * the address for which it has been compiled. Don't warn user about
+ * absolute relocations present w.r.t these symbols.
+ */
+static const char* safe_abs_relocs[] = {
+		"__kernel_vsyscall",
+		"__kernel_rt_sigreturn",
+		"__kernel_sigreturn",
+		"SYSENTER_RETURN",
+};
+
+static int is_safe_abs_reloc(const char* sym_name)
+{
+	int i, array_size;
+
+	array_size = sizeof(safe_abs_relocs)/sizeof(char*);
+
+	for(i = 0; i < array_size; i++) {
+		if (!strcmp(sym_name, safe_abs_relocs[i]))
+			/* Match found */
+			return 1;
+	}
+	if (strncmp(sym_name, "__crc_", 6) == 0)
+		return 1;
+	return 0;
+}
+
+static void die(char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
+	exit(1);
+}
+
+static const char *sym_type(unsigned type)
+{
+	static const char *type_name[] = {
+#define SYM_TYPE(X) [X] = #X
+		SYM_TYPE(STT_NOTYPE),
+		SYM_TYPE(STT_OBJECT),
+		SYM_TYPE(STT_FUNC),
+		SYM_TYPE(STT_SECTION),
+		SYM_TYPE(STT_FILE),
+		SYM_TYPE(STT_COMMON),
+		SYM_TYPE(STT_TLS),
+#undef SYM_TYPE
+	};
+	const char *s_type = "unknown sym type name";
+	if (type < sizeof(type_name)/sizeof(type_name[0])) {
+		s_type = type_name[type];
+	}
+	return s_type;
+}
+
+static const char *sym_bind(unsigned bind)
+{
+	static const char *bind_name[] = {
+#define SYM_BIND(X) [X] = #X
+		SYM_BIND(STB_LOCAL),
+		SYM_BIND(STB_GLOBAL),
+		SYM_BIND(STB_WEAK),
+#undef SYM_BIND
+	};
+	const char *s_bind = "unknown sym bind name";
+	if (bind < sizeof(bind_name)/sizeof(bind_name[0])) {
+		s_bind = bind_name[bind];
+	}
+	return s_bind;
+}
+
+static const char *sym_visibility(unsigned visibility)
+{
+	static const char *visibility_name[] = {
+#define SYM_VISIBILITY(X) [X] = #X
+		SYM_VISIBILITY(STV_DEFAULT),
+		SYM_VISIBILITY(STV_INTERNAL),
+		SYM_VISIBILITY(STV_HIDDEN),
+		SYM_VISIBILITY(STV_PROTECTED),
+#undef SYM_VISIBILITY
+	};
+	const char *name = "unknown sym visibility name";
+	if (visibility < sizeof(visibility_name)/sizeof(visibility_name[0])) {
+		name = visibility_name[visibility];
+	}
+	return name;
+}
+
+static const char *rel_type(unsigned type)
+{
+	static const char *type_name[] = {
+#define REL_TYPE(X) [X] = #X
+		REL_TYPE(R_PPC64_NONE),
+		REL_TYPE(R_PPC64_ADDR32),
+		REL_TYPE(R_PPC64_ADDR24),
+		REL_TYPE(R_PPC64_ADDR16),
+		REL_TYPE(R_PPC64_ADDR16_LO),
+		REL_TYPE(R_PPC64_ADDR16_HI),
+		REL_TYPE(R_PPC64_ADDR16_HA),
+		REL_TYPE(R_PPC64_ADDR14	),
+		REL_TYPE(R_PPC64_ADDR14_BRTAKEN),
+		REL_TYPE(R_PPC64_ADDR14_BRNTAKEN),
+		REL_TYPE(R_PPC64_REL24),
+		REL_TYPE(R_PPC64_REL14),
+		REL_TYPE(R_PPC64_REL14_BRTAKEN),
+		REL_TYPE(R_PPC64_REL14_BRNTAKEN),
+		REL_TYPE(R_PPC64_GOT16),
+		REL_TYPE(R_PPC64_GOT16_LO),
+		REL_TYPE(R_PPC64_GOT16_HI),
+		REL_TYPE(R_PPC64_GOT16_HA),
+		REL_TYPE(R_PPC64_COPY),
+		REL_TYPE(R_PPC64_GLOB_DAT),
+		REL_TYPE(R_PPC64_JMP_SLOT),
+		REL_TYPE(R_PPC64_RELATIVE),
+		REL_TYPE(R_PPC64_UADDR32),
+		REL_TYPE(R_PPC64_UADDR16),
+		REL_TYPE(R_PPC64_REL32),
+		REL_TYPE(R_PPC64_PLT32),
+		REL_TYPE(R_PPC64_PLTREL32),
+		REL_TYPE(R_PPC64_PLT16_LO),
+		REL_TYPE(R_PPC64_PLT16_HI),
+		REL_TYPE(R_PPC64_PLT16_HA),
+		REL_TYPE(R_PPC64_SECTOFF),
+		REL_TYPE(R_PPC64_SECTOFF_LO),
+		REL_TYPE(R_PPC64_SECTOFF_HI),
+		REL_TYPE(R_PPC64_SECTOFF_HA),
+		REL_TYPE(R_PPC64_ADDR30),
+		REL_TYPE(R_PPC64_ADDR64),
+		REL_TYPE(R_PPC64_ADDR16_HIGHER),
+		REL_TYPE(R_PPC64_ADDR16_HIGHERA),
+		REL_TYPE(R_PPC64_ADDR16_HIGHEST),
+		REL_TYPE(R_PPC64_ADDR16_HIGHESTA),
+		REL_TYPE(R_PPC64_UADDR64),
+		REL_TYPE(R_PPC64_REL64),
+		REL_TYPE(R_PPC64_PLT64),
+		REL_TYPE(R_PPC64_PLTREL64),
+		REL_TYPE(R_PPC64_TOC16),
+		REL_TYPE(R_PPC64_TOC16_LO),
+		REL_TYPE(R_PPC64_TOC16_HI),
+		REL_TYPE(R_PPC64_TOC16_HA),
+		REL_TYPE(R_PPC64_TOC),
+		REL_TYPE(R_PPC64_PLTGOT16),
+		REL_TYPE(R_PPC64_PLTGOT16_LO),
+		REL_TYPE(R_PPC64_PLTGOT16_HI),
+		REL_TYPE(R_PPC64_PLTGOT16_HA),
+		REL_TYPE(R_PPC64_ADDR16_DS),
+		REL_TYPE(R_PPC64_ADDR16_LO_DS),
+		REL_TYPE(R_PPC64_GOT16_DS),
+		REL_TYPE(R_PPC64_GOT16_LO_DS),
+		REL_TYPE(R_PPC64_PLT16_LO_DS),
+		REL_TYPE(R_PPC64_SECTOFF_DS),
+		REL_TYPE(R_PPC64_SECTOFF_LO_DS),
+		REL_TYPE(R_PPC64_TOC16_DS),
+		REL_TYPE(R_PPC64_TOC16_LO_DS),
+		REL_TYPE(R_PPC64_PLTGOT16_DS),
+		REL_TYPE(R_PPC64_PLTGOT16_LO_DS),
+		REL_TYPE(R_PPC64_TLS),
+		REL_TYPE(R_PPC64_DTPMOD64),
+		REL_TYPE(R_PPC64_TPREL16),
+		REL_TYPE(R_PPC64_TPREL16_LO),
+		REL_TYPE(R_PPC64_TPREL16_HI),
+		REL_TYPE(R_PPC64_TPREL16_HA),
+		REL_TYPE(R_PPC64_TPREL64),
+		REL_TYPE(R_PPC64_DTPREL16),
+		REL_TYPE(R_PPC64_DTPREL16_LO),
+		REL_TYPE(R_PPC64_DTPREL16_HI),
+		REL_TYPE(R_PPC64_DTPREL16_HA),
+		REL_TYPE(R_PPC64_DTPREL64),
+		REL_TYPE(R_PPC64_GOT_TLSGD16),
+		REL_TYPE(R_PPC64_GOT_TLSGD16_LO),
+		REL_TYPE(R_PPC64_GOT_TLSGD16_HI),
+		REL_TYPE(R_PPC64_GOT_TLSGD16_HA),
+		REL_TYPE(R_PPC64_GOT_TLSLD16),
+		REL_TYPE(R_PPC64_GOT_TLSLD16_LO),
+		REL_TYPE(R_PPC64_GOT_TLSLD16_HI),
+		REL_TYPE(R_PPC64_GOT_TLSLD16_HA),
+		REL_TYPE(R_PPC64_GOT_TPREL16_DS),
+		REL_TYPE(R_PPC64_GOT_TPREL16_LO_DS),
+		REL_TYPE(R_PPC64_GOT_TPREL16_HI),
+		REL_TYPE(R_PPC64_GOT_TPREL16_HA),
+		REL_TYPE(R_PPC64_GOT_DTPREL16_DS),
+		REL_TYPE(R_PPC64_GOT_DTPREL16_LO_DS),
+		REL_TYPE(R_PPC64_GOT_DTPREL16_HI),
+		REL_TYPE(R_PPC64_GOT_DTPREL16_HA),
+		REL_TYPE(R_PPC64_TPREL16_DS),
+		REL_TYPE(R_PPC64_TPREL16_LO_DS),
+		REL_TYPE(R_PPC64_TPREL16_HIGHER),
+		REL_TYPE(R_PPC64_TPREL16_HIGHERA),
+		REL_TYPE(R_PPC64_TPREL16_HIGHEST),
+		REL_TYPE(R_PPC64_TPREL16_HIGHESTA),
+		REL_TYPE(R_PPC64_DTPREL16_DS),
+		REL_TYPE(R_PPC64_DTPREL16_LO_DS),
+		REL_TYPE(R_PPC64_DTPREL16_HIGHER),
+		REL_TYPE(R_PPC64_DTPREL16_HIGHERA),
+		REL_TYPE(R_PPC64_DTPREL16_HIGHEST),
+		REL_TYPE(R_PPC64_DTPREL16_HIGHESTA),
+#undef REL_TYPE
+	};
+	const char *name = "unknown type rel type name";
+	if (type < sizeof(type_name)/sizeof(type_name[0])) {
+		name = type_name[type];
+	}
+	return name;
+}
+
+static const char *sec_name(unsigned shndx)
+{
+	const char *sec_strtab;
+	const char *name;
+	sec_strtab = strtab[ehdr.e_shstrndx];
+	name = "<noname>";
+	if (shndx < ehdr.e_shnum) {
+		name = sec_strtab + shdr[shndx].sh_name;
+	}
+	else if (shndx == SHN_ABS) {
+		name = "ABSOLUTE";
+	}
+	else if (shndx == SHN_COMMON) {
+		name = "COMMON";
+	}
+	return name;
+}
+
+static const char *sym_name(const char *sym_strtab, Elf64_Sym *sym)
+{
+	const char *name;
+	name = "<noname>";
+	if (sym->st_name) {
+		name = sym_strtab + sym->st_name;
+	}
+	else {
+		name = sec_name(shdr[sym->st_shndx].sh_name);
+	}
+	return name;
+}
+
+
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define be16_to_cpu(val) (val)
+#define be32_to_cpu(val) (val)
+#define be64_to_cpu(val) (val)
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define be16_to_cpu(val) bswap_16(val)
+#define be32_to_cpu(val) bswap_32(val)
+#define be64_to_cpu(val) bswap_64(val)
+#endif
+
+static uint16_t elf16_to_cpu(uint16_t val)
+{
+	return be16_to_cpu(val);
+}
+
+static uint32_t elf32_to_cpu(uint32_t val)
+{
+	return be32_to_cpu(val);
+}
+
+static uint64_t elf64_to_cpu(uint64_t val)
+{
+	return be64_to_cpu(val);
+}
+
+static void read_ehdr(FILE *fp)
+{
+	if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) {
+		die("Cannot read ELF header: %s\n",
+			strerror(errno));
+	}
+	if (memcmp(ehdr.e_ident, ELFMAG, 4) != 0) {
+		die("No ELF magic\n");
+	}
+	if (ehdr.e_ident[EI_CLASS] != ELFCLASS64) {
+		die("Not a 64 bit executable\n");
+	}
+	if (ehdr.e_ident[EI_DATA] != ELFDATA2MSB) {
+		die("Not a MSB ELF executable\n");
+	}
+	if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
+		die("Unknown ELF version\n");
+	}
+	/* Convert the fields to native endian */
+	ehdr.e_type      = elf16_to_cpu(ehdr.e_type);
+	ehdr.e_machine   = elf16_to_cpu(ehdr.e_machine);
+	ehdr.e_version   = elf32_to_cpu(ehdr.e_version);
+	ehdr.e_entry     = elf64_to_cpu(ehdr.e_entry);
+	ehdr.e_phoff     = elf64_to_cpu(ehdr.e_phoff);
+	ehdr.e_shoff     = elf64_to_cpu(ehdr.e_shoff);
+	ehdr.e_flags     = elf32_to_cpu(ehdr.e_flags);
+	ehdr.e_ehsize    = elf16_to_cpu(ehdr.e_ehsize);
+	ehdr.e_phentsize = elf16_to_cpu(ehdr.e_phentsize);
+	ehdr.e_phnum     = elf16_to_cpu(ehdr.e_phnum);
+	ehdr.e_shentsize = elf16_to_cpu(ehdr.e_shentsize);
+	ehdr.e_shnum     = elf16_to_cpu(ehdr.e_shnum);
+	ehdr.e_shstrndx  = elf16_to_cpu(ehdr.e_shstrndx);
+
+	if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN)) {
+		die("Unsupported ELF header type\n");
+	}
+	if (ehdr.e_machine != EM_PPC64) {
+		die("Not for PPC64\n");
+	}
+	if (ehdr.e_version != EV_CURRENT) {
+		die("Unknown ELF version\n");
+	}
+	if (ehdr.e_ehsize != sizeof(Elf64_Ehdr)) {
+		die("Bad Elf header size\n");
+	}
+	if (ehdr.e_phentsize != sizeof(Elf64_Phdr)) {
+		die("Bad program header entry\n");
+	}
+	if (ehdr.e_shentsize != sizeof(Elf64_Shdr)) {
+		die("Bad section header entry\n");
+	}
+	if (ehdr.e_shstrndx >= ehdr.e_shnum) {
+		die("String table index out of bounds\n");
+	}
+}
+
+static void read_shdrs(FILE *fp)
+{
+	int i;
+	if (ehdr.e_shnum > MAX_SHDRS) {
+		die("%d section headers supported: %d\n",
+			ehdr.e_shnum, MAX_SHDRS);
+	}
+	if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) {
+		die("Seek to %d failed: %s\n",
+			ehdr.e_shoff, strerror(errno));
+	}
+	if (fread(&shdr, sizeof(shdr[0]), ehdr.e_shnum, fp) != ehdr.e_shnum) {
+		die("Cannot read ELF section headers: %s\n",
+			strerror(errno));
+	}
+	for(i = 0; i < ehdr.e_shnum; i++) {
+		shdr[i].sh_name      = elf32_to_cpu(shdr[i].sh_name);
+		shdr[i].sh_type      = elf32_to_cpu(shdr[i].sh_type);
+		shdr[i].sh_flags     = elf64_to_cpu(shdr[i].sh_flags);
+		shdr[i].sh_addr      = elf64_to_cpu(shdr[i].sh_addr);
+		shdr[i].sh_offset    = elf64_to_cpu(shdr[i].sh_offset);
+		shdr[i].sh_size      = elf64_to_cpu(shdr[i].sh_size);
+		shdr[i].sh_link      = elf32_to_cpu(shdr[i].sh_link);
+		shdr[i].sh_info      = elf32_to_cpu(shdr[i].sh_info);
+		shdr[i].sh_addralign = elf64_to_cpu(shdr[i].sh_addralign);
+		shdr[i].sh_entsize   = elf64_to_cpu(shdr[i].sh_entsize);
+	}
+
+}
+
+static void read_strtabs(FILE *fp)
+{
+	int i;
+	for(i = 0; i < ehdr.e_shnum; i++) {
+		if (shdr[i].sh_type != SHT_STRTAB) {
+			continue;
+		}
+		strtab[i] = malloc(shdr[i].sh_size);
+		if (!strtab[i]) {
+			die("malloc of %d bytes for strtab failed\n",
+				shdr[i].sh_size);
+		}
+		if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) {
+			die("Seek to %d failed: %s\n",
+				shdr[i].sh_offset, strerror(errno));
+		}
+		if (fread(strtab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) {
+			die("Cannot read symbol table: %s\n",
+				strerror(errno));
+		}
+	}
+}
+
+static void read_symtabs(FILE *fp)
+{
+	int i,j;
+	for(i = 0; i < ehdr.e_shnum; i++) {
+		if (shdr[i].sh_type != SHT_SYMTAB) {
+			continue;
+		}
+		symtab[i] = malloc(shdr[i].sh_size);
+		if (!symtab[i]) {
+			die("malloc of %d bytes for symtab failed\n",
+				shdr[i].sh_size);
+		}
+		if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) {
+			die("Seek to %d failed: %s\n",
+				shdr[i].sh_offset, strerror(errno));
+		}
+		if (fread(symtab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) {
+			die("Cannot read symbol table: %s\n",
+				strerror(errno));
+		}
+		for(j = 0; j < shdr[i].sh_size/sizeof(symtab[i][0]); j++) {
+			symtab[i][j].st_name  = elf32_to_cpu(symtab[i][j].st_name);
+			symtab[i][j].st_value = elf64_to_cpu(symtab[i][j].st_value);
+			symtab[i][j].st_size  = elf64_to_cpu(symtab[i][j].st_size);
+			symtab[i][j].st_shndx = elf16_to_cpu(symtab[i][j].st_shndx);
+		}
+	}
+}
+
+
+static void read_relocs(FILE *fp)
+{
+	int i,j;
+	void *relp;
+
+	for(i = 0; i < ehdr.e_shnum; i++) {
+		if (shdr[i].sh_type != SHT_REL && shdr[i].sh_type != SHT_RELA)
+			continue;
+
+		if (shdr[i].sh_type == SHT_REL) {
+			reltab[i] = malloc(shdr[i].sh_size);
+			if (!reltab[i]) {
+				die("malloc of %d bytes for relocs failed\n",
+					shdr[i].sh_size);
+			}
+			relp = reltab[i];
+		} else {
+			reltaba[i] = malloc(shdr[i].sh_size);
+			if (!reltaba[i]) {
+				die("malloc of %d bytes for relocs failed\n",
+					shdr[i].sh_size);
+			}
+			relp = reltaba[i];
+		}
+
+		if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) {
+			die("Seek to %d failed: %s\n",
+				shdr[i].sh_offset, strerror(errno));
+		}
+		if (fread(relp, 1, shdr[i].sh_size, fp) != shdr[i].sh_size) {
+			die("Cannot read symbol table: %s\n",
+				strerror(errno));
+		}
+
+		if (shdr[i].sh_type == SHT_REL)
+			for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) {
+				reltab[i][j].r_offset = elf64_to_cpu(reltab[i][j].r_offset);
+				reltab[i][j].r_info   = elf64_to_cpu(reltab[i][j].r_info);
+			}
+		else
+			for(j = 0; j < shdr[i].sh_size/sizeof(reltaba[0][0]); j++) {
+				reltaba[i][j].r_offset = elf64_to_cpu(reltaba[i][j].r_offset);
+				reltaba[i][j].r_info   = elf64_to_cpu(reltaba[i][j].r_info);
+				reltaba[i][j].r_addend   = elf64_to_cpu(reltaba[i][j].r_addend);
+			}
+	}
+}
+
+
+static void print_absolute_symbols(void)
+{
+	int i;
+	printf("Absolute symbols\n");
+	printf(" Num:  Value            Size  Type       Bind        Visibility  Name\n");
+	for(i = 0; i < ehdr.e_shnum; i++) {
+		char *sym_strtab;
+		Elf64_Sym *sh_symtab;
+		int j;
+		if (shdr[i].sh_type != SHT_SYMTAB) {
+			continue;
+		}
+		sh_symtab = symtab[i];
+		sym_strtab = strtab[shdr[i].sh_link];
+		for(j = 0; j < shdr[i].sh_size/sizeof(symtab[0][0]); j++) {
+			Elf64_Sym *sym;
+			const char *name;
+			sym = &symtab[i][j];
+			name = sym_name(sym_strtab, sym);
+			if (sym->st_shndx != SHN_ABS) {
+				continue;
+			}
+			printf("type:[%s]\n",
+				sym_type(ELF64_ST_TYPE(sym->st_info)));
+			printf("%5d %016llx %5d type:%s bind:%10s %12s %s\n", \
+				j, sym->st_value, (int)(sym->st_size), \
+				sym_type(ELF64_ST_TYPE(sym->st_info)), \
+				sym_bind(ELF64_ST_BIND(sym->st_info)), \
+				sym_visibility(ELF64_ST_VISIBILITY(sym->st_other)), \
+				name);
+		}
+	}
+	printf("\n");
+}
+
+static void print_absolute_relocs(void)
+{
+	int i, printed = 0;
+	int nr, sh_type;
+
+	for(i = 0; i < ehdr.e_shnum; i++) {
+		char *sym_strtab;
+		Elf64_Sym *sh_symtab;
+		unsigned sec_applies, sec_symtab;
+		int j;
+		if (shdr[i].sh_type != SHT_REL && shdr[i].sh_type != SHT_RELA) {
+			continue;
+		}
+		sec_symtab  = shdr[i].sh_link;
+		sec_applies = shdr[i].sh_info;
+		if (!(shdr[sec_applies].sh_flags & SHF_ALLOC)) {
+			continue;
+		}
+		if (shdr[i].sh_type == SHT_REL) {
+			sh_type = SHT_REL;
+			nr = shdr[i].sh_size/sizeof(reltab[0][0]);
+		} else {
+			sh_type = SHT_RELA;
+			nr = shdr[i].sh_size/sizeof(reltaba[0][0]);
+		}
+
+		sh_symtab = symtab[sec_symtab];
+		sym_strtab = strtab[shdr[sec_symtab].sh_link];
+
+		for(j = 0; j < nr; j++) {
+			Elf64_Rel *rel = NULL;
+			Elf64_Rela *rela = NULL;
+			Elf64_Sym *sym;
+			const char *name;
+
+			if (sh_type == SHT_REL) {
+				rel = &reltab[i][j];
+				sym = &sh_symtab[ELF64_R_SYM(rel->r_info)];
+			} else {
+				rela = &reltaba[i][j];
+				sym = &sh_symtab[ELF64_R_SYM(rela->r_info)];
+			}
+
+			name = sym_name(sym_strtab, sym);
+			if (sym->st_shndx != SHN_ABS) {
+				continue;
+			}
+
+			/* Absolute symbols are not relocated if vmlinux is
+			 * loaded at a non-compiled address. Display a warning
+			 * to user at compile time about the absolute
+			 * relocations present.
+			 *
+			 * User need to audit the code to make sure
+			 * some symbols which should have been section
+			 * relative have not become absolute because of some
+			 * linker optimization or wrong programming usage.
+			 *
+			 * Before warning check if this absolute symbol
+			 * relocation is harmless.
+			 */
+			if (is_safe_abs_reloc(name))
+				continue;
+
+			if (!printed) {
+				printf("WARNING: Absolute relocations"
+					" present\n");
+				printf("Offset           Info             Type           Sym.Value        "
+					"Sym.Name\n");
+				printed = 1;
+			}
+
+			if (sh_type == SHT_REL)
+				printf("%016llx %016llx %10s %016llx  %s\n",
+					rel->r_offset,
+					rel->r_info,
+					rel_type(ELF64_R_TYPE(rel->r_info)),
+					sym->st_value,
+					name);
+			else
+				printf("%016llx %016llx %10s %016llx  %s\n",
+					rela->r_offset,
+					rela->r_info,
+					rel_type(ELF64_R_TYPE(rela->r_info)),
+					sym->st_value,
+					name);
+		}
+	}
+
+	if (printed)
+		printf("\n");
+}
+
+static void walk_relocs(void (*visit)(void *relp, Elf64_Sym *sym, int sh_type))
+{
+	int i;
+	/* Walk through the relocations */
+	for(i = 0; i < ehdr.e_shnum; i++) {
+		char *sym_strtab;
+		Elf64_Sym *sh_symtab;
+		unsigned sec_applies, sec_symtab;
+		int j, nr_entries, sh_type;
+		if (shdr[i].sh_type != SHT_REL && shdr[i].sh_type != SHT_RELA) {
+			continue;
+		}
+		sec_symtab  = shdr[i].sh_link;
+		sec_applies = shdr[i].sh_info;
+		if (!(shdr[sec_applies].sh_flags & SHF_ALLOC)) {
+			continue;
+		}
+		sh_symtab = symtab[sec_symtab];
+		sym_strtab = strtab[shdr[sec_symtab].sh_link];
+		if (shdr[i].sh_type == SHT_REL) {
+			sh_type = SHT_REL;
+			nr_entries = shdr[i].sh_size/sizeof(reltab[0][0]);
+		} else {
+			sh_type = SHT_RELA;
+			nr_entries = shdr[i].sh_size/sizeof(reltaba[0][0]);
+		}
+
+		for(j = 0; j < nr_entries; j++) {
+			Elf64_Rel *rel;
+			Elf64_Rela *rela;
+			Elf64_Sym *sym;
+			void *relp;
+			unsigned r_type;
+
+			if (sh_type == SHT_REL) {
+				rel = &reltab[i][j];
+				sym = &sh_symtab[ELF64_R_SYM(rel->r_info)];
+				r_type = ELF64_R_TYPE(rel->r_info);
+				relp = rel;
+			} else {
+				rela = &reltaba[i][j];
+				sym = &sh_symtab[ELF64_R_SYM(rela->r_info)];
+				r_type = ELF64_R_TYPE(rela->r_info);
+				relp = rela;
+			}
+			/* Don't visit relocations to absolute symbols */
+			if (sym->st_shndx == SHN_ABS) {
+				continue;
+			}
+			/* PC relative relocations don't need to be adjusted */
+			switch (r_type) {
+				case R_PPC64_ADDR32:
+				case R_PPC64_ADDR16:
+				case R_PPC64_ADDR16_HI:
+				case R_PPC64_ADDR24:
+				case R_PPC64_ADDR64:
+				case R_PPC64_TOC:
+					/* Visit relocations that need to be adjusted */
+					visit(relp, sym, sh_type);
+					break;
+				case R_PPC64_ADDR16_LO:
+				case R_PPC64_REL24:
+				case R_PPC64_REL64:
+				case R_PPC64_TOC16:
+				case R_PPC64_ADDR16_LO_DS:
+				case R_PPC64_ADDR16_HIGHEST:
+				case R_PPC64_ADDR16_HIGHER:
+				case R_PPC64_GOT16_DS:
+				case R_PPC64_TOC16_DS:
+				case R_PPC64_REL14:
+				default:
+					break;
+			}
+		}
+	}
+}
+
+static void count_reloc(void *relp, Elf64_Sym *sym, int sh_type)
+{
+	reloc_count += 1;
+}
+
+static void collect_reloc(void *relp, Elf64_Sym *sym, int sh_type)
+{
+	Elf64_Rel *rel;
+	Elf64_Rela *rela;
+
+	/* Remember the address that needs to be adjusted. */
+	if (sh_type == SHT_REL) {
+		rel = (Elf64_Rel *)relp;
+		relocs[reloc_idx].offset = rel->r_offset;
+		relocs[reloc_idx++].rel_type = ELF64_R_TYPE(rel->r_info);
+	} else {
+		rela = (Elf64_Rela *)relp;
+		relocs[reloc_idx].offset = rela->r_offset;
+		relocs[reloc_idx++].rel_type = ELF64_R_TYPE(rela->r_info);
+	}
+}
+
+static int cmp_relocs(const void *va, const void *vb)
+{
+	const struct reloc_info *a, *b;
+	a = va; b = vb;
+	return (a->rel_type == b->rel_type)? 0 : (a->rel_type > b->rel_type)? 1 : -1;
+}
+
+static void emit_relocs(int as_text)
+{
+	int i;
+	int prev_r_type;
+	/* Count how many relocations I have and allocate space for them. */
+	reloc_count = 0;
+	walk_relocs(count_reloc);
+	relocs = malloc(reloc_count * sizeof(relocs[0]));
+	if (!relocs) {
+		die("malloc of %d entries for relocs failed\n",
+			reloc_count);
+	}
+	/* Collect up the relocations */
+	reloc_idx = 0;
+	walk_relocs(collect_reloc);
+
+	/* Order the relocations for more efficient processing */
+	qsort(relocs, reloc_count, sizeof(relocs[0]), cmp_relocs);
+
+	/* Print the relocations */
+	if (as_text) {
+		/* Print the relocations in a form suitable that
+		 * gas will like.
+		 */
+		printf(".section \".data.reloc\",\"a\"\n");
+		printf(".balign 4\n");
+
+		printf("\t .long 0x%016llx\n", relocs[0].offset);
+		prev_r_type = relocs[0].rel_type;
+
+		for(i = 1; i < reloc_count; i++) {
+			if (prev_r_type != relocs[i].rel_type && prev_r_type == R_PPC64_ADDR16_HI) {
+				printf("\t .long 0xffffffffffffffff\n");
+				prev_r_type = relocs[i].rel_type;
+			}
+			printf("\t .long 0x%016llx\n", relocs[i].offset);
+		}
+		printf("\n");
+	}
+	else {
+		unsigned char buf[8];
+		buf[0] = buf[1] = buf[2] = buf[3] = 0;
+		buf[4] = buf[5] = buf[6] = buf[7] = 0;
+
+		/* Print a stop */
+		printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]);
+		printf("%c%c%c%c", buf[4], buf[5], buf[6], buf[7]);
+
+		buf[7] = (relocs[0].offset >>  0) & 0xff;
+		buf[6] = (relocs[0].offset >>  8) & 0xff;
+		buf[5] = (relocs[0].offset >> 16) & 0xff;
+		buf[4] = (relocs[0].offset >> 24) & 0xff;
+		buf[3] = (relocs[0].offset >> 32) & 0xff;
+		buf[2] = (relocs[0].offset >> 40) & 0xff;
+		buf[1] = (relocs[0].offset >> 48) & 0xff;
+		buf[0] = (relocs[0].offset >> 56) & 0xff;
+		printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]);
+		printf("%c%c%c%c", buf[4], buf[5], buf[6], buf[7]);
+
+		prev_r_type = relocs[0].rel_type;
+
+		/* Now print each relocation */
+		for(i = 1; i < reloc_count; i++) {
+			if (prev_r_type != relocs[i].rel_type && prev_r_type == R_PPC64_ADDR16_HI) {
+				printf("%c%c%c%c", 0xff, 0xff, 0xff, 0xff);
+				printf("%c%c%c%c", 0xff, 0xff, 0xff, 0xff);
+				prev_r_type = relocs[i].rel_type;
+			}
+			buf[7] = (relocs[i].offset >>  0) & 0xff;
+			buf[6] = (relocs[i].offset >>  8) & 0xff;
+			buf[5] = (relocs[i].offset >> 16) & 0xff;
+			buf[4] = (relocs[i].offset >> 24) & 0xff;
+			buf[3] = (relocs[i].offset >> 32) & 0xff;
+			buf[2] = (relocs[i].offset >> 40) & 0xff;
+			buf[1] = (relocs[i].offset >> 48) & 0xff;
+			buf[0] = (relocs[i].offset >> 56) & 0xff;
+			printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]);
+			printf("%c%c%c%c", buf[4], buf[5], buf[6], buf[7]);
+		}
+		buf[0] = buf[1] = buf[2] = buf[3] = 0;
+		buf[4] = buf[5] = buf[6] = buf[7] = 0;
+	}
+}
+
+static void usage(void)
+{
+	die("relocs [--abs-syms |--abs-relocs | --text] vmlinux\n");
+}
+
+int main(int argc, char **argv)
+{
+	int show_absolute_syms, show_absolute_relocs;
+	int as_text;
+	const char *fname;
+	FILE *fp;
+	int i;
+
+	show_absolute_syms = 0;
+	show_absolute_relocs = 0;
+	as_text = 0;
+	fname = NULL;
+	for(i = 1; i < argc; i++) {
+		char *arg = argv[i];
+		if (*arg == '-') {
+			if (strcmp(argv[1], "--abs-syms") == 0) {
+				show_absolute_syms = 1;
+				continue;
+			}
+
+			if (strcmp(argv[1], "--abs-relocs") == 0) {
+				show_absolute_relocs = 1;
+				continue;
+			}
+			else if (strcmp(argv[1], "--text") == 0) {
+				as_text = 1;
+				continue;
+			}
+		}
+		else if (!fname) {
+			fname = arg;
+			continue;
+		}
+		usage();
+	}
+	if (!fname) {
+		usage();
+	}
+	fp = fopen(fname, "r");
+	if (!fp) {
+		die("Cannot open %s: %s\n",
+			fname, strerror(errno));
+	}
+	read_ehdr(fp);
+	read_shdrs(fp);
+	read_strtabs(fp);
+	read_symtabs(fp);
+	read_relocs(fp);
+	if (show_absolute_syms) {
+		print_absolute_symbols();
+		return 0;
+	}
+	if (show_absolute_relocs) {
+		print_absolute_relocs();
+		return 0;
+	}
+	emit_relocs(as_text);
+	return 0;
+}
-- 
1.5.4


^ permalink raw reply related

* USB-to-ehternet adapter needed...
From: Mike Timmons @ 2008-07-21 19:02 UTC (permalink / raw)
  To: linuxppc-embedded

[-- Attachment #1: Type: text/plain, Size: 350 bytes --]

I'm running kernel 2.6.24 on mpc5200.  I need a network interface over
the USB port.

 

Looking at the kernel; menuconfig I'm not sure if I have what I need to
get a USB-to-ethernet adapter working.

 

Can anyone advise me on what driver(s) to build, and what brand
USB-to-ethernet adapter I should buy?

 

Thanks!

-Mike

 


[-- Attachment #2: Type: text/html, Size: 2457 bytes --]

^ permalink raw reply

* [PATCH v4] elf loader support for auxvec base platform string
From: Nathan Lynch @ 2008-07-21 18:48 UTC (permalink / raw)
  To: Andrew Morton; +Cc: John Reiser, linux-kernel, linuxppc-dev, torvalds, roland
In-Reply-To: <20080717154218.8981035c.akpm@linux-foundation.org>

Some IBM POWER-based platforms have the ability to run in a
mode which mostly appears to the OS as a different processor from the
actual hardware.  For example, a Power6 system may appear to be a
Power5+, which makes the AT_PLATFORM value "power5+".  This means that
programs are restricted to the ISA supported by Power5+;
Power6-specific instructions are treated as illegal.

However, some applications (virtual machines, optimized libraries) can
benefit from knowledge of the underlying CPU model.  A new aux vector
entry, AT_BASE_PLATFORM, will denote the actual hardware.  For
example, on a Power6 system in Power5+ compatibility mode, AT_PLATFORM
will be "power5+" and AT_BASE_PLATFORM will be "power6".  The idea is
that AT_PLATFORM indicates the instruction set supported, while
AT_BASE_PLATFORM indicates the underlying microarchitecture.

If the architecture has defined ELF_BASE_PLATFORM, copy that value to
the user stack in the same manner as ELF_PLATFORM.

Signed-off-by: Nathan Lynch <ntl@pobox.com>

---

Andrew Morton wrote:
> OK.
> 
> But it conflicts directly with the already-queued
> execve-filename-document-and-export-via-auxiliary-vector.patch (which
> various potential reviewers blithely deleted - don't come complaining
> to me!):
> 

Rebased to -mm to resolve conflicts with
execve-filename-document-and-export-via-auxiliary-vector.patch, and
changed AT_BASE_PLATFORM to lowest unclaimed value (24).


 fs/binfmt_elf.c        |   28 ++++++++++++++++++++++++++++
 include/linux/auxvec.h |    6 +++++-
 2 files changed, 33 insertions(+), 1 deletions(-)

diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index bad7d87..180f92b 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -131,6 +131,15 @@ static int padzero(unsigned long elf_bss)
 #define STACK_ALLOC(sp, len) ({ sp -= len ; sp; })
 #endif
 
+#ifndef ELF_BASE_PLATFORM
+/*
+ * AT_BASE_PLATFORM indicates the "real" hardware/microarchitecture.
+ * If the arch defines ELF_BASE_PLATFORM (in asm/elf.h), the value
+ * will be copied to the user stack in the same manner as AT_PLATFORM.
+ */
+#define ELF_BASE_PLATFORM NULL
+#endif
+
 static int
 create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
 		unsigned long load_addr, unsigned long interp_load_addr)
@@ -142,7 +151,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
 	elf_addr_t __user *envp;
 	elf_addr_t __user *sp;
 	elf_addr_t __user *u_platform;
+	elf_addr_t __user *u_base_platform;
 	const char *k_platform = ELF_PLATFORM;
+	const char *k_base_platform = ELF_BASE_PLATFORM;
 	int items;
 	elf_addr_t *elf_info;
 	int ei_index = 0;
@@ -172,6 +183,19 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
 			return -EFAULT;
 	}
 
+	/*
+	 * If this architecture has a "base" platform capability
+	 * string, copy it to userspace.
+	 */
+	u_base_platform = NULL;
+	if (k_base_platform) {
+		size_t len = strlen(k_base_platform) + 1;
+
+		u_base_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);
+		if (__copy_to_user(u_base_platform, k_base_platform, len))
+			return -EFAULT;
+	}
+
 	/* Create the ELF interpreter info */
 	elf_info = (elf_addr_t *)current->mm->saved_auxv;
 	/* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */
@@ -209,6 +233,10 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
 		NEW_AUX_ENT(AT_PLATFORM,
 			    (elf_addr_t)(unsigned long)u_platform);
 	}
+	if (k_base_platform) {
+		NEW_AUX_ENT(AT_BASE_PLATFORM,
+			    (elf_addr_t)(unsigned long)u_base_platform);
+	}
 	if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) {
 		NEW_AUX_ENT(AT_EXECFD, bprm->interp_data);
 	}
diff --git a/include/linux/auxvec.h b/include/linux/auxvec.h
index 0da17d1..d7afa9d 100644
--- a/include/linux/auxvec.h
+++ b/include/linux/auxvec.h
@@ -26,9 +26,13 @@
 
 #define AT_SECURE 23   /* secure mode boolean */
 
+#define AT_BASE_PLATFORM 24	/* string identifying real platform, may
+				 * differ from AT_PLATFORM. */
+
 #define AT_EXECFN  31	/* filename of program */
+
 #ifdef __KERNEL__
-#define AT_VECTOR_SIZE_BASE 17 /* NEW_AUX_ENT entries in auxiliary table */
+#define AT_VECTOR_SIZE_BASE 18 /* NEW_AUX_ENT entries in auxiliary table */
   /* number of "#define AT_.*" above, minus {AT_NULL, AT_IGNORE, AT_NOTELF} */
 #endif
 
-- 
1.5.6.2

^ permalink raw reply related

* Re: PIXIS gpio controller and gpio flags
From: Anton Vorontsov @ 2008-07-21 17:53 UTC (permalink / raw)
  To: Trent Piepho; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <Pine.LNX.4.64.0807191352040.27586@t2.domain.actdsltmp>

On Sat, Jul 19, 2008 at 02:08:01PM -0700, Trent Piepho wrote:
> On Fri, 18 Jul 2008, Anton Vorontsov wrote:
> > +int px_gpio_xlate(struct of_gpio_chip *of_gc, struct device_node *np,
> > +               const void *gpio_spec)
> > +{
> > +     if (gpio[1] & PX_GPIO_FLAG_ACTIVE_LOW)
> > +             px_gc->active_low |= pin2mask(*gpio);
> 
> You have a race here.  What if px_gpio_xlate() is called at the same time
> for different gpios?  This is an easy one to fix, since you can use the
> atomic bitops.

Thanks, I'll fix this. But I think spinlock would be less cryptic here,
since we have one, and the xlate is called quite rarely anyway.

> It doesn't look like you have any way to unset the active low flag.  What if
> I unload the leds-gpio driver (or another gpio user) and then try to use the
> gpio with something else?  The active low flag is stuck on!

Why would you want to unset the flags? It is specified in the device
tree, and can't be changed. Specifying different flags for the same GPIO
would be an error (plus, Linux forbids shared gpios, so you simply can't
specify one gpio for several devices).

> It doesn't show
> in sysfs or debugfs either.  That could be very confusing.

It is in the /proc/device-tree. But I agree, it would be great if
/sys/debug/gpio would show active-low gpios. But this would need gpiolib
changes, with which David will not agree, I suppose. But I didn't try.

> I also wonder if it's ok to have the xlate function do flag setting?

Why not? Of course, we can implement of_gpio_is_active_low(device_node,
gpion), but this is just less convenient than handling active-low gpios
transparently (i.e. for pure OF drivers you don't have to do all
this if (active_low) in the drivers themselves).

> of_get_property() just gets the property, it doesn't allocate it.  Same with
> of_get_address() and of_get_pci_address(), they don't actually allocate or
> map an address, they just get the value.  of_get_gpio() doesn't allocate the
> gpio, that gets done later with gpio_request().  It seems like what it's
> supposed to do is just get the translated value of the gpio property.

Yes, it translates gpio value, and its flags, it also "caches" the flag
so that further gpio_ calls could use it. But the flags for the
particular gpio is constant. So each xlate must end up with the same
active-low flag, otherwise you did something wrong.

> Except, your pixis gpio xlate function sets the gpio's flags.  What if one
> wants to just look up a gpio number, but not allocate it?  The flags will
> still get set.

Nothing is allocated.

> Most gpio users, including leds-gpio, can handle gpios being busy.  If
> leds-gpio can't get one of the gpios, it rolls back all the leds it did
> create, doesn't drive the device and returns EBUSY.  Except with
> of_get_gpio() setting the flags, it will change the flags out from under
> whatever had the gpio already allocated!

You're still assuming that something was allocated. It wasn't. The flag
was set, and it should not change. It is irrelevant if request() failed
or not.

Thanks,

-- 
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2

^ permalink raw reply

* Re: Networkl problems with lastest kernel....
From: Sean MacLennan @ 2008-07-21 17:37 UTC (permalink / raw)
  To: David Miller; +Cc: linuxppc-dev
In-Reply-To: <20080721.101650.181903456.davem@davemloft.net>

On Mon, 21 Jul 2008 10:16:50 -0700 (PDT)
"David Miller" <davem@davemloft.net> wrote:

> The same problem is still there, this driver will
> unfortunately require quite a bit more surgery.
> 
> You can instead add the following patch, it will
> warn instead of BUG on you, and try to continue.

Ok, that lets me boot. Thanks.

Cheers,
   Sean

^ permalink raw reply

* Re: Networkl problems with lastest kernel....
From: David Miller @ 2008-07-21 17:16 UTC (permalink / raw)
  To: smaclennan; +Cc: linuxppc-dev
In-Reply-To: <20080721130536.3ca72f3e@lappy.seanm.ca>

From: Sean MacLennan <smaclennan@pikatech.com>
Date: Mon, 21 Jul 2008 13:05:36 -0400

> But I have attached the new OOPS anyway.

The same problem is still there, this driver will
unfortunately require quite a bit more surgery.

You can instead add the following patch, it will
warn instead of BUG on you, and try to continue.

>From 867d79fb9a4d5929ad8335c896fcfe11c3b2ef14 Mon Sep 17 00:00:00 2001
From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Mon, 21 Jul 2008 09:54:18 -0700
Subject: [PATCH] net: In __netif_schedule() use WARN_ON instead of BUG_ON

Signed-off-by: David S. Miller <davem@davemloft.net>
---
 net/core/dev.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 7e2d527..cbc34c0 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1327,7 +1327,8 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 
 void __netif_schedule(struct Qdisc *q)
 {
-	BUG_ON(q == &noop_qdisc);
+	if (WARN_ON_ONCE(q == &noop_qdisc))
+		return;
 
 	if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state)) {
 		struct softnet_data *sd;
-- 
1.5.6.4.433.g09651

^ permalink raw reply related

* Re: [RFC] 4xx hardware watchpoint support
From: Josh Boyer @ 2008-07-21 17:05 UTC (permalink / raw)
  To: luisgpm; +Cc: ppc-dev, Paul Mackerras
In-Reply-To: <1216658194.5727.36.camel@gargoyle>

On Mon, 21 Jul 2008 13:36:33 -0300
Luis Machado <luisgpm@linux.vnet.ibm.com> wrote:

> 
> > This doesn't look right for how it's coded.  This would be the
> > CONFIG_4xx || CONFIG_BOOKE case, but CONFIG_4xx includes PowerPC 405.
> > That has a different bit layout among the DBCR registers.  Namely, on
> > 405 you would be clearing the TDE and IAC1 events because the DAC
> > events are in DBCR1, not DBCR0.
> 
> Maybe guarding the 405-specific parts in a separate "#if
> defined(CONFIG_40x)" block will do?

That, or adding a small function to move the bits to the appropriate
registers (set_dbcr or set_dac_events).

> Do you think it's worth to support this facility on 405's processors? If
> so, i'll gladly work on a solution to it.

I would think so.  There's really no difference from a userspace
perspective, so gdb watchpoints could be valuable there too.  I'll
leave it up to you though.

josh

^ permalink raw reply

* Re: Networkl problems with lastest kernel....
From: Sean MacLennan @ 2008-07-21 17:05 UTC (permalink / raw)
  To: David Miller; +Cc: linuxppc-dev
In-Reply-To: <20080721.093110.141511905.davem@davemloft.net>

On Mon, 21 Jul 2008 09:31:10 -0700 (PDT)
"David Miller" <davem@davemloft.net> wrote:

> If I had a penny for every driver with broken TX queue handling...
> 
> Please try this patch, thanks:
> 
> diff --git a/drivers/net/ibm_newemac/core.c
> b/drivers/net/ibm_newemac/core.c index 2e720f2..4e01d29 100644
> --- a/drivers/net/ibm_newemac/core.c
> +++ b/drivers/net/ibm_newemac/core.c
> @@ -1157,6 +1157,7 @@ static int emac_open(struct net_device *ndev)
>  	mal_enable_rx_channel(dev->mal, dev->mal_rx_chan);
>  	emac_tx_enable(dev);
>  	emac_rx_enable(dev);
> +	netif_start_queue(dev);
>  	emac_netif_start(dev);

I had to change the dev to an ndev. dev is an struct emac_instance and
ndev is the struct net_device.

It still crashes, but in a different way. I think the problem is deeper
than I thought. The kernel has been OOPSing on a reboot in the
nfs_remount or there abouts for a few days. I thought the problem was
in a debug driver I was using... so I ignored it for now.

But it does it without the debug driver.... so I think I have a
corruption somewhere in the kernel.

But I have attached the new OOPS anyway.

Cheers,
  Sean

------------[ cut here ]------------
Kernel BUG at c01ba66c [verbose debug info unavailable]
Oops: Exception in kernel mode, sig: 5 [#1]
Warp
Modules linked in:
NIP: c01ba66c LR: c015da58 CTR: 00000000
REGS: cf839e90 TRAP: 0700   Not tainted  (2.6.26-pika)
MSR: 00029000 <EE,ME>  CR: 44000042  XER: 0000005f
TASK = cf81e880[5] 'events/0' THREAD: cf838000
GPR00: 00000000 cf839f40 cf81e880 c02fd5a8 cf97856a 00000002 00000002
ffffffff GPR08: c02fd5a8 00000001 00000000 00000001 24000048 00000000
0ffac000 007fff9c GPR16: 00400684 00800000 007fff00 0ffa93c4 00000002
c02e95f8 c02f0000 c02e95f8 GPR24: c02f0000 00000000 c0030000 cf984404
cf9843d0 cf984000 cf984380 cf984000 NIP [c01ba66c]
__netif_schedule+0x28/0x84 LR [c015da58] emac_link_timer+0x704/0x754
Call Trace:
[cf839f40] [c015c9f4] __emac_set_multicast_list+0x5c/0xb0 (unreliable)
[cf839f60] [c015da58] emac_link_timer+0x704/0x754
[cf839f80] [c002db54] run_workqueue+0x9c/0x138
[cf839fa0] [c002df54] worker_thread+0x50/0xb4
[cf839fd0] [c0031424] kthread+0x84/0x8c
[cf839ff0] [c000c518] kernel_thread+0x48/0x64
Instruction dump:
4e800020 4bfffe48 7c0802a6 3d60c030 9421ffe0 396bd5a8 90010024 bfa10014 
7c681b78 7c6b5a78 200b0000 7d605914 <0f0b0000> 39200002 38030024
7d600028 ---[ end trace 3e8d5079b3c922db ]---

^ permalink raw reply

* RE: [HOW] binutils-2.17 breaks the 2.6.26 kernel
From: Rune Torgersen @ 2008-07-21 16:49 UTC (permalink / raw)
  To: Segher Boessenkool, Jon Smirl; +Cc: ppcdev, Milton Miller
In-Reply-To: <3400bffa9d49e09b00e04cafcd751322@kernel.crashing.org>

> From: Segher Boessenkool
> > Previous threads have mentioned that binutil-2.17 is broken for
> > building powerpc kernels. It is fixed in binutils-2.18.
>=20
> I have a working (tested! thanks Milton) workaround for the current
> problem, will send it later today.  This problem funnily is hidden
> by the presence of build-id :-)

Did you ever send this patch? I'd like to try it as I cannot compile a
arch/powerpc 2.6.265 kernel right now.

^ permalink raw reply

* Re: [PATCH] Don't panic when EEH_MAX_FAILS is exceeded
From: Mike Mason @ 2008-07-21 16:40 UTC (permalink / raw)
  To: paulus, benh, linasvepstas, linuxppc-dev
In-Reply-To: <488383D4.9000602@us.ibm.com>

Here's a repost of the patch with the suggested changes.

This patch changes the EEH_MAX_FAILS action from panic to printing an 
error message.  Panicking under under this condition is too harsh.  
Although performance will be affected and the device may not recover, 
the system is still running, which at the very least should allow for a 
more graceful shutdown. The patch also removes the msleep() within a 
spinlock, which can lead to a deadlock and is not recommended.

Signed-off-by: Mike Mason <mmlnx@us.ibm.com>
Acked-by: Linas Vepstas <linasvepstas@gmail.com>

--- powerpc.git/arch/powerpc/platforms/pseries/eeh.c	2008-07-18 08:51:42.000000000 -0700
+++ powerpc.git-new/arch/powerpc/platforms/pseries/eeh.c	2008-07-21 03:25:43.000000000 -0700
@@ -75,9 +75,9 @@
  */
 
 /* If a device driver keeps reading an MMIO register in an interrupt
- * handler after a slot isolation event has occurred, we assume it
- * is broken and panic.  This sets the threshold for how many read
- * attempts we allow before panicking.
+ * handler after a slot isolation event, it might be broken.
+ * This sets the threshold for how many read attempts we allow
+ * before printing an error message.
  */
 #define EEH_MAX_FAILS	2100000
 
@@ -470,6 +470,7 @@ int eeh_dn_check_failure(struct device_n
 	unsigned long flags;
 	struct pci_dn *pdn;
 	int rc = 0;
+	const char *location;
 
 	total_mmio_ffs++;
 
@@ -509,18 +510,15 @@ int eeh_dn_check_failure(struct device_n
 	rc = 1;
 	if (pdn->eeh_mode & EEH_MODE_ISOLATED) {
 		pdn->eeh_check_count ++;
-		if (pdn->eeh_check_count >= EEH_MAX_FAILS) {
-			printk (KERN_ERR "EEH: Device driver ignored %d bad reads, panicing\n",
-			        pdn->eeh_check_count);
+		if (pdn->eeh_check_count % EEH_MAX_FAILS == 0) {
+			location = of_get_property(dn, "ibm,loc-code", NULL);
+			printk (KERN_ERR "EEH: %d reads ignored for recovering device at "
+				"location=%s driver=%s pci addr=%s\n",
+				pdn->eeh_check_count, location,
+				dev->driver->name, pci_name(dev));
+			printk (KERN_ERR "EEH: Might be infinite loop in %s driver\n",
+				dev->driver->name);
 			dump_stack();
-			msleep(5000);
-			
-			/* re-read the slot reset state */
-			if (read_slot_reset_state(pdn, rets) != 0)
-				rets[0] = -1;	/* reset state unknown */
-
-			/* If we are here, then we hit an infinite loop. Stop. */
-			panic("EEH: MMIO halt (%d) on device:%s\n", rets[0], pci_name(dev));
 		}
 		goto dn_unlock;
 	}

^ permalink raw reply

* Re: [RFC] 4xx hardware watchpoint support
From: Luis Machado @ 2008-07-21 16:36 UTC (permalink / raw)
  To: Josh Boyer; +Cc: ppc-dev, Paul Mackerras
In-Reply-To: <20080719093752.5aada45c@zod.rchland.ibm.com>


> This doesn't look right for how it's coded.  This would be the
> CONFIG_4xx || CONFIG_BOOKE case, but CONFIG_4xx includes PowerPC 405.
> That has a different bit layout among the DBCR registers.  Namely, on
> 405 you would be clearing the TDE and IAC1 events because the DAC
> events are in DBCR1, not DBCR0.

Maybe guarding the 405-specific parts in a separate "#if
defined(CONFIG_40x)" block will do?

Do you think it's worth to support this facility on 405's processors? If
so, i'll gladly work on a solution to it.

Regards,
Luis

^ permalink raw reply

* Re: [PATCH 2/2] IB/ehca: Default value for Local CA ACK Delay
From: Roland Dreier @ 2008-07-21 16:34 UTC (permalink / raw)
  To: Joachim Fenkes
  Cc: LKML, OF-EWG, LinuxPPC-Dev, Christoph Raisch, OF-General,
	Alexander Schmidt, Stefan Roscher
In-Reply-To: <200807211316.37224.fenkes@de.ibm.com>

thanks, applied 1 and 2

^ permalink raw reply

* Re: Networkl problems with lastest kernel....
From: David Miller @ 2008-07-21 16:31 UTC (permalink / raw)
  To: smaclennan; +Cc: linuxppc-dev
In-Reply-To: <20080721121829.28faffab@lappy.seanm.ca>

From: Sean MacLennan <smaclennan@pikatech.com>
Date: Mon, 21 Jul 2008 12:18:29 -0400

> I just did a git pull of Linus' kernel. It seems to be mainly network
> changes... and I get the following oops. Anybody else seeing this?
> 
> I really don't have time to look at the problem right now, maybe
> tonight.

If I had a penny for every driver with broken TX queue handling...

Please try this patch, thanks:

diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 2e720f2..4e01d29 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -1157,6 +1157,7 @@ static int emac_open(struct net_device *ndev)
 	mal_enable_rx_channel(dev->mal, dev->mal_rx_chan);
 	emac_tx_enable(dev);
 	emac_rx_enable(dev);
+	netif_start_queue(dev);
 	emac_netif_start(dev);
 
 	mutex_unlock(&dev->link_lock);

^ permalink raw reply related

* Networkl problems with lastest kernel....
From: Sean MacLennan @ 2008-07-21 16:18 UTC (permalink / raw)
  To: linuxppc-dev

I just did a git pull of Linus' kernel. It seems to be mainly network
changes... and I get the following oops. Anybody else seeing this?

I really don't have time to look at the problem right now, maybe
tonight.

Cheers,
   Sean

------------[ cut here ]------------
Kernel BUG at c01ba650 [verbose debug info unavailable]
Oops: Exception in kernel mode, sig: 5 [#1]
Warp
Modules linked in:
NIP: c01ba650 LR: c015e240 CTR: c0011f84
REGS: cf821d60 TRAP: 0700   Not tainted  (2.6.26-pika)
MSR: 00029000 <EE,ME>  CR: 44000082  XER: 0000005f
TASK = cf81f900[1] 'swapper' THREAD: cf820000
GPR00: 00000000 cf821e10 cf81f900 c02fd5a8 80000000 c0010684 00000000
ffffffff GPR08: c02fd5a8 00000001 00000000 00000001 24000028 00000000
00000004 c02a0000 GPR16: 00400684 00800000 c02e0000 c0270000 c02e0000
c02e0000 c03206c0 00000001 GPR24: c02e0000 cf984000 cf984438 cf984380
00029000 00000000 cf9843d0 cf984000 NIP [c01ba650]
__netif_schedule+0x28/0x84 LR [c015e240] emac_open+0x3d8/0x470
Call Trace:
[cf821e10] [cf984000] 0xcf984000 (unreliable)
[cf821e30] [c015e240] emac_open+0x3d8/0x470
[cf821e60] [c01bc2b4] dev_open+0xa8/0x118
[cf821e80] [c01bc1b4] dev_change_flags+0x168/0x1c0
[cf821ea0] [c02d3e48] ip_auto_config+0x19c/0xecc
[cf821f60] [c02ba83c] kernel_init+0x84/0x274
[cf821ff0] [c000c518] kernel_thread+0x48/0x64
Instruction dump:
4e800020 4bfffe48 7c0802a6 3d60c030 9421ffe0 396bd5a8 90010024 bfa10014 
7c681b78 7c6b5a78 200b0000 7d605914 <0f0b0000> 39200002 38030024
7d600028 ---[ end trace be4338b61948e802 ]---

^ permalink raw reply

* [PATCH] Remove fsl-soc.c from mpc5200 build, it is not needed.
From: Jon Smirl @ 2008-07-20 15:30 UTC (permalink / raw)
  To: linuxppc-dev

Remove fsl-soc.c from mpc5200 build, it is not needed.

Signed-off-by: Jon Smirl <jonsmirl@gmail.com>
---

 arch/powerpc/platforms/52xx/Kconfig |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/52xx/Kconfig b/arch/powerpc/platforms/52xx/Kconfig
index e91a0d2..76a3411 100644
--- a/arch/powerpc/platforms/52xx/Kconfig
+++ b/arch/powerpc/platforms/52xx/Kconfig
@@ -1,7 +1,6 @@
 config PPC_MPC52xx
 	bool "52xx-based boards"
 	depends on PPC_MULTIPLATFORM && PPC32
-	select FSL_SOC
 	select PPC_CLOCK
 
 config PPC_MPC5200_SIMPLE

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox