Skip to content

Commit e999d7b

Browse files
committed
add structured flash flags for boot options
structured flags are used to store some bios settings in EC flash. This allows the EC to persist boot settings required before bios completion across reboots if RTC battery is not present. 12th gen mainboards do not require RTC battery to be installed if the main battery is installed. Signed-off-by: Kieran Levin <ktl@frame.work>
1 parent 29393cb commit e999d7b

7 files changed

Lines changed: 258 additions & 82 deletions

File tree

.github/workflows/lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
2222
- name: checkpatch
2323
run: |
24-
git diff origin/${{ github.base_ref }} | ./checkpatch.pl --mailback --no-tree --ignore MAINTAINERS,FILE_PATH_CHANGES - > checkpatch.txt || true
24+
git diff origin/${{ github.base_ref }} | ./checkpatch.pl --mailback --no-tree --ignore MAINTAINERS,FILE_PATH_CHANGES,SPDX_LICENSE_TAG - > checkpatch.txt || true
2525
if [ -s checkpatch.txt ]; then
2626
errors=$(cat checkpatch.txt)
2727
errors="${errors//'%'/'%25'}"

board/hx30/board.c

Lines changed: 5 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
#include "keyboard_8042.h"
7575
#include "keyboard_8042_sharedlib.h"
7676
#include "host_command_customization.h"
77+
#include "flash_storage.h"
7778

7879
/* Console output macros */
7980
#define CPUTS(outstr) cputs(CC_LPC, outstr)
@@ -372,7 +373,6 @@ void board_reset_pd_mcu(void)
372373

373374
}
374375

375-
#define SPI_FLAGS_REGION 0x80000
376376

377377
void spi_mux_control(int enable)
378378
{
@@ -390,52 +390,13 @@ void spi_mux_control(int enable)
390390
}
391391

392392

393-
void board_spi_read_byte(uint8_t offset, uint8_t *data)
394-
{
395-
int rv;
396-
397-
spi_mux_control(1);
398-
399-
rv = spi_flash_read(data, SPI_FLAGS_REGION + offset, 0x01);
400-
if (rv != EC_SUCCESS)
401-
CPRINTS("SPI fail to read");
402-
403-
CPRINTS("%s, offset:0x%02x, data:0x%02x", __func__, offset, *data);
404-
405-
spi_mux_control(0);
406-
}
407-
408-
void board_spi_write_byte(uint8_t offset, uint8_t data)
409-
{
410-
int rv;
411-
412-
spi_mux_control(1);
413-
414-
rv = spi_flash_erase(SPI_FLAGS_REGION, 0x1000);
415-
416-
if (rv != EC_SUCCESS)
417-
CPRINTS("SPI fail to erase");
418-
419-
rv = spi_flash_write(SPI_FLAGS_REGION + offset, 0x01, &data);
420-
421-
if (rv != EC_SUCCESS)
422-
CPRINTS("SPI fail to write");
423-
424-
CPRINTS("%s, offset:0x%02x, data:0x%02x", __func__, offset, data);
425-
426-
spi_mux_control(0);
427-
}
428393

429394
/**
430395
* Check the plug-in AC then power on system setting.
431396
*/
432397
bool ac_poweron_check(void)
433398
{
434-
uint8_t memcap;
435-
436-
board_spi_read_byte(SPI_BIOS_SETUP, &memcap);
437-
438-
return (memcap & BIOS_SETUP_AC_BOOT) ? true : false;
399+
return flash_storage_get(FLASH_FLAGS_ACPOWERON);
439400
}
440401

