baytrail: add initial support

The initial Bay Trail code is intended to support
the mobile and desktop version of Bay Trail. This support
can train memory and execute through ramstage. However,
the resource allocation is not curently handled correctly.
The MRC cache parameters are successfully saved and reused
after the initial cold boot.

BUG=chrome-os-partner:22292
BRANCH=None
TEST=Built and booted on a reference board through ramstage.

Change-Id: I238ede326802aad272c6cca39d7ad4f161d813f5
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/168387
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: http://review.coreboot.org/4847
Tested-by: build bot (Jenkins)
Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
This commit is contained in:
Aaron Durbin 2013-09-07 00:41:48 -05:00 committed by Aaron Durbin
parent ba6b07e888
commit 9a7d7bcea5
42 changed files with 16494 additions and 1 deletions

View File

@ -50,7 +50,7 @@ PHONY+= clean-abuild coreboot lint lint-stable build-dirs
#######################################################################
# root source directories of coreboot
subdirs-y := src/lib src/console src/device src/ec src/southbridge
subdirs-y := src/lib src/console src/device src/ec src/southbridge src/soc
subdirs-y += src/northbridge src/superio src/drivers src/cpu src/vendorcode
subdirs-y += util/cbfstool util/sconfig util/nvramtool
subdirs-y += src/arch/$(ARCHDIR-y)

View File

@ -261,6 +261,8 @@ comment "Super I/O"
source src/superio/Kconfig
comment "Embedded Controllers"
source src/ec/Kconfig
comment "SoC"
source src/soc/Kconfig
endmenu

3
src/soc/Kconfig Normal file
View File

@ -0,0 +1,3 @@
if ARCH_X86
source src/soc/intel/Kconfig
endif

4
src/soc/Makefile.inc Normal file
View File

@ -0,0 +1,4 @@
################################################################################
## Subdirectories
################################################################################
subdirs-y += intel

1
src/soc/intel/Kconfig Normal file
View File

@ -0,0 +1 @@
source src/soc/intel/baytrail/Kconfig

View File

@ -0,0 +1 @@
subdirs-$(CONFIG_SOC_INTEL_BAYTRAIL) += baytrail

View File

@ -0,0 +1,236 @@
config SOC_INTEL_BAYTRAIL
bool
help
Bay Trail M/D part support.
if SOC_INTEL_BAYTRAIL
config CPU_SPECIFIC_OPTIONS
def_bool y
select SMP
select SSE2
select UDELAY_TSC
select TSC_CONSTANT_RATE
select SMM_TSEG
select SMM_MODULES
select RELOCATABLE_MODULES
select DYNAMIC_CBMEM
select SUPPORT_CPU_UCODE_IN_CBFS
select TSC_SYNC_MFENCE
select CAR_MIGRATION
select MMCONF_SUPPORT
select MMCONF_SUPPORT_DEFAULT
select HAVE_SMI_HANDLER
select CACHE_MRC_SETTINGS
select CACHE_ROM
select SPI_FLASH
config BOOTBLOCK_CPU_INIT
string
default "soc/intel/baytrail/bootblock/bootblock.c"
config MMCONF_BASE_ADDRESS
hex
default 0xe0000000
config MAX_CPUS
int
default 4
config CPU_ADDR_BITS
int
default 36
config SMM_TSEG_SIZE
hex
default 0x800000
config SMM_RESERVED_SIZE
hex
default 0x100000
config HAVE_MRC
bool "Add a Memory Reference Code binary"
default y
help
Select this option to add a blob containing
memory reference code.
Note: Without this binary coreboot will not work
if HAVE_MRC
config MRC_FILE
string "Intel memory refeference code path and filename"
default "3rdparty/northbridge/intel/sandybridge/systemagent-r6.bin"
help
The path and filename of the file to use as System Agent
binary. Note that this points to the sandybridge binary file
which is will not work, but it serves its purpose to do builds.
config MRC_BIN_ADDRESS
hex
default 0xfffa0000
config CACHE_MRC_SETTINGS
bool "Save cached MRC settings"
default n
if CACHE_MRC_SETTINGS
config MRC_SETTINGS_CACHE_BASE
hex
default 0xffb00000
config MRC_SETTINGS_CACHE_SIZE
hex
default 0x10000
endif # CACHE_MRC_SETTINGS
endif # HAVE_MRC
config CAR_TILE_SIZE
hex
default 0x8000
help
The tile size is the limit that can be assigned to cache-as-ram
region as well as the amount of code cache used during cache-as-ram.
Also note that (DCACHE_RAM_BASE ^ MRC_BIN_ADDRESS) & CAR_TILE_SIZE ==
CAR_TILE_SIZE.
# Cache As RAM region layout:
#
# +-------------+ DCACHE_RAM_BASE + DCACHE_RAM_SIZE + DCACHE_RAM_MRC_VAR_SIZE
# | MRC usage |
# | |
# +-------------+ DCACHE_RAM_BASE + DCACHE_RAM_SIZE
# | Stack |\
# | | | * DCACHE_RAM_ROMSTAGE_STACK_SIZE
# | v |/
# +-------------+
# | ^ |
# | | |
# | CAR Globals |
# +-------------+ DCACHE_RAM_BASE
#
# Note that the MRC binary is linked to assume the region marked as "MRC usage"
# starts at DCACHE_RAM_BASE + DCACHE_RAM_SIZE. If those values change then
# a new MRC binary needs to be produced with the updated start and size
# information.
config DCACHE_RAM_BASE
hex
default 0xff7f8000
config DCACHE_RAM_SIZE
hex
default 0x1000
help
The size of the cache-as-ram region required during bootblock
and/or romstage. Note DCACHE_RAM_SIZE and DCACHE_RAM_MRC_VAR_SIZE
must add up to a power of 2.
config DCACHE_RAM_MRC_VAR_SIZE
hex
default 0x7000
help
The amount of cache-as-ram region required by the reference code.
config DCACHE_RAM_ROMSTAGE_STACK_SIZE
hex
default 0x800
help
The amount of anticipated stack usage from the data cache
during pre-ram rom stage execution.
config RESET_ON_INVALID_RAMSTAGE_CACHE
bool "Reset the system on S3 wake when ramstage cache invalid."
default n
depends on RELOCATABLE_RAMSTAGE
help
The baytrail romstage code caches the loaded ramstage program
in SMM space. On S3 wake the romstage will copy over a fresh
ramstage that was cached in the SMM space. This option determines
the action to take when the ramstage cache is invalid. If selected
the system will reset otherwise the ramstage will be reloaded from
cbfs.
config CBFS_SIZE
hex "Size of CBFS filesystem in ROM"
default 0x100000
help
On Bay Trail systems the firmware image has to store a lot more
than just coreboot, including:
- a firmware descriptor
- Intel Management Engine firmware
- MRC cache information
This option allows to limit the size of the CBFS portion in the
firmware image.
config ENABLE_BUILTIN_COM1
bool "Enable builtin COM1 Serial Port"
default n
help
The PMC has a legacy COM1 serial port. Choose this option to
configure the pads and enable it. This serial port can be used for
the debug console.
config HAVE_ME_BIN
bool "Add Intel Management Engine firmware"
default y
help
The Intel processor in the selected system requires a special firmware
for an integrated controller called Management Engine (ME). The ME
firmware might be provided in coreboot's 3rdparty repository. If
not and if you don't have the firmware elsewhere, you can still
build coreboot without it. In this case however, you'll have to make
sure that you don't overwrite your ME firmware on your flash ROM.
config ME_BIN_PATH
string "Path to management engine firmware"
depends on HAVE_ME_BIN
default "3rdparty/mainboard/$(MAINBOARDDIR)/me.bin"
config HAVE_IFD_BIN
bool
default y
config BUILD_WITH_FAKE_IFD
bool "Build with a fake IFD"
default y if !HAVE_IFD_BIN
help
If you don't have an Intel Firmware Descriptor (ifd.bin) for your
board, you can select this option and coreboot will build without it.
Though, the resulting coreboot.rom will not contain all parts required
to get coreboot running on your board. You can however write only the
BIOS section to your board's flash ROM and keep the other sections
untouched. Unfortunately the current version of flashrom doesn't
support this yet. But there is a patch pending [1].
WARNING: Never write a complete coreboot.rom to your flash ROM if it
was built with a fake IFD. It just won't work.
[1] http://www.flashrom.org/pipermail/flashrom/2013-June/011083.html
config IFD_BIOS_SECTION
depends on BUILD_WITH_FAKE_IFD
string
default ""
config IFD_ME_SECTION
depends on BUILD_WITH_FAKE_IFD
string
default ""
config IFD_PLATFORM_SECTION
depends on BUILD_WITH_FAKE_IFD
string
default ""
config IFD_BIN_PATH
string "Path to intel firmware descriptor"
depends on !BUILD_WITH_FAKE_IFD
default "3rdparty/mainboard/$(MAINBOARDDIR)/descriptor.bin"
endif

View File

@ -0,0 +1,65 @@
subdirs-y += microcode
subdirs-y += romstage
subdirs-y += ../../../cpu/x86/lapic
subdirs-y += ../../../cpu/x86/mtrr
subdirs-y += ../../../cpu/x86/tsc
ramstage-y += memmap.c
romstage-y += memmap.c
ramstage-y += tsc_freq.c
romstage-y += tsc_freq.c
ramstage-$(CONFIG_CACHE_MRC_SETTINGS) += nvm.c
ramstage-$(CONFIG_CACHE_MRC_SETTINGS) += mrc_cache.c
romstage-$(CONFIG_CACHE_MRC_SETTINGS) += mrc_cache.c
ramstage-y += spi.c
ramstage-y += chip.c
ramstage-y += iosf.c
romstage-y += iosf.c
# Remove as ramstage gets fleshed out
ramstage-y += placeholders.c
INCLUDES += -Isrc/soc/intel/baytrail/
# Run an intermediate step when producing coreboot.rom
# that adds additional components to the final firmware
# image outside of CBFS
INTERMEDIATE:=baytrail_add_me
ifeq ($(CONFIG_BUILD_WITH_FAKE_IFD),y)
IFD_BIN_PATH := $(objgenerated)/ifdfake.bin
IFD_SECTIONS := $(addprefix -b ,$(CONFIG_IFD_BIOS_SECTION:"%"=%)) \
$(addprefix -m ,$(CONFIG_IFD_ME_SECTION:"%"=%)) \
$(addprefix -p ,$(CONFIG_IFD_PLATFORM_SECTION:"%"=%))
else
IFD_BIN_PATH := $(CONFIG_IFD_BIN_PATH)
endif
baytrail_add_me: $(obj)/coreboot.pre $(IFDTOOL) $(IFDFAKE)
ifeq ($(CONFIG_BUILD_WITH_FAKE_IFD),y)
printf "\n** WARNING **\n"
printf "Coreboot will be built with a fake Intel Firmware Descriptor (IFD).\n"
printf "Never write a complete coreboot.rom with a fake IFD to your board's\n"
printf "flash ROM! Make sure that you only write valid flash regions.\n\n"
printf " IFDFAKE Building a fake Intel Firmware Descriptor\n"
$(IFDFAKE) $(IFD_SECTIONS) $(IFD_BIN_PATH)
endif
printf " DD Adding Intel Firmware Descriptor\n"
dd if=$(IFD_BIN_PATH) \
of=$(obj)/coreboot.pre conv=notrunc >/dev/null 2>&1
ifeq ($(CONFIG_HAVE_ME_BIN),y)
printf " IFDTOOL me.bin -> coreboot.pre\n"
$(objutil)/ifdtool/ifdtool \
-i ME:$(CONFIG_ME_BIN_PATH) \
$(obj)/coreboot.pre
mv $(obj)/coreboot.pre.new $(obj)/coreboot.pre
endif
# Add memory reference code blob.
cbfs-files-$(CONFIG_HAVE_MRC) += mrc.bin
mrc.bin-file := $(call strip_quotes,$(CONFIG_MRC_FILE))
mrc.bin-position := $(CONFIG_MRC_BIN_ADDRESS)
mrc.bin-type := 0xab
PHONY += baytrail_add_me

View File

