219d14fe5f
Executive is a library that can be used by standalone applications and kernels to abstract access to Octeon SoC and board-specific hardware and facilities. The FreeBSD port to Octeon will be updated to use this where possible.
402 lines
12 KiB
C
402 lines
12 KiB
C
/***********************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**************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
* @file
|
|
*
|
|
* interface to the low latency DRAM
|
|
*
|
|
* <hr>$Revision: 41586 $<hr>
|
|
*
|
|
*/
|
|
|
|
#ifndef __CVMX_LLM_H__
|
|
#define __CVMX_LLM_H__
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define ENABLE_DEPRECATED /* Set to enable the old 18/36 bit names */
|
|
|
|
typedef enum
|
|
{
|
|
CVMX_LLM_REPLICATION_NONE = 0,
|
|
CVMX_LLM_REPLICATION_2X = 1, // on both interfaces, or 2x if only one interface
|
|
CVMX_LLM_REPLICATION_4X = 2, // both interfaces, 2x, or 4x if only one interface
|
|
CVMX_LLM_REPLICATION_8X = 3, // both interfaces, 4x, or 8x if only one interface
|
|
} cvmx_llm_replication_t;
|
|
|
|
/**
|
|
* This structure defines the address used to the low-latency memory.
|
|
* This address format is used for both loads and stores.
|
|
*/
|
|
typedef union
|
|
{
|
|
uint64_t u64;
|
|
struct
|
|
{
|
|
uint64_t mbz :30;
|
|
cvmx_llm_replication_t repl : 2;
|
|
uint64_t address :32; // address<1:0> mbz, address<31:30> mbz
|
|
} s;
|
|
} cvmx_llm_address_t;
|
|
|
|
/**
|
|
* This structure defines the data format in the low-latency memory
|
|
*/
|
|
typedef union
|
|
{
|
|
uint64_t u64;
|
|
|
|
/**
|
|
* this format defines the format returned on a load
|
|
* a load returns the 32/36-bits in memory, plus xxor = even_parity(dat<35:0>)
|
|
* typically, dat<35> = parity(dat<34:0>), so the xor bit directly indicates parity error
|
|
* Note that the data field size is 36 bits on the 36XX/38XX, and 32 bits on the 31XX
|
|
*/
|
|
struct
|
|
{
|
|
uint64_t mbz1 :27;
|
|
uint64_t xxor : 1;
|
|
uint64_t mbz : 4;
|
|
uint64_t dat :32;
|
|
} cn31xx;
|
|
|
|
struct
|
|
{
|
|
uint64_t mbz :27;
|
|
uint64_t xxor : 1;
|
|
uint64_t dat :36;
|
|
} s;
|
|
|
|
/**
|
|
* This format defines what should be used if parity is desired. Hardware returns
|
|
* the XOR of all the bits in the 36/32 bit data word, so for parity software must use
|
|
* one of the data field bits as a parity bit.
|
|
*/
|
|
struct cn31xx_par_struct
|
|
{
|
|
uint64_t mbz :32;
|
|
uint64_t par : 1;
|
|
uint64_t dat :31;
|
|
} cn31xx_par;
|
|
struct cn38xx_par_struct
|
|
{
|
|
uint64_t mbz :28;
|
|
uint64_t par : 1;
|
|
uint64_t dat :35;
|
|
} cn38xx_par;
|
|
#if !OCTEON_IS_COMMON_BINARY()
|
|
#if CVMX_COMPILED_FOR(OCTEON_CN31XX)
|
|
struct cn31xx_par_struct spar;
|
|
#else
|
|
struct cn38xx_par_struct spar;
|
|
#endif
|
|
#endif
|
|
} cvmx_llm_data_t;
|
|
|
|
#define CVMX_LLM_NARROW_DATA_WIDTH ((CVMX_COMPILED_FOR(OCTEON_CN31XX)) ? 32 : 36)
|
|
|
|
/**
|
|
* Calculate the parity value of a number
|
|
*
|
|
* @param value
|
|
* @return parity value
|
|
*/
|
|
static inline uint64_t cvmx_llm_parity(uint64_t value)
|
|
{
|
|
uint64_t result;
|
|
CVMX_DPOP(result, value);
|
|
return result;
|
|
}
|
|
|
|
|
|
/**
|
|
* Calculate the ECC needed for 36b LLM mode
|
|
*
|
|
* @param value
|
|
* @return ECC value
|
|
*/
|
|
static inline int cvmx_llm_ecc(uint64_t value)
|
|
{
|
|
/* FIXME: This needs a re-write */
|
|
static const uint32_t ecc_code_29[7] = {
|
|
0x08962595,
|
|
0x112a4aaa,
|
|
0x024c934f,
|
|
0x04711c73,
|
|
0x0781e07c,
|
|
0x1801ff80,
|
|
0x1ffe0000};
|
|
uint64_t pop0, pop1, pop2, pop3, pop4, pop5, pop6;
|
|
|
|
pop0 = ecc_code_29[0];
|
|
pop1 = ecc_code_29[1];
|
|
pop2 = ecc_code_29[2];
|
|
pop0 &= value;
|
|
pop3 = ecc_code_29[3];
|
|
CVMX_DPOP(pop0, pop0);
|
|
pop4 = ecc_code_29[4];
|
|
pop1 &= value;
|
|
CVMX_DPOP(pop1, pop1);
|
|
pop2 &= value;
|
|
pop5 = ecc_code_29[5];
|
|
CVMX_DPOP(pop2, pop2);
|
|
pop6 = ecc_code_29[6];
|
|
pop3 &= value;
|
|
CVMX_DPOP(pop3, pop3);
|
|
pop4 &= value;
|
|
CVMX_DPOP(pop4, pop4);
|
|
pop5 &= value;
|
|
CVMX_DPOP(pop5, pop5);
|
|
pop6 &= value;
|
|
CVMX_DPOP(pop6, pop6);
|
|
|
|
return((pop6&1)<<6) | ((pop5&1)<<5) | ((pop4&1)<<4) | ((pop3&1)<<3) | ((pop2&1)<<2) | ((pop1&1)<<1) | (pop0&1);
|
|
}
|
|
|
|
|
|
#ifdef ENABLE_DEPRECATED
|
|
/* These macros are provided to provide compatibility with code that uses
|
|
** the old names for the llm access functions. The names were changed
|
|
** when support for the 31XX llm was added, as the widths differ between Octeon Models.
|
|
** The wide/narrow names are preferred, and should be used in all new code */
|
|
#define cvmx_llm_write36 cvmx_llm_write_narrow
|
|
#define cvmx_llm_read36 cvmx_llm_read_narrow
|
|
#define cvmx_llm_write64 cvmx_llm_write_wide
|
|
#define cvmx_llm_read64 cvmx_llm_read_wide
|
|
#endif
|
|
/**
|
|
* Write to LLM memory - 36 bit
|
|
*
|
|
* @param address Address in LLM to write. Consecutive writes increment the
|
|
* address by 4. The replication mode is also encoded in this
|
|
* address.
|
|
* @param value Value to write to LLM. Only the low 36 bits will be used.
|
|
* @param set Which of the two coprocessor 2 register sets to use for the
|
|
* write. May be used to get two outstanding LLM access at once
|
|
* per core. Range: 0-1
|
|
*/
|
|
static inline void cvmx_llm_write_narrow(cvmx_llm_address_t address, uint64_t value, int set)
|
|
{
|
|
cvmx_llm_data_t data;
|
|
data.s.mbz = 0;
|
|
|
|
if (cvmx_octeon_is_pass1())
|
|
data.s.dat = ((value & 0x3ffff) << 18) | ((value >> 18) & 0x3ffff);
|
|
else
|
|
data.s.dat = value;
|
|
|
|
data.s.xxor = 0;
|
|
|
|
if (set)
|
|
{
|
|
CVMX_MT_LLM_DATA(1, data.u64);
|
|
CVMX_MT_LLM_WRITE_ADDR_INTERNAL(1, address.u64);
|
|
}
|
|
else
|
|
{
|
|
CVMX_MT_LLM_DATA(0, data.u64);
|
|
CVMX_MT_LLM_WRITE_ADDR_INTERNAL(0, address.u64);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Write to LLM memory - 64 bit
|
|
*
|
|
* @param address Address in LLM to write. Consecutive writes increment the
|
|
* address by 8. The replication mode is also encoded in this
|
|
* address.
|
|
* @param value Value to write to LLM.
|
|
* @param set Which of the two coprocessor 2 register sets to use for the
|
|
* write. May be used to get two outstanding LLM access at once
|
|
* per core. Range: 0-1
|
|
*/
|
|
static inline void cvmx_llm_write_wide(cvmx_llm_address_t address, uint64_t value, int set)
|
|
{
|
|
if (cvmx_octeon_is_pass1())
|
|
{
|
|
cvmx_llm_write36(address, value & 0xfffffffffull, set);
|
|
address.s.address+=4;
|
|
cvmx_llm_write36(address, ((value>>36) & 0xfffffff) | (cvmx_llm_ecc(value) << 28), set);
|
|
}
|
|
else
|
|
{
|
|
if (set)
|
|
{
|
|
CVMX_MT_LLM_DATA(1, value);
|
|
CVMX_MT_LLM_WRITE64_ADDR_INTERNAL(1, address.u64);
|
|
}
|
|
else
|
|
{
|
|
CVMX_MT_LLM_DATA(0, value);
|
|
CVMX_MT_LLM_WRITE64_ADDR_INTERNAL(0, address.u64);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Read from LLM memory - 36 bit
|
|
*
|
|
* @param address Address in LLM to read. Consecutive reads increment the
|
|
* address by 4. The replication mode is also encoded in this
|
|
* address.
|
|
* @param set Which of the two coprocessor 2 register sets to use for the
|
|
* write. May be used to get two outstanding LLM access at once
|
|
* per core. Range: 0-1
|
|
* @return The lower 36 bits contain the result of the read
|
|
*/
|
|
static inline cvmx_llm_data_t cvmx_llm_read_narrow(cvmx_llm_address_t address, int set)
|
|
{
|
|
cvmx_llm_data_t value;
|
|
if (set)
|
|
{
|
|
CVMX_MT_LLM_READ_ADDR(1, address.u64);
|
|
CVMX_MF_LLM_DATA(1, value.u64);
|
|
}
|
|
else
|
|
{
|
|
CVMX_MT_LLM_READ_ADDR(0, address.u64);
|
|
CVMX_MF_LLM_DATA(0, value.u64);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
|
|
/**
|
|
* Read from LLM memory - 64 bit
|
|
*
|
|
* @param address Address in LLM to read. Consecutive reads increment the
|
|
* address by 8. The replication mode is also encoded in this
|
|
* address.
|
|
* @param set Which of the two coprocessor 2 register sets to use for the
|
|
* write. May be used to get two outstanding LLM access at once
|
|
* per core. Range: 0-1
|
|
* @return The result of the read
|
|
*/
|
|
static inline uint64_t cvmx_llm_read_wide(cvmx_llm_address_t address, int set)
|
|
{
|
|
uint64_t value;
|
|
if (set)
|
|
{
|
|
CVMX_MT_LLM_READ64_ADDR(1, address);
|
|
CVMX_MF_LLM_DATA(1, value);
|
|
}
|
|
else
|
|
{
|
|
CVMX_MT_LLM_READ64_ADDR(0, address);
|
|
CVMX_MF_LLM_DATA(0, value);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
|
|
#define RLD_INIT_DELAY (1<<18)
|
|
|
|
|
|
|
|
/* This structure describes the RLDRAM configuration for a board. This structure
|
|
** must be populated with the correct values and passed to the initialization function.
|
|
*/
|
|
typedef struct
|
|
{
|
|
uint32_t cpu_hz; /* CPU frequency in Hz */
|
|
char addr_rld0_fb_str [100]; /* String describing RLDRAM connections on rld 0 front (0) bunk*/
|
|
char addr_rld0_bb_str [100]; /* String describing RLDRAM connections on rld 0 back (1) bunk*/
|
|
char addr_rld1_fb_str [100]; /* String describing RLDRAM connections on rld 1 front (0) bunk*/
|
|
char addr_rld1_bb_str [100]; /* String describing RLDRAM connections on rld 1 back (1) bunk*/
|
|
uint8_t rld0_bunks; /* Number of bunks on rld 0 (0 is disabled) */
|
|
uint8_t rld1_bunks; /* Number of bunks on rld 1 (0 is disabled) */
|
|
uint16_t rld0_mbytes; /* mbytes on rld 0 */
|
|
uint16_t rld1_mbytes; /* mbytes on rld 1 */
|
|
uint16_t max_rld_clock_mhz; /* Maximum RLD clock in MHz, only used for CN58XX */
|
|
} llm_descriptor_t;
|
|
|
|
/**
|
|
* Initialize LLM memory controller. This must be done
|
|
* before the low latency memory can be used.
|
|
* This is simply a wrapper around cvmx_llm_initialize_desc(),
|
|
* and is deprecated.
|
|
*
|
|
* @return -1 on error
|
|
* 0 on success
|
|
*/
|
|
int cvmx_llm_initialize(void);
|
|
|
|
|
|
/**
|
|
* Initialize LLM memory controller. This must be done
|
|
* before the low latency memory can be used.
|
|
*
|
|
* @param llm_desc_ptr
|
|
* Pointer to descriptor structure. If NULL
|
|
* is passed, a default setting is used if available.
|
|
*
|
|
* @return -1 on error
|
|
* Size of llm in bytes on success
|
|
*/
|
|
int cvmx_llm_initialize_desc(llm_descriptor_t *llm_desc_ptr);
|
|
|
|
|
|
|
|
/**
|
|
* Gets the default llm descriptor for the board code is being run on.
|
|
*
|
|
* @param llm_desc_ptr
|
|
* Pointer to descriptor structure to be filled in. Contents are only
|
|
* valid after successful completion. Must not be NULL.
|
|
*
|
|
* @return -1 on error
|
|
* 0 on success
|
|
*/
|
|
int cvmx_llm_get_default_descriptor(llm_descriptor_t *llm_desc_ptr);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* __CVM_LLM_H__ */
|