code:
From f7d7b22a9e711783c99be55b2c1c437a6808f24d Mon Sep 17 00:00:00 2001
From: Paul Kocialkowski <contact@paulk.fr>
Date: Sat, 23 Jul 2016 15:51:58 +0200
Subject: [PATCH 4/4] cortex-m: Use assembly exception handler and routine for
 task switching

The way Cortex processors handle exceptions allows writing exception
routines directly in C, as return from exception is handled by providing
a special value for the link register.

However, it is not safe to do this when doing context switching. In
particular, C handlers may push some general-purpose registers that
are used by the handler and pop them later, even when context switch
has happened in the meantime. While the processor will restore {r0-r3}
from the stack when returning from an exception, the C handler code
may push, use and pop another register, clobbering the value resulting
from the context switch.

For this reason, it is safer to have assembly routines for exception
handlers that do context switching.

BUG=chromium:631514
BRANCH=None
TEST=Build and run big EC with a recent GCC version

Change-Id: Ia356321021731e6e372af152c962d8f01c065da5
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
---
 core/cortex-m/switch.S | 90 +++++++++++++++++++++++++++++++++++---------------
 core/cortex-m/task.c   | 28 ++++------------
 2 files changed, 69 insertions(+), 49 deletions(-)

diff --git a/core/cortex-m/switch.S b/core/cortex-m/switch.S
index 92c7e51..80a99c8 100644
--- a/core/cortex-m/switch.S
+++ b/core/cortex-m/switch.S
@@ -13,6 +13,48 @@
 .code 16

 /**
+ * Start the task scheduling.  r0 is a pointer to task_stack_ready, which is
+ * set to 1 after the task stack is set up.
+ */
+.global __task_start
+.thumb_func
+__task_start:
+  ldr r2,=scratchpad     @ area used as dummy thread stack for the first switch
+#ifdef CONFIG_FPU
+  mov r3, #6             @ use : priv. mode / thread stack / floating point on
+#else
+  mov r3, #2             @ use : priv. mode / thread stack / no floating point
+#endif
+  add r2, #17*4          @ put the pointer at the top of the stack
+  mov r1, #0             @ __Schedule parameter : re-schedule nothing
+  msr psp, r2            @ setup a thread stack up to the first context switch
+  mov r2, #1
+  isb                    @ ensure the write is done
+  msr control, r3
+  mov r3, r0
+  mov r0, #0             @ __Schedule parameter : de-schedule nothing
+  isb                    @ ensure the write is done
+  str r2, [r3]           @ Task scheduling is now active
+  bl __schedule          @ execute the task with the highest priority
+  /* we should never return here */
+  mov r0, #1             @ set to EC_ERROR_UNKNOWN
+  bx lr
+
+/**
+ * SVC exception handler
+ */
+.global svc_handler
+.thumb_func
+svc_handler:
+  push {lr}                  @ save link register
+  bl __svc_handler           @ call svc handler helper
+  ldr r3,=current_task       @ load the current task's address
+  ldr r1, [r3]               @ load the current task
+  cmp r0, r1                 @ compare with previous task returned by helper
+  beq svc_handler_return     @ return if they are the same
+  /* continue to __switchto to switch to the new task */
+
+/**
  * Task context switching
  *
  * Change the task scheduled after returning from the exception.
@@ -30,8 +72,6 @@
  *     r0, r1, r2, r3, r12, lr, pc, psr, r4, r5, r6, r7, r8, r9, r10, r11
  *       exception frame              <|> additional registers
  */
-.global __switchto
-.thumb_func
 __switchto:
   mrs r3, psp            @ get the task stack where the context has been saved
   ldr r2, [r1]           @ get the new scheduled task stack pointer
@@ -39,33 +79,29 @@ __switchto:
   ldmia r2!, {r4-r11}    @ restore r4-r11 for the next task context
   str r3, [r0]           @ save the task stack pointer in its context
   msr psp, r2            @ set the process stack pointer to exception context
-  bx lr                  @ return from exception
+
+svc_handler_return:
+  pop {pc}               @ return from exception or return to caller

 /**
- * Start the task scheduling.  r0 is a pointer to task_stack_ready, which is
- * set to 1 after the task stack is set up.
+ * Resched task if needed:
+ * Continue iff a rescheduling event happened or profiling is active,
+ * and we are not called from another exception.
  */
-.global __task_start
+.global task_resched_if_needed
 .thumb_func
-__task_start:
-  ldr r2,=scratchpad     @ area used as dummy thread stack for the first switch
-#ifdef CONFIG_FPU
-  mov r3, #6             @ use : priv. mode / thread stack / floating point on
-#else
-  mov r3, #2             @ use : priv. mode / thread stack / no floating point
-#endif
-  add r2, #17*4          @ put the pointer at the top of the stack
-  mov r1, #0             @ __Schedule parameter : re-schedule nothing
-  msr psp, r2            @ setup a thread stack up to the first context switch
-  mov r2, #1
-  isb                    @ ensure the write is done
-  msr control, r3
-  mov r3, r0
-  mov r0, #0             @ __Schedule parameter : de-schedule nothing
-  isb                    @ ensure the write is done
-  str r2, [r3]           @ Task scheduling is now active
-  bl __schedule          @ execute the task with the highest priority
-  /* we should never return here */
-  mov r0, #1             @ set to EC_ERROR_UNKNOWN
-  bx lr
+task_resched_if_needed:
+  push {lr}                                 @ save link register
+  ldr r3,=need_resched_or_profiling         @ load need's address
+  ldr r1, [r3]                              @ load need
+  cbz r1, task_resched_if_needed_return     @ return if there is no need
+  and r0, #0xf                              @ called from another exception
+  cmp r0, #1                                @ check bit
+  beq task_resched_if_needed_return         @ return if called from exception
+  movs r1, #0                               @ desched nothing
+  movs r0, #0                               @ resched nothing
+  bl svc_handler                            @ re-schedule the highest priority
+                                            @ task

+task_resched_if_needed_return:
+  pop {pc}                                  @ return to caller
diff --git a/core/cortex-m/task.c b/core/cortex-m/task.c
index bfb3a9b..9935a28 100644
--- a/core/cortex-m/task.c
+++ b/core/cortex-m/task.c
@@ -57,7 +57,6 @@ static uint32_t task_switches;   /* Number of times active task changed */
 static uint32_t irq_dist[CONFIG_IRQ_COUNT];  /* Distribution of IRQ calls */
 #endif

-extern void __switchto(task_ *from, task_ *to);
 extern int __task_start(int *task_stack_ready);

 #ifndef CONFIG_LOW_POWER_IDLE
@@ -124,7 +123,7 @@ uint32_t scratchpad[17+18];
 uint32_t scratchpad[17];
 #endif

-static task_ *current_task = (task_ *)scratchpad;
+task_ *current_task = (task_ *)scratchpad;

 /*
  * Should IRQs chain to svc_handler()?  This should be set if either of the
@@ -137,7 +136,7 @@ static task_ *current_task = (task_ *)scratchpad;
  * task unblocking.  After checking for a task switch, svc_handler() will clear
  * the flag (unless profiling is also enabled; then the flag remains set).
  */
-static int need_resched_or_profiling;
+int need_resched_or_profiling;

 /*
  * Bitmap of all tasks ready to be run.
@@ -197,7 +196,7 @@ int task_start_called(void)
 /**
  * Scheduling system call
  */
-void svc_handler(int desched, task_id_t resched)
+task_ *__svc_handler(int desched, task_id_t resched)
 {
 	task_ *current, *next;
 #ifdef CONFIG_TASK_PROFILING
@@ -264,16 +263,13 @@ void svc_handler(int desched, task_id_t resched)
 	need_resched_or_profiling = 0;
 #endif

-	/* Nothing to do */
-	if (next == current)
-		return;
-
 	/* Switch to new task */
 #ifdef CONFIG_TASK_PROFILING
-	task_switches++;
+	if (next != current)
+		task_switches++;
 #endif
 	current_task = next;
-	__switchto(current, next);
+	return current;
 }

 void __schedule(int desched, int resched)
@@ -313,18 +309,6 @@ void task_start_irq_handler(void *excep_return)
 }
 #endif

-void task_resched_if_needed(void *excep_return)
-{
-	/*
-	 * Continue iff a rescheduling event happened or profiling is active,
-	 * and we are not called from another exception.
-	 */
-	if (!need_resched_or_profiling || (((uint32_t)excep_return & 0xf) == 1))
-		return;
-
-	svc_handler(0, 0);
-}
-
 static uint32_t __wait_evt(int timeout_us, task_id_t resched)
 {
 	task_ *tsk = current_task;
--
2.9.0


code:
From 35987639080ef4293bffbc1ce21de4d8a35b41db Mon Sep 17 00:00:00 2001
From: Yunlian Jiang <yunlian@google.com>
Date: Mon, 20 Apr 2015 09:38:56 -0700
Subject: [PATCH 1/6] ec: fix a clang warning by use a unused variable.

This uses the variable 'usage' in an error message to fix a clang
warning.

BUG=chromium:475960
TEST=CC=x86_64-cros-linux-gnu-clang emerge-falco ec-devutils
BRANCH=none
Signed-off-by: yunlian@chromium.org

Change-Id: Ic5703636040805661c7b81b83fc182e127ceab8c
Reviewed-on: https://chromium-review.googlesource.com/266404
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Yunlian Jiang <yunlian@chromium.org>
Commit-Queue: Yunlian Jiang <yunlian@chromium.org>
---
 util/lbcc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/util/lbcc.c b/util/lbcc.c
index b34b21e..953f422 100644
--- a/util/lbcc.c
+++ b/util/lbcc.c
@@ -630,7 +630,7 @@ int main(int argc, char *argv[])
 	}

 	if (errorcnt) {
-		fprintf(stderr, "\nUsage:  %s [options] ...\n\n", progname);
+		fprintf(stderr, usage, progname);
 		exit(1);
 	}

--
2.9.0

repo_name: ShalokShalom/libreboot

license: mit


code:
From d2f946caf27adf4518cb657da39e296366d0b53f Mon Sep 17 00:00:00 2001
From: Mike Frysinger <vapier@chromium.org>
Date: Mon, 7 Dec 2015 21:46:13 -0500
Subject: [PATCH 2/6] use _DEFAULT_SOURCE for newer glibc

Newer versions of glibc have moved to _DEFAULT_SOURCE and away from
_BSD_SOURCE.  Trying to use the BSD define by itself leads to warnings
which causes build failures.

BRANCH=none
BUG=None
TEST=precq still works

Signed-off-by: Mike Frysinger <vapier@chromium.org>
Change-Id: Ice24b84dc6a540695fc7b76e8f22a4c85c301976
Reviewed-on: https://chromium-review.googlesource.com/316730
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
---
 util/ec_uartd.c | 3 ++-
 util/stm32mon.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/util/ec_uartd.c b/util/ec_uartd.c
index 82823c4..678932e 100644
--- a/util/ec_uartd.c
+++ b/util/ec_uartd.c
@@ -11,7 +11,8 @@
  */

 /* Force header files to define grantpt(), posix_openpt(), cfmakeraw() */
-#define _BSD_SOURCE
+#define _DEFAULT_SOURCE /* Newer glibc */
+#define _BSD_SOURCE     /* Older glibc */
 #define _XOPEN_SOURCE 600
 /* Force header file to declare ptsname_r(), etc. */
 #ifndef _GNU_SOURCE
diff --git a/util/stm32mon.c b/util/stm32mon.c
index 2de9400..ed1a7ee 100644
--- a/util/stm32mon.c
+++ b/util/stm32mon.c
@@ -13,7 +13,8 @@
  */

 /* use cfmakeraw() */
-#define _BSD_SOURCE
+#define _DEFAULT_SOURCE /* Newer glibc */
+#define _BSD_SOURCE     /* Older glibc */

 #include <arpa/inet.h>
 #include <errno.h>
--
2.9.0


code:
From 63bb6f6effbaae9864366588464a7b9354c9a623 Mon Sep 17 00:00:00 2001
From: Paul Kocialkowski <contact@paulk.fr>
Date: Wed, 20 Jul 2016 16:26:32 +0200
Subject: [PATCH 3/6] Enforce compilation without system headers

This is based on commit bc404c94b4ab1e6a62e607fd7ef034aa31d6388e
(Enforce compilation without system headers)
---
 Makefile           | 5 +++--
 Makefile.toolchain | 2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index 01581fb..195ea44 100644
