mirror of
https://github.com/xboot/xrock.git
synced 2024-11-23 01:44:46 +08:00
[xrock]first commit
This commit is contained in:
commit
365f40a57e
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
#
|
||||
# Normal rules
|
||||
#
|
||||
*.d
|
||||
*.o
|
||||
*.map
|
||||
*~
|
||||
|
||||
#
|
||||
# Generated files
|
||||
#
|
||||
/.cproject
|
||||
/.project
|
||||
/.settings
|
||||
/xrock
|
22
99-xrock.rules
Normal file
22
99-xrock.rules
Normal file
@ -0,0 +1,22 @@
|
||||
# Copy this file to /etc/udev/rules.d/ or /usr/lib/udev/rules.d/
|
||||
# If rules fail to reload automatically, you can refresh udev rules
|
||||
# with the command "sudo udevadm control --reload"
|
||||
|
||||
SUBSYSTEM!="usb", GOTO="end_rules"
|
||||
|
||||
# RK3036
|
||||
ATTRS{idVendor}=="2207", ATTRS{idProduct}=="301a", MODE="0666", GROUP="users"
|
||||
# RK3128
|
||||
ATTRS{idVendor}=="2207", ATTRS{idProduct}=="310c", MODE="0666", GROUP="users"
|
||||
# RK3229
|
||||
ATTRS{idVendor}=="2207", ATTRS{idProduct}=="320b", MODE="0666", GROUP="users"
|
||||
# RK3288
|
||||
ATTRS{idVendor}=="2207", ATTRS{idProduct}=="320a", MODE="0666", GROUP="users"
|
||||
# RK3328
|
||||
ATTRS{idVendor}=="2207", ATTRS{idProduct}=="320c", MODE="0666", GROUP="users"
|
||||
# RK3368
|
||||
ATTRS{idVendor}=="2207", ATTRS{idProduct}=="330a", MODE="0666", GROUP="users"
|
||||
# RK3399
|
||||
ATTRS{idVendor}=="2207", ATTRS{idProduct}=="330c", MODE="0666", GROUP="users"
|
||||
|
||||
LABEL="end_rules"
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright(c) 2007-2021 Jianjun Jiang <8192542@qq.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
76
Makefile
Normal file
76
Makefile
Normal file
@ -0,0 +1,76 @@
|
||||
#
|
||||
# Top makefile
|
||||
#
|
||||
|
||||
CROSS ?=
|
||||
|
||||
AS := $(CROSS)gcc -x assembler-with-cpp
|
||||
CC := $(CROSS)gcc
|
||||
CXX := $(CROSS)g++
|
||||
LD := $(CROSS)ld
|
||||
AR := $(CROSS)ar
|
||||
OC := $(CROSS)objcopy
|
||||
OD := $(CROSS)objdump
|
||||
RM := rm -fr
|
||||
|
||||
ASFLAGS := -g -ggdb -Wall -O3
|
||||
CFLAGS := -g -ggdb -Wall -O3
|
||||
CXXFLAGS := -g -ggdb -Wall -O3
|
||||
LDFLAGS :=
|
||||
ARFLAGS := -rcs
|
||||
OCFLAGS := -v -O binary
|
||||
ODFLAGS :=
|
||||
MCFLAGS :=
|
||||
|
||||
LIBDIRS :=
|
||||
LIBS := `pkg-config --libs libusb-1.0`
|
||||
|
||||
INCDIRS := -I . `pkg-config --cflags libusb-1.0`
|
||||
SRCDIRS := . chips
|
||||
|
||||
|
||||
SFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
|
||||
CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))
|
||||
CPPFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.cpp))
|
||||
|
||||
SDEPS := $(patsubst %, %, $(SFILES:.S=.o.d))
|
||||
CDEPS := $(patsubst %, %, $(CFILES:.c=.o.d))
|
||||
CPPDEPS := $(patsubst %, %, $(CPPFILES:.cpp=.o.d))
|
||||
DEPS := $(SDEPS) $(CDEPS) $(CPPDEPS)
|
||||
|
||||
SOBJS := $(patsubst %, %, $(SFILES:.S=.o))
|
||||
COBJS := $(patsubst %, %, $(CFILES:.c=.o))
|
||||
CPPOBJS := $(patsubst %, %, $(CPPFILES:.cpp=.o))
|
||||
OBJS := $(SOBJS) $(COBJS) $(CPPOBJS)
|
||||
|
||||
OBJDIRS := $(patsubst %, %, $(SRCDIRS))
|
||||
NAME := xrock
|
||||
VPATH := $(OBJDIRS)
|
||||
|
||||
.PHONY: all install clean
|
||||
|
||||
all : $(NAME)
|
||||
|
||||
$(NAME) : $(OBJS)
|
||||
@echo [LD] Linking $@
|
||||
@$(CC) $(LDFLAGS) $(LIBDIRS) -Wl,--cref,-Map=$@.map $^ -o $@ $(LIBS)
|
||||
|
||||
$(SOBJS) : %.o : %.S
|
||||
@echo [AS] $<
|
||||
@$(AS) $(ASFLAGS) -MD -MP -MF $@.d $(INCDIRS) -c $< -o $@
|
||||
|
||||
$(COBJS) : %.o : %.c
|
||||
@echo [CC] $<
|
||||
@$(CC) $(CFLAGS) -MD -MP -MF $@.d $(INCDIRS) -c $< -o $@
|
||||
|
||||
$(CPPOBJS) : %.o : %.cpp
|
||||
@echo [CXX] $<
|
||||
@$(CXX) $(CXXFLAGS) -MD -MP -MF $@.d $(INCDIRS) -c $< -o $@
|
||||
|
||||
install:
|
||||
install -Dm0755 xrock /usr/local/bin/xrock
|
||||
install -Dm0644 99-xrock.rules /etc/udev/rules.d/99-xrock.rules
|
||||
install -Dm0644 LICENSE /usr/share/licenses/xrock/LICENSE
|
||||
|
||||
clean:
|
||||
@$(RM) $(DEPS) $(OBJS) $(NAME).map $(NAME) *~
|
53
README.md
Normal file
53
README.md
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
***
|
||||
# XROCK
|
||||
The rockusb tools for rockchip SOC, support maskrom and loader mode for many chips.
|
||||
|
||||
## How to build
|
||||
|
||||
The xrock tools depends on the `libusb-1.0` library, you need to install `libusb-1.0-0-dev` before compile, for example in ubuntu:
|
||||
```shell
|
||||
sudo apt install libusb-1.0-0-dev
|
||||
```
|
||||
|
||||
Then just type `make` at the root directory, you will see a binary program.
|
||||
|
||||
```shell
|
||||
cd xrock
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
xrock(v1.1.3) - https://github.com/xboot/xrock
|
||||
usage:
|
||||
xrock version - Show chip version
|
||||
xrock hexdump <address> <length> - Dumps memory region in hex
|
||||
xrock dump <address> <length> - Binary memory dump to stdout
|
||||
xrock exec <address> - Call function address
|
||||
xrock read32 <address> - Read 32-bits value from device memory
|
||||
xrock write32 <address> <value> - Write 32-bits value to device memory
|
||||
xrock read <address> <length> <file> - Read memory to file
|
||||
xrock write <address> <file> - Write file to memory
|
||||
xrock reset - Reset device using watchdog
|
||||
xrock sid - Show sid information
|
||||
xrock jtag - Enable jtag debug
|
||||
xrock ddr [type] - Initial ddr controller with optional type
|
||||
xrock spinor - Detect spi nor flash
|
||||
xrock spinor read <address> <length> <file> - Read spi nor flash to file
|
||||
xrock spinor write <address> <file> - Write file to spi nor flash
|
||||
xrock spinand - Detect spi nand flash
|
||||
xrock spinand read <address> <length> <file> - Read spi nand flash to file
|
||||
xrock spinand write <address> <file> - Write file to spi nand flash
|
||||
```
|
||||
|
||||
## Links
|
||||
|
||||
* [The rockchip rkdeveloptool](https://github.com/rockchip-linux/rkdeveloptool)
|
||||
|
||||
## License
|
||||
|
||||
This library is free software; you can redistribute it and or modify it under the terms of the MIT license. See [MIT License](LICENSE) for details.
|
||||
|
45
crc16.c
Normal file
45
crc16.c
Normal file
@ -0,0 +1,45 @@
|
||||
#include <crc16.h>
|
||||
|
||||
static const uint16_t crc16_table[256] = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
||||
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
||||
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
|
||||
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
|
||||
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
|
||||
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
|
||||
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
|
||||
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
||||
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
|
||||
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
|
||||
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
|
||||
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
|
||||
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
|
||||
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
|
||||
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
||||
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
|
||||
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
|
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
|
||||
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
||||
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
|
||||
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
|
||||
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
|
||||
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
|
||||
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
|
||||
};
|
||||
|
||||
uint16_t crc16_sum(uint16_t crc, const uint8_t * buf, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < len; i++)
|
||||
crc = crc16_table[((crc >> 8) ^ *buf++) & 0xff] ^ (crc << 8);
|
||||
return crc;
|
||||
}
|
16
crc16.h
Normal file
16
crc16.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef __CRC16_H__
|
||||
#define __CRC16_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <x.h>
|
||||
|
||||
uint16_t crc16_sum(uint16_t crc, const uint8_t * buf, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CRC16_H__ */
|
275
main.c
Normal file
275
main.c
Normal file
@ -0,0 +1,275 @@
|
||||
#include <rock.h>
|
||||
|
||||
static uint64_t file_save(const char * filename, void * buf, uint64_t len)
|
||||
{
|
||||
FILE * out = fopen(filename, "wb");
|
||||
int r;
|
||||
if(!out)
|
||||
{
|
||||
perror("Failed to open output file");
|
||||
exit(-1);
|
||||
}
|
||||
r = fwrite(buf, len, 1, out);
|
||||
fclose(out);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void * file_load(const char * filename, uint64_t * len)
|
||||
{
|
||||
uint64_t offset = 0, bufsize = 8192;
|
||||
char * buf = malloc(bufsize);
|
||||
FILE * in;
|
||||
if(strcmp(filename, "-") == 0)
|
||||
in = stdin;
|
||||
else
|
||||
in = fopen(filename, "rb");
|
||||
if(!in)
|
||||
{
|
||||
perror("Failed to open input file");
|
||||
exit(-1);
|
||||
}
|
||||
while(1)
|
||||
{
|
||||
uint64_t len = bufsize - offset;
|
||||
uint64_t n = fread(buf + offset, 1, len, in);
|
||||
offset += n;
|
||||
if(n < len)
|
||||
break;
|
||||
bufsize *= 2;
|
||||
buf = realloc(buf, bufsize);
|
||||
if(!buf)
|
||||
{
|
||||
perror("Failed to resize load_file() buffer");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
if(len)
|
||||
*len = offset;
|
||||
if(in != stdin)
|
||||
fclose(in);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void hexdump(uint32_t addr, void * buf, size_t len)
|
||||
{
|
||||
unsigned char * p = buf;
|
||||
size_t i, j;
|
||||
|
||||
for(j = 0; j < len; j += 16)
|
||||
{
|
||||
printf("%08zx: ", addr + j);
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
if(j + i < len)
|
||||
printf("%02x ", p[j + i]);
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
putchar(' ');
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
if(j + i >= len)
|
||||
putchar(' ');
|
||||
else
|
||||
putchar(isprint(p[j + i]) ? p[j + i] : '.');
|
||||
}
|
||||
printf("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
printf("xrock(v1.0.0) - https://github.com/xboot/xrock\r\n");
|
||||
printf("usage:\r\n");
|
||||
printf(" xrock maskrom <ddr> <usbplug> - Initial chip using ddr and usbplug in maskrom mode\r\n");
|
||||
|
||||
printf(" xrock version - Show chip version\r\n");
|
||||
printf(" xrock hexdump <address> <length> - Dumps memory region in hex\r\n");
|
||||
printf(" xrock dump <address> <length> - Binary memory dump to stdout\r\n");
|
||||
printf(" xrock exec <address> - Call function address\r\n");
|
||||
printf(" xrock read32 <address> - Read 32-bits value from device memory\r\n");
|
||||
printf(" xrock write32 <address> <value> - Write 32-bits value to device memory\r\n");
|
||||
printf(" xrock read <address> <length> <file> - Read memory to file\r\n");
|
||||
printf(" xrock write <address> <file> - Write file to memory\r\n");
|
||||
printf(" xrock reset - Reset device using watchdog\r\n");
|
||||
printf(" xrock sid - Show sid information\r\n");
|
||||
printf(" xrock jtag - Enable jtag debug\r\n");
|
||||
printf(" xrock ddr [type] - Initial ddr controller with optional type\r\n");
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
struct xrock_ctx_t ctx;
|
||||
|
||||
if(argc < 2)
|
||||
{
|
||||
usage();
|
||||
return -1;
|
||||
}
|
||||
libusb_init(NULL);
|
||||
if(!xrock_init(&ctx))
|
||||
{
|
||||
printf("ERROR: Can't found any rockchip chips\r\n");
|
||||
if(ctx.hdl)
|
||||
libusb_close(ctx.hdl);
|
||||
libusb_exit(NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ctx.maskrom)
|
||||
{
|
||||
if(!strcmp(argv[1], "maskrom"))
|
||||
{
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
if(argc == 2)
|
||||
{
|
||||
rock_maskrom_init_ddr(&ctx, argv[0]);
|
||||
rock_maskrom_init_usbplug(&ctx, argv[1]);
|
||||
}
|
||||
else
|
||||
usage();
|
||||
}
|
||||
else
|
||||
usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!strcmp(argv[1], "version"))
|
||||
{
|
||||
printf("%.8s soc=0x%08x(%s) 0x%08x ver=0x%04x 0x%02x 0x%02x scratchpad=0x%08x\r\n",
|
||||
ctx.version.magic, ctx.version.id, ctx.chip->name, ctx.version.firmware,
|
||||
ctx.version.protocol, ctx.version.dflag, ctx.version.dlength, ctx.version.scratchpad);
|
||||
}
|
||||
else if(!strcmp(argv[1], "hexdump"))
|
||||
{
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
if(argc == 2)
|
||||
{
|
||||
uint32_t addr = strtoul(argv[0], NULL, 0);
|
||||
size_t len = strtoul(argv[1], NULL, 0);
|
||||
char * buf = malloc(len);
|
||||
if(buf)
|
||||
{
|
||||
fel_read(&ctx, addr, buf, len);
|
||||
hexdump(addr, buf, len);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
usage();
|
||||
}
|
||||
else if(!strcmp(argv[1], "dump"))
|
||||
{
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
if(argc == 2)
|
||||
{
|
||||
uint32_t addr = strtoul(argv[0], NULL, 0);
|
||||
size_t len = strtoul(argv[1], NULL, 0);
|
||||
char * buf = malloc(len);
|
||||
if(buf)
|
||||
{
|
||||
fel_read(&ctx, addr, buf, len);
|
||||
fwrite(buf, len, 1, stdout);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
usage();
|
||||
}
|
||||
else if(!strcmp(argv[1], "exec"))
|
||||
{
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
if(argc == 1)
|
||||
{
|
||||
uint32_t addr = strtoul(argv[0], NULL, 0);
|
||||
fel_exec(&ctx, addr);
|
||||
}
|
||||
else
|
||||
usage();
|
||||
}
|
||||
else if(!strcmp(argv[1], "read32"))
|
||||
{
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
if(argc == 1)
|
||||
{
|
||||
uint32_t addr = strtoul(argv[0], NULL, 0);
|
||||
printf("0x%08x\r\n", fel_read32(&ctx, addr));
|
||||
}
|
||||
else
|
||||
usage();
|
||||
}
|
||||
else if(!strcmp(argv[1], "write32"))
|
||||
{
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
if(argc == 2)
|
||||
{
|
||||
uint32_t addr = strtoul(argv[0], NULL, 0);
|
||||
size_t val = strtoul(argv[1], NULL, 0);
|
||||
fel_write32(&ctx, addr, val);
|
||||
}
|
||||
else
|
||||
usage();
|
||||
}
|
||||
else if(!strcmp(argv[1], "read"))
|
||||
{
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
if(argc == 3)
|
||||
{
|
||||
uint32_t addr = strtoul(argv[0], NULL, 0);
|
||||
size_t len = strtoul(argv[1], NULL, 0);
|
||||
char * buf = malloc(len);
|
||||
if(buf)
|
||||
{
|
||||
fel_read_progress(&ctx, addr, buf, len);
|
||||
file_save(argv[2], buf, len);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
usage();
|
||||
}
|
||||
else if(!strcmp(argv[1], "write"))
|
||||
{
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
if(argc == 2)
|
||||
{
|
||||
uint32_t addr = strtoul(argv[0], NULL, 0);
|
||||
size_t len;
|
||||
void * buf = file_load(argv[1], &len);
|
||||
if(buf)
|
||||
{
|
||||
fel_write_progress(&ctx, addr, buf, len);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
usage();
|
||||
}
|
||||
else if(!strcmp(argv[1], "reset"))
|
||||
{
|
||||
}
|
||||
else if(!strcmp(argv[1], "sid"))
|
||||
{
|
||||
}
|
||||
else if(!strcmp(argv[1], "jtag"))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
usage();
|
||||
}
|
||||
}
|
||||
if(ctx.hdl)
|
||||
libusb_close(ctx.hdl);
|
||||
libusb_exit(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
58
progress.c
Normal file
58
progress.c
Normal file
@ -0,0 +1,58 @@
|
||||
#include <progress.h>
|
||||
|
||||
static inline double gettime(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return tv.tv_sec + (double)tv.tv_usec / 1000000.0;
|
||||
}
|
||||
|
||||
static inline const char * format_eta(double remaining)
|
||||
{
|
||||
static char result[6] = "";
|
||||
int seconds = remaining + 0.5;
|
||||
if(seconds >= 0 && seconds < 6000)
|
||||
{
|
||||
snprintf(result, sizeof(result), "%02d:%02d", seconds / 60, seconds % 60);
|
||||
return result;
|
||||
}
|
||||
return "--:--";
|
||||
}
|
||||
|
||||
void progress_start(struct progress_t * p, size_t total)
|
||||
{
|
||||
if(p && (total > 0))
|
||||
{
|
||||
p->total = total;
|
||||
p->done = 0;
|
||||
p->start = gettime();
|
||||
}
|
||||
}
|
||||
|
||||
void progress_update(struct progress_t * p, size_t bytes)
|
||||
{
|
||||
if(p)
|
||||
{
|
||||
p->done += bytes;
|
||||
double ratio = p->total > 0 ? (double)p->done / (double)p->total : 0.0;
|
||||
double speed = (double)p->done / (gettime() - p->start);
|
||||
double eta = speed > 0 ? (p->total - p->done) / speed : 0;
|
||||
int i, pos = 48 * ratio;
|
||||
printf("\r%3.0f%% [", ratio * 100);
|
||||
for(i = 0; i < pos; i++)
|
||||
putchar('=');
|
||||
for(i = pos; i < 48; i++)
|
||||
putchar(' ');
|
||||
if(p->done < p->total)
|
||||
printf("]%6.1f kB/s, ETA %s ", speed / 1000.0, format_eta(eta));
|
||||
else
|
||||
printf("] %5.0f kB, %6.1f kB/s", p->done / 1000.0, speed / 1000.0);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
void progress_stop(struct progress_t * p)
|
||||
{
|
||||
if(p)
|
||||
printf("\r\n");
|
||||
}
|
24
progress.h
Normal file
24
progress.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef __PROGRESS_H__
|
||||
#define __PROGRESS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <x.h>
|
||||
|
||||
struct progress_t {
|
||||
size_t total;
|
||||
size_t done;
|
||||
double start;
|
||||
};
|
||||
|
||||
void progress_start(struct progress_t * p, size_t total);
|
||||
void progress_update(struct progress_t * p, size_t bytes);
|
||||
void progress_stop(struct progress_t * p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PROGRESS_H__ */
|
42
rc4.c
Normal file
42
rc4.c
Normal file
@ -0,0 +1,42 @@
|
||||
#include <rc4.h>
|
||||
|
||||
void rc4_setkey(struct rc4_ctx_t * ctx, uint8_t * key, int len)
|
||||
{
|
||||
uint8_t * s = ctx->s;
|
||||
uint8_t k[256], t;
|
||||
int i, j;
|
||||
|
||||
for(i = 0; i < 256; i++)
|
||||
{
|
||||
s[i] = (uint8_t)i;
|
||||
k[i] = key[i % len];
|
||||
}
|
||||
for(i = 0, j = 0; i < 256; i++)
|
||||
{
|
||||
j = (j + s[i] + k[i]) & 0xff;
|
||||
t = s[i];
|
||||
s[i] = s[j];
|
||||
s[j] = t;
|
||||
}
|
||||
ctx->i = 0;
|
||||
ctx->j = 0;
|
||||
}
|
||||
|
||||
void rc4_crypt(struct rc4_ctx_t * ctx, uint8_t * buf, int len)
|
||||
{
|
||||
uint8_t * s = ctx->s;
|
||||
uint8_t t;
|
||||
int i, j, o;
|
||||
|
||||
for(i = ctx->i, j = ctx->j, o = 0; o < len; o++)
|
||||
{
|
||||
i = (i + 1) & 0xff;
|
||||
j = (j + s[i]) & 0xff;
|
||||
t = s[i];
|
||||
s[i] = s[j];
|
||||
s[j] = t;
|
||||
buf[o] ^= s[(s[i] + s[j]) & 0xff];
|
||||
}
|
||||
ctx->i = i;
|
||||
ctx->j = j;
|
||||
}
|
22
rc4.h
Normal file
22
rc4.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef __RC4_H__
|
||||
#define __RC4_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <x.h>
|
||||
|
||||
struct rc4_ctx_t {
|
||||
uint8_t s[256];
|
||||
int i, j;
|
||||
};
|
||||
|
||||
void rc4_setkey(struct rc4_ctx_t * ctx, uint8_t * key, int len);
|
||||
void rc4_crypt(struct rc4_ctx_t * ctx, uint8_t * buf, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __RC4_H__ */
|
388
rock.c
Normal file
388
rock.c
Normal file
@ -0,0 +1,388 @@
|
||||
#include <rock.h>
|
||||
|
||||
static struct chip_t chips[] = {
|
||||
{ 0x281a, "RK2818" },
|
||||
{ 0x290a, "RK2918" },
|
||||
{ 0x292a, "RK2928" },
|
||||
{ 0x292c, "RK3026" },
|
||||
{ 0x300a, "RK3066" },
|
||||
{ 0x300b, "RK3168" },
|
||||
{ 0x301a, "RK3036" },
|
||||
{ 0x310a, "RK3066B" },
|
||||
{ 0x310b, "RK3188" },
|
||||
{ 0x310c, "RK312X" },
|
||||
{ 0x320a, "RK3288" },
|
||||
{ 0x320b, "RK322X" },
|
||||
{ 0x320c, "RK3328" },
|
||||
{ 0x330a, "RK3368" },
|
||||
{ 0x330c, "RK3399" },
|
||||
};
|
||||
|
||||
int xrock_init(struct xrock_ctx_t * ctx)
|
||||
{
|
||||
if(ctx)
|
||||
{
|
||||
struct libusb_device_descriptor desc;
|
||||
libusb_device_handle * hdl;
|
||||
int i;
|
||||
|
||||
ctx->hdl = NULL;
|
||||
ctx->chip = NULL;
|
||||
for(i = 0; i < ARRAY_SIZE(chips); i++)
|
||||
{
|
||||
hdl = libusb_open_device_with_vid_pid(NULL, 0x2207, chips[i].pid);
|
||||
if(hdl)
|
||||
{
|
||||
ctx->hdl = hdl;
|
||||
ctx->chip = &chips[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(ctx->hdl && ctx->chip)
|
||||
{
|
||||
if(libusb_kernel_driver_active(ctx->hdl, 0) == 1)
|
||||
libusb_detach_kernel_driver(ctx->hdl, 0);
|
||||
if(libusb_claim_interface(ctx->hdl, 0) == 0)
|
||||
{
|
||||
if(libusb_get_device_descriptor(libusb_get_device(ctx->hdl), &desc) == 0)
|
||||
{
|
||||
if((desc.bcdUSB & 0x0001) == 0x0000)
|
||||
ctx->maskrom = 1;
|
||||
else
|
||||
ctx->maskrom = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rock_maskrom_init_ddr(struct xrock_ctx_t * ctx, const char * filename)
|
||||
{
|
||||
struct rc4_ctx_t rc4;
|
||||
uint8_t key[16] = { 124, 78, 3, 4, 85, 5, 9, 7, 45, 44, 123, 56, 23, 13, 23, 17 };
|
||||
uint16_t crc16 = 0xffff;
|
||||
uint8_t buf[4096 + 2];
|
||||
FILE * f;
|
||||
int n;
|
||||
|
||||
rc4_setkey(&rc4, key, sizeof(key));
|
||||
f = fopen(filename, "rb");
|
||||
if(!f)
|
||||
{
|
||||
perror("Failed to open ddr file");
|
||||
exit(-1);
|
||||
}
|
||||
while((n = fread(buf, 1, 4096, f)) == 4096)
|
||||
{
|
||||
rc4_crypt(&rc4, buf, n);
|
||||
crc16 = crc16_sum(crc16, buf, n);
|
||||
libusb_control_transfer(ctx->hdl, LIBUSB_REQUEST_TYPE_VENDOR, 12, 0, 1137, buf, n, 0);
|
||||
}
|
||||
fclose(f);
|
||||
if(n >= 0)
|
||||
{
|
||||
rc4_crypt(&rc4, buf, n);
|
||||
crc16 = crc16_sum(crc16, buf, n);
|
||||
buf[n++] = crc16 >> 8;
|
||||
buf[n++] = crc16 & 0xff;
|
||||
libusb_control_transfer(ctx->hdl, LIBUSB_REQUEST_TYPE_VENDOR, 12, 0, 1137, buf, n, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void rock_maskrom_init_usbplug(struct xrock_ctx_t * ctx, const char * filename)
|
||||
{
|
||||
struct rc4_ctx_t rc4;
|
||||
uint8_t key[16] = { 124, 78, 3, 4, 85, 5, 9, 7, 45, 44, 123, 56, 23, 13, 23, 17 };
|
||||
uint16_t crc16 = 0xffff;
|
||||
uint8_t buf[4096 + 2];
|
||||
FILE * f;
|
||||
int n;
|
||||
|
||||
rc4_setkey(&rc4, key, sizeof(key));
|
||||
f = fopen(filename, "rb");
|
||||
if(!f)
|
||||
{
|
||||
perror("Failed to open usbplug file");
|
||||
exit(-1);
|
||||
}
|
||||
while((n = fread(buf, 1, 4096, f)) == 4096)
|
||||
{
|
||||
rc4_crypt(&rc4, buf, n);
|
||||
crc16 = crc16_sum(crc16, buf, n);
|
||||
libusb_control_transfer(ctx->hdl, LIBUSB_REQUEST_TYPE_VENDOR, 12, 0, 1138, buf, n, 0);
|
||||
}
|
||||
fclose(f);
|
||||
if(n >= 0)
|
||||
{
|
||||
rc4_crypt(&rc4, buf, n);
|
||||
crc16 = crc16_sum(crc16, buf, n);
|
||||
buf[n++] = crc16 >> 8;
|
||||
buf[n++] = crc16 & 0xff;
|
||||
libusb_control_transfer(ctx->hdl, LIBUSB_REQUEST_TYPE_VENDOR, 12, 0, 1138, buf, n, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct usb_request_t {
|
||||
char magic[8];
|
||||
uint32_t length;
|
||||
uint32_t unknown1;
|
||||
uint16_t request;
|
||||
uint32_t length2;
|
||||
char pad[10];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct fel_request_t {
|
||||
uint32_t request;
|
||||
uint32_t address;
|
||||
uint32_t length;
|
||||
uint32_t pad;
|
||||
} __attribute__((packed));
|
||||
|
||||
static inline void usb_bulk_send(libusb_device_handle * hdl, int ep, const char * buf, size_t len)
|
||||
{
|
||||
size_t max_chunk = 128 * 1024;
|
||||
size_t chunk;
|
||||
int r, bytes;
|
||||
|
||||
while(len > 0)
|
||||
{
|
||||
chunk = len < max_chunk ? len : max_chunk;
|
||||
r = libusb_bulk_transfer(hdl, ep, (void *)buf, chunk, &bytes, 10000);
|
||||
if(r != 0)
|
||||
{
|
||||
printf("usb bulk send error\r\n");
|
||||
exit(-1);
|
||||
}
|
||||
len -= bytes;
|
||||
buf += bytes;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void usb_bulk_recv(libusb_device_handle * hdl, int ep, char * buf, size_t len)
|
||||
{
|
||||
int r, bytes;
|
||||
|
||||
while(len > 0)
|
||||
{
|
||||
r = libusb_bulk_transfer(hdl, ep, (void *)buf, len, &bytes, 10000);
|
||||
if(r != 0)
|
||||
{
|
||||
printf("usb bulk recv error\r\n");
|
||||
exit(-1);
|
||||
}
|
||||
len -= bytes;
|
||||
buf += bytes;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void send_usb_request(struct xrock_ctx_t * ctx, int type, size_t length)
|
||||
{
|
||||
struct usb_request_t req = {
|
||||
.magic = "AWUC",
|
||||
.request = cpu_to_le16(type),
|
||||
.length = cpu_to_le32(length),
|
||||
.unknown1 = cpu_to_le32(0x0c000000)
|
||||
};
|
||||
req.length2 = req.length;
|
||||
usb_bulk_send(ctx->hdl, ctx->epout, (const char *)&req, sizeof(struct usb_request_t));
|
||||
}
|
||||
|
||||
static inline void read_usb_response(struct xrock_ctx_t * ctx)
|
||||
{
|
||||
char buf[13];
|
||||
|
||||
usb_bulk_recv(ctx->hdl, ctx->epin, (char *)buf, sizeof(buf));
|
||||
assert(strcmp(buf, "AWUS") == 0);
|
||||
}
|
||||
|
||||
static inline void usb_write(struct xrock_ctx_t * ctx, const void * buf, size_t len)
|
||||
{
|
||||
send_usb_request(ctx, 0x12, len);
|
||||
usb_bulk_send(ctx->hdl, ctx->epout, (const char *)buf, len);
|
||||
read_usb_response(ctx);
|
||||
}
|
||||
|
||||
static inline void usb_read(struct xrock_ctx_t * ctx, const void * data, size_t len)
|
||||
{
|
||||
send_usb_request(ctx, 0x11, len);
|
||||
usb_bulk_send(ctx->hdl, ctx->epin, (const char *)data, len);
|
||||
read_usb_response(ctx);
|
||||
}
|
||||
|
||||
static inline void send_fel_request(struct xrock_ctx_t * ctx, int type, uint32_t addr, uint32_t length)
|
||||
{
|
||||
struct fel_request_t req = {
|
||||
.request = cpu_to_le32(type),
|
||||
.address = cpu_to_le32(addr),
|
||||
.length = cpu_to_le32(length)
|
||||
};
|
||||
usb_write(ctx, &req, sizeof(struct fel_request_t));
|
||||
}
|
||||
|
||||
static inline void read_fel_status(struct xrock_ctx_t * ctx)
|
||||
{
|
||||
char buf[8];
|
||||
usb_read(ctx, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
static inline void fel_version(struct xrock_ctx_t * ctx)
|
||||
{
|
||||
int i;
|
||||
|
||||
send_fel_request(ctx, 0x001, 0, 0);
|
||||
usb_read(ctx, &ctx->version, sizeof(ctx->version));
|
||||
read_fel_status(ctx);
|
||||
ctx->version.id = le32_to_cpu(ctx->version.id);
|
||||
ctx->version.firmware = le32_to_cpu(ctx->version.firmware);
|
||||
ctx->version.protocol = le16_to_cpu(ctx->version.protocol);
|
||||
ctx->version.scratchpad = le32_to_cpu(ctx->version.scratchpad);
|
||||
ctx->chip = NULL;
|
||||
for(i = 0; i < ARRAY_SIZE(chips); i++)
|
||||
{
|
||||
/* if(chips[i]->id == ctx->version.id)
|
||||
{
|
||||
ctx->chip = chips[i];
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
int fel_init(struct xrock_ctx_t * ctx)
|
||||
{
|
||||
if(ctx && ctx->hdl)
|
||||
{
|
||||
struct libusb_config_descriptor * config;
|
||||
int if_idx, set_idx, ep_idx;
|
||||
const struct libusb_interface * iface;
|
||||
const struct libusb_interface_descriptor * setting;
|
||||
const struct libusb_endpoint_descriptor * ep;
|
||||
if(libusb_claim_interface(ctx->hdl, 0) == 0)
|
||||
{
|
||||
if(libusb_get_active_config_descriptor(libusb_get_device(ctx->hdl), &config) == 0)
|
||||
{
|
||||
for(if_idx = 0; if_idx < config->bNumInterfaces; if_idx++)
|
||||
{
|
||||
iface = config->interface + if_idx;
|
||||
for(set_idx = 0; set_idx < iface->num_altsetting; set_idx++)
|
||||
{
|
||||
setting = iface->altsetting + set_idx;
|
||||
for(ep_idx = 0; ep_idx < setting->bNumEndpoints; ep_idx++)
|
||||
{
|
||||
ep = setting->endpoint + ep_idx;
|
||||
if((ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) != LIBUSB_TRANSFER_TYPE_BULK)
|
||||
continue;
|
||||
if((ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN)
|
||||
ctx->epin = ep->bEndpointAddress;
|
||||
else
|
||||
ctx->epout = ep->bEndpointAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
libusb_free_config_descriptor(config);
|
||||
fel_version(ctx);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fel_exec(struct xrock_ctx_t * ctx, uint32_t addr)
|
||||
{
|
||||
send_fel_request(ctx, 0x102, addr, 0);
|
||||
read_fel_status(ctx);
|
||||
}
|
||||
|
||||
static inline void fel_read_raw(struct xrock_ctx_t * ctx, uint32_t addr, void * buf, size_t len)
|
||||
{
|
||||
send_fel_request(ctx, 0x103, addr, len);
|
||||
usb_read(ctx, buf, len);
|
||||
read_fel_status(ctx);
|
||||
}
|
||||
|
||||
static inline void fel_write_raw(struct xrock_ctx_t * ctx, uint32_t addr, void * buf, size_t len)
|
||||
{
|
||||
send_fel_request(ctx, 0x101, addr, len);
|
||||
usb_write(ctx, buf, len);
|
||||
read_fel_status(ctx);
|
||||
}
|
||||
|
||||
uint32_t fel_read32(struct xrock_ctx_t * ctx, uint32_t addr)
|
||||
{
|
||||
uint32_t val;
|
||||
fel_read_raw(ctx, addr, &val, sizeof(uint32_t));
|
||||
return val;
|
||||
}
|
||||
|
||||
void fel_write32(struct xrock_ctx_t * ctx, uint32_t addr, uint32_t val)
|
||||
{
|
||||
fel_write_raw(ctx, addr, &val, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void fel_read(struct xrock_ctx_t * ctx, uint32_t addr, void * buf, size_t len)
|
||||
{
|
||||
size_t n;
|
||||
|
||||
while(len > 0)
|
||||
{
|
||||
n = len > 65536 ? 65536 : len;
|
||||
fel_read_raw(ctx, addr, buf, n);
|
||||
addr += n;
|
||||
buf += n;
|
||||
len -= n;
|
||||
}
|
||||
}
|
||||
|
||||
void fel_write(struct xrock_ctx_t * ctx, uint32_t addr, void * buf, size_t len)
|
||||
{
|
||||
size_t n;
|
||||
|
||||
while(len > 0)
|
||||
{
|
||||
n = len > 65536 ? 65536 : len;
|
||||
fel_write_raw(ctx, addr, buf, n);
|
||||
addr += n;
|
||||
buf += n;
|
||||
len -= n;
|
||||
}
|
||||
}
|
||||
|
||||
void fel_read_progress(struct xrock_ctx_t * ctx, uint32_t addr, void * buf, size_t len)
|
||||
{
|
||||
struct progress_t p;
|
||||
size_t n;
|
||||
|
||||
progress_start(&p, len);
|
||||
while(len > 0)
|
||||
{
|
||||
n = len > 65536 ? 65536 : len;
|
||||
fel_read_raw(ctx, addr, buf, n);
|
||||
addr += n;
|
||||
buf += n;
|
||||
len -= n;
|
||||
progress_update(&p, n);
|
||||
}
|
||||
progress_stop(&p);
|
||||
}
|
||||
|
||||
void fel_write_progress(struct xrock_ctx_t * ctx, uint32_t addr, void * buf, size_t len)
|
||||
{
|
||||
struct progress_t p;
|
||||
size_t n;
|
||||
|
||||
progress_start(&p, len);
|
||||
while(len > 0)
|
||||
{
|
||||
n = len > 65536 ? 65536 : len;
|
||||
fel_write_raw(ctx, addr, buf, n);
|
||||
addr += n;
|
||||
buf += n;
|
||||
len -= n;
|
||||
progress_update(&p, n);
|
||||
}
|
||||
progress_stop(&p);
|
||||
}
|
46
rock.h
Normal file
46
rock.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef __ROCK_H__
|
||||
#define __ROCK_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <x.h>
|
||||
#include <rc4.h>
|
||||
#include <crc16.h>
|
||||
#include <progress.h>
|
||||
|
||||
struct chip_t {
|
||||
uint16_t pid;
|
||||
char * name;
|
||||
};
|
||||
|
||||
struct xrock_ctx_t {
|
||||
libusb_device_handle * hdl;
|
||||
struct chip_t * chip;
|
||||
int maskrom;
|
||||
|
||||
|
||||
int epout;
|
||||
int epin;
|
||||
struct {
|
||||
char magic[8];
|
||||
uint32_t id;
|
||||
uint32_t firmware;
|
||||
uint16_t protocol;
|
||||
uint8_t dflag;
|
||||
uint8_t dlength;
|
||||
uint32_t scratchpad;
|
||||
uint8_t pad[8];
|
||||
} version;
|
||||
};
|
||||
|
||||
int xrock_init(struct xrock_ctx_t * ctx);
|
||||
void rock_maskrom_init_ddr(struct xrock_ctx_t * ctx, const char * filename);
|
||||
void rock_maskrom_init_usbplug(struct xrock_ctx_t * ctx, const char * filename);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ROCK_H__ */
|
100
x.h
Normal file
100
x.h
Normal file
@ -0,0 +1,100 @@
|
||||
#ifndef __X_H__
|
||||
#define __X_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__)
|
||||
# define __WINDOWS__
|
||||
#endif
|
||||
#if defined(__linux__) || defined(__CYGWIN__)
|
||||
# include <endian.h>
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
# include <sys/endian.h>
|
||||
#elif defined(__WINDOWS__)
|
||||
# include <winsock2.h>
|
||||
# include <sys/param.h>
|
||||
#else
|
||||
# error "platform not supported!"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <libusb.h>
|
||||
|
||||
static inline uint16_t __swab16(uint16_t x)
|
||||
{
|
||||
return ( (x<<8) | (x>>8) );
|
||||
}
|
||||
|
||||
static inline uint32_t __swab32(uint32_t x)
|
||||
{
|
||||
return ( (x<<24) | (x>>24) | \
|
||||
((x & (uint32_t)0x0000ff00UL)<<8) | \
|
||||
((x & (uint32_t)0x00ff0000UL)>>8) );
|
||||
}
|
||||
|
||||
static inline uint64_t __swab64(uint64_t x)
|
||||
{
|
||||
return ( (x<<56) | (x>>56) | \
|
||||
((x & (uint64_t)0x000000000000ff00ULL)<<40) | \
|
||||
((x & (uint64_t)0x0000000000ff0000ULL)<<24) | \
|
||||
((x & (uint64_t)0x00000000ff000000ULL)<< 8) | \
|
||||
((x & (uint64_t)0x000000ff00000000ULL)>> 8) | \
|
||||
((x & (uint64_t)0x0000ff0000000000ULL)>>24) | \
|
||||
((x & (uint64_t)0x00ff000000000000ULL)>>40) );
|
||||
}
|
||||
|
||||
static inline uint32_t __swahw32(uint32_t x)
|
||||
{
|
||||
return ( ((x & (uint32_t)0x0000ffffUL)<<16) | ((x & (uint32_t)0xffff0000UL)>>16) );
|
||||
}
|
||||
|
||||
static inline uint32_t __swahb32(uint32_t x)
|
||||
{
|
||||
return ( ((x & (uint32_t)0x00ff00ffUL)<<8) | ((x & (uint32_t)0xff00ff00UL)>>8) );
|
||||
}
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define cpu_to_le64(x) (__swab64((uint64_t)(x)))
|
||||
#define le64_to_cpu(x) (__swab64((uint64_t)(x)))
|
||||
#define cpu_to_le32(x) (__swab32((uint32_t)(x)))
|
||||
#define le32_to_cpu(x) (__swab32((uint32_t)(x)))
|
||||
#define cpu_to_le16(x) (__swab16((uint16_t)(x)))
|
||||
#define le16_to_cpu(x) (__swab16((uint16_t)(x)))
|
||||
#define cpu_to_be64(x) ((uint64_t)(x))
|
||||
#define be64_to_cpu(x) ((uint64_t)(x))
|
||||
#define cpu_to_be32(x) ((uint32_t)(x))
|
||||
#define be32_to_cpu(x) ((uint32_t)(x))
|
||||
#define cpu_to_be16(x) ((uint16_t)(x))
|
||||
#define be16_to_cpu(x) ((uint16_t)(x))
|
||||
#else
|
||||
#define cpu_to_le64(x) ((uint64_t)(x))
|
||||
#define le64_to_cpu(x) ((uint64_t)(x))
|
||||
#define cpu_to_le32(x) ((uint32_t)(x))
|
||||
#define le32_to_cpu(x) ((uint32_t)(x))
|
||||
#define cpu_to_le16(x) ((uint16_t)(x))
|
||||
#define le16_to_cpu(x) ((uint16_t)(x))
|
||||
#define cpu_to_be64(x) (__swab64((uint64_t)(x)))
|
||||
#define be64_to_cpu(x) (__swab64((uint64_t)(x)))
|
||||
#define cpu_to_be32(x) (__swab32((uint32_t)(x)))
|
||||
#define be32_to_cpu(x) (__swab32((uint32_t)(x)))
|
||||
#define cpu_to_be16(x) (__swab16((uint16_t)(x)))
|
||||
#define be16_to_cpu(x) (__swab16((uint16_t)(x)))
|
||||
#endif
|
||||
|
||||
#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
|
||||
#define X(...) ("" #__VA_ARGS__ "")
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __X_H__ */
|
Loading…
Reference in New Issue
Block a user