Skip to content

Commit 24d4a7b

Browse files
authored
Merge pull request #91 from quic-bjorande/for-linux-msm/flashing-support
For linux msm/flashing support
2 parents 20d08f3 + 48efa30 commit 24d4a7b

16 files changed

Lines changed: 967 additions & 262 deletions

File tree

README

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,33 @@ devices:
8181
fastboot_set_active: true
8282
fastboot_key_timeout: 2
8383

84+
- board: qdlboard
85+
users:
86+
- username
87+
console: /dev/ttyUSB1
88+
fastboot: abcdef04
89+
qdl_programmer: /path/to/prog_firehose_ddr.elf
90+
qdl_access:
91+
- user: username
92+
targets:
93+
- boot_a
94+
- boot_b
95+
- 0/efiesp
96+
- 0/123456
97+
- user: admin
98+
targets:
99+
- all
100+
101+
QDL access targets use QDL's target syntax: <partition-name>, <lun>,
102+
<lun>/<partition-name>, or <lun>/<start-sector>. The CDBA server checks the
103+
requested target string against the configured access list before invoking QDL,
104+
but does not resolve the target to a physical partition itself. For a bare
105+
<partition-name>, QDL searches across all LUNs and flashes the first matching
106+
partition. If multiple LUNs might contain the same partition name, or if the ACL
107+
must identify an exact location, use the explicit <lun>/<partition-name> or
108+
<lun>/<start-sector> form instead. The special target "all" allows any QDL
109+
target.
110+
84111
- board: testboard
85112
console: /dev/serial/by-id/usb-1234-if00-port0
86113
name: GPIO controller board

cdba-power.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@ int main(int argc, char **argv)
7171
}
7272

7373
if (on) {
74-
device_power(selected_device, true);
74+
device_power_on(selected_device, MSG_POWER_ON_NORMAL);
7575
watch_main_loop(ready);
7676

7777
selected_device->usb_always_on = true;
7878
selected_device->power_always_on = true;
7979
} else {
8080
device_usb(selected_device, false);
81-
device_power(selected_device, false);
81+
device_power_off(selected_device);
8282
}
8383

8484
device_close(selected_device);

cdba-server.c

Lines changed: 162 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
#include <stdint.h>
1212
#include <stdio.h>
1313
#include <string.h>
14+
#include <sys/wait.h>
1415
#include <unistd.h>
1516
#include <syslog.h>
1617

1718
#include "cdba-server.h"
19+
#include "cdba.h"
1820
#include "circ_buf.h"
1921
#include "device.h"
2022
#include "device_parser.h"
@@ -26,6 +28,26 @@ static const char *username;
2628

2729
struct device *selected_device;
2830

31+
struct edl_file {
32+
struct list_head node;
33+
34+
int fd;
35+
36+
char *filename;
37+
char *target;
38+
};
39+
40+
static struct list_head edl_files = LIST_INIT(edl_files);
41+
42+
static void edl_present(bool present)
43+
{
44+
uint8_t value = present ? 1 : 0;
45+
46+
warnx("edl is %spresent", present? "" : "not ");
47+
48+
cdba_send_buf(MSG_EDL_PRESENT, 1, &value);
49+
}
50+
2951
static void fastboot_opened(struct fastboot *fb, void *data)
3052
{
3153
const uint8_t one = 1;
@@ -60,6 +82,7 @@ static void msg_select_board(const void *param)
6082
fprintf(stderr, "failed to open %s\n", (const char *)param);
6183
watch_quit();
6284
} else {
85+
device_edl_open(selected_device, edl_present);
6386
device_fastboot_open(selected_device, &fastboot_ops);
6487
}
6588

@@ -93,6 +116,123 @@ static void msg_fastboot_download(const void *data, size_t len)
93116
}
94117
}
95118