@ -0,0 +1,284 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
/* Global Variables */
Name(\PICM, 0) // IOAPIC/8259
Name(\DSEN, 1) // Display Output Switching Enable
/* Global ACPI memory region. This region is used for passing information
* between coreboot (aka "the system bios"), ACPI, and the SMI handler.
* Since we don't know where this will end up in memory at ACPI compile time,
* we have to fix it up in coreboot's ACPI creation phase.
*/
OperationRegion (GNVS, SystemMemory, 0xC0DEBABE, 0xf00)
Field (GNVS, ByteAcc, NoLock, Preserve)
{
/* Miscellaneous */
Offset (0x00),
OSYS, 16, // 0x00 - Operating System
SMIF, 8, // 0x02 - SMI function
PRM0, 8, // 0x03 - SMI function parameter
PRM1, 8, // 0x04 - SMI function parameter
SCIF, 8, // 0x05 - SCI function
PRM2, 8, // 0x06 - SCI function parameter
PRM3, 8, // 0x07 - SCI function parameter
LCKF, 8, // 0x08 - Global Lock function for EC
PRM4, 8, // 0x09 - Lock function parameter
PRM5, 8, // 0x0a - Lock function parameter
P80D, 32, // 0x0b - Debug port (IO 0x80) value
LIDS, 8, // 0x0f - LID state (open = 1)
PWRS, 8, // 0x10 - Power State (AC = 1)
/* Thermal policy */
Offset (0x11),
TLVL, 8, // 0x11 - Throttle Level Limit
FLVL, 8, // 0x12 - Current FAN Level
TCRT, 8, // 0x13 - Critical Threshold
TPSV, 8, // 0x14 - Passive Threshold
TMAX, 8, // 0x15 - CPU Tj_max
F0OF, 8, // 0x16 - FAN 0 OFF Threshold
F0ON, 8, // 0x17 - FAN 0 ON Threshold
F0PW, 8, // 0x18 - FAN 0 PWM value
F1OF, 8, // 0x19 - FAN 1 OFF Threshold
F1ON, 8, // 0x1a - FAN 1 ON Threshold
F1PW, 8, // 0x1b - FAN 1 PWM value
F2OF, 8, // 0x1c - FAN 2 OFF Threshold
F2ON, 8, // 0x1d - FAN 2 ON Threshold
F2PW, 8, // 0x1e - FAN 2 PWM value
F3OF, 8, // 0x1f - FAN 3 OFF Threshold
F3ON, 8, // 0x20 - FAN 3 ON Threshold
F3PW, 8, // 0x21 - FAN 3 PWM value
F4OF, 8, // 0x22 - FAN 4 OFF Threshold
F4ON, 8, // 0x23 - FAN 4 ON Threshold
F4PW, 8, // 0x24 - FAN 4 PWM value
TMPS, 8, // 0x25 - Temperature Sensor ID
/* Processor Identification */
Offset (0x28),
APIC, 8, // 0x28 - APIC Enabled by coreboot
MPEN, 8, // 0x29 - Multi Processor Enable
PCP0, 8, // 0x2a - PDC CPU/CORE 0
PCP1, 8, // 0x2b - PDC CPU/CORE 1
PPCM, 8, // 0x2c - Max. PPC state
PCNT, 8, // 0x2d - Processor count
/* Super I/O & CMOS config */
Offset (0x32),
NATP, 8, // 0x32 -
S5U0, 8, // 0x33 - Enable USB0 in S5
S5U1, 8, // 0x34 - Enable USB1 in S5
S3U0, 8, // 0x35 - Enable USB0 in S3
S3U1, 8, // 0x36 - Enable USB1 in S3
S33G, 8, // 0x37 - Enable 3G in S3
CMEM, 32, // 0x38 - CBMEM TOC
/* Integrated Graphics Device */
Offset (0x3c),
IGDS, 8, // 0x3c - IGD state (primary = 1)
TLST, 8, // 0x3d - Display Toggle List pointer
CADL, 8, // 0x3e - Currently Attached Devices List
PADL, 8, // 0x3f - Previously Attached Devices List
CSTE, 16, // 0x40 - Current display state
NSTE, 16, // 0x42 - Next display state
SSTE, 16, // 0x44 - Set display state
Offset (0x46),
NDID, 8, // 0x46 - Number of Device IDs
DID1, 32, // 0x47 - Device ID 1
DID2, 32, // 0x4b - Device ID 2
DID3, 32, // 0x4f - Device ID 3
DID4, 32, // 0x53 - Device ID 4
DID5, 32, // 0x57 - Device ID 5
/* TPM support */
Offset (0x5b),
TPMP, 8, // 0x5b - TPM Present
TPME, 8, // 0x5c - TPM Enable
/* LynxPoint Serial IO device BARs */
Offset (0x60),
S0B0, 32, // 0x60 - D21:F0 Serial IO SDMA BAR0
S1B0, 32, // 0x64 - D21:F1 Serial IO I2C0 BAR0
S2B0, 32, // 0x68 - D21:F2 Serial IO I2C1 BAR0
S3B0, 32, // 0x6c - D21:F3 Serial IO SPI0 BAR0
S4B0, 32, // 0x70 - D21:F4 Serial IO SPI1 BAR0
S5B0, 32, // 0x74 - D21:F5 Serial IO UAR0 BAR0
S6B0, 32, // 0x78 - D21:F6 Serial IO UAR1 BAR0
S7B0, 32, // 0x7c - D23:F0 Serial IO SDIO BAR0
S0B1, 32, // 0x80 - D21:F0 Serial IO SDMA BAR1
S1B1, 32, // 0x84 - D21:F1 Serial IO I2C0 BAR1
S2B1, 32, // 0x88 - D21:F2 Serial IO I2C1 BAR1
S3B1, 32, // 0x8c - D21:F3 Serial IO SPI0 BAR1
S4B1, 32, // 0x90 - D21:F4 Serial IO SPI1 BAR1
S5B1, 32, // 0x94 - D21:F5 Serial IO UAR0 BAR1
S6B1, 32, // 0x98 - D21:F6 Serial IO UAR1 BAR1
S7B1, 32, // 0x9c - D23:F0 Serial IO SDIO BAR1
Offset (0xa0),
CBMC, 32, // 0xa0 - coreboot mem console pointer
/* IGD OpRegion */
Offset (0xb4),
ASLB, 32, // 0xb4 - IGD OpRegion Base Address
IBTT, 8, // 0xb8 - IGD boot panel device
IPAT, 8, // 0xb9 - IGD panel type cmos option
ITVF, 8, // 0xba - IGD TV format cmos option
ITVM, 8, // 0xbb - IGD TV minor format option
IPSC, 8, // 0xbc - IGD panel scaling
IBLC, 8, // 0xbd - IGD BLC config
IBIA, 8, // 0xbe - IGD BIA config
ISSC, 8, // 0xbf - IGD SSC config
I409, 8, // 0xc0 - IGD 0409 modified settings
I509, 8, // 0xc1 - IGD 0509 modified settings
I609, 8, // 0xc2 - IGD 0609 modified settings
I709, 8, // 0xc3 - IGD 0709 modified settings
IDMM, 8, // 0xc4 - IGD Power conservation feature
IDMS, 8, // 0xc5 - IGD DVMT memory size
IF1E, 8, // 0xc6 - IGD function 1 enable
HVCO, 8, // 0xc7 - IGD HPLL VCO
NXD1, 32, // 0xc8 - IGD _DGS next DID1
NXD2, 32, // 0xcc - IGD _DGS next DID2
NXD3, 32, // 0xd0 - IGD _DGS next DID3
NXD4, 32, // 0xd4 - IGD _DGS next DID4
NXD5, 32, // 0xd8 - IGD _DGS next DID5
NXD6, 32, // 0xdc - IGD _DGS next DID6
NXD7, 32, // 0xe0 - IGD _DGS next DID7
NXD8, 32, // 0xe4 - IGD _DGS next DID8
ISCI, 8, // 0xe8 - IGD SMI/SCI mode (0: SCI)
PAVP, 8, // 0xe9 - IGD PAVP data
Offset (0xeb),
OSCC, 8, // 0xeb - PCIe OSC control
NPCE, 8, // 0xec - native pcie support
PLFL, 8, // 0xed - platform flavor
BREV, 8, // 0xee - board revision
DPBM, 8, // 0xef - digital port b mode
DPCM, 8, // 0xf0 - digital port c mode
DPDM, 8, // 0xf1 - digital port d mode
ALFP, 8, // 0xf2 - active lfp
IMON, 8, // 0xf3 - current graphics turbo imon value
MMIO, 8, // 0xf4 - 64bit mmio support
/* ChromeOS specific */
Offset (0x100),
#include <vendorcode/google/chromeos/acpi/gnvs.asl>
}
/* Set flag to enable USB charging in S3 */
Method (S3UE)
{
Store (One, \S3U0)
Store (One, \S3U1)
}
/* Set flag to disable USB charging in S3 */
Method (S3UD)
{
Store (Zero, \S3U0)
Store (Zero, \S3U1)
}
/* Set flag to enable USB charging in S5 */
Method (S5UE)
{
Store (One, \S5U0)
Store (One, \S5U1)
}
/* Set flag to disable USB charging in S5 */
Method (S5UD)
{
Store (Zero, \S5U0)
Store (Zero, \S5U1)
}
/* Set flag to enable 3G module in S3 */
Method (S3GE)
{
Store (One, \S33G)
}
/* Set flag to disable 3G module in S3 */
Method (S3GD)
{
Store (Zero, \S33G)
}
External (\_TZ.THRM)
External (\_TZ.SKIN)
Method (TZUP)
{
/* Update Primary Thermal Zone */
If (CondRefOf (\_TZ.THRM, Local0)) {
Notify (\_TZ.THRM, 0x81)
}
/* Update Secondary Thermal Zone */
If (CondRefOf (\_TZ.SKIN, Local0)) {
Notify (\_TZ.SKIN, 0x81)
}
}
/* Update Fan 0 thresholds */
Method (F0UT, 2)
{
Store (Arg0, \F0OF)
Store (Arg1, \F0ON)
TZUP ()
}
/* Update Fan 1 thresholds */
Method (F1UT, 2)
{
Store (Arg0, \F1OF)
Store (Arg1, \F1ON)
TZUP ()
}
/* Update Fan 2 thresholds */
Method (F2UT, 2)
{
Store (Arg0, \F2OF)
Store (Arg1, \F2ON)
TZUP ()
}
/* Update Fan 3 thresholds */
Method (F3UT, 2)
{
Store (Arg0, \F3OF)
Store (Arg1, \F3ON)
TZUP ()
}
/* Update Fan 4 thresholds */
Method (F4UT, 2)
{
Store (Arg0, \F4OF)
Store (Arg1, \F4ON)
TZUP ()
}
/* Update Temperature Sensor ID */
Method (TMPU, 1)
{
Store (Arg0, \TMPS)
TZUP ()
}

View File

@ -0,0 +1,27 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
Name(\_S0, Package(){0x0,0x0,0x0,0x0})
// Name(\_S1, Package(){0x1,0x1,0x0,0x0})
Name(\_S3, Package(){0x5,0x5,0x0,0x0})
Name(\_S4, Package(){0x6,0x6,0x0,0x0})
Name(\_S5, Package(){0x7,0x7,0x0,0x0})

View File

@ -0,0 +1,32 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
Scope(\)
{
// IO-Trap at 0x800. This is the ACPI->SMI communication interface.
OperationRegion(IO_T, SystemIO, 0x800, 0x10)
Field(IO_T, ByteAcc, NoLock, Preserve)
{
Offset(0x8),
TRP0, 8 // IO-Trap at 0x808
}
}

View File

@ -0,0 +1,29 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google, 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 wacbmem_entryanty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _BAYTRAIL_ACPI_H_
#define _BAYTRAIL_ACPI_H_
#include <arch/acpi.h>
void acpi_create_intel_hpet(acpi_hpet_t * hpet);
void acpi_create_serialio_ssdt(acpi_header_t *ssdt);
#endif /* _BAYTRAIL_ACPI_H_ */

View File

