1/* 2 * Architecture-specific context switch 3 */ 4 5/* 6 * Copyright (c) 2015, ETH Zurich. 7 * All rights reserved. 8 * 9 * This file is distributed under the terms in the attached LICENSE file. 10 * If you do not find this file, copies can be found by writing to: 11 * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group. 12 */ 13 14#include <kernel.h> 15#include <dispatch.h> 16#include <paging_kernel_arch.h> 17#include <sysreg.h> 18 19/** 20 * \brief Switch context to 'dcb'. 21 * 22 * Switch to the dispatcher pointed to by 'dcb'. Sets 'dcb_current'. 23 * 24 * \param dcb Pointer to dispatcher to which to switch context. 25 */ 26void 27context_switch(struct dcb *dcb) { 28 struct dispatcher_shared_generic *disp = 29 get_dispatcher_shared_generic(dcb->disp); 30 31 assert(dcb != NULL); 32 assert(dcb->vspace != 0); 33 34 // VM guests do not have a user space dispatcher 35 if (!dcb->is_vm_guest) { 36 assert(dcb->disp != 0); 37 } 38 39 paging_context_switch(dcb->vspace); 40 context_switch_counter++; 41 42 if (!dcb->is_vm_guest) { 43 assert(dcb->disp_cte.cap.type == ObjType_Frame); 44 45 /* We set the read-only thread ID register (TPIDRRO_EL0) to the user's 46 * pointer to the dispatcher shared area, so that code in 47 * libbarrelfish can efficiently locate its dispatcher. The read-write 48 * version (TPIDR_EL0) is free to implement TLS. */ 49 sysreg_write_tpidrro_el0((uint64_t)disp->udisp); 50 51 } 52 53 /* The EL1 thread ID register points to the same structure in the 54 * kernel window, and is used by trap code. This is inaccessible to 55 * user-level code. */ 56 sysreg_write_tpidr_el1((uint64_t)disp); 57} 58