blob: 80440bdb4daf9d25a37de53403e5f70fb9995ead [file] [log] [blame]
Anastasia Klimchukcffaac12021-04-21 07:58:30 +10001/*
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 <include/test.h>
17#include <string.h>
18
Anastasia Klimchuk21e22ba2021-05-10 10:19:25 +100019#include "io_mock.h"
Anastasia Klimchukcffaac12021-04-21 07:58:30 +100020#include "programmer.h"
21
Thomas Heijligen5d25f042021-06-01 14:37:12 +020022static void run_lifecycle(void **state, const struct programmer_entry *prog, const char *param)
Anastasia Klimchukcffaac12021-04-21 07:58:30 +100023{
24 (void) state; /* unused */
25
Thomas Heijligen5d25f042021-06-01 14:37:12 +020026 printf("Testing programmer_init for programmer=%s ...\n", prog->name);
Anastasia Klimchukcffaac12021-04-21 07:58:30 +100027 assert_int_equal(0, programmer_init(prog, strdup(param)));
Thomas Heijligen5d25f042021-06-01 14:37:12 +020028 printf("... programmer_init for programmer=%s successful\n", prog->name);
Anastasia Klimchukcffaac12021-04-21 07:58:30 +100029
Thomas Heijligen5d25f042021-06-01 14:37:12 +020030 printf("Testing programmer_shutdown for programmer=%s ...\n", prog->name);
Anastasia Klimchukcffaac12021-04-21 07:58:30 +100031 assert_int_equal(0, programmer_shutdown());
Thomas Heijligen5d25f042021-06-01 14:37:12 +020032 printf("... programmer_shutdown for programmer=%s successful\n", prog->name);
Anastasia Klimchukcffaac12021-04-21 07:58:30 +100033}
34
35void dummy_init_and_shutdown_test_success(void **state)
36{
Thomas Heijligen5d25f042021-06-01 14:37:12 +020037 run_lifecycle(state, &programmer_dummy, "bus=parallel+lpc+fwh+spi");
Anastasia Klimchukcffaac12021-04-21 07:58:30 +100038}
Anastasia Klimchuk98534e72021-04-23 15:47:03 +100039
Anastasia Klimchuk21e22ba2021-05-10 10:19:25 +100040struct mec1308_io_state {
41 unsigned char outb_val;
42};
43
44void mec1308_outb(void *state, unsigned char value, unsigned short port)
45{
46 struct mec1308_io_state *io_state = state;
47
48 io_state->outb_val = value;
49}
50
51unsigned char mec1308_inb(void *state, unsigned short port)
52{
53 struct mec1308_io_state *io_state = state;
54
55 return ((port == 0x2e /* MEC1308_SIO_PORT1 */
56 || port == 0x4e /* MEC1308_SIO_PORT2 */)
57 ? 0x20 /* MEC1308_DEVICE_ID_REG */
58 : ((io_state->outb_val == 0x84 /* MEC1308_MBX_DATA_START */)
59 ? 0xaa /* MEC1308_CMD_PASSTHRU_SUCCESS */
60 : 0));
61}
62
63void mec1308_init_and_shutdown_test_success(void **state)
64{
65 struct mec1308_io_state mec1308_io_state = { 0 };
66 const struct io_mock mec1308_io = {
67 .state = &mec1308_io_state,
68 .outb = mec1308_outb,
69 .inb = mec1308_inb,
70 };
71
72 io_mock_register(&mec1308_io);
73
74 will_return_always(__wrap_sio_read, 0x4d); /* MEC1308_DEVICE_ID_VAL */
Thomas Heijligen5d25f042021-06-01 14:37:12 +020075 run_lifecycle(state, &programmer_mec1308, "");
Anastasia Klimchuk21e22ba2021-05-10 10:19:25 +100076
77 io_mock_register(NULL);
78}
79
80struct ene_lpc_io_state {
81 unsigned char outb_val;
82 int pause_cmd;
83};
84
85void ene_lpc_outb_kb932(void *state, unsigned char value, unsigned short port)
86{
87 struct ene_lpc_io_state *io_state = state;
88
89 io_state->outb_val = value;
90 if (value == 0x59 /* ENE_KB932.ec_pause_cmd */)
91 io_state->pause_cmd = 1;
92}
93
94unsigned char ene_lpc_inb_kb932(void *state, unsigned short port)
95{
96 struct ene_lpc_io_state *io_state = state;
97 unsigned char ene_hwver_offset = 0; /* REG_EC_HWVER & 0xff */
98 unsigned char ene_ediid_offset = 0x24; /* REG_EC_EDIID & 0xff */
99 unsigned char ec_status_buf_offset = 0x54; /* ENE_KB932.ec_status_buf & 0xff */
100
101 if (port == 0xfd63 /* ENE_KB932.port_io_base + port_ene_data */) {
102 if (io_state->outb_val == ene_hwver_offset)
103 return 0xa2; /* ENE_KB932.hwver */
104 if (io_state->outb_val == ene_ediid_offset)
105 return 0x02; /* ENE_KB932.ediid */
106 if (io_state->outb_val == ec_status_buf_offset) {
107 if (io_state->pause_cmd == 1) {
108 io_state->pause_cmd = 0;
109 return 0x33; /* ENE_KB932.ec_is_pausing mask */
110 } else {
111 return 0x00; /* ENE_KB932.ec_is_running mask */
112 }
113 }
114 }
115
116 return 0;
117}
118
119void ene_lpc_init_and_shutdown_test_success(void **state)
120{
121 /*
122 * Current implementation tests for chip ENE_KB932.
123 * Another chip which is not tested here is ENE_KB94X.
124 */
125 struct ene_lpc_io_state ene_lpc_io_state = { 0, 0 };
126 const struct io_mock ene_lpc_io = {
127 .state = &ene_lpc_io_state,
128 .outb = ene_lpc_outb_kb932,
129 .inb = ene_lpc_inb_kb932,
130 };
131
132 io_mock_register(&ene_lpc_io);
133
Thomas Heijligen5d25f042021-06-01 14:37:12 +0200134 run_lifecycle(state, &programmer_ene_lpc, "");
Anastasia Klimchuk21e22ba2021-05-10 10:19:25 +1000135
136 io_mock_register(NULL);
137}
138
Anastasia Klimchuk98534e72021-04-23 15:47:03 +1000139void linux_spi_init_and_shutdown_test_success(void **state)
140{
141 /*
142 * Current implementation tests a particular path of the init procedure.
143 * There are two ways for it to succeed: reading the buffer size from sysfs
144 * and the fallback to getpagesize(). This test does the latter (fallback to
145 * getpagesize).
146 */
Thomas Heijligen5d25f042021-06-01 14:37:12 +0200147 run_lifecycle(state, &programmer_linux_spi, "dev=/dev/null");
Anastasia Klimchuk98534e72021-04-23 15:47:03 +1000148}