41 changes: 41 additions & 0 deletions src/commonlib/include/commonlib/tcpa_log_serialized.h
@@ -0,0 +1,41 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2018 Facebook Inc.
*
* 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.
*/

#ifndef __TCPA_LOG_SERIALIZED_H__
#define __TCPA_LOG_SERIALIZED_H__

#include <compiler.h>
#include <stdint.h>

#define MAX_TCPA_LOG_ENTRIES 50
#define TCPA_LOG_STRING_LENGTH 512
#define TCPA_FORMAT_HASH_LENGTH 128
#define TCPA_DIGEST_MAX_LENGTH 64
#define TCPA_PCR_HASH_NAME 256

struct tcpa_entry {
uint32_t pcr;
uint8_t digest[TCPA_DIGEST_MAX_LENGTH];
uint32_t digest_length;
char name[TCPA_PCR_HASH_NAME];
} __packed;

struct tcpa_table {
uint16_t max_entries;
uint16_t num_entries;
struct tcpa_entry entries[0]; /* Variable number of entries */
} __packed;

#endif
4 changes: 2 additions & 2 deletions src/commonlib/storage/mmc.c
Expand Up @@ -197,7 +197,7 @@ static int mmc_select_hs(struct storage_media *media)
return ret;
}

static int mmc_send_tunning_seq(struct sd_mmc_ctrlr *ctrlr, char *buffer)
static int mmc_send_tuning_seq(struct sd_mmc_ctrlr *ctrlr, char *buffer)
{
struct mmc_command cmd;
struct mmc_data data;
Expand Down Expand Up @@ -225,7 +225,7 @@ static int mmc_bus_tuning(struct storage_media *media)
/* Request the device send the tuning sequence up to 40 times */
ctrlr->tuning_start(ctrlr, 0);
for (index = 0; index < 40; index++) {
mmc_send_tunning_seq(ctrlr, buffer);
mmc_send_tuning_seq(ctrlr, buffer);
if (ctrlr->is_tuning_complete(ctrlr, &successful)) {
if (successful)
return 0;
Expand Down
12 changes: 8 additions & 4 deletions src/cpu/amd/agesa/family12/model_12_init.c
Expand Up @@ -27,14 +27,17 @@
#include <cpu/amd/multicore.h>
#include <cpu/amd/amdfam12.h>

#define MCI_STATUS 0x401
#define MCG_CAP 0x179
# define MCA_BANKS_MASK 0xff
#define MC0_STATUS 0x401

static void model_12_init(struct device *dev)
{
printk(BIOS_DEBUG, "Model 12 Init.\n");

u8 i;
msr_t msr;
int num_banks;

#if IS_ENABLED(CONFIG_LOGICAL_CPUS)
u32 siblings;
Expand All @@ -52,11 +55,12 @@ static void model_12_init(struct device *dev)
disable_cache();

/* zero the machine check error status registers */
msr = rdmsr(MCG_CAP);
num_banks = msr.lo & MCA_BANKS_MASK;
msr.lo = 0;
msr.hi = 0;
for (i = 0; i < 5; i++) {
wrmsr(MCI_STATUS + (i * 4), msr);
}
for (i = 0; i < num_banks; i++)
wrmsr(MC0_STATUS + (i * 4), msr);

enable_cache();

Expand Down
12 changes: 8 additions & 4 deletions src/cpu/amd/agesa/family14/model_14_init.c
Expand Up @@ -28,12 +28,15 @@
#include <arch/acpi.h>
#include <northbridge/amd/agesa/agesa_helper.h>

#define MCI_STATUS 0x401
#define MCG_CAP 0x179
# define MCA_BANKS_MASK 0xff
#define MC0_STATUS 0x401

static void model_14_init(struct device *dev)
{
u8 i;
msr_t msr;
int num_banks;
int msrno;
#if IS_ENABLED(CONFIG_LOGICAL_CPUS)
u32 siblings;
Expand Down Expand Up @@ -75,11 +78,12 @@ static void model_14_init(struct device *dev)
x86_enable_cache();

/* zero the machine check error status registers */
msr = rdmsr(MCG_CAP);
num_banks = msr.lo & MCA_BANKS_MASK;
msr.lo = 0;
msr.hi = 0;
for (i = 0; i < 6; i++) {
wrmsr(MCI_STATUS + (i * 4), msr);
}
for (i = 0; i < num_banks; i++)
wrmsr(MC0_STATUS + (i * 4), msr);

/* Enable the local CPU APICs */
setup_lapic();
Expand Down
8 changes: 5 additions & 3 deletions src/cpu/amd/agesa/family15tn/model_15_init.c
Expand Up @@ -35,6 +35,7 @@ static void model_15_init(struct device *dev)

u8 i;
msr_t msr;
int num_banks;
int msrno;
unsigned int cpu_idx;
#if IS_ENABLED(CONFIG_LOGICAL_CPUS)
Expand Down Expand Up @@ -72,11 +73,12 @@ static void model_15_init(struct device *dev)
x86_enable_cache();

/* zero the machine check error status registers */
msr = rdmsr(MCG_CAP);
num_banks = msr.lo & MCA_BANKS_MASK;
msr.lo = 0;
msr.hi = 0;
for (i = 0; i < 6; i++) {
wrmsr(MCI_STATUS + (i * 4), msr);
}
for (i = 0; i < num_banks; i++)
wrmsr(MC0_STATUS + (i * 4), msr);

/* Enable the local CPU APICs */
setup_lapic();
Expand Down
9 changes: 5 additions & 4 deletions src/cpu/amd/agesa/family16kb/model_16_init.c
Expand Up @@ -34,6 +34,7 @@ static void model_16_init(struct device *dev)

u8 i;
msr_t msr;
int num_banks;
int msrno;
#if IS_ENABLED(CONFIG_LOGICAL_CPUS)
u32 siblings;
Expand Down Expand Up @@ -70,11 +71,12 @@ static void model_16_init(struct device *dev)
x86_enable_cache();

/* zero the machine check error status registers */
msr = rdmsr(MCG_CAP);
num_banks = msr.lo & MCA_BANKS_MASK;
msr.lo = 0;
msr.hi = 0;
for (i = 0; i < 6; i++) {
wrmsr(MCI_STATUS + (i * 4), msr);
}
for (i = 0; i < num_banks; i++)
wrmsr(MC0_STATUS + (i * 4), msr);

/* Enable the local CPU APICs */
setup_lapic();
Expand All @@ -99,7 +101,6 @@ static void model_16_init(struct device *dev)
msr.hi &= ~(1 << (46 - 32));
wrmsr(NB_CFG_MSR, msr);


/* Write protect SMM space with SMMLOCK. */
msr = rdmsr(HWCR_MSR);
msr.lo |= (1 << 0);
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/amd/car/post_cache_as_ram.c
Expand Up @@ -31,7 +31,7 @@
#include "cpu/amd/car/disable_cache_as_ram.c"

// For set_sysinfo_in_ram()
#include "northbridge/amd/amdfam10/raminit.h"
#include <northbridge/amd/amdfam10/raminit.h>

#if CONFIG_RAMTOP <= 0x100000
#error "You need to set CONFIG_RAMTOP greater than 1M"
Expand Down
12 changes: 7 additions & 5 deletions src/cpu/amd/family_10h-family_15h/model_10xxx_init.c
Expand Up @@ -24,15 +24,15 @@
#include <cpu/x86/pae.h>
#include <pc80/mc146818rtc.h>
#include <cpu/x86/lapic.h>
#include "northbridge/amd/amdfam10/amdfam10.h"
#include <northbridge/amd/amdfam10/amdfam10.h>
#include <cpu/amd/model_10xxx_rev.h>
#include <cpu/cpu.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/mtrr.h>
#include <cpu/amd/multicore.h>
#include <cpu/amd/msr.h>

#define MCI_STATUS 0x401
#define MC0_STATUS 0x401

static inline uint8_t is_gt_rev_d(void)
{
Expand Down Expand Up @@ -62,6 +62,7 @@ static void model_10xxx_init(struct device *dev)
{
u8 i;
msr_t msr;
int num_banks;
struct node_core_id id;
#if IS_ENABLED(CONFIG_LOGICAL_CPUS)
u32 siblings;
Expand Down Expand Up @@ -109,11 +110,12 @@ static void model_10xxx_init(struct device *dev)
disable_cache();

/* zero the machine check error status registers */
msr = rdmsr(MCG_CAP);
num_banks = msr.lo & MCA_BANKS_MASK;
msr.lo = 0;
msr.hi = 0;
for (i = 0; i < 5; i++) {
wrmsr(MCI_STATUS + (i * 4), msr);
}
for (i = 0; i < num_banks; i++)
wrmsr(MC0_STATUS + (i * 4), msr);

enable_cache();

Expand Down
7 changes: 5 additions & 2 deletions src/cpu/amd/pi/00630F01/model_15_init.c
Expand Up @@ -35,6 +35,7 @@ static void model_15_init(struct device *dev)

u8 i;
msr_t msr;
int num_banks;
int msrno;
unsigned int cpu_idx;
#if IS_ENABLED(CONFIG_LOGICAL_CPUS)
Expand Down Expand Up @@ -69,10 +70,12 @@ static void model_15_init(struct device *dev)
x86_enable_cache();

/* zero the machine check error status registers */
msr = rdmsr(MCG_CAP);
num_banks = msr.lo & MCA_BANKS_MASK;
msr.lo = 0;
msr.hi = 0;
for (i = 0; i < 6; i++)
wrmsr(MCI_STATUS + (i * 4), msr);
for (i = 0; i < num_banks; i++)
wrmsr(MC0_STATUS + (i * 4), msr);

/* Enable the local CPU APICs */
setup_lapic();
Expand Down
8 changes: 5 additions & 3 deletions src/cpu/amd/pi/00660F01/model_15_init.c
Expand Up @@ -51,6 +51,7 @@ static void model_15_init(struct device *dev)

u8 i;
msr_t msr;
int num_banks;
int msrno;
#if IS_ENABLED(CONFIG_LOGICAL_CPUS)
u32 siblings;
Expand Down Expand Up @@ -81,11 +82,12 @@ static void model_15_init(struct device *dev)
x86_enable_cache();

/* zero the machine check error status registers */
msr = rdmsr(MCG_CAP);
num_banks = msr.lo & MCA_BANKS_MASK;
msr.lo = 0;
msr.hi = 0;
for (i = 0; i < 6; i++)
wrmsr(MCI_STATUS + (i * 4), msr);

for (i = 0; i < num_banks; i++)
wrmsr(MC0_STATUS + (i * 4), msr);

/* Enable the local CPU APICs */
setup_lapic();
Expand Down
9 changes: 5 additions & 4 deletions src/cpu/amd/pi/00730F01/model_16_init.c
Expand Up @@ -34,6 +34,7 @@ static void model_16_init(struct device *dev)

u8 i;
msr_t msr;
int num_banks;
int msrno;
#if IS_ENABLED(CONFIG_LOGICAL_CPUS)
u32 siblings;
Expand Down Expand Up @@ -66,11 +67,12 @@ static void model_16_init(struct device *dev)
x86_enable_cache();

/* zero the machine check error status registers */
msr = rdmsr(MCG_CAP);
num_banks = msr.lo & MCA_BANKS_MASK;
msr.lo = 0;
msr.hi = 0;
for (i = 0; i < 6; i++)
wrmsr(MCI_STATUS + (i * 4), msr);

for (i = 0; i < num_banks; i++)
wrmsr(MC0_STATUS + (i * 4), msr);

/* Enable the local CPU APICs */
setup_lapic();
Expand All @@ -95,7 +97,6 @@ static void model_16_init(struct device *dev)
msr.hi &= ~(1 << (46 - 32));
wrmsr(NB_CFG_MSR, msr);


/* Write protect SMM space with SMMLOCK. */
msr = rdmsr(HWCR_MSR);
msr.lo |= (1 << 0);
Expand Down
4 changes: 4 additions & 0 deletions src/cpu/intel/car/core2/cache_as_ram.S
Expand Up @@ -169,6 +169,10 @@ addrsize_set_high:
/* Setup the stack. */
movl $(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE), %eax
movl %eax, %esp
/* Align the stack 16 bytes */
andl $0xfffffff0, %esp
/* Account for pushing the BIST result */
subl $12, %esp

/* Restore the BIST result. */
movl %ebp, %eax
Expand Down
5 changes: 5 additions & 0 deletions src/cpu/intel/car/non-evict/cache_as_ram.S
Expand Up @@ -174,6 +174,11 @@ addrsize_set_high:
movl $(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE), %eax
movl %eax, %esp

/* Align the stack 16 bytes */
andl $0xfffffff0, %esp
/* Account for pushing the BIST result */
subl $12, %esp

/* Restore the BIST result. */
movl %ebp, %eax
movl %esp, %ebp
Expand Down
4 changes: 4 additions & 0 deletions src/cpu/intel/car/p4-netburst/cache_as_ram.S
Expand Up @@ -355,6 +355,10 @@ skip_cache_rom:
/* Setup the stack. */
movl $(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE), %eax
movl %eax, %esp
/* Align the stack 16 bytes */
andl $0xfffffff0, %esp
/* Account for pushing the BIST result */
subl $12, %esp

/* Restore the BIST result. */
movl %ebp, %eax
Expand Down
8 changes: 8 additions & 0 deletions src/cpu/intel/common/common.h
Expand Up @@ -17,4 +17,12 @@

void set_vmx(void);

/*
* Init CPPC block with MSRs for Intel Enhanced Speed Step Technology.
* Version 2 is suggested--this function's implementation of version 3
* may have room for improvment.
*/
struct cppc_config;
void cpu_init_cppc_config(struct cppc_config *config, u32 version);

#endif
180 changes: 180 additions & 0 deletions src/cpu/intel/common/common_init.c
Expand Up @@ -15,6 +15,7 @@
* GNU General Public License for more details.
*/

#include <arch/acpigen.h>
#include <console/console.h>
#include <cpu/x86/msr.h>
#include "common.h"
Expand Down Expand Up @@ -71,3 +72,182 @@ void set_vmx(void)
enable ? "enabled" : "disabled",
lock ? "locked" : "unlocked");
}

/*
* Init cppc_config in a way that's appropriate for Intel
* processors with Intel Enhanced Speed Step Technology.
* NOTE: version 2 is expected to be the typical use case.
* For now this function 'punts' on version 3 and just
* populates the additional fields with 'unsupported'.
*/
void cpu_init_cppc_config(struct cppc_config *config, u32 version)
{
acpi_addr_t msr = {
.space_id = ACPI_ADDRESS_SPACE_FIXED,
.bit_width = 8,
.bit_offset = 0,
{
.access_size = 4
},
.addrl = 0,
.addrh = 0,
};
static const acpi_addr_t unsupported = {
.space_id = ACPI_ADDRESS_SPACE_MEMORY,
.bit_width = 0,
.bit_offset = 0,
{
.resv = 0
},
.addrl = 0,
.addrh = 0,
};

config->version = version;

msr.addrl = MSR_IA32_HWP_CAPABILITIES;

/*
* Highest Performance:
* ResourceTemplate(){Register(FFixedHW, 0x08, 0x00, 0x771, 0x04,)},
*/
config->regs[CPPC_HIGHEST_PERF] = msr;

/*
* Nominal Performance -> Guaranteed Performance:
* ResourceTemplate(){Register(FFixedHW, 0x08, 0x08, 0x771, 0x04,)},
*/
msr.bit_offset = 8;
config->regs[CPPC_NOMINAL_PERF] = msr;

/*
* Lowest Nonlinear Performance -> Most Efficient Performance:
* ResourceTemplate(){Register(FFixedHW, 0x08, 0x10, 0x771, 0x04,)},
*/
msr.bit_offset = 16;
config->regs[CPPC_LOWEST_NONL_PERF] = msr;

/*
* Lowest Performance:
* ResourceTemplate(){Register(FFixedHW, 0x08, 0x18, 0x771, 0x04,)},
*/
msr.bit_offset = 24;
config->regs[CPPC_LOWEST_PERF] = msr;

/*
* Guaranteed Performance Register:
* ResourceTemplate(){Register(FFixedHW, 0x08, 0x08, 0x771, 0x04,)},
*/
msr.bit_offset = 8;
config->regs[CPPC_GUARANTEED_PERF] = msr;

msr.addrl = MSR_IA32_HWP_REQUEST;

/*
* Desired Performance Register:
* ResourceTemplate(){Register(FFixedHW, 0x08, 0x10, 0x774, 0x04,)},
*/
msr.bit_offset = 16;
config->regs[CPPC_DESIRED_PERF] = msr;

/*
* Minimum Performance Register:
* ResourceTemplate(){Register(FFixedHW, 0x08, 0x00, 0x774, 0x04,)},
*/
msr.bit_offset = 0;
config->regs[CPPC_MIN_PERF] = msr;

/*
* Maximum Performance Register:
* ResourceTemplate(){Register(FFixedHW, 0x08, 0x08, 0x774, 0x04,)},
*/
msr.bit_offset = 8;
config->regs[CPPC_MAX_PERF] = msr;

/*
* Performance Reduction Tolerance Register:
* ResourceTemplate(){Register(SystemMemory, 0x00, 0x00, 0x0,,)},
*/
config->regs[CPPC_PERF_REDUCE_TOLERANCE] = unsupported;

/*
* Time Window Register:
* ResourceTemplate(){Register(SystemMemory, 0x00, 0x00, 0x0,,)},
*/
config->regs[CPPC_TIME_WINDOW] = unsupported;

/*
* Counter Wraparound Time:
* ResourceTemplate(){Register(SystemMemory, 0x00, 0x00, 0x0,,)},
*/
config->regs[CPPC_COUNTER_WRAP] = unsupported;

msr.addrl = MSR_IA32_MPERF;

/*
* Reference Performance Counter Register:
* ResourceTemplate(){Register(FFixedHW, 0x40, 0x00, 0x0E7, 0x04,)},
*/
msr.bit_width = 64;
msr.bit_offset = 0;
config->regs[CPPC_REF_PERF_COUNTER] = msr;

msr.addrl = MSR_IA32_APERF;

/*
* Delivered Performance Counter Register:
* ResourceTemplate(){Register(FFixedHW, 0x40, 0x00, 0x0E8, 0x04,)},
*/
config->regs[CPPC_DELIVERED_PERF_COUNTER] = msr;

msr.addrl = MSR_IA32_HWP_STATUS;

/*
* Performance Limited Register:
* ResourceTemplate(){Register(FFixedHW, 0x01, 0x02, 0x777, 0x04,)},
*/
msr.bit_width = 1;
msr.bit_offset = 2;
config->regs[CPPC_PERF_LIMITED] = msr;

msr.addrl = MSR_IA32_PM_ENABLE;

/*
* CPPC Enable Register:
* ResourceTemplate(){Register(FFixedHW, 0x01, 0x00, 0x770, 0x04,)},
*/
msr.bit_offset = 0;
config->regs[CPPC_ENABLE] = msr;

if (version >= 2) {
/* Autonomous Selection Enable is populated below */

/* Autonomous Activity Window Register */
config->regs[CPPC_AUTO_ACTIVITY_WINDOW] = unsupported;

/* Energy Performance Preference Register */
config->regs[CPPC_PERF_PREF] = unsupported;

/* Reference Performance */
config->regs[CPPC_REF_PERF] = unsupported;

if (version >= 3) {
/* Lowest Frequency */
config->regs[CPPC_LOWEST_FREQ] = unsupported;
/* Nominal Frequency */
config->regs[CPPC_NOMINAL_FREQ] = unsupported;
}

/*
* Autonomous Selection Enable = 1
* This field is actually the first addition in version 2 but
* it's so unlike the others I'm populating it last.
*/
msr.space_id = ACPI_ADDRESS_SPACE_MEMORY;
msr.bit_width = 32;
msr.bit_offset = 0;
msr.access_size = 0;
msr.addrl = 1;
config->regs[CPPC_AUTO_SELECT] = msr;
}
}
2 changes: 1 addition & 1 deletion src/cpu/intel/fsp_model_206ax/finalize.c
Expand Up @@ -69,7 +69,7 @@ void intel_model_206ax_finalize_smm(void)
msr_set_bit(MSR_PP1_POWER_LIMIT, 31);
#endif

/* Lock TM interupts - route thermal events to all processors */
/* Lock TM interrupts - route thermal events to all processors */
msr_set_bit(MSR_MISC_PWR_MGMT, 22);

/* Lock memory configuration to protect SMM */
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/intel/haswell/finalize.c
Expand Up @@ -72,7 +72,7 @@ void intel_cpu_haswell_finalize_smm(void)
msr_set_bit(MSR_PP1_POWER_LIMIT, 31);
#endif

/* Lock TM interupts - route thermal events to all processors */
/* Lock TM interrupts - route thermal events to all processors */
msr_set_bit(MSR_MISC_PWR_MGMT, 22);

/* Lock memory configuration to protect SMM */
Expand Down
13 changes: 5 additions & 8 deletions src/cpu/intel/haswell/romstage.c
Expand Up @@ -37,13 +37,12 @@
#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
#include <ec/google/chromeec/ec.h>
#endif
#include "haswell.h"
#include "northbridge/intel/haswell/haswell.h"
#include "northbridge/intel/haswell/raminit.h"
#include "southbridge/intel/lynxpoint/pch.h"
#include "southbridge/intel/lynxpoint/me.h"
#include <security/tpm/tspi.h>
#include <northbridge/intel/haswell/haswell.h>
#include <northbridge/intel/haswell/raminit.h>
#include <southbridge/intel/lynxpoint/pch.h>
#include <southbridge/intel/lynxpoint/me.h>
#include <cpu/intel/romstage.h>
#include "haswell.h"

static inline void reset_system(void)
{
Expand Down Expand Up @@ -157,6 +156,4 @@ void romstage_common(const struct romstage_params *params)
romstage_handoff_init(wake_from_s3);

post_code(0x3f);
if (IS_ENABLED(CONFIG_TPM1) || IS_ENABLED(CONFIG_TPM2))
tpm_setup(wake_from_s3);
}
4 changes: 2 additions & 2 deletions src/cpu/intel/haswell/smmrelocate.c
Expand Up @@ -70,8 +70,8 @@ static inline void write_smrr(struct smm_relocation_params *relo_params)
{
printk(BIOS_DEBUG, "Writing SMRR. base = 0x%08x, mask=0x%08x\n",
relo_params->smrr_base.lo, relo_params->smrr_mask.lo);
wrmsr(SMRR_PHYS_BASE, relo_params->smrr_base);
wrmsr(SMRR_PHYS_MASK, relo_params->smrr_mask);
wrmsr(IA32_SMRR_PHYS_BASE, relo_params->smrr_base);
wrmsr(IA32_SMRR_PHYS_MASK, relo_params->smrr_mask);
}

static inline void write_emrr(struct smm_relocation_params *relo_params)
Expand Down
20 changes: 20 additions & 0 deletions src/cpu/intel/microcode/microcode.c
Expand Up @@ -113,6 +113,26 @@ void intel_microcode_load_unlocked(const void *microcode_patch)
#endif
}

uint32_t get_current_microcode_rev(void)
{
return read_microcode_rev();
}

uint32_t get_microcode_rev(const void *microcode)
{
return ((struct microcode *)microcode)->rev;
}

uint32_t get_microcode_size(const void *microcode)
{
return ((struct microcode *)microcode)->total_size;
}

uint32_t get_microcode_checksum(const void *microcode)
{
return ((struct microcode *)microcode)->cksum;
}

const void *intel_microcode_find(void)
{
const struct microcode *ucode_updates;
Expand Down
1 change: 1 addition & 0 deletions src/cpu/intel/model_1067x/Makefile.inc
@@ -1,5 +1,6 @@
ramstage-y += model_1067x_init.c
subdirs-y += ../../x86/name
subdirs-y += ../common
subdirs-$(CONFIG_SMM_TSEG) += ../smm/gen1

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_1067x/microcode.bin
2 changes: 1 addition & 1 deletion src/cpu/intel/model_2065x/finalize.c
Expand Up @@ -52,6 +52,6 @@ void intel_model_2065x_finalize_smm(void)
if (cpuid_ecx(1) & (1 << 25))
msr_set_bit(MSR_FEATURE_CONFIG, 0);

/* Lock TM interupts - route thermal events to all processors */
/* Lock TM interrupts - route thermal events to all processors */
msr_set_bit(MSR_MISC_PWR_MGMT, 22);
}
4 changes: 4 additions & 0 deletions src/cpu/intel/model_206ax/Makefile.inc
Expand Up @@ -5,6 +5,10 @@ subdirs-y += ../common

ramstage-y += acpi.c

ramstage-y += common.c
romstage-y += common.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += common.c

ramstage-y += tsc_freq.c
romstage-y += tsc_freq.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += tsc_freq.c
Expand Down
@@ -1,7 +1,8 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2014 Google Inc
* Copyright (C) 2009 coresystems GmbH
* Copyright (C) 2011 The Chromium OS Authors. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
Expand All @@ -12,16 +13,19 @@
* 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.
*
* clock.c: Functions for accessing clock and timer related registers
* Reference: ARM Architecture Reference Manual, ARMv8-A edition
*/

#include <stdint.h>
#include <types.h>
#include <cpu/x86/msr.h>
#include "model_206ax.h"

#include <arch/clock.h>
#define IA32_PLATFORM_ID 0x17

void set_cntfrq(uint32_t freq)
int get_platform_id(void)
{
__asm__ __volatile__("msr cntfrq_el0, %0" :: "r"((uint64_t)freq));
msr_t msr;

msr = rdmsr(IA32_PLATFORM_ID);
/* Read Platform Id Bits 52:50 */
return (msr.hi >> 18) & 0x7;
}
2 changes: 1 addition & 1 deletion src/cpu/intel/model_206ax/finalize.c
Expand Up @@ -70,7 +70,7 @@ void intel_model_206ax_finalize_smm(void)
msr_set_bit(MSR_PP1_POWER_LIMIT, 31);
#endif

/* Lock TM interupts - route thermal events to all processors */
/* Lock TM interrupts - route thermal events to all processors */
msr_set_bit(MSR_MISC_PWR_MGMT, 22);

/* Lock memory configuration to protect SMM */
Expand Down
1 change: 1 addition & 0 deletions src/cpu/intel/model_206ax/model_206ax.h
Expand Up @@ -123,5 +123,6 @@ void set_power_limits(u8 power_limit_1_time);
int cpu_config_tdp_levels(void);
void smm_relocate(void);
#endif
int get_platform_id(void);

#endif
31 changes: 27 additions & 4 deletions src/cpu/intel/model_206ax/model_206ax_init.c
Expand Up @@ -498,9 +498,33 @@ static void intel_cores_init(struct device *cpu)
}
}

static void model_206ax_init(struct device *cpu)
static void model_206ax_report(void)
{
static const char *const mode[] = {"NOT ", ""};
struct cpuid_result cpuidr;
char processor_name[49];
int vt, txt, aes;

/* Print processor name */
fill_processor_name(processor_name);
printk(BIOS_INFO, "CPU: %s.\n", processor_name);

/* Print platform ID */
printk(BIOS_INFO, "CPU: platform id %x\n", get_platform_id());

/* CPUID and features */
cpuidr = cpuid(1);
printk(BIOS_INFO, "CPU: cpuid(1) 0x%x\n", cpuidr.eax);
aes = (cpuidr.ecx & (1 << 25)) ? 1 : 0;
txt = (cpuidr.ecx & (1 << 6)) ? 1 : 0;
vt = (cpuidr.ecx & (1 << 5)) ? 1 : 0;
printk(BIOS_INFO, "CPU: AES %ssupported\n", mode[aes]);
printk(BIOS_INFO, "CPU: TXT %ssupported\n", mode[txt]);
printk(BIOS_INFO, "CPU: VT %ssupported\n", mode[vt]);
}

static void model_206ax_init(struct device *cpu)
{

/* Turn on caching if we haven't already */
x86_enable_cache();
Expand All @@ -510,9 +534,8 @@ static void model_206ax_init(struct device *cpu)
/* Clear out pending MCEs */
configure_mca();

/* Print processor name */
fill_processor_name(processor_name);
printk(BIOS_INFO, "CPU: %s.\n", processor_name);
/* Print infos */
model_206ax_report();

/* Setup MTRRs based on physical address size */
x86_setup_mtrrs_with_detect();
Expand Down
1 change: 1 addition & 0 deletions src/cpu/intel/model_6fx/Makefile.inc
@@ -1,5 +1,6 @@
ramstage-y += model_6fx_init.c
subdirs-y += ../../x86/name
subdirs-y += ../common
subdirs-$(CONFIG_SMM_TSEG) += ../smm/gen1

cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_6fx/microcode.bin
1 change: 1 addition & 0 deletions src/cpu/intel/smm/gen1/smi.h
Expand Up @@ -16,5 +16,6 @@ void southbridge_smm_init(void);
void southbridge_trigger_smi(void);
void southbridge_clear_smi_status(void);
u32 northbridge_get_tseg_base(void);
u32 northbridge_get_tseg_size(void);
int cpu_get_apic_id_map(int *apic_id_map);
void northbridge_write_smram(u8 smram);
58 changes: 48 additions & 10 deletions src/cpu/intel/smm/gen1/smmrelocate.c
Expand Up @@ -37,6 +37,10 @@
#define G_SMRAME (1 << 3)
#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))

#define IA32_FEATURE_CONTROL 0x3a
#define FEATURE_CONTROL_LOCK_BIT (1 << 0)
#define SMRR_ENABLE (1 << 3)

struct ied_header {
char signature[10];
u32 size;
Expand All @@ -57,12 +61,32 @@ struct smm_relocation_params {
static struct smm_relocation_params smm_reloc_params;
static void *default_smm_area = NULL;

static inline void write_smrr(struct smm_relocation_params *relo_params)
static void write_smrr(struct smm_relocation_params *relo_params)
{
struct cpuinfo_x86 c;

printk(BIOS_DEBUG, "Writing SMRR. base = 0x%08x, mask=0x%08x\n",
relo_params->smrr_base.lo, relo_params->smrr_mask.lo);
wrmsr(SMRR_PHYS_BASE, relo_params->smrr_base);
wrmsr(SMRR_PHYS_MASK, relo_params->smrr_mask);
/* Both model_6fx and model_1067x SMRR function slightly differently
from the rest. The MSR are at different location from the rest
and need to be explicitly enabled. */
get_fms(&c, cpuid_eax(1));
if (c.x86 == 6 && (c.x86_model == 0xf || c.x86_model == 0x17)) {
msr_t msr;
msr = rdmsr(IA32_FEATURE_CONTROL);
/* SMRR enabled and feature locked */
if (!((msr.lo & SMRR_ENABLE)
&& (msr.lo & FEATURE_CONTROL_LOCK_BIT))) {
printk(BIOS_WARNING,
"SMRR not enabled, skip writing SMRR...\n");
return;
}
wrmsr(MSR_SMRR_PHYS_BASE, relo_params->smrr_base);
wrmsr(MSR_SMRR_PHYS_MASK, relo_params->smrr_mask);
} else {
wrmsr(IA32_SMRR_PHYS_BASE, relo_params->smrr_base);
wrmsr(IA32_SMRR_PHYS_MASK, relo_params->smrr_mask);
}
}

/* The relocation work is actually performed in SMM context, but the code
Expand Down Expand Up @@ -123,7 +147,7 @@ static void fill_in_relocation_params(struct smm_relocation_params *params)
/* TSEG base is usually aligned down (to 8MiB). So we can't
derive the TSEG size from the distance to GTT but use the
configuration value instead. */
const u32 tseg_size = CONFIG_SMM_TSEG_SIZE;
const u32 tseg_size = northbridge_get_tseg_size();

/* The SMRAM available to the handler is 4MiB
since the IEDRAM lives at TSEGMB + 4MiB. */
Expand All @@ -136,12 +160,26 @@ static void fill_in_relocation_params(struct smm_relocation_params *params)
if (IS_ENABLED(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM))
params->smram_size -= CONFIG_SMM_RESERVED_SIZE;

/* SMRR has 32-bits of valid address aligned to 4KiB. */
params->smrr_base.lo = (params->smram_base & rmask) | MTRR_TYPE_WRBACK;
params->smrr_base.hi = 0;
params->smrr_mask.lo = (~(tseg_size - 1) & rmask)
| MTRR_PHYS_MASK_VALID;
params->smrr_mask.hi = 0;
if (IS_ALIGNED(tsegmb, tseg_size)) {
/* SMRR has 32-bits of valid address aligned to 4KiB. */
struct cpuinfo_x86 c;

/* On model_6fx and model_1067x bits [0:11] on smrr_base
are reserved */
get_fms(&c, cpuid_eax(1));
if (c.x86 == 6 && (c.x86_model == 0xf || c.x86_model == 0x17))
params->smrr_base.lo = (params->smram_base & rmask);
else
params->smrr_base.lo = (params->smram_base & rmask)
| MTRR_TYPE_WRBACK;
params->smrr_base.hi = 0;
params->smrr_mask.lo = (~(tseg_size - 1) & rmask)
| MTRR_PHYS_MASK_VALID;
params->smrr_mask.hi = 0;
} else {
printk(BIOS_WARNING,
"TSEG base not aligned with TSEG SIZE! Not setting SMRR\n");
}
}

static int install_relocation_handler(int *apic_id_map, int num_cpus,
Expand Down
2 changes: 0 additions & 2 deletions src/cpu/intel/socket_mPGA604/Kconfig
Expand Up @@ -6,8 +6,6 @@ if CPU_INTEL_SOCKET_MPGA604
config SOCKET_SPECIFIC_OPTIONS # dummy
def_bool y
select CPU_INTEL_MODEL_F2X
select CPU_INTEL_MODEL_F3X
select CPU_INTEL_MODEL_F4X
select MMX
select SSE
select UDELAY_TSC
Expand Down
2 changes: 0 additions & 2 deletions src/cpu/intel/socket_mPGA604/Makefile.inc
@@ -1,6 +1,4 @@
subdirs-y += ../model_f2x
subdirs-y += ../model_f3x
subdirs-y += ../model_f4x
subdirs-y += ../../x86/tsc
subdirs-y += ../../x86/mtrr
subdirs-y += ../../x86/lapic
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/x86/16bit/entry16.inc
Expand Up @@ -89,7 +89,7 @@ _start16bit:
* must be loaded at or above 0xffff0000 or below 0x100000.
*
* The linker scripts computes gdtptr16_offset by simply returning
* the low 16 bits. This means that the intial segment used
* the low 16 bits. This means that the initial segment used
* when start is called must be 64K aligned. This should not
* restrict the address as the ip address can be anything.
*
Expand Down
1 change: 1 addition & 0 deletions src/cpu/x86/lapic/Makefile.inc
Expand Up @@ -3,6 +3,7 @@ ramstage-y += lapic_cpu_init.c
ramstage-$(CONFIG_SMP) += secondary.S
romstage-$(CONFIG_UDELAY_LAPIC) += apic_timer.c
ramstage-$(CONFIG_UDELAY_LAPIC) += apic_timer.c
postcar-$(CONFIG_UDELAY_LAPIC) += apic_timer.c
bootblock-y += boot_cpu.c
verstage-y += boot_cpu.c
romstage-y += boot_cpu.c
Expand Down
21 changes: 12 additions & 9 deletions src/cpu/x86/lapic/apic_timer.c
Expand Up @@ -138,22 +138,25 @@ void udelay(u32 usecs)
} while ((start - value) < ticks);
}

#if IS_ENABLED(CONFIG_LAPIC_MONOTONIC_TIMER) && !defined(__PRE_RAM__)
#if IS_ENABLED(CONFIG_LAPIC_MONOTONIC_TIMER)
#include <timer.h>

static struct monotonic_counter {
int initialized;
struct mono_time time;
uint32_t last_value;
} mono_counter;
} mono_counter_g CAR_GLOBAL;

void timer_monotonic_get(struct mono_time *mt)
{
uint32_t current_tick;
uint32_t usecs_elapsed;
uint32_t timer_fsb;
struct monotonic_counter *mono_counter;

if (!mono_counter.initialized) {
mono_counter = car_get_var_ptr(&mono_counter_g);

if (!mono_counter->initialized) {
init_timer();
timer_fsb = get_timer_fsb();
/* An FSB frequency of 200Mhz provides a 20 second polling
Expand All @@ -163,22 +166,22 @@ void timer_monotonic_get(struct mono_time *mt)
printk(BIOS_WARNING,
"apic timer freq (%d) may be too fast.\n",
timer_fsb);
mono_counter.last_value = lapic_read(LAPIC_TMCCT);
mono_counter.initialized = 1;
mono_counter->last_value = lapic_read(LAPIC_TMCCT);
mono_counter->initialized = 1;
}

timer_fsb = get_timer_fsb();
current_tick = lapic_read(LAPIC_TMCCT);
/* Note that the APIC timer counts down. */
usecs_elapsed = (mono_counter.last_value - current_tick) / timer_fsb;
usecs_elapsed = (mono_counter->last_value - current_tick) / timer_fsb;

/* Update current time and tick values only if a full tick occurred. */
if (usecs_elapsed) {
mono_time_add_usecs(&mono_counter.time, usecs_elapsed);
mono_counter.last_value = current_tick;
mono_time_add_usecs(&mono_counter->time, usecs_elapsed);
mono_counter->last_value = current_tick;
}

/* Save result. */
*mt = mono_counter.time;
*mt = mono_counter->time;
}
#endif
6 changes: 5 additions & 1 deletion src/cpu/x86/mp_init.c
Expand Up @@ -297,6 +297,9 @@ static int save_bsp_msrs(char *start, int size)

fixed_mtrrs_hide_amd_rwdram();

/* Tell static analysis we know value is left unused. */
(void)msr_entry;

return msr_count;
}

Expand Down Expand Up @@ -404,6 +407,7 @@ static int allocate_cpu_devices(struct bus *cpu_bus, struct mp_params *p)
if (new == NULL) {
printk(BIOS_CRIT, "Could not allocate CPU device\n");
max_cpus--;
continue;
}
new->name = processor_name;
cpus[i].dev = new;
Expand Down Expand Up @@ -944,7 +948,7 @@ static void ap_wait_for_instruction(void)
continue;
}

/* Copy to local variable before signalling consumption. */
/* Copy to local variable before signaling consumption. */
memcpy(&lcb, cb, sizeof(lcb));
mfence();
store_callback(per_cpu_slot, NULL);
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/x86/sipi_vector.S
Expand Up @@ -17,7 +17,7 @@
#include <cpu/x86/cr.h>
#include <cpu/amd/mtrr.h>

/* The SIPI vector is responsible for initializing the APs in the sytem. It
/* The SIPI vector is responsible for initializing the APs in the system. It
* loads microcode, sets up MSRs, and enables caching before calling into
* C code. */

Expand Down
5 changes: 3 additions & 2 deletions src/cpu/x86/smm/smm_module_loader.c
Expand Up @@ -371,13 +371,14 @@ int smm_load_module(void *smram, size_t size, struct smm_loader_params *params)
base += alignment_size;
}

fxsave_size = 0;
fxsave_area = NULL;
if (IS_ENABLED(CONFIG_SSE)) {
fxsave_size = FXSAVE_SIZE * params->num_concurrent_stacks;
/* FXSAVE area below all the stacks stack. */
fxsave_area = params->stack_top;
fxsave_area -= total_stack_size + fxsave_size;
} else {
fxsave_size = 0;
fxsave_area = NULL;
}

/* Does the required amount of memory exceed the SMRAM region size? */
Expand Down
2 changes: 1 addition & 1 deletion src/device/cardbus_device.c
Expand Up @@ -75,7 +75,7 @@ static void cardbus_size_bridge_resource(struct device *dev, unsigned int index)
if (resource) {
min_size = resource->size;
/*
* Always allocate at least the miniumum size to a
* Always allocate at least the minimum size to a
* cardbus bridge in case a new card is plugged in.
*/
if (resource->size < min_size)
Expand Down
24 changes: 24 additions & 0 deletions src/device/device_const.c
Expand Up @@ -216,3 +216,27 @@ DEVTREE_CONST struct device *dev_find_slot_pnp(u16 port, u16 device)
}
return 0;
}

