]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/mips/nlm/hal/haldefs.h
Import tzdata 2018d
[FreeBSD/FreeBSD.git] / sys / mips / nlm / hal / haldefs.h
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are
9  * met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * NETLOGIC_BSD
31  * $FreeBSD$
32  */
33
34 #ifndef __NLM_HAL_MMIO_H__
35 #define __NLM_HAL_MMIO_H__
36
37 /*
38  * This file contains platform specific memory mapped IO implementation
39  * and will provide a way to read 32/64 bit memory mapped registers in
40  * all ABIs
41  */
42
43 /*
44  * For o32 compilation, we have to disable interrupts and enable KX bit to
45  * access 64 bit addresses or data.
46  *
47  * We need to disable interrupts because we save just the lower 32 bits of
48  * registers in  interrupt handling. So if we get hit by an interrupt while
49  * using the upper 32 bits of a register, we lose.
50  */
51 static inline uint32_t nlm_save_flags_kx(void)
52 {
53         uint32_t sr = mips_rd_status();
54
55         mips_wr_status((sr & ~MIPS_SR_INT_IE) | MIPS_SR_KX);
56         return (sr);
57 }
58
59 static inline uint32_t nlm_save_flags_cop2(void)
60 {
61         uint32_t sr = mips_rd_status();
62
63         mips_wr_status((sr & ~MIPS_SR_INT_IE) | MIPS_SR_COP_2_BIT);
64         return (sr);
65 }
66
67 static inline void nlm_restore_flags(uint32_t sr)
68 {
69         mips_wr_status(sr);
70 }
71
72 static inline uint32_t
73 nlm_load_word(uint64_t addr)
74 {
75         volatile uint32_t *p = (volatile uint32_t *)(long)addr;
76
77         return *p;
78 }
79
80 static inline void
81 nlm_store_word(uint64_t addr, uint32_t val)
82 {
83         volatile uint32_t *p = (volatile uint32_t *)(long)addr;
84
85         *p = val;
86 }
87
88 #if defined(__mips_n64) || defined(__mips_n32)
89 static inline uint64_t
90 nlm_load_dword(volatile uint64_t addr)
91 {
92         volatile uint64_t *p = (volatile uint64_t *)(long)addr;
93
94         return *p;
95 }
96
97 static inline void
98 nlm_store_dword(volatile uint64_t addr, uint64_t val)
99 {
100         volatile uint64_t *p = (volatile uint64_t *)(long)addr;
101
102         *p = val;
103 }
104
105 #else /* o32 */
106 static inline uint64_t
107 nlm_load_dword(uint64_t addr)
108 {
109         volatile uint64_t *p = (volatile uint64_t *)(long)addr;
110         uint32_t valhi, vallo, sr;
111
112         sr = nlm_save_flags_kx();
113         __asm__ __volatile__(
114                 ".set   push\n\t"
115                 ".set   mips64\n\t"
116                 "ld     $8, 0(%2)\n\t"
117                 "dsra32 %0, $8, 0\n\t"
118                 "sll    %1, $8, 0\n\t"
119                 ".set   pop\n"
120                 : "=r"(valhi), "=r"(vallo)
121                 : "r"(p)
122                 : "$8");
123         nlm_restore_flags(sr);
124
125         return ((uint64_t)valhi << 32) | vallo;
126 }
127
128 static inline void
129 nlm_store_dword(uint64_t addr, uint64_t val)
130 {
131         volatile uint64_t *p = (volatile uint64_t *)(long)addr;
132         uint32_t valhi, vallo, sr;
133
134         valhi = val >> 32;
135         vallo = val & 0xffffffff;
136
137         sr = nlm_save_flags_kx();
138         __asm__ __volatile__(
139                 ".set   push\n\t"
140                 ".set   mips64\n\t"
141                 "dsll32 $8, %1, 0\n\t"
142                 "dsll32 $9, %2, 0\n\t"  /* get rid of the */
143                 "dsrl32 $9, $9, 0\n\t"  /* sign extend */
144                 "or     $9, $9, $8\n\t"
145                 "sd     $9, 0(%0)\n\t"
146                 ".set   pop\n"
147                 : : "r"(p), "r"(valhi), "r"(vallo)
148                 : "$8", "$9", "memory");
149         nlm_restore_flags(sr);
150 }
151 #endif
152
153 #if defined(__mips_n64)
154 static inline uint64_t
155 nlm_load_word_daddr(uint64_t addr)
156 {
157         volatile uint32_t *p = (volatile uint32_t *)(long)addr;
158
159         return *p;
160 }
161
162 static inline void
163 nlm_store_word_daddr(uint64_t addr, uint32_t val)
164 {
165         volatile uint32_t *p = (volatile uint32_t *)(long)addr;
166
167         *p = val;
168 }
169
170 static inline uint64_t
171 nlm_load_dword_daddr(uint64_t addr)
172 {
173         volatile uint64_t *p = (volatile uint64_t *)(long)addr;
174
175         return *p;
176 }
177
178 static inline void
179 nlm_store_dword_daddr(uint64_t addr, uint64_t val)
180 {
181         volatile uint64_t *p = (volatile uint64_t *)(long)addr;
182
183         *p = val;
184 }
185
186 #elif defined(__mips_n32)
187
188 static inline uint64_t
189 nlm_load_word_daddr(uint64_t addr)
190 {
191         uint32_t val;
192
193         __asm__ __volatile__(
194                 ".set   push\n\t"
195                 ".set   mips64\n\t"
196                 "lw             %0, 0(%1)\n\t"
197                 ".set   pop\n"
198                 : "=r"(val)
199                 : "r"(addr));
200
201         return val;
202 }
203
204 static inline void
205 nlm_store_word_daddr(uint64_t addr, uint32_t val)
206 {
207         __asm__ __volatile__(
208                 ".set   push\n\t"
209                 ".set   mips64\n\t"
210                 "sw             %0, 0(%1)\n\t"
211                 ".set   pop\n"
212                 : : "r"(val), "r"(addr)
213                 : "memory");
214 }
215
216 static inline uint64_t
217 nlm_load_dword_daddr(uint64_t addr)
218 {
219         uint64_t val;
220
221         __asm__ __volatile__(
222                 ".set   push\n\t"
223                 ".set   mips64\n\t"
224                 "ld             %0, 0(%1)\n\t"
225                 ".set   pop\n"
226                 : "=r"(val)
227                 : "r"(addr));
228         return val;
229 }
230
231 static inline void
232 nlm_store_dword_daddr(uint64_t addr, uint64_t val)
233 {
234         __asm__ __volatile__(
235                 ".set   push\n\t"
236                 ".set   mips64\n\t"
237                 "sd             %0, 0(%1)\n\t"
238                 ".set   pop\n"
239                 : : "r"(val), "r"(addr)
240                 : "memory");
241 }
242
243 #else /* o32 */
244 static inline uint64_t
245 nlm_load_word_daddr(uint64_t addr)
246 {
247         uint32_t val, addrhi, addrlo, sr;
248
249         addrhi = addr >> 32;
250         addrlo = addr & 0xffffffff;
251
252         sr = nlm_save_flags_kx();
253         __asm__ __volatile__(
254                 ".set   push\n\t"
255                 ".set   mips64\n\t"
256                 "dsll32 $8, %1, 0\n\t"
257                 "dsll32 $9, %2, 0\n\t"
258                 "dsrl32 $9, $9, 0\n\t"
259                 "or     $9, $9, $8\n\t"
260                 "lw     %0, 0($9)\n\t"
261                 ".set   pop\n"
262                 :       "=r"(val)
263                 :       "r"(addrhi), "r"(addrlo)
264                 :       "$8", "$9");
265         nlm_restore_flags(sr);
266
267         return val;
268
269 }
270
271 static inline void
272 nlm_store_word_daddr(uint64_t addr, uint32_t val)
273 {
274         uint32_t addrhi, addrlo, sr;
275
276         addrhi = addr >> 32;
277         addrlo = addr & 0xffffffff;
278
279         sr = nlm_save_flags_kx();
280         __asm__ __volatile__(
281                 ".set   push\n\t"
282                 ".set   mips64\n\t"
283                 "dsll32 $8, %1, 0\n\t"
284                 "dsll32 $9, %2, 0\n\t"
285                 "dsrl32 $9, $9, 0\n\t"
286                 "or     $9, $9, $8\n\t"
287                 "sw     %0, 0($9)\n\t"
288                 ".set   pop\n"
289                 : : "r"(val), "r"(addrhi), "r"(addrlo)
290                 :       "$8", "$9", "memory");
291         nlm_restore_flags(sr);
292 }
293
294 static inline uint64_t
295 nlm_load_dword_daddr(uint64_t addr)
296 {
297         uint32_t addrh, addrl, sr;
298         uint32_t valh, vall;
299
300         addrh = addr >> 32;
301         addrl = addr & 0xffffffff;
302
303         sr = nlm_save_flags_kx();
304         __asm__ __volatile__(
305                 ".set   push\n\t"
306                 ".set   mips64\n\t"
307                 "dsll32 $8, %2, 0\n\t"
308                 "dsll32 $9, %3, 0\n\t"
309                 "dsrl32 $9, $9, 0\n\t"
310                 "or     $9, $9, $8\n\t"
311                 "ld     $8, 0($9)\n\t"
312                 "dsra32 %0, $8, 0\n\t"
313                 "sll    %1, $8, 0\n\t"
314                 ".set   pop\n"
315                 : "=r"(valh), "=r"(vall)
316                 : "r"(addrh), "r"(addrl)
317                 : "$8", "$9");
318         nlm_restore_flags(sr);
319
320         return ((uint64_t)valh << 32) | vall;
321 }
322
323 static inline void
324 nlm_store_dword_daddr(uint64_t addr, uint64_t val)
325 {
326         uint32_t addrh, addrl, sr;
327         uint32_t valh, vall;
328
329         addrh = addr >> 32;
330         addrl = addr & 0xffffffff;
331         valh = val >> 32;
332         vall = val & 0xffffffff;
333
334         sr = nlm_save_flags_kx();
335         __asm__ __volatile__(
336                 ".set   push\n\t"
337                 ".set   mips64\n\t"
338                 "dsll32 $8, %2, 0\n\t"
339                 "dsll32 $9, %3, 0\n\t"
340                 "dsrl32 $9, $9, 0\n\t"
341                 "or     $9, $9, $8\n\t"
342                 "dsll32 $8, %0, 0\n\t"
343                 "dsll32 $10, %1, 0\n\t"
344                 "dsrl32 $10, $10, 0\n\t"
345                 "or     $8, $8, $10\n\t"
346                 "sd     $8, 0($9)\n\t"
347                 ".set   pop\n"
348                 : :     "r"(valh), "r"(vall), "r"(addrh), "r"(addrl)
349                 :       "$8", "$9", "memory");
350         nlm_restore_flags(sr);
351 }
352 #endif /* __mips_n64 */
353
354 static inline uint32_t
355 nlm_read_reg(uint64_t base, uint32_t reg)
356 {
357         volatile uint32_t *addr = (volatile uint32_t *)(long)base + reg;
358
359         return *addr;
360 }
361
362 static inline void
363 nlm_write_reg(uint64_t base, uint32_t reg, uint32_t val)
364 {
365         volatile uint32_t *addr = (volatile uint32_t *)(long)base + reg;
366
367         *addr = val;
368 }
369
370 static inline uint64_t
371 nlm_read_reg64(uint64_t base, uint32_t reg)
372 {
373         uint64_t addr = base + (reg >> 1) * sizeof(uint64_t);
374
375         return nlm_load_dword(addr);
376 }
377
378 static inline void
379 nlm_write_reg64(uint64_t base, uint32_t reg, uint64_t val)
380 {
381         uint64_t addr = base + (reg >> 1) * sizeof(uint64_t);
382
383         return nlm_store_dword(addr, val);
384 }
385
386 /*
387  * Routines to store 32/64 bit values to 64 bit addresses,
388  * used when going thru XKPHYS to access registers
389  */
390 static inline uint32_t
391 nlm_read_reg_xkphys(uint64_t base, uint32_t reg)
392 {
393         uint64_t addr = base + reg * sizeof(uint32_t);
394
395         return nlm_load_word_daddr(addr);
396 }
397
398 static inline void
399 nlm_write_reg_xkphys(uint64_t base, uint32_t reg, uint32_t val)
400 {
401         uint64_t addr = base + reg * sizeof(uint32_t);
402         return nlm_store_word_daddr(addr, val);
403 }
404
405 static inline uint64_t
406 nlm_read_reg64_xkphys(uint64_t base, uint32_t reg)
407 {
408         uint64_t addr = base + (reg >> 1) * sizeof(uint64_t);
409
410         return nlm_load_dword_daddr(addr);
411 }
412
413 static inline void
414 nlm_write_reg64_xkphys(uint64_t base, uint32_t reg, uint64_t val)
415 {
416         uint64_t addr = base + (reg >> 1) * sizeof(uint64_t);
417
418         return nlm_store_dword_daddr(addr, val);
419 }
420
421 /* Location where IO base is mapped */
422 extern uint64_t xlp_io_base;
423
424 static inline uint64_t
425 nlm_pcicfg_base(uint32_t devoffset)
426 {
427         return xlp_io_base + devoffset;
428 }
429
430 static inline uint64_t
431 nlm_xkphys_map_pcibar0(uint64_t pcibase)
432 {
433         uint64_t paddr;
434
435         paddr = nlm_read_reg(pcibase, 0x4) & ~0xfu;
436         return (uint64_t)0x9000000000000000 | paddr;
437 }
438
439 #endif