QuarkPlatformPkg: Add new package for Galileo boards

Changes for V4
==============
1) Move delete of QuarkSocPkg\QuarkNorthCluster\Binary\QuarkMicrocode
   from QuarkPlatformPkg commit to QuarkSocPkg commit
2) Fix incorrect license header in PlatformSecLibModStrs.uni

Changes for V3
==============
1) Set PcdResetOnMemoryTypeInformationChange FALSE in QuarkMin.dsc
   This is required because QuarkMin.dsc uses the emulated variable
   driver that does not preserve any non-volatile UEFI variables
   across reset.  If the condition is met where the memory type
   information variable needs to be updated, then the system will reset
   every time the UEFI Shell is run.  By setting this PCD to FALSE,
   then reset action is disabled.
2) Move one binary file to QuarkSocBinPkg
3) Change RMU.bin FILE statements to INF statement in DSC FD region
   to be compatible with PACKAGES_PATH search for QuarkSocBinPkg

Changes for V2
==============
1) Use new generic PCI serial driver PciSioSerialDxe in MdeModulePkg
2) Configure PcdPciSerialParameters for PCI serial driver for Quark
3) Use new MtrrLib API to reduce time to set MTRRs for all DRAM
4) Convert all UNI files to utf-8
5) Replace tabs with spaces and remove trailing spaces
6) Add License.txt

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kinney <michael.d.kinney@intel.com>
Acked-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19287 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Michael Kinney
2015-12-15 19:23:57 +00:00
committed by mdkinney
parent 9b6bbcdbfd
commit b303605e1b
190 changed files with 39436 additions and 0 deletions

View File

