diff options
-rw-r--r-- | board/cr50/board.c | 2 | ||||
-rw-r--r-- | chip/g/build.mk | 1 | ||||
-rw-r--r-- | chip/g/init_chip.h | 11 | ||||
-rw-r--r-- | chip/g/jitter.c | 51 | ||||
-rw-r--r-- | chip/g/registers.h | 6 |
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)) |