blob: c9aec6d111d18d27fd6487c9320d684b8701c2c2 [file] [log] [blame]
Stefan Reinauer3b314022009-10-26 17:04:28 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2008-2009 coresystems GmbH
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Stefan Reinauer3b314022009-10-26 17:04:28 +000014 */
15
16#include <types.h>
17#include <string.h>
18#include <cbmem.h>
19#include <console/console.h>
Kyösti Mälkkibae775a2014-12-18 10:36:33 +020020#include <cpu/x86/gdt.h>
Stefan Reinauer3b314022009-10-26 17:04:28 +000021
22/* i386 lgdt argument */
23struct gdtarg {
24 u16 limit;
Stefan Reinauer96938852015-06-18 01:23:48 -070025#ifdef __x86_64__
26 u64 base;
27#else
Stefan Reinauer3b314022009-10-26 17:04:28 +000028 u32 base;
Stefan Reinauer96938852015-06-18 01:23:48 -070029#endif
Stefan Reinauer6a001132017-07-13 02:20:27 +020030} __packed;
Stefan Reinauer3b314022009-10-26 17:04:28 +000031
Paul Menzel95c4aa52017-10-11 09:58:20 +020032/*
33 * Copy GDT to new location and reload it.
Kyösti Mälkkibae775a2014-12-18 10:36:33 +020034 * FIXME: We only do this for BSP CPU.
35 */
Aaron Durbin41607a42015-06-09 13:54:10 -050036static void move_gdt(int is_recovery)
Stefan Reinauer3b314022009-10-26 17:04:28 +000037{
38 void *newgdt;
Paul Menzel01873802017-10-11 15:41:43 +020039 u16 num_gdt_bytes;
Stefan Reinauer3b314022009-10-26 17:04:28 +000040 struct gdtarg gdtarg;
41
Aaron Durbinebbd12f2016-11-19 10:06:00 -060042 /* ramstage is already in high memory. No need to use a new gdt. */
Julius Wernercd49cce2019-03-05 16:53:33 -080043 if (CONFIG(RELOCATABLE_RAMSTAGE))
Aaron Durbinebbd12f2016-11-19 10:06:00 -060044 return;
45
Stefan Reinauer3b314022009-10-26 17:04:28 +000046 newgdt = cbmem_find(CBMEM_ID_GDT);
Paul Menzel01873802017-10-11 15:41:43 +020047 num_gdt_bytes = (uintptr_t)&gdt_end - (uintptr_t)&gdt;
Stefan Reinauer3b314022009-10-26 17:04:28 +000048 if (!newgdt) {
49 newgdt = cbmem_add(CBMEM_ID_GDT, ALIGN(num_gdt_bytes, 512));
50 if (!newgdt) {
51 printk(BIOS_ERR, "Error: Could not relocate GDT.\n");
52 return;
53 }
Lee Leahy024b13d2017-03-16 13:41:11 -070054 memcpy((void *)newgdt, &gdt, num_gdt_bytes);
Stefan Reinauer3b314022009-10-26 17:04:28 +000055 }
Kyösti Mälkki78c5f0c2016-11-19 16:39:10 +020056 printk(BIOS_DEBUG, "Moving GDT to %p...", newgdt);
Stefan Reinauer3b314022009-10-26 17:04:28 +000057
Stefan Reinauer96938852015-06-18 01:23:48 -070058 gdtarg.base = (uintptr_t)newgdt;
Stefan Reinauer3b314022009-10-26 17:04:28 +000059 gdtarg.limit = num_gdt_bytes - 1;
60
61 __asm__ __volatile__ ("lgdt %0\n\t" : : "m" (gdtarg));
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000062 printk(BIOS_DEBUG, "ok\n");
Stefan Reinauer3b314022009-10-26 17:04:28 +000063}
Kyösti Mälkki4fbac462015-01-07 04:48:43 +020064RAMSTAGE_CBMEM_INIT_HOOK(move_gdt)