@ -0,0 +1,70 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _BAYTRAIL_GPIO_H_
#define _BAYTRAIL_GPIO_H_
#include <stdint.h>
#include <arch/io.h>
#include <baytrail/iomap.h>
/* Registers sitting behind the IO_BASE_ADDRESS */
#define SCORE_PCONF_OFFSET 0x0000
#define SSUS_PCONF_OFFSET 0x2000
static inline unsigned int score_pconf0(int pad_num)
{
return IO_BASE_ADDRESS + SCORE_PCONF_OFFSET + pad_num * 16;
}
static inline unsigned int ssus_pconf0(int pad_num)
{
return IO_BASE_ADDRESS + SSUS_PCONF_OFFSET + pad_num * 16;
}
static inline void score_select_func(int pad, int func)
{
uint32_t reg;
uint32_t pconf0_addr = score_pconf0(pad);
reg = read32(pconf0_addr);
reg &= ~0x7;
reg |= func & 0x7;
write32(pconf0_addr, reg);
}
static inline void ssus_select_func(int pad, int func)
{
uint32_t reg;
uint32_t pconf0_addr = ssus_pconf0(pad);
reg = read32(pconf0_addr);
reg &= ~0x7;
reg |= func & 0x7;
write32(pconf0_addr, reg);
}
/* SCORE Pad definitions. */
#define PCU_SMB_CLK_PAD 88
#define PCU_SMB_DATA_PAD 90
#define PCU_SMB_ALERT_PAD 92
#endif /* _BAYTRAIL_GPIO_H_ */

View File

@ -0,0 +1,38 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _BAYTRAIL_IOMAP_H_
#define _BAYTRAIL_IOMAP_H_
/* Memory Mapped IO bases. */
#define PMC_BASE_ADDRESS 0xfed03000
#define IO_BASE_ADDRESS 0xfed0c000
#define ILB_BASE_ADDRESS 0xfed08000
#define SPI_BASE_ADDRESS 0xfed01000
#define MPHY_BASE_ADDRESS 0xfef00000
#define RCBA_BASE_ADDRESS 0xfed1c000
/* IO Port base */
#define ACPI_BASE_ADDRESS 0x0400
#define GPIO_BASE_ADDRESS 0x0500
#define SMBUS_BASE_ADDRESS 0xefa0
#endif /* _BAYTRAIL_IOMAP_H_ */

View File

@ -0,0 +1,111 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google, 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 wacbmem_entryanty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _BAYTRAIL_IOSF_H_
#define _BAYTRAIL_IOSF_H_
#include <stdint.h>
#include <baytrail/pci_devs.h>
/*
* The Bay Trail SoC has a message network called IOSF Sideband. The access
* routines are through 3 registers in PCI config space of 00:00.0:
* MCR - control register
* MDR - data register
* MCRX - control register extension
* The extension regist is only used for addresses that don't fit into the
* 8 bit register address.
*/
#ifndef PCI_DEV
#define PCI_DEV(SEGBUS, DEV, FN) ( \
(((SEGBUS) & 0xFFF) << 20) | \
(((DEV) & 0x1F) << 15) | \
(((FN) & 0x07) << 12))
#endif
#define IOSF_PCI_DEV PCI_DEV(0,SOC_DEV,SOC_FUNC)
#define MCR_REG 0xd0
#define IOSF_OPCODE(x) ((x) << 24)
#define IOSF_PORT(x) ((0xff & (x)) << 16)
#define IOSF_REG(x) ((0xff & (x)) << 8)
#define IOSF_BYTE_EN 0xf0
#define MDR_REG 0xd4
#define MCRX_REG 0xd8
uint32_t iosf_bunit_read(int reg);
void iosf_bunit_write(int reg, uint32_t val);
/* IOSF ports. */
#define IOSF_PORT_AUNIT 0x00 /* IO Arbiter unit */
#define IOSF_PORT_SYSMEMC 0x01 /* System Memory Controller */
#define IOSF_PORT_CPU_BUS 0x02 /* CPU Bus Interface Controller */
#define IOSF_PORT_BUNIT 0x03 /* System Memroy Arbiter/Bunit */
#define IOSF_PORT_PMC 0x04 /* Power Management Controller */
#define IOSF_PORT_GFX 0x06 /* Graphics Adapter */
#define IOSF_PORT_SYSMEMIO 0x0c /* System Memory IO */
#define IOSF_PORT_USBPHY 0x43 /* USB PHY */
#define IOSF_PORT_SATAPHY 0xa3 /* SATA PHY */
#define IOSF_PORT_PCIEPHY 0xa3 /* PCIE PHY */
/* Read and write opcodes differ per port. */
#define IOSF_OP_READ_AUNIT 0x10
#define IOSF_OP_WRITE_AUNIT (IOSF_OP_READ_AUNIT | 1)
#define IOSF_OP_READ_SYSMEMC 0x10
#define IOSF_OP_WRITE_SYSMEMC (IOSF_OP_READ_SYSMEMC | 1)
#define IOSF_OP_READ_CPU_BUS 0x10
#define IOSF_OP_WRITE_CPU_BUS (IOSF_OP_READ_CPU_BUS | 1)
#define IOSF_OP_READ_BUNIT 0x10
#define IOSF_OP_WRITE_BUNIT (IOSF_OP_READ_BUNIT | 1)
#define IOSF_OP_READ_PMC 0x06
#define IOSF_OP_WRITE_PMC (IOSF_OP_READ_PMC | 1)
#define IOSF_OP_READ_GFX 0x00
#define IOSF_OP_WRITE_GFX (IOSF_OP_READ_GFX | 1)
#define IOSF_OP_READ_SYSMEMIO 0x06
#define IOSF_OP_WRITE_SYSMEMIO (IOSF_OP_READ_SYSMEMIO | 1)
#define IOSF_OP_READ_USBPHY 0x06
#define IOSF_OP_WRITE_USBPHY (IOSF_OP_READ_USBPHY | 1)
#define IOSF_OP_READ_SATAPHY 0x00
#define IOSF_OP_WRITE_SATAPHY (IOSF_OP_READ_SATAPHY | 1)
#define IOSF_OP_READ_PCIEPHY 0x00
#define IOSF_OP_WRITE_PCIEPHY (IOSF_OP_READ_PCIEPHY | 1)
/*
* BUNIT Registers.
*/
#define BNOCACHE 0x23
/* BMBOUND has a 128MiB granularity. Highest address is 0xf8000000. */
#define BUNIT_BMBOUND 0x25
/* BMBOUND_HI describes the available ram above 4GiB. It has a
* 256MiB granularity. Physical address bits 35:28 are compared with 31:24
* bits in the BMBOUND_HI register. Also note that since BMBOUND has 128MiB
* granularity care needs to be taken with the e820 map to account for a hole
* in the ram. */
#define BUNIT_BMBOUND_HI 0x26
#define BUNIT_MMCONF_REG 0x27
/* The SMMRR registers define the SMM region in MiB granularity. */
#define BUNIT_SMRRL 0x2e
#define BUNIT_SMRRH 0x2f
# define BUNIT_SMRR_ENABLE (1 << 31)
#endif /* _BAYTRAIL_IOSF_H_ */

View File

@ -0,0 +1,34 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _BAYTRAIL_LPC_H_
#define _BAYTRAIL_LPC_H_
/* PCI config registers in LPC bridge. */
#define ABASE 0x40
#define PBASE 0x44
#define GBASE 0x48
#define IOBASE 0x4c
#define IBASE 0x50
#define SBASE 0x54
#define MPBASE 0x58
#define UART_CONT 0x80
#define RCBA 0xf0
#endif /* _BAYTRAIL_LPC_H_ */

View File

@ -0,0 +1,40 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _MRC_CACHE_H_
#define _MRC_CACHE_H_
#include <stddef.h>
#include <stdint.h>
/* Wrapper object to save MRC information. */
struct mrc_saved_data {
uint32_t signature;
uint32_t size;
uint32_t checksum;
uint32_t reserved;
uint8_t data[0];
} __attribute__((packed));
/* Locate the most recently saved MRC data. */
int mrc_cache_get_current(const struct mrc_saved_data **cache);
/* Stash the resulting MRC data to be saved in non-volatile storage later. */
int mrc_cache_stash_data(void *data, size_t size);
#endif /* _MRC_CACHE_H_ */

View File

@ -0,0 +1,88 @@
/*
* MRC wrapper definitions
*
* Copyright 2013 Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Google Inc. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MRC_WRAPPER_H_
#define _MRC_WRAPPER_H_
#define MRC_PARAMS_VER 1
#define NUM_CHANNELS 2
enum {
DRAM_INFO_SPD_SMBUS, /* Use the typical SPD smbus access. */
DRAM_INFO_SPD_MEM, /* SPD info in memory. */
DRAM_INFO_DETAILED, /* Timing info not in SPD format. */
};
enum dram_type {
DRAM_DDR3,
DRAM_DDR3L,
DRAM_LPDDR3,
};
/* Errors returned by the MRC wrapper. */
enum mrc_wrapper_error {
INVALID_VER = -1,
INVALID_DRAM_TYPE = -2,
INVALID_SLEEP_MODE = -3,
PLATFORM_SETTINGS_FAIL = -4,
DIMM_DETECTION_FAILURE = -5,
MEMORY_CONFIG_FAILURE = -6,
};
struct mrc_mainboard_params {
int dram_type;
int dram_info_location; /* DRAM_INFO_* */
int spd_addrs[NUM_CHANNELS];
void *dram_data[NUM_CHANNELS]; /* SPD or Timing specific data. */
} __attribute__((packed));
struct mrc_params {
/* Mainboard Inputs */
int version;
struct mrc_mainboard_params mainboard;
void (*console_out)(unsigned char byte);
int prev_sleep_state;
int saved_data_size;
const void *saved_data;
int txe_size_mb; /* TXE memory size in megabytes. */
/* Outputs */
void *txe_base_address;
int data_to_save_size;
void *data_to_save;
} __attribute__((packed));
/* Call into wrapper. */
typedef int (*mrc_wrapper_entry_t)(struct mrc_params *);
#endif /* _MRC_WRAPPER_H_ */

View File

@ -0,0 +1,25 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google, 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 wacbmem_entryanty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _BAYTRAIL_MSR_H_
#define _BAYTRAIL_MSR_H_
#define MSR_PLATFORM_INFO 0xce
#endif /* _BAYTRAIL_IOSF_H_ */

View File

@ -0,0 +1,34 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _NVM_H_
#define _NVM_H_
#include <stddef.h>
/* Determine if area is erased. returns 1 if erased. 0 otherwise. */
int nvm_is_erased(const void *start, size_t size);
/* Erase region according to start and size. Returns < 0 on error else 0. */
int nvm_erase(void *start, size_t size);
/* Write data to NVM. Returns 0 on success < 0 on error. */
int nvm_write(void *start, const void *data, size_t size);
#endif /* _NVM_H_ */

View File