--- a/Makefile
+++ b/Makefile
@@ -99,8 +99,9 @@ _rw_size_str:=$(shell echo "CONFIG_FW_RW_SIZE" | $(CPP) $(CPPFLAGS) -P \
 _rw_size:=$(shell echo "$$(($(_rw_size_str)))")

 # Get RSA key size from board defines
-_rsa_size:=$(shell echo "CONFIG_RSA_KEY_SIZE" | $(CPP) $(CPPFLAGS) -P \
-            -Ichip/$(CHIP) -Iboard/$(BOARD) -imacros include/rsa.h)
+_rsa_size:=$(shell echo "CONFIG_RSA_KEY_SIZE" | $(CPP) $(CPPFLAGS) \
+            $(CFLAGS_WARN) -P -Ichip/$(CHIP) -Iboard/$(BOARD) \
+            -imacros include/rsa.h)
 $(eval RSA_KEY_SIZE=$(_rsa_size))

 $(eval BOARD_$(UC_BOARD)=y)
diff --git a/Makefile.toolchain b/Makefile.toolchain
index 43f390c..898129c 100644
--- a/Makefile.toolchain
+++ b/Makefile.toolchain
@@ -19,7 +19,7 @@ BUILDCC?=gcc
 HOSTCC?=$(HOST_CROSS_COMPILE)gcc

 CFLAGS_WARN=-Wall -Werror -Wundef -Wstrict-prototypes -Wno-trigraphs      \
-            -fno-strict-aliasing -fno-common                              \
+            -fno-strict-aliasing -fno-common -ffreestanding -fno-builtin  \
             -Werror-implicit-function-declaration -Wno-format-security    \
             -fno-delete-null-pointer-checks -Wdeclaration-after-statement \
             -Wno-pointer-sign -fno-strict-overflow -fconserve-stack
--
2.9.0


code:
From 3515f1d744cbcdb37471e898277aa6b1ddd3d0ee Mon Sep 17 00:00:00 2001
From: Paul Kocialkowski <contact@paulk.fr>
Date: Wed, 20 Jul 2016 16:27:05 +0200
Subject: [PATCH 4/6] Don't declare functions inline that aren't always defined
 as such

This is based on commit 960cf45b3ffe88e842c27145e7e646d63a89c371
(Don't declare functions inline that aren't always defined as such)
---
 include/task.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/task.h b/include/task.h
index cb96281..85d5b00 100644
--- a/include/task.h
+++ b/include/task.h
@@ -47,7 +47,7 @@ void interrupt_enable(void);
 /**
  * Return true if we are in interrupt context.
  */
-inline int in_interrupt_context(void);
+int in_interrupt_context(void);

 /**
  * Set a task event.
--
2.9.0


code:
From 913b2f1265bd7f3ebe6cf4cba92c20c5a423a6c3 Mon Sep 17 00:00:00 2001
From: Paul Kocialkowski <contact@paulk.fr>
Date: Tue, 2 Aug 2016 12:05:55 +0200
Subject: [PATCH 5/6] Don't include missing and unnecessary math header

This removes the inclusion of an unnecessary math header that is neither
found nor necessary for non-cortex-m ECs.

Change-Id: I56a04178dadedb76f841504fa645e2d43900d25f
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
---
 common/math_util.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/common/math_util.c b/common/math_util.c
index 120d13d..34a267d 100644
--- a/common/math_util.c
+++ b/common/math_util.c
@@ -6,7 +6,6 @@
 /* Common math functions. */

 #include "common.h"
-#include "math.h"
 #include "math_util.h"
 #include "util.h"

--
2.9.0


code:
From 9dd7ae82d3f3fa9dae31a442365e233a0b44cce3 Mon Sep 17 00:00:00 2001
From: Paul Kocialkowski <contact@paulk.fr>
Date: Sat, 23 Jul 2016 14:17:32 +0200
Subject: [PATCH 6/6] cortex-m0: Use assembly exception handlers for task
 switching

The way Cortex processors handle exceptions allows writing exception
routines directly in C, as return from exception is handled by providing
a special value for the link register.

However, it is not safe to do this when doing context switching. In
particular, C handlers may push some general-purpose registers that
are used by the handler and pop them later, even when context switch
has happened in the meantime. While the processor will restore {r0-r3}
from the stack when returning from an exception, the C handler code
may push, use and pop another register, such as r4.

It turns out that GCC 4.8 would generally only use r3 in svc_handler and
pendsv_handler, but newer versions tend to use r4, thus clobbering r4
that was restored from the context switch and leading up to a fault
when r4 is used by the task code.

An occurrence of this behaviour takes place with GCC > 4.8 in __wait_evt,
where "me" is stored in r4, which gets clobbered after an exception
triggers pendsv_handler. The exception handler uses r4 internally, does
a context switch and then restores the previous value of r4, which is
not restored by the processor's internal, thus clobbering r4.
This ends up with the following assertion failure:
'tskid < TASK_ID_COUNT' in timer_cancel() at common/timer.c:137

For this reason, it is safer to have assembly routines for exception
handlers that do context switching.

BUG=chromium:631514
BRANCH=None
TEST=Build and run speedy EC with a recent GCC version

Change-Id: Ib068bc12ce2204aee3e0f563efcb94f15aa87013
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
---
 core/cortex-m0/switch.S | 81 ++++++++++++++++++++++++++++++++++---------------
 core/cortex-m0/task.c   | 27 +----------------
 2 files changed, 58 insertions(+), 50 deletions(-)

diff --git a/core/cortex-m0/switch.S b/core/cortex-m0/switch.S
index 95ea29e..d4b47cd 100644
--- a/core/cortex-m0/switch.S
+++ b/core/cortex-m0/switch.S
@@ -7,12 +7,52 @@

 #include "config.h"

+#define CPU_SCB_ICSR		0xe000ed04
+
 .text

 .syntax unified
 .code 16

 /**
+ * Start the task scheduling.  r0 is a pointer to task_stack_ready, which is
+ * set to 1 after the task stack is set up.
+ */
+.global __task_start
+.thumb_func
+__task_start:
+  ldr  r2,=scratchpad     @ area used as dummy thread stack for the first switch
+  movs r3, #2             @ use : priv. mode / thread stack / no floating point
+  adds r2, #17*4          @ put the pointer at the top of the stack
+  movs r1, #0             @ __Schedule parameter : re-schedule nothing
+  msr  psp, r2            @ setup a thread stack up to the first context switch
+  movs r2, #1
+  isb                     @ ensure the write is done
+  msr control, r3
+  movs r3, r0
+  movs r0, #0             @ __Schedule parameter : de-schedule nothing
+  isb                     @ ensure the write is done
+  str  r2, [r3]           @ Task scheduling is now active
+  bl __schedule           @ execute the task with the highest priority
+  /* we should never return here */
+  movs r0, #1             @ set to EC_ERROR_UNKNOWN
+  bx lr
+
+/**
+ * SVC exception handler
+ */
+.global svc_handler
+.thumb_func
+svc_handler:
+  push {lr}                  @ save link register
+  bl __svc_handler           @ call svc handler helper
+  ldr r3,=current_task       @ load the current task's address
+  ldr r1, [r3]               @ load the current task
+  cmp r0, r1                 @ compare with previous task returned by helper
+  beq svc_handler_return     @ return if they are the same
+  /* continue to __switchto to switch to the new task */
+
+/**
  * Task context switching
  *
  * Change the task scheduled after returning from the exception.
@@ -30,8 +70,6 @@
  *     r8, r9, r10, r11, r4, r5, r6, r7, r0, r1, r2, r3, r12, lr, pc, psr
  *     additional registers            <|> exception frame
  */
-.global __switchto
-.thumb_func
 __switchto:
   mrs r2, psp            @ get the task stack where the context has been saved
   mov r3, sp
@@ -53,29 +91,24 @@ __switchto:
   mov r11, r7
   ldmia r2!, {r4-r7}     @ restore r4-r7 for the next task context
   msr psp, r2            @ set the process stack pointer to exception context
-  bx lr                  @ return from exception
+
+svc_handler_return:
+  pop {pc}               @ return from exception or return to caller

 /**
- * Start the task scheduling.  r0 is a pointer to task_stack_ready, which is
- * set to 1 after the task stack is set up.
+ * PendSVC exception handler
  */
-.global __task_start
+.global pendsv_handler
 .thumb_func
-__task_start:
-  ldr  r2,=scratchpad     @ area used as dummy thread stack for the first switch
-  movs r3, #2             @ use : priv. mode / thread stack / no floating point
-  adds r2, #17*4          @ put the pointer at the top of the stack
-  movs r1, #0             @ __Schedule parameter : re-schedule nothing
-  msr  psp, r2            @ setup a thread stack up to the first context switch
-  movs r2, #1
-  isb                     @ ensure the write is done
-  msr control, r3
-  movs r3, r0
-  movs r0, #0             @ __Schedule parameter : de-schedule nothing
-  isb                     @ ensure the write is done
-  str  r2, [r3]           @ Task scheduling is now active
-  bl __schedule           @ execute the task with the highest priority
-  /* we should never return here */
-  movs r0, #1             @ set to EC_ERROR_UNKNOWN
-  bx lr
-
+pendsv_handler:
+  push {lr}                  @ save link register
+  ldr r0, =#CPU_SCB_ICSR     @ load CPU_SCB_ICSR's address
+  movs r1, #1                @ prepare left shift (1 << 27)
+  lsls r1, #27               @ shift the bit
+  str r1, [r0]               @ clear pending flag
+  cpsid i                    @ ensure we have priority 0 during re-scheduling
+  movs r1, #0                @ desched nothing
+  movs r0, #0                @ resched nothing
+  bl svc_handler             @ re-schedule the highest priority task
+  cpsie i                    @ leave priority 0
+  pop {pc}                   @ return from exception
diff --git a/core/cortex-m0/task.c b/core/cortex-m0/task.c
index e51621b..f96ccf8 100644
--- a/core/cortex-m0/task.c
+++ b/core/cortex-m0/task.c
@@ -57,7 +57,6 @@ static uint32_t task_switches;   /* Number of times active task changed */
 static uint32_t irq_dist[CONFIG_IRQ_COUNT];  /* Distribution of IRQ calls */
 #endif

-extern void __switchto(task_ *from, task_ *to);
 extern int __task_start(int *task_stack_ready);

 #ifndef CONFIG_LOW_POWER_IDLE
@@ -120,7 +119,7 @@ uint8_t task_stacks[0
 /* Reserve space to discard context on first context switch. */
 uint32_t scratchpad[17];

-static task_ *current_task = (task_ *)scratchpad;
+task_ *current_task = (task_ *)scratchpad;

 /*
  * Bitmap of all tasks ready to be run.
@@ -242,18 +241,6 @@ task_ *__svc_handler(int desched, task_id_t resched)
 	return current;
 }

-void svc_handler(int desched, task_id_t resched)
-{
-	/*
-	 * The layout of the this routine (and the __svc_handler companion one)
-	 * ensures that we are getting the right tail call optimization from
-	 * the compiler.
-	 */
-	task_ *prev = __svc_handler(desched, resched);
-	if (current_task != prev)
-		__switchto(prev, current_task);
-}
-
 void __schedule(int desched, int resched)
 {
 	register int p0 asm("r0") = desched;
@@ -262,18 +249,6 @@ void __schedule(int desched, int resched)
 	asm("svc 0" : : "r"(p0), "r"(p1));
 }

-void pendsv_handler(void)
-{
-	/* Clear pending flag */
-	CPU_SCB_ICSR = (1 << 27);
-
-	/* ensure we have priority 0 during re-scheduling */
-	__asm__ __volatile__("cpsid i");
-	/* re-schedule the highest priority task */
-	svc_handler(0, 0);
-	__asm__ __volatile__("cpsie i");
-}
-
 #ifdef CONFIG_TASK_PROFILING
 void task_start_irq_handler(void *excep_return)
 {
--
2.9.0


code:
#!/usr/bin/env bash

# Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

install() {
	project_install "$project"
}

install_check() {
	project_install_check "$project"
}

release() {
	project_release_install_archive "$project" "$TOOLS"
}

release_check() {
	project_release_install_archive_check "$project" "$TOOLS"
}

clean() {
	project_clean "$project"
}

path: projects/cros-scripts/cros-scripts


code:
#!/usr/bin/env bash

# Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

REGEXP="\([^[:space:]]*\)[[:space:]]\(.*\)"

KEYBLOCK="keyblock"
VBPRIVK="vbprivk"
VBPUBK="vbpubk"
KEYB="keyb"
PEM="pem"
CRT="crt"

KEYS="ec_root_key ec_data_key root_key firmware_data_key kernel_subkey kernel_data_key recovery_key recovery_kernel_data_key installer_kernel_data_key"
KEYBLOCKS="firmware ec recovery_kernel kernel installer_kernel"
SUBKEYS="firmware_data_key root_key ec_data_key ec_root_key recovery_kernel_data_key recovery_key kernel_data_key kernel_subkey installer_kernel_data_key recovery_key"
ALGORITHMS="7 7 11 7 7 4 11 11 11"
MODES="7 7 11 7 10"

usage() {
	printf 1>&2 '%s\n' "$executable [action]"

	printf 1>&2 '\n%s\n' 'Actions:'
	printf 1>&2 '%s\n' '  generate - Generate a set of keys'
	printf 1>&2 '%s\n' '  verify - Verify keyblocks'

	printf 1>&2 '\n%s\n' 'Environment variables:'
	printf 1>&2 '%s\n' '  KEYS_VERSION - Version to give the keys'
	printf 1>&2 '%s\n' '  VBOOT_KEYS_PATH - Path to the vboot keys'
	printf 1>&2 '%s\n' '  VBOOT_TOOLS_PATH - Path to vboot tools'
}

keys_override_confirm() {
	local override=0
	local confirm

	for key in $KEYS
	do
		if [ -f "$VBOOT_KEYS_PATH/$key.$VBPUBK" ] || [ -f "$VBOOT_KEYS_PATH/$key.$VBPRIVK" ]
		then
			override=1
		fi
	done

	for keyblock in $KEYBLOCKS
	do
		if [ -f "$VBOOT_KEYS_PATH/$keyblock.$KEYBLOCK" ]
		then
			override=1
		fi
	done

	if [ $override -ne 1 ]
	then
		return 0
	fi

	printf '%s\n' 'This is going to override keys stored in the following directory:'
	printf '%s\n' "  $VBOOT_KEYS_PATH"
	printf '%s' 'Press enter to confirm: '

	read confirm
}

generate() {
	local algorithms=$ALGORITHMS
	local subkeys=$SUBKEYS
	local modes=$MODES
	local keyblock
	local algorithm
	local pubkey
	local privkey
	local mode

	keys_override_confirm

	for key in $KEYS
	do
		algorithm=$( printf '%s\n' "$algorithms" | sed "s/$REGEXP/\1/g" )
		algorithms=$( printf '%s\n' "$algorithms" | sed "s/$REGEXP/\2/g" )

		key_length=$(( 1 << (10 + ($algorithm / 3)) ))

		openssl genrsa -F4 -out "$VBOOT_KEYS_PATH/$key.$PEM" "$key_length"
		openssl req -batch -new -x509 -key "$VBOOT_KEYS_PATH/$key.$PEM"
		openssl req -batch -new -x509 -key "$VBOOT_KEYS_PATH/$key.$PEM" -out "$VBOOT_KEYS_PATH/$key.$CRT"
		dumpRSAPublicKey -cert "$VBOOT_KEYS_PATH/$key.$CRT" > "$VBOOT_KEYS_PATH/$key.$KEYB"
		futility vbutil_key --pack "$VBOOT_KEYS_PATH/$key.$VBPUBK" --key "$VBOOT_KEYS_PATH/$key.$KEYB" --version "$KEYS_VERSION" --algorithm "$algorithm"
		futility vbutil_key --pack "$VBOOT_KEYS_PATH/$key.$VBPRIVK" --key "$VBOOT_KEYS_PATH/$key.$PEM" --algorithm "$algorithm"

		rm -f "$VBOOT_KEYS_PATH/$key.$PEM" "$VBOOT_KEYS_PATH/$key.$CRT" "$VBOOT_KEYS_PATH/$key.$KEYB"
	done

	printf '\n%s\n' "Generated keys $KEYS"

	for keyblock in $KEYBLOCKS
	do
		pubkey=$( printf '%s\n' "$subkeys" | sed "s/$REGEXP/\1/g" )
		subkeys=$( printf '%s\n' "$subkeys" | sed "s/$REGEXP/\2/g" )
		privkey=$( printf '%s\n' "$subkeys" | sed "s/$REGEXP/\1/g" )
		subkeys=$( printf '%s\n' "$subkeys" | sed "s/$REGEXP/\2/g" )

		mode=$( printf '%s\n' "$modes" | sed "s/$REGEXP/\1/g" )
		modes=$( printf '%s\n' "$modes" | sed "s/$REGEXP/\2/g" )

		futility vbutil_keyblock --pack "$VBOOT_KEYS_PATH/$keyblock.$KEYBLOCK" --flags "$mode" --datapubkey "$VBOOT_KEYS_PATH/$pubkey.$VBPUBK" --signprivate "$VBOOT_KEYS_PATH/$privkey.$VBPRIVK"
		futility vbutil_keyblock --unpack "$VBOOT_KEYS_PATH/$keyblock.$KEYBLOCK" --signpubkey "$VBOOT_KEYS_PATH/$privkey.$VBPUBK"
	done

	printf '\n%s\n' "Generated keyblocks $KEYBLOCKS"
}

verify() {
	local subkeys=$SUBKEYS
	local pubkey
	local privkey

	for keyblock in $KEYBLOCKS
	do
		pubkey=$( printf '%s\n' "$subkeys" | sed "s/$REGEXP/\1/g" )
		subkeys=$( printf '%s\n' "$subkeys" | sed "s/$REGEXP/\2/g" )
		privkey=$( printf '%s\n' "$subkeys" | sed "s/$REGEXP/\1/g" )
		subkeys=$( printf '%s\n' "$subkeys" | sed "s/$REGEXP/\2/g" )

		futility vbutil_keyblock --unpack "$VBOOT_KEYS_PATH/$keyblock.$KEYBLOCK" --signpubkey "$VBOOT_KEYS_PATH/$privkey.$VBPUBK"
	done

	printf '\n%s\n' "Verified keyblocks $KEYBLOCKS"
}

requirements() {
	local requirement
	local requirement_path

	for requirement in "$@"
	do
		requirement_path=$( which "$requirement" || true )

		if [ -z "$requirement_path" ]
		then
			printf 1>&2 '%s\n' "Missing requirement: $requirement"
			exit 1
		fi
	done
}

setup() {
	root=$(readlink -f "$( dirname "$0" )" )
	executable=$( basename "$0" )

	if [ -z "$KEYS_VERSION" ]
	then
		KEYS_VERSION=1
	fi

	if ! [ -z "$VBOOT_TOOLS_PATH" ]
	then
		PATH="$PATH:$VBOOT_TOOLS_PATH"
	fi

	if [ -z "$VBOOT_KEYS_PATH" ]
	then
		VBOOT_KEYS_PATH="$root/keys"
		mkdir -p "$VBOOT_KEYS_PATH"
	fi
}

cros_boot_keys() {
	local action=$1

	set -e

	setup "$@"

	if [ -z "$action" ]
	then
		usage
		exit 1
	fi

	case $action in
		"generate")
			requirements "openssl" "dumpRSAPublicKey" "futility"
			generate
			;;
		"verify")
			requirements "futility"
			verify
			;;
		*)
			usage
			exit 1
			;;
	esac
}

