Skip to content

Commit

Permalink
MIPS: Netlogic: Support for XLR/XLS Fast Message Network
Browse files Browse the repository at this point in the history
On XLR/XLS, the cpu cores communicate with fast on-chip devices
(e.g. network accelerator, security engine etc.) using the Fast
Messaging Network(FMN). The FMN queues and credits needs to be
configured and intialized before it can be used.

The co-processor 2 on XLR/XLS CPU cores has registers for FMN access,
and the XLR/XLS has custom instructions for sending and loading
messages.  The FMN can deliver also per-cpu interrupts when messages
are available at the CPU.

This patch adds FMN initialization, adds interrupt setup and handling,
and also provides support for sending and receiving FMN messages.

Signed-off-by: Ganesan Ramalingam <ganesanr@broadcom.com>
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
Patchwork: http://patchwork.linux-mips.org/patch/4468
Signed-off-by: John Crispin <blogic@openwrt.org>
  • Loading branch information
Ganesan Ramalingam authored and John Crispin committed Nov 9, 2012
1 parent 3854174 commit ed21cfe
Show file tree
Hide file tree
Showing 12 changed files with 1,020 additions and 12 deletions.
1 change: 1 addition & 0 deletions arch/mips/include/asm/netlogic/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ void nlm_smp_irq_init(int hwcpuid);
void nlm_boot_secondary_cpus(void);
int nlm_wakeup_secondary_cpus(void);
void nlm_rmiboot_preboot(void);
void nlm_percpu_init(int hwcpuid);

static inline void
nlm_set_nmi_handler(void *handler)
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/include/asm/netlogic/interrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

#define IRQ_IPI_SMP_FUNCTION 3
#define IRQ_IPI_SMP_RESCHEDULE 4
#define IRQ_MSGRING 6
#define IRQ_FMN 5
#define IRQ_TIMER 7

#endif
137 changes: 137 additions & 0 deletions arch/mips/include/asm/netlogic/mips-extns.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,141 @@ static inline int nlm_nodeid(void)
return (__read_32bit_c0_register($15, 1) >> 5) & 0x3;
}

static inline unsigned int nlm_core_id(void)
{
return (read_c0_ebase() & 0x1c) >> 2;
}

static inline unsigned int nlm_thread_id(void)
{
return read_c0_ebase() & 0x3;
}

#define __read_64bit_c2_split(source, sel) \
({ \
unsigned long long __val; \
unsigned long __flags; \
\
local_irq_save(__flags); \
if (sel == 0) \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dmfc2\t%M0, " #source "\n\t" \
"dsll\t%L0, %M0, 32\n\t" \
"dsra\t%M0, %M0, 32\n\t" \
"dsra\t%L0, %L0, 32\n\t" \
".set\tmips0\n\t" \
: "=r" (__val)); \
else \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dmfc2\t%M0, " #source ", " #sel "\n\t" \
"dsll\t%L0, %M0, 32\n\t" \
"dsra\t%M0, %M0, 32\n\t" \
"dsra\t%L0, %L0, 32\n\t" \
".set\tmips0\n\t" \
: "=r" (__val)); \
local_irq_restore(__flags); \
\
__val; \
})

#define __write_64bit_c2_split(source, sel, val) \
do { \
unsigned long __flags; \
\
local_irq_save(__flags); \
if (sel == 0) \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dsll\t%L0, %L0, 32\n\t" \
"dsrl\t%L0, %L0, 32\n\t" \
"dsll\t%M0, %M0, 32\n\t" \
"or\t%L0, %L0, %M0\n\t" \
"dmtc2\t%L0, " #source "\n\t" \
".set\tmips0\n\t" \
: : "r" (val)); \
else \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dsll\t%L0, %L0, 32\n\t" \
"dsrl\t%L0, %L0, 32\n\t" \
"dsll\t%M0, %M0, 32\n\t" \
"or\t%L0, %L0, %M0\n\t" \
"dmtc2\t%L0, " #source ", " #sel "\n\t" \
".set\tmips0\n\t" \
: : "r" (val)); \
local_irq_restore(__flags); \
} while (0)

#define __read_32bit_c2_register(source, sel) \
({ uint32_t __res; \
if (sel == 0) \
__asm__ __volatile__( \
".set\tmips32\n\t" \
"mfc2\t%0, " #source "\n\t" \
".set\tmips0\n\t" \
: "=r" (__res)); \
else \
__asm__ __volatile__( \
".set\tmips32\n\t" \
"mfc2\t%0, " #source ", " #sel "\n\t" \
".set\tmips0\n\t" \
: "=r" (__res)); \
__res; \
})

#define __read_64bit_c2_register(source, sel) \
({ unsigned long long __res; \
if (sizeof(unsigned long) == 4) \
__res = __read_64bit_c2_split(source, sel); \
else if (sel == 0) \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dmfc2\t%0, " #source "\n\t" \
".set\tmips0\n\t" \
: "=r" (__res)); \
else \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dmfc2\t%0, " #source ", " #sel "\n\t" \
".set\tmips0\n\t" \
: "=r" (__res)); \
__res; \
})

#define __write_64bit_c2_register(register, sel, value) \
do { \
if (sizeof(unsigned long) == 4) \
__write_64bit_c2_split(register, sel, value); \
else if (sel == 0) \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dmtc2\t%z0, " #register "\n\t" \
".set\tmips0\n\t" \
: : "Jr" (value)); \
else \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dmtc2\t%z0, " #register ", " #sel "\n\t" \
".set\tmips0\n\t" \
: : "Jr" (value)); \
} while (0)

#define __write_32bit_c2_register(reg, sel, value) \
({ \
if (sel == 0) \
__asm__ __volatile__( \
".set\tmips32\n\t" \
"mtc2\t%z0, " #reg "\n\t" \
".set\tmips0\n\t" \
: : "Jr" (value)); \
else \
__asm__ __volatile__( \
".set\tmips32\n\t" \
"mtc2\t%z0, " #reg ", " #sel "\n\t" \
".set\tmips0\n\t" \
: : "Jr" (value)); \
})

#endif /*_ASM_NLM_MIPS_EXTS_H */
Loading

0 comments on commit ed21cfe

Please sign in to comment.