@@ -0,0 +1,827 @@
#------------------------------------------------------------------------------
#
# Copyright (c) 2013 Intel Corporation.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
# Module Name:
#
# Flat32.S
#
# Abstract:
#
# This is the code that goes from real-mode to protected mode.
# It consumes the reset vector, configures the stack.
#
#
#------------------------------------------------------------------------------
.macro RET32
jmp *%esp
.endm
#
# ROM/SPI/MEMORY Definitions
#
.equ QUARK_DDR3_MEM_BASE_ADDRESS, (0x000000000) # Memory Base Address = 0
.equ QUARK_MAX_DDR3_MEM_SIZE_BYTES, (0x80000000) # DDR3 Memory Size = 2GB
.equ QUARK_ESRAM_MEM_SIZE_BYTES, (0x00080000) # eSRAM Memory Size = 512K
.equ QUARK_STACK_SIZE_BYTES, (0x008000) # Quark stack size = 32K
#
# RTC/CMOS definitions
#
.equ RTC_INDEX, (0x70)
.equ NMI_DISABLE, (0x80) # Bit7=1 disables NMI
.equ NMI_ENABLE, (0x00) # Bit7=0 disables NMI
.equ RTC_DATA, (0x71)
#
# PCI Configuration definitions
#
.equ PCI_CFG, (0x80000000) # PCI configuration access mechanism
.equ PCI_ADDRESS_PORT, (0xCF8)
.equ PCI_DATA_PORT, (0xCFC)
#
# Quark PCI devices
#
.equ HOST_BRIDGE_PFA, (0x0000) # B0:D0:F0 (Host Bridge)
.equ ILB_PFA, (0x00F8) # B0:D31:F0 (Legacy Block)
#
# ILB PCI Config Registers
#
.equ BDE, (0x0D4) # BIOS Decode Enable register
.equ DECODE_ALL_REGIONS_ENABLE, (0xFF000000) # Decode all BIOS decode ranges
#
# iLB Reset Register
#
.equ ILB_RESET_REG, (0x0CF9)
.equ CF9_WARM_RESET, (0x02)
.equ CF9_COLD_RESET, (0x08)
#
# Host Bridge PCI Config Registers
#
.equ MESSAGE_BUS_CONTROL_REG, (0xD0) # Message Bus Control Register
.equ SB_OPCODE_FIELD, (0x18) # Bit location of Opcode field
.equ OPCODE_SIDEBAND_REG_READ, (0x10) # Read opcode
.equ OPCODE_SIDEBAND_REG_WRITE, (0x11) # Write opcode
.equ OPCODE_SIDEBAND_ALT_REG_READ, (0x06) # Alternate Read opcode
.equ OPCODE_SIDEBAND_ALT_REG_WRITE, (0x07) # Alternate Write opcode
.equ OPCODE_WARM_RESET_REQUEST, (0xF4) # Reset Warm
.equ OPCODE_COLD_RESET_REQUEST, (0xF5) # Reset Cold
.equ SB_PORT_FIELD, (0x10) # Bit location of Port ID field
.equ MEMORY_ARBITER_PORT_ID, (0x00)
.equ HOST_BRIDGE_PORT_ID, (0x03)
.equ RMU_PORT_ID, (0x04)
.equ MEMORY_MANAGER_PORT_ID, (0x05)
.equ SOC_UNIT_PORT_ID, (0x31)
.equ SB_ADDR_FIELD, (0x08) # Bit location of Register field
.equ SB_BE_FIELD, (0x04) # Bit location of Byte Enables field
.equ ALL_BYTE_EN, (0x0F) # All Byte Enables
.equ MESSAGE_DATA_REG, (0xD4) # Message Data Register
#
# Memory Arbiter Config Registers
#
.equ AEC_CTRL_OFFSET, (0x00)
#
# Host Bridge Config Registers
#
.equ HMISC2_OFFSET, (0x03) # PCI configuration access mechanism
.equ OR_PM_FIELD, (0x10)
.equ SMI_EN, (0x00080000)
.equ HMBOUND_OFFSET, (0x08)
.equ HMBOUND_ADDRESS, (QUARK_DDR3_MEM_BASE_ADDRESS + QUARK_MAX_DDR3_MEM_SIZE_BYTES + QUARK_ESRAM_MEM_SIZE_BYTES)
.equ HMBOUND_LOCK, (0x01)
.equ HECREG_OFFSET, (0x09)
.equ EC_BASE, (0xE0000000)
.equ EC_ENABLE, (0x01)
.equ HLEGACY_OFFSET, (0x0A)
.equ NMI, (0x00004000)
.equ SMI, (0x00001000)
.equ INTR, (0x00000400)
#
# Memory Manager Config Registers
#
.equ ESRAMPGCTRL_BLOCK_OFFSET, (0x82)
.equ BLOCK_ENABLE_PG, (0x10000000)
.equ BIMRVCTL_OFFSET, (0x19)
.equ ENABLE_IMR_INTERRUPT, (0x80000000)
#
# SOC UNIT Debug Registers
#
.equ CFGSTICKY_W1_OFFSET, (0x50)
.equ FORCE_COLD_RESET, (0x00000001)
.equ CFGSTICKY_RW_OFFSET, (0x51)
.equ RESET_FOR_ESRAM_LOCK, (0x00000020)
.equ RESET_FOR_HMBOUND_LOCK, (0x00000040)
.equ CFGNONSTICKY_W1_OFFSET, (0x52)
.equ FORCE_WARM_RESET, (0x00000001)
#
# CR0 cache control bit definition
#
.equ CR0_CACHE_DISABLE, 0x040000000
.equ CR0_NO_WRITE, 0x020000000
ASM_GLOBAL ASM_PFX(PcdGet32(PcdEsramStage1Base))
#
# Contrary to the name, this file contains 16 bit code as well.
#
.text
#----------------------------------------------------------------------------
#
# Procedure: _ModuleEntryPoint
#
# Input: None
#
# Output: None
#
# Destroys: Assume all registers
#
# Description:
#
# Transition to non-paged flat-model protected mode from a
# hard-coded GDT that provides exactly two descriptors.
# This is a bare bones transition to protected mode only
# used for a while in PEI and possibly DXE.
#
# After enabling protected mode, a far jump is executed to
# transfer to PEI using the newly loaded GDT.
#
# Return: None
#
#----------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(_ModuleEntryPoint)
ASM_PFX(_ModuleEntryPoint):
#
# Warm Reset (INIT#) check.
#
.byte 0xbe,0x00,0xf0 #movw $0xF000, %si
.byte 0x8e,0xde #movw %si, %ds
.byte 0xbe,0xf0,0xff #movw $0xFFF0, %si
.byte 0x80,0x3c,0xea #cmpb $0xEA, (%si) # Is it warm reset ?
jne NotWarmReset # Jump if not.
.byte 0xb0,0x08 #movb $0x08, %al
.byte 0xba,0xf9,0x0c #movw $0xcf9, %dx
.byte 0xee #outb %al, %dx
.byte 0xb0,0x55 #movb $0x55, %al
.byte 0xe6,0x80 #outb %al, $0x80
jmp .
NotWarmReset:
.byte 0x66,0x8b,0xe8 #movl %eax, %ebp
#
# Load the GDT table in GdtDesc
#
.byte 0x66,0xbe #movl $GdtDesc, %esi
.long GdtDesc
.byte 0x66,0x2e,0x0f,0x01,0x14 #lgdt %cs:(%si)
#
# Transition to 16 bit protected mode
#
.byte 0x0f,0x20,0xc0 #movl %cr0, %eax # Get control register 0
.byte 0x66,0x83,0xc8,0x03 #orl $0x0000003, %eax # Set PE bit (bit #0) & MP bit (bit #1)
.byte 0x0f,0x22,0xc0 #movl %eax, %cr0 # Activate protected mode
#
# Now we're in 16 bit protected mode
# Set up the selectors for 32 bit protected mode entry
#
.byte 0xb8 #movw SYS_DATA_SEL, %ax
.word SYS_DATA_SEL
.byte 0x8e,0xd8 #movw %ax, %ds
.byte 0x8e,0xc0 #movw %ax, %es
.byte 0x8e,0xe0 #movw %ax, %fs
.byte 0x8e,0xe8 #movw %ax, %gs
.byte 0x8e,0xd0 #movw %ax, %ss
#
# Transition to Flat 32 bit protected mode
# The jump to a far pointer causes the transition to 32 bit mode
#
.byte 0x66,0xbe #movl ProtectedModeEntryLinearAddress, %esi
.long ProtectedModeEntryLinearAddress
.byte 0x66,0x2e,0xff,0x2c #jmp %cs:(%esi)
#
# Protected mode portion initializes stack, configures cache, and calls C entry point
#
#----------------------------------------------------------------------------
#
# Procedure: ProtectedModeEntryPoint
#
# Input: Executing in 32 Bit Protected (flat) mode
# cs: 0-4GB
# ds: 0-4GB
# es: 0-4GB
# fs: 0-4GB
# gs: 0-4GB
# ss: 0-4GB
#
# Output: This function never returns
#
# Destroys:
# ecx
# edi
# esi
# esp
#
# Description:
# Perform any essential early platform initilaisation
# Setup a stack
# Transfer control to EDKII code in eSRAM
#
#----------------------------------------------------------------------------
ProtectedModeEntryPoint:
leal L0, %esp
jmp stackless_EarlyPlatformInit
L0:
#
# Set up stack pointer
#
movl ASM_PFX(PcdGet32(PcdEsramStage1Base)), %esp
movl $QUARK_STACK_SIZE_BYTES, %esi
addl %esi, %esp # ESP = top of stack (stack grows downwards).
#
# Store the the BIST value in EBP
#
movl $0, %ebp # No processor BIST on Quark
#
# Push processor count to stack first, then BIST status (AP then BSP)
#
movl $1, %eax
cpuid
shrl $16, %ebx
andl $0x000000FF, %ebx
cmpb $1, %bl
jae PushProcessorCount
#
# Some processors report 0 logical processors. Effectively 0 = 1.
# So we fix up the processor count
#
incl %ebx
PushProcessorCount:
pushl %ebx
#
# We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST
# for all processor threads
#
xorl %ecx, %ecx
movb %bl, %cl
PushBist:
pushl %ebp
loop PushBist
#
# Pass entry point of the PEI core
#
movl $0xFFFFFFE0, %edi
pushl %ds:(%edi)
#
# Pass BFV into the PEI Core
#
movl $0xFFFFFFFC, %edi
pushl %ds:(%edi)
#
# Pass Temp Ram Base into the PEI Core
#
movl ASM_PFX(PcdGet32(PcdEsramStage1Base)), %eax
addl $(QUARK_ESRAM_MEM_SIZE_BYTES - QUARK_STACK_SIZE_BYTES), %eax
pushl %eax
#
# Pass stack size into the PEI Core
#
pushl $QUARK_STACK_SIZE_BYTES
#
# Pass Control into the PEI Core
#
call SecStartup
#
# PEI Core should never return to here, this is just to capture an invalid return.
#
jmp .
#----------------------------------------------------------------------------
#
# Procedure: stackless_EarlyPlatformInit
#
# Input: esp - Return address
#
# Output: None
#
# Destroys: Assume all registers
#
# Description:
# Any early platform initialisation required
#
# Return:
# None
#
#----------------------------------------------------------------------------
stackless_EarlyPlatformInit:
#
# Save return address
#
movl %esp, %ebp
#
# Ensure cache is disabled.
#
movl %cr0, %eax
orl $(CR0_CACHE_DISABLE + CR0_NO_WRITE), %eax
invd
movl %eax, %cr0
#
# Disable NMI operation
# Good convention suggests you should read back RTC data port after
# accessing the RTC index port.
#
movb $(NMI_DISABLE), %al
movw $(RTC_INDEX), %dx
outb %al, %dx
movw $(RTC_DATA), %dx
inb %dx, %al
#
# Disable SMI (Disables SMI wire, not SMI messages)
#
movl $((OPCODE_SIDEBAND_REG_READ << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HMISC2_OFFSET << SB_ADDR_FIELD)), %ecx
leal L1, %esp
jmp stackless_SideBand_Read
L1:
andl $(~SMI_EN), %eax
movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HMISC2_OFFSET << SB_ADDR_FIELD)), %ecx
leal L2, %esp
jmp stackless_SideBand_Write
L2:
#
# Before we get going, check SOC Unit Registers to see if we are required to issue a warm/cold reset
#
movl $((OPCODE_SIDEBAND_ALT_REG_READ << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGNONSTICKY_W1_OFFSET << SB_ADDR_FIELD)), %ecx
leal L3, %esp
jmp stackless_SideBand_Read
L3:
andl $(FORCE_WARM_RESET), %eax
jz TestForceColdReset # Zero means bit clear, we're not requested to warm reset so continue as normal
jmp IssueWarmReset
TestForceColdReset:
movl $((OPCODE_SIDEBAND_ALT_REG_READ << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGNONSTICKY_W1_OFFSET << SB_ADDR_FIELD)), %ecx
leal L4, %esp
jmp stackless_SideBand_Read
L4:
andl $(FORCE_COLD_RESET), %eax
jz TestHmboundLock # Zero means bit clear, we're not requested to cold reset so continue as normal
jmp IssueColdReset
#
# Before setting HMBOUND, check it's not locked
#
TestHmboundLock:
movl $((OPCODE_SIDEBAND_REG_READ << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HMBOUND_OFFSET << SB_ADDR_FIELD)), %ecx
leal L5, %esp
jmp stackless_SideBand_Read
L5:
andl $(HMBOUND_LOCK), %eax
jz ConfigHmbound # Zero means bit clear, we have the config we want so continue as normal
#
# Failed to config - store sticky bit debug
#
movl $((OPCODE_SIDEBAND_ALT_REG_READ << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGSTICKY_RW_OFFSET << SB_ADDR_FIELD)), %ecx
leal L6, %esp
jmp stackless_SideBand_Read
L6:
orl $(RESET_FOR_HMBOUND_LOCK), %eax
movl $((OPCODE_SIDEBAND_ALT_REG_WRITE << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGSTICKY_RW_OFFSET << SB_ADDR_FIELD)), %ecx
leal L7, %esp
jmp stackless_SideBand_Write
L7:
jmp IssueWarmReset
#
# Set up the HMBOUND register
#
ConfigHmbound:
movl $(HMBOUND_ADDRESS), %eax # Data (Set HMBOUND location)
movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HMBOUND_OFFSET << SB_ADDR_FIELD)), %ecx
leal L8, %esp
jmp stackless_SideBand_Write
L8:
#
# Enable interrupts to Remote Management Unit when a IMR/SMM/HMBOUND violation occurs.
#
movl $(ENABLE_IMR_INTERRUPT), %eax # Data (Set interrupt enable mask)
movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (MEMORY_MANAGER_PORT_ID << SB_PORT_FIELD) | (BIMRVCTL_OFFSET << SB_ADDR_FIELD)), %ecx
leal L9, %esp
jmp stackless_SideBand_Write
L9:
#
# Set eSRAM address
#
movl ASM_PFX(PcdGet32(PcdEsramStage1Base)), %eax # Data (Set eSRAM location)
shr $(0x18), %eax
addl $(BLOCK_ENABLE_PG), %eax
movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (MEMORY_MANAGER_PORT_ID << SB_PORT_FIELD) | (ESRAMPGCTRL_BLOCK_OFFSET << SB_ADDR_FIELD)), %ecx
leal L10, %esp
jmp stackless_SideBand_Write
L10:
#
# Check that we're not blocked from setting the config that we want.
#
movl $((OPCODE_SIDEBAND_REG_READ << SB_OPCODE_FIELD) | (MEMORY_MANAGER_PORT_ID << SB_PORT_FIELD) | (ESRAMPGCTRL_BLOCK_OFFSET << SB_ADDR_FIELD)), %ecx
leal L11, %esp
jmp stackless_SideBand_Read
L11:
andl $(BLOCK_ENABLE_PG), %eax
jnz ConfigPci # Non-zero means bit set, we have the config we want so continue as normal
#
# Failed to config - store sticky bit debug
#
movl $((OPCODE_SIDEBAND_ALT_REG_READ << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGSTICKY_RW_OFFSET << SB_ADDR_FIELD)), %ecx
leal L12, %esp
jmp stackless_SideBand_Read
L12:
orl $(RESET_FOR_ESRAM_LOCK), %eax # Set the bit we're interested in
movl $((OPCODE_SIDEBAND_ALT_REG_WRITE << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGSTICKY_RW_OFFSET << SB_ADDR_FIELD)), %ecx
leal L13, %esp
jmp stackless_SideBand_Write
L13:
jmp IssueWarmReset
#
# Enable PCIEXBAR
#
ConfigPci:
movl $(EC_BASE + EC_ENABLE), %eax # Data
movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (MEMORY_ARBITER_PORT_ID << SB_PORT_FIELD) | (AEC_CTRL_OFFSET << SB_ADDR_FIELD)), %ecx
leal L14, %esp
jmp stackless_SideBand_Write
L14:
movl $(EC_BASE + EC_ENABLE), %eax # Data
movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HECREG_OFFSET << SB_ADDR_FIELD)), %ecx
leal L15, %esp
jmp stackless_SideBand_Write
L15:
#
# Open up full 8MB SPI decode
#
movl $(PCI_CFG | (ILB_PFA << 8) | BDE), %ebx # PCI Configuration address
movl $(DECODE_ALL_REGIONS_ENABLE), %eax
leal L16, %esp
jmp stackless_PCIConfig_Write
L16:
#
# Enable NMI operation
# Good convention suggests you should read back RTC data port after
# accessing the RTC index port.
#
movb $(NMI_ENABLE), %al
movw $(RTC_INDEX), %dx
outb %al, %dx
movw $(RTC_DATA), %dx
inb %dx, %al
#
# Clear Host Bridge SMI, NMI, INTR fields
#
movl $((OPCODE_SIDEBAND_REG_READ << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HLEGACY_OFFSET << SB_ADDR_FIELD)), %ecx
leal L21, %esp
jmp stackless_SideBand_Read
L21:
andl $~(NMI + SMI + INTR), %eax # Clear NMI, SMI, INTR fields
movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HLEGACY_OFFSET << SB_ADDR_FIELD)), %ecx
leal L22, %esp
jmp stackless_SideBand_Write
L22:
#
# Restore return address
#
movl %ebp, %esp
RET32
IssueWarmReset:
#
# Issue Warm Reset request to Remote Management Unit via iLB
#
movw $(CF9_WARM_RESET), %ax
movw $(ILB_RESET_REG), %dx
outw %ax, %dx
jmp . # Stay here until we are reset.
IssueColdReset:
#
# Issue Cold Reset request to Remote Management Unit via iLB
#
movw $(CF9_COLD_RESET), %ax
movw $(ILB_RESET_REG), %dx
outw %ax, %dx
jmp . # Stay here until we are reset.
#----------------------------------------------------------------------------
#
# Procedure: stackless_SideBand_Read
#
# Input: esp - return address
# ecx[15:8] - Register offset
# ecx[23:16] - Port ID
# ecx[31:24] - Opcode
#
# Output: eax - Data read
#
# Destroys:
# eax
# ebx
# cl
# esi
#
# Description:
# Perform requested sideband read
#
#----------------------------------------------------------------------------
stackless_SideBand_Read:
movl %esp, %esi # Save the return address
#
# Load the SideBand Packet Register to generate the transaction
#
movl $((PCI_CFG) | (HOST_BRIDGE_PFA << 8) | (MESSAGE_BUS_CONTROL_REG)), %ebx # PCI Configuration address
movb $(ALL_BYTE_EN << SB_BE_FIELD), %cl # Set all Byte Enable bits
xchgl %ecx, %eax
leal L17, %esp
jmp stackless_PCIConfig_Write
L17:
xchgl %ecx, %eax
#
# Read the SideBand Data Register
#
movl $((PCI_CFG) | (HOST_BRIDGE_PFA << 8) | (MESSAGE_DATA_REG)), %ebx # PCI Configuration address
leal L18, %esp
jmp stackless_PCIConfig_Read
L18:
movl %esi, %esp # Restore the return address
RET32
#----------------------------------------------------------------------------
#
# Procedure: stackless_SideBand_Write
#
# Input: esp - return address
# eax - Data
# ecx[15:8] - Register offset
# ecx[23:16] - Port ID
# ecx[31:24] - Opcode
#
# Output: None
#
# Destroys:
# ebx
# cl
# esi
#
# Description:
# Perform requested sideband write
#
#
#----------------------------------------------------------------------------
stackless_SideBand_Write:
movl %esp, %esi # Save the return address
#
# Load the SideBand Data Register with the data
#
movl $((PCI_CFG) | (HOST_BRIDGE_PFA << 8) | (MESSAGE_DATA_REG)), %ebx # PCI Configuration address
leal L19, %esp
jmp stackless_PCIConfig_Write
L19:
#
# Load the SideBand Packet Register to generate the transaction
#
movl $((PCI_CFG) | (HOST_BRIDGE_PFA << 8) | (MESSAGE_BUS_CONTROL_REG)), %ebx # PCI Configuration address
movb $(ALL_BYTE_EN << SB_BE_FIELD), %cl # Set all Byte Enable bits
xchgl %ecx, %eax
leal L20, %esp
jmp stackless_PCIConfig_Write
L20:
xchgl %ecx, %eax
movl %esi, %esp # Restore the return address
RET32
#----------------------------------------------------------------------------
#
# Procedure: stackless_PCIConfig_Write
#
# Input: esp - return address
# eax - Data to write
# ebx - PCI Config Address
#
# Output: None
#
# Destroys:
# dx
#
# Description:
# Perform a DWORD PCI Configuration write
#
#----------------------------------------------------------------------------
stackless_PCIConfig_Write:
#
# Write the PCI Config Address to the address port
#
xchgl %ebx, %eax
movw $(PCI_ADDRESS_PORT), %dx
outl %eax, %dx
xchgl %ebx, %eax
#
# Write the PCI DWORD Data to the data port
#
movw $(PCI_DATA_PORT), %dx
outl %eax, %dx
RET32
#----------------------------------------------------------------------------
#
# Procedure: stackless_PCIConfig_Read
#
# Input: esp - return address
# ebx - PCI Config Address
#
# Output: eax - Data read
#
# Destroys:
# eax
# dx
#
# Description:
# Perform a DWORD PCI Configuration read
#
#----------------------------------------------------------------------------
stackless_PCIConfig_Read:
#
# Write the PCI Config Address to the address port
#
xchgl %ebx, %eax
movw $(PCI_ADDRESS_PORT), %dx
outl %eax, %dx
xchgl %ebx, %eax
#
# Read the PCI DWORD Data from the data port
#
movw $(PCI_DATA_PORT), %dx
inl %dx, %eax
RET32
#
# ROM-based Global-Descriptor Table for the Tiano PEI Phase
#
.align 16
#
# GDT[0]: 000h: Null entry, never used.
#
GDT_BASE:
BootGdtTable:
# null descriptor
.equ NULL_SEL, . - GDT_BASE # Selector [0]
.word 0 # limit 15:0
.word 0 # base 15:0
.byte 0 # base 23:16
.byte 0 # type
.byte 0 # limit 19:16, flags
.byte 0 # base 31:24
# linear data segment descriptor
.equ LINEAR_SEL, . - GDT_BASE # Selector [0x8]
.word 0xFFFF # limit 0xFFFFF
.word 0 # base 0
.byte 0
.byte 0x92 # present, ring 0, data, expand-up, writable
.byte 0xCF # page-granular, 32-bit
.byte 0
# linear code segment descriptor
.equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [0x10]
.word 0xFFFF # limit 0xFFFFF
.word 0 # base 0
.byte 0
.byte 0x9A # present, ring 0, data, expand-up, writable
.byte 0xCF # page-granular, 32-bit
.byte 0
# system data segment descriptor
.equ SYS_DATA_SEL, . - GDT_BASE # Selector [0x18]
.word 0xFFFF # limit 0xFFFFF
.word 0 # base 0
.byte 0
.byte 0x92 # present, ring 0, data, expand-up, writable
.byte 0xCF # page-granular, 32-bit
.byte 0
# system code segment descriptor
.equ SYS_CODE_SEL, . - GDT_BASE
.word 0xFFFF # limit 0xFFFFF
.word 0 # base 0
.byte 0
.byte 0x9A # present, ring 0, data, expand-up, writable
.byte 0xCF # page-granular, 32-bit
.byte 0
# spare segment descriptor
.equ SYS16_CODE_SEL, . - GDT_BASE
.word 0xffff # limit 0xFFFFF
.word 0 # base 0
.byte 0x0f
.byte 0x9b # present, ring 0, data, expand-up, writable
.byte 0 # page-granular, 32-bit
.byte 0
# spare segment descriptor
.equ SYS16_DATA_SEL, . - GDT_BASE
.word 0xffff # limit 0xFFFFF
.word 0 # base 0
.byte 0
.byte 0x93 # present, ring 0, data, expand-up, not-writable
.byte 0 # page-granular, 32-bit
.byte 0
# spare segment descriptor
.equ SPARE5_SEL, . - GDT_BASE
.word 0 # limit 0xFFFFF
.word 0 # base 0
.byte 0
.byte 0 # present, ring 0, data, expand-up, writable
.byte 0 # page-granular, 32-bit
.byte 0
.equ GDT_SIZE, . - GDT_BASE
#
# GDT Descriptor
#
GdtDesc: # GDT descriptor
.word GDT_SIZE - 1
.long BootGdtTable
ProtectedModeEntryLinearAddress:
ProtectedModeEntryLinearOffset:
.long ProtectedModeEntryPoint
.word LINEAR_CODE_SEL

