1 /*
2 * This file is part of the flashrom project.
3 *
4 * Copyright 2021 Google LLC
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16 #include "lifecycle.h"
17
18 #if CONFIG_LINUX_SPI == 1
linux_spi_ioctl(void * state,int fd,unsigned long request,va_list args)19 static int linux_spi_ioctl(void *state, int fd, unsigned long request, va_list args) {
20
21 if (request == SPI_IOC_MESSAGE(2)) { /* ioctl code for read request */
22 struct spi_ioc_transfer* msg = va_arg(args, struct spi_ioc_transfer*);
23
24 /* First message has write array and write count */
25 unsigned int writecnt = msg[0].len;
26 unsigned char *writearr = (unsigned char *)(uintptr_t)msg[0].tx_buf;
27 /* Second message has read array and read count */
28 unsigned int readcnt = msg[1].len;
29
30 /* Detect probing */
31 if (writecnt == 1 && writearr[0] == JEDEC_RDID && readcnt == 3) {
32 /* We need to populate read array. */
33 unsigned char *readarr = (unsigned char *)(uintptr_t)msg[1].rx_buf;
34 readarr[0] = 0xEF; /* WINBOND_NEX_ID */
35 readarr[1] = 0x40; /* WINBOND_NEX_W25Q128_V left byte */
36 readarr[2] = 0x18; /* WINBOND_NEX_W25Q128_V right byte */
37 }
38 }
39
40 return 0;
41 }
42
linux_spi_fgets(void * state,char * buf,int len,FILE * fp)43 static char *linux_spi_fgets(void *state, char *buf, int len, FILE *fp)
44 {
45 /* Emulate reading max buffer size from sysfs. */
46 const char *max_buf_size = "1048576";
47
48 return memcpy(buf, max_buf_size, min(len, strlen(max_buf_size) + 1));
49 }
50
linux_spi_probe_lifecycle_test_success(void ** state)51 void linux_spi_probe_lifecycle_test_success(void **state)
52 {
53 /*
54 * Current implementation tests a particular path of the init procedure.
55 * Specifically, it is reading the buffer size from sysfs.
56 */
57 struct io_mock_fallback_open_state linux_spi_fallback_open_state = {
58 .noc = 0,
59 .paths = { LOCK_FILE, "/dev/null", NULL },
60 .flags = { O_RDWR, O_RDWR },
61 };
62 const struct io_mock linux_spi_io = {
63 .iom_fgets = linux_spi_fgets,
64 .iom_ioctl = linux_spi_ioctl,
65 .fallback_open_state = &linux_spi_fallback_open_state,
66 };
67
68 run_probe_lifecycle(state, &linux_spi_io, &programmer_linux_spi, "dev=/dev/null", "W25Q128.V");
69 }
70 #else
71 SKIP_TEST(linux_spi_probe_lifecycle_test_success)
72 #endif /* CONFIG_LINUX_SPI */
73