octeon_mp.c revision 216946
1206721Sjmallett/*- 2206721Sjmallett * Copyright (c) 2004-2010 Juli Mallett <jmallett@FreeBSD.org> 3206721Sjmallett * All rights reserved. 4206721Sjmallett * 5206721Sjmallett * Redistribution and use in source and binary forms, with or without 6206721Sjmallett * modification, are permitted provided that the following conditions 7206721Sjmallett * are met: 8206721Sjmallett * 1. Redistributions of source code must retain the above copyright 9206721Sjmallett * notice, this list of conditions and the following disclaimer. 10206721Sjmallett * 2. Redistributions in binary form must reproduce the above copyright 11206721Sjmallett * notice, this list of conditions and the following disclaimer in the 12206721Sjmallett * documentation and/or other materials provided with the distribution. 13206721Sjmallett * 14206721Sjmallett * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15206721Sjmallett * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16206721Sjmallett * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17206721Sjmallett * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18206721Sjmallett * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19206721Sjmallett * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20206721Sjmallett * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21206721Sjmallett * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22206721Sjmallett * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23206721Sjmallett * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24206721Sjmallett * SUCH DAMAGE. 25206721Sjmallett * 26206721Sjmallett * $FreeBSD: head/sys/mips/cavium/octeon_mp.c 216946 2011-01-04 02:11:03Z jmallett $ 27206721Sjmallett */ 28206721Sjmallett#include <sys/cdefs.h> 29206721Sjmallett__FBSDID("$FreeBSD: head/sys/mips/cavium/octeon_mp.c 216946 2011-01-04 02:11:03Z jmallett $"); 30206721Sjmallett 31206721Sjmallett#include <sys/param.h> 32206721Sjmallett#include <sys/conf.h> 33206721Sjmallett#include <sys/kernel.h> 34210311Sjmallett#include <sys/smp.h> 35206721Sjmallett#include <sys/systm.h> 36206721Sjmallett 37206721Sjmallett#include <machine/hwfunc.h> 38210311Sjmallett#include <machine/md_var.h> 39206721Sjmallett#include <machine/smp.h> 40206721Sjmallett 41206721Sjmallett#include <mips/cavium/octeon_pcmap_regs.h> 42206721Sjmallett 43210311Sjmallett#include <contrib/octeon-sdk/cvmx.h> 44210311Sjmallett#include <contrib/octeon-sdk/cvmx-interrupt.h> 45210311Sjmallett 46210311Sjmallett/* XXX */ 47210311Sjmallettextern cvmx_bootinfo_t *octeon_bootinfo; 48210311Sjmallett 49206721Sjmallettunsigned octeon_ap_boot = ~0; 50206721Sjmallett 51206721Sjmallettvoid 52206721Sjmallettplatform_ipi_send(int cpuid) 53206721Sjmallett{ 54210311Sjmallett cvmx_write_csr(CVMX_CIU_MBOX_SETX(cpuid), 1); 55206721Sjmallett mips_wbflush(); 56206721Sjmallett} 57206721Sjmallett 58206721Sjmallettvoid 59206721Sjmallettplatform_ipi_clear(void) 60206721Sjmallett{ 61206721Sjmallett uint64_t action; 62206721Sjmallett 63210311Sjmallett action = cvmx_read_csr(CVMX_CIU_MBOX_CLRX(PCPU_GET(cpuid))); 64206721Sjmallett KASSERT(action == 1, ("unexpected IPIs: %#jx", (uintmax_t)action)); 65210311Sjmallett cvmx_write_csr(CVMX_CIU_MBOX_CLRX(PCPU_GET(cpuid)), action); 66206721Sjmallett} 67206721Sjmallett 68206721Sjmallettint 69206721Sjmallettplatform_ipi_intrnum(void) 70206721Sjmallett{ 71206721Sjmallett return (1); 72206721Sjmallett} 73206721Sjmallett 74206721Sjmallettvoid 75206721Sjmallettplatform_init_ap(int cpuid) 76206721Sjmallett{ 77216946Sjmallett unsigned ciu_int_mask, clock_int_mask, ipi_int_mask; 78210311Sjmallett 79206721Sjmallett /* 80206721Sjmallett * Set the exception base. 81206721Sjmallett */ 82216946Sjmallett mips_wr_ebase(0x80000000); 83206721Sjmallett 84206721Sjmallett /* 85210311Sjmallett * Clear any pending IPIs. 86206721Sjmallett */ 87210311Sjmallett cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cpuid), 0xffffffff); 88210311Sjmallett 89210311Sjmallett /* 90210311Sjmallett * Set up interrupts. 91210311Sjmallett */ 92206721Sjmallett octeon_ciu_reset(); 93206721Sjmallett 94210311Sjmallett /* 95216946Sjmallett * Unmask the clock, ipi and ciu interrupts. 96210311Sjmallett */ 97216946Sjmallett ciu_int_mask = hard_int_mask(0); 98210311Sjmallett clock_int_mask = hard_int_mask(5); 99210311Sjmallett ipi_int_mask = hard_int_mask(platform_ipi_intrnum()); 100216946Sjmallett set_intr_mask(ciu_int_mask | clock_int_mask | ipi_int_mask); 101206721Sjmallett 102206721Sjmallett mips_wbflush(); 103206721Sjmallett} 104206721Sjmallett 105206721Sjmallettint 106206721Sjmallettplatform_num_processors(void) 107206721Sjmallett{ 108210311Sjmallett return (bitcount32(octeon_bootinfo->core_mask)); 109206721Sjmallett} 110206721Sjmallett 111210311Sjmallettstruct cpu_group * 112210311Sjmallettplatform_smp_topo(void) 113210311Sjmallett{ 114210311Sjmallett return (smp_topo_none()); 115210311Sjmallett} 116210311Sjmallett 117206721Sjmallettint 118206721Sjmallettplatform_start_ap(int cpuid) 119206721Sjmallett{ 120206721Sjmallett if (atomic_cmpset_32(&octeon_ap_boot, ~0, cpuid) == 0) 121206721Sjmallett return (-1); 122206721Sjmallett for (;;) { 123206721Sjmallett DELAY(1000); 124206721Sjmallett if (atomic_cmpset_32(&octeon_ap_boot, 0, ~0) != 0) 125206721Sjmallett return (0); 126206721Sjmallett printf("Waiting for cpu%d to start\n", cpuid); 127206721Sjmallett } 128206721Sjmallett} 129