diff options
author | Lee Leahy <leroy.p.leahy@intel.com> | 2015-05-12 18:23:27 -0700 |
---|---|---|
committer | Leroy P Leahy <leroy.p.leahy@intel.com> | 2015-07-16 17:24:48 +0200 |
commit | 1d14b3e926c15027f9272f1e80b8913fef8cf25d (patch) | |
tree | b3d89ad4bb1b0ea5ac05d1d7dc6cbf26ec93e6c3 /src/soc/intel/skylake/pcr.c | |
parent | b000513741d330947bb832a5835378e35bdfb394 (diff) |
soc/intel: Add Skylake SOC support
Add the files to support the Skylake SOC.
Matches chromium tree at 927026db
BRANCH=none
BUG=None
TEST=Build and run on a Skylake platform
Change-Id: I80248f7e47eaf13b52e3c7ff951eb1976edbaa15
Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com>
Reviewed-on: http://review.coreboot.org/10341
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/soc/intel/skylake/pcr.c')
-rw-r--r-- | src/soc/intel/skylake/pcr.c | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/src/soc/intel/skylake/pcr.c b/src/soc/intel/skylake/pcr.c new file mode 100644 index 0000000000..33d6cd12f5 --- /dev/null +++ b/src/soc/intel/skylake/pcr.c @@ -0,0 +1,162 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Intel Corporation. + * + * 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; version 2 of the License. + * + * 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. + */ + +#include <stdint.h> +#include <string.h> +#include <arch/io.h> +#include <device/device.h> +#include <device/pci.h> +#include <soc/pcr.h> +#include <soc/iomap.h> +#include <console/console.h> + +/* + * Read PCR register. (This is internal function) + * It returns PCR register and size in 1/2/4 bytes. + * The offset should not exceed 0xFFFF and must be aligned with size + * + * PCH_SBI_PID defines as 8 bit Port ID that will be used when sending + * transaction to sideband. + */ +static u8 pch_pcr_read(PCH_SBI_PID pid, u16 offset, u32 size, void *data) +{ + if ((offset & (size - 1)) != 0) { + printk(BIOS_DEBUG, + "PchPcrRead error. Invalid Offset: %x Size: %x", + offset, size); + return -1; + } + switch (size) { + case 4: + *(u32 *) data = read32(PCH_PCR_ADDRESS(pid, offset)); + break; + case 2: + *(u16 *) data = read16(PCH_PCR_ADDRESS(pid, offset)); + break; + case 1: + *(u8 *) data = read8(PCH_PCR_ADDRESS(pid, offset)); + break; + default: + break; + } + return 0; +} + +u8 pcr_read32(PCH_SBI_PID pid, u16 offset, u32 *outdata) +{ + return pch_pcr_read(pid, offset, sizeof(u32), (u32 *)outdata); +} + +u8 pcr_read16(PCH_SBI_PID pid, u16 offset, u16 *outdata) +{ + return pch_pcr_read(pid, offset, sizeof(u16), (u32 *)outdata); +} + +u8 pcr_read8(PCH_SBI_PID pid, u16 offset, u8 *outdata) +{ + return pch_pcr_read(pid, offset, sizeof(u8), (u32 *)outdata); +} + +/* + * Write PCR register. (This is internal function) + * It returns PCR register and size in 1/2/4 bytes. + * The offset should not exceed 0xFFFF and must be aligned with size + * + * PCH_SBI_PID defines as 8 bit Port ID that will be used when sending + * transaction to sideband. + */ +static u8 pch_pcr_write(PCH_SBI_PID pid, u16 offset, u32 size, u32 data) +{ + if ((offset & (size - 1)) != 0) { + printk(BIOS_DEBUG, + "PchPcrWrite error. Invalid Offset: %x Size: %x", + offset, size); + return -1; + } + /* Write the PCR register with provided data + * Then read back PCR register to prevent from back to back write. + */ + switch (size) { + case 4: + write32(PCH_PCR_ADDRESS(pid, offset), (u32) data); + break; + case 2: + write16(PCH_PCR_ADDRESS(pid, offset), (u16) data); + break; + case 1: + write8(PCH_PCR_ADDRESS(pid, offset), (u8) data); + break; + default: + break; + } + read32(PCH_PCR_ADDRESS(PID_LPC, R_PCH_PCR_LPC_GCFD)); + + return 0; +} + +u8 pcr_write32(PCH_SBI_PID pid, u16 offset, u32 indata) +{ + return pch_pcr_write(pid, offset, sizeof(u32), indata); +} + +u8 pcr_write16(PCH_SBI_PID pid, u16 offset, u16 indata) +{ + return pch_pcr_write(pid, offset, sizeof(u16), indata); +} + +u8 pcr_write8(PCH_SBI_PID pid, u16 offset, u8 indata) +{ + return pch_pcr_write(pid, offset, sizeof(u8), indata); +} + +/* + * Write PCR register. (This is internal function) + * It programs PCR register and size in 1/2/4 bytes. + * The offset should not exceed 0xFFFF and must be aligned with size + * + * PCH_SBI_PID defines as 8 bit Port ID that will be used when sending + * transaction to sideband. + */ +static u8 pcr_and_then_or(PCH_SBI_PID pid, u16 offset, u32 size, u32 anddata, + u32 ordata) +{ + u8 status; + u32 data32; + + status = pch_pcr_read(pid, offset, size, &data32); + if (status != 0) + return -1; + + data32 &= anddata; + data32 |= ordata; + + status = pch_pcr_write(pid, offset, size, data32); + return status; +} + +u8 pcr_andthenor32(PCH_SBI_PID pid, u16 offset, u32 anddata, u32 ordata) +{ + return pcr_and_then_or(pid, offset, sizeof(u32), anddata, ordata); +} + +u8 pcr_andthenor16(PCH_SBI_PID pid, u16 offset, u16 anddata, u16 ordata) +{ + return pcr_and_then_or(pid, offset, sizeof(u16), anddata, ordata); +} + +u8 pcr_andthenor8(PCH_SBI_PID pid, u16 offset, u8 anddata, u8 ordata) +{ + return pcr_and_then_or(pid, offset, sizeof(u8), anddata, ordata); +} |