1/*-
2 * Initial implementation:
3 * Copyright (c) 2001 Robert Drehmel
4 * All rights reserved.
5 *
6 * As long as the above copyright statement and this notice remain
7 * unchanged, you can do what ever you want with this file.
8 */
9
10#include <sys/cdefs.h>
11__FBSDID("$FreeBSD$");
12
13#include <sys/param.h>
14#include <sys/systm.h>
15#include <sys/kernel.h>
16#include <sys/sysctl.h>
17
18#include <machine/md_var.h>
19#include <machine/ver.h>
20
21char machine[] = MACHINE;
22SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD,
23    machine, 0, "Machine class");
24
25static char cpu_model[128];
26SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD,
27    cpu_model, 0, "Machine model");
28
29static SYSCTL_NODE(_hw, OID_AUTO, freq, CTLFLAG_RD, 0, "");
30
31static u_int cpu_count;
32static u_int cpu_freq;
33SYSCTL_UINT(_hw_freq, OID_AUTO, cpu, CTLFLAG_RD, &cpu_freq, 0,
34    "CPU clock frequency");
35
36void
37cpu_identify(u_long vers, u_int freq, u_int id)
38{
39	const char *manus;
40	const char *impls;
41
42	switch (VER_MANUF(vers)) {
43	case 0x04:
44		manus = "HAL/Fujitsu";
45		break;
46	case 0x13:
47	case 0x17:
48	case 0x22:
49	case 0x3e:
50		manus = "Sun Microsystems";
51		break;
52	default:
53		manus = NULL;
54		break;
55	}
56	switch (VER_IMPL(vers)) {
57	case CPU_IMPL_SPARC64:
58		impls = "SPARC64";
59		break;
60	case CPU_IMPL_SPARC64II:
61		impls = "SPARC64-II";
62		break;
63	case CPU_IMPL_SPARC64III:
64		impls = "SPARC64-III";
65		break;
66	case CPU_IMPL_SPARC64IV:
67		impls = "SPARC64-IV";
68		break;
69	case CPU_IMPL_SPARC64V:
70		impls = "SPARC64-V";
71		break;
72	case CPU_IMPL_SPARC64VI:
73		impls = "SPARC64-VI";
74		break;
75	case CPU_IMPL_SPARC64VII:
76		impls = "SPARC64-VII";
77		break;
78	case CPU_IMPL_SPARC64VIIIfx:
79		impls = "SPARC64-VIIIfx";
80		break;
81	case CPU_IMPL_ULTRASPARCI:
82		impls = "UltraSparc-I";
83		break;
84	case CPU_IMPL_ULTRASPARCII:
85		impls = "UltraSparc-II";
86		break;
87	case CPU_IMPL_ULTRASPARCIIi:
88		impls = "UltraSparc-IIi";
89		break;
90	case CPU_IMPL_ULTRASPARCIIe:
91		impls = "UltraSparc-IIe";
92		break;
93	case CPU_IMPL_ULTRASPARCIII:
94		impls = "UltraSparc-III";
95		break;
96	case CPU_IMPL_ULTRASPARCIIIp:
97		impls = "UltraSparc-III+";
98		break;
99	case CPU_IMPL_ULTRASPARCIIIi:
100		impls = "UltraSparc-IIIi";
101		break;
102	case CPU_IMPL_ULTRASPARCIV:
103		impls = "UltraSparc-IV";
104		break;
105	case CPU_IMPL_ULTRASPARCIVp:
106		impls = "UltraSparc-IV+";
107		break;
108	case CPU_IMPL_ULTRASPARCIIIip:
109		impls = "UltraSparc-IIIi+";
110		break;
111	default:
112		impls = NULL;
113		break;
114	}
115	if (manus == NULL || impls == NULL) {
116		printf(
117		    "CPU: unknown; please e-mail the following value together\n"
118		    "     with the exact name of your processor to "
119		    "<freebsd-sparc64@FreeBSD.org>.\n"
120		    "     version register: <0x%lx>\n", vers);
121		return;
122	}
123
124	snprintf(cpu_model, sizeof(cpu_model), "%s %s", manus, impls);
125	printf("cpu%d: %s %s Processor (%d.%02d MHz CPU)\n", id, manus, impls,
126	    (freq + 4999) / 1000000, ((freq + 4999) / 10000) % 100);
127	if (bootverbose) {
128		printf("  mask=0x%lx maxtl=%ld maxwin=%ld\n", VER_MASK(vers),
129		    VER_MAXTL(vers), VER_MAXWIN(vers));
130	}
131
132	/*
133	 * Calculate the average CPU frequency.
134	 */
135	freq = (freq + 500000ul) / 1000000ul;
136	cpu_freq = (cpu_freq * cpu_count + freq) / (cpu_count + 1);
137	cpu_count++;
138}
139