blob: 8a4baef67238cfbc0b551bd7cf6376c6014eb1f1 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors
//
// 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/defines.h>
#include <arch/x86/asm.h>
#include <arch/x86/descriptor.h>
#include <arch/x86/mmu.h>
#include <arch/x86/registers.h>
#include <asm.h>
#include <zircon/tls.h>
#include <mexec.h>
#define ENTRY64_ADDR 0x100020
.section .text
FUNCTION_LABEL(mexec_asm)
/* Stash all the arguments passed in registers R8 - R13 */
mov %r9, %r13 /* Unused Arg */
mov %r8, %r12 /* Memmove Ops */
mov %rcx, %r11 /* Unused Arg */
mov %rdx, %r10 /* Unused Arg */
mov %rsi, %r9 /* CR3 for Safe page tables */
mov %rdi, %r8 /* Bootimage Address */
/* Switch to the safe identity mapped page tables */
mov %r9, %cr3
/* Load the kernel relocation op into ram */
mov MEMMOV_OPS_DST_OFFSET (%r12), %rdi
mov MEMMOV_OPS_SRC_OFFSET (%r12), %rsi
mov MEMMOV_OPS_LEN_OFFSET (%r12), %rcx
call .Lmexec_memmove
/* Move the address of the bootdata into the appropriate register */
mov %r8, %rsi
/* Zero out some registers */
xor %ebx, %ebx
xor %edi, %edi
xor %ebp, %ebp
mov $ENTRY64_ADDR, %rbx
mov (%rbx), %rax
xor %rbx, %rbx
/* Clear interrupts */
cli
/* See you on the other side! */
jmp *%rax
/* Crash, we should never reach here */
ud2
.Lmexec_memmove:
/* Move RCX bytes from RSI to RDI */
cld /* Clear the direction flag so that we're copying forward */
/* by default when we start */
cmp %rsi, %rdi /* Compare the src and dst registers to see if we need to */
/* copy forwards or backwards */
jbe .Ldo_copy /* if dst is greater than src, go ahead and do the copy */
/* forwards */
mov %rcx, %rax /* rcx and rax contain the number of bytes to be copied */
sub $1, %rax /* Move rsi and rdi to the end of their respective buffers */
add %rax, %rdi
add %rax, %rsi
std /* Set the direction flag to 1. This will ensure that the */
/* copy happens from the back of the buffers to the front */
.Ldo_copy:
rep movsb /* copy RCX bytes from RSI to RDI */
cld /* Clear the direction flag since we may have polluted it */
/* if we did a copy backwards */
ret
DATA(mexec_asm_end)