xref: /netbsd-src/sys/dev/arcbios/arcbios.c (revision 5e4c038a45edbc7d63b7c2daa76e29f88b64a4e3)
1 /*	$NetBSD: arcbios.c,v 1.5 2001/11/13 12:53:24 lukem Exp $	*/
2 
3 /*-
4  * Copyright (c) 2001 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe.
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  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the NetBSD
21  *	Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: arcbios.c,v 1.5 2001/11/13 12:53:24 lukem Exp $");
41 
42 #include <sys/param.h>
43 
44 #include <sys/systm.h>
45 #include <dev/cons.h>
46 #include <sys/conf.h>
47 
48 #include <dev/arcbios/arcbios.h>
49 #include <dev/arcbios/arcbiosvar.h>
50 
51 const struct arcbios_spb *ARCBIOS_SPB;
52 const struct arcbios_fv *ARCBIOS;
53 
54 char arcbios_sysid_vendor[ARCBIOS_SYSID_FIELDLEN + 1];
55 char arcbios_sysid_product[ARCBIOS_SYSID_FIELDLEN + 1];
56 
57 char arcbios_system_identifier[64 + 1];
58 
59 int	arcbios_cngetc(dev_t);
60 void	arcbios_cnputc(dev_t, int);
61 
62 void	arcbios_fetch_system_identifier(struct arcbios_component *,
63 	    struct arcbios_treewalk_context *);
64 
65 struct consdev arcbios_cn = {
66 	NULL, NULL, arcbios_cngetc, arcbios_cnputc, nullcnpollc, NULL,
67 	    NODEV, CN_NORMAL,
68 };
69 
70 cdev_decl(arcbios_tty);
71 
72 /*
73  * arcbios_init:
74  *
75  *	Initialize the ARC BIOS.
76  */
77 int
78 arcbios_init(vaddr_t pblkva)
79 {
80 	int maj;
81 	struct arcbios_sysid *sid;
82 
83 	ARCBIOS_SPB = (struct arcbios_spb *) pblkva;
84 
85 	switch (ARCBIOS_SPB->SPBSignature) {
86 	case ARCBIOS_SPB_SIGNATURE:
87 	case ARCBIOS_SPB_SIGNATURE_1:
88 		/* Okay. */
89 		break;
90 
91 	default:
92 		/* Don't know what this is. */
93 		return (1);
94 	}
95 
96 	/* Initialize our pointer to the firmware vector. */
97 	ARCBIOS = ARCBIOS_SPB->FirmwareVector;
98 
99 	/* Find the ARC BIOS console device major (needed by cnopen) */
100 	for (maj = 0; maj < nchrdev; maj++)
101 		if (cdevsw[maj].d_open == arcbios_ttyopen)
102 			break;
103 
104 	arcbios_cn.cn_dev = makedev(maj, 0);
105 
106 	/* Initialize the bootstrap console. */
107 	cn_tab = &arcbios_cn;
108 
109 	/*
110 	 * Fetch the system ID.
111 	 */
112 	sid = (*ARCBIOS->GetSystemId)();
113 	if (sid != NULL) {
114 		memcpy(arcbios_sysid_vendor, sid->VendorId,
115 		    sizeof(sid->VendorId));
116 		arcbios_sysid_vendor[sizeof(sid->VendorId)] = '\0';
117 
118 		memcpy(arcbios_sysid_product, sid->ProductId,
119 		    sizeof(sid->ProductId));
120 		arcbios_sysid_product[sizeof(sid->ProductId)] = '\0';
121 	}
122 
123 	/*
124 	 * Fetch the identifier string from the `system' component.
125 	 * Machdep code will use this to initialize the system type.
126 	 */
127 	arcbios_tree_walk(arcbios_fetch_system_identifier, NULL);
128 
129 	return (0);
130 }
131 
132 void
133 arcbios_fetch_system_identifier(struct arcbios_component *node,
134     struct arcbios_treewalk_context *atc)
135 {
136 
137 	switch (node->Class) {
138 	case COMPONENT_CLASS_SystemClass:
139 		arcbios_component_id_copy(node,
140 		    arcbios_system_identifier,
141 		    sizeof(arcbios_system_identifier));
142 		atc->atc_terminate = 1;
143 		break;
144 
145 	default:
146 		break;
147 	}
148 }
149 
150 /****************************************************************************
151  * ARC component tree walking routines.
152  ****************************************************************************/
153 
154 static void
155 arcbios_subtree_walk(struct arcbios_component *node,
156     void (*func)(struct arcbios_component *, struct arcbios_treewalk_context *),
157     struct arcbios_treewalk_context *atc)
158 {
159 
160 	for (node = (*ARCBIOS->GetChild)(node);
161 	     node != NULL && atc->atc_terminate == 0;
162 	     node = (*ARCBIOS->GetPeer)(node)) {
163 		(*func)(node, atc);
164 		if (atc->atc_terminate)
165 			return;
166 		arcbios_subtree_walk(node, func, atc);
167 	}
168 }
169 
170 void
171 arcbios_tree_walk(void (*func)(struct arcbios_component *,
172     struct arcbios_treewalk_context *), void *cookie)
173 {
174 	struct arcbios_treewalk_context atc;
175 
176 	atc.atc_cookie = cookie;
177 	atc.atc_terminate = 0;
178 
179 	arcbios_subtree_walk(NULL, func, &atc);
180 }
181 
182 void
183 arcbios_component_id_copy(struct arcbios_component *node,
184     char *dst, size_t dstsize)
185 {
186 
187 	dstsize--;
188 	if (dstsize > node->IdentifierLength)
189 		dstsize = node->IdentifierLength;
190 	memcpy(dst, node->Identifier, dstsize);
191 	dst[dstsize] = '\0';
192 }
193 
194 /****************************************************************************
195  * Bootstrap console routines.
196  ****************************************************************************/
197 
198 int
199 arcbios_cngetc(dev_t dev)
200 {
201 	uint32_t count;
202 	char c;
203 
204 	(*ARCBIOS->Read)(ARCBIOS_STDIN, &c, 1, &count);
205 	return (c);
206 }
207 
208 void
209 arcbios_cnputc(dev_t dev, int c)
210 {
211 	uint32_t count;
212 	char ch = c;
213 
214 	(*ARCBIOS->Write)(ARCBIOS_STDOUT, &ch, 1, &count);
215 }
216