/**
* Given a device and previous match iterate through all the children.
*
* @param bus parent device's bus holding all the children
* @param prev_child previous child already traversed, if NULL start at
* children of parent bus.
* @return pointer to child or NULL when no more children
*/
DEVTREE_CONST struct device *dev_bus_each_child(const struct bus *parent,
DEVTREE_CONST struct device *prev_child)
{
DEVTREE_CONST struct device *dev;

if (parent == NULL)
return NULL;

if (prev_child == NULL)
dev = parent->children;
else
dev = prev_child->sibling;

return dev;
}
81 changes: 81 additions & 0 deletions src/device/dram/ddr3.c
Expand Up @@ -24,6 +24,9 @@
#include <device/device.h>
#include <device/dram/ddr3.h>
#include <string.h>
#include <memory_info.h>
#include <cbmem.h>
#include <smbios.h>

/*==============================================================================
* = DDR3 SPD decoding helpers
Expand Down Expand Up @@ -398,6 +401,8 @@ int spd_decode_ddr3(dimm_attr * dimm, spd_raw_data spd)
memcpy(dimm->part_number, &spd[128], 16);
printram(" Part number : %s\n", dimm->part_number);

memcpy(dimm->serial, &spd[SPD_DIMM_SERIAL_NUM], SPD_DIMM_SERIAL_LEN);

return ret;
}

Expand Down Expand Up @@ -520,6 +525,82 @@ int spd_xmp_decode_ddr3(dimm_attr *dimm,
return ret;
}


/**
* Fill cbmem with information for SMBIOS type 17.
*
* @param channel Corresponding channel of provided @info
* @param slot Corresponding slot of provided @info
* @param selected_freq The actual frequency the DRAM is running on
* @param info DIMM parameters read from SPD
*
* @return CB_SUCCESS if DIMM info was written
*/
enum cb_err spd_add_smbios17(const u8 channel, const u8 slot,
const u16 selected_freq,
const dimm_attr *info)
{
struct memory_info *mem_info;
struct dimm_info *dimm;

/*
* Allocate CBMEM area for DIMM information used to populate SMBIOS
* table 17
*/
mem_info = cbmem_find(CBMEM_ID_MEMINFO);
if (!mem_info) {
mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));

