aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libraries/libcli/Makefile3
-rw-r--r--libraries/libprof/Makefile6
-rw-r--r--libraries/libprof/gmon.c427
-rw-r--r--libraries/libprof/gmon.h57
-rw-r--r--libraries/libprof/memfunc.c (renamed from memfunc.c)52
-rw-r--r--libraries/libprof/profil.c96
-rw-r--r--libraries/libprof/profil.h60
-rw-r--r--libraries/libtfm/Makefile2
-rw-r--r--libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/TARGET_CRYPTECH_ALPHA/stm32f4xx_it.c7
-rw-r--r--projects/cli-test/cli-test.c6
-rw-r--r--projects/hsm/Makefile1
-rw-r--r--projects/hsm/hsm.c97
-rw-r--r--projects/hsm/mgmt-keystore.c51
-rw-r--r--projects/hsm/mgmt-masterkey.c90
-rw-r--r--projects/libhal-test/main.c1
-rw-r--r--spiflash_n25q128.c2
-rw-r--r--task.c22
-rw-r--r--task.h1
18 files changed, 454 insertions, 527 deletions
diff --git a/libraries/libcli/Makefile b/libraries/libcli/Makefile
index cd1d3b6..6bc805a 100644
--- a/libraries/libcli/Makefile
+++ b/libraries/libcli/Makefile
@@ -11,7 +11,8 @@ CFLAGS += \
-DDO_REGULAR=0 \
-DDO_SOCKET=0 \
-DDO_TAB_COMPLETION=1 \
- -DDO_TELNET=0
+ -DDO_TELNET=0 \
+ -DCLI_MAX_LINE_WORDS=36
CFLAGS += -Wno-unused-parameter
all: libcli.a
diff --git a/libraries/libprof/Makefile b/libraries/libprof/Makefile
index 4fe5fb4..28bedea 100644
--- a/libraries/libprof/Makefile
+++ b/libraries/libprof/Makefile
@@ -1,12 +1,16 @@
LIB = libprof.a
-OBJS = gmon.o profil.o profiler.o
+OBJS = gmon.o profiler.o memfunc.o
# Don't profile the profiling code, because that way lies madness (and recursion).
CFLAGS := $(subst -pg,,$(CFLAGS))
all: $(LIB)
+# But do profile the mem functions
+memfunc.o: memfunc.c
+ $(CC) $(CFLAGS) -pg -c -o $@ $<
+
%.o : %.c
$(CC) $(CFLAGS) -c -o $@ $<
diff --git a/libraries/libprof/gmon.c b/libraries/libprof/gmon.c
index 317a173..a34f1a2 100644
--- a/libraries/libprof/gmon.c
+++ b/libraries/libprof/gmon.c
@@ -36,289 +36,226 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
-#include <stdint.h>
-#include "gmon.h"
-#include "profil.h"
#include <string.h>
+#include "gmon.h"
#define bzero(ptr,size) memset (ptr, 0, size);
#define ERR(s) write(2, s, sizeof(s))
-struct gmonparam _gmonparam = { GMON_PROF_OFF, NULL, 0, NULL, 0, NULL, 0, 0L, 0, 0, 0};
-static char already_setup = 0; /* flag to indicate if we need to init */
-static int s_scale;
-/* see profil(2) where this is described (incorrectly) */
-#define SCALE_1_TO_1 0x10000L
+/* profiling frequency. (No larger than 1000) */
+/* Note this doesn't set the frequency, but merely describes it. */
+#define PROF_HZ 1000
-static void moncontrol(int mode);
+struct gmonparam _gmonparam = { off, NULL, 0, NULL, 0, NULL, 0, 0, 0, 0, 0};
-void monstartup (size_t lowpc, size_t highpc) {
- register size_t o;
- char *cp;
- struct gmonparam *p = &_gmonparam;
+void monstartup(size_t lowpc, size_t highpc)
+{
+ static char already_setup = 0;
+ struct gmonparam *p = &_gmonparam;
- if (already_setup) {
- /* zero out cp as value will be added there */
- bzero(p->tos, p->kcountsize + p->fromssize + p->tossize);
- moncontrol(1); /* start */
- return;
- }
- already_setup = 1;
+ if (already_setup) {
+ /* reinitialize counters and arcs */
+ bzero(p->kcount, p->kcountsize);
+ bzero(p->froms, p->fromssize);
+ bzero(p->tos, p->tossize);
+ p->state = on;
+ return;
+ }
+ already_setup = 1;
- /* enable semihosting, for eventual output */
- extern void initialise_monitor_handles(void);
- initialise_monitor_handles();
+ /* enable semihosting, for eventual output */
+ extern void initialise_monitor_handles(void);
+ initialise_monitor_handles();
- /*
- * round lowpc and highpc to multiples of the density we're using
- * so the rest of the scaling (here and in gprof) stays in ints.
- */
- p->lowpc = ROUNDDOWN(lowpc, HISTFRACTION * sizeof(HISTCOUNTER));
- p->highpc = ROUNDUP(highpc, HISTFRACTION * sizeof(HISTCOUNTER));
- p->textsize = p->highpc - p->lowpc + 0x20;
- p->kcountsize = p->textsize / HISTFRACTION;
- p->fromssize = p->textsize / HASHFRACTION;
- p->tolimit = p->textsize * ARCDENSITY / 100;
- if (p->tolimit < MINARCS) {
- p->tolimit = MINARCS;
- } else if (p->tolimit > MAXARCS) {
- p->tolimit = MAXARCS;
- }
- p->tossize = p->tolimit * sizeof(struct tostruct);
+ /*
+ * round lowpc and highpc to multiples of the density we're using
+ * so the rest of the scaling (here and in gprof) stays in ints.
+ */
+ p->lowpc = ROUNDDOWN(lowpc, HISTFRACTION * sizeof(HISTCOUNTER));
+ p->highpc = ROUNDUP(highpc, HISTFRACTION * sizeof(HISTCOUNTER));
+ p->textsize = p->highpc - p->lowpc;
+ p->kcountsize = p->textsize / HISTFRACTION;
+ p->fromssize = p->textsize / HASHFRACTION;
+ p->tolimit = p->textsize * ARCDENSITY / 100;
+ if (p->tolimit < MINARCS) {
+ p->tolimit = MINARCS;
+ } else if (p->tolimit > MAXARCS) {
+ p->tolimit = MAXARCS;
+ }
+ p->tossize = p->tolimit * sizeof(struct tostruct);
- extern void *hal_allocate_static_memory(const size_t size);
- cp = hal_allocate_static_memory(p->kcountsize + p->fromssize + p->tossize);
- if (cp == NULL) {
- ERR("monstartup: out of memory\n");
- return;
- }
+ extern void *hal_allocate_static_memory(const size_t size);
+ void *cp = hal_allocate_static_memory(p->kcountsize + p->fromssize + p->tossize);
+ if (cp == NULL) {
+ ERR("monstartup: out of memory\n");
+ return;
+ }
- /* zero out cp as value will be added there */
- bzero(cp, p->kcountsize + p->fromssize + p->tossize);
+ bzero(cp, p->kcountsize + p->fromssize + p->tossize);
+ p->kcount = (unsigned short *)cp; cp += p->kcountsize;
+ p->froms = (unsigned short *)cp; cp += p->fromssize;
+ p->tos = (struct tostruct *)cp;
- p->tos = (struct tostruct *)cp;
- cp += p->tossize;
- p->kcount = (unsigned short *)cp;
- cp += p->kcountsize;
- p->froms = (unsigned short *)cp;
+ p->state = on;
+}
- p->tos[0].link = 0;
+void _mcleanup(void)
+{
+ static const char gmon_out[] = "gmon.out";
+ int fd;
+ struct gmonparam *p = &_gmonparam;
- o = p->highpc - p->lowpc;
- if (p->kcountsize < o) {
-#ifndef notdef
- s_scale = ((float)p->kcountsize / o ) * SCALE_1_TO_1;
-#else /* avoid floating point */
- int quot = o / p->kcountsize;
+ if (p->state == err) {
+ ERR("_mcleanup: tos overflow\n");
+ }
- if (quot >= 0x10000)
- s_scale = 1;
- else if (quot >= 0x100)
- s_scale = 0x10000 / quot;
- else if (o >= 0x800000)
- s_scale = 0x1000000 / (o / (p->kcountsize >> 8));
- else
- s_scale = 0x1000000 / ((o << 8) / p->kcountsize);
-#endif
- } else {
- s_scale = SCALE_1_TO_1;
- }
- moncontrol(1); /* start */
-}
+ fd = open(gmon_out , O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0666);
+ if (fd < 0) {
+ perror( gmon_out );
+ return;
+ }
-void _mcleanup(void) {
- static const char gmon_out[] = "gmon.out";
- int fd;
- int fromindex;
- int endfrom;
- size_t frompc;
- int toindex;
- struct rawarc rawarc;
- struct gmonparam *p = &_gmonparam;
- struct gmonhdr gmonhdr = {0}, *hdr;
- const char *proffile;
-#ifdef DEBUG
- int log, len;
- char dbuf[200];
-#endif
+ struct gmonhdr hdr = {
+ .lpc = p->lowpc,
+ .hpc = p->highpc,
+ .ncnt = p->kcountsize + sizeof(struct gmonhdr),
+ .version = GMONVERSION,
+ .profrate = PROF_HZ
+ };
+ write(fd, &hdr, sizeof(hdr));
- if (p->state == GMON_PROF_ERROR) {
- ERR("_mcleanup: tos overflow\n");
- }
- moncontrol(0); /* stop */
- proffile = gmon_out;
- fd = open(proffile , O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0666);
- if (fd < 0) {
- perror( proffile );
- return;
- }
-#ifdef DEBUG
- log = open("gmon.log", O_CREAT|O_TRUNC|O_WRONLY, 0664);
- if (log < 0) {
- perror("mcount: gmon.log");
- return;
- }
- len = sprintf(dbuf, "[mcleanup1] kcount 0x%x ssiz %d\n",
- (unsigned int)p->kcount, p->kcountsize);
- write(log, dbuf, len);
-#endif
- hdr = (struct gmonhdr *)&gmonhdr;
- hdr->lpc = p->lowpc;
- hdr->hpc = p->highpc;
- hdr->ncnt = p->kcountsize + sizeof(gmonhdr);
- hdr->version = GMONVERSION;
- hdr->profrate = PROF_HZ;
- hdr->spare[0] = hdr->spare[1] = hdr->spare[2] = 0;
- write(fd, (char *)hdr, sizeof *hdr);
- write(fd, p->kcount, p->kcountsize);
- endfrom = p->fromssize / sizeof(*p->froms);
- for (fromindex = 0; fromindex < endfrom; fromindex++) {
- if (p->froms[fromindex] == 0) {
- continue;
- }
- frompc = p->lowpc;
- frompc += fromindex * HASHFRACTION * sizeof(*p->froms);
- for (toindex = p->froms[fromindex]; toindex != 0; toindex = p->tos[toindex].link) {
-#ifdef DEBUG
- len = sprintf(dbuf,
- "[mcleanup2] frompc 0x%x selfpc 0x%x count %ld\n" ,
- frompc, p->tos[toindex].selfpc,
- p->tos[toindex].count);
- write(log, dbuf, len);
-#endif
- rawarc.raw_frompc = frompc;
- rawarc.raw_selfpc = p->tos[toindex].selfpc;
- rawarc.raw_count = p->tos[toindex].count;
- write(fd, &rawarc, sizeof rawarc);
- }
- }
- close(fd);
-}
+ write(fd, p->kcount, p->kcountsize);
-/*
- * Control profiling
- * profiling is what mcount checks to see if
- * all the data structures are ready.
- */
-static void moncontrol(int mode) {
- struct gmonparam *p = &_gmonparam;
+ for (size_t fromindex = 0; fromindex < p->fromssize / sizeof(*p->froms); fromindex++) {
+ size_t frompc = p->lowpc + fromindex * HASHFRACTION * sizeof(*p->froms);
+ for (size_t toindex = p->froms[fromindex]; toindex != 0; toindex = p->tos[toindex].next) {
+ struct rawarc arc = {
+ .frompc = frompc,
+ .selfpc = p->tos[toindex].selfpc,
+ .count = p->tos[toindex].count
+ };
+ write(fd, &arc, sizeof(arc));
+ }
+ }
- if (mode) {
- /* start */
- profil((char *)p->kcount, p->kcountsize, p->lowpc, s_scale);
- p->state = GMON_PROF_ON;
- } else {
- /* stop */
- profil((char *)0, 0, 0, 0);
- p->state = GMON_PROF_OFF;
- }
+ close(fd);
}
-void _mcount_internal(uint32_t *frompcindex, uint32_t *selfpc) {
- register struct tostruct *top;
- register struct tostruct *prevtop;
- register long toindex;
+void _mcount_internal(size_t frompc, size_t selfpc)
+{
+ register unsigned short *fromptr;
+ register struct tostruct *top;
+ register unsigned short toindex;
struct gmonparam *p = &_gmonparam;
/*
- * check that we are profiling
- * and that we aren't recursively invoked.
- */
- if (p->state!=GMON_PROF_ON) {
- goto out;
- }
- p->state++;
- /*
- * check that frompcindex is a reasonable pc value.
- * for example: signal catchers get called from the stack,
- * not from text space. too bad.
+ * check that we are profiling and that we aren't recursively invoked.
+ * check that frompc is a reasonable pc value.
*/
- frompcindex = (uint32_t*)((long)frompcindex - (long)p->lowpc);
- if ((unsigned long)frompcindex > p->textsize) {
- goto done;
+ if (p->state != on || (frompc -= p->lowpc) > p->textsize) {
+ return;
}
- frompcindex = (uint32_t*)&p->froms[((long)frompcindex) / (HASHFRACTION * sizeof(*p->froms))];
- toindex = *((unsigned short*)frompcindex); /* get froms[] value */
- if (toindex == 0) {
- /*
- * first time traversing this arc
- */
- toindex = ++p->tos[0].link; /* the link of tos[0] points to the last used record in the array */
+
+ fromptr = &p->froms[frompc / (HASHFRACTION * sizeof(*p->froms))];
+ toindex = *fromptr; /* get froms[] value */
+
+ if (toindex == 0) { /* we haven't seen this caller before */
+ toindex = ++p->tos[0].next; /* index of the last used record in the array */
if (toindex >= p->tolimit) { /* more tos[] entries than we can handle! */
- goto overflow;
- }
- *((unsigned short*)frompcindex) = (unsigned short)toindex; /* store new 'to' value into froms[] */
+ overflow:
+ p->state = err; /* halt further profiling */
+#define TOLIMIT "mcount: tos overflow\n"
+ write (2, TOLIMIT, sizeof(TOLIMIT));
+ return;
+ }
+ *fromptr = toindex; /* store new 'to' value into froms[] */
top = &p->tos[toindex];
- top->selfpc = (size_t)selfpc;
+ top->selfpc = selfpc;
top->count = 1;
- top->link = 0;
- goto done;
- }
- top = &p->tos[toindex];
- if (top->selfpc == (size_t)selfpc) {
- /*
- * arc at front of chain; usual case.
- */
- top->count++;
- goto done;
+ top->next = 0;
}
- /*
- * have to go looking down chain for it.
- * top points to what we are looking at,
- * prevtop points to previous top.
- * we know it is not at the head of the chain.
- */
- for (; /* goto done */; ) {
- if (top->link == 0) {
+
+ else { /* we've seen this caller before */
+ top = &p->tos[toindex];
+ if (top->selfpc == selfpc) {
/*
- * top is end of the chain and none of the chain
- * had top->selfpc == selfpc.
- * so we allocate a new tostruct
- * and link it to the head of the chain.
+ * arc at front of chain; usual case.
*/
- toindex = ++p->tos[0].link;
- if (toindex >= p->tolimit) {
- goto overflow;
- }
- top = &p->tos[toindex];
- top->selfpc = (size_t)selfpc;
- top->count = 1;
- top->link = *((unsigned short*)frompcindex);
- *(unsigned short*)frompcindex = (unsigned short)toindex;
- goto done;
+ top->count++;
}
- /*
- * otherwise, check the next arc on the chain.
- */
- prevtop = top;
- top = &p->tos[top->link];
- if (top->selfpc == (size_t)selfpc) {
+
+ else {
/*
- * there it is.
- * increment its count
- * move it to the head of the chain.
+ * have to go looking down chain for it.
+ * top points to what we are looking at,
+ * prevtop points to previous top.
+ * we know it is not at the head of the chain.
*/
- top->count++;
- toindex = prevtop->link;
- prevtop->link = top->link;
- top->link = *((unsigned short*)frompcindex);
- *((unsigned short*)frompcindex) = (unsigned short)toindex;
- goto done;
+ while (1) {
+ if (top->next == 0) {
+ /*
+ * top is end of the chain and none of the chain
+ * had top->selfpc == selfpc.
+ * so we allocate a new tostruct
+ * and put it at the head of the chain.
+ */
+ toindex = ++p->tos[0].next;
+ if (toindex >= p->tolimit) {
+ goto overflow;
+ }
+ top = &p->tos[toindex];
+ top->selfpc = selfpc;
+ top->count = 1;
+ top->next = *fromptr;
+ *fromptr = toindex;
+ break;
+ }
+
+ else {
+ /*
+ * otherwise, check the next arc on the chain.
+ */
+ register struct tostruct *prevtop = top;
+ top = &p->tos[top->next];
+ if (top->selfpc == selfpc) {
+ /*
+ * there it is.
+ * increment its count
+ * move it to the head of the chain.
+ */
+ top->count++;
+ toindex = prevtop->next;
+ prevtop->next = top->next;
+ top->next = *fromptr;
+ *fromptr = toindex;
+ break;
+ }
+ }
+ }
}
}
- done:
- p->state--;
- /* and fall through */
- out:
- return; /* normal return restores saved registers */
- overflow:
- p->state++; /* halt further profiling */
- #define TOLIMIT "mcount: tos overflow\n"
- write (2, TOLIMIT, sizeof(TOLIMIT));
- goto out;
+
+ return; /* normal return restores saved registers */
}
-void _monInit(void) {
- _gmonparam.state = GMON_PROF_OFF;
- already_setup = 0;
+#include <stdint.h>
+#include "stm32f4xx_hal.h" /* __get_MSP */
+
+/* called from the SysTick handler */
+void profil_callback(void)
+{
+ struct gmonparam *p = &_gmonparam;
+
+ if (p->state == on) {
+ /* The interrupt mechanism pushes xPSR, PC, LR, R12, and R3-R0 onto the
+ * stack, so PC is the 6th word from the top at that point. However, the
+ * normal function entry code pushes registers as well, so the stack
+ * offset right now depends on the call tree that got us here.
+ */
+ size_t pc = (size_t)((uint32_t *)__get_MSP())[6 + 6];
+ if ((pc -= p->lowpc) < p->textsize) {
+ size_t idx = pc / (HISTFRACTION * sizeof(*p->kcount));
+ p->kcount[idx]++;
+ }
+ }
}
diff --git a/libraries/libprof/gmon.h b/libraries/libprof/gmon.h
index 8b5ecf0..9016502 100644
--- a/libraries/libprof/gmon.h
+++ b/libraries/libprof/gmon.h
@@ -40,28 +40,6 @@
#ifndef _SYS_GMON_H_
#define _SYS_GMON_H_
-#ifndef __P
-#define __P(x) x
-#endif
-
-/* On POSIX systems, profile.h is a KRB5 header. To avoid collisions, just
- pull in profile.h's content here. The profile.h header won't be provided
- by Mingw-w64 anymore at one point. */
-#if 0
-#include <profile.h>
-#else
-#ifndef _WIN64
-#define _MCOUNT_CALL __attribute__ ((regparm (2)))
-extern void _mcount(void);
-#else
-#define _MCOUNT_CALL
-extern void mcount(void);
-#endif
-#define _MCOUNT_DECL __attribute__((gnu_inline)) __inline__ \
- void _MCOUNT_CALL _mcount_private
-#define MCOUNT
-#endif
-
/*
* Structure prepended to gmon.out profiling data file.
*/
@@ -83,7 +61,8 @@ struct gmonhdr {
/*
* fraction of text space to allocate for histogram counters here, 1/2
*/
-#define HISTFRACTION 2
+//#define HISTFRACTION 2
+#define HISTFRACTION 1
/*
* Fraction of text space to allocate for from hash buckets.
@@ -113,7 +92,8 @@ struct gmonhdr {
* profiling data structures without (in practice) sacrificing
* any granularity.
*/
-#define HASHFRACTION 2
+//#define HASHFRACTION 2
+#define HASHFRACTION 1
/*
* percent of text space to allocate for tostructs with a minimum.
@@ -123,10 +103,10 @@ struct gmonhdr {
#define MAXARCS ((1 << (8 * sizeof(HISTCOUNTER))) - 2)
struct tostruct {
- size_t selfpc; /* callee address/program counter. The caller address is in froms[] array which points to tos[] array */
- long count; /* how many times it has been called */
- unsigned short link; /* link to next entry in hash table. For tos[0] this points to the last used entry */
- unsigned short pad; /* additional padding bytes, to have entries 4byte aligned */
+ size_t selfpc; /* callee address. The caller address is in froms[] array which points to tos[] array */
+ unsigned long count; /* how many times it has been called */
+ unsigned short next; /* next entry in hash table. For tos[0] this is the index of the last used entry */
+ unsigned short pad; /* additional padding bytes, to have entries 4byte aligned */
};
/*
@@ -134,9 +114,9 @@ struct tostruct {
* the called site and a count.
*/
struct rawarc {
- size_t raw_frompc;
- size_t raw_selfpc;
- long raw_count;
+ size_t frompc;
+ size_t selfpc;
+ long count;
};
/*
@@ -149,29 +129,20 @@ struct rawarc {
* The profiling data structures are housed in this structure.
*/
struct gmonparam {
- int state;
+ enum { off, on, err } state;
unsigned short *kcount; /* histogram PC sample array */
size_t kcountsize; /* size of kcount[] array in bytes */
unsigned short *froms; /* array of hashed 'from' addresses. The 16bit value is an index into the tos[] array */
size_t fromssize; /* size of froms[] array in bytes */
- struct tostruct *tos; /* to struct, contains histogram counter */
+ struct tostruct *tos; /* to struct, contains arc counters */
size_t tossize; /* size of tos[] array in bytes */
- long tolimit;
+ size_t tolimit;
size_t lowpc; /* low program counter of area */
size_t highpc; /* high program counter */
size_t textsize; /* code size */
};
extern struct gmonparam _gmonparam;
-/*
- * Possible states of profiling.
- */
-#define GMON_PROF_ON 0
-#define GMON_PROF_BUSY 1
-#define GMON_PROF_ERROR 2
-#define GMON_PROF_OFF 3
-
void _mcleanup(void); /* routine to be called to write gmon.out file */
-void _monInit(void); /* initialization routine */
#endif /* !_SYS_GMONH_ */
diff --git a/memfunc.c b/libraries/libprof/memfunc.c
index fd94b28..fc908e1 100644
--- a/memfunc.c
+++ b/libraries/libprof/memfunc.c
@@ -4,9 +4,15 @@
/*
* Profilable substitutes for mem*(), lacking libc_p.a
*
- * This code was written with reference to newlib, but does not copy every
- * quirk and loop-unrolling optimization from newlib. Its only purpose is
- * to let us figure out who is calling memcpy 2 million times.
+ * This code was written with reference to newlib, and was recently
+ * brought closer into line with newlib, to make profiling more accurate.
+ *
+ * Newlib is maintained by Cygwin, which is Red Hat. There is no copyright
+ * statement in the corresponding newlib source files, nor is there a
+ * COPYING file in newlib/libc/string or newlib/libc. Consider this file
+ * to be covered under one or more of the 50 copyright notices in
+ * newlib/COPYING, most of which are BSD. In any case, this file is only
+ * used for profiling, and is not used in production builds.
*/
#define is_word_aligned(x) (((size_t)(x) & 3) == 0)
@@ -16,12 +22,19 @@ void *memcpy(void *dst, const void *src, size_t n)
uint8_t *d8 = (uint8_t *)dst;
uint8_t *s8 = (uint8_t *)src;
- if (n >= 4 && is_word_aligned(src) && is_word_aligned(dst)) {
+ if (n >= sizeof(uint32_t) && is_word_aligned(src) && is_word_aligned(dst)) {
uint32_t *d32 = (uint32_t *)dst;
uint32_t *s32 = (uint32_t *)src;
- while (n >= 4) {
+ while (n >= 4 * sizeof(uint32_t)) {
+ *d32++ = *s32++;
+ *d32++ = *s32++;
+ *d32++ = *s32++;
*d32++ = *s32++;
- n -= 4;
+ n -= 4 * sizeof(uint32_t);
+ }
+ while (n >= sizeof(uint32_t)) {
+ *d32++ = *s32++;
+ n -= sizeof(uint32_t);
}
d8 = (uint8_t *)d32;
s8 = (uint8_t *)s32;
@@ -38,12 +51,25 @@ void *memset(void *dst, int c, size_t n)
uint8_t *d8 = (uint8_t *)dst;
uint8_t c8 = (uint8_t)c;
- if (n >= 4 && is_word_aligned(dst)) {
- uint32_t *d32 = (uint32_t *)dst;
+ while (!is_word_aligned(d8)) {
+ if (n--)
+ *d8++ = c8;
+ else
+ return dst;
+ }
+ if (n >= sizeof(uint32_t)) {
+ uint32_t *d32 = (uint32_t *)d8;
uint32_t c32 = (c8 << 24) | (c8 << 16) | (c8 << 8) | (c8);
- while (n >= 4) {
+ while (n >= 4 * sizeof(uint32_t)) {
+ *d32++ = c32;
+ *d32++ = c32;
+ *d32++ = c32;
+ *d32++ = c32;
+ n -= 4 * sizeof(uint32_t);
+ }
+ while (n >= sizeof(uint32_t)) {
*d32++ = c32;
- n -= 4;
+ n -= sizeof(uint32_t);
}
d8 = (uint8_t *)d32;
}
@@ -59,15 +85,15 @@ int memcmp(const void *dst, const void *src, size_t n)
uint8_t *d8 = (uint8_t *)dst;
uint8_t *s8 = (uint8_t *)src;
- if (n >= 4 && is_word_aligned(src) && is_word_aligned(dst)) {
+ if (n >= sizeof(uint32_t) && is_word_aligned(src) && is_word_aligned(dst)) {
uint32_t *d32 = (uint32_t *)dst;
uint32_t *s32 = (uint32_t *)src;
- while (n >= 4) {
+ while (n >= sizeof(uint32_t)) {
if (*d32 != *s32)
break;
d32++;
s32++;
- n -= 4;
+ n -= sizeof(uint32_t);
}
d8 = (uint8_t *)d32;
s8 = (uint8_t *)s32;
diff --git a/libraries/libprof/profil.c b/libraries/libprof/profil.c
deleted file mode 100644
index b0d8d55..0000000
--- a/libraries/libprof/profil.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/* profil.c -- win32 profil.c equivalent
-
- Copyright 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-
- This file is part of Cygwin.
-
- This software is a copyrighted work licensed under the terms of the
- Cygwin license. Please consult the file "CYGWIN_LICENSE" for
- details. */
-
-/*
- * This file is taken from Cygwin distribution, adapted to be used for bare embedded targets.
- */
-#include <stdio.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <math.h>
-#include "profil.h"
-#include <string.h>
-
-#include "stm32f4xx_hal.h" /* __get_MSP */
-
-/* global profinfo for profil() call */
-static struct profinfo prof = {
- PROFILE_NOT_INIT, 0, 0, 0, 0
-};
-
-/* sample the current program counter */
-void profil_callback(void) {
- if (prof.state == PROFILE_ON) {
- /* The interrupt mechanism pushes xPSR, PC, LR, R12, and R3-R0 onto the
- * stack, so PC is the 6th word from the top at that point. However, the
- * normal function entry code pushes registers as well, so the stack
- * offset right now depends on the call tree that got us here.
- */
- size_t pc = (size_t)((uint32_t *)__get_MSP())[6 + 6];
- if (pc >= prof.lowpc && pc < prof.highpc) {
- size_t idx = PROFIDX (pc, prof.lowpc, prof.scale);
- prof.counter[idx]++;
- }
- }
-}
-
-/* Stop profiling to the profiling buffer pointed to by p. */
-static int profile_off (struct profinfo *p) {
- p->state = PROFILE_OFF;
- return 0;
-}
-
-/* Create a timer thread and pass it a pointer P to the profiling buffer. */
-static int profile_on (struct profinfo *p) {
- p->state = PROFILE_ON;
- return 0; /* ok */
-}
-
-/*
- * start or stop profiling
- *
- * profiling goes into the SAMPLES buffer of size SIZE (which is treated
- * as an array of unsigned shorts of size size/2)
- *
- * each bin represents a range of pc addresses from OFFSET. The number
- * of pc addresses in a bin depends on SCALE. (A scale of 65536 maps
- * each bin to two addresses, A scale of 32768 maps each bin to 4 addresses,
- * a scale of 1 maps each bin to 128k address). Scale may be 1 - 65536,
- * or zero to turn off profiling
- */
-int profile_ctl (struct profinfo *p, char *samples, size_t size, size_t offset, unsigned int scale) {
- size_t maxbin;
-
- if (scale > 65536) {
- errno = EINVAL;
- return -1;
- }
- profile_off(p);
- if (scale) {
- memset(samples, 0, size);
- memset(p, 0, sizeof *p);
- maxbin = size >> 1;
- prof.counter = (unsigned short*)samples;
- prof.lowpc = offset;
- prof.highpc = PROFADDR(maxbin, offset, scale);
- prof.scale = scale;
- return profile_on(p);
- }
- return 0;
-}
-
-/* Equivalent to unix profil()
- Every SLEEPTIME interval, the user's program counter (PC) is examined:
- offset is subtracted and the result is multiplied by scale.
- The word pointed to by this address is incremented. */
-int profil (char *samples, size_t size, size_t offset, unsigned int scale) {
- return profile_ctl (&prof, samples, size, offset, scale);
-}
-
diff --git a/libraries/libprof/profil.h b/libraries/libprof/profil.h
deleted file mode 100644
index c72dc00..0000000
--- a/libraries/libprof/profil.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* profil.h: gprof profiling header file
-
- Copyright 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-
-This file is part of Cygwin.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-/*
- * This file is taken from Cygwin distribution. Please keep it in sync.
- * The differences should be within __MINGW32__ guard.
- */
-
-#ifndef __PROFIL_H__
-#define __PROFIL_H__
-
-/* profiling frequency. (No larger than 1000) */
-#define PROF_HZ 1000
-
-/* convert an addr to an index */
-#define PROFIDX(pc, base, scale) \
- ({ \
- size_t i = (pc - base) / 2; \
- if (sizeof (unsigned long long int) > sizeof (size_t)) \
- i = (unsigned long long int) i * scale / 65536; \
- else \
- i = i / 65536 * scale + i % 65536 * scale / 65536; \
- i; \
- })
-
-/* convert an index into an address */
-#define PROFADDR(idx, base, scale) \
- ((base) \
- + ((((unsigned long long)(idx) << 16) \
- / (unsigned long long)(scale)) << 1))
-
-/* convert a bin size into a scale */
-#define PROFSCALE(range, bins) (((bins) << 16) / ((range) >> 1))
-
-typedef void *_WINHANDLE;
-
-typedef enum {
- PROFILE_NOT_INIT = 0,
- PROFILE_ON,
- PROFILE_OFF
-} PROFILE_State;
-
-struct profinfo {
- PROFILE_State state; /* profiling state */
- unsigned short *counter; /* profiling counters */
- size_t lowpc, highpc; /* range to be profiled */
- unsigned int scale; /* scale value of bins */
-};
-
-int profile_ctl(struct profinfo *, char *, size_t, size_t, unsigned int);
-int profil(char *, size_t, size_t, unsigned int);
-
-#endif /* __PROFIL_H__ */
diff --git a/libraries/libtfm/Makefile b/libraries/libtfm/Makefile
index b50421c..359729b 100644
--- a/libraries/libtfm/Makefile
+++ b/libraries/libtfm/Makefile
@@ -38,7 +38,7 @@ STM32_LIBTFM_CFLAGS_OPTIMIZATION := -O3 -funroll-loops -fomit-frame-pointer
endif
CFLAGS := $(subst ${STM32_CFLAGS_OPTIMIZATION},${STM32_LIBTFM_CFLAGS_OPTIMIZATION},${CFLAGS})
-CFLAGS += -DTFM_ARM -Dasm=__asm__ -Wa,-mimplicit-it=thumb
+CFLAGS += -DTFM_ARM -DENDIAN_LITTLE -Dasm=__asm__ -Wa,-mimplicit-it=thumb
CFLAGS += -I${LIBTFM_SRC}/tomsfastmath/src/headers
CFLAGS += -DFP_MAX_SIZE="(${BITS}*2+(8*DIGIT_BIT))"
CFLAGS += -Wall -W -Wshadow -Wno-uninitialized
diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/TARGET_CRYPTECH_ALPHA/stm32f4xx_it.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/TARGET_CRYPTECH_ALPHA/stm32f4xx_it.c
index 81b27cb..d3bafb2 100644
--- a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/TARGET_CRYPTECH_ALPHA/stm32f4xx_it.c
+++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/TARGET_CRYPTECH_ALPHA/stm32f4xx_it.c
@@ -64,13 +64,6 @@ void HardFault_Handler(void)
while (1) { ; }
}
-static void default_SysTick_hook(void) { };
-static void (*SysTick_hook)(void) = default_SysTick_hook;
-void set_SysTick_hook(void (*hook)(void))
-{
- SysTick_hook = (hook == NULL) ? default_SysTick_hook : hook;
-}
-
/**
* @brief This function handles SysTick Handler.
* @param None
diff --git a/projects/cli-test/cli-test.c b/projects/cli-test/cli-test.c
index 82946fa..c0fe57e 100644
--- a/projects/cli-test/cli-test.c
+++ b/projects/cli-test/cli-test.c
@@ -88,3 +88,9 @@ void *hal_allocate_static_memory(const size_t size)
{
return NULL;
}
+
+int hal_free_static_memory(const void * const ptr)
+{
+ return 0;
+}
+
diff --git a/projects/hsm/Makefile b/projects/hsm/Makefile
index 3430e14..37c552d 100644
--- a/projects/hsm/Makefile
+++ b/projects/hsm/Makefile
@@ -25,7 +25,6 @@ LDFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
LDFLAGS += -Wl,--gc-sections
ifdef DO_PROFILING
-OBJS += $(TOPLEVEL)/memfunc.o
LDFLAGS += --specs=rdimon.specs -lc -lrdimon
endif
diff --git a/projects/hsm/hsm.c b/projects/hsm/hsm.c
index 64529f6..a34b1f7 100644
--- a/projects/hsm/hsm.c
+++ b/projects/hsm/hsm.c
@@ -86,27 +86,19 @@ static uint8_t busy_stack[BUSY_STACK_SIZE];
* 4096-byte block of an FPGA or bootloader image upload.
*/
#ifndef CLI_STACK_SIZE
-#define CLI_STACK_SIZE 8*1024
-#endif
-static uint8_t cli_stack[CLI_STACK_SIZE];
-
-#ifndef MAX_PKT_SIZE
-/* An arbitrary number, more or less driven by the 4096-bit RSA
- * keygen test.
- */
-#define MAX_PKT_SIZE 4096
+#define CLI_STACK_SIZE 16*1024
#endif
/* RPC buffers. For each active request, there will be two - input and output.
*/
typedef struct rpc_buffer_s {
size_t len;
- uint8_t buf[MAX_PKT_SIZE];
+ uint8_t buf[HAL_RPC_MAX_PKT_SIZE];
struct rpc_buffer_s *next; /* for ibuf queue linking */
} rpc_buffer_t;
/* RPC input (requst) buffers */
-static rpc_buffer_t ibufs[NUM_RPC_TASK];
+static rpc_buffer_t *ibufs;
/* ibuf queue structure */
typedef struct {
@@ -348,36 +340,73 @@ static void busy_task(void)
}
}
-/* Allocate memory from SDRAM1. There is only malloc, no free, so we don't
- * worry about fragmentation. */
-static uint8_t *sdram_malloc(size_t size)
+#include "stm-fpgacfg.h"
+#include "hashsig.h"
+
+static void hashsig_restart_task(void)
{
- /* end of variables declared with __attribute__((section(".sdram1"))) */
- extern uint8_t _esdram1 __asm ("_esdram1");
- /* end of SDRAM1 section */
- extern uint8_t __end_sdram1 __asm ("__end_sdram1");
+ /* wait for the fpga to configure itself on cold-boot */
+ while (fpgacfg_check_done() != CMSIS_HAL_OK)
+ task_yield();
+
+ /* reinitialize the hashsig key structures after a device restart */
+ hal_hashsig_ks_init();
+
+ /* done, convert this task to an RPC handler */
+ task_mod((char *)task_get_cookie(NULL), dispatch_task, NULL);
+}
- static uint8_t *sdram_heap = &_esdram1;
+/* end of variables declared with __attribute__((section(".sdram1"))) */
+extern uint8_t _esdram1 __asm ("_esdram1");
+/* end of SDRAM1 section */
+extern uint8_t __end_sdram1 __asm ("__end_sdram1");
+static uint8_t *sdram_heap = &_esdram1;
+
+/* Allocate memory from SDRAM1. */
+static uint8_t *sdram_malloc(size_t size)
+{
uint8_t *p = sdram_heap;
#define pad(n) (((n) + 3) & ~3)
size = pad(size);
- if (p + size > &__end_sdram1)
+ if (p + size + sizeof(uint32_t) > &__end_sdram1)
return NULL;
- sdram_heap += size;
+ *(uint32_t *)p = (uint32_t)size;
+ p += sizeof(uint32_t);
+
+ sdram_heap += size + sizeof(uint32_t);
return p;
}
-/* Implement static memory allocation for libhal over sdram_malloc().
- * Once again, there's only alloc, not free. */
+/* A very limited form of free(), which only frees memory if it's at the
+ * top of the heap.
+ */
+static hal_error_t sdram_free(uint8_t *ptr)
+{
+ uint8_t *p = ptr - sizeof(uint32_t);
+ uint32_t size = *(uint32_t *)p;
+ if (ptr + size == sdram_heap) {
+ sdram_heap = p;
+ return LIBHAL_OK;
+ }
+ else
+ return HAL_ERROR_FORBIDDEN;
+}
+/* Implement static memory allocation for libhal over sdram_malloc().
+ */
void *hal_allocate_static_memory(const size_t size)
{
return sdram_malloc(size);
}
+hal_error_t hal_free_static_memory(const void * const ptr)
+{
+ return sdram_free((uint8_t *)ptr);
+}
+
/* Critical section start/end - temporarily disable interrupts.
*/
void hal_critical_section_start(void)
@@ -431,9 +460,13 @@ int main(void)
Error_Handler();
/* Initialize the ibuf queues. */
+ ibufs = (rpc_buffer_t *)sdram_malloc(NUM_RPC_TASK * sizeof(rpc_buffer_t));
+ if (ibufs == NULL)
+ Error_Handler();
+ memset(ibufs, 0, NUM_RPC_TASK * sizeof(rpc_buffer_t));
memset(&ibuf_waiting, 0, sizeof(ibuf_waiting));
memset(&ibuf_ready, 0, sizeof(ibuf_ready));
- for (size_t i = 0; i < sizeof(ibufs)/sizeof(ibufs[0]); ++i)
+ for (size_t i = 0; i < NUM_RPC_TASK; ++i)
ibuf_put(&ibuf_waiting, &ibufs[i]);
/* Create the rpc dispatch worker tasks. */
@@ -443,8 +476,14 @@ int main(void)
void *stack = (void *)sdram_malloc(TASK_STACK_SIZE);
if (stack == NULL)
Error_Handler();
- if (task_add(label[i], dispatch_task, &ibufs[i], stack, TASK_STACK_SIZE) == NULL)
- Error_Handler();
+ if (i == NUM_RPC_TASK - 1) {
+ if (task_add("hashsig_restart", hashsig_restart_task, label[i], stack, TASK_STACK_SIZE) == NULL)
+ Error_Handler();
+ }
+ else {
+ if (task_add(label[i], dispatch_task, NULL, stack, TASK_STACK_SIZE) == NULL)
+ Error_Handler();
+ }
}
/* Create the busy task. */
@@ -461,9 +500,13 @@ int main(void)
*/
/* Create the CLI task. */
- if (task_add("cli", (funcp_t)cli_main, NULL, cli_stack, sizeof(cli_stack)) == NULL)
+ void *cli_stack = (void *)sdram_malloc(CLI_STACK_SIZE);
+ if (task_add("cli", (funcp_t)cli_main, NULL, cli_stack, CLI_STACK_SIZE) == NULL)
Error_Handler();
/* Start the tasker */
task_yield();
+
+ /*NOTREACHED*/
+ return 0;
}
diff --git a/projects/hsm/mgmt-keystore.c b/projects/hsm/mgmt-keystore.c
index b79a5fe..9eb42da 100644
--- a/projects/hsm/mgmt-keystore.c
+++ b/projects/hsm/mgmt-keystore.c
@@ -50,6 +50,7 @@
#include <stdlib.h>
#include <string.h>
+#include <strings.h>
#include <ctype.h>
@@ -180,6 +181,8 @@ static int cmd_keystore_delete_key(struct cli_def *cli, const char *command, cha
return CLI_OK;
}
+#include "ks.h"
+
static int show_keys(struct cli_def *cli, const char *title)
{
const hal_client_handle_t client = { -1 };
@@ -198,6 +201,16 @@ static int show_keys(struct cli_def *cli, const char *title)
cli_print(cli, title);
+ size_t avail;
+ if ((status = hal_ks_available(hal_ks_token, &avail)) == HAL_OK)
+ cli_print(cli, "Token keystore: %d available", avail);
+ else
+ cli_print(cli, "Error reading token keystore: %s", hal_error_string(status));
+ if ((status = hal_ks_available(hal_ks_volatile, &avail)) == HAL_OK)
+ cli_print(cli, "Volatile keystore: %d available", avail);
+ else
+ cli_print(cli, "Error reading volatile keystore: %s", hal_error_string(status));
+
while (!done) {
if ((status = hal_rpc_pkey_match(client, session, HAL_KEY_TYPE_NONE, HAL_CURVE_NONE,
@@ -248,6 +261,10 @@ static int show_keys(struct cli_def *cli, const char *title)
case HAL_KEY_TYPE_RSA_PUBLIC: type_name = "RSA public"; break;
case HAL_KEY_TYPE_EC_PRIVATE: type_name = "EC private"; break;
case HAL_KEY_TYPE_EC_PUBLIC: type_name = "EC public"; break;
+ case HAL_KEY_TYPE_HASHSIG_PRIVATE: type_name = "hashsig private"; break;
+ case HAL_KEY_TYPE_HASHSIG_PUBLIC: type_name = "hashsig public"; break;
+ case HAL_KEY_TYPE_HASHSIG_LMS: type_name = "hashsig lms"; break;
+ case HAL_KEY_TYPE_HASHSIG_LMOTS: type_name = "hashsig lmots"; break;
}
const char *curve_name = "unknown";
@@ -304,13 +321,34 @@ static int cmd_keystore_erase(struct cli_def *cli, const char *command, char *ar
{
hal_error_t err;
HAL_StatusTypeDef status;
+ int preserve_PINs = 0;
command = command;
- if (argc != 1 || strcmp(argv[0], "YesIAmSure") != 0) {
- cli_print(cli, "Syntax: keystore erase YesIAmSure");
+ if (argc < 1 || argc > 2 || strcmp(argv[0], "YesIAmSure") != 0) {
+ usage:
+ cli_print(cli, "Syntax: keystore erase YesIAmSure [preservePINs]");
return CLI_ERROR;
}
+ if (argc == 2) {
+ if (strcasecmp(argv[1], "preservePINs") != 0)
+ goto usage;
+ else
+ preserve_PINs = 1;
+ }
+
+ hal_user_t users[3] = { HAL_USER_NORMAL, HAL_USER_SO, HAL_USER_WHEEL };
+ hal_ks_pin_t pins[3];
+ if (preserve_PINs) {
+ for (size_t i = 0; i < 3; ++i) {
+ const hal_ks_pin_t *pin;
+ if (hal_get_pin(users[i], &pin) != HAL_OK) {
+ cli_print(cli, "Failed to get the PINs");
+ return CLI_ERROR;
+ }
+ memcpy(&pins[i], pin, sizeof(*pin));
+ }
+ }
cli_print(cli, "OK, erasing keystore, this will take about 45 seconds...");
if ((status = keystore_erase_bulk()) != CMSIS_HAL_OK) {
@@ -328,6 +366,15 @@ static int cmd_keystore_erase(struct cli_def *cli, const char *command, char *ar
return CLI_ERROR;
}
+ if (preserve_PINs) {
+ for (size_t i = 0; i < 3; ++i) {
+ if (hal_set_pin(users[i], &pins[i]) != HAL_OK) {
+ cli_print(cli, "Failed to restore the PINs");
+ return CLI_ERROR;
+ }
+ }
+ }
+
cli_print(cli, "Keystore erased");
return CLI_OK;
}
diff --git a/projects/hsm/mgmt-masterkey.c b/projects/hsm/mgmt-masterkey.c
index 765cb10..e63e0e0 100644
--- a/projects/hsm/mgmt-masterkey.c
+++ b/projects/hsm/mgmt-masterkey.c
@@ -60,24 +60,6 @@ static char * _status2str(const hal_error_t status)
}
}
-static int _parse_hex_groups(uint8_t *buf, size_t len, char *argv[], int argc)
-{
- int i;
- uint32_t *dst = (uint32_t *) buf;
- uint32_t *end = (uint32_t *) buf + len - 1;
- char *err_ptr = NULL;
-
- if (! argc) return 0;
-
- for (i = 0; i < argc; i++) {
- if (dst >= end) return -1;
- *dst++ = strtoul(argv[i], &err_ptr, 16);
- if (*err_ptr) return -2;
- }
-
- return 1;
-}
-
static int cmd_masterkey_status(struct cli_def *cli, const char *command, char *argv[], int argc)
{
hal_error_t status;
@@ -97,12 +79,54 @@ static int cmd_masterkey_status(struct cli_def *cli, const char *command, char *
return CLI_OK;
}
+static int str_to_hex_digit(char c)
+{
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'a' && c <= 'f')
+ c = c - 'a' + 10;
+ else if (c >= 'A' && c <= 'F')
+ c = c - 'A' + 10;
+ else
+ return -1;
+
+ return c;
+}
+
+static inline char hex_to_str_digit(const uint8_t c)
+{
+ return (c < 10) ? ((char)c + '0') : ((char)c + 'A' - 10);
+}
+
+static char *hexdump_kek(const uint8_t * const kek)
+{
+ /* This is only for dumping masterkey values, so has no length checks.
+ * Do not use it for anything else.
+ *
+ * For convenience of possibly hand-copying and hand-retyping, the key
+ * is divided into 8 4-byte (8-character) groups.
+ */
+
+ static char buf[2 * KEK_LENGTH + 8];
+ char *dst = buf;
+
+ for (size_t i = 0; i < KEK_LENGTH; ++i) {
+ uint8_t b = kek[i];
+ *dst++ = hex_to_str_digit(b >> 4);
+ *dst++ = hex_to_str_digit(b & 0xf);
+ if ((i & 3) == 3)
+ *dst++ = ' ';
+ }
+ buf[sizeof(buf) - 1] = '\0';
+
+ return buf;
+}
+
static int _masterkey_set(struct cli_def *cli, char *argv[], int argc,
char *label, hal_error_t (*writer)(const uint8_t * const, const size_t))
{
uint8_t buf[KEK_LENGTH] = {0};
hal_error_t err;
- int i;
if (argc == 0) {
/* fill master key with yummy randomness */
@@ -110,20 +134,32 @@ static int _masterkey_set(struct cli_def *cli, char *argv[], int argc,
cli_print(cli, "Error getting random key: %s", hal_error_string(err));
return CLI_ERROR;
}
- cli_print(cli, "Random key:\n");
- uart_send_hexdump(buf, 0, sizeof(buf) - 1);
- cli_print(cli, "\n");
+ cli_print(cli, "Random key:\n%s", hexdump_kek(buf));
}
else {
- if ((i = _parse_hex_groups(&buf[0], sizeof(buf), argv, argc)) != 1) {
- cli_print(cli, "Failed parsing master key, expected up to 8 groups of 32-bit hex chars (%i)", i);
+ /* input is 32 hex bytes, arranged however the user wants */
+ size_t len = 0;
+ for (int i = 0; i < argc; ++i) {
+ for (char *cp = argv[i]; *cp != '\0'; ) {
+ int c;
+ if ((c = str_to_hex_digit(*cp++)) < 0)
+ goto errout;
+ buf[len] = c << 4;
+ if ((c = str_to_hex_digit(*cp++)) < 0)
+ goto errout;
+ buf[len] |= c & 0xf;
+ if (++len > KEK_LENGTH)
+ goto errout;
+ }
+ }
+ if (len < KEK_LENGTH) {
+ errout:
+ cli_print(cli, "Failed parsing master key, expected exactly %d hex bytes", KEK_LENGTH);
return CLI_ERROR;
}
- cli_print(cli, "Parsed key:\n");
- uart_send_hexdump(buf, 0, sizeof(buf) - 1);
- cli_print(cli, "\n");
+ cli_print(cli, "Parsed key:\n%s", hexdump_kek(buf));
}
if ((err = writer(buf, sizeof(buf))) == LIBHAL_OK) {
diff --git a/projects/libhal-test/main.c b/projects/libhal-test/main.c
index fff8c38..c0d9330 100644
--- a/projects/libhal-test/main.c
+++ b/projects/libhal-test/main.c
@@ -43,6 +43,7 @@ extern void __main(void);
int main(void)
{
stm_init();
+ HAL_Delay(500);
led_on(LED_GREEN);
__main();
diff --git a/spiflash_n25q128.c b/spiflash_n25q128.c
index 5e10185..df53f19 100644
--- a/spiflash_n25q128.c
+++ b/spiflash_n25q128.c
@@ -197,7 +197,7 @@ HAL_StatusTypeDef n25q128_write_page(struct spiflash_ctx *ctx, uint32_t page_off
}
-static int n25q128_erase_something(struct spiflash_ctx *ctx, uint8_t command, uint32_t byte_offset)
+static HAL_StatusTypeDef n25q128_erase_something(struct spiflash_ctx *ctx, uint8_t command, uint32_t byte_offset)
{
// check offset
if (byte_offset >= N25Q128_NUM_BYTES) return HAL_ERROR;
diff --git a/task.c b/task.c
index 36e8580..34daa24 100644
--- a/task.c
+++ b/task.c
@@ -131,6 +131,24 @@ tcb_t *task_add(char *name, funcp_t func, void *cookie, void *stack, size_t stac
return t;
}
+/* Reinitalize the current task.
+ * NOTE: This will destroy any state in the running task.
+ * DO NOT CALL THIS UNLESS YOU ARE REALLY SURE THAT'S WHAT YOU WANT TO DO.
+ */
+void task_mod(char *name, funcp_t func, void *cookie)
+{
+ tcb_t *t = cur_task;
+ t->name = name;
+ t->func = func;
+ t->cookie = cookie;
+ t->state = TASK_INIT;
+ t->stack_ptr = t->stack_base + t->stack_len;
+ for (uint32_t *p = (uint32_t *)t->stack_base; p < (uint32_t *)t->stack_ptr; ++p)
+ *p = STACK_GUARD_WORD;
+ __set_MSP((uint32_t)cur_task->stack_ptr);
+ task_yield();
+}
+
/* Set the idle hook function pointer.
*
* This function is called repeatedly when the system is idle (there are
@@ -232,11 +250,11 @@ void task_yield(void)
/* If there are no other runnable tasks (and cur_task is runnable),
* we don't need to context-switch.
*/
- if (next == cur_task)
+ if (next == cur_task && cur_task->state != TASK_INIT)
return;
/* Save current context, if there is one. */
- if (cur_task != NULL) {
+ if (cur_task != NULL && cur_task->state != TASK_INIT) {
__asm("push {r0-r12, lr}");
cur_task->stack_ptr = (void *)__get_MSP();
diff --git a/task.h b/task.h
index 47d62d6..a71f2e4 100644
--- a/task.h
+++ b/task.h
@@ -51,6 +51,7 @@ typedef struct { unsigned locked; } task_mutex_t;
typedef void (*funcp_t)(void);
extern tcb_t *task_add(char *name, funcp_t func, void *cookie, void *stack, size_t stack_len);
+extern void task_mod(char *name, funcp_t func, void *cookie);
extern void task_set_idle_hook(funcp_t func);