119+
static struct edl_file *current_edl_file;
120+
121+
static void msg_edl_download(const void *data, size_t len)
122+
{
123+
char template[] = "/tmp/cdba.XXXXXX";
124+
struct edl_file *edl;
125+
126+
edl = current_edl_file;
127+
128+
if (!edl) {
129+
edl = calloc(1, sizeof(*edl));
130+
131+
edl->filename = strdup(template);
132+
edl->fd = mkstemp(edl->filename);
133+
if (edl->fd < 0)
134+
err(1, "failed to create temporary file");
135+
136+
list_append(&edl_files, &edl->node);
137+
138+
current_edl_file = edl;
139+
}
140+
141+
write(edl->fd, data, len);
142+
143+
if (len == 0)
144+
close(edl->fd);
145+
}
146+
147+
static void msg_edl_flash(const void *data, size_t len)
148+
{
149+
const char *target = data;
150+
151+
if (!selected_device || !current_edl_file)
152+
return;
153+
154+
if (!len || target[len - 1]) {
155+
fprintf(stderr, "invalid EDL flash target\n");
156+
watch_quit();
157+
return;
158+
}
159+
160+
fprintf(stderr, "edl flash into '%s'\n", target);
161+
162+
if (!device_qdl_access_allowed(selected_device, username, target)) {
163+
fprintf(stderr, "user '%s' is not allowed to flash EDL target '%s' on %s\n",
164+
username, target, selected_device->board);
165+
watch_quit();
166+
return;
167+
}
168+
169+
current_edl_file->target = strdup(target);
170+
current_edl_file = NULL;
171+
}
172+
173+
static void msg_edl_reset(void)
174+
{
175+
struct edl_file *edl;
176+
const char **argv;
177+
size_t args;
178+
size_t arg = 0;
179+
180+
fprintf(stderr, "edl reset\n");
181+
182+
if (!selected_device) {
183+
fprintf(stderr, "no device selected\n");
184+
watch_quit();
185+
return;
186+
}
187+
188+
if (!selected_device->qdl_programmer) {
189+
fprintf(stderr, "no EDL support configured for %s\n", selected_device->name);
190+
watch_quit();
191+
return;
192+
}
193+
194+
list_for_each_entry(edl, &edl_files, node) {
195+
if (!edl->target) {
196+
fprintf(stderr, "EDL image without flash target\n");
197+
watch_quit();
198+
return;
199+
}
200+
}
201+
202+
args = 7 + list_len(&edl_files) * 3 + 1;
203+
argv = calloc(args, sizeof(char *));
204+
205+
argv[arg++] = "qdl";
206+
argv[arg++] = selected_device->qdl_programmer;
207+
208+
if (selected_device->qdl_storage) {
209+
argv[arg++] = "--storage";
210+
argv[arg++] = selected_device->qdl_storage;
211+
}
212+
213+
if (selected_device->qdl_serial) {
214+
argv[arg++] = "--serial";
215+
argv[arg++] = selected_device->qdl_serial;
216+
}
217+
218+
list_for_each_entry(edl, &edl_files, node) {
219+
argv[arg++] = "write";
220+
argv[arg++] = edl->target;
221+
argv[arg++] = edl->filename;
222+
}
223+
argv[arg] = NULL;
224+
225+
if (fork() == 0) {
226+
dup2(STDERR_FILENO, STDOUT_FILENO);
227+
execvp("qdl", (char **)argv);
228+
err(127, "failed to spawn qdl");
229+
}
230+
wait(NULL);
231+
232+
list_for_each_entry(edl, &edl_files, node)
233+
unlink(edl->filename);
234+
}
235+
96236
static void msg_fastboot_continue(void)
97237
{
98238
device_fastboot_continue(selected_device);
@@ -138,6 +278,7 @@ static int handle_stdin(int fd, void *buf)
138278
static struct circ_buf recv_buf = { };
139279
struct msg *msg;
140280
struct msg hdr;
281+
uint8_t mode;
141282
size_t n;
142283
int ret;
143284

@@ -171,12 +312,22 @@ static int handle_stdin(int fd, void *buf)
171312
// fprintf(stderr, "hard reset\n");
172313
break;
173314
case MSG_POWER_ON:
174-
device_power(selected_device, true);
315+
if (msg->len == 1)
316+
mode = *(uint8_t *)msg->data;
317+
else
318+
mode = MSG_POWER_ON_FASTBOOT;
319+
320+
if (mode >= MSG_POWER_ON_COUNT) {
321+
fprintf(stderr, "invalid power on mode requested\n");
322+
exit(1);
323+
}
324+
325+
device_power_on(selected_device, mode);
175326

176327
cdba_send(MSG_POWER_ON);
177328
break;
178329
case MSG_POWER_OFF:
179-
device_power(selected_device, false);
330+
device_power_off(selected_device);
180331

181332
cdba_send(MSG_POWER_OFF);
182333
break;
@@ -210,6 +361,15 @@ static int handle_stdin(int fd, void *buf)
210361
case MSG_KEY_PRESS:
211362
msg_key_press(msg->data, msg->len);
212363
break;
364+
case MSG_EDL_DOWNLOAD:
365+
msg_edl_download(msg->data, msg->len);
366+
break;
367+
case MSG_EDL_WRITE:
368+
msg_edl_flash(msg->data, msg->len);
369+
break;
370+
case MSG_EDL_RESET:
371+
msg_edl_reset();
372+
break;
213373
default:
214374
fprintf(stderr, "unk %d len %d\n", msg->type, msg->len);
215375
exit(1);

0 commit comments

Comments
 (0)