linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [patch 0/6] PS3 os area patches for 2.6.24
@ 2007-10-06 21:35 geoffrey.levand
  2007-10-06 21:35 ` [patch 1/6] PS3: Cleanup of os-area.c geoffrey.levand
                   ` (5 more replies)
  0 siblings, 6 replies; 24+ messages in thread
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	[flat|nested] 24+ messages in thread

* [patch 1/6] PS3: Cleanup of os-area.c
  2007-10-06 21:35 [patch 0/6] PS3 os area patches for 2.6.24 geoffrey.levand
@ 2007-10-06 21:35 ` geoffrey.levand
  2007-10-06 21:35 ` [patch 2/6] PS3: Remove unused os-area params geoffrey.levand
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 24+ messages in thread
From: geoffrey.levand @ 2007-10-06 21:35 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

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	[flat|nested] 24+ messages in thread

* [patch 2/6] PS3: Remove unused os-area params
  2007-10-06 21:35 [patch 0/6] PS3 os area patches for 2.6.24 geoffrey.levand
  2007-10-06 21:35 ` [patch 1/6] PS3: Cleanup of os-area.c geoffrey.levand
@ 2007-10-06 21:35 ` geoffrey.levand
  2007-10-08 14:00   ` Ranulf Doswell
  2007-10-06 21:35 ` [patch 3/6] PS3: os-area workqueue processing geoffrey.levand
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 24+ messages in thread
From: geoffrey.levand @ 2007-10-06 21:35 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

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	[flat|nested] 24+ messages in thread

* [patch 3/6] PS3: os-area workqueue processing
  2007-10-06 21:35 [patch 0/6] PS3 os area patches for 2.6.24 geoffrey.levand
  2007-10-06 21:35 ` [patch 1/6] PS3: Cleanup of os-area.c geoffrey.levand
  2007-10-06 21:35 ` [patch 2/6] PS3: Remove unused os-area params geoffrey.levand
@ 2007-10-06 21:35 ` geoffrey.levand
  2007-10-06 21:35 ` [patch 4/6] PS3: Add os-area rtc_diff set/get routines geoffrey.levand
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 24+ messages in thread
From: geoffrey.levand @ 2007-10-06 21:35 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

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	[flat|nested] 24+ messages in thread

* [patch 4/6] PS3: Add os-area rtc_diff set/get routines
  2007-10-06 21:35 [patch 0/6] PS3 os area patches for 2.6.24 geoffrey.levand
                   ` (2 preceding siblings ...)
  2007-10-06 21:35 ` [patch 3/6] PS3: os-area workqueue processing geoffrey.levand
@ 2007-10-06 21:35 ` geoffrey.levand
  2007-10-06 21:35 ` [patch 5/6] PS3: Save os-area params to device tree geoffrey.levand
  2007-10-06 21:35 ` [patch 6/6] PS3: Add os-area database routines geoffrey.levand
  5 siblings, 0 replies; 24+ messages in thread
From: geoffrey.levand @ 2007-10-06 21:35 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

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	[flat|nested] 24+ messages in thread

* [patch 5/6] PS3: Save os-area params to device tree
  2007-10-06 21:35 [patch 0/6] PS3 os area patches for 2.6.24 geoffrey.levand
                   ` (3 preceding siblings ...)
  2007-10-06 21:35 ` [patch 4/6] PS3: Add os-area rtc_diff set/get routines geoffrey.levand
@ 2007-10-06 21:35 ` geoffrey.levand
  2007-10-06 21:35 ` [patch 6/6] PS3: Add os-area database routines geoffrey.levand
  5 siblings, 0 replies; 24+ messages in thread
From: geoffrey.levand @ 2007-10-06 21:35 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

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	[flat|nested] 24+ messages in thread

* [patch 6/6] PS3: Add os-area database routines
  2007-10-06 21:35 [patch 0/6] PS3 os area patches for 2.6.24 geoffrey.levand
                   ` (4 preceding siblings ...)
  2007-10-06 21:35 ` [patch 5/6] PS3: Save os-area params to device tree geoffrey.levand
@ 2007-10-06 21:35 ` geoffrey.levand
  2007-10-08  8:27   ` Geert Uytterhoeven
                     ` (3 more replies)
  5 siblings, 4 replies; 24+ messages in thread
