1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
* Copyright (C) 2007-2008 coresystems GmbH
* Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <cpu/x86/mtrr.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/post_code.h>
#include <microcode_size.h>
#include <cbmem.h>
#ifndef CONFIG_FSP_LOC
# error "CONFIG_FSP_LOC must be set."
#endif
#ifndef CONFIG_CPU_MICROCODE_CBFS_LOC
# error "CONFIG_CPU_MICROCODE_CBFS_LOC must be set."
#endif
cmp $0, %eax
je cache_as_ram
mov $0xa0, %eax
jmp .Lhlt
cache_as_ram:
post_code(0x20)
/*
* Find the FSP binary in cbfs.
* Make a fake stack that has the return value back to this code.
*/
lea fake_fsp_stack, %esp
jmp find_fsp
find_fsp_ret:
/* Save the FSP location */
mov %eax, %ebp
cmp $CONFIG_FSP_LOC, %eax
jae find_fsp_ok
mov $0xb0, %eax
jmp .Lhlt
find_fsp_ok:
post_code(0x22)
/* Calculate entry into FSP */
mov 0x30(%ebp), %eax /* Load TempRamInitEntry */
add 0x1c(%ebp), %eax /* add in the offset for the FSP base address */
/*
* Pass early init variables on a fake stack (no memory yet)
* as well as the return location
*/
lea CAR_init_stack, %esp
/* call FSP binary to setup temporary stack */
jmp *%eax
CAR_init_done:
addl $4, %esp
cmp $0, %eax
je car_init_ok
add $0xc0, %eax
jmp .Lhlt
car_init_ok:
/* Save FSP_INFO_HEADER location in ebx */
mov %ebp, %ebx
/*
* set up bootloader stack
* ecx: stack base
* edx: stack top
*/
mov %edx, %esp
movl %esp, %ebp
/* Clear the cbmem CAR memory region. */
movl %ecx, %edi
movl %edx, %ecx
sub %edi, %ecx
shr $2, %ecx
xorl %eax, %eax
rep stosl
before_romstage:
post_code(0x23)
/* Call romstage.c main function. */
pushl %ebx /* main takes FSP_INFO_HEADER as its argument */
call main /* does not return */
movb $0xB8, %ah
jmp .Lhlt
.Lhlt:
#if IS_ENABLED(CONFIG_POST_IO)
outb %al, $CONFIG_POST_IO_PORT
#endif
hlt
jmp .Lhlt
/*
* esp is set to this location so that the call into and return from the FSP
* in find_fsp will work.
*/
.align 4
fake_fsp_stack:
.long find_fsp_ret
CAR_init_params:
.long CONFIG_CPU_MICROCODE_CBFS_LOC
.long MICROCODE_REGION_LENGTH
.long 0xFFFFFFFF - CACHE_ROM_SIZE + 1 /* Firmware Location */
.long CACHE_ROM_SIZE /* Total Firmware Length */
CAR_init_stack:
.long CAR_init_done
.long CAR_init_params
|