| /* |
| * 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; |
| } |
| } |