View File

@@ -0,0 +1,691 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2013-2015 Intel Corporation.
;
; This program and the accompanying materials
; are licensed and made available under the terms and conditions of the BSD License
; which accompanies this distribution. The full text of the license may be found at
; http://opensource.org/licenses/bsd-license.php
;
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
;
; Module Name:
;
; Flat32.asm
;
; Abstract:
;
; This is the code that goes from real-mode to protected mode.
; It consumes the reset vector, configures the stack.
;
;
;------------------------------------------------------------------------------
;
; Define assembler characteristics
;
.586p
.model flat, c
;
; Include processor definitions
;
INCLUDE Platform.inc
;
; CR0 cache control bit definition
;
CR0_CACHE_DISABLE EQU 040000000h
CR0_NO_WRITE EQU 020000000h
;
; External and public declarations
; TopOfStack is used by C code
; SecStartup is the entry point to the C code
; Neither of these names can be modified without
; updating the C code.
;
EXTRN PlatformSecLibStartup: NEAR
EXTERNDEF C PcdGet32 (PcdEsramStage1Base):DWORD
;
; Contrary to the name, this file contains 16 bit code as well.
;
_TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE'
ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE
;----------------------------------------------------------------------------
;
; Procedure: _ModuleEntryPoint
;
; Input: None
;
; Output: None
;
; Destroys: Assume all registers
;
; Description:
;
; Transition to non-paged flat-model protected mode from a
; hard-coded GDT that provides exactly two descriptors.
; This is a bare bones transition to protected mode only
; used for a while in PEI and possibly DXE.
;
; After enabling protected mode, a far jump is executed to
; transfer to PEI using the newly loaded GDT.
;
; Return: None
;
;----------------------------------------------------------------------------
align 16
_ModuleEntryPoint PROC C PUBLIC
;
; Warm Reset (INIT#) check.
;
mov si, 0F000h
mov ds, si
mov si, 0FFF0h
cmp BYTE PTR [si], 0EAh ; Is it warm reset ?
jne NotWarmReset ; JIf not.
mov al, 08
mov dx, 0cf9h
out dx, al
mov al, 055h
out 080h, al;
jmp $
NotWarmReset:
;
; Load the GDT table in GdtDesc
;
mov esi, OFFSET GdtDesc
db 66h
lgdt fword ptr cs:[si]
;
; Transition to 16 bit protected mode
;
mov eax, cr0 ; Get control register 0
or eax, 00000003h ; Set PE bit (bit #0) & MP bit (bit #1)
mov cr0, eax ; Activate protected mode
;
; Now we're in 16 bit protected mode
; Set up the selectors for 32 bit protected mode entry
;
mov ax, SYS_DATA_SEL
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
;
; Transition to Flat 32 bit protected mode
; The jump to a far pointer causes the transition to 32 bit mode
;
mov esi, offset ProtectedModeEntryLinearAddress
jmp fword ptr cs:[si]
_ModuleEntryPoint ENDP
_TEXT_REALMODE ENDS
.code
;
; Protected mode portion initializes stack, configures cache, and calls C entry point
;
;----------------------------------------------------------------------------
;
; Procedure: ProtectedModeEntryPoint
;
; Input: Executing in 32 Bit Protected (flat) mode
; cs: 0-4GB
; ds: 0-4GB
; es: 0-4GB
; fs: 0-4GB
; gs: 0-4GB
; ss: 0-4GB
;
; Output: This function never returns
;
; Destroys:
; ecx
; edi
; esi
; esp
;
; Description:
; Perform any essential early platform initilaisation
; Setup a stack
; Call the main EDKII Sec C code
;
;----------------------------------------------------------------------------
ProtectedModeEntryPoint PROC NEAR C PUBLIC
JMP32 stackless_EarlyPlatformInit
;
; Set up stack pointer
;
mov esp, PcdGet32(PcdEsramStage1Base)
mov esi, QUARK_ESRAM_MEM_SIZE_BYTES
add esp, esi ; ESP = top of stack (stack grows downwards).
;
; Store the the BIST value in EBP
;
mov ebp, 00h ; No processor BIST on Quark
;
; Push processor count to stack first, then BIST status (AP then BSP)
;
mov eax, 1
cpuid
shr ebx, 16
and ebx, 0000000FFh
cmp bl, 1
jae PushProcessorCount
;
; Some processors report 0 logical processors. Effectively 0 = 1.
; So we fix up the processor count
;
inc ebx
PushProcessorCount:
push ebx
;
; We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST
; for all processor threads
;
xor ecx, ecx
mov cl, bl
PushBist:
push ebp
loop PushBist
;
; Pass Control into the PEI Core
;
call PlatformSecLibStartup
;
; PEI Core should never return to here, this is just to capture an invalid return.
;
jmp $
ProtectedModeEntryPoint ENDP
;----------------------------------------------------------------------------
;
; Procedure: stackless_EarlyPlatformInit
;
; Input: esp - Return address
;
; Output: None
;
; Destroys:
; eax
; ecx
; dx
; ebp
;
; Description:
; Any essential early platform initialisation required:
; (1) Disable Cache
; (2) Disable NMI's/SMI's
; (3) Setup HMBOUND (defines what memory accesses go to MMIO/RAM)
; (4) Setup eSRAM (provide early memory to the system)
; (5) Setup PCIEXBAR access mechanism
; (6) Open up full SPI flash decode
;
;----------------------------------------------------------------------------
stackless_EarlyPlatformInit PROC NEAR C PUBLIC
;
; Save return address
;
mov ebp, esp
;
; Ensure cache is disabled.
;
mov eax, cr0
or eax, CR0_CACHE_DISABLE + CR0_NO_WRITE
invd
mov cr0, eax
;
; Disable NMI
; Good convention suggests you should read back RTC data port after
; accessing the RTC index port.
;
mov al, NMI_DISABLE
mov dx, RTC_INDEX
out dx, al
mov dx, RTC_DATA
in al, dx
;
; Disable SMI (Disables SMI wire, not SMI messages)
;
mov ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMISC2_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Read
and eax, NOT (SMI_EN)
mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMISC2_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Write
;
; Before we get going, check SOC Unit Registers to see if we are required to issue a warm/cold reset
;
mov ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGNONSTICKY_W1_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Read
and eax, FORCE_WARM_RESET
jz TestForceColdReset ; Zero means bit clear, we're not requested to warm reset so continue as normal
jmp IssueWarmReset
TestForceColdReset:
mov ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_W1_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Read
and eax, FORCE_COLD_RESET
jz TestHmboundLock ; Zero means bit clear, we're not requested to cold reset so continue as normal
jmp IssueColdReset
;
; Before setting HMBOUND, check it's not locked
;
TestHmboundLock:
mov ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMBOUND_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Read
and eax, HMBOUND_LOCK
jz ConfigHmbound ; Zero means bit clear, we have the config we want so continue as normal
;
; Failed to config - store sticky bit debug
;
mov ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Read
or eax, RESET_FOR_HMBOUND_LOCK ; Set the bit we're interested in
mov ecx, (OPCODE_SIDEBAND_ALT_REG_WRITE SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Write
jmp IssueWarmReset
;
; Set up the HMBOUND register
;
ConfigHmbound:
mov eax, HMBOUND_ADDRESS ; Data (Set HMBOUND location)
mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMBOUND_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Write
;
; Enable interrupts to Remote Management Unit when a IMR/SMM/HMBOUND violation occurs.
;
mov eax, ENABLE_IMR_INTERRUPT ; Data (Set interrupt enable mask)
mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (MEMORY_MANAGER_PORT_ID SHL SB_PORT_FIELD) OR (BIMRVCTL_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Write
;
; Set eSRAM address
;
mov eax, PcdGet32 (PcdEsramStage1Base) ; Data (Set eSRAM location)
shr eax, 18h ; Data (Set eSRAM location)
add eax, BLOCK_ENABLE_PG
mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (MEMORY_MANAGER_PORT_ID SHL SB_PORT_FIELD) OR (ESRAMPGCTRL_BLOCK_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Write
;
; Check that we're not blocked from setting the config that we want.
;
mov ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (MEMORY_MANAGER_PORT_ID SHL SB_PORT_FIELD) OR (ESRAMPGCTRL_BLOCK_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Read
and eax, BLOCK_ENABLE_PG
jnz ConfigPci ; Non-zero means bit set, we have the config we want so continue as normal
;
; Failed to config - store sticky bit debug
;
mov ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Read
or eax, RESET_FOR_ESRAM_LOCK ; Set the bit we're interested in
mov ecx, (OPCODE_SIDEBAND_ALT_REG_WRITE SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Write
jmp IssueWarmReset
;
; Enable PCIEXBAR
;
ConfigPci:
mov eax, (EC_BASE + EC_ENABLE) ; Data
mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (MEMORY_ARBITER_PORT_ID SHL SB_PORT_FIELD) OR (AEC_CTRL_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Write
mov eax, (EC_BASE + EC_ENABLE) ; Data
mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HECREG_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Write
;
; Open up full 8MB SPI decode
;
mov ebx, PCI_CFG OR (ILB_PFA SHL 8) OR BDE ; PCI Configuration address
mov eax, DECODE_ALL_REGIONS_ENABLE
JMP32 stackless_PCIConfig_Write
;
; Enable NMI operation
; Good convention suggests you should read back RTC data port after
; accessing the RTC index port.
;
mov al, NMI_ENABLE
mov dx, RTC_INDEX
out dx, al
mov dx, RTC_DATA
in al, dx
;
; Clear Host Bridge SMI, NMI, INTR fields
;
mov ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HLEGACY_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Read
and eax, NOT(NMI + SMI + INTR) ; Clear NMI, SMI, INTR fields
mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HLEGACY_OFFSET SHL SB_ADDR_FIELD)
JMP32 stackless_SideBand_Write
;
; Restore return address
;
mov esp, ebp
RET32
IssueWarmReset:
;
; Issue Warm Reset request to Remote Management Unit via iLB
;
mov ax, CF9_WARM_RESET
mov dx, ILB_RESET_REG
out dx, ax
jmp $ ; Stay here until we are reset.
IssueColdReset:
;
; Issue Cold Reset request to Remote Management Unit via iLB
;
mov ax, CF9_COLD_RESET
mov dx, ILB_RESET_REG
out dx, ax
jmp $ ; Stay here until we are reset.
stackless_EarlyPlatformInit ENDP
;----------------------------------------------------------------------------
;
; Procedure: stackless_SideBand_Read
;
; Input: esp - return address
; ecx[15:8] - Register offset
; ecx[23:16] - Port ID
; ecx[31:24] - Opcode
;
; Output: eax - Data read
;
; Destroys:
; eax
; ebx
; cl
; esi
;
; Description:
; Perform requested sideband read
;
;----------------------------------------------------------------------------
stackless_SideBand_Read PROC NEAR C PUBLIC
mov esi, esp ; Save the return address
;
; Load the SideBand Packet Register to generate the transaction
;
mov ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_BUS_CONTROL_REG ; PCI Configuration address
mov cl, (ALL_BYTE_EN SHL SB_BE_FIELD) ; Set all Byte Enable bits
xchg eax, ecx
JMP32 stackless_PCIConfig_Write
xchg eax, ecx
;
; Read the SideBand Data Register
;
mov ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_DATA_REG ; PCI Configuration address
JMP32 stackless_PCIConfig_Read
mov esp, esi ; Restore the return address
RET32
stackless_SideBand_Read ENDP
;----------------------------------------------------------------------------
;
; Procedure: stackless_SideBand_Write
;
; Input: esp - return address
; eax - Data
; ecx[15:8] - Register offset
; ecx[23:16] - Port ID
; ecx[31:24] - Opcode
;
; Output: None
;
; Destroys:
; ebx
; cl
; esi
;
; Description:
; Perform requested sideband write
;
;
;----------------------------------------------------------------------------
stackless_SideBand_Write PROC NEAR C PUBLIC
mov esi, esp ; Save the return address
;
; Load the SideBand Data Register with the data
;
mov ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_DATA_REG ; PCI Configuration address
JMP32 stackless_PCIConfig_Write
;
; Load the SideBand Packet Register to generate the transaction
;
mov ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_BUS_CONTROL_REG ; PCI Configuration address
mov cl, (ALL_BYTE_EN SHL SB_BE_FIELD) ; Set all Byte Enable bits
xchg eax, ecx
JMP32 stackless_PCIConfig_Write
xchg eax, ecx
mov esp, esi ; Restore the return address
RET32
stackless_SideBand_Write ENDP
;----------------------------------------------------------------------------
;
; Procedure: stackless_PCIConfig_Write
;
; Input: esp - return address
; eax - Data to write
; ebx - PCI Config Address
;
; Output: None
;
; Destroys:
; dx
;
; Description:
; Perform a DWORD PCI Configuration write
;
;----------------------------------------------------------------------------
stackless_PCIConfig_Write PROC NEAR C PUBLIC
;
; Write the PCI Config Address to the address port
;
xchg eax, ebx
mov dx, PCI_ADDRESS_PORT
out dx, eax
xchg eax, ebx
;
; Write the PCI DWORD Data to the data port
;
mov dx, PCI_DATA_PORT
out dx, eax
RET32
stackless_PCIConfig_Write ENDP
;----------------------------------------------------------------------------
;
; Procedure: stackless_PCIConfig_Read
;
; Input: esp - return address
; ebx - PCI Config Address
;
; Output: eax - Data read
;
; Destroys:
; eax
; dx
;
; Description:
; Perform a DWORD PCI Configuration read
;
;----------------------------------------------------------------------------
stackless_PCIConfig_Read PROC NEAR C PUBLIC
;
; Write the PCI Config Address to the address port
;
xchg eax, ebx
mov dx, PCI_ADDRESS_PORT
out dx, eax
xchg eax, ebx
;
; Read the PCI DWORD Data from the data port
;
mov dx, PCI_DATA_PORT
in eax, dx
RET32
stackless_PCIConfig_Read ENDP
;
; ROM-based Global-Descriptor Table for the Tiano PEI Phase
;
align 16
PUBLIC BootGdtTable
;
; GDT[0]: 0x00: Null entry, never used.
;
NULL_SEL equ $ - GDT_BASE ; Selector [0]
GDT_BASE:
BootGdtTable DD 0
DD 0
;
; Linear data segment descriptor
;
LINEAR_SEL equ $ - GDT_BASE ; Selector [0x8]
DW 0FFFFh ; limit 0xFFFF
DW 0 ; base 0
DB 0
DB 092h ; present, ring 0, data, expand-up, writable
DB 0CFh ; page-granular, 32-bit
DB 0
;
; Linear code segment descriptor
;
LINEAR_CODE_SEL equ $ - GDT_BASE ; Selector [0x10]
DW 0FFFFh ; limit 0xFFFF
DW 0 ; base 0
DB 0
DB 09Bh ; present, ring 0, data, expand-up, not-writable
DB 0CFh ; page-granular, 32-bit
DB 0
;
; System data segment descriptor
;
SYS_DATA_SEL equ $ - GDT_BASE ; Selector [0x18]
DW 0FFFFh ; limit 0xFFFF
DW 0 ; base 0
DB 0
DB 093h ; present, ring 0, data, expand-up, not-writable
DB 0CFh ; page-granular, 32-bit
DB 0
;
; System code segment descriptor
;
SYS_CODE_SEL equ $ - GDT_BASE ; Selector [0x20]
DW 0FFFFh ; limit 0xFFFF
DW 0 ; base 0
DB 0
DB 09Ah ; present, ring 0, data, expand-up, writable
DB 0CFh ; page-granular, 32-bit
DB 0
;
; Spare segment descriptor
;
SYS16_CODE_SEL equ $ - GDT_BASE ; Selector [0x28]
DW 0FFFFh ; limit 0xFFFF
DW 0 ; base 0
DB 0Fh
DB 09Bh ; present, ring 0, code, expand-up, writable
DB 00h ; byte-granular, 16-bit
DB 0
;
; Spare segment descriptor
;
SYS16_DATA_SEL equ $ - GDT_BASE ; Selector [0x30]
DW 0FFFFh ; limit 0xFFFF
DW 0 ; base 0
DB 0
DB 093h ; present, ring 0, data, expand-up, not-writable
DB 00h ; byte-granular, 16-bit
DB 0
;
; Spare segment descriptor
;
SPARE5_SEL equ $ - GDT_BASE ; Selector [0x38]
DW 0 ; limit 0xFFFF
DW 0 ; base 0
DB 0
DB 0 ; present, ring 0, data, expand-up, writable
DB 0 ; page-granular, 32-bit
DB 0
GDT_SIZE EQU $ - BootGDTtable ; Size, in bytes
;
; GDT Descriptor
;
GdtDesc: ; GDT descriptor
DW GDT_SIZE - 1 ; GDT limit
DD OFFSET BootGdtTable ; GDT base address
ProtectedModeEntryLinearAddress LABEL FWORD
ProtectedModeEntryLinearOffset LABEL DWORD
DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code
DW LINEAR_CODE_SEL
END

View File

@@ -0,0 +1,140 @@
;
; Copyright (c) 2013-2015 Intel Corporation.
;
; This program and the accompanying materials
; are licensed and made available under the terms and conditions of the BSD License
; which accompanies this distribution. The full text of the license may be found at
; http://opensource.org/licenses/bsd-license.php
;
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
;
;------------------------------------------------------------------------------
;
; Module Name:
;
; Platform.inc
;
; Abstract:
;
; Quark A0 Platform Specific Definitions
;
;------------------------------------------------------------------------------
JMP32 MACRO FunctionName
lea esp, @F
jmp FunctionName
@@:
ENDM
RET32 MACRO
jmp esp
ENDM
;
; ROM/SPI/MEMORY Definitions
;
QUARK_DDR3_MEM_BASE_ADDRESS EQU 000000000h ; Memory Base Address = 0
QUARK_MAX_DDR3_MEM_SIZE_BYTES EQU 080000000h ; DDR3 Memory Size = 2GB
QUARK_ESRAM_MEM_SIZE_BYTES EQU 000080000h ; eSRAM Memory Size = 512K
QUARK_STACK_SIZE_BYTES EQU 008000h ; Quark stack size = 32K
;
; RTC/CMOS definitions
;
RTC_INDEX EQU 070h
NMI_DISABLE EQU 080h ; Bit7=1 disables NMI
NMI_ENABLE EQU 000h ; Bit7=0 disables NMI
RTC_DATA EQU 071h
;
; PCI Configuration definitions
;
PCI_CFG EQU 1 SHL 01Fh ; PCI configuration access mechanism
PCI_ADDRESS_PORT EQU 0CF8h
PCI_DATA_PORT EQU 0CFCh
;
; Quark PCI devices
;
HOST_BRIDGE_PFA EQU 0000h ; B0:D0:F0 (Host Bridge)
ILB_PFA EQU 00F8h ; B0:D31:F0 (Legacy Block)
;
; ILB PCI Config Registers
;
BDE EQU 0D4h ; BIOS Decode Enable register
DECODE_ALL_REGIONS_ENABLE EQU 0FF000000h ; Decode all BIOS decode ranges
;
; iLB Reset Register
;
ILB_RESET_REG EQU 0CF9h
CF9_WARM_RESET EQU 02h
CF9_COLD_RESET EQU 08h
;
; Host Bridge PCI Config Registers
;
MESSAGE_BUS_CONTROL_REG EQU 0D0h ; Message Bus Control Register
SB_OPCODE_FIELD EQU 018h ; Bit location of Opcode field
OPCODE_SIDEBAND_REG_READ EQU 010h ; Read opcode
OPCODE_SIDEBAND_REG_WRITE EQU 011h ; Write opcode
OPCODE_SIDEBAND_ALT_REG_READ EQU 06h ; Alternate Read opcode
OPCODE_SIDEBAND_ALT_REG_WRITE EQU 07h ; Alternate Write opcode
OPCODE_WARM_RESET_REQUEST EQU 0F4h ; Reset Warm
OPCODE_COLD_RESET_REQUEST EQU 0F5h ; Reset Cold
SB_PORT_FIELD EQU 010h ; Bit location of Port ID field
MEMORY_ARBITER_PORT_ID EQU 00h
HOST_BRIDGE_PORT_ID EQU 03h
RMU_PORT_ID EQU 04h
MEMORY_MANAGER_PORT_ID EQU 05h
SOC_UNIT_PORT_ID EQU 031h
SB_ADDR_FIELD EQU 008h ; Bit location of Register field
SB_BE_FIELD EQU 004h ; Bit location of Byte Enables field
ALL_BYTE_EN EQU 00Fh ; All Byte Enables
MESSAGE_DATA_REG EQU 0D4h ; Message Data Register
;
; Memory Arbiter Config Registers
;
AEC_CTRL_OFFSET EQU 00h
;
; Host Bridge Config Registers
;
HMISC2_OFFSET EQU 03h
OR_PM_FIELD EQU 010h
SMI_EN EQU 1 SHL 13h
HMBOUND_OFFSET EQU 08h
HMBOUND_ADDRESS EQU (QUARK_DDR3_MEM_BASE_ADDRESS + QUARK_MAX_DDR3_MEM_SIZE_BYTES + QUARK_ESRAM_MEM_SIZE_BYTES)
HMBOUND_LOCK EQU 00000001h
HECREG_OFFSET EQU 09h
EC_BASE EQU 0E0000000h
EC_ENABLE EQU 01h
HLEGACY_OFFSET EQU 0Ah
NMI EQU 1 SHL 0Eh ; Pin 14
SMI EQU 1 SHL 0Ch ; Pin 12
INTR EQU 1 SHL 0Ah ; Pin 10
;
; Memory Manager Config Registers
;
ESRAMPGCTRL_BLOCK_OFFSET EQU 082h
BLOCK_ENABLE_PG EQU 010000000h
BIMRVCTL_OFFSET EQU 019h
ENABLE_IMR_INTERRUPT EQU 080000000h
;
; SOC UNIT Debug Registers
;
CFGSTICKY_W1_OFFSET EQU 050h
FORCE_COLD_RESET EQU 00000001h
CFGSTICKY_RW_OFFSET EQU 051h
RESET_FOR_ESRAM_LOCK EQU 00000020h
RESET_FOR_HMBOUND_LOCK EQU 00000040h
CFGNONSTICKY_W1_OFFSET EQU 052h
FORCE_WARM_RESET EQU 00000001h

View File

@@ -0,0 +1,213 @@
/** @file
Platform SEC Library for Quark.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <PiPei.h>
#include <Ppi/SecPlatformInformation.h>
#include <Ppi/TemporaryRamSupport.h>
#include <Library/PcdLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/HobLib.h>
#include <Library/MtrrLib.h>
/**
Entry point to the C language phase of SEC. After the SEC assembly
code has initialized some temporary memory and set up the stack,
the control is transferred to this function.
@param SizeOfRam Size of the temporary memory available for use.
@param TempRamBase Base address of temporary ram
@param BootFirmwareVolume Base address of the Boot Firmware Volume.
**/
VOID
EFIAPI
SecStartup (
IN UINT32 SizeOfRam,
IN UINT32 TempRamBase,
IN VOID *BootFirmwareVolume
);
/**
Auto-generated function that calls the library constructors for all of the module's
dependent libraries. This function must be called by the SEC Core once a stack has
been established.
**/
VOID
EFIAPI
ProcessLibraryConstructorList (
VOID
);
/**
Entry point to the C language phase of PlatformSecLib. After the SEC assembly
code has initialized some temporary memory and set up the stack, control is
transferred to this function.
**/
VOID
EFIAPI
PlatformSecLibStartup (
VOID
)
{
//
// Process all library constructor functions linked to SecCore.
// This function must be called before any library functions are called
//
ProcessLibraryConstructorList ();
//
// Set write back cache attribute for SPI FLASH
//
MtrrSetMemoryAttribute (
PcdGet32 (PcdFlashAreaBaseAddress),
PcdGet32 (PcdFlashAreaSize),
CacheWriteBack
);
//
// Set write back cache attribute for 512KB Embedded SRAM
//
MtrrSetMemoryAttribute (
PcdGet32 (PcdEsramStage1Base),
SIZE_512KB,
CacheWriteBack
);
//
// Pass control to SecCore module passing in the size of the temporary RAM in
// Embedded SRAM, the base address of the temporary RAM in Embedded SRAM, and
// the base address of the boot firmware volume. The top 32KB of the 512 KB
// embedded SRAM are used as temporary RAM.
//
SecStartup (
SIZE_32KB,
PcdGet32 (PcdEsramStage1Base) + SIZE_512KB - SIZE_32KB,
(VOID *)(UINTN)PcdGet32 (PcdFlashFvRecoveryBase)
);
}
/**
A developer supplied function to perform platform specific operations.
It's a developer supplied function to perform any operations appropriate to a
given platform. It's invoked just before passing control to PEI core by SEC
core. Platform developer may modify the SecCoreData and PPI list that is
passed to PEI Core.
@param SecCoreData The same parameter as passing to PEI core. It
could be overridden by this function.
@param PpiList The default PPI list passed from generic SEC
part.
@return The final PPI list that platform wishes to passed to PEI core.
**/
EFI_PEI_PPI_DESCRIPTOR *
EFIAPI
SecPlatformMain (
IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData,
IN EFI_PEI_PPI_DESCRIPTOR *PpiList
)
{
return NULL;
}
/**
This interface conveys state information out of the Security (SEC) phase into PEI.
@param PeiServices Pointer to the PEI Services Table.
@param StructureSize Pointer to the variable describing size of the input buffer.
@param PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
@retval EFI_SUCCESS The data was successfully returned.
@retval EFI_BUFFER_TOO_SMALL The buffer was too small.
**/
EFI_STATUS
EFIAPI
SecPlatformInformation (
IN CONST EFI_PEI_SERVICES **PeiServices,
IN OUT UINT64 *StructureSize,
OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
)
{
UINT32 *BIST;
UINT32 Size;
UINT32 Count;
EFI_HOB_GUID_TYPE *GuidHob;
UINT32 *TopOfStack;
//
// Top of the stack is the top of the 512KB Embedded SRAM region
//
TopOfStack = (UINT32 *)(UINTN)(PcdGet32 (PcdEsramStage1Base) + SIZE_512KB);
GuidHob = GetFirstGuidHob (&gEfiSecPlatformInformationPpiGuid);
if (GuidHob != NULL) {
Size = GET_GUID_HOB_DATA_SIZE (GuidHob);
BIST = GET_GUID_HOB_DATA (GuidHob);
} else {
//
// The entries of BIST information, together with the number of them,
// reside in the bottom of stack, left untouched by normal stack operation.
// This routine copies the BIST information to the buffer pointed by
// PlatformInformationRecord for output.
//
Count = *(TopOfStack - 1);
Size = Count * sizeof (IA32_HANDOFF_STATUS);
BIST = (UINT32 *) ((UINT32) TopOfStack - sizeof (UINT32) - Size);
//
// Copy Data from Stack to Hob to avoid data is lost after memory is ready.
//
BuildGuidDataHob (
&gEfiSecPlatformInformationPpiGuid,
BIST,
(UINTN)Size
);
GuidHob = GetFirstGuidHob (&gEfiSecPlatformInformationPpiGuid);
Size = GET_GUID_HOB_DATA_SIZE (GuidHob);
BIST = GET_GUID_HOB_DATA (GuidHob);
}
if ((*StructureSize) < (UINT64) Size) {
*StructureSize = Size;
return EFI_BUFFER_TOO_SMALL;
}
*StructureSize = Size;
CopyMem (PlatformInformationRecord, BIST, Size);
return EFI_SUCCESS;
}
/**
This interface disables temporary memory in SEC Phase.
**/
VOID
EFIAPI
SecPlatformDisableTemporaryMemory (
VOID
)
{
}

View File

@@ -0,0 +1,60 @@
#/** @file
# Platform SEC Library for Quark.
#
# Copyright (c) 2013-2015 Intel Corporation.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = PlatformSecLib
FILE_GUID = 8DE4221F-A9CC-4c78-85B9-D863681F0C01
MODULE_TYPE = SEC
VERSION_STRING = 1.0
LIBRARY_CLASS = PlatformSecLib
MODULE_UNI_FILE = PlatformSecLibModStrs.uni
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32
#
[Sources]
PlatformSecLib.c
[Sources.IA32]
Ia32/Flat32.asm | MSFT
Ia32/Flat32.asm | INTEL
Ia32/Flat32.S | GCC
[Packages]
MdePkg/MdePkg.dec
UefiCpuPkg/UefiCpuPkg.dec
QuarkPlatformPkg/QuarkPlatformPkg.dec
[LibraryClasses]
DebugLib
BaseLib
BaseMemoryLib
PciLib
PcdLib
HobLib
MtrrLib
[Pcd]
gQuarkPlatformTokenSpaceGuid.PcdEsramStage1Base ## CONSUMES
gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoveryBase ## CONSUMES
gQuarkPlatformTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
gQuarkPlatformTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
[Ppis]
gEfiSecPlatformInformationPpiGuid ## UNDEFINED # it is used as GUIDED HOB

View File

@@ -0,0 +1,24 @@
// /** @file
// PlatformSecLib Localized Abstract and Description Content
//
// Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>
//
// This program and the accompanying materials
// are licensed and made available under the terms and conditions of the BSD License
// which accompanies this distribution. The full text of the license may be found at
// http://opensource.org/licenses/bsd-license.php
//
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
// **/
#string STR_MODULE_ABSTRACT
#language en-US
"SEC Platform Library "
#string STR_MODULE_DESCRIPTION
#language en-US
"Provides a platform-specific function to be used during the SEC stage of POST. "