21 #include <linux/kernel.h>
26 #include <linux/export.h>
27 #include <linux/ctype.h>
30 #include <linux/slab.h>
45 #define OS_AREA_HEADER_MAGIC_NUM "cell_ext_os_area"
124 #define OS_AREA_DB_MAGIC_NUM "-db-"
197 static const struct os_area_db_id os_area_db_id_video_mode = {
202 #define SECONDS_FROM_1970_TO_2000 946684800LL
219 static struct property property_rtc_diff = {
220 .name =
"linux,rtc_diff",
225 static struct property property_av_multi_out = {
226 .name =
"linux,av_multi_out",
239 os_area_flash_ops = ops;
249 if (os_area_flash_ops)
250 res = os_area_flash_ops->
read(buf, count, pos);
256 static ssize_t os_area_flash_write(
const void *buf,
size_t count, loff_t pos)
261 if (os_area_flash_ops)
262 res = os_area_flash_ops->
write(buf, count, pos);
282 pr_debug(
"%s:%d found %s\n", __func__, __LINE__, prop->
name);
289 pr_debug(
"%s:%d prom_set_property failed\n", __func__,
307 pr_debug(
"%s:%d not found %s\n", __func__, __LINE__,
316 for (i = 0; i < size_of_field; i++)
317 s[i] =
isprint(field[i]) ? field[
i] :
'.';
322 #define dump_header(_a) _dump_header(_a, __func__, __LINE__)
329 pr_debug(
"%s:%d: h.magic_num: '%s'\n", func, line,
331 pr_debug(
"%s:%d: h.hdr_version: %u\n", func, line,
333 pr_debug(
"%s:%d: h.db_area_offset: %u\n", func, line,
335 pr_debug(
"%s:%d: h.ldr_area_offset: %u\n", func, line,
337 pr_debug(
"%s:%d: h.ldr_format: %u\n", func, line,
339 pr_debug(
"%s:%d: h.ldr_size: %xh\n", func, line,
343 #define dump_params(_a) _dump_params(_a, __func__, __LINE__)
352 pr_debug(
"%s:%d: p.static_ip_addr: %u.%u.%u.%u\n", func, line,
355 pr_debug(
"%s:%d: p.network_mask: %u.%u.%u.%u\n", func, line,
358 pr_debug(
"%s:%d: p.default_gateway: %u.%u.%u.%u\n", func, line,
361 pr_debug(
"%s:%d: p.dns_primary: %u.%u.%u.%u\n", func, line,
364 pr_debug(
"%s:%d: p.dns_secondary: %u.%u.%u.%u\n", func, line,
373 pr_debug(
"%s:%d magic_num failed\n", __func__, __LINE__);
378 pr_debug(
"%s:%d hdr_version failed\n", __func__, __LINE__);
383 pr_debug(
"%s:%d offsets failed\n", __func__, __LINE__);
394 pr_debug(
"%s:%d magic_num failed\n", __func__, __LINE__);
399 pr_debug(
"%s:%d version failed\n", __func__, __LINE__);
423 static unsigned int db_align_up(
unsigned int val,
unsigned int size)
425 return (val + (size - 1)) & (~(size - 1));
435 static int db_for_each_64(
const struct os_area_db *db,
441 i->
match_id = match_id ? *match_id : os_area_db_id_any;
452 pr_debug(
"%s:%d: reached end\n", __func__, __LINE__);
470 for (i.
db =
NULL; db_for_each_64(db,
id, &i); ) {
472 pr_debug(
"%s:%d: got (%d:%d) %llxh\n", __func__, __LINE__,
488 pr_debug(
"%s:%d: (%d:%d) <= %llxh\n", __func__, __LINE__,
489 id->
owner, id->
key, (
unsigned long long)value);
493 pr_debug(
"%s:%d: bad id: (%d:%d)\n", __func__,
498 db_delete_64(db,
id);
501 if (db_for_each_64(db, &os_area_db_id_empty, &i)) {
503 pr_debug(
"%s:%d: got (%d:%d) %llxh\n", __func__, __LINE__,
507 i.
idx->owner =
id->owner;
508 i.
idx->key =
id->key;
511 pr_debug(
"%s:%d: set (%d:%d) <= %llxh\n", __func__, __LINE__,
521 static int db_get_64(
const struct os_area_db *db,
527 if (db_for_each_64(db,
id, &i)) {
529 pr_debug(
"%s:%d: found %lld\n", __func__, __LINE__,
533 pr_debug(
"%s:%d: not found\n", __func__, __LINE__);
537 static int db_get_rtc_diff(
const struct os_area_db *db, int64_t *rtc_diff)
539 return db_get_64(db, &os_area_db_id_rtc_diff, (
uint64_t*)rtc_diff);
542 #define dump_db(a) _dump_db(a, __func__, __LINE__)
543 static void _dump_db(
const struct os_area_db *db,
const char *
func,
549 pr_debug(
"%s:%d: db.magic_num: '%s'\n", func, line,
551 pr_debug(
"%s:%d: db.version: %u\n", func, line,
553 pr_debug(
"%s:%d: db.index_64: %u\n", func, line,
555 pr_debug(
"%s:%d: db.count_64: %u\n", func, line,
557 pr_debug(
"%s:%d: db.index_32: %u\n", func, line,
559 pr_debug(
"%s:%d: db.count_32: %u\n", func, line,
561 pr_debug(
"%s:%d: db.index_16: %u\n", func, line,
563 pr_debug(
"%s:%d: db.count_16: %u\n", func, line,
567 static void os_area_db_init(
struct os_area_db *db)
572 VALUES_64_COUNT = 57,
574 VALUES_32_COUNT = 57,
576 VALUES_16_COUNT = 57,
586 + INDEX_64_COUNT *
sizeof(
struct db_index)
587 + VALUES_64_COUNT *
sizeof(
u64);
590 + INDEX_64_COUNT *
sizeof(
struct db_index)
591 + VALUES_64_COUNT *
sizeof(
u64)
592 + INDEX_32_COUNT *
sizeof(
struct db_index)
593 + VALUES_32_COUNT *
sizeof(
u32);
607 + INDEX_64_COUNT *
sizeof(
struct db_index)
608 + VALUES_64_COUNT *
sizeof(
u64)
609 + INDEX_32_COUNT *
sizeof(
struct db_index)
610 + VALUES_32_COUNT *
sizeof(
u32)
611 + INDEX_16_COUNT *
sizeof(
struct db_index)
612 + VALUES_16_COUNT *
sizeof(
u16)
621 static int update_flash_db(
void)
634 pr_debug(
"%s: kmalloc failed\n", __func__);
638 count = os_area_flash_read(header, buf_len, 0);
640 pr_debug(
"%s: os_area_flash_read failed %zd\n", __func__,
649 pr_debug(
"%s: verify_header failed\n", __func__);
657 db = (
void *)header + pos;
661 pr_notice(
"%s: Verify of flash database failed, formatting.\n",
671 count = os_area_flash_write(db,
sizeof(
struct os_area_db), pos);
673 pr_debug(
"%s: os_area_flash_write failed %zd\n", __func__,
675 error = count < 0 ? count : -
EIO;
695 pr_debug(
" -> %s:%d\n", __func__, __LINE__);
699 os_area_set_property(node, &property_rtc_diff);
702 pr_debug(
"%s:%d of_find_node_by_path failed\n",
705 error = update_flash_db();
707 pr_warning(
"%s: Could not update FLASH ROM\n", __func__);
709 pr_debug(
" <- %s:%d\n", __func__, __LINE__);
712 static void os_area_queue_work(
void)
743 pr_debug(
" -> %s:%d\n", __func__, __LINE__);
748 pr_debug(
"%s:%d ps3_repository_read_boot_dat_info failed\n",
757 result = verify_header(header);
761 pr_debug(
"%s:%d verify_header failed\n", __func__, __LINE__);
780 memset(header, 0,
sizeof(*header));
782 pr_debug(
" <- %s:%d\n", __func__, __LINE__);
793 pr_debug(
" -> %s:%d\n", __func__, __LINE__);
799 os_area_get_property(node, &property_rtc_diff);
800 os_area_get_property(node, &property_av_multi_out);
807 os_area_set_property(node, &property_rtc_diff);
808 os_area_set_property(node, &property_av_multi_out);
811 pr_debug(
"%s:%d of_find_node_by_path failed\n",
814 pr_debug(
" <- %s:%d\n", __func__, __LINE__);
838 os_area_queue_work();