/
githubmirror
/
flashrom
Обзор
Документация
Войти
/
githubmirror
/
flashrom
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
read_extended.c
114 строк
3 KB
Antonio Vázquez Blanco
log.h: Extract log declarations to a separate header
16 июн 2026, 09:04
16 июн 2026, 09:04
2739025
Код
Авторство
О чём код?
/* * This file is part of the flashrom project. * * SPDX-License-Identifier: GPL-2.0-or-later * SPDX-FileCopyrightText: 2026 Abdelkader Boudih <coreboot@seuros.com> */ #include <stdlib.h> #include "platform/string.h" #include "log.h" #include "flash.h" #include "libflashrom.h" #include "read_extended.h" struct read_candidate { int count; unsigned char *buf; }; int read_repeated(struct flashctx *const flash, int count, unsigned char **result_buf, size_t *result_size) { const size_t size = flashrom_flash_getsize(flash); int ret = 0; int num_candidates = 0; /* Each read is compared against known candidates via memcmp. * A new buffer is only allocated when previously unseen content * is encountered. In the common case (stable chip) only one * buffer is allocated regardless of count. */ struct read_candidate *candidates = calloc(count, sizeof(*candidates)); unsigned char *buf = calloc(size, 1); if (!candidates || !buf) { msg_gerr("Memory allocation failed!\n"); ret = 1; goto free_out; } msg_ginfo("Performing %d reads to check connection stability...\n", count); for (int i = 0; i < count; i++) { msg_ginfo("Read %d/%d...\n", i + 1, count); ret = flashrom_image_read(flash, buf, size); if (ret) { msg_gerr("Read %d failed!\n", i + 1); goto free_out; } int found = -1; for (int j = 0; j < num_candidates; j++) { if (memcmp(candidates[j].buf, buf, size) == 0) { found = j; break; } } if (found >= 0) { candidates[found].count++; } else { unsigned char *stored = malloc(size); if (!stored) { msg_gerr("Memory allocation failed!\n"); ret = 1; goto free_out; } memcpy(stored, buf, size); candidates[num_candidates].count = 1; candidates[num_candidates].buf = stored; num_candidates++; } } if (num_candidates == 0) { msg_gerr("All %d reads failed.\n", count); ret = 1; goto free_out; } /* Find the most frequent read. */ int best = 0; for (int j = 1; j < num_candidates; j++) { if (candidates[j].count > candidates[best].count) best = j; } const int best_count = candidates[best].count; msg_ginfo("%d/%d reads matched.\n", best_count, count); /* Require a strict majority (> 50%). A tie is treated as a failure * since it gives no confidence about which read is correct. */ if (best_count * 2 <= count) { msg_gerr("No majority read found — connection is too unstable to trust.\n"); ret = 1; } else { if (best_count < count) msg_gwarn("Warning: only %d/%d reads matched — connection may be flaky.\n", best_count, count); else msg_ginfo("All reads match. Flash connection looks stable.\n"); /* Hand ownership of the winning buffer to the caller. */ *result_buf = candidates[best].buf; *result_size = size; candidates[best].buf = NULL; /* prevent free below */ } free_out: free(buf); for (int j = 0; j < num_candidates; j++) free(candidates[j].buf); free(candidates); return ret; }