blob: 4f68fbda6993240e85457801e190ceb9cc711ff3 [file] [log] [blame]
Daniel Hellstromc2f02da2008-03-28 09:47:00 +01001/*
2 * Added to U-boot,
3 * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
4 * Copyright (C) 2007
5 *
6 * LEON2/3 LIBIO low-level routines
7 * Written by Jiri Gaisler.
8 * Copyright (C) 2004 Gaisler Research AB
Wolfgang Denk1a459662013-07-08 09:37:19 +02009 *
10 * SPDX-License-Identifier: GPL-2.0+
11 */
Daniel Hellstromc2f02da2008-03-28 09:47:00 +010012
Wolfgang Denk1a459662013-07-08 09:37:19 +020013#ifndef __SPARC_WINMACRO_H__
14#define __SPARC_WINMACRO_H__
Daniel Hellstromc2f02da2008-03-28 09:47:00 +010015
Wolfgang Denk1a459662013-07-08 09:37:19 +020016#include <asm/asmmacro.h>
17#include <asm/stack.h>
Daniel Hellstromc2f02da2008-03-28 09:47:00 +010018
Wolfgang Denk1a459662013-07-08 09:37:19 +020019/* Store the register window onto the 8-byte aligned area starting
20 * at %reg. It might be %sp, it might not, we don't care.
21 */
22#define RW_STORE(reg) \
23 std %l0, [%reg + RW_L0]; \
24 std %l2, [%reg + RW_L2]; \
25 std %l4, [%reg + RW_L4]; \
26 std %l6, [%reg + RW_L6]; \
27 std %i0, [%reg + RW_I0]; \
28 std %i2, [%reg + RW_I2]; \
29 std %i4, [%reg + RW_I4]; \
30 std %i6, [%reg + RW_I6];
Daniel Hellstromc2f02da2008-03-28 09:47:00 +010031
Wolfgang Denk1a459662013-07-08 09:37:19 +020032/* Load a register window from the area beginning at %reg. */
33#define RW_LOAD(reg) \
34 ldd [%reg + RW_L0], %l0; \
35 ldd [%reg + RW_L2], %l2; \
36 ldd [%reg + RW_L4], %l4; \
37 ldd [%reg + RW_L6], %l6; \
38 ldd [%reg + RW_I0], %i0; \
39 ldd [%reg + RW_I2], %i2; \
40 ldd [%reg + RW_I4], %i4; \
41 ldd [%reg + RW_I6], %i6;
42
43/* Loading and storing struct pt_reg trap frames. */
44#define PT_LOAD_INS(base_reg) \
45 ldd [%base_reg + SF_REGS_SZ + PT_I0], %i0; \
46 ldd [%base_reg + SF_REGS_SZ + PT_I2], %i2; \
47 ldd [%base_reg + SF_REGS_SZ + PT_I4], %i4; \
48 ldd [%base_reg + SF_REGS_SZ + PT_I6], %i6;
49
50#define PT_LOAD_GLOBALS(base_reg) \
51 ld [%base_reg + SF_REGS_SZ + PT_G1], %g1; \
52 ldd [%base_reg + SF_REGS_SZ + PT_G2], %g2; \
53 ldd [%base_reg + SF_REGS_SZ + PT_G4], %g4; \
54 ldd [%base_reg + SF_REGS_SZ + PT_G6], %g6;
55
56#define PT_LOAD_YREG(base_reg, scratch) \
57 ld [%base_reg + SF_REGS_SZ + PT_Y], %scratch; \
58 wr %scratch, 0x0, %y;
59
60#define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
61 ld [%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \
62 ld [%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \
63 ld [%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc;
64
65#define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \
66 PT_LOAD_YREG(base_reg, scratch) \
67 PT_LOAD_INS(base_reg) \
68 PT_LOAD_GLOBALS(base_reg) \
69 PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc)
70
71#define PT_STORE_INS(base_reg) \
72 std %i0, [%base_reg + SF_REGS_SZ + PT_I0]; \
73 std %i2, [%base_reg + SF_REGS_SZ + PT_I2]; \
74 std %i4, [%base_reg + SF_REGS_SZ + PT_I4]; \
75 std %i6, [%base_reg + SF_REGS_SZ + PT_I6];
76
77#define PT_STORE_GLOBALS(base_reg) \
78 st %g1, [%base_reg + SF_REGS_SZ + PT_G1]; \
79 std %g2, [%base_reg + SF_REGS_SZ + PT_G2]; \
80 std %g4, [%base_reg + SF_REGS_SZ + PT_G4]; \
81 std %g6, [%base_reg + SF_REGS_SZ + PT_G6];
82
83#define PT_STORE_YREG(base_reg, scratch) \
84 rd %y, %scratch; \
85 st %scratch, [%base_reg + SF_REGS_SZ + PT_Y];
86
87#define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
88 st %pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \
89 st %pt_pc, [%base_reg + SF_REGS_SZ + PT_PC]; \
90 st %pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC];
91
92#define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \
93 PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \
94 PT_STORE_GLOBALS(base_reg) \
95 PT_STORE_YREG(base_reg, g_scratch) \
96 PT_STORE_INS(base_reg)
97
98/* Store the fpu register window*/
99#define FW_STORE(reg) \
100 std %f0, [reg + FW_F0]; \
101 std %f2, [reg + FW_F2]; \
102 std %f4, [reg + FW_F4]; \
103 std %f6, [reg + FW_F6]; \
104 std %f8, [reg + FW_F8]; \
105 std %f10, [reg + FW_F10]; \
106 std %f12, [reg + FW_F12]; \
107 std %f14, [reg + FW_F14]; \
108 std %f16, [reg + FW_F16]; \
109 std %f18, [reg + FW_F18]; \
110 std %f20, [reg + FW_F20]; \
111 std %f22, [reg + FW_F22]; \
112 std %f24, [reg + FW_F24]; \
113 std %f26, [reg + FW_F26]; \
114 std %f28, [reg + FW_F28]; \
115 std %f30, [reg + FW_F30]; \
116 st %fsr, [reg + FW_FSR];
117
118/* Load a fpu register window from the area beginning at reg. */
119#define FW_LOAD(reg) \
120 ldd [reg + FW_F0], %f0; \
121 ldd [reg + FW_F2], %f2; \
122 ldd [reg + FW_F4], %f4; \
123 ldd [reg + FW_F6], %f6; \
124 ldd [reg + FW_F8], %f8; \
125 ldd [reg + FW_F10], %f10; \
126 ldd [reg + FW_F12], %f12; \
127 ldd [reg + FW_F14], %f14; \
128 ldd [reg + FW_F16], %f16; \
129 ldd [reg + FW_F18], %f18; \
130 ldd [reg + FW_F20], %f20; \
131 ldd [reg + FW_F22], %f22; \
132 ldd [reg + FW_F24], %f24; \
133 ldd [reg + FW_F26], %f26; \
134 ldd [reg + FW_F28], %f28; \
135 ldd [reg + FW_F30], %f30; \
136 ld [reg + FW_FSR], %fsr;
137
138#endif