1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2019-12-04     Jiaxun Yang  Initial version
9  */
10 
11 #ifndef _MIPS_ADDRSPACE_H_
12 #define _MIPS_ADDRSPACE_H_
13 
14 
15 /*
16  *  Configure language
17  */
18 #ifdef __ASSEMBLY__
19 #define _ATYPE_
20 #define _ATYPE32_
21 #define _ATYPE64_
22 #define _CONST64_(x)    x
23 #else
24 #define _ATYPE_     __PTRDIFF_TYPE__
25 #define _ATYPE32_   int
26 #define _ATYPE64_   __s64
27 #ifdef ARCH_MIPS64
28 #define _CONST64_(x)    x ## L
29 #else
30 #define _CONST64_(x)    x ## LL
31 #endif
32 #endif
33 
34 /*
35  *  32-bit MIPS address spaces
36  */
37 #ifdef __ASSEMBLY__
38 #define _ACAST32_
39 #define _ACAST64_
40 #else
41 #define _ACAST32_       (_ATYPE_)(_ATYPE32_)    /* widen if necessary */
42 #define _ACAST64_       (_ATYPE64_)     /* do _not_ narrow */
43 #endif
44 
45 /*
46  * Returns the kernel segment base of a given address
47  */
48 #define KSEGX(a)        ((_ACAST32_ (a)) & 0xe0000000)
49 
50 /*
51  * Returns the physical address of a CKSEGx / XKPHYS address
52  */
53 #define CPHYSADDR(a)        ((_ACAST32_(a)) & 0x1fffffff)
54 #define XPHYSADDR(a)        ((_ACAST64_(a)) &           \
55                  _CONST64_(0x000000ffffffffff))
56 
57 #ifdef ARCH_MIPS64
58 
59 /*
60  * Memory segments (64bit kernel mode addresses)
61  * The compatibility segments use the full 64-bit sign extended value.  Note
62  * the R8000 doesn't have them so don't reference these in generic MIPS code.
63  */
64 #define XKUSEG          _CONST64_(0x0000000000000000)
65 #define XKSSEG          _CONST64_(0x4000000000000000)
66 #define XKPHYS          _CONST64_(0x8000000000000000)
67 #define XKSEG           _CONST64_(0xc000000000000000)
68 #define CKSEG0          _CONST64_(0xffffffff80000000)
69 #define CKSEG1          _CONST64_(0xffffffffa0000000)
70 #define CKSSEG          _CONST64_(0xffffffffc0000000)
71 #define CKSEG3          _CONST64_(0xffffffffe0000000)
72 
73 #define CKSEG0ADDR(a)       (CPHYSADDR(a) | CKSEG0)
74 #define CKSEG1ADDR(a)       (CPHYSADDR(a) | CKSEG1)
75 #define CKSEG2ADDR(a)       (CPHYSADDR(a) | CKSEG2)
76 #define CKSEG3ADDR(a)       (CPHYSADDR(a) | CKSEG3)
77 
78 #define KUSEGBASE           0xffffffff00000000
79 #define KSEG0BASE           0xffffffff80000000
80 #define KSEG1BASE           0xffffffffa0000000
81 #define KSEG2BASE           0xffffffffc0000000
82 #define KSEG3BASE           0xffffffffe0000000
83 
84 #else
85 
86 #define CKSEG0ADDR(a)       (CPHYSADDR(a) | KSEG0BASE)
87 #define CKSEG1ADDR(a)       (CPHYSADDR(a) | KSEG1BASE)
88 #define CKSEG2ADDR(a)       (CPHYSADDR(a) | KSEG2BASE)
89 #define CKSEG3ADDR(a)       (CPHYSADDR(a) | KSEG3BASE)
90 
91 /*
92  * Map an address to a certain kernel segment
93  */
94 #define KSEG0ADDR(a)        (CPHYSADDR(a) | KSEG0BASE)
95 #define KSEG1ADDR(a)        (CPHYSADDR(a) | KSEG1BASE)
96 #define KSEG2ADDR(a)        (CPHYSADDR(a) | KSEG2BASE)
97 #define KSEG3ADDR(a)        (CPHYSADDR(a) | KSEG3BASE)
98 
99 #define CKUSEG          0x00000000
100 #define CKSEG0          0x80000000
101 #define CKSEG1          0xa0000000
102 #define CKSEG2          0xc0000000
103 #define CKSEG3          0xe0000000
104 
105 /*
106  * Memory segments (32bit kernel mode addresses)
107  * These are the traditional names used in the 32-bit universe.
108  */
109 #define KUSEGBASE           0x00000000
110 #define KSEG0BASE           0x80000000
111 #define KSEG1BASE           0xa0000000
112 #define KSEG2BASE           0xc0000000
113 #define KSEG3BASE           0xe0000000
114 
115 #endif
116 
117 
118 /*
119  * Cache modes for XKPHYS address conversion macros
120  */
121 #define K_CALG_COH_EXCL1_NOL2   0
122 #define K_CALG_COH_SHRL1_NOL2   1
123 #define K_CALG_UNCACHED     2
124 #define K_CALG_NONCOHERENT  3
125 #define K_CALG_COH_EXCL     4
126 #define K_CALG_COH_SHAREABLE    5
127 #define K_CALG_NOTUSED      6
128 #define K_CALG_UNCACHED_ACCEL   7
129 
130 /*
131  * 64-bit address conversions
132  */
133 #define PHYS_TO_XKSEG_UNCACHED(p)   PHYS_TO_XKPHYS(K_CALG_UNCACHED, (p))
134 #define PHYS_TO_XKSEG_CACHED(p)     PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE, (p))
135 #define XKPHYS_TO_PHYS(p)       ((p) & TO_PHYS_MASK)
136 #define PHYS_TO_XKPHYS(cm, a)       (_CONST64_(0x8000000000000000) | \
137                      (_CONST64_(cm) << 59) | (a))
138 
139 /*
140  * Returns the uncached address of a sdram address
141  */
142 #ifndef __ASSEMBLY__
143 
144 /*
145  * The ultimate limited of the 64-bit MIPS architecture:  2 bits for selecting
146  * the region, 3 bits for the CCA mode.  This leaves 59 bits of which the
147  * R8000 implements most with its 48-bit physical address space.
148  */
149 #define TO_PHYS_MASK    _CONST64_(0x07ffffffffffffff)   /* 2^^59 - 1 */
150 #define COMPAT_K1BASE32     _CONST64_(0xffffffffa0000000)
151 #define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */
152 
153 #define KDM_TO_PHYS(x)      (_ACAST64_ (x) & TO_PHYS_MASK)
154 #define PHYS_TO_K0(x)       (_ACAST64_ (x) | CAC_BASE)
155 #endif
156 
157 
158 #ifndef __ASSEMBLY__
159 #define REG8( addr )          (*(volatile u8 *) (addr))
160 #define REG16( addr )         (*(volatile u16 *)(addr))
161 #define REG32( addr )         (*(volatile u32 *)(addr))
162 #define REG64( addr )         (*(volatile u64 *)(addr))
163 #endif
164 
165 #endif /* _MIPS_ADDRSPACE_H_ */
166