cros_boot_keys "$@"


code:
#!/usr/bin/env bash

# Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

KEYBLOCK="keyblock"
VBPRIVK="vbprivk"
VBPUBK="vbpubk"

GBB_FLAGS="dev_screen_short_delay load_option_roms enable_alternate_os force_dev_switch_on force_dev_boot_usb disable_fw_rollback_check enter_triggers_tonorm force_dev_boot_legacy faft_key_overide disable_ec_software_sync default_dev_boot_lefacy disable_pd_software_sync disable_lid_shutdown dev_boot_fastboot_full_cap enable_serial"

usage() {
	printf 1>&2 '%s\n' "$executable [action] [firmware image] [gbb action|vpd action] [gbb file|gbb flag|vpd file]"

	printf 1>&2 '\n%s\n' 'Actions:'
	printf 1>&2 '%s\n' '  sign - Sign firmware image'
	printf 1>&2 '%s\n' '  verify - Verify firmware image'
	printf 1>&2 '%s\n' '  gbb - Google Binary Block'

	printf 1>&2 '\n%s\n' 'GBB actions:'
	printf 1>&2 '%s\n' '  extract - Extract GBB from firmware image to path'
	printf 1>&2 '%s\n' '  replace - Replace GBB from path to firmware image'
	printf 1>&2 '%s\n' '  list - List enabled GBB flags'
	printf 1>&2 '%s\n' '  enable - Enable GBB flag'
	printf 1>&2 '%s\n' '  disable - Disable GBB flag'

	printf 1>&2 '\n%s\n' 'GBB flags:'

	for flag in $GBB_FLAGS
	do
		printf 1>&2 '%s\n' "  $flag"
	done

	printf 1>&2 '\n%s\n' 'VPD actions:'
	printf 1>&2 '%s\n' '  extract - Extract VPD from firmware image to path'
	printf 1>&2 '%s\n' '  replace - Replace VPD from path to firmware image'

	printf 1>&2 '\n%s\n' 'Environment variables:'
	printf 1>&2 '%s\n' '  VBOOT_KEYS_PATH - Path to the vboot keys'
	printf 1>&2 '%s\n' '  VBOOT_TOOLS_PATH - Path to vboot tools'
}

sign() {
	local firmware_image_path=$1

	futility sign --signprivate="$VBOOT_KEYS_PATH/firmware_data_key.$VBPRIVK" --keyblock "$VBOOT_KEYS_PATH/firmware.$KEYBLOCK" --kernelkey "$VBOOT_KEYS_PATH/kernel_subkey.$VBPUBK" --infile "$firmware_image_path"
	futility gbb_utility -s --recoverykey="$VBOOT_KEYS_PATH/recovery_key.$VBPUBK" --rootkey="$VBOOT_KEYS_PATH/root_key.$VBPUBK" "$firmware_image_path" "$firmware_image_path"

	printf '\n%s\n' "Signed firmwares image $firmware_image_path"
}

verify() {
	local firmware_image_path=$1

	futility verify -k "$VBOOT_KEYS_PATH/root_key.$VBPUBK" "$firmware_image_path" || ( printf '\n%s\n' "Bad firmware image signature!" >&2 && return 1 )

	printf '\n%s\n' "Verified firmware image $firmware_image_path"
}

gbb() {
	local firmware_image_path=$1
	local gbb_action=$2
	local gbb_file_path=$3
	local gbb_flag=$3

	local i=0
	local flags
	local flag
	local flag_value

	case $gbb_action in
		"extract")
			if [ -z "$gbb_file_path" ]
			then
				usage
				exit 1
			fi

			futility dump_fmap -x "$firmware_image_path" "GBB:$gbb_file_path"

			printf '\n%s\n' "Extracted GBB from $firmware_image_path to $gbb_file_path"
			;;
		"replace")
			if [ -z "$gbb_file_path" ]
			then
				usage
				exit 1
			fi

			futility load_fmap "$firmware_image_path" "GBB:$gbb_file_path"

			printf '\n%s\n' "Replaced GBB from $gbb_file_path to $firmware_image_path"
			;;
		"list")
			printf '%s\n' "GBB flags in $firmware_image_path:"

			flags=$( gbb_flags_get "$firmware_image_path" )

			for flag in $GBB_FLAGS
			do
				flag_value=$(( 1 << $i ))

				if (( $flags & $flag_value ))
				then
					printf '%s\n' "  $flag"
				fi

				i=$(( $i + 1 ))
			done

			;;
		"enable")
			if [ -z "$gbb_flag" ]
			then
				usage
				exit 1
			fi

			flags=$( gbb_flags_get "$firmware_image_path" )
			flag_value=$( gbb_flag_value "$gbb_flag" )

			if [ -z "$flag_value" ]
			then
				printf 1>&2 '%s\n' "Invalid GBB flag: $gbb_flag"
				exit 1
			fi

			flags=$( printf "0x%x\n" $(( $flags | $flag_value )) )

			gbb_flags_set "$firmware_image_path" "$flags"

			printf '\n%s\n' "Enabled GBB flag $gbb_flag in $firmware_image_path"
			;;
		"disable")
			if [ -z "$gbb_flag" ]
			then
				usage
				exit 1
			fi

			flags=$( gbb_flags_get "$firmware_image_path" )
			flag_value=$( gbb_flag_value "$gbb_flag" )

			if [ -z "$flag_value" ]
			then
				printf 1>&2 '%s\n' "Invalid GBB flag: $gbb_flag"
				exit 1
			fi

			flags=$( printf "0x%x\n" $(( $flags & ~$flag_value )) )

			gbb_flags_set "$firmware_image_path" "$flags"

			printf '\n%s\n' "Disabled GBB flag $gbb_flag in $firmware_image_path"
			;;
		*)
			usage
			exit 1
			;;
	esac

}

