1e2a74729SWarner Losh /* 2e2a74729SWarner Losh * x86_64 cpu related code 3e2a74729SWarner Losh * 4031fe7afSWarner Losh * Copyright (c) 2013 Stacey Son <sson@FreeBSD.org> 5e2a74729SWarner Losh * 6e2a74729SWarner Losh * This program is free software; you can redistribute it and/or modify 7e2a74729SWarner Losh * it under the terms of the GNU General Public License as published by 8e2a74729SWarner Losh * the Free Software Foundation; either version 2 of the License, or 9e2a74729SWarner Losh * (at your option) any later version. 10e2a74729SWarner Losh * 11e2a74729SWarner Losh * This program is distributed in the hope that it will be useful, 12e2a74729SWarner Losh * but WITHOUT ANY WARRANTY; without even the implied warranty of 13e2a74729SWarner Losh * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14e2a74729SWarner Losh * GNU General Public License for more details. 15e2a74729SWarner Losh * 16e2a74729SWarner Losh * You should have received a copy of the GNU General Public License 17e2a74729SWarner Losh * along with this program; if not, see <http://www.gnu.org/licenses/>. 18e2a74729SWarner Losh */ 19e2a74729SWarner Losh 20e2a74729SWarner Losh #include "qemu/osdep.h" 21*48e438a3SMarkus Armbruster 22e2a74729SWarner Losh #include "cpu.h" 23e2a74729SWarner Losh #include "qemu.h" 24e2a74729SWarner Losh #include "qemu/timer.h" 25e2a74729SWarner Losh 26e2a74729SWarner Losh #include "target_arch.h" 27e2a74729SWarner Losh 28e2a74729SWarner Losh static uint64_t *idt_table; 29e2a74729SWarner Losh 30e2a74729SWarner Losh uint64_t cpu_get_tsc(CPUX86State *env) 31e2a74729SWarner Losh { 32e2a74729SWarner Losh return cpu_get_host_ticks(); 33e2a74729SWarner Losh } 34e2a74729SWarner Losh 35e2a74729SWarner Losh void bsd_x86_64_write_dt(void *ptr, unsigned long addr, 36e2a74729SWarner Losh unsigned long limit, int flags) 37e2a74729SWarner Losh { 38e2a74729SWarner Losh unsigned int e1, e2; 39e2a74729SWarner Losh uint32_t *p; 40e2a74729SWarner Losh e1 = (addr << 16) | (limit & 0xffff); 41e2a74729SWarner Losh e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000); 42e2a74729SWarner Losh e2 |= flags; 43e2a74729SWarner Losh p = ptr; 44e2a74729SWarner Losh p[0] = tswap32(e1); 45e2a74729SWarner Losh p[1] = tswap32(e2); 46e2a74729SWarner Losh } 47e2a74729SWarner Losh 48e2a74729SWarner Losh static void set_gate64(void *ptr, unsigned int type, unsigned int dpl, 49e2a74729SWarner Losh uint64_t addr, unsigned int sel) 50e2a74729SWarner Losh { 51e2a74729SWarner Losh uint32_t *p, e1, e2; 52e2a74729SWarner Losh e1 = (addr & 0xffff) | (sel << 16); 53e2a74729SWarner Losh e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8); 54e2a74729SWarner Losh p = ptr; 55e2a74729SWarner Losh p[0] = tswap32(e1); 56e2a74729SWarner Losh p[1] = tswap32(e2); 57e2a74729SWarner Losh p[2] = tswap32(addr >> 32); 58e2a74729SWarner Losh p[3] = 0; 59e2a74729SWarner Losh } 60e2a74729SWarner Losh 61e2a74729SWarner Losh /* only dpl matters as we do only user space emulation */ 62e2a74729SWarner Losh void bsd_x86_64_set_idt(int n, unsigned int dpl) 63e2a74729SWarner Losh { 64e2a74729SWarner Losh set_gate64(idt_table + n * 2, 0, dpl, 0, 0); 65e2a74729SWarner Losh } 66e2a74729SWarner Losh 67e2a74729SWarner Losh void bsd_x86_64_set_idt_base(uint64_t base) 68e2a74729SWarner Losh { 69e2a74729SWarner Losh idt_table = g2h_untagged(base); 70e2a74729SWarner Losh } 71