@ -0,0 +1,136 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2009 coresystems GmbH
* Copyright (C) 2011 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "vendorcode/google/chromeos/gnvs.h"
typedef struct {
/* Miscellaneous */
u16 osys; /* 0x00 - Operating System */
u8 smif; /* 0x02 - SMI function call ("TRAP") */
u8 prm0; /* 0x03 - SMI function call parameter */
u8 prm1; /* 0x04 - SMI function call parameter */
u8 scif; /* 0x05 - SCI function call (via _L00) */
u8 prm2; /* 0x06 - SCI function call parameter */
u8 prm3; /* 0x07 - SCI function call parameter */
u8 lckf; /* 0x08 - Global Lock function for EC */
u8 prm4; /* 0x09 - Lock function parameter */
u8 prm5; /* 0x0a - Lock function parameter */
u32 p80d; /* 0x0b - Debug port (IO 0x80) value */
u8 lids; /* 0x0f - LID state (open = 1) */
u8 pwrs; /* 0x10 - Power state (AC = 1) */
/* Thermal policy */
u8 tlvl; /* 0x11 - Throttle Level Limit */
u8 flvl; /* 0x12 - Current FAN Level */
u8 tcrt; /* 0x13 - Critical Threshold */
u8 tpsv; /* 0x14 - Passive Threshold */
u8 tmax; /* 0x15 - CPU Tj_max */
u8 f0of; /* 0x16 - FAN 0 OFF Threshold */
u8 f0on; /* 0x17 - FAN 0 ON Threshold */
u8 f0pw; /* 0x18 - FAN 0 PWM value */
u8 f1of; /* 0x19 - FAN 1 OFF Threshold */
u8 f1on; /* 0x1a - FAN 1 ON Threshold */
u8 f1pw; /* 0x1b - FAN 1 PWM value */
u8 f2of; /* 0x1c - FAN 2 OFF Threshold */
u8 f2on; /* 0x1d - FAN 2 ON Threshold */
u8 f2pw; /* 0x1e - FAN 2 PWM value */
u8 f3of; /* 0x1f - FAN 3 OFF Threshold */
u8 f3on; /* 0x20 - FAN 3 ON Threshold */
u8 f3pw; /* 0x21 - FAN 3 PWM value */
u8 f4of; /* 0x22 - FAN 4 OFF Threshold */
u8 f4on; /* 0x23 - FAN 4 ON Threshold */
u8 f4pw; /* 0x24 - FAN 4 PWM value */
u8 tmps; /* 0x25 - Temperature Sensor ID */
u8 rsvd3[2];
/* Processor Identification */
u8 apic; /* 0x28 - APIC enabled */
u8 mpen; /* 0x29 - MP capable/enabled */
u8 pcp0; /* 0x2a - PDC CPU/CORE 0 */
u8 pcp1; /* 0x2b - PDC CPU/CORE 1 */
u8 ppcm; /* 0x2c - Max. PPC state */
u8 pcnt; /* 0x2d - Processor Count */
u8 rsvd4[4];
/* Super I/O & CMOS config */
u8 natp; /* 0x32 - SIO type */
u8 s5u0; /* 0x33 - Enable USB0 in S5 */
u8 s5u1; /* 0x34 - Enable USB1 in S5 */
u8 s3u0; /* 0x35 - Enable USB0 in S3 */
u8 s3u1; /* 0x36 - Enable USB1 in S3 */
u8 s33g; /* 0x37 - Enable S3 in 3G */
u32 cmem; /* 0x38 - CBMEM TOC */
/* Integrated Graphics Device */
u8 igds; /* 0x3c - IGD state */
u8 tlst; /* 0x3d - Display Toggle List Pointer */
u8 cadl; /* 0x3e - currently attached devices */
u8 padl; /* 0x3f - previously attached devices */
u16 cste; /* 0x40 - current display state */
u16 nste; /* 0x42 - next display state */
u16 sste; /* 0x44 - set display state */
u8 ndid; /* 0x46 - number of device ids */
u32 did[5]; /* 0x47 - 5b device id 1..5 */
/* TPM support */
u8 tpmp; /* 0x5b - TPM Present */
u8 tpme; /* 0x5c - TPM Enable */
u8 rsvd5[3];
/* LynxPoint Serial IO device BARs */
u32 s0b[8]; /* 0x60 - 0x7f - BAR0 */
u32 s1b[8]; /* 0x80 - 0x9f - BAR1 */
u32 cbmc; /* 0xa0 - 0xa3 - coreboot memconsole */
u8 rsvd6[16];
/* IGD OpRegion (not implemented yet) */
u32 aslb; /* 0xb4 - IGD OpRegion Base Address */
u8 ibtt; /* 0xb8 - IGD boot type */
u8 ipat; /* 0xb9 - IGD panel type */
u8 itvf; /* 0xba - IGD TV format */
u8 itvm; /* 0xbb - IGD TV minor format */
u8 ipsc; /* 0xbc - IGD Panel Scaling */
u8 iblc; /* 0xbd - IGD BLC configuration */
u8 ibia; /* 0xbe - IGD BIA configuration */
u8 issc; /* 0xbf - IGD SSC configuration */
u8 i409; /* 0xc0 - IGD 0409 modified settings */
u8 i509; /* 0xc1 - IGD 0509 modified settings */
u8 i609; /* 0xc2 - IGD 0609 modified settings */
u8 i709; /* 0xc3 - IGD 0709 modified settings */
u8 idmm; /* 0xc4 - IGD Power Conservation */
u8 idms; /* 0xc5 - IGD DVMT memory size */
u8 if1e; /* 0xc6 - IGD Function 1 Enable */
u8 hvco; /* 0xc7 - IGD HPLL VCO */
u32 nxd[8]; /* 0xc8 - IGD next state DIDx for _DGS */
u8 isci; /* 0xe8 - IGD SMI/SCI mode (0: SCI) */
u8 pavp; /* 0xe9 - IGD PAVP data */
u8 rsvd12; /* 0xea - rsvd */
u8 oscc; /* 0xeb - PCIe OSC control */
u8 npce; /* 0xec - native pcie support */
u8 plfl; /* 0xed - platform flavor */
u8 brev; /* 0xee - board revision */
u8 dpbm; /* 0xef - digital port b mode */
u8 dpcm; /* 0xf0 - digital port c mode */
u8 dpdm; /* 0xf1 - digital port c mode */
u8 alfp; /* 0xf2 - active lfp */
u8 imon; /* 0xf3 - current graphics turbo imon value */
u8 mmio; /* 0xf4 - 64bit mmio support */
u8 rsvd13[11]; /* 0xf5 - rsvd */
/* ChromeOS specific (starts at 0x100)*/
chromeos_acpi_t chromeos;
} __attribute__((packed)) global_nvs_t;
#ifdef __SMM__
/* Used in SMM to find the ACPI GNVS address */
global_nvs_t *smm_get_gnvs(void);
#endif

View File

@ -0,0 +1,149 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _BAYTRAIL_PCI_DEVS_H_
#define _BAYTRAIL_PCI_DEVS_H_
/* All these devices live on bus 0 with the associated device and function */
/* SoC transaction router */
#define SOC_DEV 0
#define SOC_FUNC 0
# define SOC_DEVID 0x0f00
/* Graphics and Display */
#define GFX_DEV 2
#define GFX_FUNC 0
# define GFX_DEVID 0x0f31
/* MMC Port */
#define MMC_DEV 16
#define MMC_FUNC 0
# define MMC_DEVID 0x0f14
/* SDIO Port */
#define SDIO_DEV 17
#define SDIO_FUNC 0
# define SDIO_DEVID 0x0f15
/* SD Port */
#define SD_DEV 18
#define SD_FUNC 0
# define SD_DEVID 0x0f16
/* SATA */
#define SATA_DEV 19
#define SATA_FUNC 0
# define ACHI1_DEVID 0x0f22
# define ACHI2_DEVID 0x0f23
/* xHCI */
#define XHCI_DEV 20
#define XHCI_FUNC 0
# define XCHI_DEVID 0x0f35
/* LPE Audio */
#define LPE_DEV 21
#define LPE_FUNC 0
# define LPE_DEVID 0x0f28
/* Serial IO 1 */
#define SIO1_DEV 24
# define SIO_DMA1_DEV SIO1_DEV
# define SIO_DMA1_FUNC 0
# define SIO_DMA1_DEVID 0x0f40
# define I2C1_DEV SIO1_DEV
# define I2C1_FUNC 1
# define I2C1_DEVID 0x0f41
# define I2C2_DEV SIO1_DEV
# define I2C2_FUNC 2
# define I2C2_DEVID 0x0f42
# define I2C3_DEV SIO1_DEV
# define I2C3_FUNC 3
# define I2C3_DEVID 0x0f43
# define I2C4_DEV SIO1_DEV
# define I2C4_FUNC 4
# define I2C4_DEVID 0x0f44
# define I2C5_DEV SIO1_DEV
# define I2C5_FUNC 5
# define I2C5_DEVID 0x0f45
# define I2C6_DEV SIO1_DEV
# define I2C6_FUNC 6
# define I2C6_DEVID 0x0f46
# define I2C7_DEV SIO1_DEV
# define I2C7_FUNC 7
# define I2C7_DEVID 0x0f47
/* Trusted Execution Engine */
#define TXE_DEV 26
#define TXE_FUNC 0
# define TXE_DEVID 0x0f18
/* HD Audio */
#define HDA_DEV 27
#define HDA_FUNC 0
# define HDA_DEVID 0x0f04
/* PCIe Ports */
#define PCIE_DEV 28
# define PCIE_PORT1_FUNC 0
# define PCIE_PORT1_DEVID 0x0f48
# define PCIE_PORT2_FUNC 1
# define PCIE_PORT2_DEVID 0x0f4a
# define PCIE_PORT3_FUNC 2
# define PCIE_PORT3_DEVID 0x0f4c
# define PCIE_PORT4_FUNC 3
# define PCIE_PORT4_DEVID 0x0f4e
/* EHCI */
#define EHCI_DEV 29
#define EHCI_FUNC 29
# define EHCI_DEVID 0x0f34
/* Serial IO 2 */
#define SIO2_DEV 30
# define SIO_DMA2_DEV SIO2_DEV
# define SIO_DMA2_FUNC 0
# define SIO_DMA2_DEVID 0x0f06
# define PWM1_DEV SIO2_DEV
# define PWM1_FUNC 1
# define PWM1_DEVID 0x0f08
# define PWM2_DEV SIO2_DEV
# define PWM2_FUNC 2
# define PWM2_DEVID 0x0f09
# define HSUART1_DEV SIO2_DEV
# define HSUART1_FUNC 3
# define HSUART1_DEVID 0x0f0a
# define HSUART2_DEV SIO2_DEV
# define HSUART2_FUNC 4
# define HSUART2_DEVID 0x0f0c
# define SPI_DEV SIO2_DEV
# define SPI_FUNC 5
# define SPI_DEVID 0xf0e
/* Platform Controller Unit */
#define PCU_DEV 31
# define LPC_DEV PCU_DEV
# define LPC_FUNC 0
# define LPC_DEVID 0x0f1c
# define SMBUS_DEV PCU_DEV
# define SMBUS_FUNC 3
# define SMBUS_DEVID 0x0f12
#endif /* _BAYTRAIL_PCI_DEVS_H_ */

View File

@ -0,0 +1,30 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _BAYTRAIL_PMC_H_
#define _BAYTRAIL_PMC_H_
#define IOCOM1 0x3f8
/* Memory mapped IO registers behind PMC_BASE_ADDRESS */
#define GEN_PMCONF1 0x20
# define UART_EN (1 << 24)
#endif /* _BAYTRAIL_PMC_H_ */

View File

@ -0,0 +1,46 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _BAYTRAIL_ROMSTAGE_H_
#define _BAYTRAIL_ROMSTAGE_H_
#if !defined(__PRE_RAM__)
#error "Don't include romstage.h from a ramstage compilation unit!"
#endif
#include <arch/cpu.h>
#include <baytrail/mrc_wrapper.h>
struct romstage_params {
struct mrc_params *mrc_params;
};
void mainboard_romstage_entry(unsigned long bist);
void romstage_common(const struct romstage_params *params);
void * asmlinkage romstage_main(unsigned long bist);
void asmlinkage romstage_after_car(void);
void raminit(struct mrc_params *mp, int prev_sleep_state);
#if CONFIG_ENABLE_BUILTIN_COM1
void byt_config_com1_and_enable(void);
#else
static inline void byt_config_com1_and_enable(void) { }
#endif
#endif /* _BAYTRAIL_ROMSTAGE_H_ */

View File

@ -0,0 +1,39 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google, 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 wacbmem_entryanty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <arch/io.h>
#include <baytrail/iosf.h>
static void bootblock_cpu_init(void)
{
uint32_t reg;
/* Set up the MMCONF range. The register lives in the BUNIT. The
* IO variant of the config access needs to be used initially to
* properly configure as the IOSF access registers live in PCI
* config space. */
reg = 0;
/* Clear the extended register. */
pci_io_write_config32(IOSF_PCI_DEV, MCRX_REG, reg);
reg = CONFIG_MMCONF_BASE_ADDRESS | 1;
pci_io_write_config32(IOSF_PCI_DEV, MDR_REG, reg);
reg = IOSF_OPCODE(IOSF_OP_WRITE_BUNIT) | IOSF_PORT(IOSF_PORT_BUNIT) |
IOSF_REG(BUNIT_MMCONF_REG) | IOSF_BYTE_EN;
pci_io_write_config32(IOSF_PCI_DEV, MCR_REG, reg);
}

View File

