summaryrefslogtreecommitdiff
path: root/rbutil/jztool/src/x1000.c
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil/jztool/src/x1000.c')
-rw-r--r--rbutil/jztool/src/x1000.c209
1 files changed, 0 insertions, 209 deletions
diff --git a/rbutil/jztool/src/x1000.c b/rbutil/jztool/src/x1000.c
deleted file mode 100644
index 1a12340316..0000000000
--- a/rbutil/jztool/src/x1000.c
+++ /dev/null
@@ -1,209 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "jztool_private.h"
23#include "../../../firmware/target/mips/ingenic_x1000/spl-x1000-defs.h"
24#include "../../../firmware/target/mips/ingenic_x1000/nand-x1000-err.h"
25#include <string.h>
26
27static uint32_t to_le32(uint32_t x)
28{
29 union { uint32_t u; uint8_t p[4]; } f;
30 f.p[0] = x & 0xff;
31 f.p[1] = (x >> 8) & 0xff;
32 f.p[2] = (x >> 16) & 0xff;
33 f.p[3] = (x >> 24) & 0xff;
34 return f.u;
35}
36
37static uint32_t from_le32(uint32_t x)
38{
39 union { uint32_t u; uint8_t p[4]; } f;
40 f.u = x;
41 return f.p[0] | (f.p[1] << 8) | (f.p[2] << 16) | (f.p[3] << 24);
42}
43
44static const char* jz_x1000_nand_strerror(int rc)
45{
46 switch(rc) {
47 case NANDERR_CHIP_UNSUPPORTED:
48 return "Chip unsupported";
49 case NANDERR_WRITE_PROTECTED:
50 return "Operation forbidden by write-protect";
51 case NANDERR_UNALIGNED_ADDRESS:
52 return "Improperly aligned address";
53 case NANDERR_UNALIGNED_LENGTH:
54 return "Improperly aligned length";
55 case NANDERR_READ_FAILED:
56 return "Read operation failed";
57 case NANDERR_ECC_FAILED:
58 return "Uncorrectable ECC error on read";
59 case NANDERR_ERASE_FAILED:
60 return "Erase operation failed";
61 case NANDERR_PROGRAM_FAILED:
62 return "Program operation failed";
63 case NANDERR_COMMAND_FAILED:
64 return "NAND command failed";
65 default:
66 return "Unknown NAND error";
67 }
68}
69
70
71static int jz_x1000_send_args(jz_usbdev* dev, struct x1000_spl_arguments* args)
72{
73 args->command = to_le32(args->command);
74 args->param1 = to_le32(args->param1);
75 args->param2 = to_le32(args->param2);
76 args->flags = to_le32(args->flags);
77 return jz_usb_send(dev, SPL_ARGUMENTS_ADDRESS, sizeof(*args), args);
78}
79
80static int jz_x1000_recv_status(jz_usbdev* dev, struct x1000_spl_status* status)
81{
82 int rc = jz_usb_recv(dev, SPL_STATUS_ADDRESS, sizeof(*status), status);
83 if(rc < 0)
84 return rc;
85
86 status->err_code = from_le32(status->err_code);
87 status->reserved = from_le32(status->reserved);
88 return JZ_SUCCESS;
89}
90
91int jz_x1000_setup(jz_usbdev* dev, size_t spl_len, const void* spl_data)
92{
93 int rc = jz_identify_x1000_spl(spl_data, spl_len);
94 if(rc < 0)
95 return JZ_ERR_BAD_FILE_FORMAT;
96 if(spl_len > SPL_MAX_SIZE)
97 return JZ_ERR_BAD_FILE_FORMAT;
98
99 rc = jz_usb_send(dev, SPL_LOAD_ADDRESS, spl_len, spl_data);
100 if(rc < 0)
101 return rc;
102
103 struct x1000_spl_arguments args;
104 args.command = SPL_CMD_BOOT;
105 args.param1 = SPL_BOOTOPT_NONE;
106 args.param2 = 0;
107 args.flags = 0;
108 rc = jz_x1000_send_args(dev, &args);
109 if(rc < 0)
110 return rc;
111
112 rc = jz_usb_start1(dev, SPL_EXEC_ADDRESS);
113 if(rc < 0)
114 return rc;
115
116 jz_sleepms(100);
117
118 struct x1000_spl_status status;
119 rc = jz_x1000_recv_status(dev, &status);
120 if(rc < 0)
121 return rc;
122
123 if(status.err_code != 0) {
124 jz_log(dev->jz, JZ_LOG_ERROR, "X1000 device init error: %d", status.err_code);
125 return JZ_ERR_OTHER;
126 }
127
128 return JZ_SUCCESS;
129}
130
131int jz_x1000_read_flash(jz_usbdev* dev, uint32_t addr, size_t len, void* data)
132{
133 struct x1000_spl_arguments args;
134 args.command = SPL_CMD_FLASH_READ;
135 args.param1 = addr;
136 args.param2 = len;
137 args.flags = SPL_FLAG_SKIP_INIT;
138 int rc = jz_x1000_send_args(dev, &args);
139 if(rc < 0)
140 return rc;
141
142 rc = jz_usb_start1(dev, SPL_EXEC_ADDRESS);
143 if(rc < 0)
144 return rc;
145
146 jz_sleepms(500);
147
148 struct x1000_spl_status status;
149 rc = jz_x1000_recv_status(dev, &status);
150 if(rc < 0)
151 return rc;
152
153 if(status.err_code != 0) {
154 jz_log(dev->jz, JZ_LOG_ERROR, "X1000 flash read error: %s",
155 jz_x1000_nand_strerror(status.err_code));
156 return JZ_ERR_FLASH_ERROR;
157 }
158
159 return jz_usb_recv(dev, SPL_BUFFER_ADDRESS, len, data);
160}
161
162int jz_x1000_write_flash(jz_usbdev* dev, uint32_t addr, size_t len, const void* data)
163{
164 int rc = jz_usb_send(dev, SPL_BUFFER_ADDRESS, len, data);
165 if(rc < 0)
166 return rc;
167
168 struct x1000_spl_arguments args;
169 args.command = SPL_CMD_FLASH_WRITE;
170 args.param1 = addr;
171 args.param2 = len;
172 args.flags = SPL_FLAG_SKIP_INIT;
173 rc = jz_x1000_send_args(dev, &args);
174 if(rc < 0)
175 return rc;
176
177 rc = jz_usb_start1(dev, SPL_EXEC_ADDRESS);
178 if(rc < 0)
179 return rc;
180
181 jz_sleepms(500);
182
183 struct x1000_spl_status status;
184 rc = jz_x1000_recv_status(dev, &status);
185 if(rc < 0)
186 return rc;
187
188 if(status.err_code != 0) {
189 jz_log(dev->jz, JZ_LOG_ERROR, "X1000 flash write error: %s",
190 jz_x1000_nand_strerror(status.err_code));
191 return JZ_ERR_FLASH_ERROR;
192 }
193
194 return JZ_SUCCESS;
195}
196
197int jz_x1000_boot_rockbox(jz_usbdev* dev)
198{
199 struct x1000_spl_arguments args;
200 args.command = SPL_CMD_BOOT;
201 args.param1 = SPL_BOOTOPT_ROCKBOX;
202 args.param2 = 0;
203 args.flags = 0;
204 int rc = jz_x1000_send_args(dev, &args);
205 if(rc < 0)
206 return rc;
207
208 return jz_usb_start1(dev, SPL_EXEC_ADDRESS);
209}