From: geoffrey.levand @ 2007-10-06 21:35 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

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	[flat|nested] 24+ messages in thread

* Re: [patch 6/6] PS3: Add os-area database routines
  2007-10-06 21:35 ` [patch 6/6] PS3: Add os-area database routines geoffrey.levand
@ 2007-10-08  8:27   ` Geert Uytterhoeven
  2007-10-09  1:08     ` Geoff Levand
  2007-10-08 12:16   ` Geert Uytterhoeven
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 24+ messages in thread
From: Geert Uytterhoeven @ 2007-10-08  8:27 UTC (permalink / raw)
  To: geoffrey.levand; +Cc: linuxppc-dev, paulus

[-- Attachment #1: Type: TEXT/PLAIN, Size: 3001 bytes --]

On Sat, 6 Oct 2007 geoffrey.levand@am.sony.com wrote:
> --- a/arch/powerpc/platforms/ps3/os-area.c
> +++ b/arch/powerpc/platforms/ps3/os-area.c
> @@ -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.
                                  ^^^^^^^^^^
#define?

> @@ -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) {
                             ^^^^^^^^^^^
#define?

> +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  | -
> +	 */

Lots of #defines and calculations?

> +
> +	memset(db, 0, sizeof(struct os_area_db));
> +
> +	db->magic_num = 0x2d64622dU;
                        ^^^^^^^^^^^
#define?

> +	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;
                       ^^
#defines?

> +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);

Ah, file operations from kernel space...

> @@ -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

Is this #ifdef needed? You don't reference ps3flash symbols directly, only by
opening /dev/ps3flash. If you always call update_flash_db(), you can print an
error message and the user will notice things haven't been written to flash.

With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [patch 6/6] PS3: Add os-area database routines
  2007-10-06 21:35 ` [patch 6/6] PS3: Add os-area database routines geoffrey.levand
  2007-10-08  8:27   ` Geert Uytterhoeven
@ 2007-10-08 12:16   ` Geert Uytterhoeven
  2007-10-09  1:12     ` Geoff Levand
  2007-10-08 13:48   ` Ranulf Doswell
  2007-10-09  1:07   ` [patch v2] " Geoff Levand
  3 siblings, 1 reply; 24+ messages in thread
From: Geert Uytterhoeven @ 2007-10-08 12:16 UTC (permalink / raw)
  To: geoffrey.levand; +Cc: linuxppc-dev, paulus

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1092 bytes --]

On Sat, 6 Oct 2007 geoffrey.levand@am.sony.com wrote:
> --- a/arch/powerpc/platforms/ps3/os-area.c
> +++ b/arch/powerpc/platforms/ps3/os-area.c

> +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);
                                                        ^^^^^^^^^^^
> +}

Woops, memory corruption, when writing a 64-bit value to a 32-bit variable.

With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [patch 6/6] PS3: Add os-area database routines
  2007-10-06 21:35 ` [patch 6/6] PS3: Add os-area database routines geoffrey.levand
  2007-10-08  8:27   ` Geert Uytterhoeven
  2007-10-08 12:16   ` Geert Uytterhoeven
@ 2007-10-08 13:48   ` Ranulf Doswell
  2007-10-08 17:52     ` Geoff Levand
  2007-10-09  1:07   ` [patch v2] " Geoff Levand
  3 siblings, 1 reply; 24+ messages in thread
From: Ranulf Doswell @ 2007-10-08 13:48 UTC (permalink / raw)
  To: geoffrey.levand@am.sony.com; +Cc: linuxppc-dev

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

On 06/10/2007, geoffrey.levand@am.sony.com <geoffrey.levand@am.sony.com>
wrote:
> 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,
>};

How do we go about claiming one of these OS_AREA_DB_OWNER_ keys? I'd very
much like to use this functionality in my python-ps3 games library.

My requirement is to be able to persist various options such as player names
and rankings. I had already been thinking about generating a unique token
and storing it somewhere at the end of the flash area so that when my game
connects to a game server, it can identify itself and be provided with all
the previous settings. Obviously, just claiming a random area of flash isn't
ideal, so your standardised solution would be perfect for this.