@ -0,0 +1,74 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <arch/pci_ops.h>
#include <baytrail/pci_devs.h>
#include <baytrail/ramstage.h>
#include "chip.h"
static void pci_domain_set_resources(device_t dev)
{
assign_resources(dev->link_list);
}
static struct device_operations pci_domain_ops = {
.read_resources = pci_domain_read_resources,
.set_resources = pci_domain_set_resources,
.enable_resources = NULL,
.init = NULL,
.scan_bus = pci_domain_scan_bus,
.ops_pci_bus = pci_bus_default_ops,
};
static void cpu_bus_init(device_t dev)
{
printk(BIOS_DEBUG, "cpu_bus_init()\n");
}
static void cpu_bus_noop(device_t dev) { }
static struct device_operations cpu_bus_ops = {
.read_resources = cpu_bus_noop,
.set_resources = cpu_bus_noop,
.enable_resources = cpu_bus_noop,
.init = cpu_bus_init,
.scan_bus = 0,
};
static void enable_dev(device_t dev)
{
printk(BIOS_DEBUG, "enable_dev(%s, %d)\n",
dev_name(dev), dev->path.type);
/* Set the operations if it is a special bus type */
if (dev->path.type == DEVICE_PATH_DOMAIN) {
dev->ops = &pci_domain_ops;
} else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
dev->ops = &cpu_bus_ops;
}
}
struct chip_operations soc_intel_baytrail_ops = {
CHIP_NAME("Intel BayTrail SoC")
.enable_dev = enable_dev,
};

View File

@ -0,0 +1,29 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _BAYTRAIL_CHIP_H_
#define _BAYTRAIL_CHIP_H_
/* The devicetree parser expects chip.h to reside directly in the path
* specified by the devicetree. */
struct soc_intel_baytrail_config {
};
extern struct chip_operations soc_intel_baytrail_ops;
#endif /* _BAYTRAIL_CHIP_H_ */

View File

@ -0,0 +1,61 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google, 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 wacbmem_entryanty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <arch/io.h>
#include <baytrail/iosf.h>
#if !defined(__PRE_RAM__)
#define IOSF_PCI_BASE (CONFIG_MMCONF_BASE_ADDRESS + (IOSF_PCI_DEV << 12))
static inline void write_iosf_reg(int reg, uint32_t value)
{
write32(IOSF_PCI_BASE + reg, value);
}
static inline uint32_t read_iosf_reg(int reg)
{
return read32(IOSF_PCI_BASE + reg);
}
#else
static inline void write_iosf_reg(int reg, uint32_t value)
{
pci_write_config32(IOSF_PCI_DEV, reg, value);
}
static inline uint32_t read_iosf_reg(int reg)
{
return pci_read_config32(IOSF_PCI_DEV, reg);
}
#endif
uint32_t iosf_bunit_read(int reg)
{
uint32_t cr = IOSF_OPCODE(IOSF_OP_READ_BUNIT) |
IOSF_PORT(IOSF_PORT_BUNIT) | IOSF_REG(reg) | IOSF_BYTE_EN;
write_iosf_reg(MCR_REG, cr);
return read_iosf_reg(MDR_REG);
}
void iosf_bunit_write(int reg, uint32_t val)
{
uint32_t cr = IOSF_OPCODE(IOSF_OP_WRITE_BUNIT) |
IOSF_PORT(IOSF_PORT_BUNIT) | IOSF_REG(reg) | IOSF_BYTE_EN;
write_iosf_reg(MCR_REG, cr);
write_iosf_reg(MDR_REG, val);
}

View File

@ -0,0 +1,27 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google, 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 wacbmem_entryanty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <arch/io.h>
#include <cbmem.h>
#include <baytrail/iosf.h>
unsigned long get_top_of_ram(void)
{
return (unsigned long)(iosf_bunit_read(BUNIT_SMRRL) << 20);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c

View File

@ -0,0 +1,3 @@
unsigned microcode[] = {
#include "M0C3067_0000030f.h"
};

View File

@ -0,0 +1,294 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string.h>
#include <console/console.h>
#include <cbmem.h>
#include <ip_checksum.h>
#if CONFIG_CHROMEOS
#include <vendorcode/google/chromeos/fmap.h>
#endif
#include <baytrail/mrc_cache.h>
#define MRC_DATA_ALIGN 0x1000
#define MRC_DATA_SIGNATURE (('M'<<0)|('R'<<8)|('C'<<16)|('D'<<24))
/* The mrc_data_region describes the larger non-volatile area to store
* mrc_saved_data objects.*/
struct mrc_data_region {
void *base;
uint32_t size;
};
/* common code */
static int mrc_cache_get_region(struct mrc_data_region *region)
{
#if CONFIG_CHROMEOS
int ret;
ret = find_fmap_entry("RW_MRC_CACHE", &region->base);
if (ret >= 0) {
region->size = ret;
return 0;
}
#endif
region->base = (void *)CONFIG_MRC_SETTINGS_CACHE_BASE;
region->size = CONFIG_MRC_SETTINGS_CACHE_SIZE;
return 0;
}
static int mrc_cache_in_region(const struct mrc_data_region *region,
const struct mrc_saved_data *cache)
{
uintptr_t region_end;
uintptr_t cache_end;
if ((uintptr_t)cache < (uintptr_t)region->base)
return 0;
region_end = (uintptr_t)region->base;
region_end += region->size;
if ((uintptr_t)cache >= region_end)
return 0;
if ((sizeof(*cache) + (uintptr_t)cache) >= region_end)
return 0;
cache_end = (uintptr_t)cache;
cache_end += cache->size + sizeof(*cache);
if (cache_end > region_end)
return 0;
return 1;
}
static int mrc_cache_valid(const struct mrc_data_region *region,
const struct mrc_saved_data *cache)
{
uint32_t checksum;
if (cache->signature != MRC_DATA_SIGNATURE)
return 0;
if (cache->size > region->size)
return 0;
if (cache->reserved != 0)
return 0;
checksum = compute_ip_checksum((void *)&cache->data[0], cache->size);
if (cache->checksum != checksum)
return 0;
return 1;
}
static const struct mrc_saved_data *
next_cache_block(const struct mrc_saved_data *cache)
{
uintptr_t next = (uintptr_t)cache;
next += ALIGN(cache->size + sizeof(*cache), MRC_DATA_ALIGN);
return (const struct mrc_saved_data *)next;
}
/* Locate the most recently saved MRC data. */
static int __mrc_cache_get_current(const struct mrc_data_region *region,
const struct mrc_saved_data **cache)
{
const struct mrc_saved_data *msd;
const struct mrc_saved_data *verified_cache;
msd = region->base;
verified_cache = NULL;
while (mrc_cache_in_region(region, msd) &&
mrc_cache_valid(region, msd)) {
verified_cache = msd;
msd = next_cache_block(msd);
}
if (verified_cache == NULL)
return -1;
*cache = verified_cache;
return 0;
}
int mrc_cache_get_current(const struct mrc_saved_data **cache)
{
struct mrc_data_region region;
if (mrc_cache_get_region(&region) < 0)
return -1;
return __mrc_cache_get_current(&region, cache);
}
#if defined(__PRE_RAM__)
/* romstage code */
/* Fill in mrc_saved_data structure with payload. */
static void mrc_cache_fill(struct mrc_saved_data *cache, void *data,
size_t size)
{
cache->signature = MRC_DATA_SIGNATURE;
cache->size = size;
cache->reserved = 0;
memcpy(&cache->data[0], data, size);
cache->checksum = compute_ip_checksum((void *)&cache->data[0],
cache->size);
}
int mrc_cache_stash_data(void *data, size_t size)
{
int cbmem_size;
struct mrc_saved_data *cache;
cbmem_size = sizeof(*cache) + ALIGN(size, 16);
cache = cbmem_add(CBMEM_ID_MRCDATA, cbmem_size);
if (cache == NULL) {
printk(BIOS_ERR, "No space in cbmem for MRC data.\n");
return -1;
}
/* Clear alignment padding bytes. */
memset(&cache->data[size], 0, cbmem_size - size);
printk(BIOS_DEBUG, "Relocate MRC DATA from %p to %p (%zu bytes)\n",
data, cache, size);
mrc_cache_fill(cache, data, size);
return 0;
}
#else
/* ramstage code */
#include <bootstate.h>
#include <baytrail/nvm.h>
static int mrc_slot_valid(const struct mrc_data_region *region,
const struct mrc_saved_data *slot,
const struct mrc_saved_data *to_save)
{
uintptr_t region_begin;
uintptr_t region_end;
uintptr_t slot_end;
uintptr_t slot_begin;
uint32_t size;
region_begin = (uintptr_t)region->base;
region_end = region_begin + region->size;
slot_begin = (uintptr_t)slot;
size = to_save->size + sizeof(*to_save);
slot_end = slot_begin + size;
if (slot_begin < region_begin || slot_begin > region_end)
return 0;
if (size > region->size)
return 0;
if (slot_end > region_end || slot_end < region_begin)
return 0;
if (!nvm_is_erased(slot, size))
return 0;
return 1;
}
static const struct mrc_saved_data *
mrc_cache_next_slot(const struct mrc_data_region *region,
const struct mrc_saved_data *current_slot)
{
const struct mrc_saved_data *next_slot;
if (current_slot == NULL) {
next_slot = region->base;
} else {
next_slot = next_cache_block(current_slot);
}
return next_slot;
}
static void update_mrc_cache(void *unused)
{
const struct mrc_saved_data *current_boot;
const struct mrc_saved_data *current_saved;
const struct mrc_saved_data *next_slot;
struct mrc_data_region region;
printk(BIOS_DEBUG, "Updating MRC cache data.\n");
current_boot = cbmem_find(CBMEM_ID_MRCDATA);
if (!current_boot) {
printk(BIOS_ERR, "No MRC cache in cbmem.\n");
return;
}
if (mrc_cache_get_region(&region)) {
printk(BIOS_ERR, "Could not obtain MRC cache region.\n");
return;
}
if (!mrc_cache_valid(&region, current_boot)) {
printk(BIOS_ERR, "MRC cache data in cbmem invalid.\n");
return;
}
current_saved = NULL;
if (!__mrc_cache_get_current(&region, &current_saved)) {
if (current_saved->size == current_boot->size &&
!memcmp(&current_saved->data[0], &current_boot->data[0],
current_saved->size)) {
printk(BIOS_DEBUG, "MRC cache up to date.\n");
return;
}
}
next_slot = mrc_cache_next_slot(&region, current_saved);
if (!mrc_slot_valid(&region, next_slot, current_boot)) {
if (nvm_erase(region.base, region.size) < 0) {
printk(BIOS_DEBUG, "Could not erase MRC region.\n");
return;
}
next_slot = region.base;
}
nvm_write((void *)next_slot, current_boot,
current_boot->size + sizeof(*current_boot));
}
BOOT_STATE_INIT_ENTRIES(mrc_cache_update) = {
BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY,
update_mrc_cache, NULL),
};
#endif /* defined(__PRE_RAM__) */

View File

@ -0,0 +1,83 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
#include <stddef.h>
#include <console/console.h>
#include <string.h>
#include <spi-generic.h>
#include <spi_flash.h>
#include <baytrail/nvm.h>
/* This module assumes the flash is memory mapped just below 4GiB in the
* address space for reading. Also this module assumes an area it erased
* when all bytes read as all 0xff's. */
static struct spi_flash *flash;
static int nvm_init(void)
{
if (flash != NULL)
return 0;
spi_init();
flash = spi_flash_probe(0, 0, 1000000, SPI_MODE_3);
if (!flash) {
printk(BIOS_DEBUG, "Could not find SPI device\n");
return -1;
}
return 0;
}
/* Convert memory mapped pointer to flash offset. */
static inline uint32_t to_flash_offset(void *p)
{
return CONFIG_ROM_SIZE + (uintptr_t)p;
}
int nvm_is_erased(const void *start, size_t size)
{
const char *cur = start;
while (size > 0) {
if (*cur != 0xff)
return 0;
cur++;
size--;
}
return 1;
}
int nvm_erase(void *start, size_t size)
{
if (nvm_init() < 0)
return -1;
flash->erase(flash, to_flash_offset(start), size);
return 0;
}
/* Write data to NVM. Returns 0 on success < 0 on error. */
int nvm_write(void *start, const void *data, size_t size)
{
if (nvm_init() < 0)
return -1;
flash->write(flash, to_flash_offset(start), size, data);
return 0;
}

View File

@ -0,0 +1,21 @@
#include <arch/acpi.h>
#include <cpu/cpu.h>
#include <device/pci_rom.h>
#include <baytrail/acpi.h>
void generate_cpu_entries(void) {}
void acpi_create_intel_hpet(acpi_hpet_t * hpet) {}
void acpi_create_serialio_ssdt(acpi_header_t *ssdt) {}
unsigned long acpi_fill_mcfg(unsigned long current) { return current; }
void smm_setup_structures(void *gnvs, void *tcg, void *smi1) {}
void smm_init(void) {}
/* Rmodules don't like weak symbols. */
u32 map_oprom_vendev(u32 vendev) { return vendev; }

