71 #include <sys/ioctl.h>
76 #include <bits/wordsize.h>
83 #define mei_msg(_me, fmt, ARGS...) do { \
85 fprintf(stderr, fmt, ##ARGS); \
88 #define mei_err(_me, fmt, ARGS...) do { \
89 fprintf(stderr, "Error: " fmt, ##ARGS); \
101 static void mei_deinit(
struct mei *
cl)
111 static bool mei_init(
struct mei *me,
const uuid_le *guid,
112 unsigned char req_protocol_version,
bool verbose)
124 mei_err(me,
"Cannot establish a handle to the Intel MEI driver\n");
134 mei_err(me,
"IOCTL_MEI_CONNECT_CLIENT receive message. err=%d\n", result);
137 cl = &
data.out_client_properties;
141 if ((req_protocol_version > 0) &&
143 mei_err(me,
"Intel MEI protocol version not supported\n");
157 ssize_t len,
unsigned long timeout)
161 mei_msg(me,
"call read length = %zd\n", len);
163 rc =
read(me->
fd, buffer, len);
165 mei_err(me,
"read failed with status %zd %s\n",
169 mei_msg(me,
"read succeeded with result %zd\n", rc);
174 static ssize_t mei_send_msg(
struct mei *me,
const unsigned char *buffer,
175 ssize_t len,
unsigned long timeout)
182 tv.tv_sec = timeout / 1000;
183 tv.tv_usec = (timeout % 1000) * 1000000;
185 mei_msg(me,
"call write length = %zd\n", len);
187 written =
write(me->
fd, buffer, len);
190 mei_err(me,
"write failed with status %zd %s\n",
196 FD_SET(me->
fd, &
set);
198 if (rc > 0 && FD_ISSET(me->
fd, &
set)) {
199 mei_msg(me,
"write success\n");
200 }
else if (rc == 0) {
201 mei_err(me,
"write failed on timeout with status\n");
204 mei_err(me,
"write failed on select with status %zd\n", rc);
220 #define AMT_MAJOR_VERSION 1
221 #define AMT_MINOR_VERSION 1
223 #define AMT_STATUS_SUCCESS 0x0
224 #define AMT_STATUS_INTERNAL_ERROR 0x1
225 #define AMT_STATUS_NOT_READY 0x2
226 #define AMT_STATUS_INVALID_AMT_MODE 0x3
227 #define AMT_STATUS_INVALID_MESSAGE_LENGTH 0x4
229 #define AMT_STATUS_HOST_IF_EMPTY_RESPONSE 0x4000
230 #define AMT_STATUS_SDK_RESOURCES 0x1004
233 #define AMT_BIOS_VERSION_LEN 65
234 #define AMT_VERSIONS_NUMBER 50
235 #define AMT_UNICODE_STRING_LEN 20
276 0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c);
278 #define AMT_HOST_IF_CODE_VERSIONS_REQUEST 0x0400001A
279 #define AMT_HOST_IF_CODE_VERSIONS_RESPONSE 0x0480001A
296 static bool amt_host_if_init(
struct amt_host_if *acmd,
297 unsigned long send_timeout,
bool verbose)
299 acmd->
send_timeout = (send_timeout) ? send_timeout : 20000;
304 static void amt_host_if_deinit(
struct amt_host_if *acmd)
306 mei_deinit(&acmd->
mei_cl);
322 ver_type_cnt = code_ver_len -
323 sizeof(code_ver->
bios) -
324 sizeof(code_ver->
count);
330 for (i = 0; i < code_ver->
count; i++) {
331 len = code_ver->
versions[
i].description.length;
338 len = code_ver->
versions[
i].version.length;
339 if (code_ver->
versions[i].version.string[len] !=
'\0' ||
355 }
else if (response_size != (resp_hdr->
length +
358 }
else if (resp_hdr->
command != command) {
370 const unsigned char *command,
ssize_t command_sz,
372 unsigned int expected_sz)
380 in_buf_sz = acmd->
mei_cl.buf_size;
382 if (*read_buf ==
NULL)
384 memset(*read_buf, 0, in_buf_sz);
387 written = mei_send_msg(&acmd->
mei_cl,
389 if (written != command_sz)
392 out_buf_sz = mei_recv_msg(&acmd->
mei_cl, *read_buf, in_buf_sz, 2000);
400 status = amt_verify_response_header(rcmd,
401 &msg_hdr->
header, out_buf_sz);
405 if (expected_sz && expected_sz != out_buf_sz)
418 status = amt_host_if_call(cmd,
419 (
const unsigned char *)&CODE_VERSION_REQ,
420 sizeof(CODE_VERSION_REQ),
427 status = amt_verify_code_versions(response);
433 if (response !=
NULL)
449 verbose = (argc > 1 &&
strcmp(argv[1],
"-v") == 0);
451 if (!amt_host_if_init(&acmd, 5000, verbose)) {
456 status = amt_get_code_versions(&acmd, &ver);
458 amt_host_if_deinit(&acmd);
462 printf(
"Intel AMT: DISABLED\n");
466 printf(
"Intel AMT: ENABLED\n");
467 for (i = 0; i < ver.
count; i++) {
474 printf(
"An error has occurred\n");