summaryrefslogtreecommitdiffstats
path: root/scripts/gen_netx_image.c
blob: 18e10bcaeb40cf0445377d17f463655799e9e79f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <fcntl.h>
#include <libgen.h>
#include <getopt.h>

struct netx_block_normal {
	uint32_t sdram_general_ctrl;	/* SDRam General control value */
	uint32_t sdram_timing_ctrl;	/* SDRam Timing control register value */
	uint32_t reserved[3];
};

struct netx_block_expbus {
		uint32_t exp_bus_reg;	/* Expension bus register value (EXPBus Bootmode) */
		uint32_t io_reg_mode0;	/* IORegmode0 register value (EXPBus Bootmode) */
		uint32_t io_reg_mode1;	/* IORegmode1 register value (EXPBus Bootmode) */
		uint32_t if_conf1;	/* IfConfig1 register value (EXPBus Bootmode) */
		uint32_t if_conf2;	/* IfConfig2 register value (EXPBus Bootmode) */
};

struct netx_bootblock {
	uint32_t cookie;     /* Cookie identifying bus width and valid bootblock */
# define MAGICCOOKIE_8BIT      0xF8BEAF08  /* Cookie used for  8Bit Flashes */
# define MAGICCOOKIE_16BIT     0xF8BEAF16  /* Cookie used for 16Bit Flashes */
# define MAGICCOOKIE_32BIT     0xF8BEAF32  /* Cookie used for 32Bit Flashes */

	union {
		uint32_t mem_ctrl;        /* Parallel/Serial Flash Mode for setting up timing parameters */
		uint32_t speed;          /* I2C/SPI Mode for identifying speed of device */
		uint32_t reserved;       /* PCI/DPM mode */
	} ctrl;

	uint32_t appl_entrypoint;   /* Entrypoint to application after relocation */
	uint32_t appl_checksum;     /* Checksum of application (DWORD sum over application) */
	uint32_t appl_size;         /* size of application in DWORDs */
	uint32_t appl_start_addr;    /* Relocation address of application */
	uint32_t signature;        /* Bootblock signature ('NETX') */
# define NETX_IDENTIFICATION   0x5854454E /* Valid signature 'N' 'E' 'T' 'X' */

	union {
		struct netx_block_normal normal;
		struct netx_block_expbus expbus;
	} config;

	uint32_t misc_asic_ctrl;            /* ASIC CTRL register value */
	uint32_t UserParameter;	/* Serial number or user parameter */
	uint32_t SourceType;	/* 1 = parallel falsh at the SRAM bus */
# define ST_PFLASH 1
# define ST_SFLASH 2
# define ST_SEEPROM 3

	uint32_t boot_checksum;            /* Bootblock checksum (complement of DWORD sum over bootblock) */
};

void print_usage(char *prg)
{
        fprintf(stderr, "Usage: %s [Options]\n"
                        "Options:\n"
			" -i, --infile=FILE      input file\n"
			" -o  --outfile=FILE     outputfile\n"
			" -m  --memctrl=REG      Memory Control register value\n"
	                " -s, --sdramctrl=REG    SDRAM Control regster value\n"
                        " -t, --sdramtimctrl=REG SDRAM Timing Control regster value\n"
                        " -e, --entrypoint=ADR   Application entrypoint\n"
                        " -c, --cookie=BITS      Cookie to use (8|16|32)\n"
			" -h, --help            this help\n",
				prg);
}