View File

@ -0,0 +1,4 @@
cpu_incs += $(src)/soc/intel/baytrail/romstage/cache_as_ram.inc
romstage-y += romstage.c
romstage-y += raminit.c
romstage-$(CONFIG_ENABLE_BUILTIN_COM1) += uart.c

View File

@ -0,0 +1,280 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
* Copyright (C) 2007-2008 coresystems GmbH
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <cpu/x86/stack.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/post_code.h>
#include <cbmem.h>
/* The full cache-as-ram size includes the cache-as-ram portion from coreboot
* and the space used by the reference code. These 2 values combined should
* be a power of 2 because the MTRR setup assumes that. */
#define CACHE_AS_RAM_SIZE \
(CONFIG_DCACHE_RAM_SIZE + CONFIG_DCACHE_RAM_MRC_VAR_SIZE)
#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
/* Enough room to cache CAR_TILE_SIZE starting at MRC_BIN_ADDRESS */
#define CACHE_MRC_BASE (CONFIG_MRC_BIN_ADDRESS)
#define CACHE_MRC_MASK (~(CONFIG_CAR_TILE_SIZE - 1))
#define CPU_PHYSMASK_HI ((1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1)
#define NoEvictMod_MSR 0x2e0
#define BBL_CR_CTL3_MSR 0x11e
#define MCG_CAP_MSR 0x179
/* Save the BIST result. */
movl %eax, %ebp
cache_as_ram:
post_code(0x20)
/* Send INIT IPI to all excluding ourself. */
movl $0x000C4500, %eax
movl $0xFEE00300, %esi
movl %eax, (%esi)
/* All CPUs need to be in Wait for SIPI state */
wait_for_sipi:
movl (%esi), %eax
bt $12, %eax
jc wait_for_sipi
post_code(0x21)
/* Configure the default memory type to uncacheable as well as disable
* fixed and variable range mtrrs. */
movl $MTRRdefType_MSR, %ecx
rdmsr
andl $(~0x00000cff), %eax
wrmsr
post_code(0x22)
/* Zero the variable MTRRs. */
movl $MCG_CAP_MSR, %ecx
rdmsr
movzx %al, %ebx
/* First variable MTRR. */
movl $0x200, %ecx
xorl %eax, %eax
xorl %edx, %edx
1:
wrmsr
inc %ecx
dec %ebx
jnz 1b
/* Zero out all fixed range and variable range MTRRs. */
movl $fixed_mtrr_table, %esi
movl $((fixed_mtrr_table_end - fixed_mtrr_table) / 2), %edi
xorl %eax, %eax
xorl %edx, %edx
1:
movw (%esi), %bx
movzx %bx, %ecx
wrmsr
add $2, %esi
dec %edi
jnz 1b
post_code(0x23)
/* Set Cache-as-RAM base address. */
movl $(MTRRphysBase_MSR(0)), %ecx
movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
xorl %edx, %edx
wrmsr
post_code(0x24)
/* Set Cache-as-RAM mask. */
movl $(MTRRphysMask_MSR(0)), %ecx
movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRRphysMaskValid), %eax
movl $CPU_PHYSMASK_HI, %edx
wrmsr
post_code(0x25)
/* Set Cache-as-RAM base address. */
movl $(MTRRphysBase_MSR(1)), %ecx
movl $(CACHE_MRC_BASE | MTRR_TYPE_WRPROT), %eax
xorl %edx, %edx
wrmsr
movl $(MTRRphysMask_MSR(1)), %ecx
movl $(CACHE_MRC_MASK | MTRRphysMaskValid), %eax
movl $CPU_PHYSMASK_HI, %edx
wrmsr
/* Enable MTRR. */
movl $MTRRdefType_MSR, %ecx
rdmsr
orl $MTRRdefTypeEn, %eax
wrmsr
post_code(0x26)
/* Enable the L2 cache. */
movl $BBL_CR_CTL3_MSR, %ecx
rdmsr
orl $0x100, %eax
wrmsr
post_code(0x27)
/* Enable cache (CR0.CD = 0, CR0.NW = 0). */
movl %cr0, %eax
andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
invd
movl %eax, %cr0
/* enable the 'no eviction' mode */
movl $NoEvictMod_MSR, %ecx
rdmsr
orl $1, %eax
wrmsr
post_code(0x28)
/* Clear the cache memory region. This will also fill up the cache */
movl $CACHE_AS_RAM_BASE, %esi
movl %esi, %edi
movl $(CACHE_AS_RAM_SIZE / 4), %ecx
xorl %eax, %eax
rep stosl
/* enable no evict mode */
movl $NoEvictMod_MSR, %ecx
rdmsr
orl $2, %eax
wrmsr
post_code(0x29)
/* Setup the stack. */
movl $(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE), %eax
movl %eax, %esp
/* Restore the BIST result. */
movl %ebp, %eax
movl %esp, %ebp
pushl %eax
before_romstage:
post_code(0x2a)
/* Call romstage.c main function. */
call romstage_main
/* Save return value from romstage_main. It contains the stack to use
* after cache-as-ram is torn down. It also contains the information
* for setting up MTRRs. */
movl %eax, %ebx
post_code(0x2b)
/* Disable cache. */
movl %cr0, %eax
orl $CR0_CacheDisable, %eax
movl %eax, %cr0
post_code(0x2c)
/* Disable MTRR. */
movl $MTRRdefType_MSR, %ecx
rdmsr
andl $(~MTRRdefTypeEn), %eax
wrmsr
invd
post_code(0x2d)
/* Disable the no eviction run state */
movl $NoEvictMod_MSR, %ecx
rdmsr
andl $~2, %eax
wrmsr
/* Disable the no eviction mode */
rdmsr
andl $~1, %eax
wrmsr
post_code(0x2e)
/* Setup stack as indicated by return value from ramstage_main(). */
movl %ebx, %esp
/* Get number of MTRRs. */
popl %ebx
movl $MTRRphysBase_MSR(0), %ecx
1:
testl %ebx, %ebx
jz 1f
/* Low 32 bits of MTRR base. */
popl %eax
/* Upper 32 bits of MTRR base. */
popl %edx
/* Write MTRR base. */
wrmsr
inc %ecx
/* Low 32 bits of MTRR mask. */
popl %eax
/* Upper 32 bits of MTRR mask. */
popl %edx
/* Write MTRR mask. */
wrmsr
inc %ecx
dec %ebx
jmp 1b
1:
post_code(0x2f)
/* And enable cache again after setting MTRRs. */
movl %cr0, %eax
andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
movl %eax, %cr0
post_code(0x30)
/* Enable MTRR. */
movl $MTRRdefType_MSR, %ecx
rdmsr
orl $MTRRdefTypeEn, %eax
wrmsr
post_code(0x31)
__main:
post_code(POST_PREPARE_RAMSTAGE)
cld /* Clear direction flag. */
call romstage_after_car
.Lhlt:
post_code(POST_DEAD_CODE)
hlt
jmp .Lhlt
/* Fixed MTRRs */
fixed_mtrr_table:
.word 0x250, 0x258, 0x259
.word 0x268, 0x269, 0x26A
.word 0x26B, 0x26C, 0x26D
.word 0x26E, 0x26F
fixed_mtrr_table_end:

View File

@ -0,0 +1,93 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stddef.h>
#include <arch/io.h>
#include <cbfs.h>
#include <cbmem.h>
#include <console/console.h>
#include <device/pci_def.h>
#include <baytrail/gpio.h>
#include <baytrail/mrc_cache.h>
#include <baytrail/iomap.h>
#include <baytrail/pci_devs.h>
#include <baytrail/romstage.h>
static void enable_smbus(void)
{
uint32_t reg;
const uint32_t smbus_dev = PCI_DEV(0, SMBUS_DEV, SMBUS_FUNC);
/* SMBus I/O BAR */
reg = SMBUS_BASE_ADDRESS | 2;
pci_write_config32(smbus_dev, PCI_BASE_ADDRESS_4, reg);
/* Enable decode of I/O space. */
reg = pci_read_config16(smbus_dev, PCI_COMMAND);
reg |= 0x1;
pci_write_config16(smbus_dev, PCI_COMMAND, reg);
/* Enable Host Controller */
reg = pci_read_config8(smbus_dev, 0x40);
reg |= 1;
pci_write_config8(smbus_dev, 0x40, reg);
/* Configure pads to be used for SMBus */
score_select_func(PCU_SMB_CLK_PAD, 1);
score_select_func(PCU_SMB_DATA_PAD, 1);
}
void raminit(struct mrc_params *mp, int prev_sleep_state)
{
int ret;
mrc_wrapper_entry_t mrc_entry;
const struct mrc_saved_data *cache;
/* Fill in default entries. */
mp->version = MRC_PARAMS_VER;
mp->console_out = &console_tx_byte;
mp->prev_sleep_state = prev_sleep_state;
if (!mrc_cache_get_current(&cache)) {
mp->saved_data_size = cache->size;
mp->saved_data = &cache->data[0];
} else {
printk(BIOS_DEBUG, "No MRC cache found.\n");
}
mrc_entry = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "mrc.bin", 0xab,
NULL);
if (mrc_entry == NULL) {
printk(BIOS_DEBUG, "Couldn't find mrc.bin\n");
return;
}
if (mp->mainboard.dram_info_location == DRAM_INFO_SPD_SMBUS)
enable_smbus();
ret = mrc_entry(mp);
cbmem_initialize_empty();
printk(BIOS_DEBUG, "MRC Wrapper returned %d\n", ret);
printk(BIOS_DEBUG, "MRC data at %p %d bytes\n", mp->data_to_save,
mp->data_to_save_size);
if (mp->data_to_save != NULL && mp->data_to_save_size > 0)
mrc_cache_stash_data(mp->data_to_save, mp->data_to_save_size);
}

View File