I would like, therefore, to reserve a single key to hold a 64-bit sized
token in order to identify the machine across reboots. I don't mind
particularly whether it's private to my application or a generally available
field, but certainly having an identifier I can rely on would be very
useful.

Cheers,
    Ralf.

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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [patch 2/6] PS3: Remove unused os-area params
  2007-10-06 21:35 ` [patch 2/6] PS3: Remove unused os-area params geoffrey.levand
@ 2007-10-08 14:00   ` Ranulf Doswell
  2007-10-08 17:53     ` Geoff Levand
  0 siblings, 1 reply; 24+ messages in thread
From: Ranulf Doswell @ 2007-10-08 14:00 UTC (permalink / raw)
  To: geoffrey.levand@am.sony.com; +Cc: linuxppc-dev

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

On 06/10/2007, geoffrey.levand@am.sony.com <geoffrey.levand@am.sony.com>
wrote:

> 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;

As these values are correctly populated by the hypervisor from the
preferences on the standard PS3 OS, it is incredibly useful to have this
information available.

Whilst none of the current 'popular' distributions use these fields, I am
currently in the process of making a bootable CD image that does use them in
order to initialise the network. Not having this information available means
that the only sensible option is to use DHCP, which may well not be
available in every case.

Please can we have these fields back? They don't actually take up all that
much room, yet they are incredibly useful.

-- 
Ranulf Doswell

One of the major reasons for the downfall of the Roman Empire was, lacking
zero, they had no way to indicate termination of their C strings.

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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [patch 6/6] PS3: Add os-area database routines
  2007-10-08 13:48   ` Ranulf Doswell
@ 2007-10-08 17:52     ` Geoff Levand
  2007-10-08 22:59       ` Ranulf Doswell
  0 siblings, 1 reply; 24+ messages in thread
From: Geoff Levand @ 2007-10-08 17:52 UTC (permalink / raw)
  To: Ranulf Doswell; +Cc: linuxppc-dev

Ranulf Doswell wrote:
> On 06/10/2007, *geoffrey.levand@am.sony.com
> <mailto:geoffrey.levand@am.sony.com>* <geoffrey.levand@am.sony.com
> <mailto:geoffrey.levand@am.sony.com>> wrote:
> 
>> 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,
>>};
> 
> How do we go about claiming one of these OS_AREA_DB_OWNER_ keys? I'd
> very much like to use this functionality in my python-ps3 games library.


It sounds like you should be storing your info in the file system like
all other applications do.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [patch 2/6] PS3: Remove unused os-area params
  2007-10-08 14:00   ` Ranulf Doswell
@ 2007-10-08 17:53     ` Geoff Levand
  2007-10-08 22:38       ` Ranulf Doswell
  0 siblings, 1 reply; 24+ messages in thread
From: Geoff Levand @ 2007-10-08 17:53 UTC (permalink / raw)
  To: Ranulf Doswell; +Cc: linuxppc-dev

Ranulf Doswell wrote:
> On 06/10/2007, *geoffrey.levand@am.sony.com
> <mailto:geoffrey.levand@am.sony.com>* <geoffrey.levand@am.sony.com
> <mailto:geoffrey.levand@am.sony.com>> wrote:
> 
>> 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;
> 
> As these values are correctly populated by the hypervisor from the
> preferences on the standard PS3 OS, it is incredibly useful to have this
> information available.


No, it is not used, and I never used it.


> Whilst none of the current 'popular' distributions use these fields, I
> am currently in the process of making a bootable CD image that does use
> them in order to initialise the network. Not having this information
> available means that the only sensible option is to use DHCP, which may
> well not be available in every case.
> 
> Please can we have these fields back? They don't actually take up all
> that much room, yet they are incredibly useful.


As a general rule we don't put unused code into the kernel, and I have no
plan to provide the support you mention.  Please submit a patch to the ML
with your feature for review.

-Geoff

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [patch 2/6] PS3: Remove unused os-area params
  2007-10-08 17:53     ` Geoff Levand
