blob: 9dfd1b8ba30dcfb21d3284574fdb8630e45660b2 [file] [log] [blame]
Philipp Deppenwiese8c678cf2018-08-10 16:15:14 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2018 Facebook, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <bootblock_common.h>
17#include <soc/soc.h>
18#include <soc/spi.h>
19#include <soc/uart.h>
20#include <soc/gpio.h>
Patrick Rudolphfb444b02018-11-07 15:24:37 +010021#include <spi_flash.h>
22#include <console/console.h>
23#include <fmap.h>
Philipp Deppenwiese8c678cf2018-08-10 16:15:14 -070024#include "mainboard.h"
25
26void bootblock_mainboard_early_init(void)
27{
28 /* Route UART0 to CON1 */
29 gpio_output(ELGON_GPIO_UART_SEL, 0);
30
31 /* Turn off error LED */
32 gpio_output(ELGON_GPIO_ERROR_LED, 0);
33
34 if (IS_ENABLED(CONFIG_BOOTBLOCK_CONSOLE)) {
35 if (!uart_is_enabled(CONFIG_UART_FOR_CONSOLE))
36 uart_setup(CONFIG_UART_FOR_CONSOLE, CONFIG_TTYS0_BAUD);
37 }
38}
39
40static void configure_spi_flash(void)
41{
42 /* The maximum SPI frequency for error free transmission is at 30 Mhz */
43 spi_init_custom(0, // bus
44 28000000, // speed Hz
45 0, // idle low disabled
46 0, // zero idle cycles between transfers
47 0, // MSB first
48 0, // Chip select 0
49 1); // assert is high
50
51 /* Route SPI to SoC */
52 gpio_output(ELGON_GPIO_SPI_MUX, 1);
53}
54
Patrick Rudolphfb444b02018-11-07 15:24:37 +010055/**
56 * Handle flash write protection.
57 * This code verifies the write-protection on each boot.
58 * Enabling the write protection does only run on the first boot.
59 * An error is fatal as it breaks the Chain Of Trust.
60 */
61static void protect_ro_rgn_spi_flash(void)
62{
63 const struct spi_flash *flash = boot_device_spi_flash();
64 const char *fmapname = "WP_RO";
65 struct region ro_rgn;
66
67 if (fmap_locate_area(fmapname, &ro_rgn)) {
68 printk(BIOS_ERR, "%s: No %s FMAP section.\n", __func__,
69 fmapname);
70 die("Can't verify flash protections!");
71 }
72
73 u8 reg8 = 0;
74 spi_flash_status(flash, &reg8);
75
76 /* Check if SRP0 is set and RO region is protected */
77 if (!(reg8 & 0x80) ||
78 spi_flash_is_write_protected(flash, &ro_rgn) != 1) {
79 printk(BIOS_WARNING, "%s: FMAP section %s is not write-protected\n",
80 __func__, fmapname);
81
82 /*
83 * Need to protect flash region :
84 * WP_RO read only and use /WP pin
85 * non-volatile programming
86 */
87 if (spi_flash_set_write_protected(flash, &ro_rgn, 1,
88 SPI_WRITE_PROTECTION_PIN) != 0)
89 die("Failed to write-protect WP_RO region!");
90 }
91 printk(BIOS_INFO, "%s: FMAP section %s is write-protected\n",
92 __func__, fmapname);
93}
94
Philipp Deppenwiese8c678cf2018-08-10 16:15:14 -070095void bootblock_mainboard_init(void)
96{
97 configure_spi_flash();
Patrick Rudolphfb444b02018-11-07 15:24:37 +010098 protect_ro_rgn_spi_flash();
Philipp Deppenwiese8c678cf2018-08-10 16:15:14 -070099}