@ -0,0 +1,218 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stddef.h>
#include <arch/cpu.h>
#include <arch/io.h>
#include <arch/cbfs.h>
#include <arch/stages.h>
#include <console/console.h>
#include <cbmem.h>
#include <cpu/x86/mtrr.h>
#include <romstage_handoff.h>
#include <baytrail/gpio.h>
#include <baytrail/iomap.h>
#include <baytrail/iosf.h>
#include <baytrail/lpc.h>
#include <baytrail/pci_devs.h>
#include <baytrail/romstage.h>
/* The cache-as-ram assembly file calls romstage_main() after setting up
* cache-as-ram. romstage_main() will then call the mainboards's
* mainboard_romstage_entry() function. That function then calls
* romstage_common() below. The reason for the back and forth is to provide
* common entry point from cache-as-ram while still allowing for code sharing.
* Because we can't use global variables the stack is used for allocations --
* thus the need to call back and forth. */
static void *setup_stack_and_mttrs(void);
static void program_base_addresses(void)
{
uint32_t reg;
const uint32_t lpc_dev = PCI_DEV(0, LPC_DEV, LPC_FUNC);
/* Memory Mapped IO registers. */
reg = PMC_BASE_ADDRESS | 2;
pci_write_config32(lpc_dev, PBASE, reg);
reg = IO_BASE_ADDRESS | 2;
pci_write_config32(lpc_dev, IOBASE, reg);
reg = ILB_BASE_ADDRESS | 2;
pci_write_config32(lpc_dev, IBASE, reg);
reg = SPI_BASE_ADDRESS | 2;
pci_write_config32(lpc_dev, SBASE, reg);
reg = MPHY_BASE_ADDRESS | 2;
pci_write_config32(lpc_dev, MPBASE, reg);
reg = RCBA_BASE_ADDRESS | 1;
pci_write_config32(lpc_dev, RCBA, reg);
/* IO Port Registers. */
reg = ACPI_BASE_ADDRESS | 2;
pci_write_config32(lpc_dev, ABASE, reg);
reg = GPIO_BASE_ADDRESS | 2;
pci_write_config32(lpc_dev, GBASE, reg);
}
/* Entry from cache-as-ram.inc. */
void * asmlinkage romstage_main(unsigned long bist)
{
/* Call into mainboard. */
mainboard_romstage_entry(bist);
return setup_stack_and_mttrs();
}
/* Entry from the mainboard. */
void romstage_common(const struct romstage_params *params)
{
struct romstage_handoff *handoff;
program_base_addresses();
byt_config_com1_and_enable();
console_init();
/* Initialize RAM */
raminit(params->mrc_params, 5);
handoff = romstage_handoff_find_or_add();
if (handoff != NULL)
handoff->s3_resume = 0;
else
printk(BIOS_DEBUG, "Romstage handoff structure not added!\n");
}
static void open_up_spi(void)
{
const uintptr_t sbase = SPI_BASE_ADDRESS;
/* Disable generating SMI when setting WPD bit. */
write32(sbase + 0xf8, read32(sbase + 0xf8) & ~(1 << 7));
/* Disable the SMM-only BIOS write and set WPD bit. */
write32(sbase + 0xfc, 1 | (read32(sbase + 0xfc) & ~(1 << 5)));
}
void asmlinkage romstage_after_car(void)
{
/* Allow BIOS to program SPI part. */
open_up_spi();
/* Load the ramstage. */
copy_and_run();
while (1);
}
static inline uint32_t *stack_push(u32 *stack, u32 value)
{
stack = &stack[-1];
*stack = value;
return stack;
}
/* Romstage needs quite a bit of stack for decompressing images since the lzma
* lib keeps its state on the stack during romstage. */
static unsigned long choose_top_of_stack(void)
{
unsigned long stack_top;
const unsigned long romstage_ram_stack_size = 0x5000;
/* cbmem_add() does a find() before add(). */
stack_top = (unsigned long)cbmem_add(CBMEM_ID_ROMSTAGE_RAM_STACK,
romstage_ram_stack_size);
stack_top += romstage_ram_stack_size;
return stack_top;
}
/* setup_stack_and_mttrs() determines the stack to use after
* cache-as-ram is torn down as well as the MTRR settings to use. */
static void *setup_stack_and_mttrs(void)
{
unsigned long top_of_stack;
int num_mtrrs;
uint32_t *slot;
uint32_t mtrr_mask_upper;
uint32_t top_of_ram;
/* Top of stack needs to be aligned to a 4-byte boundary. */
top_of_stack = choose_top_of_stack() & ~3;
slot = (void *)top_of_stack;
num_mtrrs = 0;
/* The upper bits of the MTRR mask need to set according to the number
* of physical address bits. */
mtrr_mask_upper = (1 << ((cpuid_eax(0x80000008) & 0xff) - 32)) - 1;
/* The order for each MTRR is value then base with upper 32-bits of
* each value coming before the lower 32-bits. The reasoning for
* this ordering is to create a stack layout like the following:
* +0: Number of MTRRs
* +4: MTRR base 0 31:0
* +8: MTRR base 0 63:32
* +12: MTRR mask 0 31:0
* +16: MTRR mask 0 63:32
* +20: MTRR base 1 31:0
* +24: MTRR base 1 63:32
* +28: MTRR mask 1 31:0
* +32: MTRR mask 1 63:32
*/
/* Cache the ROM as WP just below 4GiB. */
slot = stack_push(slot, mtrr_mask_upper); /* upper mask */
slot = stack_push(slot, ~(CONFIG_ROM_SIZE - 1) | MTRRphysMaskValid);
slot = stack_push(slot, 0); /* upper base */
slot = stack_push(slot, ~(CONFIG_ROM_SIZE - 1) | MTRR_TYPE_WRPROT);
num_mtrrs++;
/* Cache RAM as WB from 0 -> CONFIG_RAMTOP. */
slot = stack_push(slot, mtrr_mask_upper); /* upper mask */
slot = stack_push(slot, ~(CONFIG_RAMTOP - 1) | MTRRphysMaskValid);
slot = stack_push(slot, 0); /* upper base */
slot = stack_push(slot, 0 | MTRR_TYPE_WRBACK);
num_mtrrs++;
top_of_ram = (uint32_t)cbmem_top();
/* Cache 8MiB below the top of ram. The top of ram under 4GiB is the
* start of the TSEG region. It is required to be 8MiB aligned. Set
* this area as cacheable so it can be used later for ramstage before
* setting up the entire RAM as cacheable. */
slot = stack_push(slot, mtrr_mask_upper); /* upper mask */
slot = stack_push(slot, ~((8 << 20) - 1) | MTRRphysMaskValid);
slot = stack_push(slot, 0); /* upper base */
slot = stack_push(slot, (top_of_ram - (8 << 20)) | MTRR_TYPE_WRBACK);
num_mtrrs++;
/* Cache 8MiB at the top of ram. Top of ram is where the TSEG
* region resides. However, it is not restricted to SMM mode until
* SMM has been relocated. By setting the region to cacheable it
* provides faster access when relocating the SMM handler as well
* as using the TSEG region for other purposes. */
slot = stack_push(slot, mtrr_mask_upper); /* upper mask */
slot = stack_push(slot, ~((8 << 20) - 1) | MTRRphysMaskValid);
slot = stack_push(slot, 0); /* upper base */
slot = stack_push(slot, top_of_ram | MTRR_TYPE_WRBACK);
num_mtrrs++;
/* Save the number of MTRRs to setup. Return the stack location
* pointing to the number of MTRRs. */
slot = stack_push(slot, num_mtrrs);
return slot;
}

View File

@ -0,0 +1,39 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <arch/io.h>
#include <baytrail/gpio.h>
#include <baytrail/iomap.h>
#include <baytrail/lpc.h>
#include <baytrail/pci_devs.h>
#include <baytrail/romstage.h>
void byt_config_com1_and_enable(void)
{
uint32_t reg;
/* Enable the UART hardware for COM1. */
reg = 1;
pci_write_config32(PCI_DEV(0, LPC_DEV, 0), UART_CONT, reg);
/* Set up the pads to select the UART function. RXD and TXD are
* 0x520 and 0x530, respectively. */
write32(IO_BASE_ADDRESS + 0x520, read32(IO_BASE_ADDRESS + 0x520) | 1);
write32(IO_BASE_ADDRESS + 0x530, read32(IO_BASE_ADDRESS + 0x530) | 1);
}

View File

