/* Copyright (C) 2021,2022 fef <owo@fef.moe>.  All rights reserved. */

#include <arch/segment.h>
#include <arch/vmparam.h>

#include <asm/common.h>

	.section .multiboot.data, "a", @progbits

	.align 8
	.long 0
	.word 0
DATA(_x86_gdt_desc_phys)
	.word _x86_gdt_end - _x86_gdt - 1	/* limit */
	.quad _x86_gdt - KERNBASE		/* base */
END(_x86_gdt_desc_phys)

	.data

	.align 8
	.long 0 /* padding */
	.word 0 /* another padding :) */
DATA(_x86_gdt_desc)
	.word _x86_gdt_end - _x86_gdt - 1	/* limit */
	.quad _x86_gdt				/* base */
END(_x86_gdt_desc)

	/*
	 * These entries were generated using the GDT generator tool in
	 * arch/x86/tools/gdt.c and are the same on both i386 and amd64.
	 *
	 * AMD did the only sane thing and reduced segmentation to its minimum
	 * in 64-bit mode, where the base and limit values are ignored (64-bit
	 * segments always refer to the entire linear memory).  They still have
	 * their base and limit set to the entire 32-bit address space though,
	 * because the CPU makes one last 32-bit segment check when jumping
	 * from 32-bit to 64-bit mode.
	 *
	 * The base values for the two TSS entries are inserted in the assembly
	 * setup routine (see arch/x86/boot/setup{32,64}.S).
	 */
	.align 8
DATA(_x86_gdt)
	.quad 0x0000000000000000 /* 0x00 null descriptor    */
	.quad 0x0000000000000000 /* 0x08 unused             */
	.quad 0x00cf9a000000ffff /* 0x10 kernel code 32-bit */
	.quad 0x00cffa000000ffff /* 0x18 user   code 32-bit */
	.quad 0x00af9a000000ffff /* 0x20 kernel code 64-bit */
	.quad 0x00affa000000ffff /* 0x28 user   code 64-bit */
	.quad 0x00cf92000000ffff /* 0x30 kernel data        */
	.quad 0x00cff2000000ffff /* 0x38 user   data        */
	.quad 0x0040890000000068 /* 0x40 kernel TSS         */
	.quad 0x0000000000000000 /* 0x48  .. pad for 64-bit */
	.quad 0x0040e90000000068 /* 0x50 user   TSS         */
	.quad 0x0000000000000000 /* 0x58  .. pad for 64-bit */
END(_x86_gdt)
DATA(_x86_gdt_end)
END(_x86_gdt_end)

DATA(_x86_kern_tss)
	.skip 0x68
END(_x86_kern_tss)
DATA(_x86_user_tss)
	.skip 0x68
END(_x86_user_tss)