Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 284791
b: refs/heads/master
c: 66d2998
h: refs/heads/master
i:
  284789: 0c6c5e6
  284787: bb097e5
  284783: 709e99b
v: v3
  • Loading branch information
Jayachandran C authored and Ralf Baechle committed Dec 7, 2011
1 parent 7a9c0ac commit 388b668
Show file tree
Hide file tree
Showing 14 changed files with 235 additions and 231 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8da24631e60438631112e6fdd198ef62416ff14a
refs/heads/master: 66d29985fab8207b1b2c03ac34a2c294c5b47a30
26 changes: 23 additions & 3 deletions trunk/arch/mips/include/asm/netlogic/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,39 @@
/*
* Common SMP definitions
*/
#define RESET_VEC_PHYS 0x1fc00000
#define RESET_DATA_PHYS (RESET_VEC_PHYS + (1<<10))
#define BOOT_THREAD_MODE 0
#define BOOT_NMI_LOCK 4
#define BOOT_NMI_HANDLER 8

#ifndef __ASSEMBLY__
struct irq_desc;
extern struct plat_smp_ops nlm_smp_ops;
extern char nlm_reset_entry[], nlm_reset_entry_end[];
void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc);
void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc);
void nlm_smp_irq_init(void);
void prom_pre_boot_secondary_cpus(void);
void nlm_boot_secondary_cpus(void);
int nlm_wakeup_secondary_cpus(u32 wakeup_mask);
void nlm_boot_smp_nmi(void);
void nlm_rmiboot_preboot(void);

static inline void
nlm_set_nmi_handler(void *handler)
{
char *reset_data;

reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS);
*(int64_t *)(reset_data + BOOT_NMI_HANDLER) = (long)handler;
}

/*
* Misc.
*/
unsigned int nlm_get_cpu_frequency(void);

extern unsigned long nlm_common_ebase;
unsigned int nlm_get_cpu_frequency(void);
extern int nlm_threads_per_core;
extern uint32_t nlm_cpumask, nlm_coremask;
#endif
#endif /* _NETLOGIC_COMMON_H_ */
7 changes: 2 additions & 5 deletions trunk/arch/mips/include/asm/netlogic/xlp-hal/xlp.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,14 @@
#ifndef _NLM_HAL_XLP_H
#define _NLM_HAL_XLP_H

#define RESET_VEC_PHYS 0x1fc00000
#define RESET_DATA_PHYS (RESET_VEC_PHYS + (1<<10))
#define BOOT_THREAD_MODE 0

#define PIC_UART_0_IRQ 17
#define PIC_UART_1_IRQ 18

#ifndef __ASSEMBLY__

/* SMP support functions */
void nlm_boot_core0_siblings(void);
void xlp_boot_core0_siblings(void);
void xlp_wakeup_secondary_cpus(void);

void xlp_mmu_init(void);
void nlm_hal_init(void);
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/mips/include/asm/netlogic/xlr/xlr.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ struct uart_port;
unsigned int nlm_xlr_uart_in(struct uart_port *, int);
void nlm_xlr_uart_out(struct uart_port *, int, int);

/* SMP helpers */
void xlr_wakeup_secondary_cpus(void);

/* XLS B silicon "Rook" */
static inline unsigned int nlm_chip_is_xls_b(void)
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/mips/netlogic/common/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
obj-y += irq.o time.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SMP) += smp.o smpboot.o
obj-$(CONFIG_EARLY_PRINTK) += earlycons.o
75 changes: 73 additions & 2 deletions trunk/arch/mips/netlogic/common/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@

#if defined(CONFIG_CPU_XLP)
#include <asm/netlogic/xlp-hal/iomap.h>
#include <asm/netlogic/xlp-hal/xlp.h>
#include <asm/netlogic/xlp-hal/pic.h>
#elif defined(CONFIG_CPU_XLR)
#include <asm/netlogic/xlr/iomap.h>
#include <asm/netlogic/xlr/pic.h>
#include <asm/netlogic/xlr/xlr.h>
#else
#error "Unknown CPU"
#endif
Expand Down Expand Up @@ -125,10 +127,10 @@ void nlm_cpus_done(void)
* Boot all other cpus in the system, initialize them, and bring them into
* the boot function
*/
int nlm_cpu_unblock[NR_CPUS];
int nlm_cpu_ready[NR_CPUS];
unsigned long nlm_next_gp;
unsigned long nlm_next_sp;

cpumask_t phys_cpu_present_map;

void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
Expand All @@ -142,7 +144,7 @@ void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)

/* barrier */
__sync();
nlm_cpu_unblock[cpu] = 1;
nlm_pic_send_ipi(nlm_pic_base, cpu, 1, 1);
}

