blob: 1558ac62c8dad8bca239a6917767903c050e3071 [file] [log] [blame]
Patrick Georgi11f00792020-03-04 15:10:45 +01001/* SPDX-License-Identifier: GPL-2.0-only */
Patrick Georgi11f00792020-03-04 15:10:45 +01002
Hannah Williamsd3c0c0c2018-04-27 09:09:04 -07003.code32
4.section ".text._gdt_", "ax", @progbits
5
6 .globl gdt_init
7gdt_init:
8 lgdt %cs:gdtptr
9 ret
10
11.previous
12 .align 4
13.globl gdtptr
Hannah Williamsd3c0c0c2018-04-27 09:09:04 -070014gdtptr:
15 .word gdt_end - gdt -1 /* compute the table limit */
16 .long gdt /* we know the offset */
Patrick Rudolph4e8dee52019-03-03 17:58:54 +010017
Patrick Rudolph8daa12f2018-12-26 15:12:32 +010018#ifdef __x86_64__
19.code64
20.section ".text._gdt64_", "ax", @progbits
21 .globl gdt_init64
22gdt_init64:
Patrick Rudolph29ed4f52020-07-05 08:46:55 +020023 /* Workaround a bug in the assembler.
24 * The following code doesn't work:
25 * lgdt gdtptr64
26 *
27 * The assembler tries to save memory by using 32bit displacement addressing mode.
28 * Displacements are using signed integers.
29 * This is fine in protected mode, as the negative address points to the correct
30 * address > 2GiB, but in long mode this doesn't work at all.
31 * Tests showed that QEMU can gracefully handle it, but real CPUs can't.
32 *
33 * Use the movabs pseudo instruction to force using a 64bit absolute address.
34 */
35 movabs $gdtptr64, %rax
36 lgdt (%rax)
Patrick Rudolph8daa12f2018-12-26 15:12:32 +010037 ret
38
39.previous
40 .align 4
41.globl gdtptr64
42gdtptr64:
43 .word gdt_end - gdt -1 /* compute the table limit */
44 .quad gdt /* we know the offset */
45#endif
46
Patrick Rudolph4e8dee52019-03-03 17:58:54 +010047 .align 4
48gdt:
49 /* selgdt 0, unused */
50 .word 0x0000, 0x0000 /* dummy */
51 .byte 0x00, 0x00, 0x00, 0x00
Hannah Williamsd3c0c0c2018-04-27 09:09:04 -070052
53 /* selgdt 0x08, flat code segment */
54 .word 0xffff, 0x0000
55 .byte 0x00, 0x9b, 0xcf, 0x00 /* G=1 and 0x0f, So we get 4Gbytes
56 for limit */
57
58 /* selgdt 0x10,flat data segment */
59 .word 0xffff, 0x0000
60 .byte 0x00, 0x93, 0xcf, 0x00
61
62 /* selgdt 0x18, flat code segment (64-bit) */
63 .word 0xffff, 0x0000
64 .byte 0x00, 0x9b, 0xaf, 0x00
65
66gdt_end: