18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * r2300_switch.S: R2300 specific task switching code. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle 68c2ecf20Sopenharmony_ci * Copyright (C) 1994, 1995, 1996 by Andreas Busse 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Multi-cpu abstraction and macros for easier reading: 98c2ecf20Sopenharmony_ci * Copyright (C) 1996 David S. Miller (davem@davemloft.net) 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * Further modifications to make this work: 128c2ecf20Sopenharmony_ci * Copyright (c) 1998-2000 Harald Koerfgen 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci#include <asm/asm.h> 158c2ecf20Sopenharmony_ci#include <asm/cachectl.h> 168c2ecf20Sopenharmony_ci#include <asm/export.h> 178c2ecf20Sopenharmony_ci#include <asm/fpregdef.h> 188c2ecf20Sopenharmony_ci#include <asm/mipsregs.h> 198c2ecf20Sopenharmony_ci#include <asm/asm-offsets.h> 208c2ecf20Sopenharmony_ci#include <asm/regdef.h> 218c2ecf20Sopenharmony_ci#include <asm/stackframe.h> 228c2ecf20Sopenharmony_ci#include <asm/thread_info.h> 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#include <asm/asmmacro.h> 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci .set mips1 278c2ecf20Sopenharmony_ci .align 5 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci/* 308c2ecf20Sopenharmony_ci * task_struct *resume(task_struct *prev, task_struct *next, 318c2ecf20Sopenharmony_ci * struct thread_info *next_ti) 328c2ecf20Sopenharmony_ci */ 338c2ecf20Sopenharmony_ciLEAF(resume) 348c2ecf20Sopenharmony_ci mfc0 t1, CP0_STATUS 358c2ecf20Sopenharmony_ci sw t1, THREAD_STATUS(a0) 368c2ecf20Sopenharmony_ci cpu_save_nonscratch a0 378c2ecf20Sopenharmony_ci sw ra, THREAD_REG31(a0) 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP) 408c2ecf20Sopenharmony_ci PTR_LA t8, __stack_chk_guard 418c2ecf20Sopenharmony_ci LONG_L t9, TASK_STACK_CANARY(a1) 428c2ecf20Sopenharmony_ci LONG_S t9, 0(t8) 438c2ecf20Sopenharmony_ci#endif 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci /* 468c2ecf20Sopenharmony_ci * The order of restoring the registers takes care of the race 478c2ecf20Sopenharmony_ci * updating $28, $29 and kernelsp without disabling ints. 488c2ecf20Sopenharmony_ci */ 498c2ecf20Sopenharmony_ci move $28, a2 508c2ecf20Sopenharmony_ci cpu_restore_nonscratch a1 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci addiu t1, $28, _THREAD_SIZE - 32 538c2ecf20Sopenharmony_ci sw t1, kernelsp 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci mfc0 t1, CP0_STATUS /* Do we really need this? */ 568c2ecf20Sopenharmony_ci li a3, 0xff01 578c2ecf20Sopenharmony_ci and t1, a3 588c2ecf20Sopenharmony_ci lw a2, THREAD_STATUS(a1) 598c2ecf20Sopenharmony_ci nor a3, $0, a3 608c2ecf20Sopenharmony_ci and a2, a3 618c2ecf20Sopenharmony_ci or a2, t1 628c2ecf20Sopenharmony_ci mtc0 a2, CP0_STATUS 638c2ecf20Sopenharmony_ci move v0, a0 648c2ecf20Sopenharmony_ci jr ra 658c2ecf20Sopenharmony_ci END(resume) 66