@ 2007-10-08 22:38       ` Ranulf Doswell
  2007-10-08 22:50         ` Geoff Levand
  0 siblings, 1 reply; 24+ messages in thread
From: Ranulf Doswell @ 2007-10-08 22:38 UTC (permalink / raw)
  To: Geoff Levand; +Cc: linuxppc-dev

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

On 08/10/2007, Geoff Levand <geoffrey.levand@am.sony.com> wrote:
>
> Ranulf Doswell wrote:
> >
> > As these values are correctly populated by the hypervisor from the
> > preferences on the standard PS3 OS, it is incredibly useful to have this
> > information available.
>
> No, it is not used, and I never used it.


Maybe I've mistaken how these are used. Having just looked at the source
again, I see that the saved_params field isn't exported.

Am I correct in assuming that this information will still be available in
/dev/ps3flash starting at offset 0x200? That's actually where I'm expecting
to find the information anyway. I believed your patch was changing that
behaviour, although I probably didn't study it enough.

Cheers,
    Ralf.

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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [patch 2/6] PS3: Remove unused os-area params
  2007-10-08 22:38       ` Ranulf Doswell
@ 2007-10-08 22:50         ` Geoff Levand
  0 siblings, 0 replies; 24+ messages in thread
From: Geoff Levand @ 2007-10-08 22:50 UTC (permalink / raw)
  To: Ranulf Doswell; +Cc: linuxppc-dev

Ranulf Doswell wrote:
> On 08/10/2007, *Geoff Levand* <geoffrey.levand@am.sony.com
> <mailto:geoffrey.levand@am.sony.com>> wrote:
> 
>     Ranulf Doswell wrote:
>     >
>     > As these values are correctly populated by the hypervisor from the
>     > preferences on the standard PS3 OS, it is incredibly useful to
>     have this
>     > information available.
> 
>     No, it is not used, and I never used it.
> 
> 
> Maybe I've mistaken how these are used. Having just looked at the source
> again, I see that the saved_params field isn't exported.
> 
> Am I correct in assuming that this information will still be available
> in /dev/ps3flash starting at offset 0x200? That's actually where I'm
> expecting to find the information anyway. I believed your patch was
> changing that behaviour, although I probably didn't study it enough.

Yes, and you can use libps3-utils to get it:

  http://git.kernel.org/?p=linux/kernel/git/geoff/ps3-utils.git

-Geoff

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [patch 6/6] PS3: Add os-area database routines
  2007-10-08 17:52     ` Geoff Levand
@ 2007-10-08 22:59       ` Ranulf Doswell
  2007-10-08 23:36         ` Geoff Levand
  2007-10-09  9:35         ` Geert Uytterhoeven
  0 siblings, 2 replies; 24+ messages in thread
From: Ranulf Doswell @ 2007-10-08 22:59 UTC (permalink / raw)
  To: Geoff Levand; +Cc: linuxppc-dev

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

On 08/10/2007, Geoff Levand <geoffrey.levand@am.sony.com> wrote:
>
> > How do we go about claiming one of these OS_AREA_DB_OWNER_ keys? I'd
> > very much like to use this functionality in my python-ps3 games library.
>
> It sounds like you should be storing your info in the file system like
> all other applications do.


I'd agree that for large amounts of application specific data, the
filesystem is the correct approach.

However, in this case the only data required is a single identifier used to
identify one PS3 from another, and in fact this single 64-bit token can be
shared amongst many other applications that require the same function -
certainly I intend to expose it in a common way in my games library's API
for all users of the library.

In my particular case, my bootable CD image does not have any other use for
a filesystem on disk beyond the initrd image on the CD-ROM; this is
important because some PS3s may be formatted as 100% GameOS. All that is
needed is to write the standard kboot image to flash so that it is able to
bootstrap the CD image.

As the PS3 has flash available and you are adding a mechanism for storing
very small bits of data in the flash, it seems silly not to use it and
attempt instead to write my own incompatible database format to store this
in the flash memory. Your database also has the added protection of not
being overwritten when the loader is re-flashed, as it is protected by the
kernel.

