mb/google/brya/var/orisa: Update Type C DisplayPort HPD Configuration
[coreboot2.git] / src / cpu / x86 / entry16.S
blobff4f1a26d04fe250d9ac0ba7c10974a7e9af8aea
1 /* SPDX-License-Identifier: BSD-3-Clause */
3 /*
4  * This software and ancillary information (herein called SOFTWARE)
5  * called LinuxBIOS is made available under the terms described here.
6  *
7  * The SOFTWARE has been approved for release with associated
8  * LA-CC Number 00-34. Unless otherwise indicated, this SOFTWARE has
9  * been authored by an employee or employees of the University of
10  * California, operator of the Los Alamos National Laboratory under
11  * Contract No. W-7405-ENG-36 with the U.S. Department of Energy.
12  *
13  * The U.S. Government has rights to use, reproduce, and distribute this
14  * SOFTWARE. The public may copy, distribute, prepare derivative works
15  * and publicly display this SOFTWARE without charge, provided that this
16  * Notice and any statement of authorship are reproduced on all copies.
17  *
18  * Neither the Government nor the University makes any warranty, express
19  * or implied, or assumes any liability or responsibility for the use of
20  * this SOFTWARE.  If SOFTWARE is modified to produce derivative works,
21  * such modified SOFTWARE should be clearly marked, so as not to confuse
22  * it with the version available from LANL.
23  *
24  */
27 /* Start code to put an i386 or later processor into 32-bit protected mode.
28  */
30 #include <arch/rom_segs.h>
31 #include <cpu/x86/post_code.h>
33 .section .init._start, "ax", @progbits
35 /* Symbol _start16bit must reachable from the reset vector, and be aligned to
36  * 4kB to start AP CPUs with Startup IPI message without RAM.
37  */
38 .code16
39 .globl _start16bit
40 .type _start16bit, @function
42 _start16bit:
43         cli
44         /* Save the BIST result */
45         movl    %eax, %ebp
46         post_code(POSTCODE_RESET_VECTOR_CORRECT)
48         /* IMMEDIATELY invalidate the translation lookaside buffer (TLB) before
49          * executing any further code. Even though paging is disabled we
50          * could still get false address translations due to the TLB if we
51          * didn't invalidate it. Thanks to kmliu@sis.com.tw for this TLB fix.
52          */
54         xorl    %eax, %eax
55         movl    %eax, %cr3    /* Invalidate TLB*/
57         /* Invalidating the cache here seems to be a bad idea on
58          * modern processors.  Don't.
59          * If we are hyperthreaded or we have multiple cores it is bad,
60          * for SMP startup.  On Opterons it causes a 5 second delay.
61          * Invalidating the cache was pure paranoia in any event.
62          * If your CPU needs it you can write a CPU dependent version of
63          * entry16.inc.
64          */
66         /* Note: gas handles memory addresses in 16 bit code very poorly.
67          * In particular it doesn't appear to have a directive allowing you
68          * associate a section or even an absolute offset with a segment register.
69          *
70          * This means that anything except cs:ip relative offsets are
71          * a real pain in 16 bit mode.  And explains why it is almost
72          * impossible to get gas to do lgdt correctly.
73          *
74          * One way to work around this is to have the linker do the
75          * math instead of the assembler.  This solves the very
76          * practical problem of being able to write code that can
77          * be relocated.
78          *
79          * An lgdt call before we have memory enabled cannot be
80          * position independent, as we cannot execute a call
81          * instruction to get our current instruction pointer.
82          * So while this code is relocatable it isn't arbitrarily
83          * relocatable.
84          *
85          * The criteria for relocation have been relaxed to their
86          * utmost, so that we can use the same code for both
87          * our initial entry point and startup of the second CPU.
88          * The code assumes when executing at _start16bit that:
89          * (((cs & 0xfff) == 0) and (ip == _start16bit & 0xffff))
90          * or
91          * ((cs == anything) and (ip == 0)).
92          *
93          * The restrictions in reset16.inc mean that _start16bit initially
94          * must be loaded at or above 0xffff0000 or below 0x100000.
95          *
96          * The linker scripts computes gdtptr16_offset by simply returning
97          * the low 16 bits.  This means that the initial segment used
98          * when start is called must be 64K aligned.  This should not
99          * restrict the address as the ip address can be anything.
100          *
101          * Also load an IDT with NULL limit to prevent the 16bit IDT being used
102          * in protected mode before c_start.S sets up a 32bit IDT when entering
103          * RAM stage. In practise: CPU will shutdown on any exception.
104          * See IA32 manual Vol 3A 19.26 Interrupts.
105          */
107         movw    %cs, %ax
108         shlw    $4, %ax
109         movw    $nullidt_offset, %bx
110         subw    %ax, %bx
111         lidt    %cs:(%bx)
112         movw    $gdtptr_offset, %bx
113         subw    %ax, %bx
114         lgdtl   %cs:(%bx)
116 #if CONFIG(INTEL_CBNT_SUPPORT)
117 #include <cpu/intel/msr.h>
118         movl    $MSR_BOOT_GUARD_SACM_INFO, %ecx
119         rdmsr
120         andl    $B_BOOT_GUARD_SACM_INFO_NEM_ENABLED, %eax
121         jz      1f
122         movl    %cr0, %eax
123         andl    $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */
124         orl     $0x01, %eax /* PE = 1 */
125         movl    %eax, %cr0
126         jmp     2f
127 #endif
129         movl    %cr0, %eax
130         andl    $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */
131         orl     $0x60000001, %eax /* CD, NW, PE = 1 */
132         movl    %eax, %cr0
135         /* Restore BIST to %eax */
136         movl    %ebp, %eax
138         /* Now that we are in protected mode jump to a 32 bit code segment. */
139         ljmpl   $ROM_CODE_SEG, $bootblock_protected_mode_entry
141         /**
142          * The gdt is defined in gdt_init.S, it has a 4 Gb code segment
143          * at 0x08, and a 4 GB data segment at 0x10;
144          */
145 __gdtptr:
146         .long   gdtptr
148 .align  4
149 .globl nullidt
150 nullidt:
151         .word   0       /* limit */
152         .long   0
153         .word   0