int main(int argc, char *argv[])
{
	struct netx_bootblock *nb;
	int fd;
	struct stat s;
	int opt;
	unsigned char *buf;
	int bytes, err, barebox_size, ofs, i;
	uint32_t *ptr;
	uint32_t checksum = 0;
	uint32_t memctrl = 0, sdramctrl = 0, sdramtimctrl = 0, entrypoint = 0, cookie = 0;
	char *infile = NULL, *outfile = NULL;

	struct option long_options[] = {
		{ "help", no_argument, 0, 'h' },
		{ "infile", required_argument, 0, 'i'},
		{ "outfile", required_argument, 0, 'o'},
		{ "memctrl", required_argument, 0, 'm'},
		{ "sdramctrl", required_argument, 0, 's' },
		{ "sdramtimctrl", required_argument, 0, 't' },
		{ "entrypoint", required_argument, 0, 'e' },
		{ "cookie", required_argument, 0 , 'c' },
		{ 0, 0, 0, 0},
	};

	while ((opt = getopt_long(argc, argv, "hi:o:m:s:t:e:c:", long_options, NULL)) != -1) {
		switch (opt) {
			case 'h':
				print_usage(basename(argv[0]));
				exit(0);
			case 'i':
				infile = optarg;
				break;
			case 'o':
				outfile = optarg;
				break;
			case 'm':
				memctrl = strtoul(optarg, NULL, 0);
				break;
			case 's':
				sdramctrl = strtoul(optarg, NULL, 0);
				break;
			case 't':
				sdramtimctrl = strtoul(optarg, NULL, 0);
				break;
			case 'e':
				entrypoint = strtoul(optarg, NULL, 0);
				break;
			case 'c':
				cookie = strtoul(optarg, NULL, 0);
				break;
		}
	}

	if(!infile) {
		printf("no input filename supplied\n");
		exit(1);
	}

	if(!outfile) {
		printf("no outpu filename supplied\n");
		exit(1);
	}

	switch (cookie) {
		case 8:
			cookie = MAGICCOOKIE_8BIT;
			break;
		case 16:
			cookie = MAGICCOOKIE_16BIT;
			break;
		case 32:
			cookie = MAGICCOOKIE_32BIT;
			break;
		default:
			fprintf(stderr, "invalid coookie size %d\n",cookie);
	}

	fd = open(infile,O_RDONLY);
	if(fd < 0) {
		perror("open");
		exit(1);
	}

	if( fstat(fd, &s) < 0) {
		perror("fstat");
		exit(1);
	}

	barebox_size = s.st_size;
	printf("found barebox image. size: %d bytes. Using entrypoint 0x%08x\n",barebox_size,entrypoint);

	buf = malloc(barebox_size + sizeof(struct netx_bootblock) + 4);
	if(!buf) {
		perror("malloc");
		exit(1);
	}
	memset(buf, 0, barebox_size + sizeof(struct netx_bootblock) + 4);

	nb = (struct netx_bootblock *)buf;

	nb->cookie = cookie;
	nb->ctrl.mem_ctrl = memctrl;
	nb->appl_entrypoint = entrypoint;
	nb->appl_size = (barebox_size >> 2);

	nb->appl_start_addr = entrypoint;
	nb->signature = NETX_IDENTIFICATION;
	nb->config.normal.sdram_general_ctrl = sdramctrl;
	nb->config.normal.sdram_timing_ctrl = sdramtimctrl;
	nb->SourceType = ST_PFLASH;

	ofs = sizeof(struct netx_bootblock);
	bytes = barebox_size;

	while(bytes) {
		err = read(fd, buf + ofs, bytes);
		if( err < 0 ) {
			perror("read");
			exit(1);
		}
		bytes -= err;
		ofs += err;
	}

	close(fd);

	/* calculate application checksum */
	ptr = (uint32_t *)(buf + sizeof(struct netx_bootblock));

	checksum = 0;

	for( i = 0; i < nb->appl_size; i++) {
		checksum += *ptr++;
	}

	nb->appl_checksum = checksum;
	printf("application checksum: 0x%08x\n",nb->appl_checksum);

	/* calculate bootblock checksum */
	ptr = (uint32_t *)buf;
	checksum = 0;
	for( i = 0; i < (sizeof(struct netx_bootblock) >> 2); i++)
		checksum += *ptr++;
	nb->boot_checksum = -1 * checksum;

	fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR |
			S_IRGRP | S_IWGRP | S_IROTH);
	if(fd < 0) {
		perror("open");
		exit(1);
	}

	bytes = barebox_size + sizeof(struct netx_bootblock);
	ofs = 0;
	while(bytes) {
		err = write(fd, buf + ofs, bytes);
		if( err < 0) {
			perror("write");
			exit(1);
		}
		bytes -= err;
		ofs += err;
	}

	close(fd);
	free(buf);
	return 0;
}