printk(BIOS_DEBUG, "CBMEM entry for DIMM info: 0x%p\n",
mem_info);
if (!mem_info)
return CB_ERR;

memset(mem_info, 0, sizeof(*mem_info));
}

dimm = &mem_info->dimm[mem_info->dimm_cnt];
if (info->size_mb) {
dimm->ddr_type = MEMORY_TYPE_DDR3;
dimm->ddr_frequency = selected_freq;
dimm->dimm_size = info->size_mb;
dimm->channel_num = channel;
dimm->rank_per_dimm = info->ranks;
dimm->dimm_num = slot;
memcpy(dimm->module_part_number, info->part_number, 16);
dimm->mod_id = info->manufacturer_id;

switch (info->dimm_type) {
case SPD_DIMM_TYPE_SO_DIMM:
dimm->mod_type = SPD_SODIMM;
break;
case SPD_DIMM_TYPE_72B_SO_CDIMM:
dimm->mod_type = SPD_72B_SO_CDIMM;
break;
case SPD_DIMM_TYPE_72B_SO_RDIMM:
dimm->mod_type = SPD_72B_SO_RDIMM;
break;
case SPD_DIMM_TYPE_UDIMM:
dimm->mod_type = SPD_UDIMM;
break;
case SPD_DIMM_TYPE_RDIMM:
dimm->mod_type = SPD_RDIMM;
break;
case SPD_DIMM_TYPE_UNDEFINED:
default:
dimm->mod_type = SPD_UNDEFINED;
break;
}

dimm->bus_width = MEMORY_BUS_WIDTH_64; // non-ECC only
memcpy(dimm->serial, info->serial,
MIN(sizeof(dimm->serial), sizeof(info->serial)));
mem_info->dimm_cnt++;
}