gbb_flags_get() {
	local firmware_image_path=$1

	futility gbb_utility -g --flags "$firmware_image_path" | sed "s/^[^:]*: //g"
}

gbb_flags_set() {
	local firmware_image_path=$1
	local gbb_flags=$2

	futility gbb_utility -s --flags="$gbb_flags" "$firmware_image_path"
}

gbb_flag_value() {
	local gbb_flag=$1

	local i=0

	for flag in $GBB_FLAGS
	do
		if [ "$gbb_flag" = "$flag" ]
		then
			printf '%d\n' $(( 1 << $i ))
			return
		fi

		i=$(( $i + 1 ))
	done
}

vpd() {
	local firmware_image_path=$1
	local vpd_action=$2
	local vpd_file_path=$3

	case $vpd_action in
		"extract")
			futility dump_fmap -x "$firmware_image_path" "RO_VPD:$vpd_file_path"

			printf '\n%s\n' "Extracted VPD from $firmware_image_path to $vpd_file_path"
			;;
		"replace")
			futility load_fmap "$firmware_image_path" "RO_VPD:$vpd_file_path"

			printf '\n%s\n' "Replaced VPD from $vpd_file_path to $firmware_image_path"
			;;
		*)
			usage
			exit 1
			;;
	esac
}

requirements() {
	local requirement
	local requirement_path

	for requirement in "$@"
	do
		requirement_path=$( which "$requirement" || true )

		if [ -z "$requirement_path" ]
		then
			printf 1>&2 '%s\n' "Missing requirement: $requirement"
			exit 1
		fi
	done
}

setup() {
	root=$(readlink -f "$( dirname "$0" )" )
	executable=$( basename "$0" )

	if ! [ -z "$VBOOT_TOOLS_PATH" ]
	then
		PATH="$PATH:$VBOOT_TOOLS_PATH"
	fi

	if [ -z "$VBOOT_KEYS_PATH" ]
	then
		if ! [ -z "$VBOOT_TOOLS_PATH" ] && [ -d "$VBOOT_TOOLS_PATH/devkeys" ]
		then
			VBOOT_KEYS_PATH="$VBOOT_TOOLS_PATH/devkeys"
		else
			VBOOT_KEYS_PATH="/usr/share/vboot/devkeys"
		fi
	fi
}

cros_firmware_prepare() {
	local action=$1
	local firmware_image_path=$2
	local gbb_action=$3
	local vpd_action=$3
	local gbb_file_path_flag=$4
	local vpd_file_path=$4

	set -e

	setup "$@"

	if [ -z "$action" ] || [ -z "$firmware_image_path" ]
	then
		usage
		exit 1
	fi

	case $action in
		"sign")
			if ! [ -f "$firmware_image_path" ]
			then
				usage
				exit 1
			fi

			requirements "futility"
			sign "$firmware_image_path"
			;;
		"verify")
			requirements "futility"
			verify "$firmware_image_path"
			;;
		"gbb")
			requirements "futility"
			gbb "$firmware_image_path" "$gbb_action" "$gbb_file_path_flag"
			;;
		"vpd")
			if [ -z "$vpd_file_path" ]
			then
				usage
				exit 1
			fi

			requirements "futility"
			vpd "$firmware_image_path" "$vpd_action" "$vpd_file_path"
			;;
		*)
			usage
			exit 1
			;;
	esac
}

cros_firmware_prepare "$@"


code:
#!/usr/bin/env bash

# Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

SYS_BLOCK_PATH="/sys/class/block"
DEV_PATH="/dev"
DEVICE="device"
VENDOR="vendor"
MODEL="model"
NAME="name"

usage() {
	printf 1>&2 '%s\n' "$executable [action] [storage] [kernel image|kernel modules]"

	printf 1>&2 '\n%s\n' 'Actions:'
	printf 1>&2 '%s\n' '  backup - Backup kernel image'
	printf 1>&2 '%s\n' '  image - Install kernel image'
	printf 1>&2 '%s\n' '  modules - Install kernel modules'

	usage_storage

	printf 1>&2 '\n%s\n' 'Environment variables:'
	printf 1>&2 '%s\n' '  VBOOT_KEYS_PATH - Path to the vboot keys'
	printf 1>&2 '%s\n' '  VBOOT_TOOLS_PATH - Path to vboot tools'
}

usage_storage() {
	printf 1>&2 '\n%s\n' 'Storage:'

	local nodes=$( ls "$SYS_BLOCK_PATH" )
	local node_path
	local name

	for node in $nodes
	do
		node_path="$DEV_PATH/$node"
		if ! [ -b "$node_path" ]
		then
			continue
		fi

		name=$( storage_name "$node_path" )
		if [ -z "$name" ]
		then
			continue
		fi

		printf 1>&2 '%s\n' "  $node_path - $name"
	done
}

storage_affect_confirm() {
	local storage_path=$1

	local name=$( storage_name "$storage_path" )
	local confirm

	printf '%s\n' 'This is going to affect the following storage:'
	printf '%s\n' "  $storage_path - $name"
	printf '%s' 'Press enter to confirm: '

	read confirm
}

storage_name() {
	local storage_path=$1

	local node=$( basename "$storage_path" )
	local vendor_path="$SYS_BLOCK_PATH/$node/$DEVICE/$VENDOR"
	local model_path="$SYS_BLOCK_PATH/$node/$DEVICE/$MODEL"
	local name_path="$SYS_BLOCK_PATH/$node/$DEVICE/$NAME"
	local vendor
	local name

	if [ -f "$model_path" ]
	then
		name=$( cat "$model_path" )
	elif [ -f "$name_path" ]
	then
		name=$( cat "$name_path" )
	else
		return 0
	fi

	name=$( printf '%s\n' "$name" | sed -e "s/^[[:space:]]*//;s/[[:space:]]*$//" )

	if [ -f "$vendor_path" ]
	then
		vendor=$( cat "$vendor_path" )
		vendor=$( printf '%s\n' "$vendor" | sed -e "s/^[[:space:]]*//;s/[[:space:]]*$//" )

		name="$vendor $name"
	fi

	printf '%s\n' "$name"
}

storage_partition_path() {
	local storage_path=$1
	local index=$2

	storage_partition_path="$storage_path$index"

	if ! [ -b "$storage_partition_path" ]
	then
		storage_partition_path="$storage_path""p$index"
	fi

	if ! [ -b "$storage_partition_path" ]
	then
		return 1
	fi

	printf '%s\n' "$storage_partition_path"
}

storage_partition_mount_path() {
	local storage_partition_path=$1

	local storage_partition_mount_path=$( udisksctl info -b "$storage_partition_path"  | grep "MountPoints" | sed "s/.*MountPoints:[[:space:]]*\(.*\)/\1/g" )

	printf '%s\n' "$storage_partition_mount_path"
}

storage_kernel_path() {
	local storage_path=$1

	cgpt find -t kernel "$storage_path" | head -n 1
}

storage_rootfs_path() {
	local storage_path=$1

	cgpt find -t rootfs "$storage_path" | head -n 1
}

backup() {
	local storage_path=$1
	local kernel_image_path=$2

	local storage_kernel_path=$( storage_kernel_path "$storage_path" )

	if [ -z "$storage_kernel_path" ]
	then
		printf 1>&2 '%s\n' "No kernel partition found on storage $storage_path"
		return 1
	fi

	cat "$storage_kernel_path" > "$kernel_image_path"

	printf '\n%s\n' "Backed up kernel image to $kernel_image_path"
}

image() {
	local storage_path=$1
	local kernel_image_path=$2

	local storage_kernel_path=$( storage_kernel_path "$storage_path" )

	if [ -z "$storage_kernel_path" ]
	then
		printf 1>&2 '%s\n' "No kernel partition found on storage $storage_path"
		return 1
	fi

	storage_affect_confirm "$storage_path"

	cat "$kernel_image_path" > "$storage_kernel_path"
	sync

	printf '\n%s\n' "Installed kernel image on storage $storage_path"
}

modules() {
	local storage_path=$1
	local kernel_modules_path=$2

	local storage_rootfs_path=$( storage_rootfs_path "$storage_path" )

	if [ -z "$storage_rootfs_path" ]
	then
		printf 1>&2 '%s\n' "No rootfs partition found on storage $storage_path"
		return 1
	fi

	storage_affect_confirm "$storage_path"

	# Partition may already be mounted.
	udisksctl mount -b "$storage_rootfs_path" || true

	storage_rootfs_mount_path=$( storage_partition_mount_path "$storage_rootfs_path" )

	rsync -a --keep-dirlinks "$kernel_modules_path" "$storage_rootfs_mount_path/"
	sync

	udisksctl unmount -b "$storage_rootfs_path"

	printf '\n%s\n' "Installed kernel modules on storage $storage_path"
}

requirements() {
	local requirement
	local requirement_path

	for requirement in "$@"
	do
		requirement_path=$( which "$requirement" || true )

		if [ -z "$requirement_path" ]
		then
			printf 1>&2 '%s\n' "Missing requirement: $requirement"
			exit 1
		fi
	done
}

setup() {
	root=$(readlink -f "$( dirname "$0" )" )
	executable=$( basename "$0" )

	if ! [ -z "$VBOOT_TOOLS_PATH" ]
	then
		PATH="$PATH:$VBOOT_TOOLS_PATH"
	fi

	if [ -z "$VBOOT_KEYS_PATH" ]
	then
		if ! [ -z "$VBOOT_TOOLS_PATH" ] && [ -d "$VBOOT_TOOLS_PATH/devkeys" ]
		then
			VBOOT_KEYS_PATH="$VBOOT_TOOLS_PATH/devkeys"
		else
			VBOOT_KEYS_PATH="/usr/share/vboot/devkeys"
		fi
	fi
}

cros_kernel_install() {
	local action=$1
	local storage_path=$2
	local kernel_image_path=$3
	local kernel_modules_path=$3

	set -e

	setup "$@"

	if [ -z "$action" ] || [ -z "$storage_path" ] || [ -z "$kernel_image_path" ] || [ -z "$kernel_modules_path" ]
	then
		usage
		exit 1
	fi

	case $action in
		"backup")
			requirements "cgpt"
			backup "$storage_path" "$kernel_image_path"
			;;
		"image")
			requirements "cgpt"
			image "$storage_path" "$kernel_image_path"
			;;
		"modules")
			requirements "cgpt"
			modules "$storage_path" "$kernel_modules_path"
			;;
		*)
			usage
			exit 1
			;;
	esac
}

cros_kernel_install "$@"


code:
#!/usr/bin/env bash

# Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

KEYBLOCK="keyblock"
VBPRIVK="vbprivk"
VBPUBK="vbpubk"
ARCH="arch"
CMDLINE="cmdline"
BOOTLOADER="bootloader"
KERNEL="kernel"
ITS="its"
FIT="fit"
IMG="img"

usage() {
	printf 1>&2 '%s\n' "$executable [action] [kernel files|kernel image] [medium]"

	printf 1>&2 '\n%s\n' 'Actions:'
	printf 1>&2 '%s\n' '  pack - Pack kernel files to a medium-specific image'
	printf 1>&2 '%s\n' '  sign - Sign kernel image'
	printf 1>&2 '%s\n' '  verify - Very kernel image signatures'

	printf 1>&2 '\n%s\n' 'Medium:'
	printf 1>&2 '%s\n' '  usb - External USB storage'
	printf 1>&2 '%s\n' '  mmc - External SD card storage'
	printf 1>&2 '%s\n' '  emmc - Internal storage'

	printf 1>&2 '\n%s\n' 'Environment variables:'
	printf 1>&2 '%s\n' '  VBOOT_KEYS_PATH - Path to the vboot keys'
	printf 1>&2 '%s\n' '  VBOOT_TOOLS_PATH - Path to vboot tools'
}

pack() {
	local kernel_files_path=$1
	local medium=$2

	local arch_path="$kernel_files_path/$ARCH"
	local arch=$( cat "$arch_path" )
	local cmdline_path="$kernel_files_path/$CMDLINE-$medium"
	local bootloader_path="$kernel_files_path/$BOOTLOADER"
	local kernel_its_path="$kernel_files_path/$KERNEL.$ITS"
	local kernel_fit_path="$kernel_files_path/$KERNEL.$FIT"
	local kernel_image_path="$kernel_files_path/$KERNEL-$medium.$IMG"

	mkimage -f "$kernel_its_path" "$kernel_fit_path"
	futility vbutil_kernel --pack "$kernel_image_path" --version 1 --arch "$arch" --keyblock "$VBOOT_KEYS_PATH/kernel.$KEYBLOCK" --signprivate "$VBOOT_KEYS_PATH/kernel_data_key.$VBPRIVK" --config "$cmdline_path" --vmlinuz "$kernel_fit_path" --bootloader "$bootloader_path"

	printf '\n%s\n' "Packed kernel image $kernel_image_path"
}

