1/*	$NetBSD: platid.c,v 1.10 2006/01/17 02:50:59 uwe Exp $	*/
2
3/*-
4 * Copyright (c) 1999-2001
5 *         Shin Takemura and PocketBSD Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *	This product includes software developed by the PocketBSD project
18 *	and its contributors.
19 * 4. Neither the name of the project nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 */
36
37#include <sys/cdefs.h>
38#if !defined(_WIN32)	/* XXX: hpcboot.exe */
39__KERNEL_RCSID(0, "$NetBSD: platid.c,v 1.10 2006/01/17 02:50:59 uwe Exp $");
40#endif
41
42#include <sys/types.h>
43#include <sys/param.h>
44#include <sys/systm.h>
45
46#include <machine/platid.h>
47
48platid_t platid_unknown = {{ PLATID_UNKNOWN, PLATID_UNKNOWN }};
49platid_t platid_wild = {{ PLATID_WILD, PLATID_WILD }};
50platid_t platid = {{ PLATID_UNKNOWN, PLATID_UNKNOWN }};
51
52void
53platid_ntoh(platid_t *pid)
54{
55
56	pid->dw.dw0 = ntohl(pid->dw.dw0);
57	pid->dw.dw1 = ntohl(pid->dw.dw1);
58}
59
60void
61platid_hton(platid_t *pid)
62{
63
64	pid->dw.dw0 = htonl(pid->dw.dw0);
65	pid->dw.dw1 = htonl(pid->dw.dw1);
66}
67
68#ifdef PLATID_TEST
69void
70platid_dump(const char *name, void* pxx)
71{
72	int i;
73	unsigned char* p = (unsigned char*)pxx;
74
75	printf("%14s: ", name);
76
77	for (i = 0; i < 8; i++) {
78		printf("%02x", p[i]);
79	}
80	printf("\n");
81}
82#endif
83
84int
85platid_match(platid_t *pid, platid_mask_t *mask)
86{
87
88	return (platid_match_sub(pid, mask, 0));
89}
90
91int
92platid_match_sub(platid_t *pid, platid_mask_t *mask, int unknown_is_match)
93{
94	int match_count;
95
96#define PLATID_MATCH(mbr)				\
97	if (pid->s.mbr != mask->s.mbr &&		\
98	    mask->s.mbr != platid_wild.s.mbr &&		\
99	    !(pid->s.mbr == platid_unknown.s.mbr &&	\
100	     unknown_is_match)) {			\
101		return (0);				\
102	} else if (pid->s.mbr == mask->s.mbr) {		\
103		match_count++;				\
104	}
105
106	match_count = 1;
107	PLATID_MATCH(cpu_submodel);
108	PLATID_MATCH(cpu_model);
109	PLATID_MATCH(cpu_series);
110	PLATID_MATCH(cpu_arch);
111
112	PLATID_MATCH(submodel);
113	PLATID_MATCH(model);
114	PLATID_MATCH(series);
115	PLATID_MATCH(vendor);
116
117	return (match_count);
118
119#undef PLATID_MATCH
120}
121
122const tchar *
123platid_name(platid_t *pid)
124{
125	struct platid_name *match;
126
127	match = platid_search(pid,
128	    platid_name_table, platid_name_table_size,
129	    sizeof(struct platid_name));
130
131	return ((match != NULL) ? match->name : TEXT("UNKNOWN"));
132}
133
134struct platid_data *
135platid_search_data(platid_t *pid, struct platid_data *datap)
136{
137
138	while (datap->mask != NULL && !platid_match(pid, datap->mask))
139		datap++;
140	if (datap->mask == NULL && datap->data == NULL)
141		return (NULL);
142
143	return (datap);
144}
145
146void *
147platid_search(platid_t *pid, void *base, int nmemb, int size)
148{
149	int i, match_level, res;
150	void *match;
151
152	match_level = 0;
153	match = NULL;
154	for (i = 0; i < nmemb; i++) {
155		res = platid_match(pid, *(platid_mask_t**)base);
156		if (match_level < res) {
157			match_level = res;
158			match = base;
159		}
160		base = (char *)base + size;
161	}
162
163	return (match);
164}
165