mb/google/fatcat: Suppress unnecessary extra space in device trees
[coreboot2.git] / src / arch / x86 / wakeup.S
blob7462dadbe8d5188238b3a04f3ce9fec2f851bf26
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #define WAKEUP_BASE             0x600
4 #define RELOCATED(x)    (x - __wakeup + WAKEUP_BASE)
6 /* CR0 bits */
7 #define PE              (1 << 0)
9 #if ENV_X86_64
10         .code64
11 #else
12         .code32
13 #endif
15         .globl __wakeup
16 __wakeup:
17 #if ENV_X86_64
18         /* When called in x86_64 mode, the resume vector is in %rdi
19          * instead of the stack, save it in 4(%rsp) for the 32-bit code.
20          * It's OK to overwrite the return address at (%rsp) because this
21          * function doesn't return.
22          */
23         mov     %edi, 4(%rsp)
25         xor     %rax,%rax
26         mov     %ss, %ax
27         push    %rax
28         mov     %rsp, %rax
29         add     $8, %rax
30         push    %rax
31         pushfq
32         push    $0x10
33         lea     3(%rip), %rax
34         push    %rax
35         iretq
37         .code32
39         /* disable paging */
40         mov     %cr0, %eax
41         btc     $31, %eax
42         mov     %eax, %cr0
44         /* disable long mode */
45         mov     $0xC0000080, %ecx
46         rdmsr
47         btc     $8, %eax
48         wrmsr
49 #endif
50         /* First prepare the jmp to the resume vector */
51         mov     0x4(%esp), %eax /* vector */
52         /* last 4 bits of linear addr are taken as offset */
53         andw    $0x0f, %ax
54         movw    %ax, (__wakeup_offset)
55         mov     0x4(%esp), %eax
56         /* the rest is taken as segment */
57         shr     $4, %eax
58         movw    %ax, (__wakeup_segment)
60         /* Activate the right segment descriptor real mode. */
61         ljmp    $0x28, $RELOCATED(1f)
63 .code16
64         /* 16 bit code from here on... */
66         /* Load the segment registers w/ properly configured
67          * segment descriptors. They will retain these
68          * configurations (limits, writability, etc.) once
69          * protected mode is turned off.
70          */
71         mov     $0x30, %ax
72         mov     %ax, %ds
73         mov     %ax, %es
74         mov     %ax, %fs
75         mov     %ax, %gs
76         mov     %ax, %ss
78         /* Turn off protection */
79         movl    %cr0, %eax
80         andl    $~PE, %eax
81         movl    %eax, %cr0
83         /* Now really going into real mode */
84         ljmp    $0, $RELOCATED(1f)
86         movw    $0x0, %ax
87         movw    %ax, %ds
88         movw    %ax, %es
89         movw    %ax, %ss
90         movw    %ax, %fs
91         movw    %ax, %gs
93         /* This is a FAR JMP to the OS waking vector. The C code changed
94          * the address to be correct.
95          */
96         .byte 0xea
98 __wakeup_offset = RELOCATED(.)
99         .word 0x0000
101 __wakeup_segment = RELOCATED(.)
102         .word 0x0000
104         .globl __wakeup_size
105 __wakeup_size:
106         .long . - __wakeup