sign() {
	local kernel_image_path=$1

	futility vbutil_kernel --repack "$kernel_image_path" --version 1 --keyblock "$VBOOT_KEYS_PATH/kernel.$KEYBLOCK" --signprivate "$VBOOT_KEYS_PATH/kernel_data_key.$VBPRIVK" --oldblob "$kernel_image_path"

	printf '\n%s\n' "Signed kernel image $kernel_image_path"
}

verify() {
	local kernel_image_path=$1

	futility vbutil_kernel --verify "$kernel_image_path" --signpubkey "$VBOOT_KEYS_PATH/kernel_subkey.$VBPUBK"

	printf '\n%s\n' "Verified kernel image $kernel_image_path"
}

requirements() {
	local requirement
	local requirement_path

	for requirement in "$@"
	do
		requirement_path=$( which "$requirement" || true )

		if [ -z "$requirement_path" ]
		then
			printf 1>&2 '%s\n' "Missing requirement: $requirement"
			exit 1
		fi
	done
}

setup() {
	root=$(readlink -f "$( dirname "$0" )" )
	executable=$( basename "$0" )

	if ! [ -z "$VBOOT_TOOLS_PATH" ]
	then
		PATH="$PATH:$VBOOT_TOOLS_PATH"
	fi

	if [ -z "$VBOOT_KEYS_PATH" ]
	then
		if ! [ -z "$VBOOT_TOOLS_PATH" ] && [ -d "$VBOOT_TOOLS_PATH/devkeys" ]
		then
			VBOOT_KEYS_PATH="$VBOOT_TOOLS_PATH/devkeys"
		else
			VBOOT_KEYS_PATH="/usr/share/vboot/devkeys"
		fi
	fi
}

cros_kernel_prepare() {
	local action=$1
	local kernel_files_path=$2
	local kernel_image_path=$2
	local medium=$3

	set -e

	setup "$@"

	if [ -z "$action" ] || [ -z "$kernel_files_path" ] || [ -z "$kernel_image_path" ]
	then
		usage
		exit 1
	fi

	case $action in
		"pack")
			if [ -z "$medium" ]
			then
				usage
				exit 1
			fi

			requirements "mkimage" "futility"
			pack "$kernel_files_path" "$medium"
			;;
		"sign")
			requirements "futility"
			sign "$kernel_image_path"
			;;
		"verify")
			requirements "futility"
			verify "$kernel_image_path"
			;;
		*)
			usage
			exit 1
			;;
	esac
}

cros_kernel_prepare "$@"


code:
#!/usr/bin/env bash

# Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

SYS_BLOCK_PATH="/sys/class/block"
DEV_PATH="/dev"
DEVICE="device"
VENDOR="vendor"
MODEL="model"
NAME="name"
KERNEL="kernel"
IMG="img"
KERNEL_MODULES="modules/lib"
KERNEL_PARTITION_INDEX=1
ROOTFS_PARTITION_INDEX=2

# Size in blocks (512 kiB)
GPT_SIZE=34
KERNEL_SIZE=16384

usage() {
	printf 1>&2 '%s\n' "$executable [action] [storage] [rootfs tarball|kernel files] [medium]"

	printf 1>&2 '\n%s\n' 'Actions:'
	printf 1>&2 '%s\n' '  partitions - Setup partitions on storage'
	printf 1>&2 '%s\n' '  rootfs - Install rootfs tarball to storage'
	printf 1>&2 '%s\n' '  kernel - Install kernel files to storage'

	usage_storage

	printf 1>&2 '\n%s\n' 'Environment variables:'
	printf 1>&2 '%s\n' '  KERNEL_PATH - Path to the kernel image'
	printf 1>&2 '%s\n' '  VBOOT_TOOLS_PATH - Path to vboot tools'
}

usage_storage() {
	printf 1>&2 '\n%s\n' 'Storage:'

	local nodes=$( ls "$SYS_BLOCK_PATH" )
	local node_path
	local name

	for node in $nodes
	do
		node_path="$DEV_PATH/$node"
		if ! [ -b "$node_path" ]
		then
			continue
		fi

		name=$( storage_name "$node_path" )
		if [ -z "$name" ]
		then
			continue
		fi

		printf 1>&2 '%s\n' "  $node_path - $name"
	done
}

storage_affect_confirm() {
	local storage_path=$1

	local name=$( storage_name "$storage_path" )
	local confirm

	printf '%s\n' 'This is going to affect the following storage:'
	printf '%s\n' "  $storage_path - $name"
	printf '%s' 'Press enter to confirm: '

	read confirm
}

storage_name() {
	local storage_path=$1

	local node=$( basename "$storage_path" )
	local vendor_path="$SYS_BLOCK_PATH/$node/$DEVICE/$VENDOR"
	local model_path="$SYS_BLOCK_PATH/$node/$DEVICE/$MODEL"
	local name_path="$SYS_BLOCK_PATH/$node/$DEVICE/$NAME"
	local vendor
	local name

	if [ -f "$model_path" ]
	then
		name=$( cat "$model_path" )
	elif [ -f "$name_path" ]
	then
		name=$( cat "$name_path" )
	else
		return 0
	fi

	name=$( printf '%s\n' "$name" | sed -e "s/^[[:space:]]*//;s/[[:space:]]*$//" )

	if [ -f "$vendor_path" ]
	then
		vendor=$( cat "$vendor_path" )
		vendor=$( printf '%s\n' "$vendor" | sed -e "s/^[[:space:]]*//;s/[[:space:]]*$//" )

		name="$vendor $name"
	fi

	printf '%s\n' "$name"
}

storage_partition_path() {
	local storage_path=$1
	local index=$2

	storage_partition_path="$storage_path$index"

	if ! [ -b "$storage_partition_path" ]
	then
		storage_partition_path="$storage_path""p$index"
	fi

	if ! [ -b "$storage_partition_path" ]
	then
		return 1
	fi

	printf '%s\n' "$storage_partition_path"
}

storage_partition_mount_path() {
	local storage_partition_path=$1

	local storage_partition_mount_path=$( udisksctl info -b "$storage_partition_path"  | grep "MountPoints" | sed "s/.*MountPoints:[[:space:]]*\(.*\)/\1/g" )

	printf '%s\n' "$storage_partition_mount_path"
}

partitions() {
	local storage_path=$1

	local storage_rootfs_path
	local partitions
	local start

	storage_affect_confirm "$storage_path"

	partitions=$( mount | grep -P "^$storage_path" | sed "s/^\([^[:space:]]*\).*/\1/g" )

	for partition in $partitions
	do
		# Partition may already be unmounted.
		udisksctl unmount -b "$partition" || true
	done

	( printf '%s\n' "g" ; printf '%s\n' "w" ) | fdisk "$storage_path"

	cgpt create "$storage_path"

	start=$GPT_SIZE
	size=$KERNEL_SIZE
	cgpt add -b "$start" -s "$size" -P 1 -S 1 -t kernel -l kernel "$storage_path"

	start=$(( $start + $size ))
	size=$( cgpt show "$storage_path" | grep "Sec GPT table" | sed "s/[[:space:]]*\([0-9]*\).*/\1/g" )
	size=$(( $size - $start ))
	cgpt add -b "$start" -s "$size" -t rootfs -l rootfs "$storage_path"

	blockdev --rereadpt "$storage_path" || partprobe "$storage_path"

	storage_rootfs_path=$( storage_partition_path "$storage_path" "$ROOTFS_PARTITION_INDEX" )

	mkfs.ext4 -F "$storage_rootfs_path"

	printf '\n%s\n' "Setup partitions on storage $storage_path"
}

rootfs() {
	local storage_path=$1
	local rootfs_tarball_path=$2

	local storage_rootfs_path=$( storage_partition_path "$storage_path" "$ROOTFS_PARTITION_INDEX" )
	local storage_rootfs_mount_path

	storage_affect_confirm "$storage_path"

	# Partition may already be mounted.
	udisksctl mount -b "$storage_rootfs_path" || true

	storage_rootfs_mount_path=$( storage_partition_mount_path "$storage_rootfs_path" )

	tar -xf "$rootfs_tarball_path" -ps -C "$storage_rootfs_mount_path"

	udisksctl unmount -b "$storage_rootfs_path"

	printf '\n%s\n' "Installed rootfs on storage $storage_path"
}

kernel() {
	local storage_path=$1
	local kernel_files_path=$2
	local medium=$3

	local storage_kernel_path=$( storage_partition_path "$storage_path" "$KERNEL_PARTITION_INDEX" )
	local storage_rootfs_path=$( storage_partition_path "$storage_path" "$ROOTFS_PARTITION_INDEX" )
	local kernel_image_path="$kernel_files_path/$KERNEL-$medium.$IMG"
	local kernel_modules_path="$kernel_files_path/$KERNEL_MODULES"
	local storage_rootfs_mount_path

	storage_affect_confirm "$storage_path"

	cat "$kernel_image_path" > "$storage_kernel_path"
	sync

	# Partition may already be mounted.
	udisksctl mount -b "$storage_rootfs_path" || true

	storage_rootfs_mount_path=$( storage_partition_mount_path "$storage_rootfs_path" )

	rsync -a --keep-dirlinks "$kernel_modules_path" "$storage_rootfs_mount_path/"
	sync

	udisksctl unmount -b "$storage_rootfs_path"

	printf '\n%s\n' "Installed kernel on storage $storage_path"
}

requirements() {
	local requirement
	local requirement_path

	for requirement in "$@"
	do
		requirement_path=$( which "$requirement" || true )

		if [ -z "$requirement_path" ]
		then
			printf 1>&2 '%s\n' "Missing requirement: $requirement"
			exit 1
		fi
	done
}

setup() {
	root=$(readlink -f "$( dirname "$0" )" )
	executable=$( basename "$0" )

	if [ -z "$KERNEL_PATH" ]
	then
		KERNEL_PATH=$root
	fi

	if ! [ -z "$VBOOT_TOOLS_PATH" ]
	then
		PATH="$PATH:$VBOOT_TOOLS_PATH"
	fi
}

cros_medium_setup() {
	local action=$1
	local storage_path=$2
	local rootfs_tarball_path=$3
	local kernel_files_path=$3
	local medium=$4

	set -e

	setup "$@"

	if [ -z "$action" ] || [ -z "$storage_path" ]
	then
		usage
		exit 1
	fi

	case $action in
		"partitions")
			requirements "udisksctl" "fdisk" "cgpt" "mkfs.ext4"
			partitions "$storage_path"
			;;
		"rootfs")
			if [ -z "$rootfs_tarball_path" ]
			then
				usage
				exit 1
			fi

			requirements "udisksctl" "tar"
			rootfs "$storage_path" "$rootfs_tarball_path"
			;;
		"kernel")
			if [ -z "$kernel_files_path" ] || [ -z "$medium" ]
			then
				usage
				exit 1
			fi

			requirements "udisksctl" "rsync"
			kernel "$storage_path" "$kernel_files_path" "$medium"
			;;
		*)
			usage
			exit 1
			;;
	esac
}

cros_medium_setup "$@"


path: projects/cros-scripts/install/install


code:
cros-scripts
cros-ec tools
flashrom-cros
hdctools
vboot tools
flashmap
mosys
vpd

path: projects/cros-tools/configs/projects


code:
#!/usr/bin/env bash

# Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

download() {
	project_action_projects "$action" "$project" "$@"
}

extract() {
	project_action_projects "$action" "$project" "$@"
}

update() {
	project_action_projects "$action" "$project" "$@"
}

build() {
	project_action_projects "$action" "$project" "$@"
}

install() {
	project_action_projects "$action" "$project" "$@"
}

release() {
	project_action_projects "$action" "$project" "$@"
}

clean() {
	project_action_projects "$action" "$project" "$@"
}

path: projects/cros-tools/cros-tools


path: projects/crossgcc/configs/install


code:
arm
i386

path: projects/crossgcc/configs/targets


code:
#!/usr/bin/env bash

# Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

arguments() {
	project_arguments_targets "$project" "$@"
}

usage() {
	project_usage_actions "$project" "prefix"
	project_usage_arguments "$project" "$@"
}

download() {
	local repository="coreboot"

	git_project_prepare "$project" "$repository" "$@"
}

download_check() {
	local repository="coreboot"

	git_project_prepare_check "$project" "$repository" "$@"
}