void __init nlm_smp_setup(void)
Expand Down Expand Up @@ -178,12 +180,81 @@ void __init nlm_smp_setup(void)
(unsigned long)cpu_possible_map.bits[0]);

pr_info("Detected %i Slave CPU(s)\n", num_cpus);
nlm_set_nmi_handler(nlm_boot_secondary_cpus);
}

void nlm_prepare_cpus(unsigned int max_cpus)
{
}

static int nlm_parse_cpumask(u32 cpu_mask)
{
uint32_t core0_thr_mask, core_thr_mask;
int threadmode, i;

core0_thr_mask = cpu_mask & 0xf;
switch (core0_thr_mask) {
case 1:
nlm_threads_per_core = 1;
threadmode = 0;
break;
case 3:
nlm_threads_per_core = 2;
threadmode = 2;
break;
case 0xf:
nlm_threads_per_core = 4;
threadmode = 3;
break;
default:
goto unsupp;
}

/* Verify other cores CPU masks */
nlm_coremask = 1;
nlm_cpumask = core0_thr_mask;
for (i = 1; i < 8; i++) {
core_thr_mask = (cpu_mask >> (i * 4)) & 0xf;
if (core_thr_mask) {
if (core_thr_mask != core0_thr_mask)
goto unsupp;
nlm_coremask |= 1 << i;
nlm_cpumask |= core0_thr_mask << (4 * i);
}
}
return threadmode;

unsupp:
panic("Unsupported CPU mask %x\n", cpu_mask);
return 0;
}

int __cpuinit nlm_wakeup_secondary_cpus(u32 wakeup_mask)
{
unsigned long reset_vec;
char *reset_data;
int threadmode;

/* Update reset entry point with CPU init code */
reset_vec = CKSEG1ADDR(RESET_VEC_PHYS);
memcpy((void *)reset_vec, (void *)nlm_reset_entry,
(nlm_reset_entry_end - nlm_reset_entry));

/* verify the mask and setup core config variables */
threadmode = nlm_parse_cpumask(wakeup_mask);

/* Setup CPU init parameters */
reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS);
*(int *)(reset_data + BOOT_THREAD_MODE) = threadmode;

#ifdef CONFIG_CPU_XLP
xlp_wakeup_secondary_cpus();
#else
xlr_wakeup_secondary_cpus();
#endif
return 0;
}

