]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/mips/cavium/octeon_pcmap_regs.h
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / mips / cavium / octeon_pcmap_regs.h
1 /***********************license start***************
2  *  Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights
3  *  reserved.
4  *
5  *
6  *  Redistribution and use in source and binary forms, with or without
7  *  modification, are permitted provided that the following conditions are
8  *  met:
9  *
10  *      * Redistributions of source code must retain the above copyright
11  *        notice, this list of conditions and the following disclaimer.
12  *
13  *      * Redistributions in binary form must reproduce the above
14  *        copyright notice, this list of conditions and the following
15  *        disclaimer in the documentation and/or other materials provided
16  *        with the distribution.
17  *
18  *      * Neither the name of Cavium Networks nor the names of
19  *        its contributors may be used to endorse or promote products
20  *        derived from this software without specific prior written
21  *        permission.
22  *
23  *  TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
24  *  AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS
25  *  OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
26  *  RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
27  *  REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
28  *  DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
29  *  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
30  *  PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
31  *  POSSESSION OR CORRESPONDENCE TO DESCRIPTION.  THE ENTIRE RISK ARISING OUT
32  *  OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
33  *
34  *
35  *  For any questions regarding licensing please contact marketing@caviumnetworks.com
36  *
37  ***********************license end**************************************/
38
39 /*
40  *    This product includes software developed by the University of
41  *    California, Berkeley and its contributors."
42  */
43
44 /* $FreeBSD$ */
45
46 #ifndef __OCTEON_PCMAP_REGS_H__
47 #define __OCTEON_PCMAP_REGS_H__
48
49 #ifndef LOCORE
50
51 /*
52  * Utility inlines & macros
53  */
54
55 #if defined(__mips_n64)
56 #define oct_write64(a, v)       (*(volatile uint64_t *)(a) = (uint64_t)(v))
57 #define oct_write8_x8(a, v)     (*(volatile uint8_t *)(a) = (uint8_t)(v))
58
59 #define OCT_READ(n, t)                                                  \
60 static inline t oct_read ## n(uintptr_t a)                              \
61 {                                                                       \
62         volatile t *p = (volatile t *)a;                                \
63         return (*p);                                                    \
64 }
65
66 OCT_READ(8, uint8_t);
67 OCT_READ(16, uint16_t);
68 OCT_READ(32, uint32_t);
69 OCT_READ(64, uint64_t);
70
71 #elif defined(__mips_n32) || defined(__mips_o32)
72 #if defined(__mips_n32)
73 static inline void oct_write64 (uint64_t csr_addr, uint64_t val64)
74 {
75     __asm __volatile (
76             ".set push\n"
77             ".set mips64\n"
78             "sd     %0, 0(%1)\n"
79             ".set pop\n"
80             :
81             : "r"(val64), "r"(csr_addr));
82 }
83
84 static inline void oct_write8_x8 (uint64_t csr_addr, uint8_t val8)
85 {
86     __asm __volatile (
87             ".set push\n"
88             ".set mips64\n"
89             "sb    %0, 0(%1)\n"
90             ".set pop\n"
91             :
92             : "r"(val8), "r"(csr_addr));
93 }
94
95 #define OCT_READ(n, t, insn)                                            \
96 static inline t oct_read ## n(uint64_t a)                               \
97 {                                                                       \
98     uint64_t tmp;                                                       \
99                                                                         \
100     __asm __volatile (                                                  \
101         ".set push\n"                                                   \
102         ".set mips64\n"                                                 \
103         insn "\t%0, 0(%1)\n"                                            \
104         ".set pop\n"                                                    \
105         : "=r"(tmp)                                                     \
106         : "r"(a));                                                      \
107     return ((t)tmp);                                                    \
108 }
109
110 OCT_READ(8, uint8_t, "lb");
111 OCT_READ(16, uint16_t, "lh");
112 OCT_READ(32, uint32_t, "lw");
113 OCT_READ(64, uint64_t, "ld");
114 #else
115
116 /*
117  * XXX
118  * Add o32 variants that load the address into a register and the result out
119  * of a register properly, and simply disable interrupts before and after and
120  * hope that we don't need to refill or modify the TLB to access the address.
121  * I'd be a lot happier if csr_addr were a physical address and we mapped it
122  * into XKPHYS here so that we could guarantee that interrupts were the only
123  * kind of exception we needed to worry about.
124  *
125  * Also, some of this inline assembly is needlessly verbose.  Oh, well.
126  */
127 static inline void oct_write64 (uint64_t csr_addr, uint64_t val64)
128 {
129         uint32_t csr_addrh = csr_addr >> 32;
130         uint32_t csr_addrl = csr_addr;
131         uint32_t valh = val64 >> 32;
132         uint32_t vall = val64;
133         uint32_t tmp1;
134         uint32_t tmp2;
135         uint32_t tmp3;
136         register_t sr;
137
138         sr = intr_disable();
139
140         __asm __volatile (
141             ".set push\n"
142             ".set mips64\n"
143             ".set noreorder\n"
144             ".set noat\n"
145             "dsll   %0, %3, 32\n"
146             "dsll   %1, %5, 32\n"
147             "dsll   %2, %4, 32\n"
148             "dsrl   %2, %2, 32\n"
149             "or     %0, %0, %2\n"
150             "dsll   %2, %6, 32\n"
151             "dsrl   %2, %2, 32\n"
152             "or     %1, %1, %2\n"
153             "sd     %0, 0(%1)\n"
154             ".set pop\n"
155             : "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3)
156             : "r" (valh), "r" (vall), "r" (csr_addrh), "r" (csr_addrl));
157
158         intr_restore(sr);
159 }
160
161 static inline void oct_write8_x8 (uint64_t csr_addr, uint8_t val8)
162 {
163         uint32_t csr_addrh = csr_addr >> 32;
164         uint32_t csr_addrl = csr_addr;
165         uint32_t tmp1;
166         uint32_t tmp2;
167         register_t sr;
168
169         sr = intr_disable();
170
171         __asm __volatile (
172             ".set push\n"
173             ".set mips64\n"
174             ".set noreorder\n"
175             ".set noat\n"
176             "dsll   %0, %3, 32\n"
177             "dsll   %1, %4, 32\n"
178             "dsrl   %1, %1, 32\n"
179             "or     %0, %0, %1\n"
180             "sb     %2, 0(%0)\n"
181             ".set pop\n"
182             : "=&r" (tmp1), "=&r" (tmp2)
183             : "r" (val8), "r" (csr_addrh), "r" (csr_addrl));
184
185         intr_restore(sr);
186 }
187
188 #define OCT_READ(n, t, insn)                                            \
189 static inline t oct_read ## n(uint64_t csr_addr)                        \
190 {                                                                       \
191         uint32_t csr_addrh = csr_addr >> 32;                            \
192         uint32_t csr_addrl = csr_addr;                                  \
193         uint32_t tmp1, tmp2;                                            \
194         register_t sr;                                                  \
195                                                                         \
196         sr = intr_disable();                                            \
197                                                                         \
198         __asm __volatile (                                              \
199             ".set push\n"                                               \
200             ".set mips64\n"                                             \
201             ".set noreorder\n"                                          \
202             ".set noat\n"                                               \
203             "dsll   %1, %2, 32\n"                                       \
204             "dsll   %0, %3, 32\n"                                       \
205             "dsrl   %0, %0, 32\n"                                       \
206             "or     %1, %1, %0\n"                                       \
207             "lb     %1, 0(%1)\n"                                        \
208             ".set pop\n"                                                \
209             : "=&r" (tmp1), "=&r" (tmp2)                                \
210             : "r" (csr_addrh), "r" (csr_addrl));                        \
211                                                                         \
212         intr_restore(sr);                                               \
213                                                                         \
214         return ((t)tmp2);                                               \
215 }
216
217 OCT_READ(8, uint8_t, "lb");
218 OCT_READ(16, uint16_t, "lh");
219 OCT_READ(32, uint32_t, "lw");
220
221 static inline uint64_t oct_read64 (uint64_t csr_addr)
222 {
223         uint32_t csr_addrh = csr_addr >> 32;
224         uint32_t csr_addrl = csr_addr;
225         uint32_t valh;
226         uint32_t vall;
227         register_t sr;
228
229         sr = intr_disable();
230
231         __asm __volatile (
232             ".set push\n"
233             ".set mips64\n"
234             ".set noreorder\n"
235             ".set noat\n"
236             "dsll   %0, %2, 32\n"
237             "dsll   %1, %3, 32\n"
238             "dsrl   %1, %1, 32\n"
239             "or     %0, %0, %1\n"
240             "ld     %1, 0(%0)\n"
241             "dsrl   %0, %1, 32\n"
242             "dsll   %1, %1, 32\n"
243             "dsrl   %1, %1, 32\n"
244             ".set pop\n"
245             : "=&r" (valh), "=&r" (vall)
246             : "r" (csr_addrh), "r" (csr_addrl));
247
248         intr_restore(sr);
249
250         return ((uint64_t)valh << 32) | vall;
251 }
252 #endif
253
254 #endif
255
256 #define oct_write64_int64(a, v) (oct_write64(a, (int64_t)(v)))
257
258 /*
259  * Most write bus transactions are actually 64-bit on Octeon.
260  */
261 static inline void oct_write8 (uint64_t csr_addr, uint8_t val8)
262 {
263     oct_write64(csr_addr, (uint64_t) val8);
264 }
265
266 static inline void oct_write16 (uint64_t csr_addr, uint16_t val16)
267 {
268     oct_write64(csr_addr, (uint64_t) val16);
269 }
270
271 static inline void oct_write32 (uint64_t csr_addr, uint32_t val32)
272 {
273     oct_write64(csr_addr, (uint64_t) val32);
274 }
275
276 #define oct_readint32(a)        ((int32_t)oct_read32((a)))
277
278 /*
279  * octeon_machdep.c
280  *
281  * Direct to Board Support level.
282  */
283 extern void octeon_led_write_char(int char_position, char val);
284 extern void octeon_led_write_hexchar(int char_position, char hexval);
285 extern void octeon_led_write_hex(uint32_t wl);
286 extern void octeon_led_write_string(const char *str);
287 extern void octeon_reset(void);
288 extern void octeon_led_write_char0(char val);
289 extern void octeon_led_run_wheel(int *pos, int led_position);
290 extern void octeon_debug_symbol(void);
291 extern void octeon_ciu_reset(void);
292 extern int octeon_is_simulation(void);
293 #endif  /* LOCORE */
294
295 /*
296  * EBT3000 LED Unit
297  */
298 #define  OCTEON_CHAR_LED_BASE_ADDR      (0x1d020000 | (0x1ffffffffull << 31))
299
300 #endif /* !OCTEON_PCMAP_REGS_H__ */