extract() {
	local arguments=$@

	local repository="coreboot"
	local tarball

	project_extract "$project" "$@"

	crossgcc_tarballs "$@" | while read tarball
	do
		local tarball_sources_path=$(crossgcc_tarball_sources_path "$tarball")
		local tarball_install_path=$(crossgcc_tarball_install_path "$tarball" "$@")
		local tarball_install_directory_path=$(dirname "$tarball_install_path")

		if [[ -f "$tarball_sources_path" ]] && ! [[ -f "$tarball_install_path" ]]
		then
			printf '%s\n' "Copying source archive $tarball for $project (with ${arguments:-no argument})"

			mkdir -p "$tarball_install_directory_path"

			file_verification_check "$tarball_sources_path"
			cp "$tarball_sources_path" "$tarball_install_path"
		fi
	done
}

extract_check() {
	local repository="coreboot"
	local tarball

	project_extract_check "$project" "$@"

	crossgcc_tarballs "$@" | while read tarball
	do
		local tarball_install_path=$(crossgcc_tarball_install_path "$tarball" "$@")

		test ! -f "$tarball_install_path"
	done
}

update() {
	local arguments=$@

	local repository="coreboot"
	local tarball

	project_update_git $project $repository $arguments

	crossgcc_tarballs "$@" | while read tarball
	do
		local tarball_sources_path=$(crossgcc_tarball_sources_path "$tarball")
		local tarball_install_path=$(crossgcc_tarball_install_path "$tarball" "$@")
		local tarball_install_directory_path=$(dirname "$tarball_install_path")

		if [[ -f $tarball_sources_path ]]
		then
			printf '%s\n' "Copying source archive $tarball for $project (with ${arguments:-no argument})"

			mkdir -p "$tarball_install_directory_path"

			file_verification_check "$tarball_sources_path"
			cp "$tarball_sources_path" "$tarball_install_path"
		fi
	done
}

update_check() {
	local repository="coreboot"
	local tarball

	project_update_check_git "$project" "$repository" "$@"

	crossgcc_tarballs "$@" | while read tarball
	do
		local tarball_sources_path=$(crossgcc_tarball_sources_path "$tarball" "$@")

		test ! -f "$tarball_sources_path"
	done
}

prefix() {
	local arch=$1

	local build_path=$(project_build_path "$project" "$@")

	case $arch in
		"arm")
			printf '\n%s\n' "$build_path/bin/arm-eabi-"
			;;
		"i386")
			printf '\n%s\n' "$build_path/bin/i386-elf-"
			;;
	esac
}

build() {
	local arch=$1

	local repository="coreboot"

	project_sources_directory_missing_empty_error "$project" "$repository" "$@"

	local sources_path=$(project_sources_path "$project" "$repository" "$@")
	local build_path=$(project_build_path "$project" "$@")

	if git_project_check "$repository"
	then
		git_project_checkout "$project" "$repository" "$@"
	fi

	mkdir -p "$build_path"

	local bootstrap_flag

	if ! crossgcc_same_major_version_test; then
		printf '\n%s' 'GCC major versions differ.  Bootstrapping' 1>&2
		printf '%s\n\n' ' to avoid potential build failure' 1>&2

		bootstrap_flag='-b'
	fi

	make -C "$sources_path" "$bootstrap_flag" CPUS="$TASKS" DEST="$build_path" "crossgcc-$arch"
}

build_check() {
	project_build_check "$project" "$@"
}

install() {
	project_install "$project" "$@"
}

install_check() {
	project_install_check "$project" "$@"
}

release() {
	local arguments=$@

	local repository="coreboot"
	local tarball

	project_release_install_archive "$project" "$TOOLS" "$@"

	project_release_sources_git "$project" "$repository" "$@"

	crossgcc_tarballs "$@" | while read tarball
	do
		local tarball_install_path=$(crossgcc_tarball_install_path "$tarball" "$@")
		local tarball_release_path=$(crossgcc_tarball_release_path "$tarball" "$@")
		local release_path=$(project_release_path "$project" "$SOURCES" "$@")

		mkdir -p "$release_path"

		if [[ -f "$tarball_install_path" ]] && ! [[ -f "$tarball_release_path" ]]
		then
			printf '%s\n' "Releasing source archive $tarball for $project (with ${arguments:-no argument})"

			cp "$tarball_install_path" "$tarball_release_path"
			file_verification_create "$tarball_release_path"
		fi
	done
}

release_check() {
	local repository="coreboot"
	local tarball

	project_release_install_archive_check "$project" "$TOOLS" "$@"

	project_release_check_sources_git "$project" "$repository" "$@"

	crossgcc_tarballs "$@" | while read tarball
	do
		local tarball_release_path=$(crossgcc_tarball_release_path "$tarball" "$@")

		test -f "$tarball_release_path"
	done
}

clean() {
	project_clean "$project" "$@"
}

path: projects/crossgcc/crossgcc


code:
#!/usr/bin/env bash

# Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

crossgcc_same_major_version_test() {
	local buildgcc_path="$sources_path/util/crossgcc/buildgcc"
	local sources_path="$(project_sources_path "$project" "$repository" "$@")"

	local crossgcc_version="$(sed -rne 's/^GCC_VERSION=(.*)$/\1/p' "$buildgcc_path")"
	local host_gcc_version="$(gcc -dumpversion)"

	if [[ "${host_gcc_version%%.*}" -eq "${crossgcc_version%%.*}" ]]; then

		return 0
	else
		return 1
	fi
}

crossgcc_tarballs() {
	local sources_path=$(project_sources_path "$project" "$repository" "$@")
	local install_path="$sources_path/util/crossgcc/tarballs/"
	local tarballs=$(ls "$sources_path/util/crossgcc/sum" | sed "s/.cksum$//")

	printf '%s\n' "$tarballs"
}

crossgcc_tarball_sources_path() {
	local tarball=$1

	local tarball_sources_path="$root/$SOURCES/$tarball"

	printf '%s\n' "$tarball_sources_path"
}

crossgcc_tarball_install_path() {
	local tarball=$1
	shift

	local sources_path=$(project_sources_path "$project" "$repository" "$@")
	local install_path="$sources_path/util/crossgcc/tarballs/"
	local tarball_install_path="$install_path/$tarball"

	printf '%s\n' "$tarball_install_path"
}

crossgcc_tarball_release_path() {
	local tarball=$1
	shift

	local release_path=$(project_release_path "$project" "$SOURCES" "$@")
	local tarball_release_path="$release_path/$tarball"

	printf '%s\n' "$tarball_release_path"
}

path: projects/crossgcc/crossgcc-helper


path: projects/dejavu-fonts/configs/install


path: projects/dejavu-fonts/configs/revision


code:
#!/usr/bin/env bash

# Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

arguments() {
	project_arguments_targets "$project" "$@"
}

usage() {
	project_usage_actions "$project"
	project_usage_arguments "$project" "$@"
}

download() {
	local repository="$project"

	project_download_git "$project" \
			     "$repository" \
			     'https://github.com/dejavu-fonts/dejavu-fonts.git' \
			     "$@"

	local sources_path="$(project_sources_path "$project" "$repository" "$@")"

	download_wrapper "$sources_path/resources" \
			 'https://www.unicode.org/Public/UNIDATA/UnicodeData.txt' \
			 'https://www.unicode.org/Public/UNIDATA/Blocks.txt'
}

download_check() {
	local repository="$project"

	project_download_check_git "$project" "$repository" "$@"
}

extract() {
	local repository="$project"

	project_extract "$project" "$@"
}

extract_check() {
	local repository="$project"

	project_extract_check "$project" "$@"
}

update() {
	local repository="$project"

	project_update_git "$project" "$repository" "$@"
}

update_check() {
	local repository="$project"

	project_update_check_git "$project" "$repository" "$@"
}

build() {
	local repository="$project"

	project_sources_directory_missing_empty_error "$project" "$repository" "$@"

	if git_project_check "$repository"; then
		git_project_checkout "$project" "$repository" "$@"
	fi

	local sources_path="$(project_sources_path "$project" "$repository" "$@")"
	local build_path="$(project_build_path "$project" "$@")"

	mkdir -p "$build_path"

	# Create a symlink to the orthography files provided by fontconfig
	ln -s "$root/$SOURCES/fontconfig/fc-lang" "$sources_path/resources/fc-lang"

	make -C "$sources_path" -j"$TASKS"
	cp "$sources_path/build"/[!.]*.ttf "$build_path"
	make -C "$sources_path" clean
}

build_check() {
	project_build_check "$project" "$@"
}

install() {
	project_install "$project" "$@"
}

install_check() {
	project_install_check "$project" "$@"
}

release() {
	local repository="$project"

	project_release_sources_git "$project" "$repository" "$@"
}

release_check() {
	local repository="$project"

	project_release_check_sources_git "$project" "$repository" "$@"
}

clean() {
	project_clean "$project" "$@"
}

path: projects/dejavu-fonts/dejavu-fonts


code:
From 9ac03500773a1cc69b198ce1c43770a7fc66da98 Mon Sep 17 00:00:00 2001
From: Andrew Robbins <contact@andrewrobbins.info>
Date: Tue, 5 Sep 2017 23:57:34 -0400
Subject: [PATCH] Preserve unicode source files thru `git clean -df`

