1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
/*
* 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.
*/
#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_boot_map_with_leak(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 = cbfs_boot_map_with_leak(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;
}
}
|