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__ */
Cache object: 86abd304193e78aa9f9bd131a2113b29
|