blob: 8069b405e804d9523a597e13cd1601a149a0b959 [file] [log] [blame]
Lee Leahyb0005132015-05-12 18:19:47 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2014 Google Inc.
Lee Leahy1d14b3e2015-05-12 18:23:27 -07005 * Copyright (C) 2015 Intel Corporation.
Lee Leahyb0005132015-05-12 18:19:47 -07006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Lee Leahyb0005132015-05-12 18:19:47 -070015 */
16
17#include <arch/io.h>
18#include <bootstate.h>
Rizwan Qureshie64f7942015-11-19 16:01:54 +053019#include <chip.h>
Lee Leahyb0005132015-05-12 18:19:47 -070020#include <console/console.h>
21#include <console/post_codes.h>
22#include <cpu/x86/smm.h>
23#include <reg_script.h>
24#include <spi-generic.h>
25#include <stdlib.h>
Rizwan Qureshie64f7942015-11-19 16:01:54 +053026#include <soc/lpc.h>
Lee Leahyb0005132015-05-12 18:19:47 -070027#include <soc/pci_devs.h>
Lee Leahy1d14b3e2015-05-12 18:23:27 -070028#include <soc/pcr.h>
29#include <soc/pm.h>
30#include <soc/pmc.h>
Lee Leahyb0005132015-05-12 18:19:47 -070031#include <soc/spi.h>
32#include <soc/systemagent.h>
Lee Leahy1d14b3e2015-05-12 18:23:27 -070033#include <device/pci.h>
Archana Patni7846e342015-11-11 01:29:23 +053034#include <chip.h>
35
36#define PCH_P2SB_EPMASK0 0xB0
37#define PCH_P2SB_EPMASK(mask_number) PCH_P2SB_EPMASK0 + (mask_number * 4)
38
39#define PCH_P2SB_E0 0xE0
40
41static void pch_configure_endpoints(device_t dev, int epmask_id, uint32_t mask)
42{
43 uint32_t reg32;
44
45 reg32 = pci_read_config32(dev, PCH_P2SB_EPMASK(epmask_id));
46 pci_write_config32(dev, PCH_P2SB_EPMASK(epmask_id), reg32 | mask);
47}
48
49static void pch_disable_heci(void)
50{
51 device_t dev;
52 u8 reg8;
53 uint32_t mask;
54
55 dev = PCH_DEV_P2SB;
56
57 /*
58 * if p2sb device 1f.1 is not present or hidden in devicetree
59 * p2sb device becomes NULL
60 */
61 if (!dev)
62 return;
63
64 /* unhide p2sb device */
65 pci_write_config8(dev, PCH_P2SB_E0 + 1, 0);
66
67 /* disable heci */
68 pcr_andthenor32(PID_PSF1, PSF_BASE_ADDRESS + PCH_PCR_PSFX_T0_SHDW_PCIEN,
69 ~0, PCH_PCR_PSFX_T0_SHDW_PCIEN_FUNDIS);
70
71 /* Remove the host accessing right to PSF register range. */
72 /* Set p2sb PCI offset EPMASK5 C4h [29, 28, 27, 26] to [1, 1, 1, 1] */
73 mask = (1 << 29) | (1 << 28) | (1 << 27) | (1 << 26);
74 pch_configure_endpoints(dev, 5, mask);
75
76 /* Set the "Endpoint Mask Lock!", P2SB PCI offset E2h bit[1] to 1. */
77 reg8 = pci_read_config8(dev, PCH_P2SB_E0 + 2);
78 pci_write_config8(dev, PCH_P2SB_E0 + 2, reg8 | (1 << 1));
79
80 /* hide p2sb device */
81 pci_write_config8(dev, PCH_P2SB_E0 + 1, 1);
82}
Lee Leahyb0005132015-05-12 18:19:47 -070083
Lee Leahy1d14b3e2015-05-12 18:23:27 -070084static void pch_finalize_script(void)
85{
86 device_t dev;
87 uint32_t reg32, hsfs;
88 void *spibar = get_spi_bar();
Lee Leahy1d14b3e2015-05-12 18:23:27 -070089 u16 tcobase;
90 u16 tcocnt;
91 uint8_t *pmcbase;
Archana Patni7846e342015-11-11 01:29:23 +053092 config_t *config;
Lee Leahy1d14b3e2015-05-12 18:23:27 -070093 u32 pmsyncreg;
Lee Leahyb0005132015-05-12 18:19:47 -070094
Lee Leahyb0005132015-05-12 18:19:47 -070095 /* Set SPI opcode menu */
Lee Leahy1d14b3e2015-05-12 18:23:27 -070096 write16(spibar + SPIBAR_PREOP, SPI_OPPREFIX);
97 write16(spibar + SPIBAR_OPTYPE, SPI_OPTYPE);
98 write32(spibar + SPIBAR_OPMENU_LOWER, SPI_OPMENU_LOWER);
99 write32(spibar + SPIBAR_OPMENU_UPPER, SPI_OPMENU_UPPER);
Lee Leahyb0005132015-05-12 18:19:47 -0700100 /* Lock SPIBAR */
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700101 hsfs = read32(spibar + SPIBAR_HSFS);
102 hsfs |= SPIBAR_HSFS_FLOCKDN;
103 write32(spibar + SPIBAR_HSFS, hsfs);
Lee Leahyb0005132015-05-12 18:19:47 -0700104
Rizwan Qureshie64f7942015-11-19 16:01:54 +0530105 /*TCO Lock down */
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700106 tcobase = pmc_tco_regs();
107 tcocnt = inw(tcobase + TCO1_CNT);
108 tcocnt |= TCO_LOCK;
109 outw(tcocnt, tcobase + TCO1_CNT);
Lee Leahyb0005132015-05-12 18:19:47 -0700110
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700111 /* Lock down ABASE and sleep stretching policy */
Rizwan Qureshie64f7942015-11-19 16:01:54 +0530112 dev = PCH_DEV_PMC;
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700113 reg32 = pci_read_config32(dev, GEN_PMCON_B);
114 reg32 |= (SLP_STR_POL_LOCK | ACPI_BASE_LOCK);
115 pci_write_config32(dev, GEN_PMCON_B, reg32);
Lee Leahyb0005132015-05-12 18:19:47 -0700116
117 /* PMSYNC */
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700118 pmcbase = pmc_mmio_regs();
119 pmsyncreg = read32(pmcbase + PMSYNC_TPR_CFG);
120 pmsyncreg |= PMSYNC_LOCK;
121 write32(pmcbase + PMSYNC_TPR_CFG, pmsyncreg);
Archana Patni7846e342015-11-11 01:29:23 +0530122
123 /* we should disable Heci1 based on the devicetree policy */
124 config = dev->chip_info;
125 if (config->HeciEnabled == 0)
126 pch_disable_heci();
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700127}
Lee Leahyb0005132015-05-12 18:19:47 -0700128
Rizwan Qureshie64f7942015-11-19 16:01:54 +0530129static void soc_lockdown(void)
130{
131 u8 reg8;
132 device_t dev;
133 const struct device *dev1 = dev_find_slot(0, PCH_DEVFN_LPC);
134 const struct soc_intel_skylake_config *config = dev1->chip_info;
135
136 /* Global SMI Lock */
137 if (config->LockDownConfigGlobalSmi == 0) {
138 dev = PCH_DEV_PMC;
139 reg8 = pci_read_config8(dev, GEN_PMCON_A);
140 reg8 |= SMI_LOCK;
141 pci_write_config8(dev, GEN_PMCON_A, reg8);
142 }
143
144 /* Bios Interface Lock */
145 if (config->LockDownConfigBiosInterface == 0) {
146 pci_write_config8(PCH_DEV_LPC, BIOS_CNTL,
147 pci_read_config8(PCH_DEV_LPC,
148 BIOS_CNTL) | LPC_BC_BILD);
149 /* Reads back for posted write to take effect */
150 pci_read_config8(PCH_DEV_LPC, BIOS_CNTL);
151 pci_write_config32(PCH_DEV_SPI, SPIBAR_BIOS_CNTL,
152 pci_read_config32(PCH_DEV_SPI,
153 SPIBAR_BIOS_CNTL) |
154 SPIBAR_BC_BILD);
155 /* Reads back for posted write to take effect */
156 pci_read_config32(PCH_DEV_SPI, SPIBAR_BIOS_CNTL);
157 /* GCS reg of DMI */
158 pcr_andthenor8(PID_DMI, R_PCH_PCR_DMI_GCS, 0xFF,
159 B_PCH_PCR_DMI_GCS_BILD);
160 }
161
162 /* Bios Lock */
163 if (config->LockDownConfigBiosLock == 0) {
164 pci_write_config8(PCH_DEV_LPC, BIOS_CNTL,
165 pci_read_config8(PCH_DEV_LPC,
166 BIOS_CNTL) | LPC_BC_LE);
167 pci_write_config8(PCH_DEV_SPI, BIOS_CNTL,
168 pci_read_config8(PCH_DEV_SPI,
169 BIOS_CNTL) | SPIBAR_BC_LE);
170 }
171
172 /* SPIEiss */
173 if (config->LockDownConfigSpiEiss == 0) {
174 pci_write_config8(PCH_DEV_LPC, BIOS_CNTL,
175 pci_read_config8(PCH_DEV_LPC,
176 BIOS_CNTL) | LPC_BC_EISS);
177 pci_write_config8(PCH_DEV_SPI, BIOS_CNTL,
178 pci_read_config8(PCH_DEV_SPI,
179 SPIBAR_BIOS_CNTL) |
180 SPIBAR_BC_EISS);
181 }
182}
183
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700184static void soc_finalize(void *unused)
Lee Leahyb0005132015-05-12 18:19:47 -0700185{
186 printk(BIOS_DEBUG, "Finalizing chipset.\n");
Rizwan Qureshie64f7942015-11-19 16:01:54 +0530187
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700188 pch_finalize_script();
Lee Leahyb0005132015-05-12 18:19:47 -0700189
Rizwan Qureshie64f7942015-11-19 16:01:54 +0530190 soc_lockdown();
191
Lee Leahyb0005132015-05-12 18:19:47 -0700192 /* Indicate finalize step with post code */
193 post_code(POST_OS_BOOT);
194}
195
Lee Leahy1d14b3e2015-05-12 18:23:27 -0700196BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, soc_finalize, NULL);
197BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, soc_finalize, NULL);