return CB_SUCCESS;
}

/*
* The information printed below has a more informational character, and is not
* necessarily tied in to RAM init debugging. Hence, we stop using printram(),
Expand Down
2 changes: 1 addition & 1 deletion src/device/oprom/x86emu/prim_ops.c
Expand Up @@ -68,7 +68,7 @@
*
* By inspection, one gets: cc = ab + r'(a + b)
*
* That represents alot of operations, but NO CHOICE....
* That represents a lot of operations, but NO CHOICE....
*
* Borrow Chain Calculation.
*
Expand Down
6 changes: 3 additions & 3 deletions src/device/oprom/yabel/mem.c
Expand Up @@ -365,7 +365,7 @@ my_wrb(u32 addr, u8 val)
unsigned long translated_addr = addr;
u8 translated = biosemu_dev_translate_address(IORESOURCE_MEM, &translated_addr);
if (translated != 0) {
//translation successfull, access VGA Memory (BAR or Legacy...)
//translation successful, access VGA Memory (BAR or Legacy...)
DEBUG_PRINTF_MEM("%s(%x, %x): access to VGA Memory\n",
__func__, addr, val);
//DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __func__, addr, translated_addr);
Expand All @@ -390,7 +390,7 @@ my_wrw(u32 addr, u16 val)
unsigned long translated_addr = addr;
u8 translated = biosemu_dev_translate_address(IORESOURCE_MEM, &translated_addr);
if (translated != 0) {
//translation successfull, access VGA Memory (BAR or Legacy...)
//translation successful, access VGA Memory (BAR or Legacy...)
DEBUG_PRINTF_MEM("%s(%x, %x): access to VGA Memory\n",
__func__, addr, val);
//DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __func__, addr, translated_addr);
Expand Down Expand Up @@ -435,7 +435,7 @@ my_wrl(u32 addr, u32 val)
unsigned long translated_addr = addr;
u8 translated = biosemu_dev_translate_address(IORESOURCE_MEM, &translated_addr);
if (translated != 0) {
//translation successfull, access VGA Memory (BAR or Legacy...)
//translation successful, access VGA Memory (BAR or Legacy...)
DEBUG_PRINTF_MEM("%s(%x, %x): access to VGA Memory\n",
__func__, addr, val);
//DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __func__, addr, translated_addr);
Expand Down
2 changes: 1 addition & 1 deletion src/device/oprom/yabel/vbe.c
Expand Up @@ -502,7 +502,7 @@ vbe_get_info(void)
vbe_get_ddc_info(&ddc_info);

#if 0
DEBUG_PRINTF_VBE("DDC: edid_tranfer_time: %d\n",
DEBUG_PRINTF_VBE("DDC: edid_transfer_time: %d\n",
ddc_info.edid_transfer_time);
DEBUG_PRINTF_VBE("DDC: ddc_level: %x\n", ddc_info.ddc_level);
DEBUG_PRINTF_VBE("DDC: EDID:\n");
Expand Down
1 change: 0 additions & 1 deletion src/device/pci_device.c
Expand Up @@ -249,7 +249,6 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index)
resource->flags = 0;
} else if (attr & PCI_BASE_ADDRESS_SPACE_IO) {
/* An I/O mapped base address. */
attr &= PCI_BASE_ADDRESS_IO_ATTR_MASK;
resource->flags |= IORESOURCE_IO;
/* I don't want to deal with 32bit I/O resources. */
resource->limit = 0xffff;
Expand Down
2 changes: 1 addition & 1 deletion src/device/pci_rom.c
Expand Up @@ -41,7 +41,7 @@ struct rom_header *pci_rom_probe(struct device *dev)
rom_header = cbfs_boot_map_optionrom(dev->vendor, dev->device);

u32 vendev = (dev->vendor << 16) | dev->device;
u32 mapped_vendev = vendev;
u32 mapped_vendev;

mapped_vendev = map_oprom_vendev(vendev);

