LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* RE: Loading Linux from already running code..
From: Sumesh Kaana @ 2011-09-27  6:51 UTC (permalink / raw)
  To: p.ittershagen, cmunoz; +Cc: linuxppc-dev
In-Reply-To: <CAC157GAaqdNVQf9hycEVft3cgpbVWxOwncBSNwfVFBGQugZjpQ@mail.gmail.com>

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


Hi Philipp and Carlos,

Thanks for the reply.

When simpleImage.elf is loaded by a debugger, the debugger reads the elf image header and places various sections of image into right place in the RAM. But when I do it from already_running_code, I should manually unpack the elf and place the sections in the memory, then jump to the start address, Am I right?

Also,
Is it possible to load a simpleImage.bin file and jump to the start address using a function pointer, Hence I can avoid unpack_elf_image()...? - Will this work?


Thanks,
Sumesh.



> Date: Mon, 26 Sep 2011 20:13:24 +0200
> Subject: Re: Loading Linux from already running code..
> From: p.ittershagen@googlemail.com
> To: cmunoz@sablenetworks.com
> CC: linuxppc-dev@lists.ozlabs.org; sumeshkkn@hotmail.com
> 
> On Mon, Sep 26, 2011 at 7:26 PM, Carlos Munoz <cmunoz@sablenetworks.com> wrote:
> > You could build a tarball containing the root files system, dtb, Linux,
> > plus a header indicating where the different pieces need to be loaded.
> > Then your initial code loads the different parts at the right memory
> > locations, sets up the Linux arguments, and jumps to Linux.
> 
> That is exactly what the firmware-independent simpleImage.initrd.*
> targets already do. The resulting elf file include the dtb and initrd
> as well as a prompt-like boot arg cli.
> I think it will be possible to just place the simpleImage.initrd.*
> into you memory and let the existing code jump to the start adress of
> the elf image. I managed to start a ppc core using JTAG and the
> simpleImage.initrd elf files and I think the procedure is very much
> the same but instead of the JTAG debugger setting the PC to the start
> address, your startup code has to do it.
> 
> 
> Philipp
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
 		 	   		  

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

^ permalink raw reply

* [PATCH v2] powerpc/ptrace: Fix build with gcc 4.6
From: Benjamin Herrenschmidt @ 2011-09-27  5:37 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1317096746.29415.42.camel@pasglop>

gcc (rightfully) complains that we are accessing beyond the
end of the fpr array (we do, to access the fpscr).

The only sane thing to do (whether anything in that code can be
called remotely sane is debatable) is to special case fpscr and
handle it as a separate statement.

I initially tried to do it it by making the array access conditional
to index < PT_FPSCR and using a 3rd else leg but for some reason gcc
was unable to understand it and still spewed the warning.

So I ended up with something a tad more intricated but it seems to
build on 32-bit and on 64-bit with and without VSX.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

