Skip to content

Commit

Permalink
[a523]add jump arm64 extra command for A523/A527/T527/MR527
Browse files Browse the repository at this point in the history
  • Loading branch information
jianjunjiang committed Jul 31, 2024
1 parent 9728d78 commit 3725936
Show file tree
Hide file tree
Showing 16 changed files with 804 additions and 0 deletions.
61 changes: 61 additions & 0 deletions chips/a523_a527_t527.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,52 @@ static void payload_write32(struct xfel_ctx_t * ctx, uint32_t addr, uint32_t val
fel_exec(ctx, ctx->version.scratchpad);
}

static void payload_jmp_to_arm64(struct xfel_ctx_t * ctx, uint32_t addr)
{
static const uint8_t payload[] = {
0x00, 0x00, 0xa0, 0xe3, 0x17, 0x0f, 0x08, 0xee, 0x15, 0x0f, 0x07, 0xee,
0xd5, 0x0f, 0x07, 0xee, 0x9a, 0x0f, 0x07, 0xee, 0x95, 0x0f, 0x07, 0xee,
0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x40, 0x5c, 0x00, 0x9f, 0xe5,
0x00, 0xd0, 0x80, 0xe5, 0x04, 0xe0, 0x80, 0xe5, 0x00, 0xe0, 0x0f, 0xe1,
0x08, 0xe0, 0x80, 0xe5, 0x10, 0xef, 0x11, 0xee, 0x0c, 0xe0, 0x80, 0xe5,
0x10, 0xef, 0x1c, 0xee, 0x10, 0xe0, 0x80, 0xe5, 0x10, 0xef, 0x11, 0xee,
0x14, 0xe0, 0x80, 0xe5, 0x38, 0x00, 0x1f, 0xe5, 0x0c, 0x00, 0x00, 0xeb,
0x28, 0x00, 0x9f, 0xe5, 0x00, 0xd0, 0x90, 0xe5, 0x04, 0xe0, 0x90, 0xe5,
0x14, 0x10, 0x90, 0xe5, 0x10, 0x1f, 0x01, 0xee, 0x10, 0x10, 0x90, 0xe5,
0x10, 0x1f, 0x0c, 0xee, 0x0c, 0x10, 0x90, 0xe5, 0x10, 0x1f, 0x01, 0xee,
0x08, 0x10, 0x90, 0xe5, 0x01, 0xf0, 0x29, 0xe1, 0x1e, 0xff, 0x2f, 0xe1,
0xe0, 0x7f, 0x04, 0x00, 0x02, 0x23, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
0x40, 0x00, 0x82, 0xe5, 0x44, 0x10, 0x82, 0xe5, 0x50, 0x2f, 0x1c, 0xee,
0x03, 0x20, 0x82, 0xe3, 0x4f, 0xf0, 0x7f, 0xf5, 0x50, 0x2f, 0x0c, 0xee,
0x6f, 0xf0, 0x7f, 0xf5, 0x03, 0xf0, 0x20, 0xe3, 0xfd, 0xff, 0xff, 0xea,
0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x47, 0x4e, 0x55, 0x00, 0xec, 0x31, 0xc0, 0x4b, 0x42, 0x7a, 0x23, 0x57,
0x32, 0xfa, 0xfc, 0xe1, 0x02, 0xe3, 0xc1, 0x18, 0x42, 0x45, 0x69, 0x4c,
0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x6c, 0x64, 0x2d, 0x6c, 0x69, 0x6e, 0x75,
0x78, 0x2d, 0x61, 0x72, 0x6d, 0x68, 0x66, 0x2e, 0x73, 0x6f, 0x2e, 0x33,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xf5, 0xfe, 0xff, 0x6f, 0x08, 0x01, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00,
0x04, 0x01, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x02, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xfb, 0xff, 0xff, 0x6f,
0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
uint32_t adr = cpu_to_le32(addr);

fel_write(ctx, ctx->version.scratchpad, (void *)payload, sizeof(payload));
fel_write(ctx, ctx->version.scratchpad + 0x1c, (void *)&adr, sizeof(adr));
fel_exec(ctx, ctx->version.scratchpad);
}

static int chip_reset(struct xfel_ctx_t * ctx)
{
return 0;
Expand Down Expand Up @@ -2911,13 +2957,28 @@ static int chip_extra(struct xfel_ctx_t * ctx, int argc, char * argv[])
printf("The device does not enabled the security boot.\r\n");
return 1;
}
else if(!strcmp(argv[0], "exec"))
{
argc -= 1;
argv += 1;
if(argc > 0)
{
if(!strcmp(argv[0], "arm64") && (argc == 2))
{
uint32_t addr = strtoul(argv[1], NULL, 0);
payload_jmp_to_arm64(ctx, addr);
return 1;
}
}
}
}
printf("usage:\r\n");
printf(" xfel extra efuse dump - Dump all of the efuse information\r\n");
printf(" xfel extra efuse read32 <offset> - Read 32-bits value from efuse\r\n");
printf(" xfel extra efuse write32 <offset> <value> - Write 32-bits value to efuse\r\n");
printf(" xfel extra efuse write <offset> <file> - Write file to efuse\r\n");
printf(" xfel extra checksboot - Check whether security boot is enabled on the device\r\n");
printf(" xfel extra exec arm64 <address> - Boot arm64 and jump to address\r\n");
return 0;
}