If you agree in principle that one of these identifiers can be allocated to
this purpose, I'm happy to write and submit a patch that exposes the get/set
system ID functionality to userland, whilst internally using your database.
This could also allow for some of the bits to be used as check bits to
ensure data validity.

Possibly there already exists a way to obtain a hash of the serial number or
some other unique identifying token via one of the undocumented hypervisor
calls, but as I'm not privvy to that kind of information I need to roll my
own mechanism for doing this.

Ralf.

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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [patch 6/6] PS3: Add os-area database routines
  2007-10-08 22:59       ` Ranulf Doswell
@ 2007-10-08 23:36         ` Geoff Levand
  2007-10-09  9:35         ` Geert Uytterhoeven
  1 sibling, 0 replies; 24+ messages in thread
From: Geoff Levand @ 2007-10-08 23:36 UTC (permalink / raw)
  To: Ranulf Doswell; +Cc: linuxppc-dev

Ranulf Doswell wrote:
> On 08/10/2007, *Geoff Levand* <geoffrey.levand@am.sony.com
> <mailto:geoffrey.levand@am.sony.com>> wrote:
> 
>     > How do we go about claiming one of these OS_AREA_DB_OWNER_ keys? I'd
>     > very much like to use this functionality in my python-ps3 games
>     library.
> 
>     It sounds like you should be storing your info in the file system like
>     all other applications do.
> 
> 
> I'd agree that for large amounts of application specific data, the
> filesystem is the correct approach.
> 
> However, in this case the only data required is a single identifier used
> to identify one PS3 from another, and in fact this single 64-bit token
> can be shared amongst many other applications that require the same
> function - certainly I intend to expose it in a common way in my games
> library's API for all users of the library.
> 
> In my particular case, my bootable CD image does not have any other use
> for a filesystem on disk beyond the initrd image on the CD-ROM; this is
> important because some PS3s may be formatted as 100% GameOS. All that is
> needed is to write the standard kboot image to flash so that it is able
> to bootstrap the CD image.
> 
> As the PS3 has flash available and you are adding a mechanism for
> storing very small bits of data in the flash, it seems silly not to use
> it and attempt instead to write my own incompatible database format to
> store this in the flash memory. Your database also has the added
> protection of not being overwritten when the loader is re-flashed, as it
> is protected by the kernel.
> 
> If you agree in principle that one of these identifiers can be allocated
> to this purpose, I'm happy to write and submit a patch that exposes the
> get/set system ID functionality to userland, whilst internally using
> your database. This could also allow for some of the bits to be used as
> check bits to ensure data validity.


This feature is not intended for general application use.  If the user
wants to store data, then they should setup the system with a writable
filesystem.

-Geoff

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [patch v2] PS3: Add os-area database routines
  2007-10-06 21:35 ` [patch 6/6] PS3: Add os-area database routines geoffrey.levand
                     ` (2 preceding siblings ...)
  2007-10-08 13:48   ` Ranulf Doswell
