blob: 95bb76cecea95f2e0fd335d0b2e8e0e5ac2c664b [file] [log] [blame]
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2014 Siemens AG.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "modhwinfo.h"
#include "lcd_panel.h"
#include <cbfs.h>
#include <string.h>
/** \brief This function will find the first linked info block.
* @param *filename Filename in cbfs
* @param *file_offset Pointer to the offset of the cbfs file contents
* @return u8* Pointer to the found block
*/
u8* get_first_linked_block(char *filename, u8 **file_offset)
{
u8* block_ptr = NULL;
block_ptr = (cbfs_get_file_content(CBFS_DEFAULT_MEDIA, filename,
0x50, NULL));
if (!block_ptr)
return NULL;
if (!strncmp((char*)block_ptr, "H1W2M3I4", LEN_MAGIC_NUM)) {
if ((*((u16*)(block_ptr + HWI_LEN_OFFSET)) == LEN_MAIN_HWINFO) &&
(*((s32*)(block_ptr + NEXT_OFFSET_HWINFO)) != 0x00)) {
*file_offset = block_ptr;
return *((s32*)(block_ptr + NEXT_OFFSET_HWINFO)) + block_ptr;
} else
return NULL;
} else if (!strncmp((char*)block_ptr, "H1W2M3I5", LEN_MAGIC_NUM)) {
*file_offset = block_ptr;
return block_ptr;
} else
return NULL;
}
/** \brief This function will find the main info block
* @param *filename Filename in cbfs
* @return *hwinfo Pointer to the data of the main info block
*/
struct hwinfo* get_hwinfo(char *filename)
{
struct hwinfo* main_hwinfo;
main_hwinfo = (struct hwinfo*)(cbfs_get_file_content(CBFS_DEFAULT_MEDIA,
filename, 0x50, NULL));
if ((main_hwinfo) &&
(!strncmp(main_hwinfo->magicNumber, "H1W2M3I4", LEN_MAGIC_NUM)) &&
(main_hwinfo->length == LEN_MAIN_HWINFO))
return main_hwinfo;
else
return NULL;
}
/** \brief This function will find the short info block
* @param *filename Filename in cbfs
* @return *shortinfo Pointer to the data of the short info block
*/
struct shortinfo* get_shortinfo(char *filename)
{
u8 *block_ptr = NULL;
u8 *file_offset = NULL;
block_ptr = get_first_linked_block(filename, &file_offset);
if ((block_ptr == NULL) ||
(strncmp((char*)block_ptr, "H1W2M3I5", LEN_MAGIC_NUM)))
return NULL;
if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_SHORT_INFO)
return (struct shortinfo *)block_ptr;
block_ptr = (file_offset + *((s32*)(block_ptr + NEXT_OFFSET_EDID)));
if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_SHORT_INFO)
return (struct shortinfo *)block_ptr;
else
return NULL;
}
/** \brief This function will find the edid info block
* @param *filename Filename in cbfs
* @return *edidinfo Pointer to the data of the edid info block
*/
struct edidinfo* get_edidinfo(char *filename)
{
u8 *block_ptr = NULL;
u8 *file_offset = NULL;
block_ptr = get_first_linked_block(filename, &file_offset);
if ((block_ptr == NULL) ||
(strncmp((char*)block_ptr, "H1W2M3I5", LEN_MAGIC_NUM)))
return NULL;
if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_EDID_INFO)
return (struct edidinfo *)block_ptr;
block_ptr = (file_offset + *((s32*)(block_ptr + NEXT_OFFSET_SIB)));
if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_EDID_INFO)
return (struct edidinfo *)block_ptr;
else
return NULL;
}
/** \brief This function will search for a MAC address which can be assigned
* to a MACPHY.
* @param pci_bdf Bus, device and function of the given PCI-device
* @param mac buffer where to store the MAC address
* @return cb_err CB_ERR or CB_SUCCESS
*/
enum cb_err mainboard_get_mac_address(u16 bus, u8 devfn, u8 mac[6])
{
struct hwinfo* main_hwinfo;
u32 i;
main_hwinfo = get_hwinfo((char*)"hwinfo.hex");
if (!main_hwinfo)
return CB_ERR;
/* Ensure the first MAC-Address is not completely 0x00 or 0xff */
for (i = 0; i < 6; i++) {
if (main_hwinfo->macAddress1[i] != 0xFF)
break;
}
if (i == 6){
return CB_ERR;
}
for (i = 0; i < 6; i++) {
if (main_hwinfo->macAddress1[i] != 0x00)
break;
}
if (i == 6){
return CB_ERR;
} else {
memcpy(mac, main_hwinfo->macAddress1, 6);
return CB_SUCCESS;
}
}