Expand Down
10 changes: 10 additions & 0 deletions payloads/a523_a527_t527/jmp-arm64/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#
# Normal rules
#
*~

#
# Generated files
#
/.obj
/output
120 changes: 120 additions & 0 deletions payloads/a523_a527_t527/jmp-arm64/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#
# Top makefile
#

CROSS ?= arm-linux-gnueabihf-
NAME := jmp-arm64

#
# System environment variable.
#
ifeq ($(OS), Windows_NT)
HOSTOS := windows
else
ifneq (,$(findstring Linux, $(shell uname -a)))
HOSTOS := linux
endif
endif

#
# Load default variables.
#
ASFLAGS := -g -ggdb -Wall -O3
CFLAGS := -g -ggdb -Wall -O3
CXXFLAGS := -g -ggdb -Wall -O3
LDFLAGS := -T link.ld -nostdlib
ARFLAGS := -rcs
OCFLAGS := -v -O binary
ODFLAGS :=
MCFLAGS := -march=armv7-a -mtune=cortex-a7 -mfpu=vfpv4 -mfloat-abi=hard -marm -mno-thumb-interwork -mno-unaligned-access -fno-stack-protector

LIBDIRS :=
LIBS :=
INCDIRS :=
SRCDIRS :=

#
# Add external library
#
INCDIRS += include \
include/external
SRCDIRS += source \
source/external

#
# You shouldn't need to change anything below this point.
#
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
MKDIR := mkdir -p
CP := cp -af
RM := rm -fr
CD := cd
FIND := find

#
# X variables
#
X_ASFLAGS := $(MCFLAGS) $(ASFLAGS)
X_CFLAGS := $(MCFLAGS) $(CFLAGS)
X_CXXFLAGS := $(MCFLAGS) $(CXXFLAGS)
X_LDFLAGS := $(LDFLAGS)
X_OCFLAGS := $(OCFLAGS)
X_LIBDIRS := $(LIBDIRS)
X_LIBS := $(LIBS) -lgcc

X_OUT := output
X_NAME := $(patsubst %, $(X_OUT)/%, $(NAME))
X_INCDIRS := $(patsubst %, -I %, $(INCDIRS))
X_SRCDIRS := $(patsubst %, %, $(SRCDIRS))
X_OBJDIRS := $(patsubst %, .obj/%, $(X_SRCDIRS))

