tree: Bring tree into a re-enterent state
This is a rather large change that has been attempted before in,
`commit 63b92f99a9d43dd637bcce564cd372be3c81c5d8`
and quickly reverted in,
`commit ac1d25c100bcd37075ec4b674a16f54edcd31d94`
This was again tried later in,
`commit bcae375630ea8a9bfd3645700451209fb98b66eb`
however had to be reverted in
`commit 65eb881cf669fff21c6da4302762abaac3bf105a`.
The problem was largely to do with how the old alias mechanism was
implemented in,
`commit ba0827acee4da6740133345f43aae386923bbaad`.
and all the laying violations of cros_ec. These combined with other
tree misc divergences caused significant problems trying to adopt the
upstreams cleaner re-enterent state management control flow structures.
Since we have now removed the poorly implemented aliasing mechanism
and boxed down the cros_ec laying violations to only a small section
of flashrom.c we can proceed to finally bring about a convergence with
upstreams control-flow structure. This then entirely aligns our tree
with upstreams control flow at its core.
Drivers are then split into three main types:
i ) opaque,
ii ) par &&,
iii) spi.
where each type has a struct-typed state machine heap allocation
registered into `registered_masters`. The three pointer types are
collected together into an anon-union within the flashctx core
structure. This flashctx structure is largely passed around via the
entire life-time of the program and therefore accessable via most
functions. Each of the three driver types also contain an abstract heap
allocation untyped with `void *` called `data` that allows each driver
to maintain its own internal state machine as it sees fit in a
re-enterent fashion. This bounded life-time of internal state machines
for each driver allows each driver to be reasoned about as a monadic
unit of work and therefore the control flow to be linear across the
three. As for the differences between the types, spi being the obvious
one for SPI buses, opaque being for drivers that wrap other underlying
mechanisms such as a char driver provided by the kernel. The last driver
type 'par` is a little special parallel one that is infrequently used. A
caller can determine which pointer to use via bifurcating upon the buses
state within the flashctx and therefore picking the correct pointer type
from the anon-union.
We have to squash in many changes together to make this an atomic switch
over as things become hard to debug doing these changes bit by bit.
Squash in;
flashrom.c: Make all par_master chip ops re-enterent
register_par_master() should no longer need to be a singleton state and
instead use the internal state machine to register all par_masters just
as upstream does. Only dummyflasher is used for the purposes of
chromiumos afaik.
Squash in;
programmer.h: unwind b/171755805 hack
cli_classic.c: fixes for register_spi_master
opaque.c: Make opaque masters re-enterent
cli_classic.c: Align with upstream count_max_decode_exceedings()
kill buses_supported global
spi.c, tree: Make spi_master re-enterent
take bitbang_spi.c verbatim from upstream.
BUG=b:170440733,b:165100282
BRANCH=none
TEST=builds, confirm 'ec:type=fp' functions, many DUT's spot checked.
Signed-off-by: Edward O'Callaghan <quasisec@google.com>
Change-Id: I29d757e86099344591f833361628fa48ccb01565
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/flashrom/+/2512924
Commit-Queue: Edward O'Callaghan <quasisec@chromium.org>
Tested-by: Edward O'Callaghan <quasisec@chromium.org>
Reviewed-by: Sam McNally <sammc@chromium.org>
diff --git a/programmer.h b/programmer.h
index 5ddc50c..ad79ba5 100644
--- a/programmer.h
+++ b/programmer.h
@@ -208,7 +208,9 @@
int (*get_miso) (void);
void (*request_bus) (void);
void (*release_bus) (void);
-
+ /* optional functions to optimize xfers */
+ void (*set_sck_set_mosi) (int sck, int mosi);
+ int (*set_sck_get_miso) (int sck);
/* Length of half a clock period in usecs. */
unsigned int half_period;
};
@@ -630,12 +632,10 @@
extern struct decode_sizes max_rom_decode;
extern int programmer_may_write;
extern unsigned long flashbase;
-int check_max_decode(enum chipbustype buses, uint32_t size);
+unsigned int count_max_decode_exceedings(const struct flashctx *flash);
char *extract_programmer_param(const char *param_name);
/* spi.c */
-extern const int spi_master_count;
-
#define MAX_DATA_UNSPECIFIED 0
#define MAX_DATA_READ_UNLIMITED 64 * 1024
#define MAX_DATA_WRITE_UNLIMITED 256
@@ -646,8 +646,8 @@
struct spi_master {
uint32_t features;
- unsigned int max_data_read;
- unsigned int max_data_write;
+ unsigned int max_data_read; // (Ideally,) maximum data read size in one go (excluding opcode+address).
+ unsigned int max_data_write; // (Ideally,) maximum data write size in one go (excluding opcode+address).
int (*command)(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
const unsigned char *writearr, unsigned char *readarr);
int (*multicommand)(const struct flashctx *flash, struct spi_command *cmds);
@@ -659,14 +659,13 @@
const void *data;
};
-extern const struct spi_master *spi_master;
int default_spi_send_command(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
const unsigned char *writearr, unsigned char *readarr);
int default_spi_send_multicommand(const struct flashctx *flash, struct spi_command *cmds);
int default_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
int default_spi_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len);
int default_spi_write_aai(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len);
-int register_spi_master(const struct spi_master *programmer);
+int register_spi_master(const struct spi_master *mst);
/* The following enum is needed by ich_descriptor_tool and ich* code as well as in chipset_enable.c. */
enum ich_chipset {
@@ -759,8 +758,7 @@
int (*check_access) (const struct flashctx *flash, unsigned int start, unsigned int len, int read);
const void *data;
};
-extern struct opaque_master *opaque_master;
-void register_opaque_master(struct opaque_master *pgm);
+int register_opaque_master(const struct opaque_master *mst);
/* programmer.c */
int noop_shutdown(void);
@@ -785,8 +783,7 @@
void (*chip_readn) (const struct flashctx *flash, uint8_t *buf, const chipaddr addr, size_t len);
const void *data;
};
-extern const struct par_master *par_master;
-void register_par_master(const struct par_master *pgm, const enum chipbustype buses);
+int register_par_master(const struct par_master *mst, const enum chipbustype buses);
struct registered_master {
enum chipbustype buses_supported;
union {
@@ -869,12 +866,8 @@
/* spi_master feature checks */
static inline bool spi_master_4ba(const struct flashctx *const flash)
{
- /* TODO(b/171755805): Assume the spi drv supports 4BA now regardless until re-enterent patches land. */
- /*
return flash->mst->buses_supported & BUS_SPI &&
flash->mst->spi.features & SPI_MASTER_4BA;
- */
- return true;
}
static inline bool spi_master_no_4ba_modes(const struct flashctx *const flash)
{