1 /* 2 * BSD LICENSE 3 * 4 * Copyright (C) Cavium Inc. 2017. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * * Neither the name of Cavium networks nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifndef __OCTEONTX_IO_H__ 34 #define __OCTEONTX_IO_H__ 35 36 #include <stddef.h> 37 #include <stdint.h> 38 39 #include <rte_io.h> 40 41 /* In Cavium OcteonTX SoC, all accesses to the device registers are 42 * implicitly strongly ordered. So, The relaxed version of IO operation is 43 * safe to use with out any IO memory barriers. 44 */ 45 #define octeontx_read64 rte_read64_relaxed 46 #define octeontx_write64 rte_write64_relaxed 47 48 /* ARM64 specific functions */ 49 #if defined(RTE_ARCH_ARM64) 50 #define octeontx_prefetch_store_keep(_ptr) ({\ 51 asm volatile("prfm pstl1keep, %a0\n" : : "p" (_ptr)); }) 52 53 #define octeontx_load_pair(val0, val1, addr) ({ \ 54 asm volatile( \ 55 "ldp %x[x0], %x[x1], [%x[p1]]" \ 56 :[x0]"=r"(val0), [x1]"=r"(val1) \ 57 :[p1]"r"(addr) \ 58 ); }) 59 60 #define octeontx_store_pair(val0, val1, addr) ({ \ 61 asm volatile( \ 62 "stp %x[x0], %x[x1], [%x[p1]]" \ 63 ::[x0]"r"(val0), [x1]"r"(val1), [p1]"r"(addr) \ 64 ); }) 65 #else /* Un optimized functions for building on non arm64 arch */ 66 67 #define octeontx_prefetch_store_keep(_ptr) do {} while (0) 68 69 #define octeontx_load_pair(val0, val1, addr) \ 70 do { \ 71 val0 = rte_read64(addr); \ 72 val1 = rte_read64(((uint8_t *)addr) + 8); \ 73 } while (0) 74 75 #define octeontx_store_pair(val0, val1, addr) \ 76 do { \ 77 rte_write64(val0, addr); \ 78 rte_write64(val1, (((uint8_t *)addr) + 8)); \ 79 } while (0) 80 #endif 81 82 #if defined(RTE_ARCH_ARM64) 83 /** 84 * Perform an atomic fetch-and-add operation. 85 */ 86 static inline uint64_t 87 octeontx_reg_ldadd_u64(void *addr, int64_t off) 88 { 89 uint64_t old_val; 90 91 __asm__ volatile( 92 " .cpu generic+lse\n" 93 " ldadd %1, %0, [%2]\n" 94 : "=r" (old_val) : "r" (off), "r" (addr) : "memory"); 95 96 return old_val; 97 } 98 99 /** 100 * Perform a LMTST operation - an atomic write of up to 128 byte to 101 * an I/O block that supports this operation type. 102 * 103 * @param lmtline_va is the address where LMTLINE is mapped 104 * @param ioreg_va is the virtual address of the device register 105 * @param cmdbuf is the array of peripheral commands to execute 106 * @param cmdsize is the number of 64-bit words in 'cmdbuf' 107 * 108 * @return N/A 109 */ 110 static inline void 111 octeontx_reg_lmtst(void *lmtline_va, void *ioreg_va, const uint64_t cmdbuf[], 112 uint64_t cmdsize) 113 { 114 uint64_t result; 115 uint64_t word_count; 116 uint64_t *lmtline = lmtline_va; 117 118 word_count = cmdsize; 119 120 do { 121 /* Copy commands to LMTLINE */ 122 for (result = 0; result < word_count; result += 2) { 123 lmtline[result + 0] = cmdbuf[result + 0]; 124 lmtline[result + 1] = cmdbuf[result + 1]; 125 } 126 127 /* LDEOR initiates atomic transfer to I/O device */ 128 __asm__ volatile( 129 " .cpu generic+lse\n" 130 " ldeor xzr, %0, [%1]\n" 131 : "=r" (result) : "r" (ioreg_va) : "memory"); 132 } while (!result); 133 } 134 135 #else 136 137 static inline uint64_t 138 octeontx_reg_ldadd_u64(void *addr, int64_t off) 139 { 140 RTE_SET_USED(addr); 141 RTE_SET_USED(off); 142 return 0; 143 } 144 145 static inline void 146 octeontx_reg_lmtst(void *lmtline_va, void *ioreg_va, const uint64_t cmdbuf[], 147 uint64_t cmdsize) 148 { 149 RTE_SET_USED(lmtline_va); 150 RTE_SET_USED(ioreg_va); 151 RTE_SET_USED(cmdbuf); 152 RTE_SET_USED(cmdsize); 153 } 154 155 #endif 156 #endif /* __OCTEONTX_IO_H__ */ 157