summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgpt/cgpt.c56
-rw-r--r--cgpt/cgpt.h5
-rw-r--r--cgpt/cgpt_common.c10
3 files changed, 70 insertions, 1 deletions
diff --git a/cgpt/cgpt.c b/cgpt/cgpt.c
index a3b20d99..2851f7c5 100644
--- a/cgpt/cgpt.c
+++ b/cgpt/cgpt.c
@@ -18,6 +18,8 @@ const char* progname;
const char* command;
void (*uuid_generator)(uint8_t* buffer);
+extern struct nand_layout nand;
+
struct {
const char *name;
int (*fp)(int argc, char *argv[]);
@@ -47,7 +49,40 @@ void Usage(void) {
printf("\nFor more detailed usage, use %s COMMAND -h\n\n", progname);
}
+static int is_pow2(size_t v) {
+ return v && (v & (v - 1)) == 0;
+}
+static int parse_nand_option(const char *arg) {
+ if ('=' != arg[0])
+ return -1;
+
+ arg++;
+ nand.bytes_per_page = atoi(arg);
+ arg = strchr(arg, ',');
+ if (!arg)
+ return -1;
+
+ arg++;
+ nand.pages_per_block = atoi(arg);
+ arg = strchr(arg, ',');
+ if (!arg)
+ return -1;
+
+ arg++;
+ nand.fts_block_offset = atoi(arg);
+ arg = strchr(arg, ',');
+ if (!arg)
+ return -1;
+
+ arg++;
+ nand.fts_block_size = atoi(arg);
+ if (nand.fts_block_size == 0 || !is_pow2(nand.pages_per_block) ||
+ !is_pow2(nand.bytes_per_page) || nand.bytes_per_page < 512) {
+ return -1;
+ }
+ return 0;
+}
int main(int argc, char *argv[]) {
int i;
@@ -62,6 +97,27 @@ int main(int argc, char *argv[]) {
else
progname = argv[0];
+
+ memset(&nand, 0, sizeof(nand));
+ for (i = 1; i < argc; ++i) {
+ if (0 == strncmp(argv[i], "-N", 2)) {
+ if (!parse_nand_option(argv[i] + 2)) {
+ int j;
+ nand.enabled = 1;
+
+ // Remove it form the list.
+ for (j = i; j < argc - 1; j++)
+ argv[j] = argv[j + 1];
+ argc--;
+ break;
+ }
+ // Bad nand config.
+ printf("Nand option must fit: -N=<bytes_per_page>,<pages_per_block>,"
+ "<block_offset_of_partition>,<block_size_of_partition>\n");
+ return CGPT_FAILED;
+ }
+ }
+
if (argc < 2) {
Usage();
return CGPT_FAILED;
diff --git a/cgpt/cgpt.h b/cgpt/cgpt.h
index 3cd6e8db..f6580868 100644
--- a/cgpt/cgpt.h
+++ b/cgpt/cgpt.h
@@ -52,6 +52,11 @@ struct drive {
struct pmbr pmbr;
};
+struct nand_layout {
+ int enabled;
+ int bytes_per_page, pages_per_block, fts_block_offset, fts_block_size;
+};
+
/* mode should be O_RDONLY or O_RDWR */
int DriveOpen(const char *drive_path, struct drive *drive, int mode);
diff --git a/cgpt/cgpt_common.c b/cgpt/cgpt_common.c
index 3d2fe3ba..dd8e510d 100644
--- a/cgpt/cgpt_common.c
+++ b/cgpt/cgpt_common.c
@@ -26,6 +26,10 @@
#include "flash_ts.h"
#include "vboot_host.h"
+struct nand_layout nand = {
+ 0, 0, 0, 0, 0
+};
+
void Error(const char *format, ...) {
va_list ap;
va_start(ap, format);
@@ -339,7 +343,7 @@ int GptSave(struct drive *drive) {
int DriveOpen(const char *drive_path, struct drive *drive, int mode) {
struct stat stat;
uint32_t sector_bytes;
- int is_mtd = 0;
+ int is_mtd = nand.enabled;
require(drive_path);
require(drive);
@@ -374,6 +378,10 @@ int DriveOpen(const char *drive_path, struct drive *drive, int mode) {
}
if (is_mtd) {
+ drive->mtd.fts_block_offset = nand.fts_block_offset;
+ drive->mtd.fts_block_size = nand.fts_block_size;
+ drive->mtd.flash_page_bytes = nand.bytes_per_page;
+ drive->mtd.flash_block_bytes = nand.pages_per_block * nand.bytes_per_page;
if (MtdLoad(drive, sector_bytes)) {
goto error_close;
}