UnicodeData.txt and Blocks.txt should be preserved after a
`git clean -df` to avoid needless refetching of these resources.
---
 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index dedd2b5..841e748 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@ build/
 dist/
 tmp/
 /src/*.sfd~
+resources/Blocks.txt
+resources/UnicodeData.txt
--
1.9.1


path: projects/depthcharge/configs/install


code: arm

path: projects/depthcharge/configs/nyan/arch


path: projects/depthcharge/configs/revision


code:
nyan
veyron

path: projects/depthcharge/configs/targets


code:
#!/usr/bin/env bash

# Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

arguments() {
	project_arguments_targets "$project" "$@"
}

usage() {
	project_usage_actions "$project"
	project_usage_arguments "$project" "$@"
}

download() {
	local repository=$project

	project_download_git "$project" "$repository" "https://chromium.googlesource.com/chromiumos/platform/depthcharge https://review.coreboot.org/depthcharge.git https://github.com/coreboot/depthcharge.git" "$@"
}

download_check() {
	local repository=$project

	project_download_check_git "$project" "$repository" "$@"
}

extract() {
	project_extract "$project" "$@"
}

extract_check() {
	project_extract_check "$project" "$@"
}

update() {
	local repository=$project

	project_update_git "$project" "$repository" "$@"
}

update_check() {
	local repository=$project

	project_update_check_git "$project" "$repository" "$@"
}

build() {
	local repository=$project

	project_sources_directory_missing_empty_error "$project" "$repository" "$@"

	if git_project_check $repository
	then
		git_project_checkout "$project" "$repository" "$@"
	fi

	local sources_path=$(project_sources_path "$project" "$repository" "$@")
	local build_path=$(project_build_path "$project" "$@")

	local libpayload_build_path=$(project_build_path "libpayload" "$project" "$@")
	local libpayload_build_install_path="$libpayload_build_path/install"
	local vboot_sources_path=$(project_sources_path "vboot" "vboot" "devices")

	local arch=$(depthcharge_arch "$@")
	local device=$(depthcharge_device "$@")

	project_action_arguments "checkout" "vboot" "devices"

	mkdir -p "$build_path"

	make -C "$sources_path" obj="$build_path" DOTCONFIG="$build_path/.config" BOARD="$device" "defconfig"
	make -C "$sources_path" obj="$build_path" DOTCONFIG="$build_path/.config" LIBPAYLOAD_DIR="$libpayload_build_install_path/libpayload" VB_SOURCE="$vboot_sources_path" -j$TASKS "depthcharge"
}

build_check() {
	project_build_check "$project" "$@"
}

release() {
	local repository=$project

	project_release_sources_git "$project" "$repository" "$@"
}

release_check() {
	local repository=$project

	project_release_check_sources_git "$project" "$repository" "$@"
}

clean() {
	project_clean "$project" "$@"
}

path: projects/depthcharge/depthcharge


code:
#!/usr/bin/env bash

# Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

ARCH="arch"

depthcharge_arch() {
	project_file_contents "$project" "$CONFIGS" "$ARCH" "$@"
}

depthcharge_device() {
	arguments_concat "_" "$@"
}

path: projects/depthcharge/depthcharge-helper


code:
From 3003a569ad63a35922984a8c7d1f079cc5cbd960 Mon Sep 17 00:00:00 2001
From: Paul Kocialkowski <contact@paulk.fr>
Date: Mon, 10 Aug 2015 20:30:14 +0200
Subject: [PATCH 1/4] fdt: nonvolatile-context-storage report to mkbp for EC NV
 storage

This allows old versions of crossystem to detect that it should use mosys to
access NV storage in case it is stored on the EC.

Change-Id: I78ed64c2002727432def0e132f572a1c5173fa5e
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
---
 src/vboot/crossystem/fdt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/vboot/crossystem/fdt.c b/src/vboot/crossystem/fdt.c
index c0b10c0..5cba178 100644
--- a/src/vboot/crossystem/fdt.c
+++ b/src/vboot/crossystem/fdt.c
@@ -51,7 +51,7 @@ static int install_crossystem_data(DeviceTreeFixup *fixup, DeviceTree *tree)
 		dt_add_string_prop(node, "nonvolatile-context-storage","nvram");
 	} else if (CONFIG_NV_STORAGE_CROS_EC) {
 		dt_add_string_prop(node,
-				"nonvolatile-context-storage", "cros-ec");
+				"nonvolatile-context-storage", "mkbp");
 	} else if (CONFIG_NV_STORAGE_DISK) {
 		dt_add_string_prop(node, "nonvolatile-context-storage", "disk");
 		dt_add_u32_prop(node, "nonvolatile-context-lba",
--
2.10.2


code:
From fc2f65e964fb9636db35749579c47dde15599f57 Mon Sep 17 00:00:00 2001
From: Paul Kocialkowski <contact@paulk.fr>
Date: Mon, 10 Aug 2015 20:24:50 +0200
Subject: [PATCH 2/4] Proper firmware index report for read-only boot path

When booting from a read-only boot path, the active firmware to report is RO.
This is detected with the lack of a vboot handoff pointer.

Change-Id: I3b1b5823b4dde7bc4185abe2e29f5d056ef9f09c
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
---
 src/vboot/crossystem/fdt.c | 2 +-
 src/vboot/firmware_id.c    | 6 +++++-
 src/vboot/firmware_id.h    | 1 +
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/vboot/crossystem/fdt.c b/src/vboot/crossystem/fdt.c
index 5cba178..45cad88 100644
--- a/src/vboot/crossystem/fdt.c
+++ b/src/vboot/crossystem/fdt.c
@@ -68,7 +68,7 @@ static int install_crossystem_data(DeviceTreeFixup *fixup, DeviceTree *tree)
 				nvstorage_flash_get_blob_size());
 	}

-	int fw_index = vdat->firmware_index;
+	int fw_index = get_active_fw_index(vdat);
 	const char *fwid;
 	int fwid_size;

diff --git a/src/vboot/firmware_id.c b/src/vboot/firmware_id.c
index 82acf91..d625251 100644
--- a/src/vboot/firmware_id.c
+++ b/src/vboot/firmware_id.c
@@ -31,6 +31,7 @@ static struct fwid {
 } fw_fmap_ops[] = {
 	{VDAT_RW_A, "RW_FWID_A", NULL, 0, "RW A: ID NOT FOUND"},
 	{VDAT_RW_B, "RW_FWID_B", NULL, 0, "RW B: ID NOT FOUND"},
+	{VDAT_RO, "RO_FRID", NULL, 0, "RO: ID NOT FOUND"},
 	{VDAT_RECOVERY, "RO_FRID", NULL, 0, "RO: ID NOT FOUND"},
 };

@@ -125,10 +126,13 @@ static VbSharedDataHeader *get_vdat(void)
 	return NULL;
 }

-static inline int get_active_fw_index(VbSharedDataHeader *vdat)
+int get_active_fw_index(VbSharedDataHeader *vdat)
 {
 	int fw_index = VDAT_UNKNOWN;

+	if (lib_sysinfo.vboot_handoff == NULL)
+		return VDAT_RO;
+
 	if (vdat)
 		fw_index = vdat->firmware_index;

diff --git a/src/vboot/firmware_id.h b/src/vboot/firmware_id.h
index 181b2a1..71be302 100644
--- a/src/vboot/firmware_id.h
+++ b/src/vboot/firmware_id.h
@@ -44,6 +44,7 @@ int get_rwb_fw_size(void);
  * Get firmware details for currently active fw type. It looks up vdat,
  * identifies fw_index and returns appropriate id and size for that index.
  */
+int get_active_fw_index(VbSharedDataHeader *vdat);
 const char *get_active_fw_id(void);
 int get_active_fw_size(void);

--
2.10.2


code:
From 1e634ac65fbdd43f35046e08b302d162e5d964d4 Mon Sep 17 00:00:00 2001
From: Paul Kocialkowski <contact@paulk.fr>
Date: Tue, 11 Aug 2015 11:22:54 +0200
Subject: [PATCH 3/4] vboot: Display callbacks for all screens

We don't want to use bitmaps stored in GBB since they recommend the use of non-
free software (Chrome OS), so this implements a text-based interface instead.

Change-Id: I4927846b385b9fdbb8d90b8dc1cd159472363baa
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
---
 src/vboot/callbacks/display.c | 182 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 166 insertions(+), 16 deletions(-)

diff --git a/src/vboot/callbacks/display.c b/src/vboot/callbacks/display.c
index bae8043..b4e9958 100644
--- a/src/vboot/callbacks/display.c
+++ b/src/vboot/callbacks/display.c
@@ -20,6 +20,7 @@
 #include <sysinfo.h>
 #include <vboot_api.h>
 #include <vboot_struct.h>
+#include <vboot_nvstorage.h>

 #include "base/cleanup_funcs.h"
 #include "drivers/video/coreboot_fb.h"
@@ -81,13 +82,15 @@ void print_on_center(const char *msg)
 	print_string(msg);
 }