Expand Down
81 changes: 42 additions & 39 deletions src/device/pnp_device.c
Expand Up @@ -7,6 +7,7 @@
* Copyright (C) 2005 Tyan
* (Written by Yinghai Lu <yhlu@tyan.com> for Tyan)
* Copyright (C) 2013 Nico Huber <nico.h@gmx.de>
* Copyright (C) 2018 Felix Held <felix-coreboot@felixheld.de>
*
* 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
Expand Down Expand Up @@ -117,9 +118,21 @@ void pnp_read_resources(struct device *dev)
static void pnp_set_resource(struct device *dev, struct resource *resource)
{
if (!(resource->flags & IORESOURCE_ASSIGNED)) {
printk(BIOS_ERR, "ERROR: %s %02lx %s size: 0x%010llx "
"not assigned\n", dev_path(dev), resource->index,
resource_type(resource), resource->size);
/* The PNP_MSC super IO registers have the IRQ flag set. If no
value is assigned in the devicetree, the corresponding
PNP_MSC register doesn't get written, which should be printed
as warning and not as error. */
if (resource->flags & IORESOURCE_IRQ &&
(resource->index != PNP_IDX_IRQ0) &&
(resource->index != PNP_IDX_IRQ1))
printk(BIOS_WARNING, "WARNING: %s %02lx %s size: "
"0x%010llx not assigned\n", dev_path(dev),
resource->index, resource_type(resource),
resource->size);
else
printk(BIOS_ERR, "ERROR: %s %02lx %s size: 0x%010llx "
"not assigned\n", dev_path(dev), resource->index,
resource_type(resource), resource->size);
return;
}

Expand Down Expand Up @@ -194,52 +207,42 @@ struct device_operations pnp_ops = {
static void pnp_get_ioresource(struct device *dev, u8 index, u16 mask)
{
struct resource *resource;
unsigned moving, gran, step;
unsigned int bit;

/* If none of the mask bits is set, the resource would occupy the whole
IO space leading to IO resource conflicts with the other devices */
if (!mask) {
printk(BIOS_ERR, "ERROR: device %s index %d has no mask.\n",
dev_path(dev), index);
return;
}

resource = new_resource(dev, index);

/* Initilize the resource. */
resource->limit = 0xffff;
resource->flags |= IORESOURCE_IO;

/* Get the resource size... */

moving = mask;
gran = 15;
step = 1 << gran;

/* Find the first bit that moves. */
while ((moving & step) == 0) {
gran--;
step >>= 1;
}

/* Now find the first bit that does not move. */
while ((moving & step) != 0) {
gran--;
step >>= 1;
}

/*
* Of the moving bits the last bit in the first group,
* tells us the size of this resource.
*/
if ((moving & step) == 0) {
gran++;
step <<= 1;
}

/* Set the resource size and alignment. */
resource->gran = gran;
resource->align = gran;
resource->limit = mask | (step - 1);
resource->size = 1 << gran;
/* Calculate IO region size which is determined by the first one from
the LSB of the mask. */
for (bit = 0; bit <= 15 && (mask & (1 << bit)) == 0; ++bit)
;

resource->gran = bit;
resource->align = bit;
resource->size = 1 << bit;

/* Calculate IO region address limit which is determined by the first
one from the MSB of the mask. */
for (bit = 15; bit != 0 && (mask & (1 << bit)) == 0; --bit)
;

resource->limit = (1 << (bit + 1)) - 1;

/* The block of ones in the mask is expected to be continuous.
If there is any zero inbetween the block of ones, it is ignored
in the calculation of the resource size and limit. */
if (mask != (resource->limit ^ (resource->size - 1)))
printk(BIOS_WARNING,
"WARNING: mask of device %s index %d is wrong.\n",
dev_path(dev), index);
}

static void get_resources(struct device *dev, struct pnp_info *info)
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/amd/agesa/def_callouts.c
Expand Up @@ -91,7 +91,7 @@ AGESA_STATUS agesa_Reset (UINT32 Func, UINTN Data, VOID *ConfigPtr)

//
// Perform the RESET based upon the ResetType. In case of
// WARM_RESET_WHENVER and COLD_RESET_WHENEVER, the request will go to
// WARM_RESET_WHENEVER and COLD_RESET_WHENEVER, the request will go to
// AmdResetManager. During the critical condition, where reset is required
// immediately, the reset will be invoked directly by writing 0x04 to port
// 0xCF9 (Reset Port).
Expand Down
13 changes: 12 additions & 1 deletion src/drivers/elog/elog.c
Expand Up @@ -670,7 +670,7 @@ static int elog_find_flash(void)
}

if (region_device_sz(rdev) < 4*KiB) {
printk(BIOS_WARNING, "ELOG: Needs a minium size of 4KiB: %zu\n",
printk(BIOS_WARNING, "ELOG: Needs a minimum size of 4KiB: %zu\n",
region_device_sz(rdev));
return -1;
}
Expand Down Expand Up @@ -933,6 +933,17 @@ int elog_add_event_wake(u8 source, u32 instance)
return elog_add_event_raw(ELOG_TYPE_WAKE_SOURCE, &wake, sizeof(wake));
}

int elog_add_extended_event(u8 type, u32 complement)
{
struct elog_event_extended_event event = {
.event_type = type,
.event_complement = complement
};
return elog_add_event_raw(ELOG_TYPE_EXTENDED_EVENT,
&event,
sizeof(event));
}

/* Make sure elog_init() runs at least once to log System Boot event. */
static void elog_bs_init(void *unused) { elog_init(); }
BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_ENTRY, elog_bs_init, NULL);
27 changes: 6 additions & 21 deletions src/drivers/generic/bayhub/bh720.c
Expand Up @@ -21,28 +21,11 @@
#include <device/pci.h>
#include <device/pci_ids.h>
#include "chip.h"
#include "bh720.h"

enum {
BH720_PROTECT = 0xd0,
BH720_PROTECT_LOCK_OFF = 0,
BH720_PROTECT_LOCK_ON = BIT(0),
BH720_PROTECT_OFF = 0,
BH720_PROTECT_ON = BIT(31),

BH720_LINK_CTRL = 0x90,
BH720_LINK_CTRL_L0_ENABLE = BIT(0),
BH720_LINK_CTRL_L1_ENABLE = BIT(1),
BH720_LINK_CTRL_CLKREQ = BIT(8),

BH720_MISC2 = 0xf0,
BH720_MISC2_ASPM_DISABLE = BIT(0),
BH720_MISC2_APSM_CLKREQ_L1 = BIT(7),
BH720_MISC2_APSM_PHY_L1 = BIT(10),
BH720_MISC2_APSM_MORE = BIT(12),

BH720_RTD3_L1 = 0x3e0,
BH720_RTD3_L1_DISABLE_L1 = BIT(28),
};
__attribute__((weak)) void board_bh720(struct device *dev)
{
}

static void bh720_init(struct device *dev)
{
Expand Down Expand Up @@ -71,6 +54,8 @@ static void bh720_init(struct device *dev)
printk(BIOS_INFO, "BayHub BH720: Power-saving enabled (link_ctrl=%#x)\n",
pci_read_config32(dev, BH720_LINK_CTRL));
}

board_bh720(dev);
}

static struct pci_operations pci_ops = {
Expand Down
54 changes: 54 additions & 0 deletions src/drivers/generic/bayhub/bh720.h
@@ -0,0 +1,54 @@
/*
* Driver for BayHub Technology BH720 PCI to eMMC 5.0 HS200 bridge
*
* This file is part of the coreboot project.
*
* Copyright 2018 Google LLC.
*
* 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.
*/

enum {
BH720_PROTECT = 0xd0,
BH720_PROTECT_LOCK_OFF = 0,
BH720_PROTECT_LOCK_ON = BIT(0),
BH720_PROTECT_OFF = 0,
BH720_PROTECT_ON = BIT(31),

BH720_LINK_CTRL = 0x90,
BH720_LINK_CTRL_L0_ENABLE = BIT(0),
BH720_LINK_CTRL_L1_ENABLE = BIT(1),
BH720_LINK_CTRL_CLKREQ = BIT(8),

BH720_MISC2 = 0xf0,
BH720_MISC2_ASPM_DISABLE = BIT(0),
BH720_MISC2_APSM_CLKREQ_L1 = BIT(7),
BH720_MISC2_APSM_PHY_L1 = BIT(10),
BH720_MISC2_APSM_MORE = BIT(12),

BH720_MEM_RW_DATA = 0x200,
BH720_MEM_RW_ADR = 0x204,
BH720_MEM_RW_READ = BIT(30),
BH720_MEM_RW_WRITE = BIT(31),
BH720_MEM_ACCESS_EN = 0x208,
BH720_PCR_DrvStrength_PLL = 0x304,
BH720_PCR_DATA_CMD_DRV_MAX = 7,
BH720_PCR_CLK_DRV_MAX = 7,
BH720_PCR_EMMC_SETTING = 0x308,
BH720_PCR_EMMC_SETTING_1_8V = BIT(4),

BH720_RTD3_L1 = 0x3e0,
BH720_RTD3_L1_DISABLE_L1 = BIT(28),

BH720_PCR_CSR = 0x3e4,
BH720_PCR_CSR_EMMC_MODE_SEL = BIT(22),
};

void board_bh720(struct device *dev);
10 changes: 6 additions & 4 deletions src/drivers/i2c/da7219/da7219.c
Expand Up @@ -77,10 +77,12 @@ static void da7219_fill_ssdt(struct device *dev)
acpi_dp_add_integer(aad, "dlg,c-mic-btn-thr", config->c_mic_btn_thr);
acpi_dp_add_integer(aad, "dlg,btn-avg", config->btn_avg);
acpi_dp_add_integer(aad, "dlg,adc-1bit-rpt", config->adc_1bit_rpt);
acpi_dp_add_integer(aad, "dlg,micbias-pulse-lvl",
config->micbias_pulse_lvl);
acpi_dp_add_integer(aad, "dlg,micbias-pulse-time",
config->micbias_pulse_time);
if (config->micbias_pulse_lvl > 0) {
acpi_dp_add_integer(aad, "dlg,micbias-pulse-lvl",
config->micbias_pulse_lvl);
acpi_dp_add_integer(aad, "dlg,micbias-pulse-time",
config->micbias_pulse_time);
}

/* DA7219 Properties */
dsd = acpi_dp_new_table("_DSD");
Expand Down
1 change: 1 addition & 0 deletions src/drivers/i2c/designware/Makefile.inc
Expand Up @@ -4,5 +4,6 @@ bootblock-y += dw_i2c.c
romstage-y += dw_i2c.c
verstage-y += dw_i2c.c
ramstage-y += dw_i2c.c
postcar-y += dw_i2c.c

endif
2 changes: 1 addition & 1 deletion src/drivers/i2c/designware/dw_i2c.c
Expand Up @@ -360,7 +360,7 @@ static int _dw_i2c_transfer(unsigned int bus, const struct i2c_msg *segments,
}

/* The assumption is that the host controller is disabled -- either
after running this function or from performing the intialization
after running this function or from performing the initialization
sequence in dw_i2c_init(). */

/* Set target slave address */
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/i2c/generic/chip.h
Expand Up @@ -35,7 +35,7 @@ struct drivers_i2c_generic_config {
struct acpi_gpio irq_gpio;

/*
* This flag will add a device propery which will indicate
* This flag will add a device property which will indicate
* to the OS that it should probe this device before adding it.
*
* This can be used to declare a device that may not exist on
Expand Down
11 changes: 7 additions & 4 deletions src/drivers/i2c/tpm/cr50.c
Expand Up @@ -181,6 +181,7 @@ static int cr50_i2c_write(struct tpm_chip *chip,
static int process_reset(struct tpm_chip *chip)
{
struct stopwatch sw;
int rv = 0;
uint8_t access;

/*
Expand All @@ -193,7 +194,6 @@ static int process_reset(struct tpm_chip *chip)
*/
stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_INIT_MS);
do {
int rv;
const uint8_t mask =
TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY;

Expand All @@ -214,9 +214,12 @@ static int process_reset(struct tpm_chip *chip)
return 0;
} while (!stopwatch_expired(&sw));

printk(BIOS_ERR,
"TPM failed to reset after %ld ms, status: %#x\n",
stopwatch_duration_msecs(&sw), access);
if (rv)
printk(BIOS_ERR, "Failed to read TPM\n");
else
printk(BIOS_ERR,
"TPM failed to reset after %ld ms, status: %#x\n",
stopwatch_duration_msecs(&sw), access);

return -1;
}
Expand Down
4 changes: 2 additions & 2 deletions src/drivers/i2c/ww_ring/ww_ring.c
Expand Up @@ -74,7 +74,7 @@
#define LP55231_RESET_VALUE 0xff