@ 2007-10-09  1:07   ` Geoff Levand
  2007-10-09 11:38     ` Geert Uytterhoeven
  2007-10-09 17:15     ` Linas Vepstas
  3 siblings, 2 replies; 24+ messages in thread
From: Geoff Levand @ 2007-10-09  1:07 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

Subject: PS3: Add os-area database routines

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 bootloader 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>
---

v2: Address Geert's comments:
  o Replace numeric initializers with symbols, calculations and
    BUILD_BUG_ON() checks.
  o Add a KERN_WARNING message when flash driver is not available.
  o Remove the unused (and incorrect) routine db_get_video_mode().

 arch/powerpc/platforms/ps3/os-area.c |  445 +++++++++++++++++++++++++++++++++--
 1 file changed, 431 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,95 @@ struct os_area_params {
 	u8 _reserved_5[8];
 };
 
+enum {
+	OS_AREA_DB_MAGIC_NUM = 0x2d64622dU,
+};
+
+/**
+ * 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 _db_data[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 +269,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 +309,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 +321,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 +329,319 @@ static int __init verify_header(const st
 	return 0;
 }
 
+static int db_verify(const struct os_area_db *db)
+{
+	if (db->magic_num != OS_AREA_DB_MAGIC_NUM) {
+		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);
+}
+
+#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)
+{
+	enum {
+		HEADER_SIZE = offsetof(struct os_area_db, _db_data),
+		INDEX_64_COUNT = 64,
+		VALUES_64_COUNT = 57,
+		INDEX_32_COUNT = 64,
+		VALUES_32_COUNT = 57,
+		INDEX_16_COUNT = 64,
+		VALUES_16_COUNT = 57,
+	};
+
+	memset(db, 0, sizeof(struct os_area_db));
+
+	db->magic_num = OS_AREA_DB_MAGIC_NUM;
+	db->version = 1;
+	db->index_64 = HEADER_SIZE;
+	db->count_64 = VALUES_64_COUNT;
+	db->index_32 = HEADER_SIZE
+			+ INDEX_64_COUNT * sizeof(struct db_index)
+			+ VALUES_64_COUNT * sizeof(u64);
+	db->count_32 = VALUES_32_COUNT;
+	db->index_16 = HEADER_SIZE
+			+ INDEX_64_COUNT * sizeof(struct db_index)
+			+ VALUES_64_COUNT * sizeof(u64)
+			+ INDEX_32_COUNT * sizeof(struct db_index)
+			+ VALUES_32_COUNT * sizeof(u32);
+	db->count_16 = VALUES_16_COUNT;
+
+	/* Rules to check db layout. */
+
+	BUILD_BUG_ON(sizeof(struct db_index) != 1);
+	BUILD_BUG_ON(sizeof(struct os_area_db) != 2 * OS_AREA_SEGMENT_SIZE);
+	BUILD_BUG_ON(INDEX_64_COUNT & 0x7);
+	BUILD_BUG_ON(VALUES_64_COUNT > INDEX_64_COUNT);
+	BUILD_BUG_ON(INDEX_32_COUNT & 0x7);
+	BUILD_BUG_ON(VALUES_32_COUNT > INDEX_32_COUNT);
+	BUILD_BUG_ON(INDEX_16_COUNT & 0x7);
+	BUILD_BUG_ON(VALUES_16_COUNT > INDEX_16_COUNT);
+	BUILD_BUG_ON(HEADER_SIZE
+			+ INDEX_64_COUNT * sizeof(struct db_index)
+			+ VALUES_64_COUNT * sizeof(u64)
+			+ INDEX_32_COUNT * sizeof(struct db_index)
+			+ VALUES_32_COUNT * sizeof(u32)
+			+ INDEX_16_COUNT * sizeof(struct db_index)
+			+ VALUES_16_COUNT * sizeof(u16)
+			> sizeof(struct os_area_db));
+}
+
+/**
+ * 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 +664,12 @@ 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();
+#else
+	printk(KERN_WARNING "%s:%d: No flash rom driver configured.\n",
+		__func__, __LINE__);
+#endif
 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
 }
 
@@ -278,11 +684,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 +702,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 +722,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	[flat|nested] 24+ messages in thread

* Re: [patch 6/6] PS3: Add os-area database routines
  2007-10-08  8:27   ` Geert Uytterhoeven
@ 2007-10-09  1:08     ` Geoff Levand
  0 siblings, 0 replies; 24+ messages in thread
From: Geoff Levand @ 2007-10-09  1:08 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linuxppc-dev, paulus

Geert Uytterhoeven wrote:
> On Sat, 6 Oct 2007 geoffrey.levand@am.sony.com wrote:
>> --- a/arch/powerpc/platforms/ps3/os-area.c
>> +++ b/arch/powerpc/platforms/ps3/os-area.c
>> @@ -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.
>                                   ^^^^^^^^^^
> #define?


Well, this is a comment, and when debugging it is handy to
know the value.


>> @@ -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) {
>                              ^^^^^^^^^^^
> #define?


Sure, it is OK here.


>> +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  | -
>> +	 */
> 
> Lots of #defines and calculations?


OK.


>> +
>> +	memset(db, 0, sizeof(struct os_area_db));
>> +
>> +	db->magic_num = 0x2d64622dU;
>                         ^^^^^^^^^^^
> #define?
> 
>> +	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;
>                        ^^
> #defines?
> 
>> +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);
> 
> Ah, file operations from kernel space...


Yes.  I was thinking we could make an interface to the flash driver.

 
>> @@ -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
> 
> Is this #ifdef needed? You don't reference ps3flash symbols directly, only by
> opening /dev/ps3flash. If you always call update_flash_db(), you can print an
> error message and the user will notice things haven't been written to flash.


My thinking was that the file I/O code would be removed by the optimizer
when not needed.  I added a message.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [patch 6/6] PS3: Add os-area database routines
  2007-10-08 12:16   ` Geert Uytterhoeven
