cpu.c revision 1.30
1/*	$OpenBSD: cpu.c,v 1.30 2009/12/29 14:10:29 jsing Exp $	*/
2
3/*
4 * Copyright (c) 1998-2003 Michael Shalayeff
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26 * THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/param.h>
30#include <sys/systm.h>
31#include <sys/device.h>
32#include <sys/reboot.h>
33
34#include <machine/cpufunc.h>
35#include <machine/pdc.h>
36#include <machine/reg.h>
37#include <machine/iomod.h>
38#include <machine/autoconf.h>
39
40#include <hppa/dev/cpudevs.h>
41
42struct cpu_softc {
43	struct  device sc_dev;
44
45	hppa_hpa_t sc_hpa;
46	void *sc_ih;
47};
48
49int	cpumatch(struct device *, void *, void *);
50void	cpuattach(struct device *, struct device *, void *);
51
52struct cfattach cpu_ca = {
53	sizeof(struct cpu_softc), cpumatch, cpuattach
54};
55
56struct cfdriver cpu_cd = {
57	NULL, "cpu", DV_DULL
58};
59
60int
61cpumatch(parent, cfdata, aux)
62	struct device *parent;
63	void *cfdata;
64	void *aux;
65{
66	struct cfdata *cf = cfdata;
67	struct confargs *ca = aux;
68
69	/* probe any 1.0, 1.1 or 2.0 */
70	if (ca->ca_type.iodc_type != HPPA_TYPE_NPROC ||
71	    ca->ca_type.iodc_sv_model != HPPA_NPROC_HPPA)
72		return 0;
73
74	if (cf->cf_unit >= MAXCPUS)
75		return 0;
76
77	return 1;
78}
79
80void
81cpuattach(parent, self, aux)
82	struct device *parent;
83	struct device *self;
84	void *aux;
85{
86	/* machdep.c */
87	extern struct pdc_model pdc_model;
88	extern struct pdc_cache pdc_cache;
89	extern struct pdc_btlb pdc_btlb;
90	extern u_int cpu_ticksnum, cpu_ticksdenom;
91	extern u_int fpu_enable;
92	/* clock.c */
93	extern int cpu_hardclock(void *);
94
95	struct cpu_softc *sc = (struct cpu_softc *)self;
96	u_int mhz = 100 * cpu_ticksnum / cpu_ticksdenom;
97	const char *p;
98
99	printf (": %s ", cpu_typename);
100	if (pdc_model.hvers) {
101		static const char lvls[4][4] = { "0", "1", "1.5", "2" };
102
103		printf("L%s-%c ", lvls[pdc_model.pa_lvl], "AB"[pdc_model.mc]);
104	}
105
106	printf ("%d", mhz / 100);
107	if (mhz % 100 > 9)
108		printf(".%02d", mhz % 100);
109	printf("MHz");
110
111	if (fpu_enable) {
112		extern u_int fpu_version;
113		u_int32_t ver[2];
114
115		mtctl(fpu_enable, CR_CCR);
116		__asm volatile(
117		    "fstds   %%fr0,0(%0)\n\t"
118		    "copr,0,0\n\t"
119		    "fstds   %%fr0,0(%0)"
120		    :: "r" (&ver) : "memory");
121		mtctl(0, CR_CCR);
122		fpu_version = HPPA_FPUVER(ver[0]);
123		printf(", FPU %s rev %d",
124		    hppa_mod_info(HPPA_TYPE_FPU, fpu_version >> 5),
125		    fpu_version & 0x1f);
126	}
127
128	printf("\n%s: ", self->dv_xname);
129	p = "";
130	if (!pdc_cache.dc_conf.cc_sh) {
131		printf("%uK(%db/l) Icache, ",
132		    pdc_cache.ic_size / 1024, pdc_cache.ic_conf.cc_line * 16);
133		p = "D";
134	}
135
136	printf("%uK(%db/l) wr-%s %scache, ",
137	    pdc_cache.dc_size / 1024, pdc_cache.dc_conf.cc_line * 16,
138	    pdc_cache.dc_conf.cc_wt? "thru" : "back", p);
139
140	p = "";
141	if (!pdc_cache.dt_conf.tc_sh) {
142		printf("%u ITLB, ", pdc_cache.it_size);
143		p = "D";
144	}
145	printf("%u %scoherent %sTLB",
146	    pdc_cache.dt_size, pdc_cache.dt_conf.tc_cst? "" : "in", p);
147
148	if (pdc_btlb.finfo.num_c)
149		printf(", %u BTLB", pdc_btlb.finfo.num_c);
150	else if (pdc_btlb.finfo.num_i || pdc_btlb.finfo.num_d)
151		printf(", %u/%u D/I BTLBs",
152		    pdc_btlb.finfo.num_i, pdc_btlb.finfo.num_d);
153
154	sc->sc_ih = cpu_intr_establish(IPL_CLOCK, 31,
155	    cpu_hardclock, NULL /*frame*/, sc->sc_dev.dv_xname);
156
157	printf("\n");
158}
159