I very much welcome a few more pairs of eyes on this one in case I
missed something, this code sucks. It took me a good 15mn to figure
out that it was actually correct to begin with (hint: look at the
definition of PT_FPSCR on 32-bit, don't miss the *2 in there).

v2. Allow setting the fpscr (thanks Stephen)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index cb22024..9321d0f 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1497,9 +1497,14 @@ long arch_ptrace(struct task_struct *child, long request,
 		if (index < PT_FPR0) {
 			tmp = ptrace_get_reg(child, (int) index);
 		} else {
+			unsigned int fpidx = index - PT_FPR0;
+
 			flush_fp_to_thread(child);
-			tmp = ((unsigned long *)child->thread.fpr)
-				[TS_FPRWIDTH * (index - PT_FPR0)];
+			if (fpidx < (PT_FPSCR - PT_FPR0))
+				tmp = ((unsigned long *)child->thread.fpr)
+					[fpidx * TS_FPRWIDTH];
+			else
+				tmp = child->thread.fpscr.val;
 		}
 		ret = put_user(tmp, datalp);
 		break;
@@ -1525,9 +1530,14 @@ long arch_ptrace(struct task_struct *child, long request,
 		if (index < PT_FPR0) {
 			ret = ptrace_put_reg(child, index, data);
 		} else {
+			unsigned int fpidx = index - PT_FPR0;
+
 			flush_fp_to_thread(child);
-			((unsigned long *)child->thread.fpr)
-				[TS_FPRWIDTH * (index - PT_FPR0)] = data;
+			if (fpidx < (PT_FPSCR - PT_FPR0))
+				((unsigned long *)child->thread.fpr)
+					[fpidx * TS_FPRWIDTH] = data;
+			else
+				child->thread.fpscr.val = data;
 			ret = 0;
 		}
 		break;

^ permalink raw reply related

* [PATCH] powerpc/ptrace: Fix build with gcc 4.6
From: Benjamin Herrenschmidt @ 2011-09-27  4:12 UTC (permalink / raw)
  To: linuxppc-dev

gcc (rightfully) complains that we are accessing beyond the
end of the fpr array (we do, to access the fpscr).

The only sane thing to do (whether anything in that code can be
called remotely sane is debatable) is to special case fpscr and
handle it as a separate statement.

I initially tried to do it it by making the array access conditional
to index < PT_FPSCR and using a 3rd else leg but for some reason gcc
was unable to understand it and still spewed the warning.

So I ended up with something a tad more intricated but it seems to
build on 32-bit and on 64-bit with and without VSX.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

I very much welcome a few more pairs of eyes on this one in case I
missed something, this code sucks. It took me a good 15mn to figure
out that it was actually correct to begin with (hint: look at the
definition of PT_FPSCR on 32-bit, don't miss the *2 in there).
 
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 05b7dd2..adf4d73 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1497,9 +1497,14 @@ long arch_ptrace(struct task_struct *child, long request,
 		if (index < PT_FPR0) {
 			tmp = ptrace_get_reg(child, (int) index);
 		} else {
+			unsigned int fpidx = index - PT_FPR0;
+
 			flush_fp_to_thread(child);
-			tmp = ((unsigned long *)child->thread.fpr)
-				[TS_FPRWIDTH * (index - PT_FPR0)];
+			if (fpidx < (PT_FPSCR - PT_FPR0))
+				tmp = ((unsigned long *)child->thread.fpr)
+					[fpidx * TS_FPRWIDTH];
+			else
+				tmp = child->thread.fpscr.val;
 		}
 		ret = put_user(tmp, datalp);
 		break;
@@ -1525,9 +1530,12 @@ long arch_ptrace(struct task_struct *child, long request,
 		if (index < PT_FPR0) {
 			ret = ptrace_put_reg(child, index, data);
 		} else {
+			unsigned int fpidx = index - PT_FPR0;
+
 			flush_fp_to_thread(child);
-			((unsigned long *)child->thread.fpr)
-				[TS_FPRWIDTH * (index - PT_FPR0)] = data;
+			if (fpidx < (PT_FPSCR - PT_FPR0))
+				((unsigned long *)child->thread.fpr)
+					[fpidx * TS_FPRWIDTH] = data;
 			ret = 0;
 		}
 		break;

^ permalink raw reply related

* Re: [PATCH] powerpc/85xx: fix PHYS_64BIT selection for P1022DS
From: Scott Wood @ 2011-09-26 22:24 UTC (permalink / raw)
  To: Kumar Gala
  Cc: linuxppc-dev@lists.ozlabs.org, Anatolij Gustschin,
	Tabi Timur-B04825
In-Reply-To: <FAF4E48A-0966-4A6E-8D31-B30D07CB0746@kernel.crashing.org>

On 09/26/2011 05:12 PM, Kumar Gala wrote:
> 
> On Sep 25, 2011, at 12:06 PM, Tabi Timur-B04825 wrote:
> 
>> On Fri, Sep 23, 2011 at 2:32 PM, Anatolij Gustschin <agust@denx.de> wrote:
>>
>>> diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
>>> index 1b393f4..b29d4f2 100644
>>> --- a/arch/powerpc/platforms/85xx/Kconfig
>>> +++ b/arch/powerpc/platforms/85xx/Kconfig
>>> @@ -80,7 +80,7 @@ config P1010_RDB
>>>  config P1022_DS
>>>        bool "Freescale P1022 DS"
>>>        select DEFAULT_UIMAGE
>>> -       select CONFIG_PHYS_64BIT        # The DTS has 36-bit addresses
>>> +       select PHYS_64BIT       # The DTS has 36-bit addresses
>>
>> I have no idea how this happened, but I wonder if it's a good idea.
>> On the Freescale BSP, the default config for the P1022DS is 32-bit,
>> not 36-bit, so one day we might have a 32-bit config in the upstream
>> repository.
>>
>> PHYS_64BIT is already covered by the defconfig.  I wonder if we should
>> just delete the bad line, and let the defconfig select the address
>> size.
> 
> Why, the way this patch makes it will work both with a 32-bit or 36-bit address map.   The comment should be fixed since its wrong.

"select" should not be used for things that you think make good
defaults.  It should be used for things that are required.  It's just
like "depends on", except for user interface considerations (and the
whole transitive dependency mess).

-Scott

^ permalink raw reply

* Re: [PATCH] powerpc/85xx: fix PHYS_64BIT selection for P1022DS
From: Timur Tabi @ 2011-09-26 22:14 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Anatolij Gustschin, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <FAF4E48A-0966-4A6E-8D31-B30D07CB0746@kernel.crashing.org>

Kumar Gala wrote:
> Why, the way this patch makes it will work both with a 32-bit or 36-bit address map.   The comment should be fixed since its wrong.

I think the BSP team had said that there is a significant performance
improvement in some benchmark when 36-bit support is disabled.  That's why they
like to keep 32-bit and 36-bit environments for both, and why they default to
32-bit.

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply

* Re: [PATCH] powerpc/85xx: fix PHYS_64BIT selection for P1022DS
From: Kumar Gala @ 2011-09-26 22:12 UTC (permalink / raw)
  To: Tabi Timur-B04825; +Cc: Anatolij Gustschin, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <CAOZdJXXw-YMFG4vVbYQKOtDYHtriaXe-=sz6YBivFXbp=mH2PQ@mail.gmail.com>


On Sep 25, 2011, at 12:06 PM, Tabi Timur-B04825 wrote:

> On Fri, Sep 23, 2011 at 2:32 PM, Anatolij Gustschin <agust@denx.de> =
wrote:
>=20
>> diff --git a/arch/powerpc/platforms/85xx/Kconfig =
b/arch/powerpc/platforms/85xx/Kconfig
>> index 1b393f4..b29d4f2 100644
>> --- a/arch/powerpc/platforms/85xx/Kconfig
>> +++ b/arch/powerpc/platforms/85xx/Kconfig
>> @@ -80,7 +80,7 @@ config P1010_RDB
>>  config P1022_DS
>>        bool "Freescale P1022 DS"
>>        select DEFAULT_UIMAGE
>> -       select CONFIG_PHYS_64BIT        # The DTS has 36-bit =
addresses
>> +       select PHYS_64BIT       # The DTS has 36-bit addresses
>=20
> I have no idea how this happened, but I wonder if it's a good idea.
> On the Freescale BSP, the default config for the P1022DS is 32-bit,
> not 36-bit, so one day we might have a 32-bit config in the upstream
> repository.
>=20
> PHYS_64BIT is already covered by the defconfig.  I wonder if we should
> just delete the bad line, and let the defconfig select the address
> size.

Why, the way this patch makes it will work both with a 32-bit or 36-bit =
address map.   The comment should be fixed since its wrong.

- k=

^ permalink raw reply

* Re: Loading Linux from already running code..
From: Philipp Ittershagen @ 2011-09-26 18:13 UTC (permalink / raw)
  To: Carlos Munoz; +Cc: linuxppc-dev, Sumesh Kaana
In-Reply-To: <1317058016.1650.50.camel@pug>

On Mon, Sep 26, 2011 at 7:26 PM, Carlos Munoz <cmunoz@sablenetworks.com> wrote:
> You could build a tarball containing the root files system, dtb, Linux,
> plus a header indicating where the different pieces need to be loaded.
> Then your initial code loads the different parts at the right memory
> locations, sets up the Linux arguments, and jumps to Linux.

That is exactly what the firmware-independent simpleImage.initrd.*
targets already do. The resulting elf file include the dtb and initrd
as well as a prompt-like boot arg cli.
I think it will be possible to just place the simpleImage.initrd.*
into you memory and let the existing code jump to the start adress of
the elf image. I managed to start a ppc core using JTAG and the
simpleImage.initrd elf files and I think the procedure is very much
the same but instead of the JTAG debugger setting the PC to the start
address, your startup code has to do it.


Philipp

^ permalink raw reply

* Re: Loading Linux from already running code..
From: Carlos Munoz @ 2011-09-26 17:26 UTC (permalink / raw)
  To: Sumesh Kaana; +Cc: linuxppc-dev
In-Reply-To: <BLU124-W1648A42F7514E880C9B199B4F20@phx.gbl>

You could build a tarball containing the root files system, dtb, Linux,
plus a header indicating where the different pieces need to be loaded.
Then your initial code loads the different parts at the right memory
locations, sets up the Linux arguments, and jumps to Linux.

-Carlos

On Sun, 2011-09-25 at 18:47 +0000, Sumesh Kaana wrote:
> Hi All,
> 
> 
> I need some suggestions for booting Linux( >2.6.30 ) with my new
> project.
> 
> 
> Scenario:
> I've a custom built board with PowerPC 440 + 256 MB RAM. there is NO
> FLASH on this board.
> There is a hardware logic which will get an initial piece of
> code (through hardware network) into the ram and then execute it. This
> code does mandatory initialization of a proprietary chip and this code
> MUST execute on power on. any other images (Linux image or ramdisk)
> can be loaded any specified area in the memory along with this code.
> 
> 
> My requirement is to boot Linux at the end of the this initialization.
> 
> 
> what is the best way to do it? 
> 
> 
> 1. Will it be possible to transfer control to a
> simpleImage.initrd.myboard.elf(or .bin ..?!)  image from
> already_existing_code?
> 2. Should I use u-boot and then load uImage, ramdisk and the dts blob?
> Using u-boot will reduce the effort?
> 3. Is there any other way to approach this??
> 
> 
> 
> 
> 
> 
> Regards,
> Sumesh
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* [PATCH] memory hotplug: Correct page reservation checking
From: Nathan Fontenot @ 2011-09-26 15:22 UTC (permalink / raw)
  To: linuxppc-dev, linux-kernel, Greg KH

The check to ensure that pages of recently added memory sections are correctly
marked as reserved before trying to online the memory is broken.  The request
to online the memory fails with the following:

kernel: section number XXX page number 256 not reserved, was it already online?

This updates the page reservation checking to check the pages of each memory
section of the memory block being onlined individually.

Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
---
 drivers/base/memory.c |   60 ++++++++++++++++++++++++++++++--------------------
 1 file changed, 37 insertions(+), 23 deletions(-)

Index: linux/drivers/base/memory.c
===================================================================
--- linux.orig/drivers/base/memory.c	2011-09-26 08:33:14.000000000 -0500
+++ linux/drivers/base/memory.c	2011-09-26 08:42:14.000000000 -0500
@@ -227,41 +227,42 @@
  * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is
  * OK to have direct references to sparsemem variables in here.
  */
+static int check_page_reservations(unsigned long phys_index)
+{
+	int i;
+	struct page *page;
+
+	page = pfn_to_page(phys_index << PFN_SECTION_SHIFT);
+
+	for (i = 0; i < PAGES_PER_SECTION; i++) {
+		if (PageReserved(page + i))
+			continue;
+
+		printk(KERN_WARNING "section number %ld page number %d "
+			"not reserved, was it already online?\n", phys_index, i);
+			return -EBUSY;
+	}
+
+	return 0;
+}
+
 static int
 memory_block_action(unsigned long phys_index, unsigned long action)
 {
-	int i;
 	unsigned long start_pfn, start_paddr;
 	unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
-	struct page *first_page;
+	struct page *page;
 	int ret;
 
-	first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT);
-
-	/*
-	 * The probe routines leave the pages reserved, just
-	 * as the bootmem code does.  Make sure they're still
-	 * that way.
-	 */
-	if (action == MEM_ONLINE) {
-		for (i = 0; i < nr_pages; i++) {
-			if (PageReserved(first_page+i))
-				continue;
-
-			printk(KERN_WARNING "section number %ld page number %d "
-				"not reserved, was it already online?\n",
-				phys_index, i);
-			return -EBUSY;
-		}
-	}
+	page = pfn_to_page(phys_index << PFN_SECTION_SHIFT);
 
 	switch (action) {
 		case MEM_ONLINE:
-			start_pfn = page_to_pfn(first_page);
+			start_pfn = page_to_pfn(page);
 			ret = online_pages(start_pfn, nr_pages);
 			break;
 		case MEM_OFFLINE:
-			start_paddr = page_to_pfn(first_page) << PAGE_SHIFT;
+			start_paddr = page_to_pfn(page) << PAGE_SHIFT;
 			ret = remove_memory(start_paddr,
 					    nr_pages << PAGE_SHIFT);
 			break;
@@ -277,7 +278,7 @@
 static int memory_block_change_state(struct memory_block *mem,
 		unsigned long to_state, unsigned long from_state_req)
 {
-	int ret = 0;
+	int i, ret = 0;
 
 	mutex_lock(&mem->state_mutex);
 
@@ -289,6 +290,19 @@
 	if (to_state == MEM_OFFLINE)
 		mem->state = MEM_GOING_OFFLINE;
 
+	if (to_state == MEM_ONLINE) {
+		/*
+		 * The probe routines leave the pages reserved, just
+		 * as the bootmem code does.  Make sure they're still
+		 * that way.
+		 */
+		for (i = 0; i < sections_per_block; i++) {
+			ret = check_page_reservations(mem->start_section_nr + i);
+			if (ret)
+				return ret;
+		}
+	}
+
 	ret = memory_block_action(mem->start_section_nr, to_state);
 
 	if (ret)

^ permalink raw reply

* Re: Timer interrupt on Linux 3.0.3
From: Vineeth @ 2011-09-26  9:11 UTC (permalink / raw)
  To: Scott Wood, linuxppc-dev, linux-embedded; +Cc: mohanreddykv
In-Reply-To: <CAEZ9+qnSXXi5w9BbwyaQWQybCtaCsJ0T5j5ySEjOkpnnYmr7aA@mail.gmail.com>

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

Hi,

there's a good news which is pretty bad. Good news is that we identified why
our processor timer not working. its because the TBEN in our board is pulled
LOW. which means the decrementer and the timebase registers wont work.

The board design cannot be changed !!! but we have an MPC107 connected with
our processor. Our plan is to use the timer of MPC107 and register our
timer_interrupt function with this timer interrupt. I think that's the only
workaround left now.

Thanks
Vineeth

On Thu, Sep 22, 2011 at 11:52 AM, MohanReddy koppula <mohanreddykv@gmail.com
> wrote:

> I had the same issue with an MPC885 board. My kernel was 2.6.33. On
> that board decrementer exception was not working. I replaced the
> board, took new board (MPC885 only, just another board) and the same
> kernel worked fine. I don't know how the problem was solved.
>
> -Mohan
>
> On 9/22/11, Scott Wood <scottwood@freescale.com> wrote:
> > On 09/21/2011 01:56 AM, Vineeth wrote:
> >>>> What was the issue?  You really should try to make this work rather
> than
> >>>> hack around it.
> >>
> >> what we found was the decrementer is not generating an exception when it
> >> becomes 0. and the timebase registers are not getting incremented too.
> >
> > Does the decrementer actually tick until it reaches zero, or do it and
> > the timebase never tick?
> >
> > Is the TBEN input to the CPU asserted?
> >
> > -Scott
> >
> > _______________________________________________
> > Linuxppc-dev mailing list
> > Linuxppc-dev@lists.ozlabs.org
> > https://lists.ozlabs.org/listinfo/linuxppc-dev
> >
>

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

^ permalink raw reply

* [PATCH] powerpc/pci: Don't configure PCIe settings when PCI_PROBE_ONLY is set
From: Benjamin Herrenschmidt @ 2011-09-26  5:02 UTC (permalink / raw)
  To: linuxppc-dev

We don't want to configure PCI Express Max Payload Size or
Max Read Request Size on systems that set that flag. The
firmware will have done it for us, and under hypervisors such
as pHyp we don't even see the parent switches and bridges and
thus can make no assumption on what values are safe to use.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/kernel/pci-common.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 1bd47f3..677eccc 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1732,7 +1732,7 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose)
 		hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
 
 	/* Configure PCI Express settings */
-	if (bus) {
+	if (bus && !pci_has_flag(PCI_PROBE_ONLY)) {
 		struct pci_bus *child;
 		list_for_each_entry(child, &bus->children, node) {
 			struct pci_dev *self = child->self;

^ permalink raw reply related

* Loading Linux from already running code..
From: Sumesh Kaana @ 2011-09-25 18:47 UTC (permalink / raw)
  To: linuxppc-dev, jwboyer

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


Hi All,
I need some suggestions for booting Linux( >2.6.30 ) with my new project.
Scenario:I've a custom built board with PowerPC 440 + 256 MB RAM. there is NO FLASH on this board.There is a hardware logic which will get an initial piece of code (through hardware network) into the ram and then execute it. This code does mandatory initialization of a proprietary chip and this code MUST execute on power on. any other images (Linux image or ramdisk) can be loaded any specified area in the memory along with this code.
My requirement is to boot Linux at the end of the this initialization.
what is the best way to do it? 
1. Will it be possible to transfer control to a simpleImage.initrd.myboard.elf(or .bin ..?!)  image from already_existing_code?2. Should I use u-boot and then load uImage, ramdisk and the dts blob? Using u-boot will reduce the effort?3. Is there any other way to approach this??


Regards,Sumesh 		 	   		  

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

^ permalink raw reply

* Re: [PATCH] powerpc/85xx: fix PHYS_64BIT selection for P1022DS
From: Tabi Timur-B04825 @ 2011-09-25 17:06 UTC (permalink / raw)
  To: Anatolij Gustschin; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1316806370-21067-1-git-send-email-agust@denx.de>

On Fri, Sep 23, 2011 at 2:32 PM, Anatolij Gustschin <agust@denx.de> wrote:

> diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms=
/85xx/Kconfig
> index 1b393f4..b29d4f2 100644
> --- a/arch/powerpc/platforms/85xx/Kconfig
> +++ b/arch/powerpc/platforms/85xx/Kconfig
> @@ -80,7 +80,7 @@ config P1010_RDB
> =A0config P1022_DS
> =A0 =A0 =A0 =A0bool "Freescale P1022 DS"
> =A0 =A0 =A0 =A0select DEFAULT_UIMAGE
> - =A0 =A0 =A0 select CONFIG_PHYS_64BIT =A0 =A0 =A0 =A0# The DTS has 36-bi=
t addresses
> + =A0 =A0 =A0 select PHYS_64BIT =A0 =A0 =A0 # The DTS has 36-bit addresse=
s

I have no idea how this happened, but I wonder if it's a good idea.
On the Freescale BSP, the default config for the P1022DS is 32-bit,
not 36-bit, so one day we might have a 32-bit config in the upstream
repository.

PHYS_64BIT is already covered by the defconfig.  I wonder if we should
just delete the bad line, and let the defconfig select the address
size.

--=20
Timur Tabi
Linux kernel developer at Freescale=

^ permalink raw reply

* [PATCH] powerpc/85xx: fix PHYS_64BIT selection for P1022DS
From: Anatolij Gustschin @ 2011-09-23 19:32 UTC (permalink / raw)
  To: Kumar Gala, linuxppc-dev

Remove wrong CONFIG_ prefix in Kconfig file.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
---
 arch/powerpc/platforms/85xx/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index 1b393f4..b29d4f2 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -80,7 +80,7 @@ config P1010_RDB
 config P1022_DS
 	bool "Freescale P1022 DS"
 	select DEFAULT_UIMAGE
-	select CONFIG_PHYS_64BIT	# The DTS has 36-bit addresses
+	select PHYS_64BIT	# The DTS has 36-bit addresses
 	select SWIOTLB
 	help
 	  This option enables support for the Freescale P1022DS reference board.
-- 
1.7.1

^ permalink raw reply related

* Re: [PATCH v2] powerpc: Fix xmon for systems without MSR[RI]
From: Scott Wood @ 2011-09-23 17:56 UTC (permalink / raw)
  To: Jimi Xenidis; +Cc: linuxppc-dev, David Gibson
In-Reply-To: <72989FF4-07B5-4BAC-BD9C-FE768296FDD8@pobox.com>

On 09/23/2011 12:54 PM, Jimi Xenidis wrote:
> On Sep 23, 2011, at 11:32 AM, Scott Wood wrote:
>> How is CONFIG_BOOK3E better than CONFIG_BOOKE?  Both e500mc (has RI) and
>> e500v2 (doesn't have RI) will select both symbols.  Sounds like it
>> should be a cputable flag.
> 
> Ben was not in favor of wasting a cpu feature bit on this.

That we're discussing the wastage of a single *bit* suggests the CPU
feature mechanism could use an overhaul. :-P

-Scott

^ permalink raw reply

* Re: [PATCH v2] powerpc: Fix xmon for systems without MSR[RI]
From: Jimi Xenidis @ 2011-09-23 17:54 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, David Gibson
In-Reply-To: <4E7CB4B1.3080703@freescale.com>


On Sep 23, 2011, at 11:32 AM, Scott Wood wrote:

> On 09/23/2011 10:01 AM, Jimi Xenidis wrote:
>> From: David Gibson <dwg@au1.ibm.com>
>>=20
>> Based on patch by David Gibson <dwg@au1.ibm.com>
>>=20
>> xmon has a longstanding bug on systems which are SMP-capable but lack
>> the MSR[RI] bit.  In these cases, xmon invoked by IPI on secondary
>> CPUs will not properly keep quiet, but will print stuff, thereby
>> garbling the primary xmon's output.  This patch fixes it, by ignoring
>> the RI bit if the processor does not support it.
>>=20
>> There's already a version of this for 4xx upstream, which we'll need
>> to extend to other RI-lacking CPUs at some point.  For now this adds
>> Book3e processors to the mix.
>>=20
>> Signed-off-by: Jimi Xenidis <jimix@pobox.com>
>>=20
>> ---
>> Restricted it to Book3e
>> ---
>> arch/powerpc/xmon/xmon.c |    4 ++--
>> 1 files changed, 2 insertions(+), 2 deletions(-)
>>=20
>> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
>> index 42541bb..13f82f8 100644
>> --- a/arch/powerpc/xmon/xmon.c
>> +++ b/arch/powerpc/xmon/xmon.c
>> @@ -340,8 +340,8 @@ int cpus_are_in_xmon(void)
>>=20
>> static inline int unrecoverable_excp(struct pt_regs *regs)
>> {
>> -#ifdef CONFIG_4xx
>> -	/* We have no MSR_RI bit on 4xx, so we simply return false */
>> +#if defined(CONFIG_4xx) || defined(CONFIG_BOOK3E)
>> +	/* We have no MSR_RI bit on 4xx or Book3e, so we simply return =
false */
>> 	return 0;
>> #else
>> 	return ((regs->msr & MSR_RI) =3D=3D 0);
>=20
> How is CONFIG_BOOK3E better than CONFIG_BOOKE?  Both e500mc (has RI) =
and
> e500v2 (doesn't have RI) will select both symbols.  Sounds like it
> should be a cputable flag.

Ben was not in favor of wasting a cpu feature bit on this.
I figured that since Book3e ISA does not support an RI bit than I would =
leave that too the those who extend it. :)
Any other ideas are welcome.

-JX


>=20
> -Scott
>=20

^ permalink raw reply

* [PATCH] powerpc/fsl_msi: add support for "msi-address-64" property
From: Timur Tabi @ 2011-09-23 17:41 UTC (permalink / raw)
  To: kumar.gala, benh, linuxppc-dev

Add support for the msi-address-64 property of a PCI node.  This property
specifies the PCI address of MSIIR (message signaled interrupt index
register).

In commit 3da34aae ("powerpc/fsl: Support unique MSI addresses per PCIe Root
Complex"), the msi_addr_hi/msi_addr_lo fields of struct fsl_msi were redefined
from an actual address to just an offset, but the fields were not renamed
accordingly.  These fields are replace with a single field, msiir_offset,
to reflect the new meaning.

Signed-off-by: Timur Tabi <timur@freescale.com>
---

This patch is necessary, but not sufficient, for MSI support under the
Freescale hypervisor.  Future patches will add full support.

 .../devicetree/bindings/powerpc/fsl/msi-pic.txt    |   42 ++++++++++++++++++++
 arch/powerpc/sysdev/fsl_msi.c                      |   20 +++++++---
 arch/powerpc/sysdev/fsl_msi.h                      |    3 +-
 3 files changed, 57 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt b/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt
index 70558c3..5d586e1 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt
+++ b/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt
@@ -25,6 +25,16 @@ Required properties:
   are routed to IPIC, and for 85xx/86xx cpu the interrupts are routed
   to MPIC.
 
+Optional properties:
+- msi-address-64: 64-bit PCI address of the MSIIR register. The MSIIR register
+  is used for MSI messaging.  The address of MSIIR in PCI address space is
+  the MSI message address.
+
+  This property may be used in virtualized environments where the hypervisor
+  has created an alternate mapping for the MSIR block.  See below for an
+  explanation.
+
+
 Example:
 	msi@41600 {
 		compatible = "fsl,mpc8610-msi", "fsl,mpic-msi";
@@ -41,3 +51,35 @@ Example:
 			0xe7 0>;
 		interrupt-parent = <&mpic>;
 	};
+
+The Freescale hypervisor and msi-address-64
+-------------------------------------------
+Normally, PCI devices have access to all of CCSR via an ATMU mapping.  The
+Freescale MSI driver calculates the address of MSIIR (in the MSI register
+block) and sets that address as the MSI message address.
+
+In a virtualized environment, the hypervisor may need to create an IOMMU
+mapping for MSIIR.  The Freescale ePAPR hypervisor has this requirement
+because of hardware limitations of the Peripheral Access Management Unit
+(PAMU), which is currently the only IOMMU that the hypervisor supports.
+The ATMU is programmed with the guest physical address, and the PAMU
+intercepts transactions and reroutes them to the true physical address.
+
+In the PAMU, each PCI controller is given only one primary window.  The
+PAMU restricts DMA operations so that they can only occur within a window.
+Because PCI devices must be able to DMA to memory, the primary window must
+be used to cover all of the guest's memory space.
+
+PAMU primary windows can be divided into 256 subwindows, and each
+subwindow can have its own address mapping ("guest physical" to "true
+physical").  However, each subwindow has to have the same alignment, which
+means they cannot be located at just any address.  Because of these
+restrictions, it is usually impossible to create a 4KB subwindow that
+covers MSIIR where it's normally located.
+
+Therefore, the hypervisor has to create a subwindow inside the same
+primary window used for memory, but mapped to the MSIR block (where MSIIR
+lives).  The first subwindow after the end of guest memory is used for
+this.  The address specified in the msi-address-64 property is the PCI
+address of MSIIR.  The hypervisor configures the PAMU to map that address to
+the true physical address of MSIIR.
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 1cca251..e5c344d 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -30,7 +30,7 @@ LIST_HEAD(msi_head);
 
 struct fsl_msi_feature {
 	u32 fsl_pic_ip;
-	u32 msiir_offset;
+	u32 msiir_offset; /* Offset of MSIIR, relative to start of MSIR bank */
 };
 
 struct fsl_msi_cascade_data {
@@ -126,10 +126,19 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
 {
 	struct fsl_msi *msi_data = fsl_msi_data;
 	struct pci_controller *hose = pci_bus_to_host(pdev->bus);
-	u64 base = fsl_pci_immrbar_base(hose);
+	u64 address; /* Physical address of the MSIIR */
+	int len;
+	const u64 *reg;
+
+	/* If the msi-address-64 property exists, then use it */
+	reg = of_get_property(hose->dn, "msi-address-64", &len);
+	if (reg && (len == sizeof(u64)))
+		address = be64_to_cpup(reg);
+	else
+		address = fsl_pci_immrbar_base(hose) + msi_data->msiir_offset;
 
-	msg->address_lo = msi_data->msi_addr_lo + lower_32_bits(base);
-	msg->address_hi = msi_data->msi_addr_hi + upper_32_bits(base);
+	msg->address_lo = lower_32_bits(address);
+	msg->address_hi = upper_32_bits(address);
 
 	msg->data = hwirq;
 
@@ -359,8 +368,7 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
 
 	msi->irqhost->host_data = msi;
 
-	msi->msi_addr_hi = 0x0;
-	msi->msi_addr_lo = features->msiir_offset + (res.start & 0xfffff);
+	msi->msiir_offset = features->msiir_offset + (res.start & 0xfffff);
 
 	rc = fsl_msi_init_allocator(msi);
 	if (rc) {
diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h
index 624580c..1313abb 100644
--- a/arch/powerpc/sysdev/fsl_msi.h
+++ b/arch/powerpc/sysdev/fsl_msi.h
@@ -28,8 +28,7 @@ struct fsl_msi {
 
 	unsigned long cascade_irq;
 
-	u32 msi_addr_lo;
-	u32 msi_addr_hi;
+	u32 msiir_offset; /* Offset of MSIIR, relative to start of CCSR */
 	void __iomem *msi_regs;
 	u32 feature;
 	int msi_virqs[NR_MSI_REG];
-- 
1.7.3.4

^ permalink raw reply related

* Re: [PATCH] powerpc: Fix hugetlb with CONFIG_PPC_MM_SLICES=y
From: Becky Bruce @ 2011-09-23 16:39 UTC (permalink / raw)
  To: Paul Mackerras, Benjamin Herrenschmidt; +Cc: list linuxppc-dev
In-Reply-To: <20110921055810.GA21681@drongo>


On Sep 21, 2011, at 12:58 AM, Paul Mackerras wrote:

> Commit 41151e77a4 ("powerpc: Hugetlb for BookE") added some
> #ifdef CONFIG_MM_SLICES conditionals to hugetlb_get_unmapped_area()
> and vma_mmu_pagesize().  Unfortunately this is not the correct config
> symbol; it should be CONFIG_PPC_MM_SLICES.  The result is that
> attempting to use hugetlbfs on 64-bit Power server processors results
> in an infinite stack recursion between get_unmapped_area() and
> hugetlb_get_unmapped_area().
>=20
> This fixes it by changing the #ifdef to use CONFIG_PPC_MM_SLICES
> in those functions and also in book3e_hugetlb_preload().
>=20
> Signed-off-by: Paul Mackerras <paulus@samba.org>

Paul, Ben,

ACK since it looks like Ben has picked this up already..... but FYI I =
have a different version of this fix in my tree.  The =
get_unmapped_area() shouldn't be there  *at all*  - we can just use the =
generic code if we don't have slices.  So instead the whole =
hugetlb_get_unmapped_area function should be wrapped in PPC_MM_SLICES.  =
This is crufty debug stuff that I missed yanking out when I pushed the =
patch, my apologies.

I'll just submit a followup patch to fix this.

Cheers,
B

> ---
> arch/powerpc/mm/hugetlbpage-book3e.c |    2 +-
> arch/powerpc/mm/hugetlbpage.c        |    4 ++--
> 2 files changed, 3 insertions(+), 3 deletions(-)
>=20
> diff --git a/arch/powerpc/mm/hugetlbpage-book3e.c =
b/arch/powerpc/mm/hugetlbpage-book3e.c
> index 1295b7c..343ad0b 100644
> --- a/arch/powerpc/mm/hugetlbpage-book3e.c
> +++ b/arch/powerpc/mm/hugetlbpage-book3e.c
> @@ -52,7 +52,7 @@ void book3e_hugetlb_preload(struct mm_struct *mm, =
unsigned long ea, pte_t pte)
> 	if (unlikely(is_kernel_addr(ea)))
> 		return;
>=20
> -#ifdef CONFIG_MM_SLICES
> +#ifdef CONFIG_PPC_MM_SLICES
> 	psize =3D mmu_get_tsize(get_slice_psize(mm, ea));
> 	tsize =3D mmu_get_psize(psize);
> 	shift =3D mmu_psize_defs[psize].shift;
> diff --git a/arch/powerpc/mm/hugetlbpage.c =
b/arch/powerpc/mm/hugetlbpage.c
> index 3a5f59d..48b65be 100644
> --- a/arch/powerpc/mm/hugetlbpage.c
> +++ b/arch/powerpc/mm/hugetlbpage.c
> @@ -690,7 +690,7 @@ unsigned long hugetlb_get_unmapped_area(struct =
file *file, unsigned long addr,
> 					unsigned long len, unsigned long =
pgoff,
> 					unsigned long flags)
> {
> -#ifdef CONFIG_MM_SLICES
> +#ifdef CONFIG_PPC_MM_SLICES
> 	struct hstate *hstate =3D hstate_file(file);
> 	int mmu_psize =3D shift_to_mmu_psize(huge_page_shift(hstate));
>=20
> @@ -702,7 +702,7 @@ unsigned long hugetlb_get_unmapped_area(struct =
file *file, unsigned long addr,
>=20
> unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
> {
> -#ifdef CONFIG_MM_SLICES
> +#ifdef CONFIG_PPC_MM_SLICES
> 	unsigned int psize =3D get_slice_psize(vma->vm_mm, =
vma->vm_start);
>=20
> 	return 1UL << mmu_psize_to_shift(psize);
> --=20
> 1.7.5.4

^ permalink raw reply

* Re: [PATCH v2] powerpc: Fix xmon for systems without MSR[RI]
From: Scott Wood @ 2011-09-23 16:32 UTC (permalink / raw)
  To: Jimi Xenidis; +Cc: linuxppc-dev, David Gibson
In-Reply-To: <1316790104-10067-1-git-send-email-jimix@pobox.com>

On 09/23/2011 10:01 AM, Jimi Xenidis wrote:
> From: David Gibson <dwg@au1.ibm.com>
> 
> Based on patch by David Gibson <dwg@au1.ibm.com>
> 
> xmon has a longstanding bug on systems which are SMP-capable but lack
> the MSR[RI] bit.  In these cases, xmon invoked by IPI on secondary
> CPUs will not properly keep quiet, but will print stuff, thereby
> garbling the primary xmon's output.  This patch fixes it, by ignoring
> the RI bit if the processor does not support it.
> 
> There's already a version of this for 4xx upstream, which we'll need
> to extend to other RI-lacking CPUs at some point.  For now this adds
> Book3e processors to the mix.
> 
> Signed-off-by: Jimi Xenidis <jimix@pobox.com>
> 
> ---
> Restricted it to Book3e
> ---
>  arch/powerpc/xmon/xmon.c |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index 42541bb..13f82f8 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -340,8 +340,8 @@ int cpus_are_in_xmon(void)
>  
>  static inline int unrecoverable_excp(struct pt_regs *regs)
>  {
> -#ifdef CONFIG_4xx
> -	/* We have no MSR_RI bit on 4xx, so we simply return false */
> +#if defined(CONFIG_4xx) || defined(CONFIG_BOOK3E)
> +	/* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
>  	return 0;
>  #else
>  	return ((regs->msr & MSR_RI) == 0);

How is CONFIG_BOOK3E better than CONFIG_BOOKE?  Both e500mc (has RI) and
e500v2 (doesn't have RI) will select both symbols.  Sounds like it
should be a cputable flag.

-Scott

^ permalink raw reply

* [PATCH 3/3 v2] powerpc: icswx: Simple ACOP fault handler for both book3e and book3s parts.
From: Jimi Xenidis @ 2011-09-23 15:59 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: anton
In-Reply-To: <1316793594-22407-1-git-send-email-jimix@pobox.com>

This patch adds a fault handler that responds to illegal Coprocessor
types.  Currently all CTs are treated and illegal.  There are two ways
to report the fault back to the application.  If the application used
the record form ("icswx.") then the architected "reject" is emulated.
If the application did not used the record form ("icswx") then it is
selectable by config whether the failure is silent (as architected) or
a SIGILL is generated.

In all cases pr_warn() is used to log the bad CT.

Signed-off-by: Jimi Xenidis <jimix@pobox.com>

---
Re: galak@kernel.crashing.org
 - Fix Kconfig/CONFIG mismatch
 - Removed union/bitfields and inspect the bits directly
---
 arch/powerpc/mm/fault.c                |   16 +++++
 arch/powerpc/mm/icswx.c                |  113 ++++++++++++++++++++++++++++++++
 arch/powerpc/mm/icswx.h                |   24 +++++++
 arch/powerpc/platforms/Kconfig.cputype |   13 ++++-
 4 files changed, 165 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 5efe8c9..88abe70 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -43,6 +43,7 @@
 #include <asm/tlbflush.h>
 #include <asm/siginfo.h>
 #include <mm/mmu_decl.h>
+#include <mm/icswx.h>
 
 #ifdef CONFIG_KPROBES
 static inline int notify_page_fault(struct pt_regs *regs)
@@ -143,6 +144,21 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
 	is_write = error_code & ESR_DST;
 #endif /* CONFIG_4xx || CONFIG_BOOKE */
 
+#ifdef CONFIG_PPC_ICSWX
+	/*
+	 * we need to do this early because this "data storage
+	 * interrupt" does not update the DAR/DEAR so we don't want to
+	 * look at it
+	 */
+	if (error_code & ICSWX_DSI_UCT) {
+		int ret;
+
+		ret = acop_handle_fault(regs, address, error_code);
+		if (ret)
+			return ret;
+	}
+#endif
+
 	if (notify_page_fault(regs))
 		return 0;
 
diff --git a/arch/powerpc/mm/icswx.c b/arch/powerpc/mm/icswx.c
index 2f1dd29..c8626cc 100644
--- a/arch/powerpc/mm/icswx.c
+++ b/arch/powerpc/mm/icswx.c
@@ -17,6 +17,8 @@
 #include <linux/mm.h>
 #include <linux/spinlock.h>
 #include <linux/module.h>
+#include <linux/uaccess.h>
+
 #include "icswx.h"
 
 
@@ -160,3 +162,114 @@ void drop_cop(unsigned long acop, struct mm_struct *mm)
 	spin_unlock(&mm->page_table_lock);
 }
 EXPORT_SYMBOL_GPL(drop_cop);
+
+static int acop_use_cop(int ct)
+{
+	/* todo */
+	return -1;
+}
+
+/*
+ * Get the instruction word at the NIP
+ */
+static u32 acop_get_inst(struct pt_regs *regs)
+{
+	u32 inst;
+	u32 __user *p;
+
+	p = (u32 __user *)regs->nip;
+	if (!access_ok(VERIFY_READ, p, sizeof(*p)))
+		return 0;
+
+	if (__get_user(inst, p))
+		return 0;
+
+	return inst;
+}
+
+/**
+ * @regs: regsiters at time of interrupt
+ * @address: storage address
+ * @error_code: Fault code, usually the DSISR or ESR depending on
+ *		processor type
+ *
+ * Return 0 if we are able to resolve the data storage fault that
+ * results from a CT miss in the ACOP register.
+ */
+int acop_handle_fault(struct pt_regs *regs, unsigned long address,
+		      unsigned long error_code)
+{
+	int ct;
+	u32 inst = 0;
+
+	if (!cpu_has_feature(CPU_FTR_ICSWX)) {
+		pr_info("No coprocessors available");
+		_exception(SIGILL, regs, ILL_ILLOPN, address);
+	}
+
+	if (!user_mode(regs)) {
+		/* this could happen if the HV denies the
+		 * kernel access, for now we just die */
+		die("ICSWX from kernel failed", regs, SIGSEGV);
+	}
+
+	/* Some implementations leave us a hint for the CT */
+	ct = ICSWX_GET_CT_HINT(error_code);
+	if (ct < 0) {
+		/* we have to peek at the instruction word to figure out CT */
+		u32 ccw;
+		u32 rs;
+
+		inst = acop_get_inst(regs);
+		if (inst == 0)
+			return -1;
+
+		rs = (inst >> (31 - 10)) & 0x1f;
+		ccw = regs->gpr[rs];
+		ct = (ccw >> 16) & 0x3f;
+	}
+
+	if (!acop_use_cop(ct))
+		return 0;
+
+	/* at this point the CT is unknown to the system */
+	pr_warn("%s[%d]: Coprocessor %d is unavailable",
+		current->comm, current->pid, ct);
+
+	/* get inst if we don't already have it */
+	if (inst == 0) {
+		inst = acop_get_inst(regs);
+		if (inst == 0)
+			return -1;
+	}
+
+	/* Check if the instruction is the "record form" */
+	if (inst & 1) {
+		/*
+		 * the instruction is "record" form so we can reject
+		 * using CR0
+		 */
+		regs->ccr &= ~(0xful << 28);
+		regs->ccr |= ICSWX_RC_NOT_FOUND << 28;
+
+		/* Move on to the next instruction */
+		regs->nip += 4;
+	} else {
+		/*
+		 * There is no architected mechanism to report a bad
+		 * CT so we could either SIGILL or report nothing.
+		 * Since the non-record version should only bu used
+		 * for "hints" or "don't care" we should probably do
+		 * nothing.  However, I could see how some people
+		 * might want an SIGILL so it here if you want it.
+		 */
+#ifdef CONFIG_PPC_ICSWX_USE_SIGILL
+		_exception(SIGILL, regs, ILL_ILLOPN, address);
+#else
+		regs->nip += 4;
+#endif
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(acop_handle_fault);
diff --git a/arch/powerpc/mm/icswx.h b/arch/powerpc/mm/icswx.h
index 5121ddd..4c1ecc3 100644
--- a/arch/powerpc/mm/icswx.h
+++ b/arch/powerpc/mm/icswx.h
@@ -32,3 +32,27 @@ extern void free_cop_pid(int free_pid);
 #define disable_cop_pid(m) (COP_PID_NONE)
 #define free_cop_pid(p)
 #endif
+
+/*
+ * These are implementation bits for architected registers.  If this
+ * ever becomes architecture the should be moved to reg.h et. al.
+ */
+/* UCT is the same bit for Server and Embedded */
+#define ICSWX_DSI_UCT		0x00004000  /* Unavailable Coprocessor Type */
+
+#ifdef CONFIG_BOOKE
+/* Embedded implementation gives us no hits as to what the CT is */
+#define ICSWX_GET_CT_HINT(x) (-1)
+#else
+/* Server implementation contains the CT value in the DSISR */
+#define ICSWX_DSISR_CTMASK	0x00003f00
+#define ICSWX_GET_CT_HINT(x)	(((x) & ICSWX_DSISR_CTMASK) >> 8)
+#endif
+
+#define ICSWX_RC_STARTED	0x8	/* The request has been started */
+#define ICSWX_RC_NOT_IDLE	0x4	/* No coprocessor found idle */
+#define ICSWX_RC_NOT_FOUND	0x2	/* No coprocessor found */
+#define ICSWX_RC_UNDEFINED	0x1	/* Reserved */
+
+extern int acop_handle_fault(struct pt_regs *regs, unsigned long address,
+			     unsigned long error_code);
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 3cd22e5..4173129 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -255,9 +255,20 @@ config PPC_ICSWX_PID
 	depends on PPC_ICSWX && POWER4
 	default y
 	---help---
-	  PID register in server is used explicitly for ICSWX.  In
+	  The PID register in server is used explicitly for ICSWX.  In
 	  embedded systems PID managment is done by the system.
 
+config PPC_ICSWX_USE_SIGILL
+	bool "Should a bad CT cause a SIGILL?"
+	depends on PPC_ICSWX
+	default n
+	---help---
+	  Should a bad CT used for "non-record form ICSWX" cause an
+	  illegal intruction signal or should it be silent as
+	  architected.
+
+	  If in doubt, say N here.
+
 config SPE
 	bool "SPE Support"
 	depends on E200 || (E500 && !PPC_E500MC)
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH 2/3 v2] powerpc: book3e: Add ICSWX/ACOP support to Book3e cores like A2
From: Jimi Xenidis @ 2011-09-23 15:59 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: anton
In-Reply-To: <1316793594-22407-1-git-send-email-jimix@pobox.com>

ICSWX is also used by the A2 processor to access coprocessors,
although not all "chips" that contain A2s have coprocessors.

Signed-off-by: Jimi Xenidis <jimix@pobox.com>

---
Re: galak@kernel.crashing.org
    Fix white space *embarrassed*
---
 arch/powerpc/include/asm/cputable.h   |    2 +-
 arch/powerpc/include/asm/mmu-book3e.h |    4 ++++
 arch/powerpc/include/asm/reg_booke.h  |    4 ++++
 arch/powerpc/kernel/cpu_setup_a2.S    |   10 ++++++++--
 arch/powerpc/platforms/wsp/Kconfig    |    1 +
 5 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index e30442c..7044233 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -437,7 +437,7 @@ extern const char *powerpc_base_platform;
 #define CPU_FTRS_COMPATIBLE	(CPU_FTR_USE_TB | CPU_FTR_PPCAS_ARCH_V2)
 
 #define CPU_FTRS_A2 (CPU_FTR_USE_TB | CPU_FTR_SMT | CPU_FTR_DBELL | \
-		     CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN)
+		     CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN | CPU_FTR_ICSWX)
 
 #ifdef __powerpc64__
 #ifdef CONFIG_PPC_BOOK3E
diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/mmu-book3e.h
index 3ea0f9a..6554608 100644
--- a/arch/powerpc/include/asm/mmu-book3e.h
+++ b/arch/powerpc/include/asm/mmu-book3e.h
@@ -212,6 +212,10 @@ typedef struct {
 	unsigned int	id;
 	unsigned int	active;
 	unsigned long	vdso_base;
+#ifdef CONFIG_PPC_ICSWX
+	struct spinlock *cop_lockp;	/* guard cop related stuff */
+	unsigned long acop;		/* mask of enabled coprocessor types */
+#endif /* CONFIG_PPC_ICSWX */
 } mm_context_t;
 
 /* Page size definitions, common between 32 and 64-bit
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 9ec0b39..e927049 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -187,6 +187,10 @@
 #define SPRN_CSRR1	SPRN_SRR3 /* Critical Save and Restore Register 1 */
 #endif
 
+#ifdef CONFIG_PPC_ICSWX
+#define SPRN_HACOP	0x15F	/* Hypervisor Available Coprocessor Register */
+#endif
+
 /* Bit definitions for CCR1. */
 #define	CCR1_DPC	0x00000100 /* Disable L1 I-Cache/D-Cache parity checking */
 #define	CCR1_TCS	0x00000080 /* Timer Clock Select */
diff --git a/arch/powerpc/kernel/cpu_setup_a2.S b/arch/powerpc/kernel/cpu_setup_a2.S
index 7f818fe..ebc62f4 100644
--- a/arch/powerpc/kernel/cpu_setup_a2.S
+++ b/arch/powerpc/kernel/cpu_setup_a2.S
@@ -41,11 +41,16 @@ _GLOBAL(__setup_cpu_a2)
 	 * core local but doing it always won't hurt
 	 */
 
-#ifdef CONFIG_PPC_WSP_COPRO
+#ifdef CONFIG_PPC_ICSWX
 	/* Make sure ACOP starts out as zero */
 	li	r3,0
 	mtspr   SPRN_ACOP,r3
 
+	/* Skip the following if we are in Guest mode */
+	mfmsr	r3
+	andis.	r0,r3,MSR_GS@h
+	bne	_icswx_skip_guest
+
 	/* Enable icswx instruction */
 	mfspr   r3,SPRN_A2_CCR2
 	ori     r3,r3,A2_CCR2_ENABLE_ICSWX
@@ -54,7 +59,8 @@ _GLOBAL(__setup_cpu_a2)
 	/* Unmask all CTs in HACOP */
 	li      r3,-1
 	mtspr   SPRN_HACOP,r3
-#endif /* CONFIG_PPC_WSP_COPRO */
+_icswx_skip_guest:
+#endif /* CONFIG_PPC_ICSWX */
 
 	/* Enable doorbell */
 	mfspr   r3,SPRN_A2_CCR2
diff --git a/arch/powerpc/platforms/wsp/Kconfig b/arch/powerpc/platforms/wsp/Kconfig
index d051581..3540293 100644
--- a/arch/powerpc/platforms/wsp/Kconfig
+++ b/arch/powerpc/platforms/wsp/Kconfig
@@ -1,6 +1,7 @@
 config PPC_WSP
 	bool
 	select PPC_A2
+	select PPC_ICSWX
 	select PPC_SCOM
 	select PPC_XICS
 	select PPC_ICP_NATIVE
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH 1/3 v2] powerpc: Split ICSWX ACOP and PID processing
From: Jimi Xenidis @ 2011-09-23 15:59 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: anton

Some processors, like embedded, that already have a PID register that
is managed by the system.  This patch separates the ACOP and PID
processing into separate files so that the ACOP code can be shared.

Signed-off-by: Jimi Xenidis <jimix@pobox.com>

---
Re: galak@kernel.crashing.org
    Fix typo in arch/powerpc/mm/Makefile

Re: anton@samba.org
    merge in: powerpc: Fix deadlock in icswx code
---
 arch/powerpc/mm/Makefile               |    2 +
 arch/powerpc/mm/icswx.c                |  162 ++++++++++++++++++++++++++
 arch/powerpc/mm/icswx.h                |   34 ++++++
 arch/powerpc/mm/icswx_pid.c            |   87 ++++++++++++++
 arch/powerpc/mm/mmu_context_hash64.c   |  195 --------------------------------
 arch/powerpc/platforms/Kconfig.cputype |   10 ++-
 6 files changed, 294 insertions(+), 196 deletions(-)
 create mode 100644 arch/powerpc/mm/icswx.c
 create mode 100644 arch/powerpc/mm/icswx.h
 create mode 100644 arch/powerpc/mm/icswx_pid.c

diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index bdca46e..fb7976f 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -21,6 +21,8 @@ obj-$(CONFIG_PPC_STD_MMU_32)	+= ppc_mmu_32.o
 obj-$(CONFIG_PPC_STD_MMU)	+= hash_low_$(CONFIG_WORD_SIZE).o \
 				   tlb_hash$(CONFIG_WORD_SIZE).o \
 				   mmu_context_hash$(CONFIG_WORD_SIZE).o
+obj-$(CONFIG_PPC_ICSWX)		+= icswx.o
+obj-$(CONFIG_PPC_ICSWX_PID)	+= icswx_pid.o
 obj-$(CONFIG_40x)		+= 40x_mmu.o
 obj-$(CONFIG_44x)		+= 44x_mmu.o
 obj-$(CONFIG_PPC_FSL_BOOK3E)	+= fsl_booke_mmu.o
diff --git a/arch/powerpc/mm/icswx.c b/arch/powerpc/mm/icswx.c
new file mode 100644
index 0000000..2f1dd29
--- /dev/null
+++ b/arch/powerpc/mm/icswx.c
@@ -0,0 +1,162 @@
+/*
+ *  ICSWX and ACOP Management
+ *
+ *  Copyright (C) 2011 Anton Blanchard, IBM Corp. <anton@samba.org>
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include "icswx.h"
+
+
+/*
+ * The processor and its L2 cache cause the icswx instruction to
+ * generate a COP_REQ transaction on PowerBus. The transaction has no
+ * address, and the processor does not perform an MMU access to
+ * authenticate the transaction. The command portion of the PowerBus
+ * COP_REQ transaction includes the LPAR_ID (LPID) and the coprocessor
+ * Process ID (PID), which the coprocessor compares to the authorized
+ * LPID and PID held in the coprocessor, to determine if the process
+ * is authorized to generate the transaction.  The data of the COP_REQ
+ * transaction is cache block or less, typically 64 or 128 bytes in
+ * size, and is placed in cacheable memory on a 128-byte boundary
+ * _always_.
+ *
+ * The task to use a coprocessor should use use_cop() mark the use of
+ * the coprocessor type (CT) and context swithing.  On a server
+ * processor the PID register is used only for coprocessor management
+ * and so a coprocessor PID is allocated before executing icswx
+ * instruction. Drop_cop() is used to free the resources created by
+ * use_cop().
+ *
+ * Example:
+ * Host Fabric Interface (HFI) is a PowerPC network coprocessor.
+ * Each HFI have multiple windows. Each HFI window serves as a
+ * network device sending to and receiving from HFI network.
+ * HFI immediate send function uses icswx instruction. The immediate
+ * send function allows small (single cache-line) packets be sent
+ * without using the regular HFI send FIFO and doorbell, which are
+ * much slower than immediate send.
+ *
+ * For each task intending to use HFI immediate send, the HFI driver
+ * calls use_cop() to obtain a coprocessor PID for the task.
+ * The HFI driver then allocate a free HFI window and save the
+ * coprocessor PID to the HFI window to allow the task to use the
+ * HFI window.
+ *
+ * The HFI driver repeatedly creates immediate send packets and
+ * issues icswx instruction to send data through the HFI window.
+ * The HFI compares the coprocessor PID in the CPU PID register
+ * to the PID held in the HFI window to determine if the transaction
+ * is allowed.
+ *
+ * When the task to release the HFI window, the HFI driver calls
+ * drop_cop() to release the coprocessor PID.
+ */
+
+void switch_cop(struct mm_struct *next)
+{
+#ifdef CONFIG_ICSWX_PID
+	mtspr(SPRN_PID, next->context.cop_pid);
+#endif
+	mtspr(SPRN_ACOP, next->context.acop);
+}
+
+/**
+ * Start using a coprocessor.
+ * @acop: mask of coprocessor to be used.
+ * @mm: The mm the coprocessor to associate with. Most likely current mm.
+ *
+ * Return a positive PID if successful. Negative errno otherwise.
+ * The returned PID will be fed to the coprocessor to determine if an
+ * icswx transaction is authenticated.
+ */
+int use_cop(unsigned long acop, struct mm_struct *mm)
+{
+	int ret;
+
+	if (!cpu_has_feature(CPU_FTR_ICSWX))
+		return -ENODEV;
+
+	if (!mm || !acop)
+		return -EINVAL;
+
+	/* The page_table_lock ensures mm_users won't change under us */
+	spin_lock(&mm->page_table_lock);
+	spin_lock(mm->context.cop_lockp);
+
+	ret = get_cop_pid(mm);
+	if (ret < 0)
+		goto out;
+
+	/* update acop */
+	mm->context.acop |= acop;
+
+	sync_cop(mm);
+
+	/*
+	 * If this is a threaded process then there might be other threads
+	 * running. We need to send an IPI to force them to pick up any
+	 * change in PID and ACOP.
+	 */
+	if (atomic_read(&mm->mm_users) > 1)
+		smp_call_function(sync_cop, mm, 1);
+
+out:
+	spin_unlock(mm->context.cop_lockp);
+	spin_unlock(&mm->page_table_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(use_cop);
+
+/**
+ * Stop using a coprocessor.
+ * @acop: mask of coprocessor to be stopped.
+ * @mm: The mm the coprocessor associated with.
+ */
+void drop_cop(unsigned long acop, struct mm_struct *mm)
+{
+	int free_pid;
+
+	if (!cpu_has_feature(CPU_FTR_ICSWX))
+		return;
+
+	if (WARN_ON_ONCE(!mm))
+		return;
+
+	/* The page_table_lock ensures mm_users won't change under us */
+	spin_lock(&mm->page_table_lock);
+	spin_lock(mm->context.cop_lockp);
+
+	mm->context.acop &= ~acop;
+
+	free_pid = disable_cop_pid(mm);
+	sync_cop(mm);
+
+	/*
+	 * If this is a threaded process then there might be other threads
+	 * running. We need to send an IPI to force them to pick up any
+	 * change in PID and ACOP.
+	 */
+	if (atomic_read(&mm->mm_users) > 1)
+		smp_call_function(sync_cop, mm, 1);
+
+	if (free_pid != COP_PID_NONE)
+		free_cop_pid(free_pid);
+
+	spin_unlock(mm->context.cop_lockp);
+	spin_unlock(&mm->page_table_lock);
+}
+EXPORT_SYMBOL_GPL(drop_cop);
diff --git a/arch/powerpc/mm/icswx.h b/arch/powerpc/mm/icswx.h
new file mode 100644
index 0000000..5121ddd
--- /dev/null
+++ b/arch/powerpc/mm/icswx.h
@@ -0,0 +1,34 @@
+/*
+ *  ICSWX and ACOP Management
+ *
+ *  Copyright (C) 2011 Anton Blanchard, IBM Corp. <anton@samba.org>
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <asm/mmu_context.h>
+
+/* also used to denote that PIDs are not used */
+#define COP_PID_NONE 0
+
+static inline void sync_cop(void *arg)
+{
+	struct mm_struct *mm = arg;
+
+	if (mm == current->active_mm)
+		switch_cop(current->active_mm);
+}
+
+#ifdef CONFIG_PPC_ICSWX_PID
+extern int get_cop_pid(struct mm_struct *mm);
+extern int disable_cop_pid(struct mm_struct *mm);
+extern void free_cop_pid(int free_pid);
+#else
+#define get_cop_pid(m) (COP_PID_NONE)
+#define disable_cop_pid(m) (COP_PID_NONE)
+#define free_cop_pid(p)
+#endif
diff --git a/arch/powerpc/mm/icswx_pid.c b/arch/powerpc/mm/icswx_pid.c
new file mode 100644
index 0000000..91e30eb
--- /dev/null
+++ b/arch/powerpc/mm/icswx_pid.c
@@ -0,0 +1,87 @@
+/*
+ *  ICSWX and ACOP/PID Management
+ *
+ *  Copyright (C) 2011 Anton Blanchard, IBM Corp. <anton@samba.org>
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/idr.h>
+#include <linux/module.h>
+#include "icswx.h"
+
+#define COP_PID_MIN (COP_PID_NONE + 1)
+#define COP_PID_MAX (0xFFFF)
+
+static DEFINE_SPINLOCK(mmu_context_acop_lock);
+static DEFINE_IDA(cop_ida);
+
+static int new_cop_pid(struct ida *ida, int min_id, int max_id,
+		       spinlock_t *lock)
+{
+	int index;
+	int err;
+
+again:
+	if (!ida_pre_get(ida, GFP_KERNEL))
+		return -ENOMEM;
+
+	spin_lock(lock);
+	err = ida_get_new_above(ida, min_id, &index);
+	spin_unlock(lock);
+
+	if (err == -EAGAIN)
+		goto again;
+	else if (err)
+		return err;
+
+	if (index > max_id) {
+		spin_lock(lock);
+		ida_remove(ida, index);
+		spin_unlock(lock);
+		return -ENOMEM;
+	}
+
+	return index;
+}
+
+int get_cop_pid(struct mm_struct *mm)
+{
+	int pid;
+
+	if (mm->context.cop_pid == COP_PID_NONE) {
+		pid = new_cop_pid(&cop_ida, COP_PID_MIN, COP_PID_MAX,
+				  &mmu_context_acop_lock);
+		if (pid >= 0)
+			mm->context.cop_pid = pid;
+	}
+	return mm->context.cop_pid;
+}
+
+int disable_cop_pid(struct mm_struct *mm)
+{
+	int free_pid = COP_PID_NONE;
+
+	if ((!mm->context.acop) && (mm->context.cop_pid != COP_PID_NONE)) {
+		free_pid = mm->context.cop_pid;
+		mm->context.cop_pid = COP_PID_NONE;
+	}
+	return free_pid;
+}
+
+void free_cop_pid(int free_pid)
+{
+	spin_lock(&mmu_context_acop_lock);
+	ida_remove(&cop_ida, free_pid);
+	spin_unlock(&mmu_context_acop_lock);
+}
diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c
index 3bafc3d..a75832c 100644
--- a/arch/powerpc/mm/mmu_context_hash64.c
+++ b/arch/powerpc/mm/mmu_context_hash64.c
@@ -24,201 +24,6 @@
 
 #include <asm/mmu_context.h>
 
-#ifdef CONFIG_PPC_ICSWX
-/*
- * The processor and its L2 cache cause the icswx instruction to
- * generate a COP_REQ transaction on PowerBus. The transaction has
- * no address, and the processor does not perform an MMU access
- * to authenticate the transaction. The command portion of the
- * PowerBus COP_REQ transaction includes the LPAR_ID (LPID) and
- * the coprocessor Process ID (PID), which the coprocessor compares
- * to the authorized LPID and PID held in the coprocessor, to determine
- * if the process is authorized to generate the transaction.
- * The data of the COP_REQ transaction is 128-byte or less and is
- * placed in cacheable memory on a 128-byte cache line boundary.
- *
- * The task to use a coprocessor should use use_cop() to allocate
- * a coprocessor PID before executing icswx instruction. use_cop()
- * also enables the coprocessor context switching. Drop_cop() is
- * used to free the coprocessor PID.
- *
- * Example:
- * Host Fabric Interface (HFI) is a PowerPC network coprocessor.
- * Each HFI have multiple windows. Each HFI window serves as a
- * network device sending to and receiving from HFI network.
- * HFI immediate send function uses icswx instruction. The immediate
- * send function allows small (single cache-line) packets be sent
- * without using the regular HFI send FIFO and doorbell, which are
- * much slower than immediate send.
- *
- * For each task intending to use HFI immediate send, the HFI driver
- * calls use_cop() to obtain a coprocessor PID for the task.
- * The HFI driver then allocate a free HFI window and save the
- * coprocessor PID to the HFI window to allow the task to use the
- * HFI window.
- *
- * The HFI driver repeatedly creates immediate send packets and
- * issues icswx instruction to send data through the HFI window.
- * The HFI compares the coprocessor PID in the CPU PID register
- * to the PID held in the HFI window to determine if the transaction
- * is allowed.
- *
- * When the task to release the HFI window, the HFI driver calls
- * drop_cop() to release the coprocessor PID.
- */
-
-#define COP_PID_NONE 0
-#define COP_PID_MIN (COP_PID_NONE + 1)
-#define COP_PID_MAX (0xFFFF)
-
-static DEFINE_SPINLOCK(mmu_context_acop_lock);
-static DEFINE_IDA(cop_ida);
-
-void switch_cop(struct mm_struct *next)
-{
-	mtspr(SPRN_PID, next->context.cop_pid);
-	mtspr(SPRN_ACOP, next->context.acop);
-}
-
-static int new_cop_pid(struct ida *ida, int min_id, int max_id,
-		       spinlock_t *lock)
-{
-	int index;
-	int err;
-
-again:
-	if (!ida_pre_get(ida, GFP_KERNEL))
-		return -ENOMEM;
-
-	spin_lock(lock);
-	err = ida_get_new_above(ida, min_id, &index);
-	spin_unlock(lock);
-
-	if (err == -EAGAIN)
-		goto again;
-	else if (err)
-		return err;
-
-	if (index > max_id) {
-		spin_lock(lock);
-		ida_remove(ida, index);
-		spin_unlock(lock);
-		return -ENOMEM;
-	}
-
-	return index;
-}
-
-static void sync_cop(void *arg)
-{
-	struct mm_struct *mm = arg;
-
-	if (mm == current->active_mm)
-		switch_cop(current->active_mm);
-}
-
-/**
- * Start using a coprocessor.
- * @acop: mask of coprocessor to be used.
- * @mm: The mm the coprocessor to associate with. Most likely current mm.
- *
- * Return a positive PID if successful. Negative errno otherwise.
- * The returned PID will be fed to the coprocessor to determine if an
- * icswx transaction is authenticated.
- */
-int use_cop(unsigned long acop, struct mm_struct *mm)
-{
-	int ret;
-
-	if (!cpu_has_feature(CPU_FTR_ICSWX))
-		return -ENODEV;
-
-	if (!mm || !acop)
-		return -EINVAL;
-
-	/* We need to make sure mm_users doesn't change */
-	down_read(&mm->mmap_sem);
-	spin_lock(mm->context.cop_lockp);
-
-	if (mm->context.cop_pid == COP_PID_NONE) {
-		ret = new_cop_pid(&cop_ida, COP_PID_MIN, COP_PID_MAX,
-				  &mmu_context_acop_lock);
-		if (ret < 0)
-			goto out;
-
-		mm->context.cop_pid = ret;
-	}
-	mm->context.acop |= acop;
-
-	sync_cop(mm);
-
-	/*
-	 * If this is a threaded process then there might be other threads
-	 * running. We need to send an IPI to force them to pick up any
-	 * change in PID and ACOP.
-	 */
-	if (atomic_read(&mm->mm_users) > 1)
-		smp_call_function(sync_cop, mm, 1);
-
-	ret = mm->context.cop_pid;
-
-out:
-	spin_unlock(mm->context.cop_lockp);
-	up_read(&mm->mmap_sem);
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(use_cop);
-
-/**
- * Stop using a coprocessor.
- * @acop: mask of coprocessor to be stopped.
- * @mm: The mm the coprocessor associated with.
- */
-void drop_cop(unsigned long acop, struct mm_struct *mm)
-{
-	int free_pid = COP_PID_NONE;
-
-	if (!cpu_has_feature(CPU_FTR_ICSWX))
-		return;
-
-	if (WARN_ON_ONCE(!mm))
-		return;
-
-	/* We need to make sure mm_users doesn't change */
-	down_read(&mm->mmap_sem);
-	spin_lock(mm->context.cop_lockp);
-
-	mm->context.acop &= ~acop;
-
-	if ((!mm->context.acop) && (mm->context.cop_pid != COP_PID_NONE)) {
-		free_pid = mm->context.cop_pid;
-		mm->context.cop_pid = COP_PID_NONE;
-	}
-
-	sync_cop(mm);
-
-	/*
-	 * If this is a threaded process then there might be other threads
-	 * running. We need to send an IPI to force them to pick up any
-	 * change in PID and ACOP.
-	 */
-	if (atomic_read(&mm->mm_users) > 1)
-		smp_call_function(sync_cop, mm, 1);
-
-	if (free_pid != COP_PID_NONE) {
-		spin_lock(&mmu_context_acop_lock);
-		ida_remove(&cop_ida, free_pid);
-		spin_unlock(&mmu_context_acop_lock);
-	}
-
-	spin_unlock(mm->context.cop_lockp);
-	up_read(&mm->mmap_sem);
-}
-EXPORT_SYMBOL_GPL(drop_cop);
-
-#endif /* CONFIG_PPC_ICSWX */
-
 static DEFINE_SPINLOCK(mmu_context_lock);
 static DEFINE_IDA(mmu_context_ida);
 
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index e06e395..3cd22e5 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -234,7 +234,7 @@ config VSX
 
 config PPC_ICSWX
 	bool "Support for PowerPC icswx coprocessor instruction"
-	depends on POWER4
+	depends on POWER4 || PPC_A2
 	default n
 	---help---
 
@@ -250,6 +250,14 @@ config PPC_ICSWX
 
 	  If in doubt, say N here.
 
+config PPC_ICSWX_PID
+	bool "icswx requires direct PID management"
+	depends on PPC_ICSWX && POWER4
+	default y
+	---help---
+	  PID register in server is used explicitly for ICSWX.  In
+	  embedded systems PID managment is done by the system.
+
 config SPE
 	bool "SPE Support"
 	depends on E200 || (E500 && !PPC_E500MC)
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH v2] powerpc: Fix xmon for systems without MSR[RI]
From: Jimi Xenidis @ 2011-09-23 15:40 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: scottwood, David Gibson
In-Reply-To: <1312838739-20660-1-git-send-email-jimix@pobox.com>

From: David Gibson <dwg@au1.ibm.com>

Based on patch by David Gibson <dwg@au1.ibm.com>

xmon has a longstanding bug on systems which are SMP-capable but lack
the MSR[RI] bit.  In these cases, xmon invoked by IPI on secondary
CPUs will not properly keep quiet, but will print stuff, thereby
garbling the primary xmon's output.  This patch fixes it, by ignoring
the RI bit if the processor does not support it.

There's already a version of this for 4xx upstream, which we'll need
to extend to other RI-lacking CPUs at some point.  For now this adds
Book3e processors to the mix.

Signed-off-by: Jimi Xenidis <jimix@pobox.com>

---
Restricted it to Book3e
---
 arch/powerpc/xmon/xmon.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 42541bb..13f82f8 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -340,8 +340,8 @@ int cpus_are_in_xmon(void)
 
 static inline int unrecoverable_excp(struct pt_regs *regs)
 {
-#ifdef CONFIG_4xx
-	/* We have no MSR_RI bit on 4xx, so we simply return false */
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOK3E)
+	/* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
 	return 0;
 #else
 	return ((regs->msr & MSR_RI) == 0);
-- 
1.7.0.4

^ permalink raw reply related

* Re: I2c driver crash
From: MohanReddy koppula @ 2011-09-23  6:05 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: scottwood, linuxppc-dev, smitha.vanga
In-Reply-To: <1316741319.2629.0.camel@pasglop>

I think the client->adapter pointer is NULL. Make sure the
ds75_attach_adapte() is called before you invoke ioctl().

-Mohan

On Fri, Sep 23, 2011 at 6:58 AM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Thu, 2011-09-22 at 15:25 +0000, smitha.vanga@wipro.com wrote:
>> Hi Scott,
>>
>> When I call if =A0i2c_master_send(&ds75->i2c_client,buffer,2) it
>> crashes. In module initialization I don't see any errors. Below are
>> kernel messages. Could you please let me know what may be the reason
>> for this crash.
>
> Why the heck are you trying to write a new driver for ds75 ? There's
> already one in there (lm75, same thing).
>
> Cheers,
> Ben.
>
>> -----------Logs---------
>> Loading Temperature Sensor Interface module (temp_if.ko)
>> ds75_init
>> DS75_DRIVER : Open
>> DS75_DRIVER : Device Open Successful!
>> DS75_DRIVER =A0: ioctl TEMP_READ cmd 1
>> =A0ds75_temp_read calling i2c_master_send
>> In i2c_master_send enter-------
>> Unable to handle kernel paging request for data at address 0x00000010
>> Faulting instruction address: 0xc01b06a4
>> Oops: Kernel access of bad area, sig: 11 [#1]
>>
>> Modules linked in: temp_if gpio_if
>> NIP: C01B06A4 LR: C01B06A0 CTR: C019BC90
>> REGS: c309bdc0 TRAP: 0300 =A0 Not tainted
>> (2.6.21.7-hrt1-cfs-v22-grsec-WR2.0bl_cgl)
>> MSR: 00009032 <EE,ME,IR,DR> =A0CR: 44004822 =A0XER: 00000000
>> DAR: 00000010, DSISR: 20000000
>> TASK =3D c306f810[145] 'epn412' THREAD: c309a000
>> GPR00: 00007D00 C309BE70 C306F810 C02A0000 00000001 00000001 00000000
>> FDFBD0A0
>> GPR08: 003DE8A0 A827A936 00003F78 C02EAE88 00000001 1011C7C0 03EFD000
>> FFFFFFFF
>> GPR16: 00000001 00000000 007FFC00 37942FA8 1012EAC0 1001E530 37942FB4
>> 00000003
>> GPR24: 37942FB4 00000000 003D0F00 C309BEA8 FFFFFFF7 00000008 C309BEA8
>> 00000002
>> Call Trace:
>> [C309BE70] [C01B0698] =A0(unreliable)
>> [C309BEA0] [C50B71DC]
>> [C309BED0] [C007A0D0]
>> [C309BEE0] [C007A158]
>> [C309BF10] [C007A4EC]
>> [C309BF40] [C000E780]
>> --- Exception: c01Instruction dump:
>> 7c0802a6 bf61001c 7c7d1b78 3c60c02a 386313b4 7cbf2b78 90010034
>> 7c9b2378
>> 4be6bc79 386007d0 4be5ac6d 3c60c02a <839d0008> 386313d8 4be6bc61
>> a01d0004
>>
>>
>>
>>
>> Below is the driver code.
>> -------------------------
>>
>> #include "temp_if.h"
>> #include <asm-powerpc/uaccess.h>
>> #include <linux/i2c.h>
>> //#include <asm/arch/platform.h>
>>
>>
>> #define I2C_DEBUG
>>
>> #ifdef =A0 =A0 =A0I2C_DEBUG
>> #define =A0 =A0 I2C_DBG1(x) =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_=
WARNING x)
>> #define =A0 =A0 I2C_DBG2(x,y) =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_WA=
RNING x,y)
>> #define =A0 =A0 I2C_DBG3(x,y,z) =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_WARN=
ING x,y,z)
>> #define =A0 =A0 I2C_DBG4(w,x,y,z) =A0 =A0 =A0 =A0 =A0 printk(KERN_WARNIN=
G w,x,y,z)
>> #else
>> #define I2C_DBG1(x)
>> #define I2C_DBG2(x,y)
>> #define I2C_DBG3(x,y,z)
>> #define I2C_DBG4(w,x,y,z)
>> #endif
>>
>> /* Function Prototype */
>> static int ds75_open(struct inode *inode, struct file *filp);
>> static int ds75_iotcl(struct inode *inode, struct file *flip, unsigned
>> int cmd, unsigned long arg);
>> static int ds75_release(struct inode *inode, struct file *flip);
>> int ds75_attach_client(struct ds75_data * ds75, struct i2c_adapter
>> *adapter);
>>
>> int ds75_attach_adapter(struct i2c_adapter *adapter);
>> int ds75_detach_client(struct i2c_client *client);
>>
>>
>>
>>
>> /* Structure */
>> static struct file_operations tmpsensor_fops =3D
>> {
>> =A0 =A0 =A0 =A0 ioctl: =A0 =A0 =A0 =A0 =A0ds75_iotcl,
>> =A0 =A0 =A0 =A0 open: =A0 =A0 =A0 =A0 =A0 ds75_open,
>> =A0 =A0 =A0 =A0 release: =A0 =A0 =A0 =A0ds75_release,
>>
>> };
>>
>> static struct i2c_driver ds75_driver =3D {
>> =A0 =A0 =A0 =A0 .driver =3D {
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 .name =A0 =3D "DS75",
>> =A0 =A0 =A0 =A0 },
>> =A0 =A0 =A0 =A0 .attach_adapter =3D ds75_attach_adapter,
>> =A0 =A0 =A0 =A0 .detach_client =A0=3D ds75_detach_client,
>> };
>>
>> /* Global Variable */
>> static int s_nI2CMajor =3D 0;
>> static int s_bI2CDevOpen =3D 0;
>> static int s_nUseCnt =3D 0;
>> struct ds75_data *ds75;
>>
>>
>> static int ds75_open(struct inode *inode, struct file *flip)
>> {
>> =A0 I2C_DBG1( "DS75_DRIVER : Open\n");
>> =A0 if(s_bI2CDevOpen =3D=3D 0)
>> =A0 =A0 {
>> =A0 =A0 =A0 I2C_DBG1("DS75_DRIVER : Device Open Successful!\n");
>> =A0 =A0 =A0 s_bI2CDevOpen =3D 1;
>> =A0 =A0 =A0 s_nUseCnt++;
>>
>> =A0 =A0 }
>> =A0 else
>> =A0 =A0 {
>> =A0 =A0 =A0 I2C_DBG1("DS75_DRIVER : Device Already Opened Successfully!\=
n");
>> =A0 =A0 =A0 s_bI2CDevOpen =3D 1;
>> =A0 =A0 =A0 s_nUseCnt++;
>> =A0 =A0 }
>> =A0 return 0;
>> }
>>
>>
>> static int ds75_release(struct inode *inode, struct file *flip)
>> {
>> =A0 I2C_DBG1 (KERN_INFO "Entering ds75_release\n" );
>> =A0 if(s_bI2CDevOpen)
>> =A0 =A0 {
>> =A0 =A0 =A0 if( s_nUseCnt <=3D 0 )
>> =A0 =A0 =A0 =A0 {
>> =A0 =A0 =A0 =A0 =A0 I2C_DBG1("DS75_DRIVER =A0: i2c driver can't be relea=
sed!\n");
>> =A0 =A0 =A0 =A0 =A0 return -EIO;
>> =A0 =A0 =A0 =A0 }
>> =A0 =A0 =A0 else
>> =A0 =A0 =A0 =A0 {
>> =A0 =A0 =A0 =A0 =A0 I2C_DBG1("DS75_DRIVER =A0: Release Successful!\n");
>> =A0 =A0 =A0 =A0 =A0 s_nUseCnt--;
>> =A0 =A0 =A0 =A0 =A0 if( s_nUseCnt =3D=3D 0 )
>> =A0 =A0 =A0 =A0 =A0 =A0 {
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 s_bI2CDevOpen =3D 0;
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 I2C_DBG1("DS75_DRIVER =A0: I2C Driver is Clo=
sed!\n");
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
>> =A0 =A0 =A0 =A0 }
>> =A0 =A0 =A0 return 0;
>> =A0 =A0 }
>> =A0 else
>> =A0 =A0 {
>> =A0 =A0 =A0 I2C_DBG1("DS75_DRIVER =A0: Release Fail! (Device is Not Open=
)\n");
>> =A0 =A0 =A0 return -EIO;
>> =A0 =A0 }
>> }
>>
>> /*
>> =A0This function will read the Temperature from the device and copies to
>> user space
>> */
>> static int ds75_temp_read(struct ds75_msg_t *pData)
>> {
>> =A0 =A0 =A0//unsigned char buffer[4];
>> =A0 =A0 =A0signed char buffer[4];
>> =A0 =A0 =A0int ret;
>> =A0 =A0 =A0buffer[0]=3D0; =A0/* Writing 0 in to Pointer register. --> Te=
mprature
>> read register */
>> =A0 =A0 =A0if ((ret =3D i2c_master_send(&ds75->i2c_client,buffer,2)) !=
=3D2)
>> =A0 =A0 =A0{
>> =A0 =A0 =A0 =A0 =A0I2C_DBG2("DS75_DRIVER =A0: Error writing to I2C ret =
=3D %d
>> \n",ret);
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return -1;
>> =A0 =A0 =A0}
>>
>> =A0 =A0 =A0/* reading from the temperature read register */
>> =A0 =A0 =A0if (i2c_master_recv(&ds75->i2c_client,buffer,2)!=3D 2)
>> =A0 =A0 =A0{
>> =A0 =A0 =A0 =A0 =A0I2C_DBG1("DS75_DRIVER =A0: Error reading from I2C\n")=
;
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return -1;
>> =A0 =A0 =A0}
>>
>> =A0 =A0 =A0//I2C_DBG3("DS75_DRIVER: data[0] =3D %d, data[1] =3D %d
>> \n",buffer[0],buffer[1]);
>> =A0 =A0 =A0 =A0 //I2C_DBG3("DS75_DRIVER: data[0] =3D %d, data[1] =3D %d
>> \n",buffer[0],buffer[1]);
>>
>> =A0 =A0 =A0/* Copy User Memory Area */
>> =A0 =A0 =A0 =A0 =A0 =A0if(copy_to_user(pData->ReadData,buffer, 2 ) !=3D =
0)
>> =A0 =A0 =A0 =A0 =A0 =A0{
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 I2C_DBG1("DS75_DRIVER =A0: error in copying =
to user
>> space");
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -1;
>> =A0 =A0 =A0 =A0 =A0 =A0}
>>
>> =A0 =A0 =A0return 0; =A0/* Success */
>>
>> }
>>
>>
>> static int ds75_iotcl(struct inode *inode, struct file *flip, unsigned
>> int cmd, unsigned long arg)
>> {
>> =A0 =A0 =A0 =A0 int nRetVal =3D 0;
>>
>> =A0 =A0 =A0 =A0 if( ((struct ds75_msg_t *)arg) =3D=3D NULL ){
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 I2C_DBG1("DS75_DRIVER =A0: ioctl Message=
 Buff must not
>> be NULL\n");
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -EFAULT;
>> =A0 =A0 =A0 =A0 }
>>
>> =A0 =A0 =A0 =A0 switch(cmd){
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 case TEMP_READ:
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 I2C_DBG2("DS75_DRIVER =
=A0: ioctl TEMP_READ cmd %
>> d\n",cmd);
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 nRetVal =3D ds75_temp_re=
ad((struct ds75_msg_t *)
>> arg);
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
>>
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 default:
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Error! */
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 I2C_DBG1("DS75_DRIVER =
=A0: Command =A0not
>> implemented\n");
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 nRetVal =3D -EIO;
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
>> =A0 =A0 =A0 =A0 }
>> =A0 =A0 =A0 =A0 return nRetVal;
>> }
>>
>>
>> /*
>> =A0* =A0i2c_attach_client - tries to detect and initialize slics
>> */
>> int ds75_attach_client(struct ds75_data * ds75, struct i2c_adapter
>> *adapter)
>> {
>> =A0 =A0 =A0 =A0 struct i2c_client * client;
>>
>> =A0 =A0 =A0 =A0 /* register i2c client */
>> =A0 =A0 =A0 =A0 client =3D &ds75->i2c_client;
>> =A0 =A0 =A0 =A0 client->adapter =3D adapter;
>> =A0 =A0 =A0 =A0 client->driver =3D &ds75_driver;
>> // =A0 =A0 =A0client->flags =3D I2C_CLIENT_ALLOW_USE;
>> =A0 client->addr =3D DS75_ADDR;
>> =A0 strlcpy(client->name, "DS75", I2C_NAME_SIZE);
>> =A0 =A0 =A0 =A0 i2c_set_clientdata(client, ds75);
>>
>> =A0 =A0 =A0 =A0 if (i2c_attach_client(client))
>> =A0 =A0 =A0return -1;
>>
>> =A0 =A0 =A0 =A0 printk (KERN_INFO DS75_DRIVER_NAME ": I2C client attache=
d\n");
>> =A0 =A0 =A0 =A0 return 0;
>> }
>>
>> /*
>> =A0* =A0i2c_attach_adapter - initializes the maxim driver
>> */
>> int ds75_attach_adapter(struct i2c_adapter *adapter)
>> {
>> =A0 =A0 =A0 =A0 /* allocate maxim_data structure */
>> =A0 =A0 =A0 =A0 ds75 =3D kmalloc(sizeof (struct ds75_data), GFP_KERNEL);
>> =A0 =A0 =A0 =A0 if (ds75 =3D=3D NULL)
>> =A0 =A0 =A0 =A0 {
>> =A0 =A0 =A0 =A0 =A0 =A0printk (KERN_ERR "Unable to allocate memory for d=
s75 temp
>> sensor driver\n");
>> =A0 =A0 =A0 =A0 =A0 =A0goto err0;
>> =A0 =A0 =A0 =A0 }
>> =A0 =A0 =A0 =A0 memset(ds75, 0, sizeof(struct ds75_data));
>>
>> =A0 =A0 =A0 =A0 /* Attach Spi Client */
>> =A0 =A0 =A0 =A0 if (ds75_attach_client(ds75, adapter) !=3D 0)
>> =A0 =A0 =A0 =A0 {
>> =A0 =A0 =A0 =A0 =A0 =A0printk (KERN_ERR "No ds75 device detected\n");
>> =A0 =A0 =A0 =A0 =A0 =A0goto err1;
>> =A0 =A0 =A0 =A0 }
>>
>> =A0 =A0 =A0 =A0 return 0;
>>
>> err1:
>> =A0 =A0 =A0 =A0 kfree(ds75);
>> err0:
>> =A0 =A0 =A0 =A0 return -1;
>> }
>>
>> /*
>> =A0* =A0i2c_detach_client - cleans up the maxim driver
>> */
>> int ds75_detach_client(struct i2c_client *client)
>> {
>> =A0 =A0 =A0 =A0 struct ds75_data *ds75 =3D i2c_get_clientdata(client);
>>
>> =A0 =A0 =A0 =A0 if (ds75->owned_irq)
>> =A0 =A0 =A0 =A0 {
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 free_irq(ds75->irq, ds75);
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ds75->owned_irq =3D 0;
>>
>> =A0 =A0 =A0 =A0 }
>>
>> =A0 =A0 =A0 =A0 i2c_detach_client(&ds75->i2c_client);
>>
>> =A0 =A0 =A0 =A0 kfree (ds75); =A0 =A0 =A0// Free the kernel memory */
>>
>> =A0 =A0 =A0 =A0 return 0;
>> }
>>
>>
>>
>>
>> /*
>> =A0* Temperature sensor DS75 init -
>> =A0*
>> =A0*/
>> int __init ds75_init(void)
>> {
>> =A0 =A0 =A0 =A0 int rc;
>> =A0 =A0 =A0 =A0 rc =3D i2c_add_driver(&ds75_driver);
>> =A0 =A0 =A0 =A0 if (rc)
>> =A0 =A0 =A0 =A0 {
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk (KERN_ERR DS75_DRIVER_NAME ": una=
ble to add
>> driver\n");
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return rc;
>> =A0 =A0 =A0 =A0 }
>>
>> =A0 =A0 =A0 =A0 rc =3D register_chrdev (DS75_DEVICE_MAJOR_NUM, DS75_DRIV=
ER_NAME,
>> &tmpsensor_fops);
>> =A0 =A0 =A0 =A0 if (rc)
>> =A0 =A0 =A0 =A0 {
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk (KERN_ERR DS75_DRIVER_NAME ": una=
ble to
>> register char device\n");
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return rc;
>> =A0 =A0 =A0 =A0 }
>>
>> =A0 =A0 =A0 =A0 return 0;
>> }
>>
>> /**
>> =A0* maxim _exit -
>> =A0*
>> =A0*
>> =A0*/
>> void __exit ds75_exit(void)
>> {
>> =A0 =A0 =A0 =A0 unregister_chrdev (DS75_DEVICE_MAJOR_NUM, DS75_DRIVER_NA=
ME);
>>
>> =A0 =A0 =A0 =A0 i2c_del_driver(&ds75_driver);
>> }
>>
>> MODULE_AUTHOR("xxxx");
>> MODULE_DESCRIPTION("DS75 I2C driver");
>> MODULE_LICENSE("GPL");
>>
>> module_init(ds75_init);
>> module_exit(ds75_exit);
>>
>>
>> Regards,
>> Smitha
>>
>> Please do not print this email unless it is absolutely necessary.
>>
>> The information contained in this electronic message and any
>> attachments to this message are intended for the exclusive use of the
>> addressee(s) and may contain proprietary, confidential or privileged
>> information. If you are not the intended recipient, you should not
>> disseminate, distribute or copy this e-mail. Please notify the sender
>> immediately and destroy all copies of this message and any
>> attachments.
>>
>> WARNING: Computer viruses can be transmitted via email. The recipient
>> should check this email and any attachments for the presence of
>> viruses. The company accepts no liability for any damage caused by any
>> virus transmitted by this email.
>>
>> www.wipro.com
>>
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>

^ permalink raw reply

* [PATCH] [v2] drivers/tty: don't use the byte channel handle as a parameter in ehv_bytechan.c
From: Timur Tabi @ 2011-09-23  1:33 UTC (permalink / raw)
  To: greg, linuxppc-dev, linux-kernel

The ePAPR hypervisor byte channel console driver only supports one byte
channel as a console, and the byte channel handle is stored in a global
variable.  It doesn't make any sense to pass that handle as a parameter
to the console functions, since these functions already have access to the
global variable.

Signed-off-by: Timur Tabi <timur@freescale.com>
---
 drivers/tty/ehv_bytechan.c |    7 ++-----
 1 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c
index f733718..1595dba 100644
--- a/drivers/tty/ehv_bytechan.c
+++ b/drivers/tty/ehv_bytechan.c
@@ -282,7 +282,6 @@ static int ehv_bc_console_byte_channel_send(unsigned int handle, const char *s,
 static void ehv_bc_console_write(struct console *co, const char *s,
 				 unsigned int count)
 {
-	unsigned int handle = (uintptr_t)co->data;
 	char s2[EV_BYTE_CHANNEL_MAX_BYTES];
 	unsigned int i, j = 0;
 	char c;
@@ -295,14 +294,14 @@ static void ehv_bc_console_write(struct console *co, const char *s,
 
 		s2[j++] = c;
 		if (j >= (EV_BYTE_CHANNEL_MAX_BYTES - 1)) {
-			if (ehv_bc_console_byte_channel_send(handle, s2, j))
+			if (ehv_bc_console_byte_channel_send(stdout_bc, s2, j))
 				return;
 			j = 0;
 		}
 	}
 
 	if (j)
-		ehv_bc_console_byte_channel_send(handle, s2, j);
+		ehv_bc_console_byte_channel_send(stdout_bc, s2, j);
 }
 
 /*
@@ -348,8 +347,6 @@ static int __init ehv_bc_console_init(void)
 			   CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE);
 #endif
 
-	ehv_bc_console.data = (void *)(uintptr_t)stdout_bc;
-
 	/* add_preferred_console() must be called before register_console(),
 	   otherwise it won't work.  However, we don't want to enumerate all the
 	   byte channels here, either, since we only care about one. */
-- 
1.7.4.4

^ permalink raw reply related


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