Index: head/sys/mips/malta/asm_malta.S =================================================================== --- head/sys/mips/malta/asm_malta.S (revision 305742) +++ head/sys/mips/malta/asm_malta.S (revision 305743) @@ -1,89 +1,90 @@ /*- * Copyright (c) 2016 Ruslan Bukin * All rights reserved. * * Portions of this software were developed by SRI International and the * University of Cambridge Computer Laboratory under DARPA/AFRL contract * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. * * Portions of this software were developed by the University of Cambridge * Computer Laboratory as part of the CTSRD Project, with support from the * UK Higher Education Innovation Fund (HEIF). * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #include #define VPECONF0_MVP (1 << 1) +#define VPECONF0_VPA (1 << 0) .set noreorder #ifdef SMP /* * This function must be implemented in assembly because it is called early * in AP boot without a valid stack. */ LEAF(platform_processor_id) .set push .set mips32r2 mfc0 v0, $15, 1 jr ra andi v0, 0x1f .set pop END(platform_processor_id) -LEAF(enable_mvp) +LEAF(malta_cpu_configure) .set push .set mips32r2 .set noat - li t2, (VPECONF0_MVP) + li t2, (VPECONF0_MVP | VPECONF0_VPA) move $1, t2 jr ra .word 0x41810000 | (1 << 11) | 2 # mttc0 t2, $1, 2 .set pop -END(enable_mvp) +END(malta_cpu_configure) /* * Called on APs to wait until they are told to launch. */ LEAF(malta_ap_wait) jal platform_processor_id nop 1: ll t0, malta_ap_boot bne v0, t0, 1b nop move t0, zero sc t0, malta_ap_boot beqz t0, 1b nop j mpentry nop END(malta_ap_wait) #endif Index: head/sys/mips/malta/malta_mp.c =================================================================== --- head/sys/mips/malta/malta_mp.c (revision 305742) +++ head/sys/mips/malta/malta_mp.c (revision 305743) @@ -1,226 +1,281 @@ /*- * Copyright (c) 2016 Ruslan Bukin * All rights reserved. * * Portions of this software were developed by SRI International and the * University of Cambridge Computer Laboratory under DARPA/AFRL contract * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. * * Portions of this software were developed by the University of Cambridge * Computer Laboratory as part of the CTSRD Project, with support from the * UK Higher Education Innovation Fund (HEIF). * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #define MALTA_MAXCPU 2 +#define VPECONF0_VPA (1 << 0) +#define MVPCONTROL_VPC (1 << 1) +#define TCSTATUS_A (1 << 13) unsigned malta_ap_boot = ~0; #define C_SW0 (1 << 8) #define C_SW1 (1 << 9) #define C_IRQ0 (1 << 10) #define C_IRQ1 (1 << 11) #define C_IRQ2 (1 << 12) #define C_IRQ3 (1 << 13) #define C_IRQ4 (1 << 14) #define C_IRQ5 (1 << 15) static inline void +evpe(void) +{ + __asm __volatile( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips32r2 \n" + " .word 0x41600021 # evpe \n" + " ehb \n" + " .set pop \n"); +} + +static inline void ehb(void) { __asm __volatile( " .set mips32r2 \n" " ehb \n" " .set mips0 \n"); } #define mttc0(rd, sel, val) \ ({ \ __asm __volatile( \ " .set push \n" \ " .set mips32r2 \n" \ " .set noat \n" \ " move $1, %0 \n" \ " .word 0x41810000 | (" #rd " << 11) | " #sel " \n" \ " .set pop \n" \ :: "r" (val)); \ }) #define mftc0(rt, sel) \ ({ \ unsigned long __res; \ __asm __volatile( \ " .set push \n" \ " .set mips32r2 \n" \ " .set noat \n" \ " .word 0x41000800 | (" #rt " << 16) | " #sel " \n" \ " move %0, $1 \n" \ " .set pop \n" \ : "=r" (__res)); \ __res; \ }) #define write_c0_register32(reg, sel, val) \ ({ \ __asm __volatile( \ " .set push \n" \ " .set mips32 \n" \ " mtc0 %0, $%1, %2 \n" \ " .set pop \n" \ :: "r" (val), "i" (reg), "i" (sel)); \ }) #define read_c0_register32(reg, sel) \ ({ \ uint32_t __retval; \ __asm __volatile( \ " .set push \n" \ " .set mips32 \n" \ " mfc0 %0, $%1, %2 \n" \ " .set pop \n" \ : "=r" (__retval) : "i" (reg), "i" (sel)); \ __retval; \ }) -void -platform_ipi_send(int cpuid) +static void +set_thread_context(int cpuid) { uint32_t reg; - /* - * Set thread context. - * Note this is not global, so we don't need lock. - */ reg = read_c0_register32(1, 1); reg &= ~(0xff); reg |= cpuid; write_c0_register32(1, 1, reg); ehb(); +} +void +platform_ipi_send(int cpuid) +{ + uint32_t reg; + + set_thread_context(cpuid); + /* Set cause */ reg = mftc0(13, 0); - mttc0(13, 0, (reg | C_SW1)); + reg |= (C_SW1); + mttc0(13, 0, reg); } void platform_ipi_clear(void) { uint32_t reg; reg = mips_rd_cause(); reg &= ~(C_SW1); mips_wr_cause(reg); } int platform_ipi_hardintr_num(void) { return (-1); } int platform_ipi_softintr_num(void) { return (1); } void platform_init_ap(int cpuid) { uint32_t clock_int_mask; uint32_t ipi_intr_mask; /* * Clear any pending IPIs. */ platform_ipi_clear(); /* * Unmask the clock and ipi interrupts. */ ipi_intr_mask = soft_int_mask(platform_ipi_softintr_num()); clock_int_mask = hard_int_mask(5); set_intr_mask(ipi_intr_mask | clock_int_mask); mips_wbflush(); } void platform_cpu_mask(cpuset_t *mask) { uint32_t i, m; CPU_ZERO(mask); for (i = 0, m = 1 ; i < MALTA_MAXCPU; i++, m <<= 1) CPU_SET(i, mask); } struct cpu_group * platform_smp_topo(void) { return (smp_topo_none()); } int platform_start_ap(int cpuid) { + uint32_t reg; int timeout; + + /* Enter into configuration */ + reg = read_c0_register32(0, 1); + reg |= (MVPCONTROL_VPC); + write_c0_register32(0, 1, reg); + + set_thread_context(cpuid); + + /* + * Hint: how to set entry point. + * reg = 0x80000000; + * mttc0(2, 3, reg); + */ + + /* Enable thread */ + reg = mftc0(2, 1); + reg |= (TCSTATUS_A); + mttc0(2, 1, reg); + + /* Unhalt CPU core */ + mttc0(2, 4, 0); + + /* Activate VPE */ + reg = mftc0(1, 2); + reg |= (VPECONF0_VPA); + mttc0(1, 2, reg); + + /* Out of configuration */ + reg = read_c0_register32(0, 1); + reg &= ~(MVPCONTROL_VPC); + write_c0_register32(0, 1, reg); + + evpe(); if (atomic_cmpset_32(&malta_ap_boot, ~0, cpuid) == 0) return (-1); printf("Waiting for cpu%d to start\n", cpuid); timeout = 100; do { DELAY(1000); if (atomic_cmpset_32(&malta_ap_boot, 0, ~0) != 0) { printf("CPU %d started\n", cpuid); return (0); } } while (timeout--); printf("CPU %d failed to start\n", cpuid); return (0); } Index: head/sys/mips/mips/locore.S =================================================================== --- head/sys/mips/mips/locore.S (revision 305742) +++ head/sys/mips/mips/locore.S (revision 305743) @@ -1,202 +1,202 @@ /* $OpenBSD: locore.S,v 1.18 1998/09/15 10:58:53 pefo Exp $ */ /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Digital Equipment Corporation and Ralph Campbell. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * Copyright (C) 1989 Digital Equipment Corporation. * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appears in all copies. * Digital Equipment Corporation makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/loMem.s, * v 1.1 89/07/11 17:55:04 nelson Exp SPRITE (DECWRL) * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsm.s, * v 9.2 90/01/29 18:00:39 shirriff Exp SPRITE (DECWRL) * from: Header: /sprite/src/kernel/vm/ds3100.md/vmPmaxAsm.s, * v 1.1 89/07/10 14:27:41 nelson Exp SPRITE (DECWRL) * * from: @(#)locore.s 8.5 (Berkeley) 1/4/94 * JNPR: locore.S,v 1.6.2.1 2007/08/29 12:24:49 girish * $FreeBSD$ */ /* * FREEBSD_DEVELOPERS_FIXME * The start routine below was written for a multi-core CPU * with each core being hyperthreaded. This serves as an example * for a complex CPU architecture. For a different CPU complex * please make necessary changes to read CPU-ID etc. * A clean solution would be to have a different locore file for * each CPU type. */ /* * Contains code that is the first executed at boot time plus * assembly language support routines. */ #include #include #include #include #include "assym.s" .data #ifdef YAMON GLOBAL(fenvp) .space 4 # Assumes mips32? Is that OK? #endif .set noreorder .text GLOBAL(btext) ASM_ENTRY(_start) VECTOR(_locore, unknown) /* UNSAFE TO USE a0..a3, need to preserve the args from boot loader */ mtc0 zero, MIPS_COP_0_CAUSE # Clear soft interrupts #if defined(CPU_CNMIPS) /* * t1: Bits to set explicitly: * Enable FPU */ /* Set these bits */ li t1, (MIPS_SR_COP_0_BIT | MIPS_SR_PX | MIPS_SR_KX | MIPS_SR_UX | MIPS_SR_SX | MIPS_SR_BEV) /* Reset these bits */ li t0, ~(MIPS_SR_DE | MIPS_SR_SR | MIPS_SR_ERL | MIPS_SR_EXL | MIPS_SR_INT_IE | MIPS_SR_COP_2_BIT) #elif defined (CPU_RMI) || defined (CPU_NLM) /* Set these bits */ li t1, (MIPS_SR_COP_2_BIT | MIPS_SR_COP_0_BIT | MIPS_SR_KX | MIPS_SR_UX) /* Reset these bits */ li t0, ~(MIPS_SR_BEV | MIPS_SR_SR | MIPS_SR_INT_IE) #else /* * t0: Bits to preserve if set: * Soft reset * Boot exception vectors (firmware-provided) */ li t0, (MIPS_SR_BEV | MIPS_SR_SR) /* * t1: Bits to set explicitly: * Enable FPU */ li t1, MIPS_SR_COP_1_BIT #ifdef __mips_n64 or t1, MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX #endif #endif /* * Read coprocessor 0 status register, clear bits not * preserved (namely, clearing interrupt bits), and set * bits we want to explicitly set. */ mfc0 t2, MIPS_COP_0_STATUS and t2, t0 or t2, t1 mtc0 t2, MIPS_COP_0_STATUS COP0_SYNC /* Make sure KSEG0 is cached */ li t0, MIPS_CCA_CACHED mtc0 t0, MIPS_COP_0_CONFIG COP0_SYNC /*xxximp * now that we pass a0...a3 to the platform_init routine, do we need * to stash this stuff here? */ #ifdef YAMON /* Save YAMON boot environment pointer */ sw a2, _C_LABEL(fenvp) #endif #if defined(CPU_CNMIPS) && defined(SMP) .set push .set mips32r2 rdhwr t2, $0 beqz t2, 1f nop j octeon_ap_wait nop .set pop 1: #endif #if defined(CPU_MALTA) && defined(SMP) .set push .set mips32r2 - jal enable_mvp + jal malta_cpu_configure nop jal platform_processor_id nop beqz v0, 1f nop j malta_ap_wait nop .set pop 1: #endif /* * Initialize stack and call machine startup. */ PTR_LA sp, _C_LABEL(pcpu_space) PTR_ADDU sp, (PAGE_SIZE * 2) - CALLFRAME_SIZ REG_S zero, CALLFRAME_RA(sp) # Zero out old ra for debugger REG_S zero, CALLFRAME_SP(sp) # Zero out old fp for debugger PTR_LA gp, _C_LABEL(_gp) /* Call the platform-specific startup code. */ jal _C_LABEL(platform_start) nop PTR_LA sp, _C_LABEL(thread0_st) PTR_L a0, TD_PCB(sp) REG_LI t0, ~7 and a0, a0, t0 PTR_SUBU sp, a0, CALLFRAME_SIZ jal _C_LABEL(mi_startup) # mi_startup(frame) sw zero, CALLFRAME_SIZ - 8(sp) # Zero out old fp for debugger PANIC("Startup failed!") VECTOR_END(_locore)