@ 2007-10-09  1:12     ` Geoff Levand
  0 siblings, 0 replies; 24+ messages in thread
From: Geoff Levand @ 2007-10-09  1:12 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linuxppc-dev, paulus

Geert Uytterhoeven wrote:
> On Sat, 6 Oct 2007 geoffrey.levand@am.sony.com wrote:
>> --- a/arch/powerpc/platforms/ps3/os-area.c
>> +++ b/arch/powerpc/platforms/ps3/os-area.c
> 
>> +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);
>                                                         ^^^^^^^^^^^
>> +}
> 
> Woops, memory corruption, when writing a 64-bit value to a 32-bit variable.

Whoa!  That routines is not even used, so I removed it.

-Geoff  

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [patch 6/6] PS3: Add os-area database routines
  2007-10-08 22:59       ` Ranulf Doswell
  2007-10-08 23:36         ` Geoff Levand
@ 2007-10-09  9:35         ` Geert Uytterhoeven
  2007-10-09 12:23           ` Ranulf Doswell
  1 sibling, 1 reply; 24+ messages in thread
From: Geert Uytterhoeven @ 2007-10-09  9:35 UTC (permalink / raw)
  To: Ranulf Doswell; +Cc: linuxppc-dev

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1442 bytes --]

On Mon, 8 Oct 2007, Ranulf Doswell wrote:
> On 08/10/2007, Geoff Levand <geoffrey.levand@am.sony.com> wrote:
> > > How do we go about claiming one of these OS_AREA_DB_OWNER_ keys? I'd
> > > very much like to use this functionality in my python-ps3 games library.
> >
> > It sounds like you should be storing your info in the file system like
> > all other applications do.
> 
> 
> I'd agree that for large amounts of application specific data, the
> filesystem is the correct approach.
> 
> However, in this case the only data required is a single identifier used to
> identify one PS3 from another, and in fact this single 64-bit token can be
> shared amongst many other applications that require the same function -
> certainly I intend to expose it in a common way in my games library's API
> for all users of the library.

MAC address?

With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [patch v2] PS3: Add os-area database routines
  2007-10-09  1:07   ` [patch v2] " Geoff Levand
@ 2007-10-09 11:38     ` Geert Uytterhoeven
  2007-10-09 17:15     ` Linas Vepstas
  1 sibling, 0 replies; 24+ messages in thread
From: Geert Uytterhoeven @ 2007-10-09 11:38 UTC (permalink / raw)
  To: Geoff Levand; +Cc: linuxppc-dev, paulus

[-- Attachment #1: Type: TEXT/PLAIN, Size: 2048 bytes --]

On Mon, 8 Oct 2007, Geoff Levand wrote:
>   o Add a KERN_WARNING message when flash driver is not available.

> --- a/arch/powerpc/platforms/ps3/os-area.c
> +++ b/arch/powerpc/platforms/ps3/os-area.c

> +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__);
                ^^^^^^^^
pr_warn?

If the ps3flash module is not loaded, you want to see the warning.

> @@ -264,6 +664,12 @@ 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();
> +#else
> +	printk(KERN_WARNING "%s:%d: No flash rom driver configured.\n",
> +		__func__, __LINE__);
> +#endif
>  	pr_debug(" <- %s:%d\n", __func__, __LINE__);
>  }

Alternatively:

    #if defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE)
    static int update_flash_db(void)
    {
	...
	return error;
    }
    #else
    static inline int update_flash_db(void)
    {
	return -Exxx;
    }
    #endif

	if (update_flash_db())
	    printk(KERN_WARNING ...);


