* 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
* Re: [PATCH] powerpc/ep8248e: Fix compile problem if !CONFIG_FS_ENET
From: Scott Wood @ 2008-07-21 16:14 UTC (permalink / raw)
To: Kumar Gala; +Cc: Dave Jones, akpm, torvalds, linux-kernel, linuxppc-dev
In-Reply-To: <BB883309-0856-4371-BFC3-68E2F54B5B29@kernel.crashing.org>
On Wed, Jul 16, 2008 at 05:55:17PM -0500, Kumar Gala wrote:
> It looks like the simplest solution at this point is to unconditionally
> select the PHYLIB for this board. We should look at moving the low level
> mdio bitbang ops out so they can be built as a module.
Or exporting the MDIO/MDC pins through the GPIO API.
-Scott
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox