Home | History | Annotate | Line # | Download | only in prep
      1 /*	$NetBSD: cpu.c,v 1.18 2011/07/01 20:52:02 dyoung Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by NONAKA Kimihiro.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.18 2011/07/01 20:52:02 dyoung Exp $");
     34 
     35 #include <sys/param.h>
     36 #include <sys/systm.h>
     37 #include <sys/device.h>
     38 
     39 #include <machine/autoconf.h>
     40 #include <sys/bus.h>
     41 #include <machine/cpu.h>
     42 #include <machine/platform.h>
     43 
     44 #ifdef MULTIPROCESSOR
     45 #include <arch/powerpc/pic/picvar.h>
     46 #include <arch/powerpc/pic/ipivar.h>
     47 #include <powerpc/openpic.h>
     48 #include <powerpc/trap.h>
     49 
     50 extern void openpic_set_priority(int, int);
     51 #endif
     52 
     53 int cpumatch(device_t, cfdata_t, void *);
     54 void cpuattach(device_t, device_t, void *);
     55 
     56 CFATTACH_DECL_NEW(cpu, 0,
     57     cpumatch, cpuattach, NULL, NULL);
     58 
     59 extern struct cfdriver cpu_cd;
     60 
     61 int
     62 cpumatch(device_t parent, cfdata_t cfdata, void *aux)
     63 {
     64 	struct confargs *ca = aux;
     65 
     66 	if (strcmp(ca->ca_name, cpu_cd.cd_name) != 0)
     67 		return (0);
     68 #if 0
     69 	if (cpu_info[0].ci_dev != NULL)
     70 		return (0);
     71 #endif
     72 	return (1);
     73 }
     74 
     75 void
     76 cpuattach(device_t parent, device_t self, void *aux)
     77 {
     78 	struct cpu_info *ci;
     79 	struct confargs *ca = aux;
     80 	int id = ca->ca_node;
     81 
     82 	ci = cpu_attach_common(self, id);
     83 	if (ci == NULL)
     84 		return;
     85 
     86 #ifdef MULTIPROCESSOR
     87 	if (id > 0) {
     88 		cpu_spinup(self, ci);
     89 		return;
     90 	}
     91 #endif
     92 
     93 	cpu_setup_prep_generic(self);
     94 }
     95 
     96 #ifdef MULTIPROCESSOR
     97 
     98 int
     99 md_setup_trampoline(volatile struct cpu_hatch_data *h, struct cpu_info *ci)
    100 {
    101 	if (!openpic_base)
    102 		return -1;
    103 
    104 	/* construct an absolute branch instruction */
    105 	/* ba cpu_spinup_trampoline */
    106 	*(u_int *)EXC_RST = 0x48000002 | (u_int)cpu_spinup_trampoline;
    107 	__syncicache((void *)EXC_RST, 0x100);
    108 	h->hatch_running = -1;
    109 
    110 	/* Start secondary CPU. */
    111 	openpic_write(OPENPIC_PROC_INIT, (1 << 1));
    112 	return 1;
    113 }
    114 
    115 void
    116 md_presync_timebase(volatile struct cpu_hatch_data *h)
    117 {
    118 	uint64_t tb;
    119 
    120 	/* Sync timebase. */
    121 	tb = mftb();
    122 	tb += 100000;  /* 3ms @ 33MHz */
    123 
    124 	h->hatch_tbu = tb >> 32;
    125 	h->hatch_tbl = tb & 0xffffffff;
    126 
    127 	while (tb > mftb())
    128 		;
    129 
    130 	__asm volatile ("sync; isync");
    131 	h->hatch_running = 0;
    132 
    133 	delay(500000);
    134 }
    135 
    136 void
    137 md_start_timebase(volatile struct cpu_hatch_data *h)
    138 {
    139 	/* do nada */
    140 }
    141 
    142 void
    143 md_sync_timebase(volatile struct cpu_hatch_data *h)
    144 {
    145 	u_int tbu = h->hatch_tbu;
    146 	u_int tbl = h->hatch_tbl;
    147 
    148 	while (h->hatch_running == -1)
    149 		;
    150 
    151 	__asm volatile ("sync; isync");
    152 	__asm volatile ("mttbl %0" :: "r"(0));
    153 	__asm volatile ("mttbu %0" :: "r"(tbu));
    154 	__asm volatile ("mttbl %0" :: "r"(tbl));
    155 }
    156 
    157 void
    158 md_setup_interrupts(void)
    159 {
    160 	if (!openpic_base)
    161 		return;
    162 	/* clear the reset on all CPU's */
    163 	openpic_write(OPENPIC_PROC_INIT, 0);
    164 	openpic_set_priority(cpu_number(), 0);
    165 }
    166 #endif /* MULTIPROCESSOR */
    167