octeonvar.h revision 1.8 1 1.8 simonb /* $NetBSD: octeonvar.h,v 1.8 2020/05/31 06:27:06 simonb Exp $ */
2 1.1 hikaru
3 1.1 hikaru /*-
4 1.1 hikaru * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 1.1 hikaru * All rights reserved.
6 1.1 hikaru *
7 1.1 hikaru * This code is derived from software contributed to The NetBSD Foundation
8 1.1 hikaru * by Jason R. Thorpe.
9 1.1 hikaru *
10 1.1 hikaru * Redistribution and use in source and binary forms, with or without
11 1.1 hikaru * modification, are permitted provided that the following conditions
12 1.1 hikaru * are met:
13 1.1 hikaru * 1. Redistributions of source code must retain the above copyright
14 1.1 hikaru * notice, this list of conditions and the following disclaimer.
15 1.1 hikaru * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 hikaru * notice, this list of conditions and the following disclaimer in the
17 1.1 hikaru * documentation and/or other materials provided with the distribution.
18 1.1 hikaru *
19 1.1 hikaru * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 hikaru * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 hikaru * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 hikaru * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 hikaru * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 hikaru * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 hikaru * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 hikaru * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 hikaru * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 hikaru * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 hikaru * POSSIBILITY OF SUCH DAMAGE.
30 1.1 hikaru */
31 1.1 hikaru
32 1.1 hikaru #ifndef _MIPS_OCTEON_OCTEONVAR_H_
33 1.1 hikaru #define _MIPS_OCTEON_OCTEONVAR_H_
34 1.1 hikaru
35 1.1 hikaru #include <sys/bus.h>
36 1.2 matt #include <sys/evcnt.h>
37 1.4 matt #include <sys/kcpuset.h>
38 1.1 hikaru #include <mips/locore.h>
39 1.1 hikaru #include <dev/pci/pcivar.h>
40 1.1 hikaru
41 1.1 hikaru /* XXX elsewhere */
42 1.1 hikaru #define _ASM_PROLOGUE \
43 1.1 hikaru " .set push \n" \
44 1.1 hikaru " .set noreorder \n"
45 1.1 hikaru #define _ASM_PROLOGUE_MIPS64 \
46 1.1 hikaru _ASM_PROLOGUE \
47 1.1 hikaru " .set mips64 \n"
48 1.1 hikaru #define _ASM_PROLOGUE_OCTEON \
49 1.1 hikaru _ASM_PROLOGUE \
50 1.1 hikaru " .set arch=octeon \n"
51 1.1 hikaru #define _ASM_EPILOGUE \
52 1.1 hikaru " .set pop \n"
53 1.1 hikaru /*
54 1.1 hikaru * subbits = __BITS64_GET(XXX, bits);
55 1.1 hikaru * bits = __BITS64_SET(XXX, subbits);
56 1.1 hikaru */
57 1.1 hikaru #ifndef __BITS64_GET
58 1.1 hikaru #define __BITS64_GET(name, bits) \
59 1.1 hikaru (((uint64_t)(bits) & name) >> name##_SHIFT)
60 1.1 hikaru #endif
61 1.1 hikaru #ifndef __BITS64_SET
62 1.1 hikaru #define __BITS64_SET(name, subbits) \
63 1.1 hikaru (((uint64_t)(subbits) << name##_SHIFT) & name)
64 1.1 hikaru #endif
65 1.1 hikaru
66 1.1 hikaru struct octeon_config {
67 1.1 hikaru struct mips_bus_space mc_iobus_bust;
68 1.1 hikaru struct mips_bus_space mc_bootbus_bust;
69 1.1 hikaru struct mips_pci_chipset mc_pc;
70 1.1 hikaru
71 1.1 hikaru struct mips_bus_dma_tag mc_iobus_dmat;
72 1.1 hikaru struct mips_bus_dma_tag mc_bootbus_dmat;
73 1.1 hikaru struct mips_bus_dma_tag mc_core1_dmat;
74 1.5 matt struct mips_bus_dma_tag mc_fpa_dmat;
75 1.1 hikaru
76 1.1 hikaru struct extent *mc_io_ex;
77 1.1 hikaru struct extent *mc_mem_ex;
78 1.1 hikaru
79 1.1 hikaru int mc_mallocsafe;
80 1.1 hikaru };
81 1.1 hikaru
82 1.2 matt #define NIRQS 64
83 1.2 matt
84 1.2 matt struct cpu_softc {
85 1.2 matt struct cpu_info *cpu_ci;
86 1.3 matt
87 1.2 matt uint64_t cpu_int0_sum0;
88 1.2 matt uint64_t cpu_int1_sum0;
89 1.2 matt uint64_t cpu_int2_sum0;
90 1.2 matt
91 1.2 matt uint64_t cpu_int0_en0;
92 1.2 matt uint64_t cpu_int1_en0;
93 1.2 matt uint64_t cpu_int2_en0;
94 1.2 matt
95 1.2 matt uint64_t cpu_int0_en1;
96 1.2 matt uint64_t cpu_int1_en1;
97 1.2 matt uint64_t cpu_int2_en1;
98 1.2 matt
99 1.2 matt uint64_t cpu_int32_en;
100 1.2 matt
101 1.2 matt struct evcnt cpu_intr_evs[NIRQS];
102 1.2 matt
103 1.2 matt uint64_t cpu_int0_enable0;
104 1.2 matt uint64_t cpu_int1_enable0;
105 1.2 matt uint64_t cpu_int2_enable0;
106 1.2 matt
107 1.3 matt void *cpu_wdog_sih; // wdog softint handler
108 1.3 matt uint64_t cpu_wdog;
109 1.3 matt uint64_t cpu_pp_poke;
110 1.3 matt
111 1.2 matt #ifdef MULTIPROCESSOR
112 1.2 matt uint64_t cpu_mbox_set;
113 1.2 matt uint64_t cpu_mbox_clr;
114 1.2 matt #endif
115 1.2 matt };
116 1.2 matt
117 1.1 hikaru /*
118 1.1 hikaru * FPA map
119 1.1 hikaru */
120 1.1 hikaru
121 1.1 hikaru #define OCTEON_POOL_NO_PKT 0
122 1.1 hikaru #define OCTEON_POOL_NO_WQE 1
123 1.1 hikaru #define OCTEON_POOL_NO_CMD 2
124 1.1 hikaru #define OCTEON_POOL_NO_SG 3
125 1.1 hikaru #define OCTEON_POOL_NO_XXX_4 4
126 1.1 hikaru #define OCTEON_POOL_NO_XXX_5 5
127 1.1 hikaru #define OCTEON_POOL_NO_XXX_6 6
128 1.1 hikaru #define OCTEON_POOL_NO_DUMP 7 /* FPA debug dump */
129 1.1 hikaru
130 1.1 hikaru #define OCTEON_POOL_SIZE_PKT 2048 /* 128 x 16 */
131 1.1 hikaru #define OCTEON_POOL_SIZE_WQE 128 /* 128 x 1 */
132 1.1 hikaru #define OCTEON_POOL_SIZE_CMD 1024 /* 128 x 8 */
133 1.1 hikaru #define OCTEON_POOL_SIZE_SG 512 /* 128 x 4 */
134 1.1 hikaru #define OCTEON_POOL_SIZE_XXX_4 0
135 1.1 hikaru #define OCTEON_POOL_SIZE_XXX_5 0
136 1.1 hikaru #define OCTEON_POOL_SIZE_XXX_6 0
137 1.1 hikaru #define OCTEON_POOL_SIZE_XXX_7 0
138 1.1 hikaru
139 1.1 hikaru #define OCTEON_POOL_NELEMS_PKT 4096
140 1.1 hikaru #define OCTEON_POOL_NELEMS_WQE 4096
141 1.1 hikaru #define OCTEON_POOL_NELEMS_CMD 32
142 1.1 hikaru #define OCTEON_POOL_NELEMS_SG 1024
143 1.1 hikaru #define OCTEON_POOL_NELEMS_XXX_4 0
144 1.1 hikaru #define OCTEON_POOL_NELEMS_XXX_5 0
145 1.1 hikaru #define OCTEON_POOL_NELEMS_XXX_6 0
146 1.1 hikaru #define OCTEON_POOL_NELEMS_XXX_7 0
147 1.1 hikaru
148 1.1 hikaru /*
149 1.1 hikaru * CVMSEG (``scratch'') memory map
150 1.1 hikaru */
151 1.1 hikaru struct octeon_cvmseg_map {
152 1.1 hikaru /* 0-3 */
153 1.1 hikaru uint64_t csm_xxx_0;
154 1.1 hikaru uint64_t csm_xxx_1;
155 1.1 hikaru uint64_t csm_xxx_2;
156 1.1 hikaru uint64_t csm_pow_intr;
157 1.1 hikaru
158 1.1 hikaru /* 4-19 */
159 1.1 hikaru struct octeon_cvmseg_ether_map {
160 1.1 hikaru uint64_t csm_ether_fau_req;
161 1.1 hikaru uint64_t csm_ether_fau_done;
162 1.1 hikaru uint64_t csm_ether_fau_cmdptr;
163 1.1 hikaru uint64_t csm_ether_xxx_3;
164 1.1 hikaru } csm_ether[4/* XXX */];
165 1.1 hikaru
166 1.7 riastrad /* 20-31 */
167 1.1 hikaru uint64_t xxx_20_32[32 - 20];
168 1.7 riastrad
169 1.7 riastrad /* 32-63 */
170 1.7 riastrad uint64_t csm_rnm[32];
171 1.1 hikaru } __packed;
172 1.1 hikaru #define OCTEON_CVMSEG_OFFSET(entry) \
173 1.1 hikaru offsetof(struct octeon_cvmseg_map, entry)
174 1.1 hikaru #define OCTEON_CVMSEG_ETHER_OFFSET(n, entry) \
175 1.1 hikaru (offsetof(struct octeon_cvmseg_map, csm_ether) + \
176 1.1 hikaru sizeof(struct octeon_cvmseg_ether_map) * (n) + \
177 1.1 hikaru offsetof(struct octeon_cvmseg_ether_map, entry))
178 1.1 hikaru
179 1.1 hikaru /*
180 1.1 hikaru * FAU register map
181 1.1 hikaru *
182 1.1 hikaru * => FAU registers exist in FAU unit
183 1.1 hikaru * => devices (PKO) can access these registers
184 1.1 hikaru * => CPU can read those values after loading them into CVMSEG
185 1.1 hikaru */
186 1.8 simonb struct octfau_map {
187 1.1 hikaru struct {
188 1.1 hikaru /* PKO command index */
189 1.1 hikaru uint64_t _fau_map_port_pkocmdidx;
190 1.1 hikaru /* send requested */
191 1.1 hikaru uint64_t _fau_map_port_txreq;
192 1.1 hikaru /* send completed */
193 1.1 hikaru uint64_t _fau_map_port_txdone;
194 1.1 hikaru /* XXX */
195 1.1 hikaru uint64_t _fau_map_port_pad;
196 1.1 hikaru } __packed _fau_map_port[3];
197 1.1 hikaru };
198 1.1 hikaru
199 1.1 hikaru /*
200 1.1 hikaru * POW qos/group map
201 1.1 hikaru */
202 1.1 hikaru
203 1.1 hikaru #define OCTEON_POW_QOS_PIP 0
204 1.1 hikaru #define OCTEON_POW_QOS_CORE1 1
205 1.1 hikaru #define OCTEON_POW_QOS_XXX_2 2
206 1.1 hikaru #define OCTEON_POW_QOS_XXX_3 3
207 1.1 hikaru #define OCTEON_POW_QOS_XXX_4 4
208 1.1 hikaru #define OCTEON_POW_QOS_XXX_5 5
209 1.1 hikaru #define OCTEON_POW_QOS_XXX_6 6
210 1.1 hikaru #define OCTEON_POW_QOS_XXX_7 7
211 1.1 hikaru
212 1.1 hikaru #define OCTEON_POW_GROUP_PIP 0
213 1.1 hikaru #define OCTEON_POW_GROUP_XXX_1 1
214 1.1 hikaru #define OCTEON_POW_GROUP_XXX_2 2
215 1.1 hikaru #define OCTEON_POW_GROUP_XXX_3 3
216 1.1 hikaru #define OCTEON_POW_GROUP_XXX_4 4
217 1.1 hikaru #define OCTEON_POW_GROUP_XXX_5 5
218 1.1 hikaru #define OCTEON_POW_GROUP_XXX_6 6
219 1.1 hikaru #define OCTEON_POW_GROUP_CORE1_SEND 7
220 1.1 hikaru #define OCTEON_POW_GROUP_CORE1_TASK_0 8
221 1.1 hikaru #define OCTEON_POW_GROUP_CORE1_TASK_1 9
222 1.1 hikaru #define OCTEON_POW_GROUP_CORE1_TASK_2 10
223 1.1 hikaru #define OCTEON_POW_GROUP_CORE1_TASK_3 11
224 1.1 hikaru #define OCTEON_POW_GROUP_CORE1_TASK_4 12
225 1.1 hikaru #define OCTEON_POW_GROUP_CORE1_TASK_5 13
226 1.1 hikaru #define OCTEON_POW_GROUP_CORE1_TASK_6 14
227 1.1 hikaru #define OCTEON_POW_GROUP_CORE1_TASK_7 15
228 1.1 hikaru
229 1.1 hikaru #ifdef _KERNEL
230 1.1 hikaru extern struct octeon_config octeon_configuration;
231 1.2 matt #ifdef MULTIPROCESSOR
232 1.4 matt extern kcpuset_t *cpus_booted;
233 1.2 matt extern struct cpu_softc octeon_cpu1_softc;
234 1.2 matt #endif
235 1.1 hikaru
236 1.1 hikaru void octeon_bus_io_init(bus_space_tag_t, void *);
237 1.1 hikaru void octeon_bus_mem_init(bus_space_tag_t, void *);
238 1.1 hikaru void octeon_cal_timer(int);
239 1.1 hikaru void octeon_dma_init(struct octeon_config *);
240 1.2 matt void octeon_intr_init(struct cpu_info *);
241 1.1 hikaru void octeon_iointr(int, vaddr_t, uint32_t);
242 1.8 simonb void octpci_init(pci_chipset_tag_t, struct octeon_config *);
243 1.2 matt void *octeon_intr_establish(int, int, int (*)(void *), void *);
244 1.1 hikaru void octeon_intr_disestablish(void *cookie);
245 1.2 matt
246 1.5 matt void octeon_reset_vector(void);
247 1.2 matt uint64_t mips_cp0_cvmctl_read(void);
248 1.2 matt void mips_cp0_cvmctl_write(uint64_t);
249 1.2 matt
250 1.1 hikaru #endif /* _KERNEL */
251 1.1 hikaru
252 1.1 hikaru #if defined(__mips_n32)
253 1.1 hikaru #define ffs64 __builtin_ffsll
254 1.1 hikaru #elif defined(_LP64)
255 1.1 hikaru #define ffs64 __builtin_ffsl
256 1.1 hikaru #else
257 1.1 hikaru #error unknown ABI
258 1.1 hikaru #endif
259 1.1 hikaru
260 1.1 hikaru /*
261 1.1 hikaru * Prefetch
262 1.1 hikaru *
263 1.1 hikaru * OCTEON_PREF normal (L1 and L2)
264 1.1 hikaru * OCTEON_PREF_L1 L1 only
265 1.1 hikaru * OCTEON_PREF_L2 L2 only
266 1.1 hikaru * OCTEON_PREF_DWB don't write back
267 1.1 hikaru * OCTEON_PREF_PFS prepare for store
268 1.1 hikaru */
269 1.1 hikaru #define __OCTEON_PREF_N(n, base, offset) \
270 1.1 hikaru __asm __volatile ( \
271 1.1 hikaru " .set push \
272 1.1 hikaru " .set arch=octeon \n" \
273 1.1 hikaru " pref "#n", "#offset"(%[base]) \n" \
274 1.1 hikaru " .set pop \
275 1.1 hikaru : : [base] "d" (base) \
276 1.1 hikaru )
277 1.1 hikaru #define __OCTEON_PREF_0(base, offset) __OCTEON_PREF_N(0, base, offset)
278 1.1 hikaru #define __OCTEON_PREF_4(base, offset) __OCTEON_PREF_N(4, base, offset)
279 1.1 hikaru #define __OCTEON_PREF_28(base, offset) __OCTEON_PREF_N(28, base, offset)
280 1.1 hikaru #define __OCTEON_PREF_29(base, offset) __OCTEON_PREF_N(29, base, offset)
281 1.1 hikaru #define __OCTEON_PREF_30(base, offset) __OCTEON_PREF_N(30, base, offset)
282 1.1 hikaru #define OCTEON_PREF(base, offset) __OCTEON_PREF_0(base, offset)
283 1.1 hikaru #define OCTEON_PREF_L1(base, offset) __OCTEON_PREF_4(base, offset)
284 1.1 hikaru #define OCTEON_PREF_L2(base, offset) __OCTEON_PREF_28(base, offset)
285 1.1 hikaru #define OCTEON_PREF_DWB(base, offset) __OCTEON_PREF_29(base, offset)
286 1.1 hikaru #define OCTEON_PREF_PFS(base, offset) __OCTEON_PREF_30(base, offset)
287 1.1 hikaru
288 1.1 hikaru /*
289 1.1 hikaru * Sync
290 1.1 hikaru */
291 1.1 hikaru #define OCTEON_SYNCCOMMON(name) \
292 1.1 hikaru __asm __volatile ( \
293 1.1 hikaru _ASM_PROLOGUE_OCTEON \
294 1.1 hikaru " "#name" \n" \
295 1.1 hikaru _ASM_EPILOGUE \
296 1.1 hikaru ::: "memory")
297 1.1 hikaru #define OCTEON_SYNCIOBDMA OCTEON_SYNCCOMMON(synciobdma)
298 1.1 hikaru #define OCTEON_SYNCW OCTEON_SYNCCOMMON(syncw)
299 1.1 hikaru #define OCTEON_SYNC OCTEON_SYNCCOMMON(sync)
300 1.1 hikaru #define OCTEON_SYNCWS OCTEON_SYNCCOMMON(syncws)
301 1.1 hikaru #define OCTEON_SYNCS OCTEON_SYNCCOMMON(syncs)
302 1.1 hikaru /* XXX backward compatibility */
303 1.1 hikaru #if 1
304 1.1 hikaru #define OCT_SYNCIOBDMA OCTEON_SYNCIOBDMA
305 1.1 hikaru #define OCT_SYNCW OCTEON_SYNCW
306 1.1 hikaru #define OCT_SYNC OCTEON_SYNC
307 1.1 hikaru #define OCT_SYNCWS OCTEON_SYNCWS
308 1.1 hikaru #define OCT_SYNCS OCTEON_SYNCS
309 1.1 hikaru #endif
310 1.1 hikaru
311 1.1 hikaru /* octeon core does not use cca to determine cacheability */
312 1.1 hikaru #define OCTEON_CCA_NONE UINT64_C(0)
313 1.1 hikaru
314 1.6 christos static __inline uint64_t
315 1.1 hikaru octeon_xkphys_read_8(paddr_t address)
316 1.1 hikaru {
317 1.5 matt return mips3_ld(MIPS_PHYS_TO_XKPHYS(OCTEON_CCA_NONE, address));
318 1.1 hikaru }
319 1.1 hikaru
320 1.6 christos static __inline void
321 1.1 hikaru octeon_xkphys_write_8(paddr_t address, uint64_t value)
322 1.1 hikaru {
323 1.5 matt mips3_sd(MIPS_PHYS_TO_XKPHYS(OCTEON_CCA_NONE, address), value);
324 1.1 hikaru }
325 1.1 hikaru
326 1.1 hikaru /* XXX backward compatibility */
327 1.1 hikaru #if 1
328 1.1 hikaru #define octeon_read_csr(address) \
329 1.1 hikaru octeon_xkphys_read_8(address)
330 1.1 hikaru #define octeon_write_csr(address, value) \
331 1.1 hikaru octeon_xkphys_write_8(address, value)
332 1.1 hikaru #endif
333 1.1 hikaru
334 1.6 christos static __inline void
335 1.1 hikaru octeon_iobdma_write_8(uint64_t value)
336 1.1 hikaru {
337 1.1 hikaru uint64_t addr = UINT64_C(0xffffffffffffa200);
338 1.1 hikaru
339 1.1 hikaru octeon_xkphys_write_8(addr, value);
340 1.1 hikaru }
341 1.1 hikaru
342 1.6 christos static __inline uint64_t
343 1.1 hikaru octeon_cvmseg_read_8(size_t offset)
344 1.1 hikaru {
345 1.1 hikaru return octeon_xkphys_read_8(UINT64_C(0xffffffffffff8000) + offset);
346 1.1 hikaru }
347 1.1 hikaru
348 1.6 christos static __inline void
349 1.1 hikaru octeon_cvmseg_write_8(size_t offset, uint64_t value)
350 1.1 hikaru {
351 1.1 hikaru octeon_xkphys_write_8(UINT64_C(0xffffffffffff8000) + offset, value);
352 1.1 hikaru }
353 1.1 hikaru
354 1.1 hikaru /* XXX */
355 1.6 christos static __inline uint32_t
356 1.1 hikaru octeon_disable_interrupt(uint32_t *new)
357 1.1 hikaru {
358 1.1 hikaru uint32_t s, tmp;
359 1.1 hikaru
360 1.1 hikaru __asm __volatile (
361 1.1 hikaru _ASM_PROLOGUE
362 1.1 hikaru " mfc0 %[s], $12 \n"
363 1.1 hikaru " and %[tmp], %[s], ~1 \n"
364 1.1 hikaru " mtc0 %[tmp], $12 \n"
365 1.1 hikaru _ASM_EPILOGUE
366 1.1 hikaru : [s]"=&r"(s), [tmp]"=&r"(tmp));
367 1.1 hikaru if (new)
368 1.1 hikaru *new = tmp;
369 1.1 hikaru return s;
370 1.1 hikaru }
371 1.1 hikaru
372 1.1 hikaru /* XXX */
373 1.6 christos static __inline void
374 1.1 hikaru octeon_restore_status(uint32_t s)
375 1.1 hikaru {
376 1.1 hikaru __asm __volatile (
377 1.1 hikaru _ASM_PROLOGUE
378 1.1 hikaru " mtc0 %[s], $12 \n"
379 1.1 hikaru _ASM_EPILOGUE
380 1.1 hikaru :: [s]"r"(s));
381 1.1 hikaru }
382 1.1 hikaru
383 1.6 christos static __inline uint64_t
384 1.1 hikaru octeon_get_cycles(void)
385 1.1 hikaru {
386 1.1 hikaru #if defined(__mips_o32)
387 1.1 hikaru uint32_t s, lo, hi;
388 1.1 hikaru
389 1.1 hikaru s = octeon_disable_interrupt((void *)0);
390 1.1 hikaru __asm __volatile (
391 1.1 hikaru _ASM_PROLOGUE_MIPS64
392 1.1 hikaru " dmfc0 %[lo], $9, 6 \n"
393 1.1 hikaru " add %[hi], %[lo], $0 \n"
394 1.1 hikaru " srl %[hi], 32 \n"
395 1.1 hikaru " sll %[lo], 32 \n"
396 1.1 hikaru " srl %[lo], 32 \n"
397 1.1 hikaru _ASM_EPILOGUE
398 1.1 hikaru : [lo]"=&r"(lo), [hi]"=&r"(hi));
399 1.1 hikaru octeon_restore_status(s);
400 1.1 hikaru return ((uint64_t)hi << 32) + (uint64_t)lo;
401 1.1 hikaru #else
402 1.1 hikaru uint64_t tmp;
403 1.1 hikaru
404 1.1 hikaru __asm __volatile (
405 1.1 hikaru _ASM_PROLOGUE_MIPS64
406 1.1 hikaru " dmfc0 %[tmp], $9, 6 \n"
407 1.1 hikaru _ASM_EPILOGUE
408 1.1 hikaru : [tmp]"=&r"(tmp));
409 1.1 hikaru return tmp;
410 1.1 hikaru #endif
411 1.1 hikaru }
412 1.1 hikaru
413 1.1 hikaru /* -------------------------------------------------------------------------- */
414 1.1 hikaru
415 1.1 hikaru /* ---- event counter */
416 1.1 hikaru
417 1.8 simonb #if defined(CNMAC_DEBUG)
418 1.1 hikaru #define OCTEON_EVCNT_INC(sc, name) \
419 1.1 hikaru do { (sc)->sc_ev_##name.ev_count++; } while (0)
420 1.1 hikaru #define OCTEON_EVCNT_ADD(sc, name, n) \
421 1.1 hikaru do { (sc)->sc_ev_##name.ev_count += (n); } while (0)
422 1.1 hikaru #define OCTEON_EVCNT_ATTACH_EVCNTS(sc, entries, devname) \
423 1.1 hikaru do { \
424 1.1 hikaru int i; \
425 1.1 hikaru const struct octeon_evcnt_entry *ee; \
426 1.1 hikaru \
427 1.1 hikaru for (i = 0; i < (int)__arraycount(entries); i++) { \
428 1.1 hikaru ee = &(entries)[i]; \
429 1.1 hikaru evcnt_attach_dynamic( \
430 1.1 hikaru (struct evcnt *)((uintptr_t)(sc) + ee->ee_offset), \
431 1.1 hikaru ee->ee_type, ee->ee_parent, devname, \
432 1.1 hikaru ee->ee_name); \
433 1.1 hikaru } \
434 1.1 hikaru } while (0)
435 1.1 hikaru #else
436 1.1 hikaru #define OCTEON_EVCNT_INC(sc, name)
437 1.1 hikaru #define OCTEON_EVCNT_ADD(sc, name, n)
438 1.1 hikaru #define OCTEON_EVCNT_ATTACH_EVCNTS(sc, entries, devname)
439 1.1 hikaru #endif
440 1.1 hikaru
441 1.1 hikaru struct octeon_evcnt_entry {
442 1.1 hikaru size_t ee_offset;
443 1.1 hikaru int ee_type;
444 1.1 hikaru struct evcnt *ee_parent;
445 1.1 hikaru const char *ee_name;
446 1.1 hikaru };
447 1.1 hikaru
448 1.1 hikaru #define OCTEON_EVCNT_ENTRY(_sc_type, _var, _ev_type, _parent, _name) \
449 1.1 hikaru { \
450 1.1 hikaru .ee_offset = offsetof(_sc_type, sc_ev_##_var), \
451 1.1 hikaru .ee_type = EVCNT_TYPE_##_ev_type, \
452 1.1 hikaru .ee_parent = _parent, \
453 1.1 hikaru .ee_name = _name \
454 1.1 hikaru }
455 1.1 hikaru
456 1.1 hikaru #endif /* _MIPS_OCTEON_OCTEONVAR_H_ */
457