With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [patch 6/6] PS3: Add os-area database routines
  2007-10-09  9:35         ` Geert Uytterhoeven
@ 2007-10-09 12:23           ` Ranulf Doswell
  0 siblings, 0 replies; 24+ messages in thread
From: Ranulf Doswell @ 2007-10-09 12:23 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linuxppc-dev

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

On 09/10/2007, Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com> wrote:
>
> On Mon, 8 Oct 2007, Ranulf Doswell wrote:
> > However, in this case the only data required is a single identifier used
> to
> > identify one PS3 from another, and in fact this single 64-bit token can
> be
> > shared amongst many other applications that require the same function -
> > certainly I intend to expose it in a common way in my games library's
> API
> > for all users of the library.
>
> MAC address?
>

Indeed, that's perfect! That solution also just occurred to me whilst
walking back from lunch and when I come back to check my e-mail you've
already suggested it! Funny how I've been ignoring the most obvious answer
for weeks!

Cheers,
    Ralf.

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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [patch v2] PS3: Add os-area database routines
  2007-10-09  1:07   ` [patch v2] " Geoff Levand
  2007-10-09 11:38     ` Geert Uytterhoeven
@ 2007-10-09 17:15     ` Linas Vepstas
  1 sibling, 0 replies; 24+ messages in thread
From: Linas Vepstas @ 2007-10-09 17:15 UTC (permalink / raw)
  To: Geoff Levand; +Cc: linuxppc-dev, paulus

On Mon, Oct 08, 2007 at 06:07:24PM -0700, Geoff Levand wrote:
> Subject: PS3: Add os-area database routines
> 
> 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 bootloader 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.

Perhaps I missed the discussion; but .. out of general curiosity,
what is the relation between this and the ppc_md.nvram_* system?
I note that pseries, powermac, chrp, celleb implement the nvram calls,
but cell and ps3 do not. So clearly, whatever this is, its not 
layered on top of nvram?

FWIW, I don't quite understand the nvram system; it seems to have
partitions; one part is an "os area", and a chuck of it is set 
up as a file system.

So I'm wondering -- wouldn't the DB os-area be "generically 
interesting" to other ppowerpc platforms? Maybe even other arches?
And why isn't this built on top of the nvram structure? ... etc?

--linas

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2007-10-09 17:15 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-06 21:35 [patch 0/6] PS3 os area patches for 2.6.24 geoffrey.levand
2007-10-06 21:35 ` [patch 1/6] PS3: Cleanup of os-area.c geoffrey.levand
2007-10-06 21:35 ` [patch 2/6] PS3: Remove unused os-area params geoffrey.levand
2007-10-08 14:00   ` Ranulf Doswell
2007-10-08 17:53     ` Geoff Levand
2007-10-08 22:38       ` Ranulf Doswell
2007-10-08 22:50         ` Geoff Levand
2007-10-06 21:35 ` [patch 3/6] PS3: os-area workqueue processing geoffrey.levand
2007-10-06 21:35 ` [patch 4/6] PS3: Add os-area rtc_diff set/get routines geoffrey.levand
2007-10-06 21:35 ` [patch 5/6] PS3: Save os-area params to device tree geoffrey.levand
2007-10-06 21:35 ` [patch 6/6] PS3: Add os-area database routines geoffrey.levand
2007-10-08  8:27   ` Geert Uytterhoeven
2007-10-09  1:08     ` Geoff Levand
2007-10-08 12:16   ` Geert Uytterhoeven
2007-10-09  1:12     ` Geoff Levand
2007-10-08 13:48   ` Ranulf Doswell
2007-10-08 17:52     ` Geoff Levand
2007-10-08 22:59       ` Ranulf Doswell
2007-10-08 23:36         ` Geoff Levand
2007-10-09  9:35         ` Geert Uytterhoeven
2007-10-09 12:23           ` Ranulf Doswell
2007-10-09  1:07   ` [patch v2] " Geoff Levand
2007-10-09 11:38     ` Geert Uytterhoeven
2007-10-09 17:15     ` Linas Vepstas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).