xref: /netbsd-src/sys/dev/arcbios/arcbios.c (revision c4a72b64362cdaf56b20ef58a2b9eb3d98492c47)
1 /*	$NetBSD: arcbios.c,v 1.6 2002/09/06 13:18:43 gehenna 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.6 2002/09/06 13:18:43 gehenna 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 extern const struct cdevsw arcbios_cdevsw;
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 	maj = cdevsw_lookup_major(&arcbios_cdevsw);
101 
102 	arcbios_cn.cn_dev = makedev(maj, 0);
103 
104 	/* Initialize the bootstrap console. */
105 	cn_tab = &arcbios_cn;
106 
107 	/*
108 	 * Fetch the system ID.
109 	 */
110 	sid = (*ARCBIOS->GetSystemId)();
111 	if (sid != NULL) {
112 		memcpy(arcbios_sysid_vendor, sid->VendorId,
113 		    sizeof(sid->VendorId));
114 		arcbios_sysid_vendor[sizeof(sid->VendorId)] = '\0';
115 
116 		memcpy(arcbios_sysid_product, sid->ProductId,
117 		    sizeof(sid->ProductId));
118 		arcbios_sysid_product[sizeof(sid->ProductId)] = '\0';
119 	}
120 
121 	/*
122 	 * Fetch the identifier string from the `system' component.
123 	 * Machdep code will use this to initialize the system type.
124 	 */
125 	arcbios_tree_walk(arcbios_fetch_system_identifier, NULL);
126 
127 	return (0);
128 }
129 
130 void
131 arcbios_fetch_system_identifier(struct arcbios_component *node,
132     struct arcbios_treewalk_context *atc)
133 {
134 
135 	switch (node->Class) {
136 	case COMPONENT_CLASS_SystemClass:
137 		arcbios_component_id_copy(node,
138 		    arcbios_system_identifier,
139 		    sizeof(arcbios_system_identifier));
140 		atc->atc_terminate = 1;
141 		break;
142 
143 	default:
144 		break;
145 	}
146 }
147 
148 /****************************************************************************
149  * ARC component tree walking routines.
150  ****************************************************************************/
151 
152 static void
153 arcbios_subtree_walk(struct arcbios_component *node,
154     void (*func)(struct arcbios_component *, struct arcbios_treewalk_context *),
155     struct arcbios_treewalk_context *atc)
156 {
157 
158 	for (node = (*ARCBIOS->GetChild)(node);
159 	     node != NULL && atc->atc_terminate == 0;
160 	     node = (*ARCBIOS->GetPeer)(node)) {
161 		(*func)(node, atc);
162 		if (atc->atc_terminate)
163 			return;
164 		arcbios_subtree_walk(node, func, atc);
165 	}
166 }
167 
168 void
169 arcbios_tree_walk(void (*func)(struct arcbios_component *,
170     struct arcbios_treewalk_context *), void *cookie)
171 {
172 	struct arcbios_treewalk_context atc;
173 
174 	atc.atc_cookie = cookie;
175 	atc.atc_terminate = 0;
176 
177 	arcbios_subtree_walk(NULL, func, &atc);
178 }
179 
180 void
181 arcbios_component_id_copy(struct arcbios_component *node,
182     char *dst, size_t dstsize)
183 {
184 
185 	dstsize--;
186 	if (dstsize > node->IdentifierLength)
187 		dstsize = node->IdentifierLength;
188 	memcpy(dst, node->Identifier, dstsize);
189 	dst[dstsize] = '\0';
190 }
191 
192 /****************************************************************************
193  * Bootstrap console routines.
194  ****************************************************************************/
195 
196 int
197 arcbios_cngetc(dev_t dev)
198 {
199 	uint32_t count;
200 	char c;
201 
202 	(*ARCBIOS->Read)(ARCBIOS_STDIN, &c, 1, &count);
203 	return (c);
204 }
205 
206 void
207 arcbios_cnputc(dev_t dev, int c)
208 {
209 	uint32_t count;
210 	char ch = c;
211 
212 	(*ARCBIOS->Write)(ARCBIOS_STDOUT, &ch, 1, &count);
213 }
214