xref: /netbsd-src/sys/arch/evbmips/evbmips/yamon.c (revision 3b3fdbf2c9ac813a670326224d18aca5e8690e8f)
1 /*	$NetBSD: yamon.c,v 1.14 2015/06/26 21:57:25 matt Exp $	*/
2 
3 /*
4  * Copyright 2002 Wasabi Systems, Inc.
5  * All rights reserved.
6  *
7  * Written by Simon Burge for Wasabi Systems, Inc.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed for the NetBSD Project by
20  *      Wasabi Systems, Inc.
21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22  *    or promote products derived from this software without specific prior
23  *    written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 /* XXX move to arch/mips/yamon/yamon.c or similar? */
39 
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: yamon.c,v 1.14 2015/06/26 21:57:25 matt Exp $");
42 
43 #include <sys/param.h>
44 #include <sys/device.h>
45 #include <sys/kernel.h>
46 #include <sys/systm.h>
47 #include <sys/cpu.h>
48 
49 #include <dev/cons.h>
50 
51 #include <mips/locore.h>
52 
53 #include <machine/yamon.h>
54 
55 static int  yamongetc(dev_t);
56 static void yamonputc(dev_t, int);
57 
58 /*
59  * Default consdev, for errors or warnings before
60  * consinit runs: use the PROM.
61  */
62 struct consdev yamon_promcd = {
63 	NULL,		/* probe */
64 	NULL,		/* init */
65 	yamongetc,	/* getc */
66 	yamonputc,	/* putc */
67 	nullcnpollc,	/* pollc */
68 	NULL,		/* bell */
69 	makedev(0, 0),
70 	CN_DEAD,
71 };
72 /*
73  * Get character from PROM console.
74  */
75 static int
yamongetc(dev_t dev)76 yamongetc(dev_t dev)
77 {
78 	char chr;
79 
80 	while (!YAMON_GETCHAR(&chr))
81 		/* nothing */;
82 	return chr;
83 }
84 
85 /*
86  * Print a character on PROM console.
87  */
88 static void
yamonputc(dev_t dev,int c)89 yamonputc(dev_t dev, int c)
90 {
91 	char chr;
92 
93 	chr = c;
94 	YAMON_PRINT_COUNT(&chr, 1);
95 }
96 
97 char *
yamon_getenv(const char * name)98 yamon_getenv(const char *name)
99 {
100 	yamon_env_var *yev = yamon_envp;
101 
102 	if (yev == NULL)
103 		return (NULL);
104 	while (yev->name != NULL) {
105 		if (strcmp(yev->name, name) == 0)
106 			return (yev->val);
107 		yev++;
108 	}
109 
110 	return (NULL);
111 }
112 
113 void
yamon_print(const char * str)114 yamon_print(const char *str)
115 {
116 
117 	YAMON_PRINT(str);
118 }
119 
120 void
yamon_exit(uint32_t rc)121 yamon_exit(uint32_t rc)
122 {
123 
124 	YAMON_EXIT(rc);
125 }
126 
127 /*
128  * Ask YAMON for the CPU frequency.
129  * If "force" is set, then use a random frequency (100MHz) so
130  * that at least delay() works, even though not perfectly.
131  * Return 1 if YAMON returns a CPU frequency.
132  */
133 int
yamon_setcpufreq(int force)134 yamon_setcpufreq(int force)
135 {
136 	struct cpu_info * const ci = curcpu();
137 	uint32_t freq;
138 	int ret;
139 
140 	ret = YAMON_SYSCON_READ(SYSCON_BOARD_CPU_CLOCK_FREQ_ID, &freq,
141 	    sizeof(freq));
142 	if (!force && (ret != 0 || freq == 0))
143 		return 0;
144 
145 	if (ret != 0 || freq == 0) {
146 		freq = 100 * 1000 * 1000;
147 		ret = 0;
148 	} else
149 		ret = 1;
150 
151 	ci->ci_cpu_freq = freq;
152 	ci->ci_cycles_per_hz = (freq + hz / 2) / hz;
153 	ci->ci_divisor_delay = ((freq + 500000) / 1000000);
154 	ci->ci_cctr_freq /= ci->ci_cpu_freq;
155 	if (mips_options.mips_cpu_flags & CPU_MIPS_DOUBLE_COUNT) {
156 		ci->ci_cycles_per_hz /= 2;
157 		ci->ci_divisor_delay /= 2;
158 		ci->ci_cctr_freq /= 2;
159 	}
160 
161 	return ret;
162 }
163