summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/target/firmware/Makefile2
-rw-r--r--src/target/firmware/board/compal_e86/init.c4
-rwxr-xr-xsrc/target/firmware/board/compal_e88/init.c4
-rw-r--r--src/target/firmware/board/fcdev3b/init.c4
-rw-r--r--src/target/firmware/board/gta0x/init.c4
-rw-r--r--src/target/firmware/board/pirelli_dpl10/init.c4
-rw-r--r--src/target/firmware/include/string.h3
-rw-r--r--src/target/firmware/include/tiffs.h33
-rw-r--r--src/target/firmware/lib/Makefile5
-rw-r--r--src/target/firmware/lib/index.c12
-rw-r--r--src/target/firmware/lib/memcmp.S18
-rw-r--r--src/target/firmware/lib/strcmp.c12
-rw-r--r--src/target/firmware/tiffs/Makefile5
-rw-r--r--src/target/firmware/tiffs/globals.c12
-rw-r--r--src/target/firmware/tiffs/globals.h9
-rw-r--r--src/target/firmware/tiffs/init.c103
-rw-r--r--src/target/firmware/tiffs/readfile.c264
17 files changed, 496 insertions, 2 deletions
diff --git a/src/target/firmware/Makefile b/src/target/firmware/Makefile
index 1196d10f..914db6c7 100644
--- a/src/target/firmware/Makefile
+++ b/src/target/firmware/Makefile
@@ -107,6 +107,7 @@ ANY_APP_LIBS+= calypso/libcalypso.a \
layer1/liblayer1.a \
lib/libmini.a \
comm/libcomm.a \
+ tiffs/libtiffs.a \
../../shared/libosmocore/build-target/src/.libs/libosmocore.a \
../../shared/libosmocore/build-target/src/gsm/.libs/libosmogsm.a \
../../shared/libosmocore/build-target/src/codec/.libs/libosmocodec.a
@@ -123,6 +124,7 @@ INCLUDES=-Iinclude/ -I../../../include -I../../shared/libosmocore/include -I../.
-include calypso/Makefile
-include layer1/Makefile
-include comm/Makefile
+-include tiffs/Makefile
-include lib/Makefile
# Include rules
diff --git a/src/target/firmware/board/compal_e86/init.c b/src/target/firmware/board/compal_e86/init.c
index fed9f85a..725f1841 100644
--- a/src/target/firmware/board/compal_e86/init.c
+++ b/src/target/firmware/board/compal_e86/init.c
@@ -31,6 +31,7 @@
#include <keypad.h>
#include <console.h>
#include <flash/cfi_flash.h>
+#include <tiffs.h>
#include <calypso/irq.h>
#include <calypso/clock.h>
@@ -146,4 +147,7 @@ void board_init(int with_irq)
/* enable LEDB driver of Iota for keypad backlight */
twl3025_reg_write(AUXLED, 0x02);
+
+ /* Initialize TIFFS reader (5 sectors of 64 KiB each) */
+ tiffs_init(0x370000, 0x10000, 5);
}
diff --git a/src/target/firmware/board/compal_e88/init.c b/src/target/firmware/board/compal_e88/init.c
index 04ae4588..956f7dc5 100755
--- a/src/target/firmware/board/compal_e88/init.c
+++ b/src/target/firmware/board/compal_e88/init.c
@@ -30,6 +30,7 @@
#include <keypad.h>
#include <console.h>
#include <flash/cfi_flash.h>
+#include <tiffs.h>
#include <calypso/irq.h>
#include <calypso/clock.h>
@@ -142,4 +143,7 @@ void board_init(int with_irq)
/* Initialize the charging controller */
battery_compal_e88_init();
+
+ /* Initialize TIFFS reader (6 sectors of 8 KiB each) */
+ tiffs_init(0x001f0000, 0x2000, 6);
}
diff --git a/src/target/firmware/board/fcdev3b/init.c b/src/target/firmware/board/fcdev3b/init.c
index 92be6674..c0705364 100644
--- a/src/target/firmware/board/fcdev3b/init.c
+++ b/src/target/firmware/board/fcdev3b/init.c
@@ -32,6 +32,7 @@
#include <keypad.h>
#include <console.h>
#include <flash/cfi_flash.h>
+#include <tiffs.h>
#include <calypso/irq.h>
#include <calypso/clock.h>
@@ -138,4 +139,7 @@ void board_init(int with_irq)
/* Initialize ABB driver (uses SPI) */
twl3025_init();
+
+ /* Initialize TIFFS reader (8 sectors of 256 KiB each) */
+ tiffs_init(0x01800000, 0x40000, 8);
}
diff --git a/src/target/firmware/board/gta0x/init.c b/src/target/firmware/board/gta0x/init.c
index b93f79c7..7fba7561 100644
--- a/src/target/firmware/board/gta0x/init.c
+++ b/src/target/firmware/board/gta0x/init.c
@@ -30,6 +30,7 @@
#include <keypad.h>
#include <console.h>
#include <flash/cfi_flash.h>
+#include <tiffs.h>
#include <calypso/irq.h>
#include <calypso/clock.h>
@@ -132,4 +133,7 @@ void board_init(int with_irq)
/* Initialize ABB driver (uses SPI) */
twl3025_init();
+
+ /* Initialize TIFFS reader (7 sectors of 64 KiB each) */
+ tiffs_init(0x380000, 0x10000, 7);
}
diff --git a/src/target/firmware/board/pirelli_dpl10/init.c b/src/target/firmware/board/pirelli_dpl10/init.c
index da233088..1af6e7c9 100644
--- a/src/target/firmware/board/pirelli_dpl10/init.c
+++ b/src/target/firmware/board/pirelli_dpl10/init.c
@@ -31,6 +31,7 @@
#include <keypad.h>
#include <console.h>
#include <flash/cfi_flash.h>
+#include <tiffs.h>
#include <calypso/irq.h>
#include <calypso/clock.h>
@@ -156,4 +157,7 @@ void board_init(int with_irq)
/* enable LEDB driver of Iota for keypad backlight */
twl3025_reg_write(AUXLED, 0x02);
+
+ /* Initialize TIFFS reader (18 sectors of 256 KiB each) */
+ tiffs_init(0x02000000, 0x40000, 18);
}
diff --git a/src/target/firmware/include/string.h b/src/target/firmware/include/string.h
index f060659a..ecef13d0 100644
--- a/src/target/firmware/include/string.h
+++ b/src/target/firmware/include/string.h
@@ -9,4 +9,7 @@ size_t strlen(const char *s);
void *memset(void *s, int c, size_t n);
void *memcpy(void *dest, const void *src, size_t n);
+int memcmp(const void *s1, const void *s2, size_t n);
+int strcmp(const char *s1, const char *s2);
+
#endif
diff --git a/src/target/firmware/include/tiffs.h b/src/target/firmware/include/tiffs.h
new file mode 100644
index 00000000..4713c4e1
--- /dev/null
+++ b/src/target/firmware/include/tiffs.h
@@ -0,0 +1,33 @@
+/*
+ * The external API for the TIFFS reader library (libtiffs).
+ *
+ * For the file reading functions, the return code is 0 if the file wasn't
+ * found or there is no valid FFS (no error msg printed), 1 if the file was
+ * found and read successfully, or negative if some other error(s) occurred
+ * (error msg printed internally).
+ */
+
+#define INODE_TO_DATAPTR(i) \
+ ((uint8_t *)tiffs_base_addr + ((i)->dataptr << 4))
+
+#define TIFFS_OBJTYPE_FILE 0xF1
+#define TIFFS_OBJTYPE_DIR 0xF2
+#define TIFFS_OBJTYPE_SEGMENT 0xF4
+
+struct tiffs_inode {
+ uint16_t len;
+ uint8_t reserved1;
+ uint8_t type;
+ uint16_t descend;
+ uint16_t sibling;
+ uint32_t dataptr;
+ uint16_t sequence;
+ uint16_t updates;
+};
+
+int tiffs_init(uint32_t base_addr, uint32_t sector_size, unsigned nsectors);
+
+int tiffs_read_file_maxlen(const char *pathname, uint8_t *buf,
+ size_t maxlen, size_t *lenrtn);
+int tiffs_read_file_fixedlen(const char *pathname, uint8_t *buf,
+ size_t expect_len);
diff --git a/src/target/firmware/lib/Makefile b/src/target/firmware/lib/Makefile
index a2a6d457..75461984 100644
--- a/src/target/firmware/lib/Makefile
+++ b/src/target/firmware/lib/Makefile
@@ -2,6 +2,7 @@
LIBRARIES+=mini
LIB_mini_DIR=lib
LIB_mini_SRCS=vsprintf.c string.c ctype.c printf.c console.c ctors.c \
- changebit.S clearbit.S delay.c div64.S lib1funcs.S memcpy.S memset.S setbit.S testchangebit.S testclearbit.S testsetbit.S
-
+ changebit.S clearbit.S delay.c div64.S lib1funcs.S memcpy.S \
+ memset.S setbit.S testchangebit.S testclearbit.S testsetbit.S \
+ memcmp.S index.c strcmp.c
diff --git a/src/target/firmware/lib/index.c b/src/target/firmware/lib/index.c
new file mode 100644
index 00000000..bb304c04
--- /dev/null
+++ b/src/target/firmware/lib/index.c
@@ -0,0 +1,12 @@
+char *
+index(p, ch)
+ register char *p, ch;
+{
+ for (;; ++p) {
+ if (*p == ch)
+ return(p);
+ if (!*p)
+ return((char *)0);
+ }
+ /* NOTREACHED */
+}
diff --git a/src/target/firmware/lib/memcmp.S b/src/target/firmware/lib/memcmp.S
new file mode 100644
index 00000000..c60b170b
--- /dev/null
+++ b/src/target/firmware/lib/memcmp.S
@@ -0,0 +1,18 @@
+ .text
+ .code 32
+ .globl memcmp
+memcmp:
+ cmp r2, #0
+ beq zero_len_out
+ mov r3, r0
+1: ldrb r0, [r3], #1
+ ldrb r12, [r1], #1
+ subs r0, r0, r12
+ bxne lr
+ subs r2, r2, #1
+ bne 1b
+ bx lr
+
+zero_len_out:
+ mov r0, #0
+ bx lr
diff --git a/src/target/firmware/lib/strcmp.c b/src/target/firmware/lib/strcmp.c
new file mode 100644
index 00000000..9a7fa818
--- /dev/null
+++ b/src/target/firmware/lib/strcmp.c
@@ -0,0 +1,12 @@
+/*
+ * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0
+ */
+
+strcmp(s1, s2)
+ register char *s1, *s2;
+{
+ while (*s1 == *s2++)
+ if (*s1++=='\0')
+ return(0);
+ return(*s1 - *--s2);
+}
diff --git a/src/target/firmware/tiffs/Makefile b/src/target/firmware/tiffs/Makefile
new file mode 100644
index 00000000..6ded9e87
--- /dev/null
+++ b/src/target/firmware/tiffs/Makefile
@@ -0,0 +1,5 @@
+
+LIBRARIES+=tiffs
+LIB_tiffs_DIR=tiffs
+LIB_tiffs_SRCS=globals.c init.c readfile.c
+
diff --git a/src/target/firmware/tiffs/globals.c b/src/target/firmware/tiffs/globals.c
new file mode 100644
index 00000000..ffbba42a
--- /dev/null
+++ b/src/target/firmware/tiffs/globals.c
@@ -0,0 +1,12 @@
+/* global variables for the TIFFS reader code */
+
+#include <stdint.h>
+#include "globals.h"
+
+uint32_t tiffs_base_addr;
+uint32_t tiffs_sector_size;
+unsigned tiffs_nsectors;
+
+struct tiffs_inode *tiffs_active_index;
+int tiffs_root_ino;
+int tiffs_init_done;
diff --git a/src/target/firmware/tiffs/globals.h b/src/target/firmware/tiffs/globals.h
new file mode 100644
index 00000000..7c64693b
--- /dev/null
+++ b/src/target/firmware/tiffs/globals.h
@@ -0,0 +1,9 @@
+/* global variables for the TIFFS reader code - extern declarations */
+
+extern uint32_t tiffs_base_addr;
+extern uint32_t tiffs_sector_size;
+extern unsigned tiffs_nsectors;
+
+extern struct tiffs_inode *tiffs_active_index;
+extern int tiffs_root_ino;
+extern int tiffs_init_done;
diff --git a/src/target/firmware/tiffs/init.c b/src/target/firmware/tiffs/init.c
new file mode 100644
index 00000000..6a3b48a4
--- /dev/null
+++ b/src/target/firmware/tiffs/init.c
@@ -0,0 +1,103 @@
+/* TIFFS (TI Flash File System) reader implementation */
+
+/*
+ * (C) 2017 by Mychaela Falconia <mychaela.falconia@gmail.com>
+ * Tweaked (coding style changes) by Vadim Yanitskiy <axilirator@gmail.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include <tiffs.h>
+#include "globals.h"
+
+/* Each flash sector used for TIFFS begins with this 6-byte signature */
+static const uint8_t ffs_sector_signature[6] = {
+ 'F', 'f', 's', '#', 0x10, 0x02
+};
+
+static int find_indexblk(void)
+{
+ uint32_t sector_addr;
+ uint8_t *sector_ptr;
+ unsigned i;
+
+ sector_addr = tiffs_base_addr;
+ for (i = 0; i < tiffs_nsectors; i++) {
+ sector_ptr = (uint8_t *) sector_addr;
+ if (!memcmp(sector_ptr, ffs_sector_signature, 6)
+ && sector_ptr[8] == 0xAB) {
+ printf("Found TIFFS active index block "
+ "at 0x%" PRIx32 "\n", sector_addr);
+ tiffs_active_index = (struct tiffs_inode *) sector_addr;
+ return 0;
+ }
+ sector_addr += tiffs_sector_size;
+ }
+
+ puts("TIFFS error: no active index block found\n");
+ return -1;
+}
+
+static int find_rootino(void)
+{
+ struct tiffs_inode *irec;
+ unsigned ino = 0;
+
+ while (++ino < tiffs_sector_size >> 4) {
+ irec = tiffs_active_index + ino;
+ if (irec->type != TIFFS_OBJTYPE_DIR)
+ continue;
+ if (*INODE_TO_DATAPTR(irec) != '/')
+ continue;
+
+ printf("Found TIFFS root inode at #%x\n", ino);
+ tiffs_root_ino = ino;
+ return 0;
+ }
+
+ puts("TIFFS error: no root inode found\n");
+ return -1;
+}
+
+int tiffs_init(uint32_t base_addr, uint32_t sector_size, unsigned nsectors)
+{
+ int rc;
+
+ printf("Looking for TIFFS (TI Flash File System) header at "
+ "0x%" PRIx32 ", %u sectors of 0x%" PRIx32 " bytes\n",
+ base_addr, nsectors, sector_size);
+
+ tiffs_base_addr = base_addr;
+ tiffs_sector_size = sector_size;
+ tiffs_nsectors = nsectors;
+
+ rc = find_indexblk();
+ if (rc < 0)
+ return rc;
+ rc = find_rootino();
+ if (rc < 0)
+ return rc;
+
+ tiffs_init_done = 1;
+ return 0;
+}
diff --git a/src/target/firmware/tiffs/readfile.c b/src/target/firmware/tiffs/readfile.c
new file mode 100644
index 00000000..f3e916fa
--- /dev/null
+++ b/src/target/firmware/tiffs/readfile.c
@@ -0,0 +1,264 @@
+/* TIFFS (TI Flash File System) reader implementation */
+
+/*
+ * (C) 2017 by Mychaela Falconia <mychaela.falconia@gmail.com>
+ * Tweaked (coding style changes) by Vadim Yanitskiy <axilirator@gmail.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <tiffs.h>
+#include "globals.h"
+
+extern char *index();
+
+#define MAX_FN_COMPONENT 20
+
+static unsigned find_named_child(unsigned start, const char *seekname)
+{
+ struct tiffs_inode *irec;
+ unsigned ino;
+
+ for (ino = start; ino != 0xFFFF; ino = irec->sibling) {
+ irec = tiffs_active_index + ino;
+ if (!irec->type)
+ continue;
+ if (!strcmp((const char *) INODE_TO_DATAPTR(irec), seekname))
+ return ino;
+ }
+
+ return 0;
+}
+
+static int pathname_to_inode(const char *pathname)
+{
+ char seekname[MAX_FN_COMPONENT + 1];
+ struct tiffs_inode *irec;
+ const char *cur, *next;
+ unsigned ino, namelen;
+
+ cur = pathname;
+ if (*cur == '/')
+ cur++;
+
+ for (ino = tiffs_root_ino; cur; cur = next) {
+ if (!*cur)
+ break;
+
+ next = index(cur, '/');
+ if (next == cur) {
+ puts("Malformed TIFFS pathname: multiple adjacent slashes\n");
+ return -1;
+ } else if (next) {
+ namelen = next - cur;
+ next++;
+ } else {
+ namelen = strlen(cur);
+ }
+
+ if (namelen > MAX_FN_COMPONENT) {
+ puts("Malformed TIFFS pathname: component name too long\n");
+ return -1;
+ }
+
+ memcpy(seekname, cur, namelen);
+ seekname[namelen] = '\0';
+
+ irec = tiffs_active_index + ino;
+ if (irec->type != TIFFS_OBJTYPE_DIR) {
+ /* printf("Error: non-terminal non-directory\n"); */
+ return 0;
+ }
+ ino = find_named_child(irec->descend, seekname);
+ if (!ino) {
+ /* printf("Error: pathname component not found\n"); */
+ return 0;
+ }
+ }
+
+ return ino;
+}
+
+static uint8_t *find_endofchunk(int ino)
+{
+ struct tiffs_inode *irec;
+ uint8_t *ptr;
+ int i;
+
+ irec = tiffs_active_index + ino;
+ ptr = INODE_TO_DATAPTR(irec) + irec->len;
+
+ for (i = 0; i < 16; i++) {
+ ptr--;
+ if (!*ptr)
+ return ptr;
+ if (*ptr != 0xFF)
+ break;
+ }
+
+ printf("TIFFS error: inode #%x has no valid termination\n", ino);
+ return ptr; /* XXX */
+}
+
+static int get_file_head(const char *pathname, uint8_t **startret,
+ size_t *sizeret, int *continue_ret)
+{
+ struct tiffs_inode *irec;
+ uint8_t *start, *end;
+ int ino, cont, size;
+
+ ino = pathname_to_inode(pathname);
+ if (ino <= 0)
+ return ino;
+
+ irec = tiffs_active_index + ino;
+ if (irec->type != TIFFS_OBJTYPE_FILE) {
+ printf("TIFFS error: '%s' is not a regular file\n", pathname);
+ return -1;
+ }
+
+ start = INODE_TO_DATAPTR(irec);
+ start += strlen((const char *) start) + 1;
+ end = find_endofchunk(ino);
+
+ size = end - start;
+ if (size < 0)
+ size = 0;
+
+ cont = irec->descend;
+ if (cont == 0xFFFF)
+ cont = 0;
+ if (startret)
+ *startret = start;
+ if (sizeret)
+ *sizeret = size;
+ if (continue_ret)
+ *continue_ret = cont;
+
+ return 1;
+}
+
+static int get_segment(int ino, uint8_t **startret,
+ size_t *sizeret, int *continue_ret)
+{
+ struct tiffs_inode *irec;
+ uint8_t *start, *end;
+ int cont, size;
+
+ for (;;) {
+ irec = tiffs_active_index + ino;
+ if (irec->type)
+ break;
+ if (irec->sibling == 0xFFFF) {
+ printf("TIFFS error: segment inode #%d: "
+ "deleted and no sibling\n", ino);
+ return -1;
+ }
+ ino = irec->sibling;
+ }
+
+ if (irec->type != TIFFS_OBJTYPE_SEGMENT) {
+ printf("TIFFS error: inode #%x is not a segment\n", ino);
+ return -1;
+ }
+
+ start = INODE_TO_DATAPTR(irec);
+ end = find_endofchunk(ino);
+
+ size = end - start;
+ if (size <= 0) {
+ printf("TIFFS error: segment inode #%x has bad length\n", ino);
+ return -1;
+ }
+
+ cont = irec->descend;
+ if (cont == 0xFFFF)
+ cont = 0;
+ if (startret)
+ *startret = start;
+ if (sizeret)
+ *sizeret = size;
+ if (continue_ret)
+ *continue_ret = cont;
+
+ return 0;
+}
+
+int tiffs_read_file_maxlen(const char *pathname, uint8_t *buf,
+ size_t maxlen, size_t *lenrtn)
+{
+ size_t chunk_size, real_len, roomleft;
+ uint8_t *chunk_start;
+ int stat, cont;
+
+ if (!tiffs_init_done) {
+ puts("TIFFS reader is not initialized\n");
+ return -1;
+ }
+
+ stat = get_file_head(pathname, &chunk_start, &chunk_size, &cont);
+ if (stat <= 0)
+ return stat;
+ if (chunk_size > maxlen) {
+toobig: printf("TIFFS error: '%s' is bigger than the read buffer\n", pathname);
+ return -1;
+ }
+
+ real_len = chunk_size;
+ memcpy(buf, chunk_start, chunk_size);
+ buf += chunk_size;
+ roomleft = maxlen - chunk_size;
+ while (cont) {
+ stat = get_segment(cont, &chunk_start, &chunk_size, &cont);
+ if (stat < 0)
+ return stat;
+ if (chunk_size > roomleft)
+ goto toobig;
+
+ real_len += chunk_size;
+ memcpy(buf, chunk_start, chunk_size);
+ buf += chunk_size;
+ roomleft -= chunk_size;
+ }
+
+ if (lenrtn)
+ *lenrtn = real_len;
+
+ return 1;
+}
+
+int tiffs_read_file_fixedlen(const char *pathname, uint8_t *buf,
+ size_t expect_len)
+{
+ size_t real_len;
+ int rc;
+
+ rc = tiffs_read_file_maxlen(pathname, buf, expect_len, &real_len);
+ if (rc <= 0)
+ return rc;
+ if (real_len != expect_len) {
+ printf("TIFFS error: '%s' has the wrong length\n", pathname);
+ return -1;
+ }
+
+ return 1;
+}