blob: ac7404b4fbb6d365dd3e7dc4161866ae9b09ef86 [file] [log] [blame]
Werner Zehc42a6132015-02-12 12:40:15 +01001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2014 Siemens AG.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Werner Zehc42a6132015-02-12 12:40:15 +010014 */
15
16#include "modhwinfo.h"
17#include "lcd_panel.h"
18#include <cbfs.h>
19#include <string.h>
20
21/** \brief This function will find the first linked info block.
22 * @param *filename Filename in cbfs
23 * @param *file_offset Pointer to the offset of the cbfs file contents
24 * @return u8* Pointer to the found block
25 */
26u8* get_first_linked_block(char *filename, u8 **file_offset)
27{
28 u8* block_ptr = NULL;
29
Aaron Durbin899d13d2015-05-15 23:39:23 -050030 block_ptr = cbfs_boot_map_with_leak(filename, 0x50, NULL);
Werner Zehc42a6132015-02-12 12:40:15 +010031 if (!block_ptr)
32 return NULL;
33 if (!strncmp((char*)block_ptr, "H1W2M3I4", LEN_MAGIC_NUM)) {
34 if ((*((u16*)(block_ptr + HWI_LEN_OFFSET)) == LEN_MAIN_HWINFO) &&
35 (*((s32*)(block_ptr + NEXT_OFFSET_HWINFO)) != 0x00)) {
36 *file_offset = block_ptr;
37 return *((s32*)(block_ptr + NEXT_OFFSET_HWINFO)) + block_ptr;
38 } else
39 return NULL;
40 } else if (!strncmp((char*)block_ptr, "H1W2M3I5", LEN_MAGIC_NUM)) {
41 *file_offset = block_ptr;
42 return block_ptr;
43 } else
44 return NULL;
45}
46
47/** \brief This function will find the main info block
48 * @param *filename Filename in cbfs
49 * @return *hwinfo Pointer to the data of the main info block
50 */
51struct hwinfo* get_hwinfo(char *filename)
52{
53 struct hwinfo* main_hwinfo;
54
Aaron Durbin899d13d2015-05-15 23:39:23 -050055 main_hwinfo = cbfs_boot_map_with_leak(filename, 0x50, NULL);
Werner Zehc42a6132015-02-12 12:40:15 +010056 if ((main_hwinfo) &&
57 (!strncmp(main_hwinfo->magicNumber, "H1W2M3I4", LEN_MAGIC_NUM)) &&
58 (main_hwinfo->length == LEN_MAIN_HWINFO))
59 return main_hwinfo;
60 else
61 return NULL;
62}
63
64/** \brief This function will find the short info block
65 * @param *filename Filename in cbfs
66 * @return *shortinfo Pointer to the data of the short info block
67 */
68struct shortinfo* get_shortinfo(char *filename)
69{
70 u8 *block_ptr = NULL;
71 u8 *file_offset = NULL;
72
73 block_ptr = get_first_linked_block(filename, &file_offset);
74 if ((block_ptr == NULL) ||
75 (strncmp((char*)block_ptr, "H1W2M3I5", LEN_MAGIC_NUM)))
76 return NULL;
77
78 if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_SHORT_INFO)
79 return (struct shortinfo *)block_ptr;
80
81 block_ptr = (file_offset + *((s32*)(block_ptr + NEXT_OFFSET_EDID)));
82 if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_SHORT_INFO)
83 return (struct shortinfo *)block_ptr;
84 else
85 return NULL;
86}
87
88/** \brief This function will find the edid info block
89 * @param *filename Filename in cbfs
90 * @return *edidinfo Pointer to the data of the edid info block
91 */
92struct edidinfo* get_edidinfo(char *filename)
93{
94 u8 *block_ptr = NULL;
95 u8 *file_offset = NULL;
96
97 block_ptr = get_first_linked_block(filename, &file_offset);
98 if ((block_ptr == NULL) ||
99 (strncmp((char*)block_ptr, "H1W2M3I5", LEN_MAGIC_NUM)))
100 return NULL;
101
102 if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_EDID_INFO)
103 return (struct edidinfo *)block_ptr;
104
105 block_ptr = (file_offset + *((s32*)(block_ptr + NEXT_OFFSET_SIB)));
106 if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_EDID_INFO)
107 return (struct edidinfo *)block_ptr;
108 else
109 return NULL;
110}
111
112/** \brief This function will search for a MAC address which can be assigned
113 * to a MACPHY.
114 * @param pci_bdf Bus, device and function of the given PCI-device
115 * @param mac buffer where to store the MAC address
116 * @return cb_err CB_ERR or CB_SUCCESS
117 */
118enum cb_err mainboard_get_mac_address(u16 bus, u8 devfn, u8 mac[6])
119{
120 struct hwinfo* main_hwinfo;
121 u32 i;
122
123 main_hwinfo = get_hwinfo((char*)"hwinfo.hex");
124 if (!main_hwinfo)
125 return CB_ERR;
126 /* Ensure the first MAC-Address is not completely 0x00 or 0xff */
127 for (i = 0; i < 6; i++) {
128 if (main_hwinfo->macAddress1[i] != 0xFF)
129 break;
130 }
131 if (i == 6){
132 return CB_ERR;
133 }
134 for (i = 0; i < 6; i++) {
135 if (main_hwinfo->macAddress1[i] != 0x00)
136 break;
137 }
138 if (i == 6){
139 return CB_ERR;
140 } else {
141 memcpy(mac, main_hwinfo->macAddress1, 6);
142 return CB_SUCCESS;
143 }
144}