// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2009 Corey Tabaka
// Copyright (c) 2016 Travis Geiselbrecht
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include "arch/x86/descriptor.h"

#include <assert.h>
#include <bits.h>
#include <string.h>
#include <trace.h>
#include <zircon/compiler.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <arch/arch_ops.h>
#include <arch/x86.h>
#include <arch/x86/idt.h>
#include <arch/x86/interrupts.h>
#include <arch/x86/mp.h>
#include <kernel/mp.h>
#include <ktl/move.h>
#include <vm/fault.h>
#include <vm/pmm.h>
#include <vm/vm_address_region.h>
#include <vm/vm_aspace.h>
#include <vm/vm_object_paged.h>
#include <vm/vm_object_physical.h>

#define TSS_DESC_BUSY_BIT (1ull << 41)

/* Temporary GDT defined in assembly is used during AP/BP setup process */
extern uint8_t _temp_gdt[];
extern uint8_t _temp_gdt_end[];

/* We create a new GDT after initialization is done and switch everyone to it */
static uintptr_t gdt = (uintptr_t)_temp_gdt;

static void x86_tss_assign_ists(struct x86_percpu* percpu, tss_t* tss);

struct task_desc {
  uint64_t low;
  uint64_t high;
} __PACKED;

void x86_initialize_percpu_tss(void) {
  struct x86_percpu* percpu = x86_get_percpu();
  uint cpu_num = percpu->cpu_num;
  tss_t* tss = &percpu->default_tss;
  memset(tss, 0, sizeof(*tss));

  /* zeroed out TSS is okay for now */
  set_global_desc_64(TSS_SELECTOR(cpu_num), (uintptr_t)tss, sizeof(*tss) - 1, 1, 0, 0, SEG_TYPE_TSS,
                     0, 0);

  x86_tss_assign_ists(percpu, tss);

  tss->iomap_base = offsetof(tss_64_t, tss_bitmap);
  // Need to have an extra byte at the end of the bitmap because it will always potentially read two
  // bytes
  tss->tss_bitmap[IO_BITMAP_BYTES] = 0xff;

  x86_ltr(TSS_SELECTOR(cpu_num));
}

static void x86_tss_assign_ists(struct x86_percpu* percpu, tss_t* tss) {
  tss->ist1 = (uintptr_t)&percpu->interrupt_stacks[0] + PAGE_SIZE;
  tss->ist2 = (uintptr_t)&percpu->interrupt_stacks[1] + PAGE_SIZE;
  tss->ist3 = (uintptr_t)&percpu->interrupt_stacks[2] + PAGE_SIZE;
}

void x86_set_tss_sp(vaddr_t sp) {
  tss_t* tss = &x86_get_percpu()->default_tss;
  tss->rsp0 = sp;
}

void x86_clear_tss_busy(seg_sel_t sel) {
  uint index = sel >> 3;
  struct task_desc* desc = (struct task_desc*)(gdt + index * 8);
  desc->low &= ~TSS_DESC_BUSY_BIT;
}

void set_global_desc_64(seg_sel_t sel, uint64_t base, uint32_t limit, uint8_t present, uint8_t ring,
                        uint8_t sys, uint8_t type, uint8_t gran, uint8_t bits) {
  // 64 bit descriptor structure
  struct seg_desc_64 {
    uint16_t limit_15_0;
    uint16_t base_15_0;
    uint8_t base_23_16;

    uint8_t type : 4;
    uint8_t s : 1;
    uint8_t dpl : 2;
    uint8_t p : 1;

    uint8_t limit_19_16 : 4;
    uint8_t avl : 1;
    uint8_t reserved_0 : 1;
    uint8_t d_b : 1;
    uint8_t g : 1;

    uint8_t base_31_24;

    uint32_t base_63_32;
    uint32_t reserved_sbz;
  } __PACKED;

  struct seg_desc_64 entry = {};

  entry.limit_15_0 = limit & 0x0000ffff;
  entry.limit_19_16 = (limit & 0x000f0000) >> 16;

  entry.base_15_0 = base & 0x0000ffff;
  entry.base_23_16 = (base & 0x00ff0000) >> 16;
  entry.base_31_24 = (base & 0xff000000) >> 24;
  entry.base_63_32 = (uint32_t)(base >> 32);

  entry.type = type & 0x0f;  // segment type
  entry.p = present != 0;    // present
  entry.dpl = ring & 0x03;   // descriptor privilege level
  entry.g = gran != 0;       // granularity
  entry.s = sys != 0;        // system / non-system
  entry.d_b = bits != 0;     // 16 / 32 bit

  // copy it into the appropriate entry
  uint index = sel >> 3;

  // for x86_64 index is still in units of 8 bytes into the gdt table
  struct seg_desc_64* g = (struct seg_desc_64*)(gdt + index * 8);
  *g = entry;
}

void gdt_setup() {
  DEBUG_ASSERT(arch_curr_cpu_num() == 0);
  DEBUG_ASSERT(mp_get_online_mask() == 1);
  // Max GDT size is limited to 64K and we reserve the whole 64K area, but we map
  // just enough pages to store GDT and leave the rest unmapped so all accesses
  // beyond GDT last page are going to cause page fault.
  // Why don't we just set a a proper limit value? That's because during VM exit
  // on x86 architecture GDT limit is always set to 0xFFFF (see Intel SDM, Volume
  // 3, 27.5.2 Loading Host Segment and Descriptor-Table Registers) and therefore
  // requiring the hypervisor to restore GDT limit after VM exit using LGDT
  // instruction which is a serializing instruction (see Intel SDM, Volume 3, 8.3
  // Serializing Instructions).
  uint32_t vmar_flags =
      VMAR_FLAG_CAN_MAP_SPECIFIC | VMAR_FLAG_CAN_MAP_READ | VMAR_FLAG_CAN_MAP_WRITE;
  uint32_t mmu_flags = ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE;

  size_t gdt_real_size = _temp_gdt_end - _temp_gdt;
  size_t gdt_size = 0x10000;

  fbl::RefPtr<VmObjectPaged> vmo;
  zx_status_t status =
      VmObjectPaged::Create(PMM_ALLOC_FLAG_ANY, /*options*/ 0u, gdt_real_size, &vmo);
  ASSERT(status == ZX_OK);

  fbl::RefPtr<VmAddressRegion> vmar;
  status = VmAspace::kernel_aspace()->RootVmar()->CreateSubVmar(0, gdt_size, PAGE_SIZE_SHIFT,
                                                                vmar_flags, "gdt_vmar", &vmar);
  ASSERT(status == ZX_OK);

  fbl::RefPtr<VmMapping> mapping;
  status = vmar->CreateVmMapping(
      /*mapping_offset*/ 0u, gdt_real_size, PAGE_SIZE_SHIFT, VMAR_FLAG_SPECIFIC, ktl::move(vmo),
      /*vmo_offset*/ 0u, mmu_flags, "gdt", &mapping);
  ASSERT(status == ZX_OK);

  status = mapping->MapRange(0, gdt_real_size, /*commit*/ true);
  ASSERT(status == ZX_OK);

  memcpy((void*)mapping->base(), _temp_gdt, gdt_real_size);
  gdt = mapping->base();
  gdt_load(gdt_get());
}

uintptr_t gdt_get(void) { return gdt; }
