#include <sys/cdefs.h>
#if !defined(_WIN32)
__KERNEL_RCSID(0, "$NetBSD: platid.c,v 1.11 2006/05/10 06:24:02 skrll Exp $");
#endif
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <machine/platid.h>
platid_t platid_unknown = {{ PLATID_UNKNOWN, PLATID_UNKNOWN }};
platid_t platid_wild = {{ PLATID_WILD, PLATID_WILD }};
platid_t platid = {{ PLATID_UNKNOWN, PLATID_UNKNOWN }};
void
platid_ntoh(platid_t *pid)
{
pid->dw.dw0 = ntohl(pid->dw.dw0);
pid->dw.dw1 = ntohl(pid->dw.dw1);
}
void
platid_hton(platid_t *pid)
{
pid->dw.dw0 = htonl(pid->dw.dw0);
pid->dw.dw1 = htonl(pid->dw.dw1);
}
#ifdef PLATID_TEST
void
platid_dump(const char *name, void* pxx)
{
int i;
unsigned char* p = (unsigned char*)pxx;
printf("%14s: ", name);
for (i = 0; i < 8; i++) {
printf("%02x", p[i]);
}
printf("\n");
}
#endif
int
platid_match(platid_t *pid, platid_mask_t *mask)
{
return (platid_match_sub(pid, mask, 0));
}
int
platid_match_sub(platid_t *pid, platid_mask_t *mask, int unknown_is_match)
{
int match_count;
#define PLATID_MATCH(mbr) \
if (pid->s.mbr != mask->s.mbr && \
mask->s.mbr != platid_wild.s.mbr && \
!(pid->s.mbr == platid_unknown.s.mbr && \
unknown_is_match)) { \
return (0); \
} else if (pid->s.mbr == mask->s.mbr) { \
match_count++; \
}
match_count = 1;
PLATID_MATCH(cpu_submodel);
PLATID_MATCH(cpu_model);
PLATID_MATCH(cpu_series);
PLATID_MATCH(cpu_arch);
PLATID_MATCH(submodel);
PLATID_MATCH(model);
PLATID_MATCH(series);
PLATID_MATCH(vendor);
return (match_count);
#undef PLATID_MATCH
}
const tchar *
platid_name(platid_t *pid)
{
struct platid_name *match;
match = platid_search(pid,
platid_name_table, platid_name_table_size,
sizeof(struct platid_name));
return ((match != NULL) ? match->name : TEXT("UNKNOWN"));
}
struct platid_data *
platid_search_data(platid_t *pid, struct platid_data *datap)
{
while (datap->mask != NULL && !platid_match(pid, datap->mask))
datap++;
if (datap->mask == NULL && datap->data == NULL)
return (NULL);
return (datap);
}
void *
platid_search(platid_t *pid, void *base, int nmemb, int size)
{
int i, match_level, res;
void *match;
match_level = 0;
match = NULL;
for (i = 0; i < nmemb; i++) {
res = platid_match(pid, *(platid_mask_t**)base);
if (match_level < res) {
match_level = res;
match = base;
}
base = (char *)base + size;
}
return (match);
}