Home | History | Annotate | Line # | Download | only in arcbios
arcbios.c revision 1.9
      1 /*	$NetBSD: arcbios.c,v 1.9 2005/02/27 00:26:58 perry 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.9 2005/02/27 00:26:58 perry 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,
     67 	    NULL, NULL, NULL, 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 	unsigned long 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 	unsigned long count;
    210 	char ch = c;
    211 
    212 	(*ARCBIOS->Write)(ARCBIOS_STDOUT, &ch, 1, &count);
    213 }
    214