summaryrefslogtreecommitdiffstats
path: root/src/mainboard/scaleway/tagada/bmcinfo.c
blob: 0be5532e38ef0c7584217355377ed4207bf0ae96 (plain)
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/* SPDX-License-Identifier: GPL-2.0-only */

#include <stdint.h>
#include <console/console.h>
#include <console/uart.h>

#include "bmcinfo.h"

typedef struct {
	u32 magic0; // "BMCI"
	u32 magic1; // "nfo0"
	u16 length;
	u16 chksum;
	u8 uuid[16];
	u8 bmcSerial[9]; // as null terminated string
	u8 slot;
	u8 corebootVerbosityLevel;
	u8 relaxSecurity;
	u32 baudrate;
	u8 bootOption;
	u8 hwRev; // Note: Initial implementation ended here
	u8 disableNic1;
	u8 endMarker; // Insert new fields before
} biosBmcInfo_t;

#define BIOSBMCINFO_MAGIC0 0x49434d42
#define BIOSBMCINFO_MAGIC1 0x306f666e


#define BMC_INFO ((biosBmcInfo_t *)CONFIG_BMC_INFO_LOC)

enum biosBmcInfoValidFlag_e {
	BMCINFO_UNTESTED = 0,
	BMCINFO_INVALID,
	BMCINFO_INVALID_WARNED,
	BMCINFO_VALID_NEED_WARN,
	BMCINFO_VALID,
};
static bool bmcinfo_is_valid(size_t minsize)
{
	static enum biosBmcInfoValidFlag_e biosBmcInfoValidFlag;
	const biosBmcInfo_t *bmc_info = BMC_INFO;
	if (biosBmcInfoValidFlag == BMCINFO_UNTESTED) {
		biosBmcInfoValidFlag = BMCINFO_INVALID;
		if ((bmc_info->magic0 == BIOSBMCINFO_MAGIC0)
		 && (bmc_info->magic1 == BIOSBMCINFO_MAGIC1)
		 && (bmc_info->length >= offsetof(biosBmcInfo_t, hwRev))
		 && (bmc_info->length <= 0x1000)) {
			u16 chksum = 0 - (bmc_info->chksum & 0xff)
				- (bmc_info->chksum >> 8);
			int i;
			for (i = 0; i < bmc_info->length ; i++)
				chksum += ((u8 *)bmc_info)[i];
			if (bmc_info->chksum == chksum) {
				if (bmc_info->length >= offsetof(biosBmcInfo_t,
							endMarker))
					biosBmcInfoValidFlag = BMCINFO_VALID;
				else
					biosBmcInfoValidFlag = BMCINFO_VALID_NEED_WARN;
			}
		}
	}
	if (ENV_RAMSTAGE && biosBmcInfoValidFlag == BMCINFO_INVALID) {
		int length = offsetof(biosBmcInfo_t, endMarker);
		printk(BIOS_CRIT, "WARNING bmcInfo struct"
				"is not available please update your BMC.\n");
		biosBmcInfoValidFlag = BMCINFO_INVALID_WARNED;
		printk(BIOS_CRIT, "bmcInfo magic = \"%x-%x\"\n",
				bmc_info->magic0, bmc_info->magic1);
		printk(BIOS_CRIT, "bmcInfo length = %d expected = %d\"\n",
				bmc_info->length, length);
		u16 chksum = 0 - (bmc_info->chksum & 0xff)
			- (bmc_info->chksum >> 8);
		int i;
		for (i = 0; i < bmc_info->length; i++)
			chksum += ((u8 *)bmc_info)[i];
		printk(BIOS_CRIT, "bmcInfo chksum = 0x%x expected = 0x%x\"\n",
				bmc_info->chksum, chksum);
	}
	if (ENV_RAMSTAGE && biosBmcInfoValidFlag == BMCINFO_VALID_NEED_WARN) {
		printk(BIOS_CRIT, "WARNING bmcInfo struct"
				" is incomplete please update your BMC.\n");

		biosBmcInfoValidFlag = BMCINFO_VALID;
	}
	if (biosBmcInfoValidFlag < BMCINFO_VALID_NEED_WARN)
		return false;
	return (bmc_info->length >= minsize);
}

#define IS_BMC_INFO_FIELD_VALID(field) \
	(bmcinfo_is_valid(offsetof(biosBmcInfo_t, field) \
		+ sizeof(((biosBmcInfo_t *)0)->field)))

char *bmcinfo_serial(void)
{
	if (IS_BMC_INFO_FIELD_VALID(bmcSerial))
		return (char *) BMC_INFO->bmcSerial;
	return NULL;
}

u8 *bmcinfo_uuid(void)
{
	if (IS_BMC_INFO_FIELD_VALID(uuid))
		return BMC_INFO->uuid;
	return NULL;
}


int bmcinfo_slot(void)
{
	if (IS_BMC_INFO_FIELD_VALID(slot))
		return BMC_INFO->slot;
	return -1;
}

int bmcinfo_hwrev(void)
{
	if (IS_BMC_INFO_FIELD_VALID(hwRev))
		return BMC_INFO->hwRev;
	return -1;
}

u32 bmcinfo_baudrate(void)
{
	if (IS_BMC_INFO_FIELD_VALID(baudrate))
		return BMC_INFO->baudrate;
	return 0;
}

int bmcinfo_coreboot_verbosity_level(void)
{
	if (IS_BMC_INFO_FIELD_VALID(corebootVerbosityLevel))
		return BMC_INFO->corebootVerbosityLevel & 0xf;
	return BIOS_CRIT;
}

int bmcinfo_fsp_verbosity_level(void)
{
	if (IS_BMC_INFO_FIELD_VALID(corebootVerbosityLevel))
		return BMC_INFO->corebootVerbosityLevel >> 4;
	return 0;
}

int bmcinfo_relax_security(void)
{
	if (IS_BMC_INFO_FIELD_VALID(relaxSecurity))
		return BMC_INFO->relaxSecurity;
	return 0;
}

int bmcinfo_boot_option(void)
{
	if (IS_BMC_INFO_FIELD_VALID(bootOption))
		return BMC_INFO->bootOption;
	return 0;
}

int bmcinfo_disable_nic1(void)
{
	if (IS_BMC_INFO_FIELD_VALID(disableNic1))
		return BMC_INFO->disableNic1;
	return 0;
}

/* Add override functions below */

/* Override default uart baudrate */
unsigned int get_uart_baudrate(void)
{
	int baudrate = bmcinfo_baudrate();
	if (baudrate)
		return baudrate;
	return 115200;
}

#if __CONSOLE_ENABLE__
/* Override default console loglevel */
int get_console_loglevel(void)
{
	return bmcinfo_coreboot_verbosity_level();
}
#endif