X_SFILES := $(foreach dir, $(X_SRCDIRS), $(wildcard $(dir)/*.S))
X_CFILES := $(foreach dir, $(X_SRCDIRS), $(wildcard $(dir)/*.c))
X_CPPFILES := $(foreach dir, $(X_SRCDIRS), $(wildcard $(dir)/*.cpp))

X_SDEPS := $(patsubst %, .obj/%, $(X_SFILES:.S=.o.d))
X_CDEPS := $(patsubst %, .obj/%, $(X_CFILES:.c=.o.d))
X_CPPDEPS := $(patsubst %, .obj/%, $(X_CPPFILES:.cpp=.o.d))
X_DEPS := $(X_SDEPS) $(X_CDEPS) $(X_CPPDEPS)

X_SOBJS := $(patsubst %, .obj/%, $(X_SFILES:.S=.o))
X_COBJS := $(patsubst %, .obj/%, $(X_CFILES:.c=.o))
X_CPPOBJS := $(patsubst %, .obj/%, $(X_CPPFILES:.cpp=.o))
X_OBJS := $(X_SOBJS) $(X_COBJS) $(X_CPPOBJS)

VPATH := $(X_OBJDIRS)

.PHONY: all clean
all : $(X_NAME)

$(X_NAME) : $(X_OBJS)
@echo [LD] Linking $@.elf
@$(CC) $(X_LDFLAGS) $(X_LIBDIRS) -Wl,--cref,-Map=$@.map $^ -o $@.elf $(X_LIBS)
@echo [OC] Objcopying $@.bin
@$(OC) $(X_OCFLAGS) $@.elf $@.bin

$(X_SOBJS) : .obj/%.o : %.S
@echo [AS] $<
@$(AS) $(X_ASFLAGS) -MD -MP -MF $@.d $(X_INCDIRS) -c $< -o $@

$(X_COBJS) : .obj/%.o : %.c
@echo [CC] $<
@$(CC) $(X_CFLAGS) -MD -MP -MF $@.d $(X_INCDIRS) -c $< -o $@

$(X_CPPOBJS) : .obj/%.o : %.cpp
@echo [CXX] $<
@$(CXX) $(X_CXXFLAGS) -MD -MP -MF $@.d $(X_INCDIRS) -c $< -o $@

clean:
@$(RM) .obj $(X_OUT)

#
# Include the dependency files, should be place the last of makefile
#
sinclude $(shell $(MKDIR) $(X_OBJDIRS) $(X_OUT)) $(X_DEPS)
83 changes: 83 additions & 0 deletions payloads/a523_a527_t527/jmp-arm64/include/byteorder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#ifndef __BYTEORDER_H__
#define __BYTEORDER_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <types.h>

static inline u16_t __swab16(u16_t x)
{
return ( (x<<8) | (x>>8) );
}

static inline u32_t __swab32(u32_t x)
{
return ( (x<<24) | (x>>24) | \
((x & (u32_t)0x0000ff00UL)<<8) | \
((x & (u32_t)0x00ff0000UL)>>8) );
}

static inline u64_t __swab64(u64_t x)
{
return ( (x<<56) | (x>>56) | \
((x & (u64_t)0x000000000000ff00ULL)<<40) | \
((x & (u64_t)0x0000000000ff0000ULL)<<24) | \
((x & (u64_t)0x00000000ff000000ULL)<< 8) | \
((x & (u64_t)0x000000ff00000000ULL)>> 8) | \
((x & (u64_t)0x0000ff0000000000ULL)>>24) | \
((x & (u64_t)0x00ff000000000000ULL)>>40) );
}

/*
* swap bytes bizarrely.
* swahw32 - swap 16-bit half-words in a 32-bit word
*/
static inline u32_t __swahw32(u32_t x)
{
return ( ((x & (u32_t)0x0000ffffUL)<<16) | ((x & (u32_t)0xffff0000UL)>>16) );
}

/*
* swap bytes bizarrely.
* swahb32 - swap 8-bit halves of each 16-bit half-word in a 32-bit word
*/
static inline u32_t __swahb32(u32_t x)
{
return ( ((x & (u32_t)0x00ff00ffUL)<<8) | ((x & (u32_t)0xff00ff00UL)>>8) );
}

#if (BYTE_ORDER == BIG_ENDIAN)
#define cpu_to_le64(x) (__swab64((u64_t)(x)))
#define le64_to_cpu(x) (__swab64((u64_t)(x)))
#define cpu_to_le32(x) (__swab32((u32_t)(x)))
#define le32_to_cpu(x) (__swab32((u32_t)(x)))
#define cpu_to_le16(x) (__swab16((u16_t)(x)))
#define le16_to_cpu(x) (__swab16((u16_t)(x)))
#define cpu_to_be64(x) ((u64_t)(x))
#define be64_to_cpu(x) ((u64_t)(x))
#define cpu_to_be32(x) ((u32_t)(x))
#define be32_to_cpu(x) ((u32_t)(x))
#define cpu_to_be16(x) ((u16_t)(x))
#define be16_to_cpu(x) ((u16_t)(x))
#else
#define cpu_to_le64(x) ((u64_t)(x))
#define le64_to_cpu(x) ((u64_t)(x))
#define cpu_to_le32(x) ((u32_t)(x))
#define le32_to_cpu(x) ((u32_t)(x))
#define cpu_to_le16(x) ((u16_t)(x))
#define le16_to_cpu(x) ((u16_t)(x))
#define cpu_to_be64(x) (__swab64((u64_t)(x)))
#define be64_to_cpu(x) (__swab64((u64_t)(x)))
#define cpu_to_be32(x) (__swab32((u32_t)(x)))
#define be32_to_cpu(x) (__swab32((u32_t)(x)))
#define cpu_to_be16(x) (__swab16((u16_t)(x)))
#define be16_to_cpu(x) (__swab16((u16_t)(x)))
#endif

#ifdef __cplusplus
}
#endif

#endif /* __BYTEORDER_H__ */
27 changes: 27 additions & 0 deletions payloads/a523_a527_t527/jmp-arm64/include/endian.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef __ARM32_ENDIAN_H__
#define __ARM32_ENDIAN_H__

#ifdef __cplusplus
extern "C" {
#endif

#define LITTLE_ENDIAN (0x1234)
#define BIG_ENDIAN (0x4321)

#if ( !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN) )
#define __LITTLE_ENDIAN
#endif

#if defined(__LITTLE_ENDIAN)
#define BYTE_ORDER LITTLE_ENDIAN
#elif defined(__BIG_ENDIAN)
#define BYTE_ORDER BIG_ENDIAN
#else
#error "Unknown byte order!"
#endif

#ifdef __cplusplus
}
#endif

#endif /* __ARM32_ENDIAN_H__ */
54 changes: 54 additions & 0 deletions payloads/a523_a527_t527/jmp-arm64/include/io.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef __IO_H__
#define __IO_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <types.h>

static inline u8_t read8(virtual_addr_t addr)
{
return( *((volatile u8_t *)(addr)) );
}

static inline u16_t read16(virtual_addr_t addr)
{
return( *((volatile u16_t *)(addr)) );
}

static inline u32_t read32(virtual_addr_t addr)
{
return( *((volatile u32_t *)(addr)) );
}

static inline u64_t read64(virtual_addr_t addr)
{
return( *((volatile u64_t *)(addr)) );
}

static inline void write8(virtual_addr_t addr, u8_t value)
{
*((volatile u8_t *)(addr)) = value;
}

static inline void write16(virtual_addr_t addr, u16_t value)
{
*((volatile u16_t *)(addr)) = value;
}

static inline void write32(virtual_addr_t addr, u32_t value)
{
*((volatile u32_t *)(addr)) = value;
}

static inline void write64(virtual_addr_t addr, u64_t value)
{
*((volatile u64_t *)(addr)) = value;
}

#ifdef __cplusplus
}
#endif

#endif /* __IO_H__ */
Loading

0 comments on commit 3725936

Please sign in to comment.