/*
* The controller has 192 bytes of SRAM for code/data, availabe as six 32 byte
* The controller has 192 bytes of SRAM for code/data, available as six 32 byte
* pages.
*/
#define LP55231_PROG_PAGE_SIZE 32
Expand Down Expand Up @@ -119,7 +119,7 @@ static int ledc_transfer(TiLp55231 *ledc, struct i2c_msg *segs,
while (max_attempts--) {
rv = i2c_transfer(ledc->i2c_bus, segs, seg_count);

/* Accessing reset regsiter is expected to fail. */
/* Accessing reset register is expected to fail. */
if (!rv || reset)
break;
}
Expand Down
12 changes: 1 addition & 11 deletions src/drivers/intel/fsp1_1/romstage.c
Expand Up @@ -37,7 +37,6 @@
#include <stage_cache.h>
#include <string.h>
#include <timestamp.h>
#include <security/tpm/tspi.h>
#include <vendorcode/google/chromeos/chromeos.h>

asmlinkage void *romstage_main(FSP_INFO_HEADER *fih)
Expand Down Expand Up @@ -129,7 +128,7 @@ void romstage_common(struct romstage_params *params)
params->pei_data->saved_data_size =
region_device_sz(&rdev);
params->pei_data->saved_data = rdev_mmap_full(&rdev);
/* Assum boot device is memory mapped. */
/* Assume boot device is memory mapped. */
assert(IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED));
} else if (params->pei_data->boot_mode == ACPI_S3) {
/* Waking from S3 and no cache. */
Expand Down Expand Up @@ -167,15 +166,6 @@ void romstage_common(struct romstage_params *params)
if (romstage_handoff_init(
params->power_state->prev_sleep_state == ACPI_S3) < 0)
hard_reset();

/*
* Initialize the TPM, unless the TPM was already initialized
* in verstage and used to verify romstage.
*/
if ((IS_ENABLED(CONFIG_TPM1) || IS_ENABLED(CONFIG_TPM2)) &&
!IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
tpm_setup(params->power_state->prev_sleep_state ==
ACPI_S3);
}

void after_cache_as_ram_stage(void)
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/intel/fsp2_0/debug.c
Expand Up @@ -36,7 +36,7 @@ void fsp_debug_before_memory_init(fsp_memory_init_fn memory_init,
if (IS_ENABLED(CONFIG_DISPLAY_UPD_DATA))
fspm_display_upd_values(fspm_old_upd, fspm_new_upd);

/* Display the call entry point and paramters */
/* Display the call entry point and parameters */
if (!IS_ENABLED(CONFIG_DISPLAY_FSP_CALLS_AND_STATUS))
return;
printk(BIOS_SPEW, "Calling FspMemoryInit: 0x%p\n", memory_init);
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/intel/fsp2_0/include/fsp/api.h
Expand Up @@ -107,7 +107,7 @@ void soc_update_memory_params_for_mma(FSP_M_CONFIG *memory_cfg,
*
* This function is responsible for loading and executing the notify code from
* the FSP-S binary. It expects that fsp_silicon_init() has already been called
* succesfully, and that the FSP-S binary is still loaded into memory.
* successfully, and that the FSP-S binary is still loaded into memory.
*/

#endif /* _FSP2_0_API_H_ */
10 changes: 8 additions & 2 deletions src/drivers/intel/gma/acpi/common.asl
Expand Up @@ -44,8 +44,11 @@
Store (And(Arg0, 7), DSEN)
}

/* Using Notify is the right way. But Windows doesn't handle
it well. So use both method in a way to avoid double action.
/*
* Decrement display brightness.
*
* Using Notify is the right way. But Windows doesn't handle
* it well. So use both method in a way to avoid double action.
*/
Method (DECB, 0, NotSerialized)
{
Expand All @@ -62,6 +65,9 @@
}
}

/*
* Increment display brightness.
*/
Method (INCB, 0, NotSerialized)
{
If (BRCT)
Expand Down
191 changes: 175 additions & 16 deletions src/drivers/intel/gma/acpi/configure_brightness_levels.asl
@@ -1,24 +1,183 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2015 Nico Huber <nico.huber@secunet.com>
* Copyright (C) 2018 Nico Huber <nico.h@gmx.de>
* Copyright (C) 2018 Patrick Rudolph
*
* 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.
*/

/*
* Pseudo device that contains methods to modify Opregion
* "Mailbox 3 BIOS to Driver Notification"
* The BIOS to Driver Notification mailbox is intended to support
* BIOS to Driver event notification or data storage for BIOS to
* Driver data synchronization purpose.
*/
Device (BOX3)
{
Name (_ADR, 0)

OperationRegion (OPRG, SystemMemory, ASLS, 0x2000)
Field (OPRG, DWordAcc, NoLock, Preserve)
{
// OpRegion Header
Offset (0x58),
MBOX, 32,

// Mailbox 3
Offset (0x300),
ARDY, 1, /* Offset 0 Driver readiness */
, 31,
ASLC, 32, /* Offset 4 ASLE interrupt command / status */
TCHE, 32, /* Offset 8 Technology enabled indicator */
ALSI, 32, /* Offset 12 Current ALS illuminance reading */
BCLP, 32, /* Offset 16 Backlight britness to set */
PFIT, 32, /* Offset 20 Panel fitting Request */
CBLV, 32, /* Offset 24 Brightness Current State */
}

/*
* Request back-light brightness change through mailbox 3
*
* @param Arg0 The brightness level to set in percent
* @Return Zero on success, Ones on failure
* Errors: * ASLS is zero
* * Mailbox 3 support not advertised
* * Driver not loaded or not ready
* * Driver reported an error during ASLE IRQ
*/
Method (XBCM, 1, NotSerialized)
{
If (LEqual(ASLS, Zero))
{
Return (Ones)
}
If (LEqual(And(MBOX, 0x4), Zero))
{
Return (Ones)
}

/* Always keep BCLP up to date, even if driver is not ready.
It requires a full 8-bit brightness value. 255 = 100% */
Store (Divide (Multiply (Arg0, 255), 100), Local1)
If (LGreater(Local1, 255)) {
Store (255, Local1)
}
/* also set valid bit */
Store (Or (Local1, 0x80000000), BCLP)

If (LEqual(ARDY, Zero))
{
Return (Ones)
}

/* Request back-light change */
Store (0x2, ASLC)
/* Trigger IRQ */
Store (0x1, ASLE)

Store (0x20, Local0)
While (LGreater(Local0, Zero))
{
Sleep (1)
If (LEqual(And(ShiftRight(ASLC, 12), 0x3), Zero))
{
Return (Zero)
}
Decrement (Local0)
}

Return (Ones)
}

/*
* Get current back-light brightness through mailbox 3
*
* @Return The current brightness or Ones on error
* Errors: * ASLS is zero
* * Mailbox 3 support not advertised
* * Driver not loaded or not ready
* * CBLV is not marked valid
*/
Method (XBQC, 0, NotSerialized)
{
If (LEqual(ASLS, Zero))
{
Return (Ones)
}
If (LEqual(And(MBOX, 0x4), Zero))
{
Return (Ones)
}
If (LEqual(ARDY, Zero))
{
Return (Ones)
}
If (LEqual(And (CBLV, 0x80000000), Zero))
{
Return (Ones)
}
Return (And (CBLV, 0xff))
}
}

/*
* Pseudo device that contains methods to operate on GTT memory
*/
Device (LEGA)
{
Name (_ADR, 0)

Method (XBCM, 1, NotSerialized)
{
Store (Divide (Multiply (Arg0, BCLM), 100), BCLV)
}

Method (XBQC, 0, NotSerialized)
{
/* Find value close to BCLV in BRIG (which must be ordered) */
Store (BCLV, Local0) // Current value
Store (BCLM, Local1) // For calculations
Store (2, Local2) // Loop index
While (LLess (Local2, Subtract (SizeOf (BRIG), 1))) {
Store (DeRefOf (Index (BRIG, Local2)), Local3)
/* Use same calculation as XBCM, to get exact matches */
Store (Divide (Multiply (Local3, Local1), 100), Local3)

If (LLessEqual (Local0, Local3)) {
Return (DeRefOf (Index (BRIG, Local2)))
}
Add (Local2, 1, Local2)
}
/* Didn't find greater/equal value: use the last */
Return (DeRefOf (Index (BRIG, Local2)))
}
}

Method (XBCM, 1, NotSerialized)
{
Store (Divide (Multiply (Arg0, BCLM), 100), BCLV)
If (LEqual(^BOX3.XBCM (Arg0), Ones))
{
^LEGA.XBCM (Arg0)
}
}

Method (XBQC, 0, NotSerialized)
{
/* Find value close to BCLV in BRIG (which must be ordered) */
Store (BCLV, Local0) // Current value
Store (BCLM, Local1) // For calculations
Store (2, Local2) // Loop index
While (LLess (Local2, Subtract (SizeOf (BRIG), 1))) {
Store (DeRefOf (Index (BRIG, Local2)), Local3)
/* Use same calculation as XBCM, to get exact matches */
Store (Divide (Multiply (Local3, Local1), 100), Local3)

If (LLessEqual (Local0, Local3)) {
Return (DeRefOf (Index (BRIG, Local2)))
}
Add (Local2, 1, Local2)
Store (^BOX3.XBQC (), Local0)
If (LEqual(Local0, Ones))
{
Store (^LEGA.XBQC (), Local0)
}
/* Didn't find greater/equal value: use the last */
Return (DeRefOf (Index (BRIG, Local2)))

Return (Local0)
}
6 changes: 5 additions & 1 deletion src/drivers/intel/gma/acpi/non-pch.asl
Expand Up @@ -22,7 +22,11 @@ Device (GFX0)
Field (GFXC, DWordAcc, NoLock, Preserve)
{
Offset (0x10),
BAR0, 64
BAR0, 64,
Offset (0xe4),
ASLE, 32,
Offset (0xfc),
ASLS, 32,
}

OperationRegion (GFRG, SystemMemory, And (BAR0, 0xfffffffffffffff0), 0x400000)
Expand Down
6 changes: 5 additions & 1 deletion src/drivers/intel/gma/acpi/pch.asl
Expand Up @@ -22,7 +22,11 @@ Device (GFX0)
Field (GFXC, DWordAcc, NoLock, Preserve)
{
Offset (0x10),
BAR0, 64
BAR0, 64,
Offset (0xe4),
ASLE, 32,
Offset (0xfc),
ASLS, 32,
}

OperationRegion (GFRG, SystemMemory, And (BAR0, 0xfffffffffffffff0), 0x400000)
Expand Down
6 changes: 3 additions & 3 deletions src/drivers/intel/gma/i915_reg.h
Expand Up @@ -609,7 +609,7 @@
#define LM_FIFO_WATERMARK 0x0000001F
#define MI_ARB_STATE 0x020e4 /* 915+ only */

/* Make render/texture TLB fetches lower priorty than associated data
/* Make render/texture TLB fetches lower priority than associated data
* fetches. This is not turned on by default
*/
#define MI_ARB_RENDER_TLB_LOW_PRIORITY (1 << 15)
Expand Down Expand Up @@ -1636,9 +1636,9 @@
#define BLM_PIPE_C (2 << 29) /* ivb + */
#define BLM_PIPE(pipe) ((pipe) << 29)
#define BLM_POLARITY_I965 (1 << 28) /* gen4 only */
#define BLM_PHASE_IN_INTERUPT_STATUS (1 << 26)
#define BLM_PHASE_IN_INTERRUPT_STATUS (1 << 26)
#define BLM_PHASE_IN_ENABLE (1 << 25)
#define BLM_PHASE_IN_INTERUPT_ENABL (1 << 24)
#define BLM_PHASE_IN_INTERRUPT_ENABL (1 << 24)
#define BLM_PHASE_IN_TIME_BASE_SHIFT (16)
#define BLM_PHASE_IN_TIME_BASE_MASK (0xff << 16)
#define BLM_PHASE_IN_COUNT_SHIFT (8)
Expand Down
1 change: 0 additions & 1 deletion src/drivers/intel/gma/intel_ddi.c
Expand Up @@ -29,7 +29,6 @@
#include <string.h>
#include <stdlib.h>
#include <device/device.h>
#include <device/device.h>
#include <device/pci_def.h>
#include <device/pci_ops.h>
#include <console/console.h>
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/intel/gma/opregion.c
Expand Up @@ -318,7 +318,7 @@ intel_gma_init_igd_opregion(igd_opregion_t *opregion)
opregion->header.size = sizeof(igd_opregion_t) / 1024;

/*
* Left-shift version field to accomodate Intel Windows driver quirk
* Left-shift version field to accommodate Intel Windows driver quirk
* when not using a VBIOS.
* Required for Legacy boot + NGI, UEFI + NGI, and UEFI + GOP driver.
*
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/intel/wifi/Kconfig
Expand Up @@ -31,7 +31,7 @@ config GEO_SAR_ENABLE
depends on USE_SAR

config WIFI_SAR_CBFS
bool
bool "Enable SAR table addition to CBFS"
default n
depends on USE_SAR
help
Expand Down
37 changes: 0 additions & 37 deletions src/drivers/intel/wifi/acpi/wrdd.asl

This file was deleted.

2 changes: 1 addition & 1 deletion src/drivers/intel/wifi/wifi.c
Expand Up @@ -198,7 +198,7 @@ static void intel_wifi_fill_ssdt(struct device *dev)
const char *path = acpi_device_path(dev->bus->dev);
u32 address;

if (!path)
if (!path || !dev->enabled)
return;

/* Device */
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/maxim/max77802/max77802.h
Expand Up @@ -227,7 +227,7 @@ enum {

/*
* MAX77802_REG_PMIC_BBAT set to
* Back up batery charger on and
* Back up battery charger on and
* limit voltage setting to 3.5v
*/
#define MAX77802_BBCHOSTEN (1 << 0)
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/net/chip.h
Expand Up @@ -19,7 +19,7 @@ struct drivers_net_config {
unsigned wake; /* Wake pin for ACPI _PRW */
/*
* There maybe many NIC cards in a system.
* This paramter is for driver to identify what
* This parameter is for driver to identify what
* the device number is and the valid range is [1-10].
*/
uint8_t device_index;
Expand Down
1 change: 0 additions & 1 deletion src/drivers/pc80/pc/i8254.c
Expand Up @@ -15,7 +15,6 @@

#include <arch/io.h>
#include <pc80/i8254.h>
#include <console/console.h>

/* Initialize i8254 timers */

Expand Down
1 change: 0 additions & 1 deletion src/drivers/pc80/pc/spkmodem.c
Expand Up @@ -14,7 +14,6 @@
* GNU General Public License for more details.
*/

#include <console/console.h>
#include <arch/io.h>
#include <console/spkmodem.h>
#include <cpu/x86/tsc.h>
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/pc80/rtc/mc146818rtc.c
Expand Up @@ -303,7 +303,7 @@ enum cb_err get_option(void *dest, const char *name)
}
}
if (!found) {
printk(BIOS_DEBUG, "WARNING: No CMOS option '%s'.\n", name);
printk(BIOS_DEBUG, "No CMOS option '%s'.\n", name);
rdev_munmap(&rdev, ct);
UNLOCK_NVRAM_CBFS_SPINLOCK();
return CB_CMOS_OPTION_NOT_FOUND;
Expand Down
5 changes: 3 additions & 2 deletions src/drivers/pc80/tpm/tis.c
Expand Up @@ -125,10 +125,11 @@ static const struct device_name atmel_devices[] = {

static const struct device_name infineon_devices[] = {
{0x000b, "SLB9635 TT 1.2"},
{0x001a, "SLB9660 TT 1.2"},
#if IS_ENABLED(CONFIG_TPM2)
{0x001a, "SLB9665 TT 2.0"},
{0x001b, "SLB9670 TT 2.0"},
#else
{0x001a, "SLB9660 TT 1.2"},
{0x001b, "SLB9670 TT 1.2"},
#endif
{0xffff}
Expand Down Expand Up @@ -743,7 +744,7 @@ static int tis_setup_interrupt(int vector, int polarity)
/* Set TPM interrupt vector */
tpm_write_int_vector(vector, locality);

/* Set TPM interupt polarity and disable interrupts */
/* Set TPM interrupt polarity and disable interrupts */
tpm_write_int_polarity(polarity, locality);

/* Close connection if it was opened */
Expand Down
4 changes: 4 additions & 0 deletions src/drivers/spi/spi_flash.c
Expand Up @@ -206,6 +206,10 @@ int spi_flash_cmd_erase(const struct spi_flash *flash, u32 offset, size_t len)
printk(BIOS_WARNING, "SF: Erase offset/length not multiple of erase size\n");
return -1;
}
if (len == 0) {
printk(BIOS_WARNING, "SF: Erase length cannot be 0\n");
return -1;
}

cmd[0] = flash->erase_cmd;
start = offset;
Expand Down
17 changes: 13 additions & 4 deletions src/drivers/spi/stmicro.c
Expand Up @@ -45,17 +45,18 @@
* Device ID = (memory_type << 8) + memory_capacity
*/
#define STM_ID_M25P10 0x2011
#define STM_ID_M25P16 0x2015
#define STM_ID_M25P20 0x2012
#define STM_ID_M25P32 0x2016
#define STM_ID_M25P40 0x2013
#define STM_ID_M25P64 0x2017
#define STM_ID_M25P80 0x2014
#define STM_ID_M25P16 0x2015
#define STM_ID_M25P32 0x2016
#define STM_ID_M25P64 0x2017
#define STM_ID_M25P128 0x2018
#define STM_ID_N25Q032__3E 0xba16
#define STM_ID_N25Q128A 0xba18
#define STM_ID_N25Q256 0xba19
#define STM_ID_N25Q064 0xbb17
#define STM_ID_N25Q128 0xbb18
#define STM_ID_N25Q128A 0xba18

struct stmicro_spi_flash_params {
u16 device_id;
Expand Down Expand Up @@ -131,6 +132,14 @@ static const struct stmicro_spi_flash_params stmicro_spi_flash_table[] = {
.nr_sectors = 64,
.name = "M25P128",
},
{
.device_id = STM_ID_N25Q032__3E,
.op_erase = CMD_M25PXX_SSE,
.page_size = 256,
.pages_per_sector = 16,
.nr_sectors = 1024,
.name = "N25Q032..3E",
},
{
.device_id = STM_ID_N25Q064,
.op_erase = CMD_M25PXX_SSE,
Expand Down
170 changes: 86 additions & 84 deletions src/drivers/spi/winbond.c
Expand Up @@ -32,111 +32,110 @@
#define ADDR_W25_SEC3 0x30

struct winbond_spi_flash_params {
uint16_t id;
/* Log2 of page size in power-of-two mode */
uint8_t l2_page_size;
uint16_t pages_per_sector;
uint16_t sectors_per_block;
uint16_t nr_blocks;
const char *name;
uint16_t id;
uint8_t l2_page_size_shift;
uint8_t pages_per_sector_shift : 4;
uint8_t sectors_per_block_shift : 4;
uint8_t nr_blocks_shift;
char name[10];
};

static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
{
.id = 0x3015,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 32,
.name = "W25X16",
.id = 0x3015,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 5,
.name = "W25X16",
},
{
.id = 0x3016,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 64,
.name = "W25X32",
.id = 0x3016,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 6,
.name = "W25X32",
},
{
.id = 0x3017,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 128,
.name = "W25X64",
.id = 0x3017,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 7,
.name = "W25X64",
},
{
.id = 0x4014,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 16,
.name = "W25Q80",
.id = 0x4014,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 4,
.name = "W25Q80",
},
{
.id = 0x4015,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 32,
.name = "W25Q16",
.id = 0x4015,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 5,
.name = "W25Q16",
},
{
.id = 0x4016,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 64,
.name = "W25Q32",
.id = 0x4016,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 6,
.name = "W25Q32",
},
{
.id = 0x6016,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 64,
.name = "W25Q32DW",
.id = 0x6016,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 6,
.name = "W25Q32DW",
},
{
.id = 0x4017,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 128,
.name = "W25Q64",
.id = 0x4017,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 7,
.name = "W25Q64",
},
{
.id = 0x6017,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 128,
.name = "W25Q64DW",
.id = 0x6017,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 7,
.name = "W25Q64DW",
},
{
.id = 0x4018,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 256,
.name = "W25Q128",
.id = 0x4018,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 8,
.name = "W25Q128",
},
{
.id = 0x6018,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 256,
.name = "W25Q128FW",
.id = 0x6018,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 8,
.name = "W25Q128FW",
},
{
.id = 0x4019,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 512,
.name = "W25Q256",
.id = 0x4019,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 9,
.name = "W25Q256",
},
};

Expand Down Expand Up @@ -258,11 +257,14 @@ int spi_flash_probe_winbond(const struct spi_slave *spi, u8 *idcode,

memcpy(&flash->spi, spi, sizeof(*spi));
flash->name = params->name;
/* Assuming power-of-two page size initially. */
flash->page_size = 1 << params->l2_page_size;
flash->sector_size = flash->page_size * params->pages_per_sector;
flash->size = flash->sector_size * params->sectors_per_block *
params->nr_blocks;

/* Params are in power-of-two. */
flash->page_size = 1 << params->l2_page_size_shift;
flash->sector_size = flash->page_size *
(1 << params->pages_per_sector_shift);
flash->size = flash->sector_size *
(1 << params->sectors_per_block_shift) *
(1 << params->nr_blocks_shift);
flash->erase_cmd = CMD_W25_SE;
flash->status_cmd = CMD_W25_RDSR;

Expand Down
2 changes: 1 addition & 1 deletion src/drivers/ti/tps65913/tps65913rtc.c
Expand Up @@ -29,7 +29,7 @@ enum TPS65913_RTC_REG {
TPS65913_WEEKS_REG = 0x06,
TPS65913_RTC_CTRL_REG = 0x10,
TPS65913_RTC_STATUS_REG = 0x11,
TPS65913_RTC_INTERRUPS_REG = 0x12,
TPS65913_RTC_INTERRUPTS_REG = 0x12,
};

enum {
Expand Down
7 changes: 7 additions & 0 deletions src/drivers/tpm/Kconfig
@@ -0,0 +1,7 @@
config TPM_INIT
bool
default y if TPM1 || TPM2
depends on !VBOOT
help
This driver automatically initializes the TPM if vboot is not used.
The TPM driver init is done during the ramstage chip init phase.
1 change: 1 addition & 0 deletions src/drivers/tpm/Makefile.inc
@@ -0,0 +1 @@
ramstage-$(CONFIG_TPM_INIT) += tpm.c
29 changes: 18 additions & 11 deletions src/soc/marvell/mvmap2315/media.c → src/drivers/tpm/tpm.c
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2016 Marvell, Inc.
* Copyright (C) 2018 Facebook Inc.
*
* 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
Expand All @@ -13,18 +13,25 @@
* GNU General Public License for more details.
*/

#include <types.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <bootstate.h>
#include <security/tpm/tspi.h>

#include <boot_device.h>
#include <soc/addressmap.h>
#include <symbols.h>
#if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)
#include <arch/acpi.h>
#endif

static struct mem_region_device mdev =
MEM_REGION_DEV_RO_INIT((void *)MVMAP2315_CBFS_BASE, CONFIG_ROM_SIZE);

const struct region_device *boot_device_ro(void)
static void init_tpm_dev(void *unused)
{
return &mdev.rdev;
#if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)
int s3resume = acpi_is_wakeup_s3();
tpm_setup(s3resume);
#else
/* This can lead to PCR reset attacks but currently there
is no generic way to detect resume on other platforms. */
tpm_setup(false);
#endif
}

BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, init_tpm_dev, NULL);
2 changes: 1 addition & 1 deletion src/drivers/usb/Kconfig
Expand Up @@ -82,7 +82,7 @@ config USBDEBUG_DONGLE_STD
Net20DC, BeagleBone Black, Raspberry Pi Zero W

config USBDEBUG_DONGLE_BEAGLEBONE
bool "BeagleBone"
bool "BeagleBone (not BeagleBone Black)"
help
Use this to configure the USB hub on BeagleBone board.
Do NOT select this for the BeagleBone Black.
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/xgi/common/vb_setmode.c
Expand Up @@ -958,7 +958,7 @@ static void XGI_SetCRT1FIFO(struct xgi_hw_device_info *HwDeviceExtension,

data = xgifb_reg_get(pVBInfo->P3c4, 0x3D);
data &= 0xfe;
xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */
xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* disable auto-threshold */

xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34);
data = xgifb_reg_get(pVBInfo->P3c4, 0x09);
Expand Down
5 changes: 2 additions & 3 deletions src/ec/compal/ene932/ec.c
Expand Up @@ -144,13 +144,12 @@ static struct device_operations ops = {
};

static struct pnp_info pnp_dev_info[] = {
{ &ops, 0, 0, 0, }
{ NULL, 0, 0, 0, }
};

static void enable_dev(struct device *dev)
{
pnp_enable_devices(dev, &pnp_ops, ARRAY_SIZE(pnp_dev_info),
pnp_dev_info);
pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
}

struct chip_operations ec_compal_ene932_ops = {
Expand Down
13 changes: 13 additions & 0 deletions src/ec/google/chromeec/acpi/cros_ec.asl
Expand Up @@ -30,4 +30,17 @@ Device (CREC)
Name (_DDN, "EC MKBP Device")
}
#endif

#ifdef EC_ENABLE_CBAS_DEVICE
Device (CBAS)
{
Name (_HID, "GOOG000B")
Name (_UID, 1)
Name (_DDN, "EC Base Switch Device")
}
#endif
Method(_STA, 0)
{
Return (0xB)
}
}
26 changes: 12 additions & 14 deletions src/ec/google/chromeec/acpi/ec.asl
Expand Up @@ -467,25 +467,23 @@ Device (EC0)
*/
Method (_Q09, 0, NotSerialized)
{
If (Acquire (^PATM, 1000)) {
Return ()
}

/* Read sensor ID for event */
Store (^PATI, Local0)
If (LNot(Acquire (^PATM, 1000))) {
/* Read sensor ID for event */
Store (^PATI, Local0)

/* When sensor ID returns 0xFF then no more events */
While (LNotEqual (Local0, EC_TEMP_SENSOR_NOT_PRESENT))
{
/* When sensor ID returns 0xFF then no more events */
While (LNotEqual (Local0, EC_TEMP_SENSOR_NOT_PRESENT))
{
#ifdef HAVE_THERM_EVENT_HANDLER
\_SB.DPTF.TEVT (Local0)
\_SB.DPTF.TEVT (Local0)
#endif

/* Keep reaading sensor ID for event */
Store (^PATI, Local0)
}
/* Keep reaading sensor ID for event */
Store (^PATI, Local0)
}

Release (^PATM)
Release (^PATM)
}
}

/*
Expand Down
4 changes: 4 additions & 0 deletions src/ec/google/chromeec/acpi/pd.asl
Expand Up @@ -18,4 +18,8 @@ Device (ECPD)
Name (_HID, "GOOG0003")
Name (_UID, 1)
Name (_DDN, "EC PD Device")
Method(_STA, 0)
{
Return (0xB)
}
}
6 changes: 3 additions & 3 deletions src/ec/google/chromeec/acpi/superio.asl
Expand Up @@ -39,7 +39,7 @@ Device (SIO) {
#ifdef SIO_EC_MEMMAP_ENABLE
Device (ECMM) {
Name (_HID, EISAID ("PNP0C02"))
Name (_UID, 1)
Name (_UID, 4)
Name (_ADR, 0)

Method (_STA, 0, NotSerialized) {
Expand Down Expand Up @@ -137,8 +137,8 @@ Device (SIO) {
{
Name (_UID, 0)
Name (_ADR, 0)
Name (_HID, EISAID("PNP0303"))
Name (_CID, EISAID("PNP030B"))
Name (_HID, "GOOG000A")
Name (_CID, Package() { EISAID("PNP0303"), EISAID("PNP030B") } )

Method (_STA, 0, NotSerialized) {
Return (0x0F)
Expand Down
4 changes: 4 additions & 0 deletions src/ec/google/chromeec/acpi/tbmc.asl
Expand Up @@ -26,4 +26,8 @@ Device (TBMC)
Return (0x0)
}
}
Method(_STA, 0)
{
Return (0xB)
}
}
165 changes: 159 additions & 6 deletions src/ec/google/chromeec/ec.c
Expand Up @@ -573,14 +573,14 @@ int google_chromeec_reboot(int dev_idx, enum ec_reboot_cmd type, uint8_t flags)
return google_chromeec_command(&cec_cmd);
}

static int cbi_get_uint32(uint32_t *id, uint32_t type)
static int cbi_get_uint32(uint32_t *id, uint32_t tag)
{
struct chromeec_command cmd;
struct ec_params_get_cbi p;
uint32_t r = 0;
int rv;

p.type = type;
p.tag = tag;

cmd.cmd_code = EC_CMD_GET_CROS_BOARD_INFO;
cmd.cmd_version = 0;
Expand All @@ -607,6 +607,31 @@ int google_chromeec_cbi_get_oem_id(uint32_t *id)
return cbi_get_uint32(id, CBI_TAG_OEM_ID);
}

int google_chromeec_cbi_get_dram_part_num(char *buf, size_t bufsize)
{
struct ec_params_get_cbi p = {
.tag = CBI_TAG_DRAM_PART_NUM,
};
struct chromeec_command cmd = {
.cmd_code = EC_CMD_GET_CROS_BOARD_INFO,
.cmd_version = 0,
.cmd_data_in = &p,
.cmd_data_out = buf,
.cmd_size_in = sizeof(p),
.cmd_size_out = bufsize,
};
int rv;

rv = google_chromeec_command(&cmd);
if (rv < 0)
return rv;

/* Ensure NUL termination. */
buf[bufsize - 1] = '\0';

return 0;
}

#ifndef __SMM__
u16 google_chromeec_get_board_version(void)
{
Expand Down Expand Up @@ -892,8 +917,7 @@ int google_chromeec_set_usb_pd_role(u8 port, enum usb_pd_control_role role)

#ifndef __SMM__

static
int google_chromeec_hello(void)
static int google_chromeec_hello(void)
{
struct chromeec_command cec_cmd;
struct ec_params_hello cmd_hello;
Expand All @@ -912,15 +936,142 @@ int google_chromeec_hello(void)
return cec_cmd.cmd_code;
}

/*
* Convert a reset cause ID to human-readable string, providing total coverage
* of the 'cause' space. The returned string points to static storage and must
* not be free()ed.
*/
static const char *reset_cause_to_str(uint16_t cause)
{
/* See also ChromiumOS EC include/chipset.h for details. */
static const char * const reset_causes[] = {
"(reset unknown)",
"reset: board custom",
"reset: ap hang detected",
"reset: console command",
"reset: keyboard sysreset",
"reset: keyboard warm reboot",
"reset: debug warm reboot",
"reset: at AP's request",
"reset: during EC initialization",
};

static const size_t shutdown_cause_begin = 1 << 15;
static const char * const shutdown_causes[] = {
"shutdown: power failure",
"shutdown: during EC initialization",
"shutdown: board custom",
"shutdown: battery voltage startup inhibit",
"shutdown: power wait asserted",
"shutdown: critical battery",
"shutdown: by console command",
"shutdown: entering G3",
"shutdown: thermal",
"shutdown: power button",
};

if (cause < ARRAY_SIZE(reset_causes))
return reset_causes[cause];

if (cause < shutdown_cause_begin)
return "(reset unknown)";

if (cause < shutdown_cause_begin + ARRAY_SIZE(shutdown_causes))
return shutdown_causes[cause - shutdown_cause_begin];

return "(shutdown unknown)";
}

/*
* Copy the EC's information about resets of the AP and its own uptime for
* debugging purposes.
*/
static void google_chromeec_log_uptimeinfo(void)
{
/* See also ChromiumOS EC include/system.h RESET_FLAG for details. */
static const char * const reset_flag_strings[] = {
"other",
"reset-pin",
"brownout",
"power-on",
"watchdog",
"soft",
"hibernate",
"rtc-alarm",
"wake-pin",
"low-battery",
"sysjump",
"hard",
"ap-off",
"preserved",
"usb-resume",
"rdd",
"rbox",
"security"
};
struct ec_response_uptime_info cmd_resp;
int i, flag, flag_count;

struct chromeec_command get_uptime_cmd = {
.cmd_code = EC_CMD_GET_UPTIME_INFO,
.cmd_version = 0,
.cmd_data_in = NULL,
.cmd_size_in = 0,
.cmd_data_out = &cmd_resp,
.cmd_size_out = sizeof(cmd_resp),
.cmd_dev_index = 0,
};
google_chromeec_command(&get_uptime_cmd);
if (get_uptime_cmd.cmd_code) {
/*
* Deliberately say nothing for EC's that don't support this
* command
*/
return;
}

printk(BIOS_DEBUG, "Google Chrome EC uptime: %d.%03d seconds\n",
cmd_resp.time_since_ec_boot_ms / MSECS_PER_SEC,
cmd_resp.time_since_ec_boot_ms % MSECS_PER_SEC);

printk(BIOS_DEBUG, "Google Chrome AP resets since EC boot: %d\n",
cmd_resp.ap_resets_since_ec_boot);

printk(BIOS_DEBUG, "Google Chrome most recent AP reset causes:\n");
for (i = 0; i != ARRAY_SIZE(cmd_resp.recent_ap_reset); ++i) {
if (cmd_resp.recent_ap_reset[i].reset_time_ms == 0)
continue;

printk(BIOS_DEBUG, "\t%d.%03d: %d %s\n",
cmd_resp.recent_ap_reset[i].reset_time_ms /
MSECS_PER_SEC,
cmd_resp.recent_ap_reset[i].reset_time_ms %
MSECS_PER_SEC,
cmd_resp.recent_ap_reset[i].reset_cause,
reset_cause_to_str(
cmd_resp.recent_ap_reset[i].reset_cause));
}

printk(BIOS_DEBUG, "Google Chrome EC reset flags at last EC boot: ");
flag_count = 0;
for (flag = 0; flag != ARRAY_SIZE(reset_flag_strings); ++flag) {
if ((cmd_resp.ec_reset_flags & (1 << flag)) != 0) {
if (flag_count)
printk(BIOS_DEBUG, " | ");
printk(BIOS_DEBUG, reset_flag_strings[flag]);
flag_count++;
}
}
printk(BIOS_DEBUG, "\n");
}

static int ec_image_type; /* Cached EC image type (ro or rw). */

void google_chromeec_init(void)
{
struct chromeec_command cec_cmd;
struct ec_response_get_version cec_resp = {{0}};

printk(BIOS_DEBUG, "Google Chrome EC: Initializing keyboard.\n");

google_chromeec_hello();

cec_cmd.cmd_code = EC_CMD_GET_VERSION;
Expand All @@ -942,6 +1093,8 @@ void google_chromeec_init(void)
cec_resp.current_image);
ec_image_type = cec_resp.current_image;
}

google_chromeec_log_uptimeinfo();
}

int google_ec_running_ro(void)
Expand Down
1 change: 1 addition & 0 deletions src/ec/google/chromeec/ec.h
Expand Up @@ -74,6 +74,7 @@ int google_chromeec_reboot(int dev_idx, enum ec_reboot_cmd type, uint8_t flags);
*/
int google_chromeec_cbi_get_oem_id(uint32_t *id);
int google_chromeec_cbi_get_sku_id(uint32_t *id);
int google_chromeec_cbi_get_dram_part_num(char *buf, size_t bufsize);

/* MEC uses 0x800/0x804 as register/index pair, thus an 8-byte resource. */
#define MEC_EMI_BASE 0x800
Expand Down