1299241Sadrian/*-
2299241Sadrian * Copyright (c) 2016 Landon Fuller <landon@landonf.org>
3299241Sadrian * All rights reserved.
4299241Sadrian *
5299241Sadrian * Redistribution and use in source and binary forms, with or without
6299241Sadrian * modification, are permitted provided that the following conditions
7299241Sadrian * are met:
8299241Sadrian * 1. Redistributions of source code must retain the above copyright
9299241Sadrian *    notice, this list of conditions and the following disclaimer,
10299241Sadrian *    without modification.
11299241Sadrian * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12299241Sadrian *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13299241Sadrian *    redistribution must be conditioned upon including a substantially
14299241Sadrian *    similar Disclaimer requirement for further binary redistribution.
15299241Sadrian *
16299241Sadrian * NO WARRANTY
17299241Sadrian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18299241Sadrian * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19299241Sadrian * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20299241Sadrian * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21299241Sadrian * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22299241Sadrian * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23299241Sadrian * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24299241Sadrian * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25299241Sadrian * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26299241Sadrian * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27299241Sadrian * THE POSSIBILITY OF SUCH DAMAGES.
28299241Sadrian */
29299241Sadrian
30299241Sadrian#include <sys/cdefs.h>
31299241Sadrian__FBSDID("$FreeBSD$");
32299241Sadrian
33299241Sadrian#include <sys/param.h>
34299241Sadrian#include <sys/types.h>
35299241Sadrian#include <sys/systm.h>
36299241Sadrian
37299241Sadrian#include "bhnd_nvram_map_data.h"
38299241Sadrian
39299241Sadrian/*
40299241Sadrian * CRC-8 lookup table used to checksum SPROM and NVRAM data via
41299241Sadrian * bhnd_nvram_crc8().
42299241Sadrian *
43299241Sadrian * Generated with following parameters:
44299241Sadrian * 	polynomial:	CRC-8 (x^8 + x^7 + x^6 + x^4 + x^2 + 1)
45299241Sadrian * 	reflected bits:	false
46299241Sadrian * 	reversed:	true
47299241Sadrian */
48299241Sadrianconst uint8_t bhnd_nvram_crc8_tab[] = {
49299241Sadrian	0x00, 0xf7, 0xb9, 0x4e, 0x25, 0xd2, 0x9c, 0x6b, 0x4a, 0xbd, 0xf3,
50299241Sadrian	0x04, 0x6f, 0x98, 0xd6, 0x21, 0x94, 0x63, 0x2d, 0xda, 0xb1, 0x46,
51299241Sadrian	0x08, 0xff, 0xde, 0x29, 0x67, 0x90, 0xfb, 0x0c, 0x42, 0xb5, 0x7f,
52299241Sadrian	0x88, 0xc6, 0x31, 0x5a, 0xad, 0xe3, 0x14, 0x35, 0xc2, 0x8c, 0x7b,
53299241Sadrian	0x10, 0xe7, 0xa9, 0x5e, 0xeb, 0x1c, 0x52, 0xa5, 0xce, 0x39, 0x77,
54299241Sadrian	0x80, 0xa1, 0x56, 0x18, 0xef, 0x84, 0x73, 0x3d, 0xca, 0xfe, 0x09,
55299241Sadrian	0x47, 0xb0, 0xdb, 0x2c, 0x62, 0x95, 0xb4, 0x43, 0x0d, 0xfa, 0x91,
56299241Sadrian	0x66, 0x28, 0xdf, 0x6a, 0x9d, 0xd3, 0x24, 0x4f, 0xb8, 0xf6, 0x01,
57299241Sadrian	0x20, 0xd7, 0x99, 0x6e, 0x05, 0xf2, 0xbc, 0x4b, 0x81, 0x76, 0x38,
58299241Sadrian	0xcf, 0xa4, 0x53, 0x1d, 0xea, 0xcb, 0x3c, 0x72, 0x85, 0xee, 0x19,
59299241Sadrian	0x57, 0xa0, 0x15, 0xe2, 0xac, 0x5b, 0x30, 0xc7, 0x89, 0x7e, 0x5f,
60299241Sadrian	0xa8, 0xe6, 0x11, 0x7a, 0x8d, 0xc3, 0x34, 0xab, 0x5c, 0x12, 0xe5,
61299241Sadrian	0x8e, 0x79, 0x37, 0xc0, 0xe1, 0x16, 0x58, 0xaf, 0xc4, 0x33, 0x7d,
62299241Sadrian	0x8a, 0x3f, 0xc8, 0x86, 0x71, 0x1a, 0xed, 0xa3, 0x54, 0x75, 0x82,
63299241Sadrian	0xcc, 0x3b, 0x50, 0xa7, 0xe9, 0x1e, 0xd4, 0x23, 0x6d, 0x9a, 0xf1,
64299241Sadrian	0x06, 0x48, 0xbf, 0x9e, 0x69, 0x27, 0xd0, 0xbb, 0x4c, 0x02, 0xf5,
65299241Sadrian	0x40, 0xb7, 0xf9, 0x0e, 0x65, 0x92, 0xdc, 0x2b, 0x0a, 0xfd, 0xb3,
66299241Sadrian	0x44, 0x2f, 0xd8, 0x96, 0x61, 0x55, 0xa2, 0xec, 0x1b, 0x70, 0x87,
67299241Sadrian	0xc9, 0x3e, 0x1f, 0xe8, 0xa6, 0x51, 0x3a, 0xcd, 0x83, 0x74, 0xc1,
68299241Sadrian	0x36, 0x78, 0x8f, 0xe4, 0x13, 0x5d, 0xaa, 0x8b, 0x7c, 0x32, 0xc5,
69299241Sadrian	0xae, 0x59, 0x17, 0xe0, 0x2a, 0xdd, 0x93, 0x64, 0x0f, 0xf8, 0xb6,
70299241Sadrian	0x41, 0x60, 0x97, 0xd9, 0x2e, 0x45, 0xb2, 0xfc, 0x0b, 0xbe, 0x49,
71299241Sadrian	0x07, 0xf0, 0x9b, 0x6c, 0x22, 0xd5, 0xf4, 0x03, 0x4d, 0xba, 0xd1,
72299241Sadrian	0x26, 0x68, 0x9f
73299241Sadrian};
74299241Sadrian
75299241Sadrian
76299241Sadrian/**
77299241Sadrian * Return the size of type @p dt.
78299241Sadrian *
79299241Sadrian * @param dt NVRAM data type.
80299241Sadrian * @result the byte width of @p dt.
81299241Sadrian */
82299241Sadriansize_t
83299241Sadrianbhnd_nvram_type_width(bhnd_nvram_dt dt)
84299241Sadrian{
85299241Sadrian	switch (dt) {
86299241Sadrian	case BHND_NVRAM_DT_INT8:
87299241Sadrian	case BHND_NVRAM_DT_UINT8:
88299241Sadrian	case BHND_NVRAM_DT_CHAR:
89299241Sadrian		return (sizeof(uint8_t));
90299241Sadrian
91299241Sadrian	case BHND_NVRAM_DT_INT16:
92299241Sadrian	case BHND_NVRAM_DT_UINT16:
93299241Sadrian		return (sizeof(uint16_t));
94299241Sadrian
95299241Sadrian	case BHND_NVRAM_DT_INT32:
96299241Sadrian	case BHND_NVRAM_DT_UINT32:
97299241Sadrian		return (sizeof(uint32_t));
98299241Sadrian	}
99299241Sadrian
100299241Sadrian	/* Quiesce gcc4.2 */
101299241Sadrian	panic("bhnd nvram data type %u unknown", dt);
102299241Sadrian}
103299241Sadrian
104299241Sadrian
105299241Sadrian/**
106299241Sadrian * Return the variable definition for @p varname, if any.
107299241Sadrian *
108299241Sadrian * @param varname variable name
109299241Sadrian *
110299241Sadrian * @retval bhnd_nvram_var If a valid definition for @p varname is found.
111299241Sadrian * @retval NULL If no definition for @p varname is found.
112299241Sadrian */
113299241Sadrianconst struct bhnd_nvram_var *
114299241Sadrianbhnd_nvram_var_defn(const char *varname)
115299241Sadrian{
116299241Sadrian	size_t	min, mid, max;
117299241Sadrian	int	order;
118299241Sadrian
119299241Sadrian	/*
120299241Sadrian	 * Locate the requested variable using a binary search.
121299241Sadrian	 *
122299241Sadrian	 * The variable table is guaranteed to be sorted in lexicographical
123299241Sadrian	 * order (using the 'C' locale for collation rules)
124299241Sadrian	 */
125299241Sadrian	min = 0;
126299241Sadrian	mid = 0;
127299241Sadrian	max = nitems(bhnd_nvram_vars) - 1;
128299241Sadrian
129299241Sadrian	while (max >= min) {
130299241Sadrian		/* Select midpoint */
131299241Sadrian		mid = (min + max) / 2;
132299241Sadrian
133299241Sadrian		/* Determine which side of the partition to search */
134299241Sadrian		order = strcmp(bhnd_nvram_vars[mid].name, varname);
135299241Sadrian		if (order < 0) {
136299241Sadrian			/* Search upper partition */
137299241Sadrian			min = mid + 1;
138299241Sadrian		} else if (order > 0) {
139299241Sadrian			/* Search lower partition */
140299241Sadrian			max = mid - 1;
141299241Sadrian		} else if (order == 0) {
142299241Sadrian			/* Match found */
143299241Sadrian			return (&bhnd_nvram_vars[mid]);
144299241Sadrian		}
145299241Sadrian	}
146299241Sadrian
147299241Sadrian	/* Not found */
148299241Sadrian	return (NULL);
149299241Sadrian}
150