#ifndef _MIPS_OCTEON_OCTEONVAR_H_
#define _MIPS_OCTEON_OCTEONVAR_H_
#include <machine/bus.h>
#define _ASM_PROLOGUE \
" .set push \n" \
" .set noreorder \n"
#define _ASM_PROLOGUE_MIPS64 \
_ASM_PROLOGUE \
" .set mips64 \n"
#define _ASM_PROLOGUE_OCTEON \
_ASM_PROLOGUE \
" .set arch=octeon \n"
#define _ASM_EPILOGUE \
" .set pop \n"
#ifndef __BITS64_GET
#define __BITS64_GET(name, bits) \
(((uint64_t)(bits) & name) >> name##_SHIFT)
#endif
#ifndef __BITS64_SET
#define __BITS64_SET(name, subbits) \
(((uint64_t)(subbits) << name##_SHIFT) & name)
#endif
struct octeon_config {
bus_space_tag_t mc_iobus_bust;
bus_space_tag_t mc_bootbus_bust;
bus_dma_tag_t mc_iobus_dmat;
bus_dma_tag_t mc_bootbus_dmat;
};
#define GPIO_CONFIG_MD_OUTPUT_SEL_MASK (GPIO_CONFIG_MD0 | GPIO_CONFIG_MD1)
#define GPIO_CONFIG_MD_USB0_VBUS_CTRL GPIO_CONFIG_MD0
#define GPIO_CONFIG_MD_USB1_VBUS_CTRL GPIO_CONFIG_MD1
#define OCTEON_POOL_NO_PKT 0
#define OCTEON_POOL_NO_WQE 1
#define OCTEON_POOL_NO_CMD 2
#define OCTEON_POOL_NO_SG 3
#define OCTEON_POOL_NO_XXX_4 4
#define OCTEON_POOL_NO_XXX_5 5
#define OCTEON_POOL_NO_XXX_6 6
#define OCTEON_POOL_NO_DUMP 7
#define OCTEON_POOL_SIZE_PKT 1920
#define OCTEON_POOL_SIZE_WQE 128
#define OCTEON_POOL_SIZE_CMD 1024
#define OCTEON_POOL_SIZE_SG 128
#define OCTEON_POOL_SIZE_XXX_4 0
#define OCTEON_POOL_SIZE_XXX_5 0
#define OCTEON_POOL_SIZE_XXX_6 0
#define OCTEON_POOL_SIZE_XXX_7 0
#define OCTEON_POOL_NELEMS_PKT 4096
#define OCTEON_POOL_NELEMS_WQE 4096
#define OCTEON_POOL_NELEMS_CMD 32
#define OCTEON_POOL_NELEMS_SG 4096
#define OCTEON_POOL_NELEMS_XXX_4 0
#define OCTEON_POOL_NELEMS_XXX_5 0
#define OCTEON_POOL_NELEMS_XXX_6 0
#define OCTEON_POOL_NELEMS_XXX_7 0
struct octeon_cvmseg_map {
uint64_t csm_pow_intr;
struct octeon_cvmseg_ether_map {
uint64_t csm_ether_fau_done;
} csm_ether[12];
} __packed;
#define OCTEON_CVMSEG_OFFSET(entry) \
offsetof(struct octeon_cvmseg_map, entry)
#define OCTEON_CVMSEG_ETHER_OFFSET(n, entry) \
(offsetof(struct octeon_cvmseg_map, csm_ether) + \
sizeof(struct octeon_cvmseg_ether_map) * (n) + \
offsetof(struct octeon_cvmseg_ether_map, entry))
struct octeon_fau_map {
struct {
uint64_t _fau_map_port_pkocmdidx;
uint64_t _fau_map_port_txreq;
uint64_t _fau_map_port_txdone;
uint64_t _fau_map_port_pad;
} __packed _fau_map_port[3];
};
#define OCTEON_POW_QOS_PIP 0
#define OCTEON_POW_QOS_CORE1 1
#define OCTEON_POW_QOS_XXX_2 2
#define OCTEON_POW_QOS_XXX_3 3
#define OCTEON_POW_QOS_XXX_4 4
#define OCTEON_POW_QOS_XXX_5 5
#define OCTEON_POW_QOS_XXX_6 6
#define OCTEON_POW_QOS_XXX_7 7
#define OCTEON_POW_GROUP_MAX 16
enum cnmac_stat {
cnmac_stat_rx_toto_gmx,
cnmac_stat_rx_totp_gmx,
cnmac_stat_rx_toto_pip,
cnmac_stat_rx_totp_pip,
cnmac_stat_rx_h64,
cnmac_stat_rx_h127,
cnmac_stat_rx_h255,
cnmac_stat_rx_h511,
cnmac_stat_rx_h1023,
cnmac_stat_rx_h1518,
cnmac_stat_rx_hmax,
cnmac_stat_rx_bcast,
cnmac_stat_rx_mcast,
cnmac_stat_rx_qdpo,
cnmac_stat_rx_qdpp,
cnmac_stat_rx_fcs,
cnmac_stat_rx_frag,
cnmac_stat_rx_undersz,
cnmac_stat_rx_jabber,
cnmac_stat_rx_oversz,
cnmac_stat_rx_raw,
cnmac_stat_rx_bad,
cnmac_stat_rx_drop,
cnmac_stat_rx_ctl,
cnmac_stat_rx_dmac,
cnmac_stat_tx_toto,
cnmac_stat_tx_totp,
cnmac_stat_tx_hmin,
cnmac_stat_tx_h64,
cnmac_stat_tx_h127,
cnmac_stat_tx_h255,
cnmac_stat_tx_h511,
cnmac_stat_tx_h1023,
cnmac_stat_tx_h1518,
cnmac_stat_tx_hmax,
cnmac_stat_tx_bcast,
cnmac_stat_tx_mcast,
cnmac_stat_tx_coll,
cnmac_stat_tx_defer,
cnmac_stat_tx_scol,
cnmac_stat_tx_mcol,
cnmac_stat_tx_ctl,
cnmac_stat_tx_uflow,
cnmac_stat_count
};
#if defined(_KERNEL) || defined(_STANDALONE)
#define OCTEON_ARGV_MAX 64
enum octeon_board {
BOARD_UNKNOWN,
BOARD_CHECKPOINT_N100,
BOARD_CN3010_EVB_HS5,
BOARD_DLINK_DSR_500,
BOARD_NETGEAR_UTM25,
BOARD_RHINOLABS_UTM8,
BOARD_UBIQUITI_E100,
BOARD_UBIQUITI_E120,
BOARD_UBIQUITI_E200,
BOARD_UBIQUITI_E220,
BOARD_UBIQUITI_E300,
BOARD_UBIQUITI_E1000,
};
struct boot_desc {
uint32_t desc_ver;
uint32_t desc_size;
uint64_t stack_top;
uint64_t heap_start;
uint64_t heap_end;
uint64_t __unused17;
uint64_t __unused16;
uint32_t __unused18;
uint32_t __unused15;
uint32_t __unused14;
uint32_t argc;
uint32_t argv[OCTEON_ARGV_MAX];
uint32_t flags;
uint32_t core_mask;
uint32_t dram_size;
uint32_t phy_mem_desc_addr;
uint32_t debugger_flag_addr;
uint32_t eclock;
uint32_t __unused10;
uint32_t __unused9;
uint16_t __unused8;
uint8_t __unused7;
uint8_t __unused6;
uint16_t __unused5;
uint8_t __unused4;
uint8_t __unused3;
uint8_t __unused2[20];
uint8_t __unused1[6];
uint8_t __unused0;
uint64_t boot_info_addr;
};
struct boot_info {
uint32_t ver_major;
uint32_t ver_minor;
uint64_t stack_top;
uint64_t heap_start;
uint64_t heap_end;
uint64_t boot_desc_addr;
uint32_t exception_base_addr;
uint32_t stack_size;
uint32_t flags;
uint32_t core_mask;
uint32_t dram_size;
uint32_t phys_mem_desc_addr;
uint32_t debugger_flags_addr;
uint32_t eclock;
uint32_t dclock;
uint32_t __unused0;
uint16_t board_type;
uint8_t board_rev_major;
uint8_t board_rev_minor;
uint16_t __unused1;
uint8_t __unused2;
uint8_t __unused3;
char board_serial[20];
uint8_t mac_addr_base[6];
uint8_t mac_addr_count;
uint64_t cf_common_addr;
uint64_t cf_attr_addr;
uint64_t led_display_addr;
uint32_t dfaclock;
uint32_t config_flags;
uint64_t fdt_addr;
};
struct octeon_bootmem_desc {
uint32_t lock;
uint32_t flags;
uint64_t head_addr;
uint32_t major_version;
uint32_t minor_version;
uint64_t app_data_addr;
uint64_t app_data_size;
uint32_t named_block_num_blocks;
uint32_t named_block_name_len;
uint64_t named_block_array_addr;
};
struct octeon_bootmem_block {
uint64_t next;
uint64_t size;
};
extern enum octeon_board octeon_board;
extern struct boot_desc *octeon_boot_desc;
extern struct boot_info *octeon_boot_info;
#ifdef _KERNEL
#define BOOTINFO_CFG_FLAG_PCI_HOST (1ull << 0)
#define BOOTINFO_CFG_FLAG_PCI_TARGET (1ull << 1)
#define BOOTINFO_CFG_FLAG_DEBUG (1ull << 2)
#define BOOTINFO_CFG_FLAG_NO_MAGIC (1ull << 3)
#define BOOTMEM_BLOCK_ALIGN 16
#define BOOTMEM_BLOCK_MASK (BOOTMEM_BLOCK_ALIGN - 1)
#define BOOTMEM_BLOCK_MIN_SIZE 16
int bootmem_alloc_region(paddr_t, size_t);
void bootmem_free(paddr_t, size_t);
int octeon_ioclock_speed(void);
#endif
#endif
static inline uint64_t
octeon_xkphys_read_8(paddr_t address)
{
volatile uint64_t *p =
(volatile uint64_t *)(PHYS_TO_XKPHYS(address, CCA_NC));
return (*p);
}
#define MIO_BOOT_BIST_STAT 0x00011800000000f8ULL
static inline void
octeon_xkphys_write_8(paddr_t address, uint64_t value)
{
*(volatile uint64_t *)(PHYS_TO_XKPHYS(address, CCA_NC)) = value;
if (((address >> 40) & 0xfffff) == (0x118)) {
value = *(volatile uint64_t *)
(PHYS_TO_XKPHYS(MIO_BOOT_BIST_STAT, CCA_NC));
}
}
static inline void
octeon_iobdma_write_8(uint64_t value)
{
uint64_t addr = 0xffffffffffffa200ULL;
*(volatile uint64_t *)addr = value;
}
static inline void
octeon_lmtdma_write_8(off_t offset, uint64_t value)
{
*(volatile uint64_t *)(0xffffffffffffa400ULL + offset) = value;
}
static inline uint64_t
octeon_cvmseg_read_8(size_t offset)
{
return *(volatile uint64_t *)(0xffffffffffff8000ULL + offset);
}
static inline void
octeon_cvmseg_write_8(size_t offset, uint64_t value)
{
*(volatile uint64_t *)(0xffffffffffff8000ULL + offset) = value;
}
static inline uint32_t
octeon_get_coreid(void)
{
uint32_t coreid;
__asm volatile (
_ASM_PROLOGUE_OCTEON
" rdhwr %0, $0\n"
_ASM_EPILOGUE
: "=r" (coreid));
return coreid;
}
static inline uint64_t
octeon_get_cycles(void)
{
uint64_t tmp;
__asm volatile (
_ASM_PROLOGUE_MIPS64
" dmfc0 %[tmp], $9, 6 \n"
_ASM_EPILOGUE
: [tmp]"=&r"(tmp));
return tmp;
}
static inline uint64_t
octeon_get_cvmctl(void)
{
uint64_t tmp;
__asm volatile (
_ASM_PROLOGUE_OCTEON
" dmfc0 %[tmp], $9, 7 \n"
_ASM_EPILOGUE
: [tmp]"=r"(tmp));
return tmp;
}
static inline uint64_t
octeon_get_cvmmemctl(void)
{
uint64_t tmp;
__asm volatile (
_ASM_PROLOGUE_OCTEON
" dmfc0 %[tmp], $11, 7 \n"
_ASM_EPILOGUE
: [tmp]"=r"(tmp));
return tmp;
}
static inline void
octeon_set_cvmmemctl(uint64_t val)
{
__asm volatile (
_ASM_PROLOGUE_OCTEON
" dmtc0 %[tmp], $11, 7 \n"
_ASM_EPILOGUE
: : [tmp]"r"(val) : "memory");
}
static inline void
octeon_synciobdma(void)
{
__asm volatile (
_ASM_PROLOGUE_OCTEON
" synciobdma\n"
_ASM_EPILOGUE
: : : "memory");
}
#endif