struct plat_smp_ops nlm_smp_ops = {
.send_ipi_single = nlm_send_ipi_single,
.send_ipi_mask = nlm_send_ipi_mask,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
#include <asm/asmmacro.h>
#include <asm/addrspace.h>

#include <asm/netlogic/common.h>

#include <asm/netlogic/xlp-hal/iomap.h>
#include <asm/netlogic/xlp-hal/xlp.h>
#include <asm/netlogic/xlp-hal/sys.h>
Expand All @@ -67,11 +69,37 @@
mtcr t1, t0
.endm

/*
* The cores can come start when they are woken up. This is also the NMI
* entry, so check that first.
*
* The data corresponding to reset is stored at RESET_DATA_PHYS location,
* this will have the thread mask (used when core is woken up) and the
* current NMI handler in case we reached here for an NMI.
*
* When a core or thread is newly woken up, it loops in a 'wait'. When
* the CPU really needs waking up, we send an NMI to it, with the NMI
* handler set to prom_boot_secondary_cpus
*/

.set noreorder
.set noat
.set arch=xlr /* for mfcr/mtcr, XLR is sufficient */

__CPUINIT
EXPORT(nlm_reset_entry)
FEXPORT(nlm_reset_entry)
dmtc0 k0, $22, 6
dmtc0 k1, $22, 7
mfc0 k0, CP0_STATUS
li k1, 0x80000
and k1, k0, k1
beqz k1, 1f /* go to real reset entry */
nop
li k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */
ld k0, BOOT_NMI_HANDLER(k1)
jr k0
nop

1: /* Entry point on core wakeup */
mfc0 t0, CP0_EBASE, 1
mfc0 t1, CP0_EBASE, 1
srl t1, 5
Expand Down Expand Up @@ -128,7 +156,7 @@ EXPORT(nlm_boot_siblings)
ehb
#endif

2: beqz v0, 3f
2: beqz v0, 4f
nop

/* setup status reg */
Expand All @@ -140,17 +168,22 @@ EXPORT(nlm_boot_siblings)
ori t1, ST0_KX
#endif
mtc0 t1, CP0_STATUS

/* SETUP TLBs for a mapped kernel here */
PTR_LA t0, prom_pre_boot_secondary_cpus
jalr t0
/* mark CPU ready */
PTR_LA t1, nlm_cpu_ready
sll v1, v0, 2
PTR_ADDU t1, v1
li t2, 1
sw t2, 0(t1)
/* Wait until NMI hits */
3: wait
j 3b
nop

/*
* For the boot CPU, we have to restore registers and
* return
*/
3: dmfc0 t0, $4, 2 /* restore SP from UserLocal */
4: dmfc0 t0, $4, 2 /* restore SP from UserLocal */
li t1, 0xfadebeef
dmtc0 t1, $4, 2 /* restore SP from UserLocal */
PTR_SUBU sp, t0, PT_SIZE
Expand All @@ -159,7 +192,7 @@ EXPORT(nlm_boot_siblings)
nop
EXPORT(nlm_reset_entry_end)

EXPORT(nlm_boot_core0_siblings) /* "Master" (n0c0t0) cpu starts from here */
FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */
__config_lsu
dmtc0 sp, $4, 2 /* SP saved in UserLocal */
SAVE_ALL
Expand All @@ -173,34 +206,11 @@ EXPORT(nlm_boot_core0_siblings) /* "Master" (n0c0t0) cpu starts from here */
/* call it */
jr t2
nop
__FINIT
/* not reached */

__CPUINIT
NESTED(prom_pre_boot_secondary_cpus, 16, sp)
.set mips64
mfc0 a0, CP0_EBASE, 1 /* read ebase */
andi a0, 0x3ff /* a0 has the processor_id() */
sll t0, a0, 2 /* offset in cpu array */

PTR_LA t1, nlm_cpu_ready /* mark CPU ready */
PTR_ADDU t1, t0
li t2, 1
sw t2, 0(t1)

PTR_LA t1, nlm_cpu_unblock
PTR_ADDU t1, t0
1: lw t2, 0(t1) /* wait till unblocked */
bnez t2, 2f
nop
nop
nop
nop
nop
nop
j 1b
nop

2: PTR_LA t1, nlm_next_sp
NESTED(nlm_boot_secondary_cpus, 16, sp)
PTR_LA t1, nlm_next_sp
PTR_L sp, 0(t1)
PTR_LA t1, nlm_next_gp
PTR_L gp, 0(t1)
Expand All @@ -213,5 +223,50 @@ NESTED(prom_pre_boot_secondary_cpus, 16, sp)
PTR_LA t0, smp_bootstrap
jr t0
nop
END(prom_pre_boot_secondary_cpus)
END(nlm_boot_secondary_cpus)
__FINIT

/*
* In case of RMIboot bootloader which is used on XLR boards, the CPUs
* be already woken up and waiting in bootloader code.
* This will get them out of the bootloader code and into linux. Needed
* because the bootloader area will be taken and initialized by linux.
*/
__CPUINIT
NESTED(nlm_rmiboot_preboot, 16, sp)
mfc0 t0, $15, 1 # read ebase
andi t0, 0x1f # t0 has the processor_id()
andi t2, t0, 0x3 # thread no
sll t0, 2 # offset in cpu array

PTR_LA t1, nlm_cpu_ready # mark CPU ready
PTR_ADDU t1, t0
li t3, 1
sw t3, 0(t1)

bnez t2, 1f # skip thread programming
nop # for non zero hw threads

/*
* MMU setup only for first thread in core
*/
li t0, 0x400
mfcr t1, t0
li t2, 6 # XLR thread mode mask
nor t3, t2, zero
and t2, t1, t2 # t2 - current thread mode
li v0, CKSEG1ADDR(RESET_DATA_PHYS)
lw v1, BOOT_THREAD_MODE(v0) # v1 - new thread mode
sll v1, 1
beq v1, t2, 1f # same as request value
nop # nothing to do */

and t2, t1, t3 # mask out old thread mode
or t1, t2, v1 # put in new value
mtcr t1, t0 # update core control

1: wait
j 1b
nop
END(nlm_rmiboot_preboot)
__FINIT
2 changes: 1 addition & 1 deletion trunk/arch/mips/netlogic/xlp/Makefile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
obj-y += setup.o platform.o nlm_hal.o
obj-$(CONFIG_SMP) += smpboot.o wakeup.o
obj-$(CONFIG_SMP) += wakeup.o
4 changes: 4 additions & 0 deletions trunk/arch/mips/netlogic/xlp/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@

unsigned long nlm_common_ebase = 0x0;

/* default to uniprocessor */
uint32_t nlm_coremask = 1, nlm_cpumask = 1;
int nlm_threads_per_core = 1;

static void nlm_linux_exit(void)
{
nlm_write_sys_reg(nlm_sys_base, SYS_CHIP_RESET, 1);
Expand Down
Loading

0 comments on commit 388b668

Please sign in to comment.