162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/* include/asm/processor.h
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#ifndef __ASM_SPARC_PROCESSOR_H
862306a36Sopenharmony_ci#define __ASM_SPARC_PROCESSOR_H
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <asm/psr.h>
1162306a36Sopenharmony_ci#include <asm/ptrace.h>
1262306a36Sopenharmony_ci#include <asm/head.h>
1362306a36Sopenharmony_ci#include <asm/signal.h>
1462306a36Sopenharmony_ci#include <asm/page.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci/* Whee, this is STACK_TOP + PAGE_SIZE and the lowest kernel address too...
1762306a36Sopenharmony_ci * That one page is used to protect kernel from intruders, so that
1862306a36Sopenharmony_ci * we can make our access_ok test faster
1962306a36Sopenharmony_ci */
2062306a36Sopenharmony_ci#define TASK_SIZE	PAGE_OFFSET
2162306a36Sopenharmony_ci#ifdef __KERNEL__
2262306a36Sopenharmony_ci#define STACK_TOP	(PAGE_OFFSET - PAGE_SIZE)
2362306a36Sopenharmony_ci#define STACK_TOP_MAX	STACK_TOP
2462306a36Sopenharmony_ci#endif /* __KERNEL__ */
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_cistruct task_struct;
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#ifdef __KERNEL__
2962306a36Sopenharmony_cistruct fpq {
3062306a36Sopenharmony_ci	unsigned long *insn_addr;
3162306a36Sopenharmony_ci	unsigned long insn;
3262306a36Sopenharmony_ci};
3362306a36Sopenharmony_ci#endif
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci/* The Sparc processor specific thread struct. */
3662306a36Sopenharmony_cistruct thread_struct {
3762306a36Sopenharmony_ci	struct pt_regs *kregs;
3862306a36Sopenharmony_ci	unsigned int _pad1;
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	/* Special child fork kpsr/kwim values. */
4162306a36Sopenharmony_ci	unsigned long fork_kpsr __attribute__ ((aligned (8)));
4262306a36Sopenharmony_ci	unsigned long fork_kwim;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	/* Floating point regs */
4562306a36Sopenharmony_ci	unsigned long   float_regs[32] __attribute__ ((aligned (8)));
4662306a36Sopenharmony_ci	unsigned long   fsr;
4762306a36Sopenharmony_ci	unsigned long   fpqdepth;
4862306a36Sopenharmony_ci	struct fpq	fpqueue[16];
4962306a36Sopenharmony_ci};
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci#define INIT_THREAD  { \
5262306a36Sopenharmony_ci	.kregs = (struct pt_regs *)(init_stack+THREAD_SIZE)-1 \
5362306a36Sopenharmony_ci}
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci/* Do necessary setup to start up a newly executed thread. */
5662306a36Sopenharmony_cistatic inline void start_thread(struct pt_regs * regs, unsigned long pc,
5762306a36Sopenharmony_ci				    unsigned long sp)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	register unsigned long zero asm("g1");
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	regs->psr = (regs->psr & (PSR_CWP)) | PSR_S;
6262306a36Sopenharmony_ci	regs->pc = ((pc & (~3)) - 4);
6362306a36Sopenharmony_ci	regs->npc = regs->pc + 4;
6462306a36Sopenharmony_ci	regs->y = 0;
6562306a36Sopenharmony_ci	zero = 0;
6662306a36Sopenharmony_ci	__asm__ __volatile__("std\t%%g0, [%0 + %3 + 0x00]\n\t"
6762306a36Sopenharmony_ci			     "std\t%%g0, [%0 + %3 + 0x08]\n\t"
6862306a36Sopenharmony_ci			     "std\t%%g0, [%0 + %3 + 0x10]\n\t"
6962306a36Sopenharmony_ci			     "std\t%%g0, [%0 + %3 + 0x18]\n\t"
7062306a36Sopenharmony_ci			     "std\t%%g0, [%0 + %3 + 0x20]\n\t"
7162306a36Sopenharmony_ci			     "std\t%%g0, [%0 + %3 + 0x28]\n\t"
7262306a36Sopenharmony_ci			     "std\t%%g0, [%0 + %3 + 0x30]\n\t"
7362306a36Sopenharmony_ci			     "st\t%1, [%0 + %3 + 0x38]\n\t"
7462306a36Sopenharmony_ci			     "st\t%%g0, [%0 + %3 + 0x3c]"
7562306a36Sopenharmony_ci			     : /* no outputs */
7662306a36Sopenharmony_ci			     : "r" (regs),
7762306a36Sopenharmony_ci			       "r" (sp - sizeof(struct reg_window32)),
7862306a36Sopenharmony_ci			       "r" (zero),
7962306a36Sopenharmony_ci			       "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))
8062306a36Sopenharmony_ci			     : "memory");
8162306a36Sopenharmony_ci}
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ciunsigned long __get_wchan(struct task_struct *);
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci#define task_pt_regs(tsk) ((tsk)->thread.kregs)
8662306a36Sopenharmony_ci#define KSTK_EIP(tsk)  ((tsk)->thread.kregs->pc)
8762306a36Sopenharmony_ci#define KSTK_ESP(tsk)  ((tsk)->thread.kregs->u_regs[UREG_FP])
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci#ifdef __KERNEL__
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ciextern struct task_struct *last_task_used_math;
9262306a36Sopenharmony_ciint do_mathemu(struct pt_regs *regs, struct task_struct *fpt);
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci#define cpu_relax()	barrier()
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ciextern void (*sparc_idle)(void);
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci#endif
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci#endif /* __ASM_SPARC_PROCESSOR_H */
101