blob: dfd9d85e3002bec934dcfe1f7852db17efb8a48a [file] [log] [blame]
Angel Ponsf23ae0b2020-04-02 23:48:12 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Stefan Reinauerdebb11f2008-10-29 04:46:52 +00003
Stefan Reinauer14e22772010-04-27 06:56:47 +00004// FIXME: Is this piece of code southbridge specific, or
Stefan Reinauer4da810b2009-07-21 21:41:42 +00005// can it be cleaned up so this include is not required?
Stefan Reinauerbc0f7a62010-08-01 15:41:14 +00006// It's needed right now because we get our DEFAULT_PMBASE from
Stefan Reinauer5f5436f2010-04-25 20:42:02 +00007// here.
Julius Wernercd49cce2019-03-05 16:53:33 -08008#if CONFIG(SOUTHBRIDGE_INTEL_I82801DX)
Elyes HAOUAS660389e2018-10-14 20:34:09 +02009#include <southbridge/intel/i82801dx/i82801dx.h>
Julius Wernercd49cce2019-03-05 16:53:33 -080010#elif CONFIG(SOUTHBRIDGE_INTEL_I82801IX)
Elyes HAOUAS660389e2018-10-14 20:34:09 +020011#include <southbridge/intel/i82801ix/i82801ix.h>
Stefan Reinauerbc0f7a62010-08-01 15:41:14 +000012#else
13#error "Southbridge needs SMM handler support."
14#endif
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000015
Edward O'Callaghan1104c272017-01-08 19:57:45 +110016// ADDR32() macro
Patrick Georgie8741fe2017-09-04 17:37:31 +020017#include <arch/registers.h>
Edward O'Callaghan1104c272017-01-08 19:57:45 +110018
Kyösti Mälkki4d372c72019-07-08 13:48:57 +030019#if !CONFIG(SMM_ASEG)
20#error "Only use this file with ASEG."
21#endif /* CONFIG_SMM_ASEG */
Stefan Reinauer3aa067f2012-04-02 13:24:04 -070022
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000023#define LAPIC_ID 0xfee00020
24
25.global smm_relocation_start
26.global smm_relocation_end
27
28/* initially SMM is some sort of real mode. */
29.code16
30
31/**
Stefan Reinauer8c5b58e2012-04-04 10:38:05 -070032 * When starting up, x86 CPUs have their SMBASE set to 0x30000. However,
33 * this is not a good place for the SMM handler to live, so it needs to
34 * be relocated.
35 * Traditionally SMM handlers used to live in the A segment (0xa0000).
36 * With growing SMM handlers, more CPU cores, etc. CPU vendors started
37 * allowing to relocate the handler to the end of physical memory, which
38 * they refer to as TSEG.
39 * This trampoline code relocates SMBASE to base address - ( lapicid * 0x400 )
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000040 *
41 * Why 0x400? It is a safe value to cover the save state area per CPU. On
42 * current AMD CPUs this area is _documented_ to be 0x200 bytes. On Intel
43 * Core 2 CPUs the _documented_ parts of the save state area is 48 bytes
44 * bigger, effectively sizing our data structures 0x300 bytes.
45 *
Stefan Reinauer8c5b58e2012-04-04 10:38:05 -070046 * Example (with SMM handler living at 0xa0000):
47 *
Elyes HAOUAS9d759572018-05-28 15:41:12 +020048 * LAPICID SMBASE SMM Entry SAVE STATE
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000049 * 0 0xa0000 0xa8000 0xafd00
50 * 1 0x9fc00 0xa7c00 0xaf900
51 * 2 0x9f800 0xa7800 0xaf500
52 * 3 0x9f400 0xa7400 0xaf100
53 * 4 0x9f000 0xa7000 0xaed00
54 * 5 0x9ec00 0xa6c00 0xae900
55 * 6 0x9e800 0xa6800 0xae500
56 * 7 0x9e400 0xa6400 0xae100
57 * 8 0x9e000 0xa6000 0xadd00
58 * 9 0x9dc00 0xa5c00 0xad900
59 * 10 0x9d800 0xa5800 0xad500
60 * 11 0x9d400 0xa5400 0xad100
61 * 12 0x9d000 0xa5000 0xacd00
62 * 13 0x9cc00 0xa4c00 0xac900
63 * 14 0x9c800 0xa4800 0xac500
64 * 15 0x9c400 0xa4400 0xac100
65 * . . . .
66 * . . . .
67 * . . . .
68 * 31 0x98400 0xa0400 0xa8100
69 *
70 * With 32 cores, the SMM handler would need to fit between
71 * 0xa0000-0xa0400 and the stub plus stack would need to go
72 * at 0xa8000-0xa8100 (example for core 0). That is not enough.
73 *
Elyes HAOUASd82be922016-07-28 18:58:27 +020074 * This means we're basically limited to 16 CPU cores before
Stefan Reinauer8c5b58e2012-04-04 10:38:05 -070075 * we need to move the SMM handler to TSEG.
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000076 *
77 * Note: Some versions of Pentium M need their SMBASE aligned to 32k.
78 * On those the above only works for up to 2 cores. But for now we only
79 * care fore Core (2) Duo/Solo
80 *
81 */
82
83smm_relocation_start:
84 /* Check revision to see if AMD64 style SMM_BASE
85 * Intel Core Solo/Duo: 0x30007
86 * Intel Core2 Solo/Duo: 0x30100
Stefan Reinauer3aa067f2012-04-02 13:24:04 -070087 * Intel SandyBridge: 0x30101
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000088 * AMD64: 0x3XX64
89 * This check does not make much sense, unless someone ports
90 * SMI handling to AMD64 CPUs.
91 */
92
93 mov $0x38000 + 0x7efc, %ebx
Edward O'Callaghan1104c272017-01-08 19:57:45 +110094 ADDR32(mov) (%ebx), %al
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000095 cmp $0x64, %al
96 je 1f
Stefan Reinauer14e22772010-04-27 06:56:47 +000097
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000098 mov $0x38000 + 0x7ef8, %ebx
99 jmp smm_relocate
1001:
101 mov $0x38000 + 0x7f00, %ebx
102
103smm_relocate:
104 /* Get this CPU's LAPIC ID */
105 movl $LAPIC_ID, %esi
Edward O'Callaghan1104c272017-01-08 19:57:45 +1100106 ADDR32(movl) (%esi), %ecx
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000107 shr $24, %ecx
Stefan Reinauer14e22772010-04-27 06:56:47 +0000108
109 /* calculate offset by multiplying the
Elyes HAOUASd6e96862016-08-21 10:12:15 +0200110 * APIC ID by 1024 (0x400)
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000111 */
112 movl %ecx, %edx
113 shl $10, %edx
114
115 movl $0xa0000, %eax
116 subl %edx, %eax /* subtract offset, see above */
117
Edward O'Callaghan1104c272017-01-08 19:57:45 +1100118 ADDR32(movl) %eax, (%ebx)
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000119
Stefan Reinauerbc0f7a62010-08-01 15:41:14 +0000120 /* The next section of code is potentially southbridge specific */
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000121
122 /* Clear SMI status */
123 movw $(DEFAULT_PMBASE + 0x34), %dx
124 inw %dx, %ax
125 outw %ax, %dx
126
127 /* Clear PM1 status */
128 movw $(DEFAULT_PMBASE + 0x00), %dx
129 inw %dx, %ax
130 outw %ax, %dx
131
132 /* Set EOS bit so other SMIs can occur */
133 movw $(DEFAULT_PMBASE + 0x30), %dx
134 inl %dx, %eax
135 orl $(1 << 1), %eax
136 outl %eax, %dx
137
Stefan Reinauerbc0f7a62010-08-01 15:41:14 +0000138 /* End of southbridge specific section. */
139
Julius Wernercd49cce2019-03-05 16:53:33 -0800140#if CONFIG(DEBUG_SMM_RELOCATION)
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000141 /* print [SMM-x] so we can determine if CPUx went to SMM */
Stefan Reinauer08670622009-06-30 15:17:49 +0000142 movw $CONFIG_TTYS0_BASE, %dx
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000143 mov $'[', %al
144 outb %al, %dx
145 mov $'S', %al
146 outb %al, %dx
147 mov $'M', %al
148 outb %al, %dx
149 outb %al, %dx
150 movb $'-', %al
151 outb %al, %dx
Elyes HAOUASd82be922016-07-28 18:58:27 +0200152 /* calculate ascii of CPU number. More than 9 cores? -> FIXME */
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000153 movb %cl, %al
Stefan Reinauer14e22772010-04-27 06:56:47 +0000154 addb $'0', %al
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000155 outb %al, %dx
156 mov $']', %al
157 outb %al, %dx
158 mov $'\r', %al
159 outb %al, %dx
160 mov $'\n', %al
161 outb %al, %dx
162#endif
163
164 /* That's it. return */
165 rsm
166smm_relocation_end: