LK: Add support to write on modem partition
Modem nand layout is different from Android nand layout. This change
updates lk nand driver to write on modem nand partitions.
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 6d6cf1c..3eac025 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -90,6 +90,8 @@
{
struct atag_ptbl_entry atag_ptn;
+ if (ptn->type == TYPE_MODEM_PARTITION)
+ return;
memcpy(atag_ptn.name, ptn->name, 16);
atag_ptn.name[15] = '\0';
atag_ptn.offset = ptn->start;
@@ -104,6 +106,7 @@
void *ramdisk, unsigned ramdisk_size)
{
unsigned *ptr = tags;
+ unsigned pcount = 0;
void (*entry)(unsigned,unsigned,unsigned*) = kernel;
struct ptable *ptable;
int cmdline_len = 0;
@@ -126,7 +129,13 @@
/* Skip NAND partition ATAGS for eMMC boot */
if ((ptable = flash_get_ptable()) && (ptable->count != 0)) {
int i;
- *ptr++ = 2 + (ptable->count * (sizeof(struct atag_ptbl_entry) /
+ for(i=0; i < ptable->count; i++) {
+ struct ptentry *ptn;
+ ptn = ptable_get(ptable, i);
+ if (ptn->type == TYPE_APPS_PARTITION)
+ pcount++;
+ }
+ *ptr++ = 2 + (pcount * (sizeof(struct atag_ptbl_entry) /
sizeof(unsigned)));
*ptr++ = 0x4d534d70;
for (i = 0; i < ptable->count; ++i)
diff --git a/include/lib/ptable.h b/include/lib/ptable.h
index 0883b8c..07fbf80 100644
--- a/include/lib/ptable.h
+++ b/include/lib/ptable.h
@@ -2,6 +2,8 @@
* Copyright (c) 2008, Google Inc.
* All rights reserved.
*
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -34,14 +36,20 @@
* (flash erase units)
*/
#define MAX_PTENTRY_NAME 16
-#define MAX_PTABLE_PARTS 16
+#define MAX_PTABLE_PARTS 32
+#define TYPE_MODEM_PARTITION 1
+#define TYPE_APPS_PARTITION 0
+#define PERM_NON_WRITEABLE 0
+#define PERM_WRITEABLE 1
struct ptentry
{
char name[MAX_PTENTRY_NAME];
unsigned start;
unsigned length;
unsigned flags;
+ char type;
+ char perm;
};
struct ptable
@@ -53,7 +61,7 @@
/* tools to populate and query the partition table */
void ptable_init(struct ptable *ptable);
void ptable_add(struct ptable *ptable, char *name, unsigned start,
- unsigned length, unsigned flags);
+ unsigned length, unsigned flags, char type, char perm);
struct ptentry *ptable_find(struct ptable *ptable, const char *name);
struct ptentry *ptable_get(struct ptable *ptable, int n);
int ptable_size(struct ptable *ptable);
diff --git a/lib/ptable/ptable.c b/lib/ptable/ptable.c
index 9648ef5..3ddf5fa 100644
--- a/lib/ptable/ptable.c
+++ b/lib/ptable/ptable.c
@@ -2,6 +2,8 @@
* Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
+ *Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -38,8 +40,11 @@
memset(ptable, 0, sizeof(struct ptable));
}
+char* ptype[] = {"Apps", "Modem"};
+char* pperm[] = {"No", "Yes"};
+
void ptable_add(struct ptable *ptable, char *name, unsigned start,
- unsigned length, unsigned flags)
+ unsigned length, unsigned flags, char type, char perm)
{
struct ptentry *ptn;
@@ -50,6 +55,8 @@
ptn->start = start;
ptn->length = length;
ptn->flags = flags;
+ ptn->type = type;
+ ptn->perm = perm;
}
void ptable_dump(struct ptable *ptable)
@@ -60,8 +67,8 @@
for (i = 0; i < ptable->count; ++i) {
ptn = &ptable->parts[i];
dprintf(INFO, "ptn %d name='%s' start=%08x len=%08x "
- "flags=%08x\n", i, ptn->name, ptn->start, ptn->length,
- ptn->flags);
+ "flags=%08x type=%s Writable=%s\n", i, ptn->name, ptn->start, ptn->length,
+ ptn->flags, ptype[ptn->type], pperm[ptn->perm]);
}
}
diff --git a/platform/msm_shared/nand.c b/platform/msm_shared/nand.c
index 6e5a86f..40b080c 100755
--- a/platform/msm_shared/nand.c
+++ b/platform/msm_shared/nand.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2008, Google Inc.
* All rights reserved.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -69,6 +69,8 @@
#define NAND_CFG1_RAW 0x5045D
static unsigned CFG0, CFG1;
+static unsigned CFG0_M, CFG1_M;
+static unsigned CFG0_A, CFG1_A;
#define CFG1_WIDE_FLASH (1U << 1)
@@ -137,6 +139,19 @@
/* Note: Onenand flag is 0 for NAND Flash and 1 for OneNAND flash */
/* Note: The First row will be filled at runtime during ONFI probe */
};
+static void set_nand_configuration(char type)
+{
+ if(type == TYPE_MODEM_PARTITION)
+ {
+ CFG0 = CFG0_M;
+ CFG1 = CFG1_M;
+ }
+ else
+ {
+ CFG0 = CFG0_A;
+ CFG1 = CFG1_A;
+ }
+}
static void flash_nand_read_id(dmov_s *cmdlist, unsigned *ptrlist)
{
@@ -525,6 +540,11 @@
unsigned n;
unsigned cwperpage;
cwperpage = (flash_pagesize >> 9);
+ unsigned modem_partition = 0;
+ if (CFG0 == CFG0_M)
+ {
+ modem_partition = 1;
+ }
data->cmd = NAND_CMD_PRG_PAGE;
data->addr0 = page << 16;
@@ -544,7 +564,10 @@
/* GO bit for the EXEC register */
data->exec = 1;
- data->ecc_cfg = 0x203;
+ if (modem_partition)
+ data->ecc_cfg = 0x1FF;
+ else
+ data->ecc_cfg = 0x203;
/* save existing ecc config */
cmd->cmd = CMD_OCB;
@@ -581,15 +604,20 @@
cmd->cmd = 0;
cmd->dst = NAND_FLASH_BUFFER;
if (!raw_mode){
- cmd->src = addr + n * 516;
- cmd->len = ((n < (cwperpage - 1)) ? 516 : (512 - ((cwperpage - 1) << 2)));
+ if(modem_partition){
+ cmd->src = addr + n * 512;
+ cmd->len = 512;
+ }else{
+ cmd->src = addr + n * 516;
+ cmd->len = ((n < (cwperpage - 1)) ? 516 : (512 - ((cwperpage - 1) << 2)));
+ }
}else{
cmd->src = addr;
cmd->len = 528;
}
cmd++;
- if ((n == (cwperpage - 1)) && (!raw_mode)) {
+ if ((n == (cwperpage - 1)) && (!raw_mode) && (!modem_partition)) {
/* write extra data */
cmd->cmd = 0;
cmd->src = spareaddr;
@@ -677,30 +705,33 @@
static int flash_nand_read_config(dmov_s *cmdlist, unsigned *ptrlist)
{
+ static unsigned CFG0_TMP, CFG1_TMP;
cmdlist[0].cmd = CMD_OCB;
cmdlist[0].src = NAND_DEV0_CFG0;
- cmdlist[0].dst = paddr(&CFG0);
+ cmdlist[0].dst = paddr(&CFG0_TMP);
cmdlist[0].len = 4;
cmdlist[1].cmd = CMD_OCU | CMD_LC;
cmdlist[1].src = NAND_DEV0_CFG1;
- cmdlist[1].dst = paddr(&CFG1);
+ cmdlist[1].dst = paddr(&CFG1_TMP);
cmdlist[1].len = 4;
*ptrlist = (paddr(cmdlist) >> 3) | CMD_PTR_LP;
dmov_exec_cmdptr(DMOV_NAND_CHAN, ptrlist);
- if((CFG0 == 0) || (CFG1 == 0)) {
+ if((CFG0_TMP == 0) || (CFG1_TMP == 0)) {
return -1;
}
+ CFG0_A = CFG0_TMP;
+ CFG1_A = CFG1_TMP;
if (flash_info.type == FLASH_16BIT_NAND_DEVICE) {
nand_cfg1 |= CFG1_WIDE_FLASH;
}
dprintf(INFO, "nandcfg: %x %x (initial)\n", CFG0, CFG1);
- CFG0 = (((flash_pagesize >> 9) - 1) << 6) /* 4/8 cw/pg for 2/4k */
+ CFG0_A = (((flash_pagesize >> 9) - 1) << 6) /* 4/8 cw/pg for 2/4k */
| (516 << 9) /* 516 user data bytes */
| (10 << 19) /* 10 parity bytes */
| (5 << 27) /* 5 address cycles */
@@ -708,7 +739,7 @@
| (1 << 31) /* Send read cmd */
/* 0 spare bytes for 16 bit nand or 1 spare bytes for 8 bit */
| ((nand_cfg1 & CFG1_WIDE_FLASH) ? (0 << 23) : (1 << 23));
- CFG1 = (0 << 0) /* Enable ecc */
+ CFG1_A = (0 << 0) /* Enable ecc */
| (7 << 2) /* 8 recovery cycles */
| (0 << 5) /* Allow CS deassertion */
| ((flash_pagesize - (528 * ((flash_pagesize >> 9) - 1)) + 1) << 6) /* Bad block marker location */
@@ -716,8 +747,28 @@
| (2 << 17) /* 6 cycle tWB/tRB */
| (nand_cfg1 & CFG1_WIDE_FLASH); /* preserve wide flash flag */
- dprintf(INFO, "nandcfg: %x %x (used)\n", CFG0, CFG1);
+ dprintf(INFO, "nandcfg(Apps): %x %x (used)\n", CFG0_A, CFG1_A);
+ CFG0_M = CFG0_TMP;
+ CFG1_M = CFG1_TMP;
+ if (flash_info.type == FLASH_16BIT_NAND_DEVICE) {
+ nand_cfg1 |= CFG1_WIDE_FLASH;
+ }
+ CFG0_M = (((flash_pagesize >> 9) - 1) << 6) /* 4/8 cw/pg for 2/4k */
+ | (512 << 9) /* 512 user data bytes */
+ | (10 << 19) /* 10 parity bytes */
+ | (5 << 27) /* 5 address cycles */
+ | (0 << 30) /* Do not read status before data */
+ | (1 << 31) /* Send read cmd */
+ | ((nand_cfg1 & CFG1_WIDE_FLASH) ? (4 << 23) : (5 << 23));
+ CFG1_M = (0 << 0) /* Enable ecc */
+ | (7 << 2) /* 8 recovery cycles */
+ | (0 << 5) /* Allow CS deassertion */
+ | ((flash_pagesize - (528 * ((flash_pagesize >> 9) - 1)) + 1) << 6) /* Bad block marker location */
+ | (0 << 16) /* Bad block in user data area */
+ | (2 << 17) /* 6 cycle tWB/tRB */
+ | (nand_cfg1 & CFG1_WIDE_FLASH); /* preserve wide flash flag */
+ dprintf(INFO, "nandcfg(Modem): %x %x (used)\n", CFG0_M, CFG1_M);
return 0;
}
@@ -2244,6 +2295,7 @@
unsigned block = ptn->start;
unsigned count = ptn->length;
+ set_nand_configuration(ptn->type);
while(count-- > 0) {
if(flash_erase_block(flash_cmdlist, flash_ptrlist, block * 64)) {
dprintf(INFO, "cannot erase @ %d (bad block?)\n", block);
@@ -2267,6 +2319,9 @@
int result = 0;
int isbad = 0;
+ ASSERT(ptn->type == TYPE_APPS_PARTITION);
+ set_nand_configuration(TYPE_APPS_PARTITION);
+
if(offset & (flash_pagesize - 1))
return -1;
@@ -2323,6 +2378,13 @@
unsigned n;
int r;
+ if ((flash_info.type == FLASH_ONENAND_DEVICE) && (ptn->type == TYPE_MODEM_PARTITION))
+ {
+ dprintf(CRITICAL, "flash_write_image: feature not supported\n");
+ return -1;
+ }
+
+ set_nand_configuration(ptn->type);
for(n = 0; n < 16; n++) spare[n] = 0xffffffff;
while(bytes > 0) {
@@ -2356,7 +2418,9 @@
if(flash_erase_block(flash_cmdlist, flash_ptrlist, page)) {
dprintf(INFO, "flash_write_image: erase failure @ page %d\n", page);
}
- flash_mark_badblock(flash_cmdlist, flash_ptrlist, page);
+ if (ptn->type != TYPE_MODEM_PARTITION) {
+ flash_mark_badblock(flash_cmdlist, flash_ptrlist, page);
+ }
dprintf(INFO, "flash_write_image: restart write @ page %d (src %d)\n", page, image - (const unsigned char *)data);
page += 64;
continue;
diff --git a/platform/msm_shared/smem_ptable.c b/platform/msm_shared/smem_ptable.c
index 1e07532..de4422d 100644
--- a/platform/msm_shared/smem_ptable.c
+++ b/platform/msm_shared/smem_ptable.c
@@ -2,6 +2,8 @@
* Copyright (c) 2009, Google Inc.
* All rights reserved.
*
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -31,6 +33,7 @@
#include <string.h>
#include <sys/types.h>
#include <platform/iomap.h>
+#include <lib/ptable.h>
#include "smem.h"
@@ -100,3 +103,33 @@
{
return smem_apps_flash_start;
}
+
+void smem_add_modem_partitions(struct ptable *flash_ptable)
+{
+ int i;
+
+ if (smem_ptable.magic[0] != _SMEM_PTABLE_MAGIC_1 ||
+ smem_ptable.magic[1] != _SMEM_PTABLE_MAGIC_2)
+ return;
+
+ for (i = 0; i < 16; i++)
+ {
+ char * token;
+ char * pname = NULL;
+ struct smem_ptn *p = &smem_ptable.parts[i];
+ if (p->name[0] == '\0')
+ continue;
+ token = strtok(p->name, ":");
+ while (token)
+ {
+ pname = token;
+ token = strtok (NULL, ":");
+ }
+ if(pname)
+ {
+ ptable_add(flash_ptable, pname, p->start,
+ p->size, 0, TYPE_MODEM_PARTITION, PERM_WRITEABLE);
+ }
+ }
+}
+
diff --git a/target/msm7625_ffa/init.c b/target/msm7625_ffa/init.c
index 546cc02..e686d5b 100644
--- a/target/msm7625_ffa/init.c
+++ b/target/msm7625_ffa/init.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2009, Google Inc.
* All rights reserved.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -119,9 +119,11 @@
if ((len == 0) && (i == num_parts - 1))
len = flash_info->num_blocks - offset - ptn->start;
ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
- len, ptn->flags);
+ len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
}
+ smem_add_modem_partitions(&flash_ptable);
+
ptable_dump(&flash_ptable);
flash_set_ptable(&flash_ptable);
}
diff --git a/target/msm7625_surf/init.c b/target/msm7625_surf/init.c
index 9bdd729..01a8a46 100644
--- a/target/msm7625_surf/init.c
+++ b/target/msm7625_surf/init.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2009, Google Inc.
* All rights reserved.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -119,9 +119,11 @@
if ((len == 0) && (i == num_parts - 1))
len = flash_info->num_blocks - offset - ptn->start;
ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
- len, ptn->flags);
+ len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
}
+ smem_add_modem_partitions(&flash_ptable);
+
ptable_dump(&flash_ptable);
flash_set_ptable(&flash_ptable);
}
diff --git a/target/msm7627_ffa/init.c b/target/msm7627_ffa/init.c
index 02d4de9..6c9ea7d 100644
--- a/target/msm7627_ffa/init.c
+++ b/target/msm7627_ffa/init.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2009, Google Inc.
* All rights reserved.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -152,9 +152,11 @@
next_ptr_start_adr = ptn->start + ptn->length;
}
ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
- len, ptn->flags);
+ len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
}
+ smem_add_modem_partitions(&flash_ptable);
+
ptable_dump(&flash_ptable);
flash_set_ptable(&flash_ptable);
}
diff --git a/target/msm7627_surf/init.c b/target/msm7627_surf/init.c
index 89451cb..9014e2d 100644
--- a/target/msm7627_surf/init.c
+++ b/target/msm7627_surf/init.c
@@ -157,9 +157,11 @@
next_ptr_start_adr = ptn->start + ptn->length;
}
ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
- len, ptn->flags);
+ len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
}
+ smem_add_modem_partitions(&flash_ptable);
+
ptable_dump(&flash_ptable);
flash_set_ptable(&flash_ptable);
}
diff --git a/target/msm7630_surf/init.c b/target/msm7630_surf/init.c
index 132fe66..75ac749 100644
--- a/target/msm7630_surf/init.c
+++ b/target/msm7630_surf/init.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2009, Google Inc.
* All rights reserved.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -165,9 +165,11 @@
next_ptr_start_adr = ptn->start + ptn->length;
}
ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
- len, ptn->flags);
+ len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
}
+ smem_add_modem_partitions(&flash_ptable);
+
ptable_dump(&flash_ptable);
flash_set_ptable(&flash_ptable);
}
diff --git a/target/qsd8250_ffa/init.c b/target/qsd8250_ffa/init.c
index 7eb10e8..b44014d 100644
--- a/target/qsd8250_ffa/init.c
+++ b/target/qsd8250_ffa/init.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2009, Google Inc.
* All rights reserved.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -144,9 +144,11 @@
next_ptr_start_adr = ptn->start + ptn->length;
}
ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
- len, ptn->flags);
+ len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
}
+ smem_add_modem_partitions(&flash_ptable);
+
ptable_dump(&flash_ptable);
flash_set_ptable(&flash_ptable);
}
diff --git a/target/qsd8250_surf/init.c b/target/qsd8250_surf/init.c
index 08c5470..0b3b0cd 100644
--- a/target/qsd8250_surf/init.c
+++ b/target/qsd8250_surf/init.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2009, Google Inc.
* All rights reserved.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -143,9 +143,11 @@
next_ptr_start_adr = ptn->start + ptn->length;
}
ptable_add(&flash_ptable, ptn->name, offset + ptn->start,
- len, ptn->flags);
+ len, ptn->flags, TYPE_APPS_PARTITION, PERM_WRITEABLE);
}
+ smem_add_modem_partitions(&flash_ptable);
+
ptable_dump(&flash_ptable);
flash_set_ptable(&flash_ptable);
}