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