blob: 41a4a77833aebba076e602601fe9a09d6c6ae845 [file] [log] [blame]
Anton Staafb2647882014-09-17 15:13:43 -07001/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright 2014, Google Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following disclaimer
15 * in the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name of Google Inc. nor the names of its
18 * contributors may be used to endorse or promote products derived from
19 * this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Alternatively, this software may be distributed under the terms of the
34 * GNU General Public License ("GPL") version 2 as published by the Free
35 * Software Foundation.
36 */
37
38/*
39 * This SPI flash programming interface is designed to talk to a Chromium OS
40 * device over a Raiden USB connection. The USB connection is routed to a
41 * microcontroller running an image compiled from:
42 *
43 * https://chromium.googlesource.com/chromiumos/platform/ec
44 *
45 * The protocol for the USB-SPI bridge is documented in the following file in
46 * that respository:
47 *
48 * chip/stm32/usb_spi.c
49 */
50
51#include <stdio.h>
52#include <string.h>
53#include "programmer.h"
54#include "spi.h"
55
56#include <libusb.h>
57#include <stdlib.h>
58
59#define GOOGLE_VID 0x18D1
60#define GOOGLE_RAIDEN_PID 0x500f
Anton Staafb4661ee2014-10-21 11:24:36 -070061#define GOOGLE_RAIDEN_INTERFACE 2
Anton Staafb049ae32014-10-21 10:30:37 -070062#define GOOGLE_RAIDEN_ENDPOINT 3
Anton Staafb4661ee2014-10-21 11:24:36 -070063#define GOOGLE_RAIDEN_CONFIG 1
Anton Staafb2647882014-09-17 15:13:43 -070064
Anton Staaf4589cd12015-03-23 13:36:44 -070065enum raiden_debug_spi_request {
66 RAIDEN_DEBUG_SPI_REQ_ENABLE = 0x0000,
67 RAIDEN_DEBUG_SPI_REQ_DISABLE = 0x0001,
68};
69
Anton Staafd27536d2014-09-30 08:10:17 -070070#define PACKET_HEADER_SIZE 2
71#define MAX_PACKET_SIZE 64
Anton Staafb2647882014-09-17 15:13:43 -070072
73/*
74 * This timeout is so large because the Raiden SPI timeout is 800ms.
75 */
76#define TRANSFER_TIMEOUT_MS 1000
77
78#define CHECK(expression, string...) \
79 ({ \
80 int error__ = (expression); \
81 \
82 if (error__ != 0) { \
83 msg_perr("Raiden: libusb error: %s:%d %s\n", \
84 __FILE__, \
85 __LINE__, \
86 libusb_error_name(error__)); \
87 msg_perr(string); \
88 return 0x20000 | -error__; \
89 } \
90 })
91
Anton Staaf4589cd12015-03-23 13:36:44 -070092static libusb_context *context = NULL;
93static libusb_device_handle *device = NULL;
94static uint8_t endpoint = GOOGLE_RAIDEN_ENDPOINT;
95static int interface = GOOGLE_RAIDEN_INTERFACE;
Anton Staafb2647882014-09-17 15:13:43 -070096
97static int send_command(unsigned int write_count,
98 unsigned int read_count,
99 const unsigned char *write_buffer,
100 unsigned char *read_buffer)
101{
102 uint8_t buffer[MAX_PACKET_SIZE];
103 int transferred;
104
105 if (write_count > MAX_PACKET_SIZE - PACKET_HEADER_SIZE) {
106 msg_perr("Raiden: invalid write_count of %d\n", write_count);
107 return SPI_INVALID_LENGTH;
108 }
109
110 if (read_count > MAX_PACKET_SIZE - PACKET_HEADER_SIZE) {
111 msg_perr("Raiden: invalid read_count of %d\n", read_count);
112 return SPI_INVALID_LENGTH;
113 }
114
115 buffer[0] = write_count;
116 buffer[1] = read_count;
117
118 memcpy(buffer + PACKET_HEADER_SIZE, write_buffer, write_count);
119
120 CHECK(libusb_bulk_transfer(device,
Anton Staafb049ae32014-10-21 10:30:37 -0700121 LIBUSB_ENDPOINT_OUT | endpoint,
Anton Staafb2647882014-09-17 15:13:43 -0700122 buffer,
123 write_count + PACKET_HEADER_SIZE,
124 &transferred,
125 TRANSFER_TIMEOUT_MS),
126 "Raiden: OUT transfer failed\n"
127 " write_count = %d\n"
128 " read_count = %d\n",
129 write_count,
130 read_count);
131
132 if (transferred != write_count + PACKET_HEADER_SIZE) {
133 msg_perr("Raiden: Write failure (wrote %d, expected %d)\n",
134 transferred, write_count + PACKET_HEADER_SIZE);
135 return 0x10001;
136 }
137
138 CHECK(libusb_bulk_transfer(device,
Anton Staafb049ae32014-10-21 10:30:37 -0700139 LIBUSB_ENDPOINT_IN | endpoint,
Anton Staafb2647882014-09-17 15:13:43 -0700140 buffer,
141 read_count + PACKET_HEADER_SIZE,
142 &transferred,
143 TRANSFER_TIMEOUT_MS),
144 "Raiden: IN transfer failed\n"
145 " write_count = %d\n"
146 " read_count = %d\n",
147 write_count,
148 read_count);
149
150 if (transferred != read_count + PACKET_HEADER_SIZE) {
151 msg_perr("Raiden: Read failure (read %d, expected %d)\n",
152 transferred, read_count + PACKET_HEADER_SIZE);
153 return 0x10002;
154 }
155
156 memcpy(read_buffer, buffer + PACKET_HEADER_SIZE, read_count);
157
158 return buffer[0] | (buffer[1] << 8);
159}
160
161/*
162 * Unfortunately there doesn't seem to be a way to specify the maximum number
163 * of bytes that your SPI device can read/write, these values are the maximum
164 * data chunk size that flashrom will package up with an additional four bytes
165 * of command for the flash device, resulting in a 62 byte packet, that we then
166 * add two bytes to in either direction, making our way up to the 64 byte
167 * maximum USB packet size for the device.
168 *
169 * The largest command that flashrom generates is the byte program command, so
170 * we use that command header maximum size here. The definition of
171 * JEDEC_BYTE_PROGRAM_OUTSIZE includes enough space for a single byte of data
172 * to write, so we add one byte of space back.
173 */
174#define MAX_DATA_SIZE (MAX_PACKET_SIZE - \
175 PACKET_HEADER_SIZE - \
176 JEDEC_BYTE_PROGRAM_OUTSIZE + \
177 1)
178
179static const struct spi_programmer spi_programmer_raiden_debug = {
180 .type = SPI_CONTROLLER_RAIDEN_DEBUG,
181 .max_data_read = MAX_DATA_SIZE,
182 .max_data_write = MAX_DATA_SIZE,
183 .command = send_command,
184 .multicommand = default_spi_send_multicommand,
185 .read = default_spi_read,
186 .write_256 = default_spi_write_256,
187};
188
Anton Staafd27536d2014-09-30 08:10:17 -0700189static long int get_parameter(char const * name, long int default_value)
190{
191 char * string = extract_programmer_param(name);
192 long int value = default_value;
193
194 if (string)
195 value = strtol(string, NULL, 0);
196
197 free(string);
198
199 return value;
200}
201
Anton Staaf4589cd12015-03-23 13:36:44 -0700202static int shutdown(void * data)
203{
204 CHECK(libusb_control_transfer(device,
205 LIBUSB_ENDPOINT_OUT |
206 LIBUSB_REQUEST_TYPE_VENDOR |
207 LIBUSB_RECIPIENT_INTERFACE,
208 RAIDEN_DEBUG_SPI_REQ_DISABLE,
209 0,
210 interface,
211 NULL,
212 0,
213 TRANSFER_TIMEOUT_MS),
214 "Raiden: Failed to disable SPI bridge\n");
215
216 libusb_close(device);
217 libusb_exit(NULL);
218
219 return 0;
220}
221
Anton Staafb2647882014-09-17 15:13:43 -0700222int raiden_debug_spi_init(void)
223{
Anton Staaf4589cd12015-03-23 13:36:44 -0700224 uint16_t vid = get_parameter("vid", GOOGLE_VID);
225 uint16_t pid = get_parameter("pid", GOOGLE_RAIDEN_PID);
226 int config = get_parameter("config", GOOGLE_RAIDEN_CONFIG);
Anton Staafb4661ee2014-10-21 11:24:36 -0700227 int current_config;
Anton Staafd27536d2014-09-30 08:10:17 -0700228
Anton Staafb2647882014-09-17 15:13:43 -0700229 CHECK(libusb_init(&context), "Raiden: libusb_init failed\n");
230
Anton Staaf4589cd12015-03-23 13:36:44 -0700231 interface = get_parameter("interface", GOOGLE_RAIDEN_INTERFACE);
232 endpoint = get_parameter("endpoint", GOOGLE_RAIDEN_ENDPOINT);
233 device = libusb_open_device_with_vid_pid(context, vid, pid);
Anton Staafb2647882014-09-17 15:13:43 -0700234
235 if (device == NULL) {
Anton Staafd27536d2014-09-30 08:10:17 -0700236 msg_perr("Unable to find device 0x%04x:0x%04x\n", vid, pid);
Anton Staafb2647882014-09-17 15:13:43 -0700237 return 1;
238 }
239
Anton Staafb4661ee2014-10-21 11:24:36 -0700240 CHECK(libusb_get_configuration(device, &current_config),
241 "Raiden: Failed to get current device configuration\n");
242
243 if (current_config != config)
244 CHECK(libusb_set_configuration(device, config),
245 "Raiden: Failed to set new configuration from %d to %d\n",
246 current_config,
247 config);
248
249 CHECK(libusb_set_auto_detach_kernel_driver(device, 1),
250 "Raiden: Failed to enable auto kernel driver detach\n");
251
252 CHECK(libusb_claim_interface(device, interface),
253 "Raiden: Could not claim device interface %d\n",
254 interface);
Anton Staafb2647882014-09-17 15:13:43 -0700255
Anton Staaf4589cd12015-03-23 13:36:44 -0700256 CHECK(libusb_control_transfer(device,
257 LIBUSB_ENDPOINT_OUT |
258 LIBUSB_REQUEST_TYPE_VENDOR |
259 LIBUSB_RECIPIENT_INTERFACE,
260 RAIDEN_DEBUG_SPI_REQ_ENABLE,
261 0,
262 interface,
263 NULL,
264 0,
265 TRANSFER_TIMEOUT_MS),
266 "Raiden: Failed to enable SPI bridge\n");
267
Anton Staafb2647882014-09-17 15:13:43 -0700268 register_spi_programmer(&spi_programmer_raiden_debug);
Anton Staaf4589cd12015-03-23 13:36:44 -0700269 register_shutdown(shutdown, NULL);
Anton Staafb2647882014-09-17 15:13:43 -0700270
271 return 0;
272}