/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "thread.h"

#include <sys/syscall.h>
#include <sys/types.h>

#include "asm_support_x86.h"
#include "base/enums.h"
#include "base/macros.h"
#include "thread-current-inl.h"
#include "thread_list.h"

#if defined(__APPLE__)
#include <architecture/i386/table.h>
#include <i386/user_ldt.h>
struct descriptor_table_entry_t {
  uint16_t limit0;
  uint16_t base0;
  unsigned base1: 8, type: 4, s: 1, dpl: 2, p: 1;
  unsigned limit: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8;
} __attribute__((packed));
#define MODIFY_LDT_CONTENTS_DATA 0
#else
#include <asm/ldt.h>
#endif

namespace art {

void Thread::InitCpu() {
  // Take the ldt lock, Thread::Current isn't yet established.
  MutexLock mu(nullptr, *Locks::modify_ldt_lock_);

  const uintptr_t base = reinterpret_cast<uintptr_t>(this);
  const size_t limit = sizeof(Thread);

  const int contents = MODIFY_LDT_CONTENTS_DATA;
  const int seg_32bit = 1;
  const int read_exec_only = 0;
  const int limit_in_pages = 1;
  const int seg_not_present = 0;
  const int useable = 1;

  int entry_number;
  uint16_t table_indicator;

#if defined(__APPLE__)
  descriptor_table_entry_t entry;
  memset(&entry, 0, sizeof(entry));
  entry.limit0 = (limit & 0x0ffff);
  entry.limit  = (limit & 0xf0000) >> 16;
  entry.base0 = (base & 0x0000ffff);
  entry.base1 = (base & 0x00ff0000) >> 16;
  entry.base2 = (base & 0xff000000) >> 24;
  entry.type = ((read_exec_only ^ 1) << 1) | (contents << 2);
  entry.s = 1;
  entry.dpl = 0x3;
  entry.p = seg_not_present ^ 1;
  entry.avl = useable;
  entry.l = 0;
  entry.d = seg_32bit;
  entry.g = limit_in_pages;

  entry_number = i386_set_ldt(LDT_AUTO_ALLOC, reinterpret_cast<ldt_entry*>(&entry), 1);
  if (entry_number == -1) {
    PLOG(FATAL) << "i386_set_ldt failed";
  }

  table_indicator = 1 << 2;  // LDT
#else
  // We use a GDT entry on Linux.
  user_desc gdt_entry;
  memset(&gdt_entry, 0, sizeof(gdt_entry));

  // On Linux, there are 3 TLS GDT entries. We use one of those to to store our segment descriptor
  // data.
  //
  // This entry must be shared, as the kernel only guarantees three TLS entries. For simplicity
  // (and locality), use this local global, which practically becomes readonly after the first
  // (startup) thread of the runtime has been initialized (during Runtime::Start()).
  //
  // We also share this between all runtimes in the process. This is both for simplicity (one
  // well-known slot) as well as to avoid the three-slot limitation. Downside is that we cannot
  // free the slot when it is known that a runtime stops.
  static unsigned int gdt_entry_number = -1;

  if (gdt_entry_number == static_cast<unsigned int>(-1)) {
    gdt_entry.entry_number = -1;  // Let the kernel choose.
  } else {
    gdt_entry.entry_number = gdt_entry_number;
  }
  gdt_entry.base_addr = base;
  gdt_entry.limit = limit;
  gdt_entry.seg_32bit = seg_32bit;
  gdt_entry.contents = contents;
  gdt_entry.read_exec_only = read_exec_only;
  gdt_entry.limit_in_pages = limit_in_pages;
  gdt_entry.seg_not_present = seg_not_present;
  gdt_entry.useable = useable;
  int rc = syscall(__NR_set_thread_area, &gdt_entry);
  if (rc != -1) {
    entry_number = gdt_entry.entry_number;
    if (gdt_entry_number == static_cast<unsigned int>(-1)) {
      gdt_entry_number = entry_number;  // Save the kernel-assigned entry number.
    }
  } else {
    PLOG(FATAL) << "set_thread_area failed";
    UNREACHABLE();
  }
  table_indicator = 0;  // GDT
#endif

  // Change %fs to be new DT entry.
  uint16_t rpl = 3;  // Requested privilege level
  uint16_t selector = (entry_number << 3) | table_indicator | rpl;
  __asm__ __volatile__("movw %w0, %%fs"
      :    // output
      : "q"(selector)  // input
      :);  // clobber

  // Allow easy indirection back to Thread*.
  tlsPtr_.self = this;

  // Check that the reads from %fs point to this Thread*.
  Thread* self_check;
  CHECK_EQ(THREAD_SELF_OFFSET, SelfOffset<PointerSize::k32>().Int32Value());
  __asm__ __volatile__("movl %%fs:(%1), %0"
      : "=r"(self_check)  // output
      : "r"(THREAD_SELF_OFFSET)  // input
      :);  // clobber
  CHECK_EQ(self_check, this);

  // Check the other offsets
  CHECK_EQ(THREAD_EXCEPTION_OFFSET, ExceptionOffset<PointerSize::k32>().Int32Value());
  CHECK_EQ(THREAD_CARD_TABLE_OFFSET, CardTableOffset<PointerSize::k32>().Int32Value());
  CHECK_EQ(THREAD_ID_OFFSET, ThinLockIdOffset<PointerSize::k32>().Int32Value());
}

void Thread::CleanupCpu() {
  MutexLock mu(this, *Locks::modify_ldt_lock_);

  // Check that the reads from %fs point to this Thread*.
  Thread* self_check;
  __asm__ __volatile__("movl %%fs:(%1), %0"
      : "=r"(self_check)  // output
      : "r"(THREAD_SELF_OFFSET)  // input
      :);  // clobber
  CHECK_EQ(self_check, this);

  // Extract the LDT entry number from the FS register.
  uint16_t selector;
  __asm__ __volatile__("movw %%fs, %w0"
      : "=q"(selector)  // output
      :  // input
      :);  // clobber

  // Free LDT entry.
#if defined(__APPLE__)
  // TODO: release selectors on OS/X this is a leak which will cause ldt entries to be exhausted
  // after enough threads are created. However, the following code results in kernel panics in OS/X
  // 10.9.
  UNUSED(selector);
  // i386_set_ldt(selector >> 3, 0, 1);
#else
  // Note if we wanted to clean up the GDT entry, we would do that here, when the *last* thread
  // is being deleted. But see the comment on gdt_entry_number. Code would look like this:
  //
  // user_desc gdt_entry;
  // memset(&gdt_entry, 0, sizeof(gdt_entry));
  // gdt_entry.entry_number = selector >> 3;
  // gdt_entry.contents = MODIFY_LDT_CONTENTS_DATA;
  // // "Empty" = Delete = seg_not_present==1 && read_exec_only==1.
  // gdt_entry.seg_not_present = 1;
  // gdt_entry.read_exec_only = 1;
  // syscall(__NR_set_thread_area, &gdt_entry);
  UNUSED(selector);
#endif
}

}  // namespace art