441402
int poweron_reason_acin(void)
@@ -669,14 +630,11 @@ void charger_psys_enable(uint8_t enable)
669630
/* Initialize board. */
670631
static void board_init(void)
671632
{
672-
uint8_t memcap;
673633

674-
board_spi_read_byte(SPI_BIOS_SETUP, &memcap);
634+
if (flash_storage_get(FLASH_FLAGS_ACPOWERON) && !ac_boot_status())
635+
*host_get_customer_memmap(0x48) = flash_storage_get(FLASH_FLAGS_ACPOWERON);
675636

676-
if ((memcap & BIOS_SETUP_AC_BOOT) && !ac_boot_status())
677-
*host_get_customer_memmap(0x48) = (memcap & BIOS_SETUP_AC_BOOT);
678-
679-
if (memcap & BIOS_SETUP_STANDALONE)
637+
if (flash_storage_get(FLASH_FLAGS_STANDALONE))
680638
set_standalone_mode(1);
681639

682640
check_chassis_open(1);
@@ -1264,24 +1222,6 @@ DECLARE_CONSOLE_COMMAND(spimux, cmd_spimux,
12641222
"[enable/disable]",
12651223
"Set if spi CLK is in SPI mode (true) or PWM mode");
12661224

1267-
1268-
static int cmd_boardspicontrol(int argc, char **argv)
1269-
{
1270-
uint8_t data;
1271-
1272-
if (!strcasecmp(argv[1], "read")) {
1273-
board_spi_read_byte(0x01, &data);
1274-
CPRINTS("DEBUG: cmd get data:0x%02x", data);
1275-
} else if (!strcasecmp(argv[1], "write")) {
1276-
board_spi_write_byte(0x01, 0xAA);
1277-
}
1278-
1279-
return EC_SUCCESS;
1280-
}
1281-
DECLARE_CONSOLE_COMMAND(boardspi, cmd_boardspicontrol,
1282-
"[read/write]",
1283-
"test");
1284-
12851225
#define FP_LOCKOUT_TIMEOUT (8 * SECOND)
12861226
static void fingerprint_ctrl_detection_deferred(void);
12871227
DECLARE_DEFERRED(fingerprint_ctrl_detection_deferred);

board/hx30/board.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,8 @@ int poweron_reason_acin(void);
781781

782782
enum battery_present board_batt_is_present(void);
783783

784+
void spi_mux_control(int enable);
785+
784786
#ifdef CONFIG_EMI_REGION1
785787
void power_state_clear(int state);
786788
#endif

board/hx30/build.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ CHIP_VARIANT:=mec152x_3400
1717

1818
CHIP_SPI_SIZE_KB:=512
1919

20-
board-y=board.o led.o power_sequence.o cypress5525.o ucsi.o diagnostics.o cpu_power.o
20+
board-y=board.o led.o power_sequence.o cypress5525.o ucsi.o diagnostics.o cpu_power.o flash_storage.o
2121
board-$(CONFIG_BATTERY_SMART)+=battery.o
2222
board-$(CONFIG_FANS)+=fan.o
2323
board-$(CONFIG_KEYBOARD_CUSTOMIZATION)+=keyboard_customization.o

board/hx30/flash_storage.c

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/* Copyright 2022 The Chromium OS Authors. All rights reserved.
2+
* Use of this source code is governed by a BSD-style license that can be
3+
* found in the LICENSE file.
4+
*/
5+
6+
#include "util.h"
7+
#include "hooks.h"
8+
9+
#include "board.h"
10+
#include "gpio.h"
11+
12+
#include "spi.h"
13+
#include "spi_chip.h"
14+
#include "spi_flash.h"
15+
16+
#include "flash_storage.h"
17+
18+
19+
20+
21+
22+
23+
#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)
24+
#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args)
25+
26+
static struct ec_flash_flags_info current_flags;
27+
bool flash_storage_dirty;
28+
29+
bool check_flags_valid_header(void)
30+
{
31+
if (current_flags.magic != FLASH_FLAGS_MAGIC ||
32+
current_flags.length != (sizeof(current_flags) - 8) ||
33+
current_flags.version != FLASH_FLAGS_VERSION) {
34+
return false;
35+
} else {
36+
return true;
37+
}
38+
}
39+
40+
void flash_storage_load_defaults(void)
41+
{
42+
CPRINTS("Init flash storage to defaults");
43+
memset(&current_flags, 0x00, sizeof(current_flags));
44+
current_flags.magic = FLASH_FLAGS_MAGIC;
45+
current_flags.length = (sizeof(current_flags) - 8);
46+
current_flags.version = FLASH_FLAGS_VERSION;
47+
flash_storage_dirty = true;
48+
}
49+
50+
int flash_storage_initialize(void)
51+
{
52+
53+
int rv;
54+
55+
spi_mux_control(1);
56+
57+
rv = spi_flash_read((void *)&current_flags, SPI_FLAGS_REGION, sizeof(current_flags));
58+
if (rv != EC_SUCCESS)
59+
CPRINTS("Could not load flash storage");
60+
61+
spi_mux_control(0);
62+
63+
/*Check structure is valid*/
64+
if (check_flags_valid_header() == false) {
65+
CPRINTS("loading flash default flags");
66+
flash_storage_load_defaults();
67+
}
68+
69+
return rv;
70+
}
71+
72+
int flash_storage_update(enum ec_flash_flags_idx idx, uint8_t v)
73+
{
74+
if (idx >= FLASH_FLAGS_MAX)
75+
return EC_ERROR_PARAM1;
76+
77+
if (check_flags_valid_header() == false)
78+
flash_storage_initialize();
79+
80+
if (current_flags.flags[idx] != v) {
81+
current_flags.flags[idx] = v;
82+
flash_storage_dirty = true;
83+
}
84+
return EC_SUCCESS;
85+
}
86+
87+
int flash_storage_commit(void)
88+
{
89+
int rv = EC_SUCCESS;
90+
91+
if (check_flags_valid_header() == false)
92+
flash_storage_initialize();
93+
94+
if (flash_storage_dirty) {
95+
96+
spi_mux_control(1);
97+
98+
rv = spi_flash_erase(SPI_FLAGS_REGION, 0x1000);
99+
100+
if (rv != EC_SUCCESS) {
101+
CPRINTS("SPI fail to erase");
102+
goto fail;
103+
}
104+
105+
current_flags.update_number += 1;
106+
107+
rv = spi_flash_write(SPI_FLAGS_REGION,
108+
sizeof(current_flags),
109+
(void *)&current_flags);
110+
111+
if (rv != EC_SUCCESS) {
112+
CPRINTS("SPI fail to write");
113+
goto fail;
114+
}
115+
116+
CPRINTS("%s, update:%d", __func__, current_flags.update_number);
117+
118+
spi_mux_control(0);
119+
flash_storage_dirty = false;
120+
}
121+
122+
return rv;
123+
124+
fail:
125+
spi_mux_control(0);
126+
return rv;
127+
}
128+
129+
int flash_storage_get(enum ec_flash_flags_idx idx)
130+
{
131+
if (idx >= FLASH_FLAGS_MAX)
132+
return -1;
133+
134+
if (check_flags_valid_header() == false)
135+
flash_storage_initialize();
136+
137+
return current_flags.flags[idx];
138+
}
139+
140+
static int cmd_flash_flags(int argc, char **argv)
141+
{
142+
int data;
143+
int i, d;
144+
char *e;
145+
146+
147+
if (argc >= 3) {
148+
149+
i = strtoi(argv[2], &e, 0);
150+
151+
if (*e)
152+
return EC_ERROR_PARAM2;
153+
154+
if (!strcasecmp(argv[1], "read")) {
155+
data = flash_storage_get(i);
156+
CPRINTS("Flash data:%d", data);
157+
} else if (argc >= 4 && !strcasecmp(argv[1], "write")) {
158+
159+
d = strtoi(argv[3], &e, 0);
160+
if (*e)
161+
return EC_ERROR_PARAM3;
162+
flash_storage_update(i, d);
163+
flash_storage_commit();
164+
} else {
165+
return EC_ERROR_PARAM3;
166+
}
167+
return EC_SUCCESS;
168+
}
169+
170+
return EC_ERROR_PARAM2;
171+
}
172+
DECLARE_CONSOLE_COMMAND(flashflag, cmd_flash_flags,
173+
"[read/write] i [d]",
174+
"read or write bytes from flags structure");

board/hx30/flash_storage.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/* Copyright 2022 The Chromium OS Authors. All rights reserved.
2+
* Use of this source code is governed by a BSD-style license that can be
3+
* found in the LICENSE file.
4+
*
5+
* flash storage function for seldom updated flash flags
6+
*/
7+
8+
#ifndef __CROS_EC_FLASHSTORAGE_H
9+
#define __CROS_EC_FLASHSTORAGE_H
10+
11+
#define SPI_FLAGS_REGION (0x80000)
12+
13+
enum ec_flash_flags_idx {
14+
FLASH_FLAGS_ACPOWERON = 0,
15+
FLASH_FLAGS_STANDALONE = 1,
16+
FLASH_FLAGS_MAX = 64
17+
};
18+
19+
#define FLASH_FLAGS_MAGIC (0xF1A3)
20+
#define FLASH_FLAGS_VERSION (0x1)
21+
22+
struct ec_flash_flags_info {
23+
/* Header */
24+
uint32_t magic; /* 0xF1A3 */
25+
uint32_t length; /* Length of fields following this */
26+
uint32_t version; /* Version=1, update this if field structures below this change */
27+
/**
28+
* An incrementing counter that should be incremented
29+
* every time the structure is written to flash
30+
*/
31+
uint32_t update_number;
32+
33+
uint8_t flags[FLASH_FLAGS_MAX];
34+
35+
} __ec_align1;
36+
37+
/**
38+
* @brief Update flags value at idx, but does not write to flash
39+
*
40+
* @param idx ec_flash_flags_idx for which flag to update
41+
* @param v uint8_t new value
42+
* @return int EC_SUCCESS
43+
*/
44+
int flash_storage_update(enum ec_flash_flags_idx idx, uint8_t v);
45+
46+
/**
47+
* @brief Commits storage if dirty
48+
*
49+
* @return int EC_SUCCESS
50+
*/
51+
int flash_storage_commit(void);
52+
53+
/**
54+
* @brief Get flags value
55+
*
56+
* @param idx index of flag to get
57+
* @return int flag value, or -1 on failure
58+
*/
59+
int flash_storage_get(enum ec_flash_flags_idx idx);
60+
61+
/**
62+
* @brief Initialize structure in memory, does not update flash
63+
*
64+
* @return int EC_SUCCESS
65+
*/
66+
void flash_storage_load_defaults(void);
67+
68+
#endif /* __CROS_EC_FLASHSTORAGE_H */

0 commit comments

Comments
 (0)