1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * Ptrace interface test helper functions
4 *
5 * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
6 */
7
8#define __SANE_USERSPACE_TYPES__
9
10#include <inttypes.h>
11#include <unistd.h>
12#include <stdlib.h>
13#include <string.h>
14#include <malloc.h>
15#include <errno.h>
16#include <time.h>
17#include <sys/ptrace.h>
18#include <sys/ioctl.h>
19#include <sys/uio.h>
20#include <sys/types.h>
21#include <sys/wait.h>
22#include <sys/signal.h>
23#include <sys/ipc.h>
24#include <sys/shm.h>
25#include <sys/user.h>
26#include <sys/syscall.h>
27#include <linux/elf.h>
28#include <linux/types.h>
29#include <linux/auxvec.h>
30#include "reg.h"
31#include "utils.h"
32
33#define TEST_PASS 0
34#define TEST_FAIL 1
35
36struct fpr_regs {
37	__u64 fpr[32];
38	__u64 fpscr;
39};
40
41struct tm_spr_regs {
42	unsigned long tm_tfhar;
43	unsigned long tm_texasr;
44	unsigned long tm_tfiar;
45};
46
47#ifndef NT_PPC_TAR
48#define NT_PPC_TAR	0x103
49#define NT_PPC_PPR	0x104
50#define NT_PPC_DSCR	0x105
51#define NT_PPC_EBB	0x106
52#define NT_PPC_PMU	0x107
53#define NT_PPC_TM_CGPR	0x108
54#define NT_PPC_TM_CFPR	0x109
55#define NT_PPC_TM_CVMX	0x10a
56#define NT_PPC_TM_CVSX	0x10b
57#define NT_PPC_TM_SPR	0x10c
58#define NT_PPC_TM_CTAR	0x10d
59#define NT_PPC_TM_CPPR	0x10e
60#define NT_PPC_TM_CDSCR	0x10f
61#endif
62
63/* Basic ptrace operations */
64int start_trace(pid_t child)
65{
66	int ret;
67
68	ret = ptrace(PTRACE_ATTACH, child, NULL, NULL);
69	if (ret) {
70		perror("ptrace(PTRACE_ATTACH) failed");
71		return TEST_FAIL;
72	}
73	ret = waitpid(child, NULL, 0);
74	if (ret != child) {
75		perror("waitpid() failed");
76		return TEST_FAIL;
77	}
78	return TEST_PASS;
79}
80
81int stop_trace(pid_t child)
82{
83	int ret;
84
85	ret = ptrace(PTRACE_DETACH, child, NULL, NULL);
86	if (ret) {
87		perror("ptrace(PTRACE_DETACH) failed");
88		return TEST_FAIL;
89	}
90	return TEST_PASS;
91}
92
93int cont_trace(pid_t child)
94{
95	int ret;
96
97	ret = ptrace(PTRACE_CONT, child, NULL, NULL);
98	if (ret) {
99		perror("ptrace(PTRACE_CONT) failed");
100		return TEST_FAIL;
101	}
102	return TEST_PASS;
103}
104
105int ptrace_read_regs(pid_t child, unsigned long type, unsigned long regs[],
106		     int n)
107{
108	struct iovec iov;
109	long ret;
110
111	FAIL_IF(start_trace(child));
112
113	iov.iov_base = regs;
114	iov.iov_len = n * sizeof(unsigned long);
115
116	ret = ptrace(PTRACE_GETREGSET, child, type, &iov);
117	if (ret)
118		return ret;
119
120	FAIL_IF(stop_trace(child));
121
122	return TEST_PASS;
123}
124
125long ptrace_write_regs(pid_t child, unsigned long type, unsigned long regs[],
126		       int n)
127{
128	struct iovec iov;
129	long ret;
130
131	FAIL_IF(start_trace(child));
132
133	iov.iov_base = regs;
134	iov.iov_len = n * sizeof(unsigned long);
135
136	ret = ptrace(PTRACE_SETREGSET, child, type, &iov);
137
138	FAIL_IF(stop_trace(child));
139
140	return ret;
141}
142
143/* TAR, PPR, DSCR */
144int show_tar_registers(pid_t child, unsigned long *out)
145{
146	struct iovec iov;
147	unsigned long *reg;
148	int ret;
149
150	reg = malloc(sizeof(unsigned long));
151	if (!reg) {
152		perror("malloc() failed");
153		return TEST_FAIL;
154	}
155	iov.iov_base = (u64 *) reg;
156	iov.iov_len = sizeof(unsigned long);
157
158	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TAR, &iov);
159	if (ret) {
160		perror("ptrace(PTRACE_GETREGSET) failed");
161		goto fail;
162	}
163	if (out)
164		out[0] = *reg;
165
166	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_PPR, &iov);
167	if (ret) {
168		perror("ptrace(PTRACE_GETREGSET) failed");
169		goto fail;
170	}
171	if (out)
172		out[1] = *reg;
173
174	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_DSCR, &iov);
175	if (ret) {
176		perror("ptrace(PTRACE_GETREGSET) failed");
177		goto fail;
178	}
179	if (out)
180		out[2] = *reg;
181
182	free(reg);
183	return TEST_PASS;
184fail:
185	free(reg);
186	return TEST_FAIL;
187}
188
189int write_tar_registers(pid_t child, unsigned long tar,
190		unsigned long ppr, unsigned long dscr)
191{
192	struct iovec iov;
193	unsigned long *reg;
194	int ret;
195
196	reg = malloc(sizeof(unsigned long));
197	if (!reg) {
198		perror("malloc() failed");
199		return TEST_FAIL;
200	}
201
202	iov.iov_base = (u64 *) reg;
203	iov.iov_len = sizeof(unsigned long);
204
205	*reg = tar;
206	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TAR, &iov);
207	if (ret) {
208		perror("ptrace(PTRACE_SETREGSET) failed");
209		goto fail;
210	}
211
212	*reg = ppr;
213	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_PPR, &iov);
214	if (ret) {
215		perror("ptrace(PTRACE_SETREGSET) failed");
216		goto fail;
217	}
218
219	*reg = dscr;
220	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_DSCR, &iov);
221	if (ret) {
222		perror("ptrace(PTRACE_SETREGSET) failed");
223		goto fail;
224	}
225
226	free(reg);
227	return TEST_PASS;
228fail:
229	free(reg);
230	return TEST_FAIL;
231}
232
233int show_tm_checkpointed_state(pid_t child, unsigned long *out)
234{
235	struct iovec iov;
236	unsigned long *reg;
237	int ret;
238
239	reg = malloc(sizeof(unsigned long));
240	if (!reg) {
241		perror("malloc() failed");
242		return TEST_FAIL;
243	}
244
245	iov.iov_base = (u64 *) reg;
246	iov.iov_len = sizeof(unsigned long);
247
248	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CTAR, &iov);
249	if (ret) {
250		perror("ptrace(PTRACE_GETREGSET) failed");
251		goto fail;
252	}
253	if (out)
254		out[0] = *reg;
255
256	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CPPR, &iov);
257	if (ret) {
258		perror("ptrace(PTRACE_GETREGSET) failed");
259		goto fail;
260	}
261	if (out)
262		out[1] = *reg;
263
264	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CDSCR, &iov);
265	if (ret) {
266		perror("ptrace(PTRACE_GETREGSET) failed");
267		goto fail;
268	}
269	if (out)
270		out[2] = *reg;
271
272	free(reg);
273	return TEST_PASS;
274
275fail:
276	free(reg);
277	return TEST_FAIL;
278}
279
280int write_ckpt_tar_registers(pid_t child, unsigned long tar,
281		unsigned long ppr, unsigned long dscr)
282{
283	struct iovec iov;
284	unsigned long *reg;
285	int ret;
286
287	reg = malloc(sizeof(unsigned long));
288	if (!reg) {
289		perror("malloc() failed");
290		return TEST_FAIL;
291	}
292
293	iov.iov_base = (u64 *) reg;
294	iov.iov_len = sizeof(unsigned long);
295
296	*reg = tar;
297	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CTAR, &iov);
298	if (ret) {
299		perror("ptrace(PTRACE_GETREGSET) failed");
300		goto fail;
301	}
302
303	*reg = ppr;
304	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CPPR, &iov);
305	if (ret) {
306		perror("ptrace(PTRACE_GETREGSET) failed");
307		goto fail;
308	}
309
310	*reg = dscr;
311	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CDSCR, &iov);
312	if (ret) {
313		perror("ptrace(PTRACE_GETREGSET) failed");
314		goto fail;
315	}
316
317	free(reg);
318	return TEST_PASS;
319fail:
320	free(reg);
321	return TEST_FAIL;
322}
323
324/* FPR */
325int show_fpr(pid_t child, __u64 *fpr)
326{
327	struct fpr_regs *regs;
328	int ret, i;
329
330	regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
331	ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
332	if (ret) {
333		perror("ptrace(PTRACE_GETREGSET) failed");
334		return TEST_FAIL;
335	}
336
337	if (fpr) {
338		for (i = 0; i < 32; i++)
339			fpr[i] = regs->fpr[i];
340	}
341	return TEST_PASS;
342}
343
344int write_fpr(pid_t child, __u64 val)
345{
346	struct fpr_regs *regs;
347	int ret, i;
348
349	regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
350	ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
351	if (ret) {
352		perror("ptrace(PTRACE_GETREGSET) failed");
353		return TEST_FAIL;
354	}
355
356	for (i = 0; i < 32; i++)
357		regs->fpr[i] = val;
358
359	ret = ptrace(PTRACE_SETFPREGS, child, NULL, regs);
360	if (ret) {
361		perror("ptrace(PTRACE_GETREGSET) failed");
362		return TEST_FAIL;
363	}
364	return TEST_PASS;
365}
366
367int show_ckpt_fpr(pid_t child, __u64 *fpr)
368{
369	struct fpr_regs *regs;
370	struct iovec iov;
371	int ret, i;
372
373	regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
374	iov.iov_base = regs;
375	iov.iov_len = sizeof(struct fpr_regs);
376
377	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
378	if (ret) {
379		perror("ptrace(PTRACE_GETREGSET) failed");
380		return TEST_FAIL;
381	}
382
383	if (fpr) {
384		for (i = 0; i < 32; i++)
385			fpr[i] = regs->fpr[i];
386	}
387
388	return TEST_PASS;
389}
390
391int write_ckpt_fpr(pid_t child, unsigned long val)
392{
393	struct fpr_regs *regs;
394	struct iovec iov;
395	int ret, i;
396
397	regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
398	iov.iov_base = regs;
399	iov.iov_len = sizeof(struct fpr_regs);
400
401	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
402	if (ret) {
403		perror("ptrace(PTRACE_GETREGSET) failed");
404		return TEST_FAIL;
405	}
406
407	for (i = 0; i < 32; i++)
408		regs->fpr[i] = val;
409
410	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CFPR, &iov);
411	if (ret) {
412		perror("ptrace(PTRACE_GETREGSET) failed");
413		return TEST_FAIL;
414	}
415	return TEST_PASS;
416}
417
418/* GPR */
419int show_gpr(pid_t child, unsigned long *gpr)
420{
421	struct pt_regs *regs;
422	int ret, i;
423
424	regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
425	if (!regs) {
426		perror("malloc() failed");
427		return TEST_FAIL;
428	}
429
430	ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
431	if (ret) {
432		perror("ptrace(PTRACE_GETREGSET) failed");
433		return TEST_FAIL;
434	}
435
436	if (gpr) {
437		for (i = 14; i < 32; i++)
438			gpr[i-14] = regs->gpr[i];
439	}
440
441	return TEST_PASS;
442}
443
444long sys_ptrace(enum __ptrace_request request, pid_t pid, unsigned long addr, unsigned long data)
445{
446	return syscall(__NR_ptrace, request, pid, (void *)addr, data);
447}
448
449// 33 because of FPSCR
450#define PT_NUM_FPRS	(33 * (sizeof(__u64) / sizeof(unsigned long)))
451
452__u64 *peek_fprs(pid_t child)
453{
454	unsigned long *fprs, *p, addr;
455	long ret;
456	int i;
457
458	fprs = malloc(sizeof(unsigned long) * PT_NUM_FPRS);
459	if (!fprs) {
460		perror("malloc() failed");
461		return NULL;
462	}
463
464	for (i = 0, p = fprs; i < PT_NUM_FPRS; i++, p++) {
465		addr = sizeof(unsigned long) * (PT_FPR0 + i);
466		ret = sys_ptrace(PTRACE_PEEKUSER, child, addr, (unsigned long)p);
467		if (ret) {
468			perror("ptrace(PTRACE_PEEKUSR) failed");
469			return NULL;
470		}
471	}
472
473	addr = sizeof(unsigned long) * (PT_FPR0 + i);
474	ret = sys_ptrace(PTRACE_PEEKUSER, child, addr, (unsigned long)&addr);
475	if (!ret) {
476		printf("ptrace(PTRACE_PEEKUSR) succeeded unexpectedly!\n");
477		return NULL;
478	}
479
480	return (__u64 *)fprs;
481}
482
483int poke_fprs(pid_t child, unsigned long *fprs)
484{
485	unsigned long *p, addr;
486	long ret;
487	int i;
488
489	for (i = 0, p = fprs; i < PT_NUM_FPRS; i++, p++) {
490		addr = sizeof(unsigned long) * (PT_FPR0 + i);
491		ret = sys_ptrace(PTRACE_POKEUSER, child, addr, *p);
492		if (ret) {
493			perror("ptrace(PTRACE_POKEUSR) failed");
494			return -1;
495		}
496	}
497
498	addr = sizeof(unsigned long) * (PT_FPR0 + i);
499	ret = sys_ptrace(PTRACE_POKEUSER, child, addr, addr);
500	if (!ret) {
501		printf("ptrace(PTRACE_POKEUSR) succeeded unexpectedly!\n");
502		return -1;
503	}
504
505	return 0;
506}
507
508int write_gpr(pid_t child, unsigned long val)
509{
510	struct pt_regs *regs;
511	int i, ret;
512
513	regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
514	if (!regs) {
515		perror("malloc() failed");
516		return TEST_FAIL;
517	}
518
519	ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
520	if (ret) {
521		perror("ptrace(PTRACE_GETREGSET) failed");
522		return TEST_FAIL;
523	}
524
525	for (i = 14; i < 32; i++)
526		regs->gpr[i] = val;
527
528	ret = ptrace(PTRACE_SETREGS, child, NULL, regs);
529	if (ret) {
530		perror("ptrace(PTRACE_GETREGSET) failed");
531		return TEST_FAIL;
532	}
533	return TEST_PASS;
534}
535
536int show_ckpt_gpr(pid_t child, unsigned long *gpr)
537{
538	struct pt_regs *regs;
539	struct iovec iov;
540	int ret, i;
541
542	regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
543	if (!regs) {
544		perror("malloc() failed");
545		return TEST_FAIL;
546	}
547
548	iov.iov_base = (u64 *) regs;
549	iov.iov_len = sizeof(struct pt_regs);
550
551	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
552	if (ret) {
553		perror("ptrace(PTRACE_GETREGSET) failed");
554		return TEST_FAIL;
555	}
556
557	if (gpr) {
558		for (i = 14; i < 32; i++)
559			gpr[i-14] = regs->gpr[i];
560	}
561
562	return TEST_PASS;
563}
564
565int write_ckpt_gpr(pid_t child, unsigned long val)
566{
567	struct pt_regs *regs;
568	struct iovec iov;
569	int ret, i;
570
571	regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
572	if (!regs) {
573		perror("malloc() failed\n");
574		return TEST_FAIL;
575	}
576	iov.iov_base = (u64 *) regs;
577	iov.iov_len = sizeof(struct pt_regs);
578
579	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
580	if (ret) {
581		perror("ptrace(PTRACE_GETREGSET) failed");
582		return TEST_FAIL;
583	}
584
585	for (i = 14; i < 32; i++)
586		regs->gpr[i] = val;
587
588	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CGPR, &iov);
589	if (ret) {
590		perror("ptrace(PTRACE_GETREGSET) failed");
591		return TEST_FAIL;
592	}
593	return TEST_PASS;
594}
595
596/* VMX */
597int show_vmx(pid_t child, unsigned long vmx[][2])
598{
599	int ret;
600
601	ret = ptrace(PTRACE_GETVRREGS, child, 0, vmx);
602	if (ret) {
603		perror("ptrace(PTRACE_GETVRREGS) failed");
604		return TEST_FAIL;
605	}
606	return TEST_PASS;
607}
608
609int show_vmx_ckpt(pid_t child, unsigned long vmx[][2])
610{
611	unsigned long regs[34][2];
612	struct iovec iov;
613	int ret;
614
615	iov.iov_base = (u64 *) regs;
616	iov.iov_len = sizeof(regs);
617	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVMX, &iov);
618	if (ret) {
619		perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVMX) failed");
620		return TEST_FAIL;
621	}
622	memcpy(vmx, regs, sizeof(regs));
623	return TEST_PASS;
624}
625
626
627int write_vmx(pid_t child, unsigned long vmx[][2])
628{
629	int ret;
630
631	ret = ptrace(PTRACE_SETVRREGS, child, 0, vmx);
632	if (ret) {
633		perror("ptrace(PTRACE_SETVRREGS) failed");
634		return TEST_FAIL;
635	}
636	return TEST_PASS;
637}
638
639int write_vmx_ckpt(pid_t child, unsigned long vmx[][2])
640{
641	unsigned long regs[34][2];
642	struct iovec iov;
643	int ret;
644
645	memcpy(regs, vmx, sizeof(regs));
646	iov.iov_base = (u64 *) regs;
647	iov.iov_len = sizeof(regs);
648	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVMX, &iov);
649	if (ret) {
650		perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVMX) failed");
651		return TEST_FAIL;
652	}
653	return TEST_PASS;
654}
655
656/* VSX */
657int show_vsx(pid_t child, unsigned long *vsx)
658{
659	int ret;
660
661	ret = ptrace(PTRACE_GETVSRREGS, child, 0, vsx);
662	if (ret) {
663		perror("ptrace(PTRACE_GETVSRREGS) failed");
664		return TEST_FAIL;
665	}
666	return TEST_PASS;
667}
668
669int show_vsx_ckpt(pid_t child, unsigned long *vsx)
670{
671	unsigned long regs[32];
672	struct iovec iov;
673	int ret;
674
675	iov.iov_base = (u64 *) regs;
676	iov.iov_len = sizeof(regs);
677	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVSX, &iov);
678	if (ret) {
679		perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVSX) failed");
680		return TEST_FAIL;
681	}
682	memcpy(vsx, regs, sizeof(regs));
683	return TEST_PASS;
684}
685
686int write_vsx(pid_t child, unsigned long *vsx)
687{
688	int ret;
689
690	ret = ptrace(PTRACE_SETVSRREGS, child, 0, vsx);
691	if (ret) {
692		perror("ptrace(PTRACE_SETVSRREGS) failed");
693		return TEST_FAIL;
694	}
695	return TEST_PASS;
696}
697
698int write_vsx_ckpt(pid_t child, unsigned long *vsx)
699{
700	unsigned long regs[32];
701	struct iovec iov;
702	int ret;
703
704	memcpy(regs, vsx, sizeof(regs));
705	iov.iov_base = (u64 *) regs;
706	iov.iov_len = sizeof(regs);
707	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVSX, &iov);
708	if (ret) {
709		perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVSX) failed");
710		return TEST_FAIL;
711	}
712	return TEST_PASS;
713}
714
715/* TM SPR */
716int show_tm_spr(pid_t child, struct tm_spr_regs *out)
717{
718	struct tm_spr_regs *regs;
719	struct iovec iov;
720	int ret;
721
722	regs = (struct tm_spr_regs *) malloc(sizeof(struct tm_spr_regs));
723	if (!regs) {
724		perror("malloc() failed");
725		return TEST_FAIL;
726	}
727
728	iov.iov_base = (u64 *) regs;
729	iov.iov_len = sizeof(struct tm_spr_regs);
730
731	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_SPR, &iov);
732	if (ret) {
733		perror("ptrace(PTRACE_GETREGSET) failed");
734		return TEST_FAIL;
735	}
736
737	if (out)
738		memcpy(out, regs, sizeof(struct tm_spr_regs));
739
740	return TEST_PASS;
741}
742
743
744
745/* Analyse TEXASR after TM failure */
746inline unsigned long get_tfiar(void)
747{
748	return mfspr(SPRN_TFIAR);
749}
750
751void analyse_texasr(unsigned long texasr)
752{
753	printf("TEXASR: %16lx\t", texasr);
754
755	if (texasr & TEXASR_FP)
756		printf("TEXASR_FP  ");
757
758	if (texasr & TEXASR_DA)
759		printf("TEXASR_DA  ");
760
761	if (texasr & TEXASR_NO)
762		printf("TEXASR_NO  ");
763
764	if (texasr & TEXASR_FO)
765		printf("TEXASR_FO  ");
766
767	if (texasr & TEXASR_SIC)
768		printf("TEXASR_SIC  ");
769
770	if (texasr & TEXASR_NTC)
771		printf("TEXASR_NTC  ");
772
773	if (texasr & TEXASR_TC)
774		printf("TEXASR_TC  ");
775
776	if (texasr & TEXASR_TIC)
777		printf("TEXASR_TIC  ");
778
779	if (texasr & TEXASR_IC)
780		printf("TEXASR_IC  ");
781
782	if (texasr & TEXASR_IFC)
783		printf("TEXASR_IFC  ");
784
785	if (texasr & TEXASR_ABT)
786		printf("TEXASR_ABT  ");
787
788	if (texasr & TEXASR_SPD)
789		printf("TEXASR_SPD  ");
790
791	if (texasr & TEXASR_HV)
792		printf("TEXASR_HV  ");
793
794	if (texasr & TEXASR_PR)
795		printf("TEXASR_PR  ");
796
797	if (texasr & TEXASR_FS)
798		printf("TEXASR_FS  ");
799
800	if (texasr & TEXASR_TE)
801		printf("TEXASR_TE  ");
802
803	if (texasr & TEXASR_ROT)
804		printf("TEXASR_ROT  ");
805
806	printf("TFIAR :%lx\n", get_tfiar());
807}
808
809void store_gpr(unsigned long *addr);
810