mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
71 lines
2.6 KiB
71 lines
2.6 KiB
/* SPDX-License-Identifier: GPL-2.0 */ |
|
/* |
|
* Low-level task switching. This is based on information published in |
|
* the Processor Abstraction Layer and the System Abstraction Layer |
|
* manual. |
|
* |
|
* Copyright (C) 1998-2003 Hewlett-Packard Co |
|
* David Mosberger-Tang <[email protected]> |
|
* Copyright (C) 1999 Asit Mallick <[email protected]> |
|
* Copyright (C) 1999 Don Dugger <[email protected]> |
|
*/ |
|
#ifndef _ASM_IA64_SWITCH_TO_H |
|
#define _ASM_IA64_SWITCH_TO_H |
|
|
|
#include <linux/percpu.h> |
|
|
|
struct task_struct; |
|
|
|
/* |
|
* Context switch from one thread to another. If the two threads have |
|
* different address spaces, schedule() has already taken care of |
|
* switching to the new address space by calling switch_mm(). |
|
* |
|
* Disabling access to the fph partition and the debug-register |
|
* context switch MUST be done before calling ia64_switch_to() since a |
|
* newly created thread returns directly to |
|
* ia64_ret_from_syscall_clear_r8. |
|
*/ |
|
extern struct task_struct *ia64_switch_to (void *next_task); |
|
|
|
extern void ia64_save_extra (struct task_struct *task); |
|
extern void ia64_load_extra (struct task_struct *task); |
|
|
|
#define IA64_HAS_EXTRA_STATE(t) \ |
|
((t)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID)) |
|
|
|
#define __switch_to(prev,next,last) do { \ |
|
if (IA64_HAS_EXTRA_STATE(prev)) \ |
|
ia64_save_extra(prev); \ |
|
if (IA64_HAS_EXTRA_STATE(next)) \ |
|
ia64_load_extra(next); \ |
|
ia64_psr(task_pt_regs(next))->dfh = !ia64_is_local_fpu_owner(next); \ |
|
(last) = ia64_switch_to((next)); \ |
|
} while (0) |
|
|
|
#ifdef CONFIG_SMP |
|
/* |
|
* In the SMP case, we save the fph state when context-switching away from a thread that |
|
* modified fph. This way, when the thread gets scheduled on another CPU, the CPU can |
|
* pick up the state from task->thread.fph, avoiding the complication of having to fetch |
|
* the latest fph state from another CPU. In other words: eager save, lazy restore. |
|
*/ |
|
# define switch_to(prev,next,last) do { \ |
|
if (ia64_psr(task_pt_regs(prev))->mfh && ia64_is_local_fpu_owner(prev)) { \ |
|
ia64_psr(task_pt_regs(prev))->mfh = 0; \ |
|
(prev)->thread.flags |= IA64_THREAD_FPH_VALID; \ |
|
__ia64_save_fpu((prev)->thread.fph); \ |
|
} \ |
|
__switch_to(prev, next, last); \ |
|
/* "next" in old context is "current" in new context */ \ |
|
if (unlikely((current->thread.flags & IA64_THREAD_MIGRATION) && \ |
|
(task_cpu(current) != \ |
|
task_thread_info(current)->last_cpu))) { \ |
|
task_thread_info(current)->last_cpu = task_cpu(current); \ |
|
} \ |
|
} while (0) |
|
#else |
|
# define switch_to(prev,next,last) __switch_to(prev, next, last) |
|
#endif |
|
|
|
#endif /* _ASM_IA64_SWITCH_TO_H */
|
|
|