* Re: [PATCH 6/7] [POWERPC] mpc8568mds.dts: fix PCI/PCIe nodes
From: Scott Wood @ 2007-10-05 18:01 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: linuxppc-dev
In-Reply-To: <47067ADE.9060306@ru.mvista.com>
On Fri, Oct 05, 2007 at 09:56:46PM +0400, Sergei Shtylyov wrote:
> Hello.
>
> Anton Vorontsov wrote:
>
> > Commit 5bece127f0666996ca90772229e00332a34e516c tried to fix
> > PCI/PCIe nodes, but actually it broke them even harder. ;-)
>
> Of course. But shouldn't those be the subnoses of the "soc" type node?
No -- the soc node is for immr/ccsr only, and while the PCI control
registers are there, the ranges are not. There was a lengthy discussion on
IRC about this a couple weeks ago. It'd be cleaner to split the control
node from the bus node, and connect them with phandles, but some people
didn't like that, and this is what we compromised on.
-Scott
^ permalink raw reply
* Re: [PATCH 6/7] [POWERPC] mpc8568mds.dts: fix PCI/PCIe nodes
From: Anton Vorontsov @ 2007-10-05 18:05 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: linuxppc-dev
In-Reply-To: <47067ADE.9060306@ru.mvista.com>
On Fri, Oct 05, 2007 at 09:56:46PM +0400, Sergei Shtylyov wrote:
> Hello.
>
> Anton Vorontsov wrote:
>
>> Commit 5bece127f0666996ca90772229e00332a34e516c tried to fix
>> PCI/PCIe nodes, but actually it broke them even harder. ;-)
>
> Of course. But shouldn't those be the subnoses of the "soc" type node?
Nope. PCI's ranges = <>; isn't in the SOC address space.
Valentine Barshak posted a patch titled "[RFC] [PATCH] PowerPC: Add 64-bit
phys addr support to 32-bit pci" that started using of_translate_address()
for ranges, and of_translate_address() will not work if PCI placed in the
SOC node. Not sure if that patch applied or not, though.
Good luck,
--
Anton Vorontsov
email: cbou@mail.ru
backup email: ya-cbou@yandex.ru
irc://irc.freenode.net/bd2
^ permalink raw reply
* Re: [PATCH 5/6] PowerPC 440EPx: Sequoia board support
From: Valentine Barshak @ 2007-10-05 18:36 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, Stefan Roese
In-Reply-To: <1186144536.5981.5.camel@gruick>
Benjamin Herrenschmidt wrote:
>> Depends on interpretation. IIRC currently the same die is used for 440EPx and
>> 440GRx. I could be wrong here though and it is just a bug in the chip. But
>> anyway we should support this somehow. Could be that I missed this in the
>> current 440GRx (Rainier) arch/ppc support too. I have to admit, that no
>> clever solution comes to my mind right away though.
>
> We can always come up with some kind of runtime detection, by turning on
> MSR:FP, issuing an fp instruction and catching the illegal instruction
> fault if any :-)
>
> Ben.
>
>
Is it OK to workaround the GRX/EPX having the same PVR issue using
device tree?
Say, check the PVR value and if we have 440EPx PVR, but 440GRX node in
the device tree, fix the cputable entry and omit FPU initialization code.
Thanks,
Valentine.
^ permalink raw reply
* Re: Device tree and external RTC
From: Bruce_Leonard @ 2007-10-05 19:37 UTC (permalink / raw)
To: Guennadi Liakhovetski; +Cc: Peter Korsgaard, linuxppc-embedded
In-Reply-To: <Pine.LNX.4.60.0710051242050.5434@poirot.grange>
Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote on 10/05/2007 03:45:27
AM:
> Ok, we both (Peter and myself) have forgotten, that this change has
first
> aooeared after 2.6.22. So, best try 2.6.23-rc9, or use one of the
> git-trees (from Linux or from Paulus, or from Kumar Gala, or...) _plus_
> the patch we both pointed at.
Thanks Guennadi, that's what I was starting to think, that I was going to
have to get something newer. Thanks to both you and Peter for the help. I
really appreciate it.
Bruce
^ permalink raw reply
* Re: [PATCH 6/7] [POWERPC] mpc8568mds.dts: fix PCI/PCIe nodes
From: Kumar Gala @ 2007-10-05 20:58 UTC (permalink / raw)
To: avorontsov; +Cc: linuxppc-dev
In-Reply-To: <20071005180553.GA32405@localhost.localdomain>
On Oct 5, 2007, at 1:05 PM, Anton Vorontsov wrote:
> On Fri, Oct 05, 2007 at 09:56:46PM +0400, Sergei Shtylyov wrote:
>> Hello.
>>
>> Anton Vorontsov wrote:
>>
>>> Commit 5bece127f0666996ca90772229e00332a34e516c tried to fix
>>> PCI/PCIe nodes, but actually it broke them even harder. ;-)
>>
>> Of course. But shouldn't those be the subnoses of the "soc"
>> type node?
>
> Nope. PCI's ranges = <>; isn't in the SOC address space.
>
> Valentine Barshak posted a patch titled "[RFC] [PATCH] PowerPC: Add
> 64-bit
> phys addr support to 32-bit pci" that started using
> of_translate_address()
> for ranges, and of_translate_address() will not work if PCI placed
> in the
> SOC node. Not sure if that patch applied or not, though.
I'm confused, what's the actual issue with PCI that this patch
addresses?
- k
^ permalink raw reply
* Re: [RFC] [PATCH] PowerPC: add more than 4MB kernel image size support to bootwarapper
From: Mark A. Greer @ 2007-10-05 21:03 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20071005173054.GA4295@loki.buserror.net>
On Fri, Oct 05, 2007 at 12:30:54PM -0500, Scott Wood wrote:
> On Thu, Oct 04, 2007 at 06:58:49PM -0700, Mark A. Greer wrote:
> > Having the link address jump around depending on the size of the kernel
> > or zImage is wrong IMHO. It just screams "weird can't boot issues."
> > We need a way to specify exactly where we want the zImage linked no
> > matter what the kernel or zImage size.
>
> Why?
Why? Because its only safe to download a zImage to certain "safe" locations.
Where those "safe" locations are vary by firmware, firmware version, and
zImage size. This is the issue we're discussing.
I've already explained _why_ the link address matters WRT where its downloaded.
> The zImage is relocatable. It doesn't matter where it's linked.
We know...and a zImage running at an address it wasn't linked at is
not the issue.
> > Also, being able to control the link address (that is, the download
> > address with some firmwares) is not a u-boot specific issue and we
> > shouldn't make a u-boot specific solution.
>
> How is this a u-boot specific solution?
Because the hoops being jumped through in the patch(es) are to make
u-boot happy and no other firmware.
> > The more general problem is that some firmwares examine the ELF header
> > and download the zImage to address it was linked at. Some firmwares let
> > you override this but some don't and those are the problem ones.
>
> That's not the more general problem; it's the same problem with a different
> file format.
True, I misspoke. I'll restate it this way:
The more general problem is that some firmwares will only download to
the address the zImage is linked at. So, we need to control what that
link address is."
> > I still like my idea best. I haven't coded yet it so I don't have a patch
> > but this is what I mean:
> >
> > 1) add a config option (default 4MB) for the link address
> > 2) add a parameter to the wrapper script thru which we pass the value in
> > the config option
> > 3) the wrapper script changes the VMA/LMA to the address specified
> > (objcopy --change-addresses=<some math to get correct incr> ?).
>
> I'd much rather it be automatic than require the user to guess an
> appropriate value (and be aware in the first place that it needs to be set).
Sure, automatic is nice; conjuring up the magic to make it work in all
situations isn't.
Having the link address--and therefore the download address on some
systems--mysteriously and uncontrollably jump around based on the zImage
size is asking for trouble.
Mark
^ permalink raw reply
* Re: [PATCH respin 0/7] MPC8568E-MDS related patches
From: Kumar Gala @ 2007-10-05 22:09 UTC (permalink / raw)
To: avorontsov; +Cc: linuxppc-dev
In-Reply-To: <20071005174015.GA11016@localhost.localdomain>
On Oct 5, 2007, at 12:40 PM, Anton Vorontsov wrote:
> Hello Kumar,
>
> This is respin of MPC8568E-MDS patches, on top of master branch
> as of today.
>
> If there are no objections against SPI patch, please Ack it, thus
> David could pick it up.
I've applied patches 1-5 however I'm not able to get UCC enet working
on my board. Is there something special that has to be done? (I've
got the card standalone, no MDS backplane).
I'm using the 1.3.0-rc2 u-boot w/o any modifications.
Also, I tried a PCIe e1000 card w/the .dts that's in my tree and that
works w/o any issue.
- k
^ permalink raw reply
* Re: [PATCH 5/6] PowerPC 440EPx: Sequoia board support
From: Benjamin Herrenschmidt @ 2007-10-05 22:17 UTC (permalink / raw)
To: Valentine Barshak; +Cc: linuxppc-dev, Stefan Roese
In-Reply-To: <47068433.7060803@ru.mvista.com>
On Fri, 2007-10-05 at 22:36 +0400, Valentine Barshak wrote:
> Benjamin Herrenschmidt wrote:
> >> Depends on interpretation. IIRC currently the same die is used for 440EPx and
> >> 440GRx. I could be wrong here though and it is just a bug in the chip. But
> >> anyway we should support this somehow. Could be that I missed this in the
> >> current 440GRx (Rainier) arch/ppc support too. I have to admit, that no
> >> clever solution comes to my mind right away though.
> >
> > We can always come up with some kind of runtime detection, by turning on
> > MSR:FP, issuing an fp instruction and catching the illegal instruction
> > fault if any :-)
> >
> > Ben.
> >
> >
>
> Is it OK to workaround the GRX/EPX having the same PVR issue using
> device tree?
> Say, check the PVR value and if we have 440EPx PVR, but 440GRX node in
> the device tree, fix the cputable entry and omit FPU initialization code.
Fixing the CPU features based on the tree is definitely legit. We do
that on pseries. In fact, with paulus latest patch, the cputable is
__initdata and the cur CPU features is a -copy- which makes it even more
legitimate to whack it.
Ben.
^ permalink raw reply
* [PATCH] Fix non-terminated PCI match table in PowerMac IDE
From: Benjamin Herrenschmidt @ 2007-10-06 8:52 UTC (permalink / raw)
To: Linus Torvalds
Cc: Bartlomiej Zolnierkiewicz, linuxppc-dev list, Heikki Lindholm,
Paul Mackerras
The PCI device table in the powermac IDE driver isn't properly
terminated. Depending on how your kernel is linked and other random
factors, you can end up with this driver matched against any other PCI
device in your system, possibly crashing at boot.
Thanks to Heikki for tracking this down with me, the bug have been there
for some time, though it rarely hurts due to luck. In this case, the
switch from .22 to .23-rc9 is causing it to show up due to differences
in the resulting layout of .data I suppose.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
If that can still make it in .23, that would be great. I'll also get it
in the various -stable releases.
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index f19eb6d..2fb047b 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1546,6 +1546,7 @@ static struct pci_device_id pmac_ide_pci_match[] = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID2_ATA,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {},
};
static struct pci_driver pmac_ide_pci_driver = {
^ permalink raw reply related
* [PATCH 00/15] [POWERPC] TQM5200, CM5200 and Motion-PRO support
From: Marian Balakowicz @ 2007-10-06 10:12 UTC (permalink / raw)
To: linuxppc-dev
Hello,
The following series of patches adds arch/powerpc support for three MPC5200 based boards:
TQM5200, CM5200 and Motion-PRO.
Included are also patches with modifications to common 52xx code. New helper
routine mpc52xx_find_and_map_path() is added, and is being used in LED driver
for Motion-PRO. Another patch adds mpc52xx_restart(), mpc52xx_halt()
and mpc52xx_power_off(). This modification has been around for some time now
and relies on Sascha Hauer's patch.
01/15 [POWERPC] TQM5200 DTS
02/15 [POWERPC] TQM5200 defconfig
03/15 [POWERPC] TQM5200 board support
04/15 [POWERPC] cm5200 DTS
05/15 [POWERPC] cm5200 defconfig
06/15 [POWERPC] cm5200 board support
07/15 [POWERPC] Promess motionpro DTS
08/15 [POWERPC] Promess motionpro defconfig
09/15 [POWERPC] Promess motionpro board support
10/15 [POWERPC] Add mpc52xx_find_and_map_path(), refactor utility functions.
11/15 [POWERPC] Motion-PRO: Add LED support.
12/15 [POWERPC] Add mpc52xx_restart(), mpc52xx_halt(), mpc52xx_power_off().
13/15 [POWERPC] Init restart/halt/power_off machine hooks for tqm5200.
14/15 [POWERPC] Init restart/halt/power_off machine hooks for cm5200.
15/15 [POWERPC] Init restart/halt/power_off machine hooks for motionpro.
Comments and review notes are welcome.
Cheers,
Marian Balakowicz
^ permalink raw reply
* TASK_SIZE default 0x80000000 ?
From: Kumar Gala @ 2007-10-06 13:36 UTC (permalink / raw)
To: PowerPC dev list; +Cc: Benjamin Herrenschmidt, Paul Mackerras
In a discussion with Hollis over beer he raised the question why
TASK_SIZE is 0x80000000 on ppc32.
I was wondering if anyone know why this was still the case? Seems
like we have a 1Gb whole between TASK_SIZE & KERNELBASE.
- k
^ permalink raw reply
* Re: TASK_SIZE default 0x80000000 ?
From: Dan Malek @ 2007-10-06 17:22 UTC (permalink / raw)
To: Kumar Gala; +Cc: PowerPC dev list, Benjamin Herrenschmidt, Paul Mackerras
In-Reply-To: <C2771B73-A555-4119-AC21-1441D4CC2125@freescale.com>
On Oct 6, 2007, at 6:36 AM, Kumar Gala wrote:
> In a discussion with Hollis over beer he raised the question why
> TASK_SIZE is 0x80000000 on ppc32.
Left over from the old days (2.1) of the PReP port when
things were hard coded. We used some of the space
between 0x80000000 and 0xc0000000 for mapping
IO devices in the kernel.
> I was wondering if anyone know why this was still the case? Seems
> like we have a 1Gb whole between TASK_SIZE & KERNELBASE.
I thought all of this was now configurable in the
advanced options. The configuration files should
set the default to remove this gap.
-- Dan
^ permalink raw reply
* Re: [PATCH] fsl_spi_init: Support non-QE processors
From: Peter Korsgaard @ 2007-10-06 20:06 UTC (permalink / raw)
To: Kumar Gala; +Cc: PowerPC dev list, Stephen Rothwell
In-Reply-To: <17D08E8E-6ADC-4D61-8859-8329EDD4DC6D@kernel.crashing.org>
>>>>> "Kumar" == Kumar Gala <galak@kernel.crashing.org> writes:
Kumar> On Oct 3, 2007, at 11:01 PM, Stephen Rothwell wrote:
>> On Wed, 03 Oct 2007 17:43:50 +0200 Peter Korsgaard
>> <jacmet@sunsite.dk> wrote:
>>>
>>> @@ -1220,14 +1220,17 @@ int __init fsl_spi_init(struct
>>> spi_board_info *board_infos,
>>> {
>>> struct device_node *np;
>>> unsigned int i;
>>> - const u32 *sysclk;
>>> + const u32 *qe_sysclk = 0, *soc_sysclk = 0;
>>
>> Please use NULL when referring to pointers.
Kumar> Peter, any chance of getting a respin. I'd like this to go
Kumar> into 2.6.24.
Certainly. Sorry for the delay, I have been offline for 2 days
building my house ..
---
fsl_spi_init: Support non-QE processors
On non-QE processors (mpc831x/mpc834x) the SPI clock is the SoC clock.
Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
---
arch/powerpc/sysdev/fsl_soc.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index be5e0bd..3ace747 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -1222,8 +1222,12 @@ int __init fsl_spi_init(struct spi_board_info *board_infos,
unsigned int i;
const u32 *sysclk;
+ /* SPI controller is either clocked from QE or SoC clock */
np = of_find_node_by_type(NULL, "qe");
if (!np)
+ np = of_find_node_by_type(NULL, "soc");
+
+ if (!np)
return -ENODEV;
sysclk = of_get_property(np, "bus-frequency", NULL);
--
1.5.3.2
--
Bye, Peter Korsgaard
^ permalink raw reply related
* Where are inb/outb macros?
From: Peter Lemenkov @ 2007-10-06 20:47 UTC (permalink / raw)
To: linuxppc-dev
Hello All!
I can't compile one small software title because of lack <sys/io.h>
and inb/outb macros. What sould I do to overcome this obstacle?
My linux distro is Fedora 7 if it is matter.
--
With best regards!
^ permalink raw reply
* Re: Where are inb/outb macros?
From: Benjamin Herrenschmidt @ 2007-10-06 21:08 UTC (permalink / raw)
To: Peter Lemenkov; +Cc: linuxppc-dev
In-Reply-To: <adf480660710061347l59903ba6vf6b327db674606a9@mail.gmail.com>
On Sun, 2007-10-07 at 00:47 +0400, Peter Lemenkov wrote:
> Hello All!
> I can't compile one small software title because of lack <sys/io.h>
> and inb/outb macros. What sould I do to overcome this obstacle?
>
> My linux distro is Fedora 7 if it is matter.
They don't exist in user space on non-x86. You have to do things
differently. What is your software trying to do ? If it's trying to
access a PCI device IO space, you probably want to mmap it in sysfs and
write your own accessors with appropriate memory barriers.
Ben
^ permalink raw reply
* [patch 5/6] PS3: Save os-area params to device tree
From: geoffrey.levand @ 2007-10-06 21:35 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20071006213542.311447584@am.sony.com>
Add the PS3 os-area startup params to the device tree. This allows
a second stage kernel loaded with kexec to use these values.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/platforms/ps3/os-area.c | 104 +++++++++++++++++++++++++++++++++-
arch/powerpc/platforms/ps3/platform.h | 1
arch/powerpc/platforms/ps3/setup.c | 1
3 files changed, 104 insertions(+), 2 deletions(-)
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -119,10 +119,65 @@ struct os_area_params {
*/
struct saved_params {
+ unsigned int valid;
s64 rtc_diff;
unsigned int av_multi_out;
} static saved_params;
+static struct property property_rtc_diff = {
+ .name = "linux,rtc_diff",
+ .length = sizeof(saved_params.rtc_diff),
+ .value = &saved_params.rtc_diff,
+};
+
+static struct property property_av_multi_out = {
+ .name = "linux,av_multi_out",
+ .length = sizeof(saved_params.av_multi_out),
+ .value = &saved_params.av_multi_out,
+};
+
+/**
+ * os_area_set_property - Add or overwrite a saved_params value to the device tree.
+ *
+ * Overwrites an existing property.
+ */
+
+static void os_area_set_property(struct device_node *node,
+ struct property *prop)
+{
+ int result;
+ struct property *tmp = of_find_property(node, prop->name, NULL);
+
+ if (tmp) {
+ pr_debug("%s:%d found %s\n", __func__, __LINE__, prop->name);
+ prom_remove_property(node, tmp);
+ }
+
+ result = prom_add_property(node, prop);
+
+ if (result)
+ pr_debug("%s:%d prom_set_property failed\n", __func__,
+ __LINE__);
+}
+
+/**
+ * os_area_get_property - Get a saved_params value from the device tree.
+ *
+ */
+
+static void __init os_area_get_property(struct device_node *node,
+ struct property *prop)
+{
+ const struct property *tmp = of_find_property(node, prop->name, NULL);
+
+ if (tmp) {
+ BUG_ON(prop->length != tmp->length);
+ memcpy(prop->value, tmp->value, prop->length);
+ } else
+ pr_debug("%s:%d not found %s\n", __func__, __LINE__,
+ prop->name);
+}
+
#define dump_header(_a) _dump_header(_a, __func__, __LINE__)
static void _dump_header(const struct os_area_header *h, const char *func,
int line)
@@ -196,8 +251,19 @@ static int __init verify_header(const st
static void os_area_queue_work_handler(struct work_struct *work)
{
+ struct device_node *node;
+
pr_debug(" -> %s:%d\n", __func__, __LINE__);
+ node = of_find_node_by_path("/");
+
+ if (node) {
+ os_area_set_property(node, &property_rtc_diff);
+ of_node_put(node);
+ } else
+ pr_debug("%s:%d of_find_node_by_path failed\n",
+ __func__, __LINE__);
+
pr_debug(" <- %s:%d\n", __func__, __LINE__);
}
@@ -244,6 +310,8 @@ void __init ps3_os_area_save_params(void
result = verify_header(header);
if (result) {
+ /* Second stage kernels exit here. */
+
pr_debug("%s:%d verify_header failed\n", __func__, __LINE__);
dump_header(header);
return;
@@ -254,6 +322,7 @@ void __init ps3_os_area_save_params(void
saved_params.rtc_diff = params->rtc_diff;
saved_params.av_multi_out = params->av_multi_out;
+ saved_params.valid = 1;
memset(header, 0, sizeof(*header));
@@ -261,13 +330,44 @@ void __init ps3_os_area_save_params(void
}
/**
+ * ps3_os_area_init - Setup os area device tree properties as needed.
+ */
+
+void __init ps3_os_area_init(void)
+{
+ struct device_node *node;
+
+ pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+ node = of_find_node_by_path("/");
+
+ if (!saved_params.valid && node) {
+ /* Second stage kernels should have a dt entry. */
+ os_area_get_property(node, &property_rtc_diff);
+ os_area_get_property(node, &property_av_multi_out);
+ }
+
+ if(!saved_params.rtc_diff)
+ saved_params.rtc_diff = SECONDS_FROM_1970_TO_2000;
+
+ if (node) {
+ os_area_set_property(node, &property_rtc_diff);
+ os_area_set_property(node, &property_av_multi_out);
+ of_node_put(node);
+ } else
+ pr_debug("%s:%d of_find_node_by_path failed\n",
+ __func__, __LINE__);
+
+ pr_debug(" <- %s:%d\n", __func__, __LINE__);
+}
+
+/**
* ps3_os_area_get_rtc_diff - Returns the rtc diff value.
*/
u64 ps3_os_area_get_rtc_diff(void)
{
- return saved_params.rtc_diff ? saved_params.rtc_diff
- : SECONDS_FROM_1970_TO_2000;
+ return saved_params.rtc_diff;
}
/**
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -63,6 +63,7 @@ int ps3_set_rtc_time(struct rtc_time *ti
/* os area */
void __init ps3_os_area_save_params(void);
+void __init ps3_os_area_init(void);
u64 ps3_os_area_get_rtc_diff(void);
void ps3_os_area_set_rtc_diff(u64 rtc_diff);
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -206,6 +206,7 @@ static void __init ps3_setup_arch(void)
prealloc_ps3flash_bounce_buffer();
ppc_md.power_save = ps3_power_save;
+ ps3_os_area_init();
DBG(" <- %s:%d\n", __func__, __LINE__);
}
--
^ permalink raw reply
* [patch 1/6] PS3: Cleanup of os-area.c
From: geoffrey.levand @ 2007-10-06 21:35 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20071006213542.311447584@am.sony.com>
Minor cleanup of the PS3 file os-area.c:
o Correct file text header.
o Add type names enum os_area_ldr_format, enum os_area_boot_flag,
enum os_area_ctrl_button.
o Change struct os_area_header.magic_num type to u8.
o Add preprocessor macro SECONDS_FROM_1970_TO_2000.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/platforms/ps3/os-area.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -1,5 +1,5 @@
/*
- * PS3 'Other OS' area data.
+ * PS3 flash memory os area.
*
* Copyright (C) 2006 Sony Computer Entertainment Inc.
* Copyright 2006 Sony Corp.
@@ -29,7 +29,7 @@ enum {
OS_AREA_SEGMENT_SIZE = 0X200,
};
-enum {
+enum os_area_ldr_format {
HEADER_LDR_FORMAT_RAW = 0,
HEADER_LDR_FORMAT_GZIP = 1,
};
@@ -50,7 +50,7 @@ enum {
*/
struct os_area_header {
- s8 magic_num[16];
+ u8 magic_num[16];
u32 hdr_version;
u32 os_area_offset;
u32 ldr_area_offset;
@@ -60,12 +60,12 @@ struct os_area_header {
u32 _reserved_2[6];
};
-enum {
+enum os_area_boot_flag {
PARAM_BOOT_FLAG_GAME_OS = 0,
PARAM_BOOT_FLAG_OTHER_OS = 1,
};
-enum {
+enum os_area_ctrl_button {
PARAM_CTRL_BUTTON_O_IS_YES = 0,
PARAM_CTRL_BUTTON_X_IS_YES = 1,
};
@@ -84,6 +84,9 @@ enum {
* @dns_primary: User preference of static primary dns server.
* @dns_secondary: User preference of static secondary dns server.
*
+ * The ps3 rtc maintains a read-only value that approximates seconds since
+ * 2000-01-01 00:00:00 UTC.
+ *
* User preference of zero for static_ip_addr means use dhcp.
*/
@@ -108,6 +111,8 @@ struct os_area_params {
u8 _reserved_5[8];
};
+#define SECONDS_FROM_1970_TO_2000 946684800LL
+
/**
* struct saved_params - Static working copies of data from the 'Other OS' area.
*
@@ -213,7 +218,8 @@ int __init ps3_os_area_init(void)
}
header = (struct os_area_header *)__va(lpar_addr);
- params = (struct os_area_params *)__va(lpar_addr + OS_AREA_SEGMENT_SIZE);
+ params = (struct os_area_params *)__va(lpar_addr
+ + OS_AREA_SEGMENT_SIZE);
result = verify_header(header);
@@ -238,16 +244,13 @@ int __init ps3_os_area_init(void)
}
/**
- * ps3_os_area_rtc_diff - Returns the ps3 rtc diff value.
- *
- * The ps3 rtc maintains a value that approximates seconds since
- * 2000-01-01 00:00:00 UTC. Returns the exact number of seconds from 1970 to
- * 2000 when saved_params.rtc_diff has not been properly set up.
+ * ps3_os_area_rtc_diff - Returns the rtc diff value.
*/
u64 ps3_os_area_rtc_diff(void)
{
- return saved_params.rtc_diff ? saved_params.rtc_diff : 946684800UL;
+ return saved_params.rtc_diff ? saved_params.rtc_diff
+ : SECONDS_FROM_1970_TO_2000;
}
/**
--
^ permalink raw reply
* [patch 0/6] PS3 os area patches for 2.6.24
From: geoffrey.levand @ 2007-10-06 21:35 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
Paul,
This is a small set of patches that reworks and improves
the 'other os' area of the PS3's flash rom.
Please apply for 2.6.24.
-Geoff
--
^ permalink raw reply
* [patch 2/6] PS3: Remove unused os-area params
From: geoffrey.levand @ 2007-10-06 21:35 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20071006213542.311447584@am.sony.com>
Updates for PS3 os-area startup params
o Remove some unused PS3 os-area startup params from struct saved_params.
o Rename ps3_os_area_init() to ps3_os_area_save_params().
o Zero mirrored header after saving params.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/platforms/ps3/os-area.c | 44 ++++++++++++++--------------------
arch/powerpc/platforms/ps3/platform.h | 2 -
arch/powerpc/platforms/ps3/setup.c | 2 -
3 files changed, 21 insertions(+), 27 deletions(-)
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -114,27 +114,12 @@ struct os_area_params {
#define SECONDS_FROM_1970_TO_2000 946684800LL
/**
- * struct saved_params - Static working copies of data from the 'Other OS' area.
- *
- * For the convinience of the guest, the HV makes a copy of the 'Other OS' area
- * in flash to a high address in the boot memory region and then puts that RAM
- * address and the byte count into the repository for retreval by the guest.
- * We copy the data we want into a static variable and allow the memory setup
- * by the HV to be claimed by the lmb manager.
+ * struct saved_params - Static working copies of data from the PS3 'os area'.
*/
struct saved_params {
- /* param 0 */
s64 rtc_diff;
unsigned int av_multi_out;
- unsigned int ctrl_button;
- /* param 1 */
- u8 static_ip_addr[4];
- u8 network_mask[4];
- u8 default_gateway[4];
- /* param 2 */
- u8 dns_primary[4];
- u8 dns_secondary[4];
} static saved_params;
#define dump_header(_a) _dump_header(_a, __func__, __LINE__)
@@ -201,7 +186,17 @@ static int __init verify_header(const st
return 0;
}
-int __init ps3_os_area_init(void)
+/**
+ * ps3_os_area_save_params - Copy data from os area mirror to @saved_params.
+ *
+ * For the convenience of the guest, the HV makes a copy of the os area in
+ * flash to a high address in the boot memory region and then puts that RAM
+ * address and the byte count into the repository for retreval by the guest.
+ * We copy the data we want into a static variable and allow the memory setup
+ * by the HV to be claimed by the lmb manager.
+ */
+
+void __init ps3_os_area_save_params(void)
{
int result;
u64 lpar_addr;
@@ -209,12 +204,14 @@ int __init ps3_os_area_init(void)
struct os_area_header *header;
struct os_area_params *params;
+ pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
result = ps3_repository_read_boot_dat_info(&lpar_addr, &size);
if (result) {
pr_debug("%s:%d ps3_repository_read_boot_dat_info failed\n",
__func__, __LINE__);
- return result;
+ return;
}
header = (struct os_area_header *)__va(lpar_addr);
@@ -226,7 +223,7 @@ int __init ps3_os_area_init(void)
if (result) {
pr_debug("%s:%d verify_header failed\n", __func__, __LINE__);
dump_header(header);
- return -EIO;
+ return;
}
dump_header(header);
@@ -234,13 +231,10 @@ int __init ps3_os_area_init(void)
saved_params.rtc_diff = params->rtc_diff;
saved_params.av_multi_out = params->av_multi_out;
- saved_params.ctrl_button = params->ctrl_button;
- memcpy(saved_params.static_ip_addr, params->static_ip_addr, 4);
- memcpy(saved_params.network_mask, params->network_mask, 4);
- memcpy(saved_params.default_gateway, params->default_gateway, 4);
- memcpy(saved_params.dns_secondary, params->dns_secondary, 4);
- return result;
+ memset(header, 0, sizeof(*header));
+
+ pr_debug(" <- %s:%d\n", __func__, __LINE__);
}
/**
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -62,7 +62,7 @@ int ps3_set_rtc_time(struct rtc_time *ti
/* os area */
-int __init ps3_os_area_init(void);
+void __init ps3_os_area_save_params(void);
u64 ps3_os_area_rtc_diff(void);
/* spu */
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -228,7 +228,7 @@ static int __init ps3_probe(void)
powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE;
- ps3_os_area_init();
+ ps3_os_area_save_params();
ps3_mm_init();
ps3_mm_vas_create(&htab_size);
ps3_hpte_init(htab_size);
--
^ permalink raw reply
* [patch 3/6] PS3: os-area workqueue processing
From: geoffrey.levand @ 2007-10-06 21:35 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20071006213542.311447584@am.sony.com>
Add a workqueue to the PS3 os-area support. This is needed to
support writing updates to flash memory and to update the /proc
device tree entries from the timer tick interrupt context.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/platforms/ps3/os-area.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/io.h>
+#include <linux/workqueue.h>
#include <asm/lmb.h>
@@ -187,6 +188,28 @@ static int __init verify_header(const st
}
/**
+ * os_area_queue_work_handler - Asynchronous write handler.
+ *
+ * An asynchronous write for flash memory and the device tree. Do not
+ * call directly, use os_area_queue_work().
+ */
+
+static void os_area_queue_work_handler(struct work_struct *work)
+{
+ pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+ pr_debug(" <- %s:%d\n", __func__, __LINE__);
+}
+
+static void os_area_queue_work(void)
+{
+ static DECLARE_WORK(q, os_area_queue_work_handler);
+
+ wmb();
+ schedule_work(&q);
+}
+
+/**
* ps3_os_area_save_params - Copy data from os area mirror to @saved_params.
*
* For the convenience of the guest, the HV makes a copy of the os area in
--
^ permalink raw reply
* [patch 6/6] PS3: Add os-area database routines
From: geoffrey.levand @ 2007-10-06 21:35 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20071006213542.311447584@am.sony.com>
Add support for a simple tagged database in the PS3 flash rom
os-area. The database allows the flash rom os-area to be shared
between a bootloder and installed operating systems. The
application ps3-flash-util or the library libps3-utils from the
ps3-utils package can be used for userspace database operations.
The latest ps3-utils package is available here:
git://git.kernel.org/pub/scm/linux/kernel/git/geoff/ps3-utils.git
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/platforms/ps3/os-area.c | 422 +++++++++++++++++++++++++++++++++--
1 file changed, 408 insertions(+), 14 deletions(-)
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -21,6 +21,8 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/workqueue.h>
+#include <linux/fs.h>
+#include <linux/syscalls.h>
#include <asm/lmb.h>
@@ -39,7 +41,7 @@ enum os_area_ldr_format {
* struct os_area_header - os area header segment.
* @magic_num: Always 'cell_ext_os_area'.
* @hdr_version: Header format version number.
- * @os_area_offset: Starting segment number of os image area.
+ * @db_area_offset: Starting segment number of other os database area.
* @ldr_area_offset: Starting segment number of bootloader image area.
* @ldr_format: HEADER_LDR_FORMAT flag.
* @ldr_size: Size of bootloader image in bytes.
@@ -53,7 +55,7 @@ enum os_area_ldr_format {
struct os_area_header {
u8 magic_num[16];
u32 hdr_version;
- u32 os_area_offset;
+ u32 db_area_offset;
u32 ldr_area_offset;
u32 _reserved_1;
u32 ldr_format;
@@ -112,10 +114,91 @@ struct os_area_params {
u8 _reserved_5[8];
};
+/**
+ * struct os_area_db - Shared flash memory database.
+ * @magic_num: Always '-db-' = 0x2d64622d.
+ * @version: os_area_db format version number.
+ * @index_64: byte offset of the database id index for 64 bit variables.
+ * @count_64: number of usable 64 bit index entries
+ * @index_32: byte offset of the database id index for 32 bit variables.
+ * @count_32: number of usable 32 bit index entries
+ * @index_16: byte offset of the database id index for 16 bit variables.
+ * @count_16: number of usable 16 bit index entries
+ *
+ * Flash rom storage for exclusive use by guests running in the other os lpar.
+ * The current system configuration allocates 1K (two segments) for other os
+ * use.
+ */
+
+struct os_area_db {
+ u32 magic_num;
+ u16 version;
+ u16 _reserved_1;
+ u16 index_64;
+ u16 count_64;
+ u16 index_32;
+ u16 count_32;
+ u16 index_16;
+ u16 count_16;
+ u32 _reserved_2;
+ u8 _reserved_3[1000];
+};
+
+/**
+ * enum os_area_db_owner - Data owners.
+ */
+
+enum os_area_db_owner {
+ OS_AREA_DB_OWNER_ANY = -1,
+ OS_AREA_DB_OWNER_NONE = 0,
+ OS_AREA_DB_OWNER_PROTOTYPE = 1,
+ OS_AREA_DB_OWNER_LINUX = 2,
+ OS_AREA_DB_OWNER_PETITBOOT = 3,
+ OS_AREA_DB_OWNER_MAX = 32,
+};
+
+enum os_area_db_key {
+ OS_AREA_DB_KEY_ANY = -1,
+ OS_AREA_DB_KEY_NONE = 0,
+ OS_AREA_DB_KEY_RTC_DIFF = 1,
+ OS_AREA_DB_KEY_VIDEO_MODE = 2,
+ OS_AREA_DB_KEY_MAX = 8,
+};
+
+struct os_area_db_id {
+ int owner;
+ int key;
+};
+
+static const struct os_area_db_id os_area_db_id_empty = {
+ .owner = OS_AREA_DB_OWNER_NONE,
+ .key = OS_AREA_DB_KEY_NONE
+};
+
+static const struct os_area_db_id os_area_db_id_any = {
+ .owner = OS_AREA_DB_OWNER_ANY,
+ .key = OS_AREA_DB_KEY_ANY
+};
+
+static const struct os_area_db_id os_area_db_id_rtc_diff = {
+ .owner = OS_AREA_DB_OWNER_LINUX,
+ .key = OS_AREA_DB_KEY_RTC_DIFF
+};
+
+static const struct os_area_db_id os_area_db_id_video_mode = {
+ .owner = OS_AREA_DB_OWNER_LINUX,
+ .key = OS_AREA_DB_KEY_VIDEO_MODE
+};
+
#define SECONDS_FROM_1970_TO_2000 946684800LL
/**
* struct saved_params - Static working copies of data from the PS3 'os area'.
+ *
+ * The order of preference we use for the rtc_diff source:
+ * 1) The database value.
+ * 2) The game os value.
+ * 3) The number of seconds from 1970 to 2000.
*/
struct saved_params {
@@ -182,17 +265,17 @@ static void __init os_area_get_property(
static void _dump_header(const struct os_area_header *h, const char *func,
int line)
{
- pr_debug("%s:%d: h.magic_num: '%s'\n", func, line,
+ pr_debug("%s:%d: h.magic_num: '%s'\n", func, line,
h->magic_num);
- pr_debug("%s:%d: h.hdr_version: %u\n", func, line,
+ pr_debug("%s:%d: h.hdr_version: %u\n", func, line,
h->hdr_version);
- pr_debug("%s:%d: h.os_area_offset: %u\n", func, line,
- h->os_area_offset);
+ pr_debug("%s:%d: h.db_area_offset: %u\n", func, line,
+ h->db_area_offset);
pr_debug("%s:%d: h.ldr_area_offset: %u\n", func, line,
h->ldr_area_offset);
- pr_debug("%s:%d: h.ldr_format: %u\n", func, line,
+ pr_debug("%s:%d: h.ldr_format: %u\n", func, line,
h->ldr_format);
- pr_debug("%s:%d: h.ldr_size: %xh\n", func, line,
+ pr_debug("%s:%d: h.ldr_size: %xh\n", func, line,
h->ldr_size);
}
@@ -222,7 +305,7 @@ static void _dump_params(const struct os
p->dns_secondary[2], p->dns_secondary[3]);
}
-static int __init verify_header(const struct os_area_header *header)
+static int verify_header(const struct os_area_header *header)
{
if (memcmp(header->magic_num, "cell_ext_os_area", 16)) {
pr_debug("%s:%d magic_num failed\n", __func__, __LINE__);
@@ -234,7 +317,7 @@ static int __init verify_header(const st
return -1;
}
- if (header->os_area_offset > header->ldr_area_offset) {
+ if (header->db_area_offset > header->ldr_area_offset) {
pr_debug("%s:%d offsets failed\n", __func__, __LINE__);
return -1;
}
@@ -242,6 +325,303 @@ static int __init verify_header(const st
return 0;
}
+static int db_verify(const struct os_area_db *db)
+{
+ if (db->magic_num != 0x2d64622dU) {
+ pr_debug("%s:%d magic_num failed\n", __func__, __LINE__);
+ return -1;
+ }
+
+ if (db->version != 1) {
+ pr_debug("%s:%d version failed\n", __func__, __LINE__);
+ return -1;
+ }
+
+ return 0;
+}
+
+struct db_index {
+ uint8_t owner:5;
+ uint8_t key:3;
+};
+
+struct db_iterator {
+ const struct os_area_db *db;
+ struct os_area_db_id match_id;
+ struct db_index *idx;
+ struct db_index *last_idx;
+ union {
+ uint64_t *value_64;
+ uint32_t *value_32;
+ uint16_t *value_16;
+ };
+};
+
+static unsigned int db_align_up(unsigned int val, unsigned int size)
+{
+ return (val + (size - 1)) & (~(size - 1));
+}
+
+/**
+ * db_for_each_64 - Iterator for 64 bit entries.
+ *
+ * A NULL value for id can be used to match all entries.
+ * OS_AREA_DB_OWNER_ANY and OS_AREA_DB_KEY_ANY can be used to match all.
+ */
+
+static int db_for_each_64(const struct os_area_db *db,
+ const struct os_area_db_id *match_id, struct db_iterator *i)
+{
+next:
+ if (!i->db) {
+ i->db = db;
+ i->match_id = match_id ? *match_id : os_area_db_id_any;
+ i->idx = (void *)db + db->index_64;
+ i->last_idx = i->idx + db->count_64;
+ i->value_64 = (void *)db + db->index_64
+ + db_align_up(db->count_64, 8);
+ } else {
+ i->idx++;
+ i->value_64++;
+ }
+
+ if (i->idx >= i->last_idx) {
+ pr_debug("%s:%d: reached end\n", __func__, __LINE__);
+ return 0;
+ }
+
+ if (i->match_id.owner != OS_AREA_DB_OWNER_ANY
+ && i->match_id.owner != (int)i->idx->owner)
+ goto next;
+ if (i->match_id.key != OS_AREA_DB_KEY_ANY
+ && i->match_id.key != (int)i->idx->key)
+ goto next;
+
+ return 1;
+}
+
+static int db_delete_64(struct os_area_db *db, const struct os_area_db_id *id)
+{
+ struct db_iterator i;
+
+ for (i.db = NULL; db_for_each_64(db, id, &i); ) {
+
+ pr_debug("%s:%d: got (%d:%d) %llxh\n", __func__, __LINE__,
+ i.idx->owner, i.idx->key,
+ (unsigned long long)*i.value_64);
+
+ i.idx->owner = 0;
+ i.idx->key = 0;
+ *i.value_64 = 0;
+ }
+ return 0;
+}
+
+static int db_set_64(struct os_area_db *db, const struct os_area_db_id *id,
+ uint64_t value)
+{
+ struct db_iterator i;
+
+ pr_debug("%s:%d: (%d:%d) <= %llxh\n", __func__, __LINE__,
+ id->owner, id->key, (unsigned long long)value);
+
+ if (!id->owner || id->owner == OS_AREA_DB_OWNER_ANY
+ || id->key == OS_AREA_DB_KEY_ANY) {
+ pr_debug("%s:%d: bad id: (%d:%d)\n", __func__,
+ __LINE__, id->owner, id->key);
+ return -1;
+ }
+
+ db_delete_64(db, id);
+
+ i.db = NULL;
+ if (db_for_each_64(db, &os_area_db_id_empty, &i)) {
+
+ pr_debug("%s:%d: got (%d:%d) %llxh\n", __func__, __LINE__,
+ i.idx->owner, i.idx->key,
+ (unsigned long long)*i.value_64);
+
+ i.idx->owner = id->owner;
+ i.idx->key = id->key;
+ *i.value_64 = value;
+
+ pr_debug("%s:%d: set (%d:%d) <= %llxh\n", __func__, __LINE__,
+ i.idx->owner, i.idx->key,
+ (unsigned long long)*i.value_64);
+ return 0;
+ }
+ pr_debug("%s:%d: database full.\n",
+ __func__, __LINE__);
+ return -1;
+}
+
+static int db_get_64(const struct os_area_db *db,
+ const struct os_area_db_id *id, uint64_t *value)
+{
+ struct db_iterator i;
+
+ i.db = NULL;
+ if (db_for_each_64(db, id, &i)) {
+ *value = *i.value_64;
+ pr_debug("%s:%d: found %lld\n", __func__, __LINE__,
+ (long long int)*i.value_64);
+ return 0;
+ }
+ pr_debug("%s:%d: not found\n", __func__, __LINE__);
+ return -1;
+}
+
+static int db_get_rtc_diff(const struct os_area_db *db, int64_t *rtc_diff)
+{
+ return db_get_64(db, &os_area_db_id_rtc_diff, (uint64_t*)rtc_diff);
+}
+
+static int db_get_video_mode(const struct os_area_db *db,
+ unsigned int *video_mode)
+{
+ return db_get_64(db, &os_area_db_id_video_mode, (uint64_t*)video_mode);
+}
+
+#define dump_db(a) _dump_db(a, __func__, __LINE__)
+static void _dump_db(const struct os_area_db *db, const char *func,
+ int line)
+{
+ pr_debug("%s:%d: db.magic_num: '%s'\n", func, line,
+ (const char*)&db->magic_num);
+ pr_debug("%s:%d: db.version: %u\n", func, line,
+ db->version);
+ pr_debug("%s:%d: db.index_64: %u\n", func, line,
+ db->index_64);
+ pr_debug("%s:%d: db.count_64: %u\n", func, line,
+ db->count_64);
+ pr_debug("%s:%d: db.index_32: %u\n", func, line,
+ db->index_32);
+ pr_debug("%s:%d: db.count_32: %u\n", func, line,
+ db->count_32);
+ pr_debug("%s:%d: db.index_16: %u\n", func, line,
+ db->index_16);
+ pr_debug("%s:%d: db.count_16: %u\n", func, line,
+ db->count_16);
+}
+
+static void os_area_db_init(struct os_area_db *db)
+{
+ /*
+ * item | start | size
+ * ----------+-------+-------
+ * header | 0 | 24
+ * index_64 | 24 | 64
+ * values_64 | 88 | 57*8 = 456
+ * index_32 | 544 | 64
+ * values_32 | 609 | 57*4 = 228
+ * index_16 | 836 | 64
+ * values_16 | 900 | 57*2 = 114
+ * end | 1014 | -
+ */
+
+ memset(db, 0, sizeof(struct os_area_db));
+
+ db->magic_num = 0x2d64622dU;
+ db->version = 1;
+ db->index_64 = 24;
+ db->count_64 = 57;
+ db->index_32 = 544;
+ db->count_32 = 57;
+ db->index_16 = 836;
+ db->count_16 = 57;
+}
+
+/**
+ * update_flash_db - Helper for os_area_queue_work_handler.
+ *
+ */
+
+static void update_flash_db(void)
+{
+ int result;
+ int file;
+ off_t offset;
+ ssize_t count;
+ static const unsigned int buf_len = 8 * OS_AREA_SEGMENT_SIZE;
+ const struct os_area_header *header;
+ struct os_area_db* db;
+
+ /* Read in header and db from flash. */
+
+ file = sys_open("/dev/ps3flash", O_RDWR, 0);
+
+ if (file < 0) {
+ pr_debug("%s:%d sys_open failed\n", __func__, __LINE__);
+ goto fail_open;
+ }
+
+ header = kmalloc(buf_len, GFP_KERNEL);
+
+ if (!header) {
+ pr_debug("%s:%d kmalloc failed\n", __func__, __LINE__);
+ goto fail_malloc;
+ }
+
+ offset = sys_lseek(file, 0, SEEK_SET);
+
+ if (offset != 0) {
+ pr_debug("%s:%d sys_lseek failed\n", __func__, __LINE__);
+ goto fail_header_seek;
+ }
+
+ count = sys_read(file, (char __user *)header, buf_len);
+
+ result = count < OS_AREA_SEGMENT_SIZE || verify_header(header)
+ || count < header->db_area_offset * OS_AREA_SEGMENT_SIZE;
+
+ if (result) {
+ pr_debug("%s:%d verify_header failed\n", __func__, __LINE__);
+ dump_header(header);
+ goto fail_header;
+ }
+
+ /* Now got a good db offset and some maybe good db data. */
+
+ db = (void*)header + header->db_area_offset * OS_AREA_SEGMENT_SIZE;
+
+ result = db_verify(db);
+
+ if (result) {
+ printk(KERN_NOTICE "%s:%d: Verify of flash database failed, "
+ "formatting.\n", __func__, __LINE__);
+ dump_db(db);
+ os_area_db_init(db);
+ }
+
+ /* Now got good db data. */
+
+ db_set_64(db, &os_area_db_id_rtc_diff, saved_params.rtc_diff);
+
+ offset = sys_lseek(file, header->db_area_offset * OS_AREA_SEGMENT_SIZE,
+ SEEK_SET);
+
+ if (offset != header->db_area_offset * OS_AREA_SEGMENT_SIZE) {
+ pr_debug("%s:%d sys_lseek failed\n", __func__, __LINE__);
+ goto fail_db_seek;
+ }
+
+ count = sys_write(file, (const char __user *)db,
+ sizeof(struct os_area_db));
+
+ if (count < sizeof(struct os_area_db)) {
+ pr_debug("%s:%d sys_write failed\n", __func__, __LINE__);
+ }
+
+fail_db_seek:
+fail_header:
+fail_header_seek:
+ kfree(header);
+fail_malloc:
+ sys_close(file);
+fail_open:
+ return;
+}
+
/**
* os_area_queue_work_handler - Asynchronous write handler.
*
@@ -264,6 +644,9 @@ static void os_area_queue_work_handler(s
pr_debug("%s:%d of_find_node_by_path failed\n",
__func__, __LINE__);
+#if defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE)
+ update_flash_db();
+#endif
pr_debug(" <- %s:%d\n", __func__, __LINE__);
}
@@ -278,11 +661,15 @@ static void os_area_queue_work(void)
/**
* ps3_os_area_save_params - Copy data from os area mirror to @saved_params.
*
- * For the convenience of the guest, the HV makes a copy of the os area in
+ * For the convenience of the guest the HV makes a copy of the os area in
* flash to a high address in the boot memory region and then puts that RAM
- * address and the byte count into the repository for retreval by the guest.
+ * address and the byte count into the repository for retrieval by the guest.
* We copy the data we want into a static variable and allow the memory setup
* by the HV to be claimed by the lmb manager.
+ *
+ * The os area mirror will not be available to a second stage kernel, and
+ * the header verify will fail. In this case, the saved_params values will
+ * be set from flash memory or the passed in device tree in ps3_os_area_init().
*/
void __init ps3_os_area_save_params(void)
@@ -292,6 +679,7 @@ void __init ps3_os_area_save_params(void
unsigned int size;
struct os_area_header *header;
struct os_area_params *params;
+ struct os_area_db *db;
pr_debug(" -> %s:%d\n", __func__, __LINE__);
@@ -311,16 +699,22 @@ void __init ps3_os_area_save_params(void
if (result) {
/* Second stage kernels exit here. */
-
pr_debug("%s:%d verify_header failed\n", __func__, __LINE__);
dump_header(header);
return;
}
+ db = (struct os_area_db *)__va(lpar_addr
+ + header->db_area_offset * OS_AREA_SEGMENT_SIZE);
+
dump_header(header);
dump_params(params);
+ dump_db(db);
- saved_params.rtc_diff = params->rtc_diff;
+ result = db_verify(db) || db_get_rtc_diff(db, &saved_params.rtc_diff);
+ if (result)
+ saved_params.rtc_diff = params->rtc_diff ? params->rtc_diff
+ : SECONDS_FROM_1970_TO_2000;
saved_params.av_multi_out = params->av_multi_out;
saved_params.valid = 1;
--
^ permalink raw reply
* [patch 4/6] PS3: Add os-area rtc_diff set/get routines
From: geoffrey.levand @ 2007-10-06 21:35 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20071006213542.311447584@am.sony.com>
Updates for PS3 os-area rtc_diff set/get routines
o Add a new routine ps3_os_area_set_rtc_diff().
o Rename ps3_os_area_rtc_diff() to ps3_os_area_get_rtc_diff().
o Remove static variable rtc_shift with calls to ps3_os_area_get_rtc_diff().
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/platforms/ps3/os-area.c | 19 +++++++++++++++++--
arch/powerpc/platforms/ps3/platform.h | 3 ++-
arch/powerpc/platforms/ps3/time.c | 14 +++-----------
3 files changed, 22 insertions(+), 14 deletions(-)
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -261,16 +261,31 @@ void __init ps3_os_area_save_params(void
}
/**
- * ps3_os_area_rtc_diff - Returns the rtc diff value.
+ * ps3_os_area_get_rtc_diff - Returns the rtc diff value.
*/
-u64 ps3_os_area_rtc_diff(void)
+u64 ps3_os_area_get_rtc_diff(void)
{
return saved_params.rtc_diff ? saved_params.rtc_diff
: SECONDS_FROM_1970_TO_2000;
}
/**
+ * ps3_os_area_set_rtc_diff - Set the rtc diff value.
+ *
+ * An asynchronous write is needed to support writing updates from
+ * the timer interrupt context.
+ */
+
+void ps3_os_area_set_rtc_diff(u64 rtc_diff)
+{
+ if (saved_params.rtc_diff != rtc_diff) {
+ saved_params.rtc_diff = rtc_diff;
+ os_area_queue_work();
+ }
+}
+
+/**
* ps3_os_area_get_av_multi_out - Returns the default video mode.
*/
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -63,7 +63,8 @@ int ps3_set_rtc_time(struct rtc_time *ti
/* os area */
void __init ps3_os_area_save_params(void);
-u64 ps3_os_area_rtc_diff(void);
+u64 ps3_os_area_get_rtc_diff(void);
+void ps3_os_area_set_rtc_diff(u64 rtc_diff);
/* spu */
--- a/arch/powerpc/platforms/ps3/time.c
+++ b/arch/powerpc/platforms/ps3/time.c
@@ -50,12 +50,6 @@ static void __maybe_unused _dump_time(in
_dump_tm(&tm, func, line);
}
-/**
- * rtc_shift - Difference in seconds between 1970 and the ps3 rtc value.
- */
-
-static s64 rtc_shift;
-
void __init ps3_calibrate_decr(void)
{
int result;
@@ -66,8 +60,6 @@ void __init ps3_calibrate_decr(void)
ppc_tb_freq = tmp;
ppc_proc_freq = ppc_tb_freq * 40;
-
- rtc_shift = ps3_os_area_rtc_diff();
}
static u64 read_rtc(void)
@@ -87,18 +79,18 @@ int ps3_set_rtc_time(struct rtc_time *tm
u64 now = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
- rtc_shift = now - read_rtc();
+ ps3_os_area_set_rtc_diff(now - read_rtc());
return 0;
}
void ps3_get_rtc_time(struct rtc_time *tm)
{
- to_tm(read_rtc() + rtc_shift, tm);
+ to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm);
tm->tm_year -= 1900;
tm->tm_mon -= 1;
}
unsigned long __init ps3_get_boot_time(void)
{
- return read_rtc() + rtc_shift;
+ return read_rtc() + ps3_os_area_get_rtc_diff();
}
--
^ permalink raw reply
* Re: Where are inb/outb macros?
From: Arnd Bergmann @ 2007-10-06 23:46 UTC (permalink / raw)
To: linuxppc-dev, benh
In-Reply-To: <1191704881.6414.3.camel@pasglop>
On Saturday 06 October 2007, Benjamin Herrenschmidt wrote:
> On Sun, 2007-10-07 at 00:47 +0400, Peter Lemenkov wrote:
> > Hello All!
> > I can't compile one small software title because of lack <sys/io.h>
> > and inb/outb macros. What sould I do to overcome this obstacle?
> >
> > My linux distro is Fedora 7 if it is matter.
>
> They don't exist in user space on non-x86. You have to do things
> differently. What is your software trying to do ? If it's trying to
> access a PCI device IO space, you probably want to mmap it in sysfs and
> write your own accessors with appropriate memory barriers.
All cases where I've seen application software use <sys/io.h>, there was
actually a full device driver in the kernel that already exported a
high-level interface to user space. If that's the case here, the application
should use that instead of sysfs.
Arnd <><
^ permalink raw reply
* Re: TASK_SIZE default 0x80000000 ?
From: Paul Mackerras @ 2007-10-07 4:06 UTC (permalink / raw)
To: Kumar Gala; +Cc: PowerPC dev list, Benjamin Herrenschmidt
In-Reply-To: <C2771B73-A555-4119-AC21-1441D4CC2125@freescale.com>
Kumar Gala writes:
> In a discussion with Hollis over beer he raised the question why
> TASK_SIZE is 0x80000000 on ppc32.
>
> I was wondering if anyone know why this was still the case? Seems
> like we have a 1Gb whole between TASK_SIZE & KERNELBASE.
Two reasons: (a) PReP used to map PCI stuff with BATs in the
0x80000000 - 0xbfffffff region, and (b) some embedded ports with
software-loaded TLBs test just the high bit of the address to
determine whether to use the kernel or user page tables.
Paul.
^ permalink raw reply
* [PATCH 01/15] [POWERPC] TQM5200 DTS
From: Marian Balakowicz @ 2007-10-07 11:15 UTC (permalink / raw)
Cc: linuxppc-dev
In-Reply-To: <47075FA7.3030108@semihalf.com>
Add device tree source file for TQM5200 board.
Signed-off-by: Marian Balakowicz <m8@semihalf.com>
Signed-off-by: Grzegorz Bernacki <gjb@semihalf.com>
Signed-off-by: Martin Krause <martin.krause@tqs.de>
---
tqm5200.dts | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 217 insertions(+)
diff --git a/arch/powerpc/boot/dts/tqm5200.dts b/arch/powerpc/boot/dts/tqm5200.dts
new file mode 100644
index 0000000..e3e0ebf
--- /dev/null
+++ b/arch/powerpc/boot/dts/tqm5200.dts
@@ -0,0 +1,217 @@
+/*
+ * TQM5200 board Device Tree Source
+ *
+ * Copyright (C) 2007 Semihalf
+ * Modified for TQM5200 by Marian Balakowicz <m8@semihalf.com>
+ *
+ * Copyright 2006-2007 Secret Lab Technologies Ltd.
+ * Grant Likely <grant.likely@secretlab.ca>
+ *
+ * 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.
+ */
+
+/*
+ * WARNING: Do not depend on this tree layout remaining static just yet.
+ * The MPC5200 device tree conventions are still in flux
+ * Keep an eye on the linuxppc-dev mailing list for more details
+ */
+
+/ {
+ model = "fsl,tqm5200";
+ compatible = "fsl,tqm5200\0generic-mpc5200";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,5200@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <20>;
+ i-cache-line-size = <20>;
+ d-cache-size = <4000>; // L1, 16K
+ i-cache-size = <4000>; // L1, 16K
+ timebase-frequency = <0>; // from bootloader
+ bus-frequency = <0>; // from bootloader
+ clock-frequency = <0>; // from bootloader
+ 32-bit;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <00000000 04000000>; // 64MB
+ };
+
+ soc5200@f0000000 {
+ model = "fsl,mpc5200";
+ compatible = "mpc5200";
+ revision = ""; // from bootloader
+ #interrupt-cells = <3>;
+ device_type = "soc";
+ ranges = <0 f0000000 f0010000>;
+ reg = <f0000000 00010000>;
+ bus-frequency = <0>; // from bootloader
+ system-frequency = <0>; // from bootloader
+
+ cdm@200 {
+ compatible = "mpc5200b-cdm\0mpc5200-cdm";
+ reg = <200 38>;
+ };
+
+ mpc5200_pic: pic@500 {
+ // 5200 interrupts are encoded into two levels;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ device_type = "interrupt-controller";
+ compatible = "mpc5200-pic";
+ reg = <500 80>;
+ built-in;
+ };
+
+ gpt@600 { // General Purpose Timer
+ compatible = "mpc5200-gpt";
+ device_type = "gpt";
+ cell-index = <0>;
+ reg = <600 10>;
+ interrupts = <1 9 0>;
+ interrupt-parent = <&mpc5200_pic>;
+ has-wdt;
+ };
+
+ gpio@b00 {
+ compatible = "mpc5200-gpio";
+ reg = <b00 40>;
+ interrupts = <1 7 0>;
+ interrupt-parent = <&mpc5200_pic>;
+ };
+
+ usb@1000 {
+ device_type = "usb-ohci-be";
+ compatible = "mpc5200-ohci\0ohci-be";
+ reg = <1000 ff>;
+ interrupts = <2 6 0>;
+ interrupt-parent = <&mpc5200_pic>;
+ };
+
+ pci@0d00 {
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ compatible = "mpc5200-pci";
+ reg = <d00 100>;
+ interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map = <c000 0 0 1 &mpc5200_pic 0 0 3
+ c000 0 0 2 &mpc5200_pic 0 0 3
+ c000 0 0 3 &mpc5200_pic 0 0 3
+ c000 0 0 4 &mpc5200_pic 0 0 3>;
+ clock-frequency = <0>; // From boot loader
+ interrupts = <2 8 0 2 9 0 2 a 0>;
+ interrupt-parent = <&mpc5200_pic>;
+ bus-range = <0 0>;
+ ranges = <42000000 0 80000000 80000000 0 10000000
+ 02000000 0 90000000 90000000 0 10000000
+ 01000000 0 00000000 a0000000 0 01000000>;
+ };
+
+ bestcomm@1200 {
+ device_type = "dma-controller";
+ compatible = "mpc5200-bestcomm";
+ reg = <1200 80>;
+ interrupts = <3 0 0 3 1 0 3 2 0 3 3 0
+ 3 4 0 3 5 0 3 6 0 3 7 0
+ 3 8 0 3 9 0 3 a 0 3 b 0
+ 3 c 0 3 d 0 3 e 0 3 f 0>;
+ interrupt-parent = <&mpc5200_pic>;
+ };
+
+ xlb@1f00 {
+ compatible = "mpc5200-xlb";
+ reg = <1f00 100>;
+ };
+
+ serial@2000 { // PSC1
+ device_type = "serial";
+ compatible = "mpc5200-psc-uart";
+ port-number = <0>; // Logical port assignment
+ cell-index = <0>;
+ reg = <2000 100>;
+ interrupts = <2 1 0>;
+ interrupt-parent = <&mpc5200_pic>;
+ };
+
+ serial@2200 { // PSC2
+ device_type = "serial";
+ compatible = "mpc5200-psc-uart";
+ port-number = <1>; // Logical port assignment
+ cell-index = <1>;
+ reg = <2200 100>;
+ interrupts = <2 2 0>;
+ interrupt-parent = <&mpc5200_pic>;
+ };
+
+ serial@2400 { // PSC3
+ device_type = "serial";
+ compatible = "mpc5200-psc-uart";
+ port-number = <2>; // Logical port assignment
+ cell-index = <2>;
+ reg = <2400 100>;
+ interrupts = <2 3 0>;
+ interrupt-parent = <&mpc5200_pic>;
+ };
+
+ ethernet@3000 {
+ device_type = "network";
+ compatible = "mpc5200-fec";
+ reg = <3000 800>;
+ interrupts = <2 5 0>;
+ interrupt-parent = <&mpc5200_pic>;
+ };
+
+ ata@3a00 {
+ device_type = "ata";
+ compatible = "mpc5200b-ata\0mpc5200-ata";
+ reg = <3a00 100>;
+ interrupts = <2 7 0>;
+ interrupt-parent = <&mpc5200_pic>;
+ };
+
+ i2c@3d40 {
+ device_type = "i2c";
+ compatible = "mpc5200-i2c\0fsl-i2c";
+ cell-index = <1>;
+ reg = <3d40 40>;
+ interrupts = <2 10 0>;
+ interrupt-parent = <&mpc5200_pic>;
+ fsl5200-clocking;
+ };
+
+ sram@8000 {
+ device_type = "sram";
+ compatible = "mpc5200-sram\0sram";
+ reg = <8000 4000>;
+ };
+
+ flash@c000000 {
+ device_type = "rom";
+ compatible = "direct-mapped";
+ reg = <0c000000 02000000>;
+ probe-type = "CFI";
+ bank-width = <4>;
+ partitions = <00000000 000a0000
+ 000a0000 00020000
+ 000c0000 00240000
+ 00300000 00200000
+ 00500000 00400000
+ 00900000 00800000
+ 01100000 00f00000>;
+ partition-names = "firmware\0dtb\0kernel\0initrd\0small-fs\0misc\0big-fs";
+ };
+ };
+};
^ permalink raw reply related
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