/***********************license start*************** * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights * reserved. * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of Cavium Networks nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. * * * For any questions regarding licensing please contact marketing@caviumnetworks.com * ***********************license end**************************************/ /* * This product includes software developed by the University of * California, Berkeley and its contributors." */ /* $FreeBSD$ */ #ifndef __OCTEON_PCMAP_REGS_H__ #define __OCTEON_PCMAP_REGS_H__ #ifndef LOCORE /* * Utility inlines & macros */ #if defined(__mips_n64) #define oct_write64(a, v) (*(volatile uint64_t *)(a) = (uint64_t)(v)) #define oct_write8_x8(a, v) (*(volatile uint8_t *)(a) = (uint8_t)(v)) #define OCT_READ(n, t) \ static inline t oct_read ## n(uintptr_t a) \ { \ volatile t *p = (volatile t *)a; \ return (*p); \ } OCT_READ(8, uint8_t); OCT_READ(16, uint16_t); OCT_READ(32, uint32_t); OCT_READ(64, uint64_t); #elif defined(__mips_n32) || defined(__mips_o32) #if defined(__mips_n32) static inline void oct_write64 (uint64_t csr_addr, uint64_t val64) { __asm __volatile ( ".set push\n" ".set mips64\n" "sd %0, 0(%1)\n" ".set pop\n" : : "r"(val64), "r"(csr_addr)); } static inline void oct_write8_x8 (uint64_t csr_addr, uint8_t val8) { __asm __volatile ( ".set push\n" ".set mips64\n" "sb %0, 0(%1)\n" ".set pop\n" : : "r"(val8), "r"(csr_addr)); } #define OCT_READ(n, t, insn) \ static inline t oct_read ## n(uint64_t a) \ { \ uint64_t tmp; \ \ __asm __volatile ( \ ".set push\n" \ ".set mips64\n" \ insn "\t%0, 0(%1)\n" \ ".set pop\n" \ : "=r"(tmp) \ : "r"(a)); \ return ((t)tmp); \ } OCT_READ(8, uint8_t, "lb"); OCT_READ(16, uint16_t, "lh"); OCT_READ(32, uint32_t, "lw"); OCT_READ(64, uint64_t, "ld"); #else /* * XXX * Add o32 variants that load the address into a register and the result out * of a register properly, and simply disable interrupts before and after and * hope that we don't need to refill or modify the TLB to access the address. * I'd be a lot happier if csr_addr were a physical address and we mapped it * into XKPHYS here so that we could guarantee that interrupts were the only * kind of exception we needed to worry about. * * Also, some of this inline assembly is needlessly verbose. Oh, well. */ static inline void oct_write64 (uint64_t csr_addr, uint64_t val64) { uint32_t csr_addrh = csr_addr >> 32; uint32_t csr_addrl = csr_addr; uint32_t valh = val64 >> 32; uint32_t vall = val64; uint32_t tmp1; uint32_t tmp2; uint32_t tmp3; register_t sr; sr = intr_disable(); __asm __volatile ( ".set push\n" ".set mips64\n" ".set noreorder\n" ".set noat\n" "dsll %0, %3, 32\n" "dsll %1, %5, 32\n" "dsll %2, %4, 32\n" "dsrl %2, %2, 32\n" "or %0, %0, %2\n" "dsll %2, %6, 32\n" "dsrl %2, %2, 32\n" "or %1, %1, %2\n" "sd %0, 0(%1)\n" ".set pop\n" : "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3) : "r" (valh), "r" (vall), "r" (csr_addrh), "r" (csr_addrl)); intr_restore(sr); } static inline void oct_write8_x8 (uint64_t csr_addr, uint8_t val8) { uint32_t csr_addrh = csr_addr >> 32; uint32_t csr_addrl = csr_addr; uint32_t tmp1; uint32_t tmp2; register_t sr; sr = intr_disable(); __asm __volatile ( ".set push\n" ".set mips64\n" ".set noreorder\n" ".set noat\n" "dsll %0, %3, 32\n" "dsll %1, %4, 32\n" "dsrl %1, %1, 32\n" "or %0, %0, %1\n" "sb %2, 0(%0)\n" ".set pop\n" : "=&r" (tmp1), "=&r" (tmp2) : "r" (val8), "r" (csr_addrh), "r" (csr_addrl)); intr_restore(sr); } #define OCT_READ(n, t, insn) \ static inline t oct_read ## n(uint64_t csr_addr) \ { \ uint32_t csr_addrh = csr_addr >> 32; \ uint32_t csr_addrl = csr_addr; \ uint32_t tmp1, tmp2; \ register_t sr; \ \ sr = intr_disable(); \ \ __asm __volatile ( \ ".set push\n" \ ".set mips64\n" \ ".set noreorder\n" \ ".set noat\n" \ "dsll %1, %2, 32\n" \ "dsll %0, %3, 32\n" \ "dsrl %0, %0, 32\n" \ "or %1, %1, %0\n" \ "lb %1, 0(%1)\n" \ ".set pop\n" \ : "=&r" (tmp1), "=&r" (tmp2) \ : "r" (csr_addrh), "r" (csr_addrl)); \ \ intr_restore(sr); \ \ return ((t)tmp2); \ } OCT_READ(8, uint8_t, "lb"); OCT_READ(16, uint16_t, "lh"); OCT_READ(32, uint32_t, "lw"); static inline uint64_t oct_read64 (uint64_t csr_addr) { uint32_t csr_addrh = csr_addr >> 32; uint32_t csr_addrl = csr_addr; uint32_t valh; uint32_t vall; register_t sr; sr = intr_disable(); __asm __volatile ( ".set push\n" ".set mips64\n" ".set noreorder\n" ".set noat\n" "dsll %0, %2, 32\n" "dsll %1, %3, 32\n" "dsrl %1, %1, 32\n" "or %0, %0, %1\n" "ld %1, 0(%0)\n" "dsrl %0, %1, 32\n" "dsll %1, %1, 32\n" "dsrl %1, %1, 32\n" ".set pop\n" : "=&r" (valh), "=&r" (vall) : "r" (csr_addrh), "r" (csr_addrl)); intr_restore(sr); return ((uint64_t)valh << 32) | vall; } #endif #endif #define oct_write64_int64(a, v) (oct_write64(a, (int64_t)(v))) /* * Most write bus transactions are actually 64-bit on Octeon. */ static inline void oct_write8 (uint64_t csr_addr, uint8_t val8) { oct_write64(csr_addr, (uint64_t) val8); } static inline void oct_write16 (uint64_t csr_addr, uint16_t val16) { oct_write64(csr_addr, (uint64_t) val16); } static inline void oct_write32 (uint64_t csr_addr, uint32_t val32) { oct_write64(csr_addr, (uint64_t) val32); } #define oct_readint32(a) ((int32_t)oct_read32((a))) /* * octeon_machdep.c * * Direct to Board Support level. */ extern void octeon_led_write_char(int char_position, char val); extern void octeon_led_write_hexchar(int char_position, char hexval); extern void octeon_led_write_hex(uint32_t wl); extern void octeon_led_write_string(const char *str); extern void octeon_reset(void); extern void octeon_led_write_char0(char val); extern void octeon_led_run_wheel(int *pos, int led_position); extern void octeon_debug_symbol(void); extern void octeon_ciu_reset(void); extern int octeon_is_simulation(void); #endif /* LOCORE */ /* * EBT3000 LED Unit */ #define OCTEON_CHAR_LED_BASE_ADDR (0x1d020000 | (0x1ffffffffull << 31)) /* * Default FLASH device (physical) base address */ #define OCTEON_FLASH_BASE_ADDR (0x1d040000ull) #endif /* !OCTEON_PCMAP_REGS_H__ */