@ -0,0 +1,654 @@
/*
* Copyright (c) 2013 Google Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* 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; either version 2 of
* the License, or (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/* This file is derived from the flashrom project. */
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <delay.h>
#include <arch/io.h>
#include <console/console.h>
#include <device/pci_ids.h>
#include <spi_flash.h>
#include <baytrail/lpc.h>
#include <baytrail/pci_devs.h>
#ifdef __SMM__
#define pci_read_config_byte(dev, reg, targ)\
*(targ) = pci_read_config8(dev, reg)
#define pci_read_config_word(dev, reg, targ)\
*(targ) = pci_read_config16(dev, reg)
#define pci_read_config_dword(dev, reg, targ)\
*(targ) = pci_read_config32(dev, reg)
#define pci_write_config_byte(dev, reg, val)\
pci_write_config8(dev, reg, val)
#define pci_write_config_word(dev, reg, val)\
pci_write_config16(dev, reg, val)
#define pci_write_config_dword(dev, reg, val)\
pci_write_config32(dev, reg, val)
#else /* !__SMM__ */
#include <device/device.h>
#include <device/pci.h>
#define pci_read_config_byte(dev, reg, targ)\
*(targ) = pci_read_config8(dev, reg)
#define pci_read_config_word(dev, reg, targ)\
*(targ) = pci_read_config16(dev, reg)
#define pci_read_config_dword(dev, reg, targ)\
*(targ) = pci_read_config32(dev, reg)
#define pci_write_config_byte(dev, reg, val)\
pci_write_config8(dev, reg, val)
#define pci_write_config_word(dev, reg, val)\
pci_write_config16(dev, reg, val)
#define pci_write_config_dword(dev, reg, val)\
pci_write_config32(dev, reg, val)
#endif /* !__SMM__ */
typedef struct spi_slave ich_spi_slave;
static int ichspi_lock = 0;
typedef struct ich9_spi_regs {
uint32_t bfpr;
uint16_t hsfs;
uint16_t hsfc;
uint32_t faddr;
uint32_t _reserved0;
uint32_t fdata[16];
uint32_t frap;
uint32_t freg[5];
uint32_t _reserved1[3];
uint32_t pr[5];
uint32_t _reserved2[2];
uint8_t ssfs;
uint8_t ssfc[3];
uint16_t preop;
uint16_t optype;
uint8_t opmenu[8];
uint32_t bbar;
uint8_t _reserved3[12];
uint32_t fdoc;
uint32_t fdod;
uint8_t _reserved4[8];
uint32_t afc;
uint32_t lvscc;
uint32_t uvscc;
uint8_t _reserved5[4];
uint32_t fpb;
uint8_t _reserved6[28];
uint32_t srdl;
uint32_t srdc;
uint32_t srd;
} __attribute__((packed)) ich9_spi_regs;
typedef struct ich_spi_controller {
int locked;
uint8_t *opmenu;
int menubytes;
uint16_t *preop;
uint16_t *optype;
uint32_t *addr;
uint8_t *data;
unsigned databytes;
uint8_t *status;
uint16_t *control;
uint32_t *bbar;
} ich_spi_controller;
static ich_spi_controller cntlr;
enum {
SPIS_SCIP = 0x0001,
SPIS_GRANT = 0x0002,
SPIS_CDS = 0x0004,
SPIS_FCERR = 0x0008,
SSFS_AEL = 0x0010,
SPIS_LOCK = 0x8000,
SPIS_RESERVED_MASK = 0x7ff0,
SSFS_RESERVED_MASK = 0x7fe2
};
enum {
SPIC_SCGO = 0x000002,
SPIC_ACS = 0x000004,
SPIC_SPOP = 0x000008,
SPIC_DBC = 0x003f00,
SPIC_DS = 0x004000,
SPIC_SME = 0x008000,
SSFC_SCF_MASK = 0x070000,
SSFC_RESERVED = 0xf80000
};
enum {
HSFS_FDONE = 0x0001,
HSFS_FCERR = 0x0002,
HSFS_AEL = 0x0004,
HSFS_BERASE_MASK = 0x0018,
HSFS_BERASE_SHIFT = 3,
HSFS_SCIP = 0x0020,
HSFS_FDOPSS = 0x2000,
HSFS_FDV = 0x4000,
HSFS_FLOCKDN = 0x8000
};
enum {
HSFC_FGO = 0x0001,
HSFC_FCYCLE_MASK = 0x0006,
HSFC_FCYCLE_SHIFT = 1,
HSFC_FDBC_MASK = 0x3f00,
HSFC_FDBC_SHIFT = 8,
HSFC_FSMIE = 0x8000
};
enum {
SPI_OPCODE_TYPE_READ_NO_ADDRESS = 0,
SPI_OPCODE_TYPE_WRITE_NO_ADDRESS = 1,
SPI_OPCODE_TYPE_READ_WITH_ADDRESS = 2,
SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3
};
#if CONFIG_DEBUG_SPI_FLASH
static u8 readb_(const void *addr)
{
u8 v = read8((unsigned long)addr);
printk(BIOS_DEBUG, "read %2.2x from %4.4x\n",
v, ((unsigned) addr & 0xffff) - 0xf020);
return v;
}
static u16 readw_(const void *addr)
{
u16 v = read16((unsigned long)addr);
printk(BIOS_DEBUG, "read %4.4x from %4.4x\n",
v, ((unsigned) addr & 0xffff) - 0xf020);
return v;
}
static u32 readl_(const void *addr)
{
u32 v = read32((unsigned long)addr);
printk(BIOS_DEBUG, "read %8.8x from %4.4x\n",
v, ((unsigned) addr & 0xffff) - 0xf020);
return v;
}
static void writeb_(u8 b, const void *addr)
{
write8((unsigned long)addr, b);
printk(BIOS_DEBUG, "wrote %2.2x to %4.4x\n",
b, ((unsigned) addr & 0xffff) - 0xf020);
}
static void writew_(u16 b, const void *addr)
{
write16((unsigned long)addr, b);
printk(BIOS_DEBUG, "wrote %4.4x to %4.4x\n",
b, ((unsigned) addr & 0xffff) - 0xf020);
}
static void writel_(u32 b, const void *addr)
{
write32((unsigned long)addr, b);
printk(BIOS_DEBUG, "wrote %8.8x to %4.4x\n",
b, ((unsigned) addr & 0xffff) - 0xf020);
}
#else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */
#define readb_(a) read8((uint32_t)a)
#define readw_(a) read16((uint32_t)a)
#define readl_(a) read32((uint32_t)a)
#define writeb_(val, addr) write8((uint32_t)addr, val)
#define writew_(val, addr) write16((uint32_t)addr, val)
#define writel_(val, addr) write32((uint32_t)addr, val)
#endif /* CONFIG_DEBUG_SPI_FLASH ^^^ NOT enabled */
static void write_reg(const void *value, void *dest, uint32_t size)
{
const uint8_t *bvalue = value;
uint8_t *bdest = dest;
while (size >= 4) {
writel_(*(const uint32_t *)bvalue, bdest);
bdest += 4; bvalue += 4; size -= 4;
}
while (size) {
writeb_(*bvalue, bdest);
bdest++; bvalue++; size--;
}
}
static void read_reg(const void *src, void *value, uint32_t size)
{
const uint8_t *bsrc = src;
uint8_t *bvalue = value;
while (size >= 4) {
*(uint32_t *)bvalue = readl_(bsrc);
bsrc += 4; bvalue += 4; size -= 4;
}
while (size) {
*bvalue = readb_(bsrc);
bsrc++; bvalue++; size--;
}
}
static void ich_set_bbar(uint32_t minaddr)
{
const uint32_t bbar_mask = 0x00ffff00;
uint32_t ichspi_bbar;
minaddr &= bbar_mask;
ichspi_bbar = readl_(cntlr.bbar) & ~bbar_mask;
ichspi_bbar |= minaddr;
writel_(ichspi_bbar, cntlr.bbar);
}
int spi_cs_is_valid(unsigned int bus, unsigned int cs)
{
printk(BIOS_DEBUG, "spi_cs_is_valid used but not implemented\n");
return 0;
}
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int mode)
{
ich_spi_slave *slave = malloc(sizeof(*slave));
if (!slave) {
printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n");
return NULL;
}
memset(slave, 0, sizeof(*slave));
slave->bus = bus;
slave->cs = cs;
return slave;
}
static ich9_spi_regs *spi_regs(void)
{
device_t dev;
uint32_t sbase;
#ifdef __SMM__
dev = PCI_DEV(0, LPC_DEV, LPC_FUNC);
#else
dev = dev_find_slot(0, PCI_DEVFN(LPC_DEV, LPC_FUNC));
#endif
pci_read_config_dword(dev, SBASE, &sbase);
sbase &= ~0x1ff;
return (void *)sbase;
}
void spi_init(void)
{
ich9_spi_regs *ich9_spi = spi_regs();
ichspi_lock = readw_(&ich9_spi->hsfs) & HSFS_FLOCKDN;
cntlr.opmenu = ich9_spi->opmenu;
cntlr.menubytes = sizeof(ich9_spi->opmenu);
cntlr.optype = &ich9_spi->optype;
cntlr.addr = &ich9_spi->faddr;
cntlr.data = (uint8_t *)ich9_spi->fdata;
cntlr.databytes = sizeof(ich9_spi->fdata);
cntlr.status = &ich9_spi->ssfs;
cntlr.control = (uint16_t *)ich9_spi->ssfc;
cntlr.bbar = &ich9_spi->bbar;
cntlr.preop = &ich9_spi->preop;
ich_set_bbar(0);
}
int spi_claim_bus(struct spi_slave *slave)
{
/* Handled by ICH automatically. */
return 0;
}
void spi_release_bus(struct spi_slave *slave)
{
/* Handled by ICH automatically. */
}
void spi_cs_activate(struct spi_slave *slave)
{
/* Handled by ICH automatically. */
}
void spi_cs_deactivate(struct spi_slave *slave)
{
/* Handled by ICH automatically. */
}
typedef struct spi_transaction {
const uint8_t *out;
uint32_t bytesout;
uint8_t *in;
uint32_t bytesin;
uint8_t type;
uint8_t opcode;
uint32_t offset;
} spi_transaction;
static inline void spi_use_out(spi_transaction *trans, unsigned bytes)
{
trans->out += bytes;
trans->bytesout -= bytes;
}
static inline void spi_use_in(spi_transaction *trans, unsigned bytes)
{
trans->in += bytes;
trans->bytesin -= bytes;
}
static void spi_setup_type(spi_transaction *trans)
{
trans->type = 0xFF;
/* Try to guess spi type from read/write sizes. */
if (trans->bytesin == 0) {
if (trans->bytesout > 4)
/*
* If bytesin = 0 and bytesout > 4, we presume this is
* a write data operation, which is accompanied by an
* address.
*/
trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;
else
trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS;
return;
}
if (trans->bytesout == 1) { /* and bytesin is > 0 */
trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS;
return;
}
if (trans->bytesout == 4) { /* and bytesin is > 0 */
trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
}
/* Fast read command is called with 5 bytes instead of 4 */
if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) {
trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
--trans->bytesout;
}
}
static int spi_setup_opcode(spi_transaction *trans)
{
uint16_t optypes;
uint8_t opmenu[cntlr.menubytes];
trans->opcode = trans->out[0];
spi_use_out(trans, 1);
if (!ichspi_lock) {
/* The lock is off, so just use index 0. */
writeb_(trans->opcode, cntlr.opmenu);
optypes = readw_(cntlr.optype);
optypes = (optypes & 0xfffc) | (trans->type & 0x3);
writew_(optypes, cntlr.optype);
return 0;
} else {
/* The lock is on. See if what we need is on the menu. */
uint8_t optype;
uint16_t opcode_index;
/* Write Enable is handled as atomic prefix */
if (trans->opcode == SPI_OPCODE_WREN)
return 0;
read_reg(cntlr.opmenu, opmenu, sizeof(opmenu));
for (opcode_index = 0; opcode_index < cntlr.menubytes;
opcode_index++) {
if (opmenu[opcode_index] == trans->opcode)
break;
}
if (opcode_index == cntlr.menubytes) {
printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n",
trans->opcode);
return -1;
}
optypes = readw_(cntlr.optype);
optype = (optypes >> (opcode_index * 2)) & 0x3;
if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS &&
optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS &&
trans->bytesout >= 3) {
/* We guessed wrong earlier. Fix it up. */
trans->type = optype;
}
if (optype != trans->type) {
printk(BIOS_DEBUG, "ICH SPI: Transaction doesn't fit type %d\n",
optype);
return -1;
}
return opcode_index;
}
}
static int spi_setup_offset(spi_transaction *trans)
{
/* Separate the SPI address and data. */
switch (trans->type) {
case SPI_OPCODE_TYPE_READ_NO_ADDRESS:
case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS:
return 0;
case SPI_OPCODE_TYPE_READ_WITH_ADDRESS:
case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS:
trans->offset = ((uint32_t)trans->out[0] << 16) |
((uint32_t)trans->out[1] << 8) |
((uint32_t)trans->out[2] << 0);
spi_use_out(trans, 3);
return 1;
default:
printk(BIOS_DEBUG, "Unrecognized SPI transaction type %#x\n", trans->type);
return -1;
}
}
/*
* Wait for up to 60ms til status register bit(s) turn 1 (in case wait_til_set
* below is True) or 0. In case the wait was for the bit(s) to set - write
* those bits back, which would cause resetting them.
*
* Return the last read status value on success or -1 on failure.
*/
static int ich_status_poll(u16 bitmask, int wait_til_set)
{
int timeout = 6000; /* This will result in 60 ms */
u16 status = 0;
while (timeout--) {
status = readw_(cntlr.status);
if (wait_til_set ^ ((status & bitmask) == 0)) {
if (wait_til_set)
writew_((status & bitmask), cntlr.status);
return status;
}
udelay(10);
}
printk(BIOS_DEBUG, "ICH SPI: SCIP timeout, read %x, expected %x\n",
status, bitmask);
return -1;
}
int spi_xfer(struct spi_slave *slave, const void *dout,
unsigned int bitsout, void *din, unsigned int bitsin)
{
uint16_t control;
int16_t opcode_index;
int with_address;
int status;
spi_transaction trans = {
dout, bitsout / 8,
din, bitsin / 8,
0xff, 0xff, 0
};
/* There has to always at least be an opcode. */
if (!bitsout || !dout) {
printk(BIOS_DEBUG, "ICH SPI: No opcode for transfer\n");
return -1;
}
/* Make sure if we read something we have a place to put it. */
if (bitsin != 0 && !din) {
printk(BIOS_DEBUG, "ICH SPI: Read but no target buffer\n");
return -1;
}
/* Right now we don't support writing partial bytes. */
if (bitsout % 8 || bitsin % 8) {
printk(BIOS_DEBUG, "ICH SPI: Accessing partial bytes not supported\n");
return -1;
}
if (ich_status_poll(SPIS_SCIP, 0) == -1)
return -1;
writew_(SPIS_CDS | SPIS_FCERR, cntlr.status);
spi_setup_type(&trans);
if ((opcode_index = spi_setup_opcode(&trans)) < 0)
return -1;
if ((with_address = spi_setup_offset(&trans)) < 0)
return -1;
if (trans.opcode == SPI_OPCODE_WREN) {
/*
* Treat Write Enable as Atomic Pre-Op if possible
* in order to prevent the Management Engine from
* issuing a transaction between WREN and DATA.
*/
if (!ichspi_lock)
writew_(trans.opcode, cntlr.preop);
return 0;
}
/* Preset control fields */
control = SPIC_SCGO | ((opcode_index & 0x07) << 4);
/* Issue atomic preop cycle if needed */
if (readw_(cntlr.preop))
control |= SPIC_ACS;
if (!trans.bytesout && !trans.bytesin) {
/* SPI addresses are 24 bit only */
if (with_address)
writel_(trans.offset & 0x00FFFFFF, cntlr.addr);
/*
* This is a 'no data' command (like Write Enable), its
* bitesout size was 1, decremented to zero while executing
* spi_setup_opcode() above. Tell the chip to send the
* command.
*/
writew_(control, cntlr.control);
/* wait for the result */
status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1);
if (status == -1)
return -1;
if (status & SPIS_FCERR) {
printk(BIOS_DEBUG, "ICH SPI: Command transaction error\n");
return -1;
}
return 0;
}
/*
* Check if this is a write command atempting to transfer more bytes
* than the controller can handle. Iterations for writes are not
* supported here because each SPI write command needs to be preceded
* and followed by other SPI commands, and this sequence is controlled
* by the SPI chip driver.
*/
if (trans.bytesout > cntlr.databytes) {
printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use"
" CONTROLLER_PAGE_LIMIT?\n");
return -1;
}
/*
* Read or write up to databytes bytes at a time until everything has
* been sent.
*/
while (trans.bytesout || trans.bytesin) {
uint32_t data_length;
/* SPI addresses are 24 bit only */
writel_(trans.offset & 0x00FFFFFF, cntlr.addr);
if (trans.bytesout)
data_length = min(trans.bytesout, cntlr.databytes);
else
data_length = min(trans.bytesin, cntlr.databytes);
/* Program data into FDATA0 to N */
if (trans.bytesout) {
write_reg(trans.out, cntlr.data, data_length);
spi_use_out(&trans, data_length);
if (with_address)
trans.offset += data_length;
}
/* Add proper control fields' values */
control &= ~((cntlr.databytes - 1) << 8);
control |= SPIC_DS;
control |= (data_length - 1) << 8;
/* write it */
writew_(control, cntlr.control);
/* Wait for Cycle Done Status or Flash Cycle Error. */
status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1);
if (status == -1)
return -1;
if (status & SPIS_FCERR) {
printk(BIOS_DEBUG, "ICH SPI: Data transaction error\n");
return -1;
}
if (trans.bytesin) {
read_reg(cntlr.data, trans.in, data_length);
spi_use_in(&trans, data_length);
if (with_address)
trans.offset += data_length;
}
}
/* Clear atomic preop now that xfer is done */
writew_(0, cntlr.preop);
return 0;
}

View File

@ -0,0 +1,32 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/tsc.h>
#include <baytrail/msr.h>
#define BCLK 100 /* 100 MHz */
unsigned long tsc_freq_mhz(void)
{
msr_t platform_info;
platform_info = rdmsr(MSR_PLATFORM_INFO);
return BCLK * ((platform_info.lo >> 8) & 0xff);
}