summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/cr50/board.c2
-rw-r--r--chip/g/build.mk1
-rw-r--r--chip/g/init_chip.h11
-rw-r--r--chip/g/jitter.c51
-rw-r--r--chip/g/registers.h6
5 files changed, 71 insertions, 0 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index 4640064c81..9ecc75c28a 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -9,6 +9,7 @@
#include "flash_config.h"
#include "gpio.h"
#include "hooks.h"
+#include "init_chip.h"
#include "registers.h"
#include "task.h"
#include "trng.h"
@@ -97,6 +98,7 @@ static void board_init(void)
init_timers();
init_interrupts();
init_trng();
+ init_jittery_clock(1); /* high-security mode */
init_runlevel(PERMISSION_MEDIUM);
/* TODO(crosbug.com/p/49959): For now, leave flash WP unlocked */
diff --git a/chip/g/build.mk b/chip/g/build.mk
index 09f2d9c536..8161966d4e 100644
--- a/chip/g/build.mk
+++ b/chip/g/build.mk
@@ -40,6 +40,7 @@ chip-$(CONFIG_DCRYPTO)+= dcrypto/sha256.o
chip-$(CONFIG_SPI_MASTER)+=spi_master.o
+chip-y+= jitter.o
chip-y+= pmu.o
chip-y+= trng.o
chip-$(CONFIG_USB_FW_UPDATE)+= usb_upgrade.o
diff --git a/chip/g/init_chip.h b/chip/g/init_chip.h
new file mode 100644
index 0000000000..60d156e533
--- /dev/null
+++ b/chip/g/init_chip.h
@@ -0,0 +1,11 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __CROS_EC_INIT_CHIP_H
+#define __CROS_EC_INIT_CHIP_H
+
+void init_jittery_clock(int highsec);
+
+#endif /* __CROS_EC_INIT_CHIP_H */
diff --git a/chip/g/jitter.c b/chip/g/jitter.c
new file mode 100644
index 0000000000..db1859b0d4
--- /dev/null
+++ b/chip/g/jitter.c
@@ -0,0 +1,51 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "common.h"
+#include "console.h"
+#include "init_chip.h"
+#include "registers.h"
+
+void init_jittery_clock(int highsec)
+{
+ unsigned trimfast = GR_FUSE(RC_JTR_OSC60_CC_TRIM);
+ unsigned trim48 = GR_FUSE(RC_JTR_OSC48_CC_TRIM);
+ unsigned delta = (trim48 - trimfast);
+ /* for metastability reasons, avoid clk_jtr ~= clk_timer, make
+ * a keepout region around 24MHz of about 0.75MHz, about 3/16 of the
+ * the delta from trimfast and trim48 */
+ unsigned skiplow = (trim48 << 4) - (delta * 6);
+ unsigned skiphigh = (trim48 << 4) + (delta * 6);
+ unsigned setting = trimfast << 4;
+ unsigned stepx16;
+ unsigned bankval;
+ int bank;
+
+ if (highsec)
+ stepx16 = 0xff - trimfast;
+ else
+ stepx16 = 2 * (trim48 - trimfast);
+
+ for (bank = 0; bank < 16; bank++) {
+ /* saturate at 0xff */
+ bankval = (setting > 0xfff) ? 0xff : (setting >> 4);
+
+ GR_XO_JTR_JITTERY_TRIM_BANK(bank) = bankval;
+
+ setting += stepx16;
+ if ((setting > skiplow) && (setting < skiphigh))
+ setting = skiphigh;
+ }
+
+ GWRITE_FIELD(XO, CLK_JTR_TRIM_CTRL, RC_COARSE_TRIM_SRC, 2);
+ GWRITE_FIELD(XO, CLK_JTR_TRIM_CTRL, RC_INITIAL_TRIM_PERIOD, 100);
+ GWRITE_FIELD(XO, CLK_JTR_TRIM_CTRL, RC_TRIM_EN, 1);
+ GREG32(XO, CLK_JTR_JITTERY_TRIM_EN) = 1;
+ GREG32(XO, CLK_JTR_SYNC_CONTENTS) = 0;
+
+ /* Writing any value locks things until the next hard reboot */
+ GREG32(XO, CFG_WR_EN) = 0;
+ GREG32(XO, JTR_CTRL_EN) = 0;
+}
diff --git a/chip/g/registers.h b/chip/g/registers.h
index 8ce2e90d7b..50caf87920 100644
--- a/chip/g/registers.h
+++ b/chip/g/registers.h
@@ -266,6 +266,9 @@ static inline int x_timehs_addr(unsigned int module, unsigned int timer,
#define GR_WATCHDOG_ITOP GR_WDOG_REG(GC_WATCHDOG_WDOGITOP_OFFSET)
/* Oscillator */
+#define GR_XO_REG(off) REG32(GC_XO0_BASE_ADDR + (off))
+#define GR_XO_JTR_JITTERY_TRIM_BANK(n) \
+ GR_XO_REG(GC_XO_CLK_JTR_JITTERY_TRIM_BANK0_OFFSET + (n) * 4)
#define GR_XO_OSC_CLKOUT REG32(GC_XO0_BASE_ADDR + GC_XO_OSC_CLKOUT_OFFSET)
#define GR_XO_OSC_ADC_CAL_FREQ2X REG32(GC_XO0_BASE_ADDR + GC_XO_OSC_ADC_CAL_FREQ2X_OFFSET)
#define GR_XO_OSC_ADC_CAL_FREQ2X_STAT REG32(GC_XO0_BASE_ADDR + GC_XO_OSC_ADC_CAL_FREQ2X_STAT_OFFSET)
@@ -292,6 +295,9 @@ static inline int x_timehs_addr(unsigned int module, unsigned int timer,
#define GR_XO_OSC_SETHOLD REG32(GC_XO0_BASE_ADDR + GC_XO_OSC_SETHOLD_OFFSET)
#define GR_XO_OSC_CLRHOLD REG32(GC_XO0_BASE_ADDR + GC_XO_OSC_CLRHOLD_OFFSET)
+/* Fuses (shadowed) */
+#define GR_FUSE(rname) (GREG32(FUSE, rname) & GFIELD_MASK(FUSE, rname, VAL))
+
/* Key manager */
#define GR_KEYMGR_AES_KEY(n) REG32(GREG32_ADDR(KEYMGR, AES_KEY0) + (n))
#define GR_KEYMGR_AES_CTR(n) REG32(GREG32_ADDR(KEYMGR, AES_CTR0) + (n))