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) \ 60static inline t oct_read ## n(uintptr_t a) \ 61{ \ 62 volatile t *p = (volatile t *)a; \ 63 return (*p); \ 64} 65 66OCT_READ(8, uint8_t); 67OCT_READ(16, uint16_t); 68OCT_READ(32, uint32_t); 69OCT_READ(64, uint64_t); 70 71#elif defined(__mips_n32) || defined(__mips_o32) 72#if defined(__mips_n32) 73static 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 84static 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) \ 96static 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 110OCT_READ(8, uint8_t, "lb"); 111OCT_READ(16, uint16_t, "lh"); 112OCT_READ(32, uint32_t, "lw"); 113OCT_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 */ 127static 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 161static 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) \ 189static 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 217OCT_READ(8, uint8_t, "lb"); 218OCT_READ(16, uint16_t, "lh"); 219OCT_READ(32, uint32_t, "lw"); 220 221static 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 */ 261static inline void oct_write8 (uint64_t csr_addr, uint8_t val8) 262{ 263 oct_write64(csr_addr, (uint64_t) val8); 264} 265 266static inline void oct_write16 (uint64_t csr_addr, uint16_t val16) 267{ 268 oct_write64(csr_addr, (uint64_t) val16); 269} 270 271static 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 */ 283extern void octeon_led_write_char(int char_position, char val); 284extern void octeon_led_write_hexchar(int char_position, char hexval); 285extern void octeon_led_write_hex(uint32_t wl); 286extern void octeon_led_write_string(const char *str); 287extern void octeon_reset(void); 288extern void octeon_led_write_char0(char val); 289extern void octeon_led_run_wheel(int *pos, int led_position); 290extern void octeon_debug_symbol(void); 291extern void octeon_ciu_reset(void); 292extern 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__ */ 301