18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci#include <asm/trap_pf.h>
38c2ecf20Sopenharmony_ci#include <asm/segment.h>
48c2ecf20Sopenharmony_ci#include <asm/trapnr.h>
58c2ecf20Sopenharmony_ci#include "misc.h"
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_cistatic void set_idt_entry(int vector, void (*handler)(void))
88c2ecf20Sopenharmony_ci{
98c2ecf20Sopenharmony_ci	unsigned long address = (unsigned long)handler;
108c2ecf20Sopenharmony_ci	gate_desc entry;
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci	memset(&entry, 0, sizeof(entry));
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci	entry.offset_low    = (u16)(address & 0xffff);
158c2ecf20Sopenharmony_ci	entry.segment       = __KERNEL_CS;
168c2ecf20Sopenharmony_ci	entry.bits.type     = GATE_TRAP;
178c2ecf20Sopenharmony_ci	entry.bits.p        = 1;
188c2ecf20Sopenharmony_ci	entry.offset_middle = (u16)((address >> 16) & 0xffff);
198c2ecf20Sopenharmony_ci	entry.offset_high   = (u32)(address >> 32);
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci	memcpy(&boot_idt[vector], &entry, sizeof(entry));
228c2ecf20Sopenharmony_ci}
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci/* Have this here so we don't need to include <asm/desc.h> */
258c2ecf20Sopenharmony_cistatic void load_boot_idt(const struct desc_ptr *dtr)
268c2ecf20Sopenharmony_ci{
278c2ecf20Sopenharmony_ci	asm volatile("lidt %0"::"m" (*dtr));
288c2ecf20Sopenharmony_ci}
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci/* Setup IDT before kernel jumping to  .Lrelocated */
318c2ecf20Sopenharmony_civoid load_stage1_idt(void)
328c2ecf20Sopenharmony_ci{
338c2ecf20Sopenharmony_ci	boot_idt_desc.address = (unsigned long)boot_idt;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT))
378c2ecf20Sopenharmony_ci		set_idt_entry(X86_TRAP_VC, boot_stage1_vc);
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	load_boot_idt(&boot_idt_desc);
408c2ecf20Sopenharmony_ci}
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci/* Setup IDT after kernel jumping to  .Lrelocated */
438c2ecf20Sopenharmony_civoid load_stage2_idt(void)
448c2ecf20Sopenharmony_ci{
458c2ecf20Sopenharmony_ci	boot_idt_desc.address = (unsigned long)boot_idt;
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	set_idt_entry(X86_TRAP_PF, boot_page_fault);
488c2ecf20Sopenharmony_ci	set_idt_entry(X86_TRAP_NMI, boot_nmi_trap);
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci#ifdef CONFIG_AMD_MEM_ENCRYPT
518c2ecf20Sopenharmony_ci	set_idt_entry(X86_TRAP_VC, boot_stage2_vc);
528c2ecf20Sopenharmony_ci#endif
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	load_boot_idt(&boot_idt_desc);
558c2ecf20Sopenharmony_ci}
56