blob: f2b3ea7f5dbdf51bad0dd26626cf3b3f3fc55cce [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2009 Corey Tabaka
//
// 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 <asm.h>
#include <arch/x86/mp.h>
#include <err.h>
.text
/* This follows the x86-64 ABI, the parameters are stored in registers in the following order*/
/*
%rdi used to pass 1st argument
%rsi used to pass 2nd argument
%rdx used to pass 3rd argument and 2nd return register
%rcx used to pass 4th argument
%r8 used to pass 5th argument
%r9 used to pass 6th argument
%rax 1st return register
*/
/* void arch_idle(); */
FUNCTION(arch_idle)
pushf
popq %rax
andq $0x200, %rax
test %rax, %rax
je 1f /* don't halt if local interrupts are disabled */
hlt
1:
ret
END_FUNCTION(arch_idle)
/* status_t read_msr_safe(uint32_t msr_id, uint64_t *val); */
FUNCTION(read_msr_safe)
# Set up MSR index
mov %rdi, %rcx
# Disable interrupts before touching percpu state
pushfq
cli
# Set up the GPF handler, in case the MSR doesn't exist
movq $.Lgpf_handler, %gs:PERCPU_GPF_RETURN_OFFSET
rdmsr
# Cleanup the GPF handler
movq $0, %gs:PERCPU_GPF_RETURN_OFFSET
# Restore interrupts if they were on before
popfq
# rdmsr returns value via edx:eax
shl $32, %rdx
or %rax, %rdx
mov %rdx, (%rsi)
mov $ZX_OK, %rax
ret
.Lgpf_handler:
# Cleanup GPF handler
movq $0, %gs:PERCPU_GPF_RETURN_OFFSET
# Restore interrupts if they were on before
popfq
mov $ZX_ERR_NOT_SUPPORTED, %rax
ret
END_FUNCTION(read_msr_safe)