-VbError_t VbExDisplayScreen(uint32_t screen_type, uint32_t locale)
+VbError_t VbExDisplayScreen(uint32_t screen_type, uint32_t locale,
+			    VbDisplayInfo *info)
 {
-	const char *msg = NULL;
-
-	if (vboot_draw_screen(screen_type, locale) == CBGFX_SUCCESS)
-		return VBERROR_SUCCESS;
-
+	unsigned int rows, cols;
+	const char *fw_id;
+	int fw_index;
+	void *blob = NULL;
+	int size = 0;
+	char *msg;
 	/*
 	 * Show the debug messages for development. It is a backup method
 	 * when GBB does not contain a full set of bitmaps.
@@ -98,31 +101,178 @@ VbError_t VbExDisplayScreen(uint32_t screen_type, uint32_t locale)
 		video_console_clear();
 		break;
 	case VB_SCREEN_DEVELOPER_WARNING:
-		msg = "developer mode warning";
+		video_console_clear();
+		video_console_set_cursor(0, 0);
+
+		if (info == NULL)
+			return VBERROR_SUCCESS;
+
+		print_string(
+			"Welcome to developer mode!\n\n"
+			"Useful key combinations:\n"
+			"- Ctrl + H: Hold developer mode\n"
+			"- Ctrl + D: Boot from default medium\n");
+
+		if (info->allow_usb)
+			print_string("- Ctrl + U: Boot from external medium\n");
+
+		if (info->allow_legacy)
+			print_string("- Ctrl + L: Boot from legacy payload\n");
+
+		print_string(
+			"- Ctrl + I: Show device information\n"
+			"- Space: Disable developer mode\n\n"
+			"This screen is shown for 3 seconds (if not held)."
+			"\n\n");
+
+		if (!info->signed_only)
+			print_string(
+				"Warning: this device will boot kernels"
+				" without verifying their signature!"
+				"\n");
+
+		if (info->allow_usb)
+			print_string(
+				"Warning: this device will boot from "
+				"external media!\n");
+
+		if (info->allow_legacy)
+			print_string(
+				"Warning: this device will boot legacy "
+				"payloads!\n");
+
+		if (!info->signed_only || info->allow_usb ||
+		    info->allow_legacy)
+			print_string("\n");
+
+		print_string("Default boot medium: ");
+
+		if (info->use_legacy)
+			print_string("legacy payload");
+		else if (info->use_usb)
+			print_string("external");
+		else
+			print_string("internal");
+
+		print_string("\n");
+
+		find_common_params(&blob, &size);
+
+		if (blob != NULL) {
+			VbSharedDataHeader *vdat = (VbSharedDataHeader *) blob;
+			fw_index = get_active_fw_index(vdat);
+			fw_id = get_fw_id(fw_index);
+
+			if (fw_id == NULL)
+				fw_id = "NOT FOUND";
+
+			print_string("Active firmware id: ");
+			print_string(fw_id);
+
+			switch (fw_index) {
+				case VDAT_RW_A:
+					print_string(" (RW A)\n");
+					break;
+				case VDAT_RW_B:
+					print_string(" (RW A)\n");
+					break;
+				case VDAT_RO:
+					print_string(" (RO)\n");
+					break;
+				default:
+					print_string(" (UNKNOWN)\n");
+					break;
+			}
+		}
 		break;
 	case VB_SCREEN_DEVELOPER_EGG:
-		msg = "easter egg";
+		video_console_clear();
+		print_on_center("Free as in Freedom!");
 		break;
 	case VB_SCREEN_RECOVERY_REMOVE:
-		msg = "remove inserted devices";
+		video_console_clear();
+		print_on_center(
+			"Please remove any external media before accessing "
+			"recovery screen.");
 		break;
 	case VB_SCREEN_RECOVERY_INSERT:
-		msg = "insert recovery image";
-		break;
 	case VB_SCREEN_RECOVERY_NO_GOOD:
-		msg = "insert image invalid";
+		video_console_clear();
+		print_string(
+			"Welcome to recovery mode!\n\n"
+			"Useful key combinations:\n"
+			"- Ctrl + D: Enable developer mode (if possible)\n\n");
+
+		if (screen_type == VB_SCREEN_RECOVERY_NO_GOOD)
+			print_on_center(
+				"Invalid recovery media, please instert a "
+				"valid one.");
+		else
+			print_on_center(
+				"Please insert an external recovery media.");
+		break;
+	case VB_SCREEN_RECOVERY_TO_DEV:
+		video_console_clear();
+		video_get_rows_cols(&rows, &cols);
+
+		video_console_set_cursor(0, 0);
+
+		print_string(
+			"Enabling developer mode will allow booting unsigned "
+			"kernels and booting from external media (when enabled "
+			"with crossystem).\n\n"
+			"Developer mode can be disabled via the developer mode "
+			"screen.");
+
+		msg = "Developer mode will be enabled.";
+		video_console_set_cursor((cols - strlen(msg)) / 2, rows / 2);
+		print_string(msg);
+
+		msg = "Press enter to confirm or escape to go back.";
+		video_console_set_cursor((cols - strlen(msg)) / 2,
+					 rows / 2 + 2);
+		print_string(msg);
+		break;
+	case VB_SCREEN_DEVELOPER_TO_NORM:
+		video_console_clear();
+		video_get_rows_cols(&rows, &cols);
+
+		video_console_set_cursor(0, 0);
+
+		print_string(
+			"Disabling developer mode will restrict boot to signed "
+			"kernels stored on internal memory only.\n\n"
+			"Developer mode can be enabled again via the recovery "
+			"mode screen.");
+
+		msg = "Developer mode will be disabled.";
+		video_console_set_cursor((cols - strlen(msg)) / 2, rows / 2);
+		print_string(msg);
+
+		msg = "Press enter to confirm or escape to go back.";
+		video_console_set_cursor((cols - strlen(msg)) / 2,
+					 rows / 2 + 2);
+		print_string(msg);
 		break;
 	case VB_SCREEN_WAIT:
-		msg = "wait for ec update";
+		video_console_clear();
+		print_on_center("Waiting for EC update...");
+		break;
+	case VB_SCREEN_TO_NORM_CONFIRMED:
+		video_console_clear();
+		print_on_center("Disabling developer mode.");
+		break;
+	case VB_SCREEN_OS_BROKEN:
+		video_console_clear();
+		print_on_center(
+			"Something went wrong and the device cannot boot.\n"
+			"Press Escape + Refresh + Power to access recovery.");
 		break;
 	default:
 		printf("Not a valid screen type: %d.\n", screen_type);
 		return VBERROR_INVALID_SCREEN_INDEX;
 	}

-	if (msg)
-		print_on_center(msg);
-
 	return VBERROR_SUCCESS;
 }

--
2.10.2


code:
From 925042a09afb9529b112eff2e4d56bf979ff32ec Mon Sep 17 00:00:00 2001
From: Paul Kocialkowski <contact@paulk.fr>
Date: Mon, 19 Dec 2016 14:54:40 +0100
Subject: [PATCH 4/4] mmc: Initialize clock variable in mmc_recalculate_clock

Initializing the variable before it is used (and set to a proper value)
avoids triggering a maybe uninitialized compiler warning.

Change-Id: I0f78e534919e892e23fbe6d38bba6e68c408b0c4
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
---
 src/drivers/storage/mmc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/drivers/storage/mmc.c b/src/drivers/storage/mmc.c
index b877548..54306a1 100644
--- a/src/drivers/storage/mmc.c
+++ b/src/drivers/storage/mmc.c
@@ -509,7 +509,7 @@ static void mmc_set_clock(MmcCtrlr *ctrlr, uint32_t clock)

 static void mmc_recalculate_clock(MmcMedia *media)
 {
-	uint32_t clock;
+	uint32_t clock = 0;

 	if (IS_SD(media)) {
 		if (media->caps & MMC_MODE_HS)
--
2.10.2


path: projects/flashmap/configs/install


path: projects/flashmap/configs/revision


code:
#!/usr/bin/env bash

# Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

download() {
	local repository=$project

	project_download_git "$project" "$repository" "https://chromium.googlesource.com/chromiumos/third_party/flashmap" "$@"
}

download_check() {
	local repository=$project

	project_download_check_git "$project" "$repository" "$@"
}

extract() {
	local repository=$project

	project_extract "$project" "$@"
}

extract_check() {
	local repository=$project

	project_extract_check "$project" "$@"
}

update() {
	local repository=$project

	project_update_git "$project" "$repository" "$@"
}

update_check() {
	local repository=$project

	project_update_check_git "$project" "$repository" "$@"
}

build() {
	local repository=$project

	project_sources_directory_missing_empty_error "$project" "$repository" "$@"

	local sources_path=$(project_sources_path "$project" "$repository" "$@")
	local build_path=$(project_build_path "$project" "$@")

	if git_project_check "$repository"
	then
		git_project_checkout "$project" "$repository" "$@"
	fi

	mkdir -p "$build_path"

	make -C "$sources_path" -j$TASKS

	cp -r "$sources_path/lib" "$build_path"

	make -C "$sources_path" "clean"
}

build_check() {
	project_build_check "$project" "$@"
}

release() {
	local repository=$project

	project_release_sources_git "$project" "$repository" "$@"
}

release_check() {
	local repository=$project

	project_release_check_sources_git "$project" "$repository" "$@"
}

clean() {
	project_clean "$project" "$@"
}

path: projects/flashmap/flashmap


path: projects/flashrom-cros/configs/install


path: projects/flashrom-cros/configs/revision


code:
#!/usr/bin/env bash

# Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

download() {
	local repository=$project

	project_download_git "$project" "$repository" "https://chromium.googlesource.com/chromiumos/third_party/flashrom" "$@"
}

download_check() {
	local repository=$project

	project_download_check_git "$project" "$repository" "$@"
}

extract() {
	local repository=$project

	project_extract "$project" "$@"
}

extract_check() {
	local repository=$project

	project_extract_check "$project" "$@"
}

update() {
	local repository=$project

	project_update_git "$project" "$repository" "$@"
}

update_check() {
	local repository=$project

	project_update_check_git "$project" "$repository" "$@"
}

build() {
	local repository=$project

	project_sources_directory_missing_empty_error "$project" "$repository" "$@"

	if git_project_check "$repository"
	then
		git_project_checkout "$project" "$repository" "$@"
	fi

	local sources_path=$(project_sources_path "$project" "$repository" "$@")
	local build_path=$(project_build_path "$project" "$@")

	mkdir -p "$build_path"

	make -C "$sources_path" CONFIG_SATAMV="no" NOWARNERROR="yes" NEED_PCI="yes" CONFIG_LINUX_SPI="yes" CONFIG_LINUX_I2C="yes" -j$TASKS

	cp "$sources_path/flashrom" "$build_path"

	make -C "$sources_path" CONFIG_SATAMV="no" NOWARNERROR="yes" NEED_PCI="yes" CONFIG_LINUX_SPI="yes" CONFIG_LINUX_I2C="yes" "clean"
}

build_check() {
	project_build_check "$project" "$@"
}

install() {
	project_install "$project" "$@"
}

install_check() {
	project_install_check "$project" "$@"
}

release() {
	local repository=$project

	project_release_install_archive "$project" "$TOOLS" "$@"

	project_release_sources_git "$project" "$repository" "$@"
}

release_check() {
	local repository=$project

	project_release_install_archive_check "$project" "$TOOLS" "$@"

	project_release_check_sources_git "$project" "$repository" "$@"
}

clean() {
	project_clean "$project" "$@"
}

path: projects/flashrom-cros/flashrom-cros


code:
From f721cdd46196a99dbcc41f0f7ecaf2ee17a147fe Mon Sep 17 00:00:00 2001
From: Paul Kocialkowski <contact@paulk.fr>
Date: Wed, 2 Nov 2016 19:16:50 +0100
Subject: [PATCH] programmer.h: Define ich_generation after enum declaration

This moves the ich_generation definition after the declaration of its
associated enum.

Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
---
 programmer.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/programmer.h b/programmer.h
index 191fb1e..86a695a 100644
--- a/programmer.h
+++ b/programmer.h
@@ -275,7 +275,6 @@ int board_flash_enable(const char *vendor, const char *part);
 /* chipset_enable.c */
 int chipset_flash_enable(void);
 int get_target_bus_from_chipset(enum chipbustype *target_bus);
-enum ich_chipset ich_generation;

 /* processor_enable.c */
 int processor_flash_enable(void);
@@ -603,6 +602,8 @@ enum ich_chipset {
 };

 #if CONFIG_INTERNAL == 1
+enum ich_chipset ich_generation;
+
 extern uint32_t ichspi_bbar;
 int ich_init_spi(struct pci_dev *dev, uint32_t base, void *rcrb,
 		 enum ich_chipset ich_generation);
--
2.10.2


code:
diff --git a/hwaccess.h b/hwaccess.h
index 0299ecb..a6732c2 100644
--- a/hwaccess.h
+++ b/hwaccess.h
@@ -24,11 +24,9 @@
 #ifndef __HWACCESS_H__
 #define __HWACCESS_H__ 1

-#if defined (__i386__) || defined (__x86_64__)
-#if defined(__GLIBC__)
+#if defined (__i386__) || defined (__x86_64__) || defined(__arm__)
 #include <sys/io.h>
 #endif
-#endif

 #if NEED_PCI == 1
 /*
@@ -72,7 +70,6 @@

 #if !defined (__FLASHROM_BIG_ENDIAN__) && !defined (__FLASHROM_LITTLE_ENDIAN__)
 /* Nonstandard libc-specific macros for determining endianness. */
-#if defined(__GLIBC__)
 #include <endian.h>
 #if BYTE_ORDER == LITTLE_ENDIAN
 #define __FLASHROM_LITTLE_ENDIAN__ 1
@@ -80,7 +77,6 @@
 #define __FLASHROM_BIG_ENDIAN__ 1
 #endif
 #endif
-#endif

 #if !defined (__FLASHROM_BIG_ENDIAN__) && !defined (__FLASHROM_LITTLE_ENDIAN__)
 #error Unable to determine endianness. Please add support for your arch or libc.


code:
diff --git a/linux_spi.c b/linux_spi.c
index 0199cf5..d56e8b0 100644
--- a/linux_spi.c
+++ b/linux_spi.c
@@ -20,11 +20,12 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include <sys/fcntl.h>
+#include <fcntl.h>
 #include <errno.h>
 #include <ctype.h>
 #include <unistd.h>
 #include <linux/spi/spidev.h>
+#include <linux/ioctl.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/types.h>


code:
diff --git a/fdtmap.h b/fdtmap.h
index 68eeef9..fe75291 100644
--- a/fdtmap.h
+++ b/fdtmap.h
@@ -36,6 +36,12 @@
 #ifndef FLASHMAP_LIB_FDTMAP_H__
 #define FLASHMAP_LIB_FDTMAP_H__

+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <fcntl.h>
+
 #define FDTMAP_SIGNATURE	"__FDTM__"

 struct romlayout;
diff --git a/fmap.h b/fmap.h
index b3c0a34..8aa82f7 100644
--- a/fmap.h
+++ b/fmap.h
@@ -38,7 +38,12 @@
 #ifndef FLASHMAP_LIB_FMAP_H__
 #define FLASHMAP_LIB_FMAP_H__

+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
 #include <inttypes.h>
+#include <fcntl.h>

 struct flashctx;


code:
diff --git a/Makefile b/Makefile
index a2f95cf..fcfce9b 100644
--- a/Makefile
+++ b/Makefile
@@ -35,7 +35,7 @@ PKG_CONFIG ?= pkg-config
 WARNERROR ?= yes

 ifneq ($(NOWARNERROR),yes)
-CFLAGS += -Werror
+CFLAGS +=
 endif

 ifeq ($(CONFIG_STATIC),yes)
@@ -354,7 +354,7 @@ CONFIG_BUSPIRATE_SPI ?= no
 CONFIG_RAIDEN_DEBUG_SPI ?= no

 # Enable Linux I2C for ChromeOS EC
-CONFIG_LINUX_I2C ?= no
+CONFIG_LINUX_I2C ?= yes

 CONFIG_LINUX_MTD ?= no

@@ -401,6 +401,7 @@ PROGRAMMER_OBJS += ichspi.o ich_descriptors.o
 else
 ifeq ($(ARCH),arm)
 PROGRAMMER_OBJS += cros_ec_i2c.o
+CONFIG_SATAMV := no
 endif
 NEED_PCI := yes
 endif
@@ -453,7 +454,7 @@ endif

 ifeq ($(CONFIG_FT2232_SPI), yes)
 FTDILIBS := $(shell $(PKG_CONFIG) --libs libftdi1 2>/dev/null ||	\
-		    $(PKG_CONFIG) --libs libftdi 2>/dev/null || echo "-lftdi -lusb")
+		    $(PKG_CONFIG) --libs libftdi 2>/dev/null || echo "-lftdi -lusb-1.0")
 FTDICFLAGS := $(shell $(PKG_CONFIG) --cflags libftdi1 2>/dev/null ||	\
 		      $(PKG_CONFIG) --cflags libftdi 2>/dev/null)
 # This is a totally ugly hack.
@@ -528,7 +529,7 @@ endif

 ifeq ($(CONFIG_DEDIPROG), yes)
 FEATURE_CFLAGS += -D'CONFIG_DEDIPROG=1'
-FEATURE_LIBS += -lusb
+FEATURE_LIBS += -lusb-1.0
 PROGRAMMER_OBJS += dediprog.o
 endif


path: projects/flashrom/configs/install


path: projects/flashrom/configs/revision


code:
generic
lenovobios

path: projects/flashrom/configs/targets


code:
#!/usr/bin/env bash

# Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

arguments() {
	project_arguments_targets "$project" "$@"
}

usage() {
	project_usage_actions "$project"
	project_usage_arguments "$project" "$@"
}

download() {
	local repository=$project

	project_download_git "$project" "$repository" 'https://review.coreboot.org/flashrom.git https://github.com/stefanct/flashrom.git' "$@"
}

download_check() {
	local repository=$project

	project_download_check_git "$project" "$repository" "$@"
}

extract() {
	local repository=$project

	project_extract "$project" "$@"
}

extract_check() {
	local repository=$project

	project_extract_check "$project" "$@"
}

update() {
	local repository=$project

	project_update_git "$project" "$repository" "$@"
}

update_check() {
	local repository=$project

	project_update_check_git "$project" "$repository" "$@"
}

build() {
	local repository=$project

	project_sources_directory_missing_empty_error "$project" "$repository" "$@"

	if git_project_check "$repository"
	then
		git_project_checkout "$project" "$repository" "$@"
	fi

	local sources_path=$(project_sources_path "$project" "$repository" "$@")
	local build_path=$(project_build_path "$project" "$@")

	mkdir -p "$build_path"

	make -C "$sources_path" -j$TASKS

	cp "$sources_path/flashrom" "$build_path"

	make -C "$sources_path" "clean"
}

build_check() {
	project_build_check "$project" "$@"
}

install() {
	project_install "$project" "$@"
}

install_check() {
	project_install_check "$project" "$@"
}

release() {
	local repository=$project

	project_release_install_archive "$project" "$TOOLS" "$@"

	project_release_sources_git "$project" "$repository" "$@"
}

release_check() {
	local repository=$project

	project_release_install_archive_check "$project" "$TOOLS" "$@"

	project_release_check_sources_git "$project" "$repository" "$@"
}

clean() {
	project_clean "$project" "$@"
}

path: projects/flashrom/flashrom