cd49cce7b7
This patch is a raw application of find src/ -type f | xargs sed -i -e 's/IS_ENABLED\s*(CONFIG_/CONFIG(/g' Change-Id: I6262d6d5c23cabe23c242b4f38d446b74fe16b88 Signed-off-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/31774 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Patrick Georgi <pgeorgi@google.com>
219 lines
4.4 KiB
ArmAsm
219 lines
4.4 KiB
ArmAsm
/*
|
|
* 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.
|
|
*/
|
|
|
|
#include <cpu/x86/cr.h>
|
|
#include <cpu/amd/mtrr.h>
|
|
#include <cpu/x86/msr.h>
|
|
|
|
/* The SIPI vector is responsible for initializing the APs in the system. It
|
|
* loads microcode, sets up MSRs, and enables caching before calling into
|
|
* C code. */
|
|
|
|
/* These segment selectors need to match the gdt entries in c_start.S. */
|
|
#define CODE_SEG 0x10
|
|
#define DATA_SEG 0x18
|
|
|
|
.section ".module_parameters", "aw", @progbits
|
|
ap_start_params:
|
|
gdtaddr:
|
|
.word 0 /* limit */
|
|
.long 0 /* table */
|
|
.word 0 /* unused */
|
|
idt_ptr:
|
|
.long 0
|
|
stack_top:
|
|
.long 0
|
|
stack_size:
|
|
.long 0
|
|
microcode_lock:
|
|
.long 0
|
|
microcode_ptr:
|
|
.long 0
|
|
msr_table_ptr:
|
|
.long 0
|
|
msr_count:
|
|
.long 0
|
|
c_handler:
|
|
.long 0
|
|
ap_count:
|
|
.long 0
|
|
|
|
#define CR0_CLEAR_FLAGS_CACHE_ENABLE (CR0_CD | CR0_NW)
|
|
#define CR0_SET_FLAGS (CR0_CLEAR_FLAGS_CACHE_ENABLE | CR0_PE)
|
|
#define CR0_CLEAR_FLAGS \
|
|
(CR0_PG | CR0_AM | CR0_WP | CR0_NE | CR0_TS | CR0_EM | CR0_MP)
|
|
|
|
.text
|
|
.code16
|
|
.global _start
|
|
_start:
|
|
cli
|
|
xorl %eax, %eax
|
|
movl %eax, %cr3 /* Invalidate TLB*/
|
|
|
|
/* On hyper threaded cpus, invalidating the cache here is
|
|
* very very bad. Don't.
|
|
*/
|
|
|
|
/* setup the data segment */
|
|
movw %cs, %ax
|
|
movw %ax, %ds
|
|
|
|
/* The gdtaddr needs to be releative to the data segment in order
|
|
* to properly dereference it. The .text section comes first in an
|
|
* rmodule so _start can be used as a proxy for the load address. */
|
|
movl $(gdtaddr), %ebx
|
|
sub $(_start), %ebx
|
|
|
|
lgdtl (%ebx)
|
|
|
|
movl %cr0, %eax
|
|
andl $~CR0_CLEAR_FLAGS, %eax
|
|
orl $CR0_SET_FLAGS, %eax
|
|
movl %eax, %cr0
|
|
|
|
ljmpl $CODE_SEG, $1f
|
|
1:
|
|
.code32
|
|
movw $DATA_SEG, %ax
|
|
movw %ax, %ds
|
|
movw %ax, %es
|
|
movw %ax, %ss
|
|
movw %ax, %fs
|
|
movw %ax, %gs
|
|
|
|
/* Load the Interrupt descriptor table */
|
|
mov idt_ptr, %ebx
|
|
lidt (%ebx)
|
|
|
|
/* Obtain CPU number. */
|
|
movl ap_count, %eax
|
|
1:
|
|
movl %eax, %ecx
|
|
inc %ecx
|
|
lock cmpxchg %ecx, ap_count
|
|
jnz 1b
|
|
|
|
/* Setup stacks for each CPU. */
|
|
movl stack_size, %eax
|
|
mul %ecx
|
|
movl stack_top, %edx
|
|
subl %eax, %edx
|
|
mov %edx, %esp
|
|
andl $0xfffffff0, %esp /* ensure stack alignment */
|
|
|
|
/* Save CPU number. */
|
|
mov %ecx, %esi
|
|
|
|
/* Determine if one should check microcode versions. */
|
|
mov microcode_ptr, %edi
|
|
test %edi, %edi
|
|
jz microcode_done /* Bypass if no microde exists. */
|
|
|
|
/* Get the Microcode version. */
|
|
mov $1, %eax
|
|
cpuid
|
|
mov $IA32_BIOS_SIGN_ID, %ecx
|
|
rdmsr
|
|
/* If something already loaded skip loading again. */
|
|
test %edx, %edx
|
|
jnz microcode_done
|
|
|
|
/* Determine if parallel microcode loading is allowed. */
|
|
cmpl $0xffffffff, microcode_lock
|
|
je load_microcode
|
|
|
|
/* Protect microcode loading. */
|
|
lock_microcode:
|
|
lock bts $0, microcode_lock
|
|
jc lock_microcode
|
|
|
|
load_microcode:
|
|
/* Load new microcode. */
|
|
mov $IA32_BIOS_UPDT_TRIG, %ecx
|
|
xor %edx, %edx
|
|
mov %edi, %eax
|
|
/* The microcode pointer is passed in pointing to the header. Adjust
|
|
* pointer to reflect the payload (header size is 48 bytes). */
|
|
add $48, %eax
|
|
pusha
|
|
wrmsr
|
|
popa
|
|
|
|
/* Unconditionally unlock microcode loading. */
|
|
cmpl $0xffffffff, microcode_lock
|
|
je microcode_done
|
|
|
|
xor %eax, %eax
|
|
mov %eax, microcode_lock
|
|
|
|
microcode_done:
|
|
/*
|
|
* Load MSRs. Each entry in the table consists of:
|
|
* 0: index,
|
|
* 4: value[31:0]
|
|
* 8: value[63:32]
|
|
*/
|
|
mov msr_table_ptr, %edi
|
|
mov msr_count, %ebx
|
|
test %ebx, %ebx
|
|
jz 1f
|
|
|
|
#if CONFIG(X86_AMD_FIXED_MTRRS)
|
|
/* Allow modification of RdDram and WrDram bits */
|
|
mov $SYSCFG_MSR, %ecx
|
|
rdmsr
|
|
or $SYSCFG_MSR_MtrrFixDramModEn, %eax
|
|
wrmsr
|
|
#endif
|
|
|
|
load_msr:
|
|
mov (%edi), %ecx
|
|
mov 4(%edi), %eax
|
|
mov 8(%edi), %edx
|
|
wrmsr
|
|
add $12, %edi
|
|
dec %ebx
|
|
jnz load_msr
|
|
|
|
#if CONFIG(X86_AMD_FIXED_MTRRS)
|
|
mov $SYSCFG_MSR, %ecx
|
|
rdmsr
|
|
and $~SYSCFG_MSR_MtrrFixDramModEn, %eax
|
|
wrmsr
|
|
#endif
|
|
|
|
1:
|
|
/* Enable caching. */
|
|
mov %cr0, %eax
|
|
and $~(CR0_CLEAR_FLAGS_CACHE_ENABLE), %eax
|
|
mov %eax, %cr0
|
|
|
|
#if CONFIG(SSE)
|
|
/* Enable sse instructions. */
|
|
mov %cr4, %eax
|
|
orl $(CR4_OSFXSR | CR4_OSXMMEXCPT), %eax
|
|
mov %eax, %cr4
|
|
#endif
|
|
|
|
/* c_handler(cpu_num), preserve proper stack alignment */
|
|
sub $12, %esp
|
|
push %esi /* cpu_num */
|
|
mov c_handler, %eax
|
|
call *%eax
|
|
halt_jump:
|
|
hlt
|
|
jmp halt_jump
|