/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifdef _KERNEL
#else
#include <strings.h>
#endif
/*
* Refer to
* Intel 64 and IA-32 Architectures Software Developers's Manual
* Chapter 9.11 Microcode Update Facilities
* for details.
*/
/*
* Validates the microcode header.
* Returns EM_OK on success, EM_HEADER on failure.
*/
{
return (EM_HEADER);
/*
* The only header version number supported is 1.
*/
return (EM_HEADER);
/*
* The body size field of the microcode code header specifies the size
* of the encrypted data section, its value must be a multiple of the
* size of DWORD. The total size field must be in multiples of 1K
* bytes.
*/
if ((body_size % sizeof (int)) ||
return (EM_HEADER);
/*
* Sanity check to avoid reading bogus files
*/
return (EM_HEADER);
/*
* If there is extended signature table, total_size is the sum of
* header_size
* body_size
* sizeof (struct ucode_ext_table)
* n * sizeof (struct ucode_ext_sig)
* where n is indicated by uet_count in struct ucode_ext_table.
*/
return (EM_HEADER);
}
}
return (EM_OK);
}
/*
* Returns checksum.
*/
{
int i;
i = size >> 2;
while (i--)
return (sum);
}
{
/* LINTED: pointer alignment */
return (EM_INVALIDARG);
/* Magic Number: "AMD\0" */
size -= 4;
if (*ptr++ != 0x00414d44)
return (EM_FILEFORMAT);
/* equivalence table */
size -= 4;
if (*ptr++)
return (EM_FILEFORMAT);
size -= 4;
return (EM_FILEFORMAT);
/* LINTED: pointer alignment */
while (size > 8) {
/* microcode patch */
size -= 4;
if (*ptr++ != 1)
return (EM_FILEFORMAT);
size -= 4;
return (EM_FILEFORMAT);
/* LINTED: pointer alignment */
}
if (size)
return (EM_FILEFORMAT);
return (EM_OK);
}
{
int remaining;
return (EM_INVALIDARG);
return (rc);
return (EM_CHECKSUM);
if (ext_size > 0) {
uint32_t i;
if (ucode_checksum_intel(0, ext_size,
return (EM_CHECKSUM);
}
for (i = 0; i < ext_size / UCODE_EXT_SIG_SIZE_INTEL;
i++) {
if (ucode_checksum_intel(0,
i * UCODE_EXT_SIG_SIZE_INTEL])) {
return (EM_CHECKSUM);
}
}
}
remaining -= total_size;
}
return (EM_OK);
}