Skip to content

Commit 6358153

Browse files
rizlikdanielinux
authored andcommitted
x86: add support for gdt table in C
1 parent aa01f6e commit 6358153

File tree

5 files changed

+136
-3
lines changed

5 files changed

+136
-3
lines changed

arch.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,7 @@ ifeq ("${FSP}", "1")
10121012
OBJS += src/x86/mptable.o
10131013
OBJS += src/stage2_params.o
10141014
OBJS += src/x86/exceptions.o
1015+
OBJS += src/x86/gdt.o
10151016
UPDATE_OBJS := src/update_disk.o
10161017
CFLAGS+=-DWOLFBOOT_UPDATE_DISK
10171018
ifeq ($(64BIT),1)

hal/kontron_vx3060_s2.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <uart_drv.h>
2525
#include <printf.h>
2626
#include <pci.h>
27+
#include <x86/gdt.h>
2728
#include <x86/common.h>
2829

2930
#ifdef __WOLFBOOT
@@ -85,6 +86,8 @@ int tgl_lock_bios_region()
8586

8687
void hal_init(void)
8788
{
89+
gdt_setup_table();
90+
gdt_update_segments();
8891
}
8992

9093
void hal_prepare_boot(void)

hal/x86_fsp_qemu.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@
2626

2727
#ifdef __WOLFBOOT
2828
#include <printf.h>
29-
#include <x86/common.h>
30-
#include <x86/ahci.h>
3129
#include <x86/ata.h>
32-
#include <x86/gpt.h>
30+
#include <x86/gdt.h>
31+
#include <x86/common.h>
3332
#include <pci.h>
3433

3534
void hal_init(void)
3635
{
36+
gdt_setup_table();
37+
gdt_update_segments();
3738
}
3839

3940
void hal_prepare_boot(void)

include/x86/gdt.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* gdt.h
2+
*
3+
* Copyright (C) 2023 wolfSSL Inc.
4+
*
5+
* This file is part of wolfBoot.
6+
*
7+
* wolfBoot is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfBoot is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20+
*/
21+
#ifndef GDT_H
22+
#define GDT_H
23+
24+
#define GDT_DS (0x08)
25+
#define GDT_CS_32BIT (0x10)
26+
#define GDT_CS_64BIT (0x18)
27+
#define GDT_CS_32BIT_COMPAT (0x20)
28+
29+
int gdt_setup_table(void);
30+
int gdt_update_segments(void);
31+
32+
#endif /* GDT_H */

src/x86/gdt.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/* gdt.c
2+
*
3+
* Copyright (C) 2023 wolfSSL Inc.
4+
*
5+
* This file is part of wolfBoot.
6+
*
7+
* wolfBoot is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfBoot is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20+
*
21+
*/
22+
#include <stdint.h>
23+
#include <x86/gdt.h>
24+
25+
struct segment_descriptor {
26+
uint16_t seg_limit_15_0;
27+
uint16_t base_addr_15_0;
28+
uint8_t base_addr_23_16;
29+
uint8_t type_s_dpl_p;
30+
uint8_t seg_limt_19_16_avl_flags;
31+
uint8_t base_addr_31_24;
32+
} __attribute__((packed));
33+
34+
struct gdtr_32 {
35+
uint16_t limit;
36+
uint32_t base;
37+
} __attribute__((packed));
38+
39+
struct gdtr_64 {
40+
uint16_t limit;
41+
uint64_t base;
42+
} __attribute__((packed));
43+
44+
#define SEGMENT_DESCRIPTOR_INIT(base, limit, type, s, dpl, p, avl, l, db, g) { \
45+
.seg_limit_15_0 = (limit) & 0xffff, \
46+
.base_addr_15_0 = (base) & 0xffff, \
47+
.base_addr_23_16 = (((base) >> 16) & 0xff), \
48+
.type_s_dpl_p = ((type & 0xf) | ((s & 0x1) << 4) | ((dpl & 0x3) << 5) | ((p & 0x1) << 7)), \
49+
.seg_limt_19_16_avl_flags = ((((limit) >> 16) & 0xf) | ((avl & 0x1) << 4) | ((l & 0x1) << 5) | ((db & 0x1) << 6) | ((g & 0x1) << 7)), \
50+
.base_addr_31_24 = ((base) >> 24) & 0xff, \
51+
}
52+
53+
#define GDT_NUM_ENTRIES 5
54+
55+
struct segment_descriptor gdt[GDT_NUM_ENTRIES] = {
56+
/* NULL */
57+
SEGMENT_DESCRIPTOR_INIT(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
58+
/* Data */
59+
SEGMENT_DESCRIPTOR_INIT(0, 0xffffffff, 0x3, 1, 0, 1, 0, 0, 1, 1),
60+
/* Code (32bit) */
61+
SEGMENT_DESCRIPTOR_INIT(0, 0xffffffff, 0xb, 1, 0, 1, 0, 0, 1, 1),
62+
/* Code (64bit) */
63+
SEGMENT_DESCRIPTOR_INIT(0, 0xffffffff, 0xb, 1, 0, 1, 0, 1, 0, 1),
64+
/* Code (64bit) compat mode */
65+
SEGMENT_DESCRIPTOR_INIT(0, 0xffffffff, 0xb, 1, 0, 1, 0, 0, 1, 1),
66+
};
67+
68+
int gdt_setup_table(void)
69+
{
70+
struct gdtr_64 gdtr;
71+
gdtr.limit = sizeof(gdt) - 1;
72+
gdtr.base = (uint64_t)(uintptr_t)gdt;
73+
__asm__ volatile ("lgdt %0" : : "m" (gdtr));
74+
return 0;
75+
}
76+
77+
int gdt_update_segments(void)
78+
{
79+
__asm__ volatile (
80+
"mov %0, %%ax\r\n"
81+
"mov %%ax, %%ds\r\n"
82+
"mov %%ax, %%es\r\n"
83+
"mov %%ax, %%fs\r\n"
84+
"mov %%ax, %%gs\r\n"
85+
"mov %%ax, %%ss\r\n"
86+
"push %1\r\n"
87+
"lea (seg_cs), %%rax\r\n"
88+
"push %%rax\r\n"
89+
"retfq\r\n"
90+
"seg_cs:\r\n"
91+
:
92+
: "i"(GDT_DS), "i" (GDT_CS_64BIT)
93+
: "rax"
94+
);
95+
return 0;
96+
}

0 commit comments

Comments
 (0)