On Fri, Dec 13, 2013 at 11:58:05AM +0100, Andrew Jones wrote: > We're going to need PSR bit defines and pt_regs. We'll also need > pt_regs offsets in assembly code. This patch adapts the linux > kernel's ptrace.h and asm-offsets to this framework. Even though > lib/arm/asm-offsets.h is a generated file, we still commit it, > as it's unlikely to change. Also adapt cp15.h from the kernel, > since we'll need bit defines from there too. Why commit the autogenerated header? That will just create noise in the git log... It seems like it's auto-building it every time anyway, so it would only be to avoid that step... > > Signed-off-by: Andrew Jones <drjones@xxxxxxxxxx> > --- > config/config-arm.mak | 17 ++++++-- > lib/arm/asm-offsets.h | 27 +++++++++++++ > lib/arm/cp15.h | 36 +++++++++++++++++ > lib/arm/ptrace.h | 100 ++++++++++++++++++++++++++++++++++++++++++++++ > scripts/arm/asm-offsets.c | 40 +++++++++++++++++++ > 5 files changed, 216 insertions(+), 4 deletions(-) > create mode 100644 lib/arm/asm-offsets.h > create mode 100644 lib/arm/cp15.h > create mode 100644 lib/arm/ptrace.h > create mode 100644 scripts/arm/asm-offsets.c > > diff --git a/config/config-arm.mak b/config/config-arm.mak > index d0814186b279c..173e606fbe64c 100644 > --- a/config/config-arm.mak > +++ b/config/config-arm.mak > @@ -1,3 +1,4 @@ > +PROCESSOR = cortex-a15 > mach = mach-virt > iodevs = pl011 virtio_mmio > phys_base = 0x40000000 > @@ -30,8 +31,7 @@ $(libcflat) $(libeabi): CFLAGS += -ffreestanding -I lib > > CFLAGS += -Wextra > CFLAGS += -marm > -#CFLAGS += -mcpu=$(PROCESSOR) > -CFLAGS += -mcpu=cortex-a15 > +CFLAGS += -mcpu=$(PROCESSOR) > CFLAGS += -O2 unrelated changes? > > libgcc := $(shell $(CC) -m$(ARCH) --print-libgcc-file-name) > @@ -55,7 +55,7 @@ tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg > > test_cases: $(tests-common) $(tests) > > -$(TEST_DIR)/%.o: CFLAGS += -std=gnu99 -ffreestanding -I lib > +$(TEST_DIR)/%.o scripts/arm/%.o: CFLAGS += -std=gnu99 -ffreestanding -I lib > > $(TEST_DIR)/boot.elf: $(cstart.o) $(TEST_DIR)/boot.o > > @@ -67,7 +67,16 @@ lib/$(TEST_DIR)/mach-virt.dts: > $(QEMU_BIN) -kernel /dev/null -M virt -machine dumpdtb=$(dtb) > fdtdump $(dtb) > $@ > > +.PHONY: asm-offsets > + > +asm-offsets: scripts/arm/asm-offsets.flat > + $(QEMU_BIN) -device virtio-testdev -display none -serial stdio \ > + -M virt -cpu $(PROCESSOR) \ > + -kernel $^ > lib/arm/asm-offsets.h || true this is a shame, you're depending on a full working setup with a correct QEMU to just build this thing. Did you consider replicating the kernel's Kbuild approach? In fact, when I started playing around with this, it was quite the hassle, because I run with a cross-compiled QEMU for my ARM devices which doesn't compile on my build-machine, so now I need a different x86-compiled QEMU with mach-virt support compiled somewhere, and I can only build unit-tests when I remember to set the QEMU variable in my shell. So if we really stick with this approach, why not make it part of the ./configure options? That being said, I really want the build here only to depend on having an ARM compiler :(( > +scripts/arm/asm-offsets.elf: $(cstart.o) scripts/arm/asm-offsets.o > + > arch_clean: > $(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \ > $(libeabi) $(eabiobjs) $(TEST_DIR)/.*.d lib/arm/.*.d \ > - lib/$(TEST_DIR)/iomaps.gen.c lib/$(TEST_DIR)/mach-virt.* > + lib/$(TEST_DIR)/iomaps.gen.c lib/$(TEST_DIR)/mach-virt.* \ > + scripts/arm/.*.d scripts/arm/*.o scripts/arm/*.flat scripts/arm/*.elf > diff --git a/lib/arm/asm-offsets.h b/lib/arm/asm-offsets.h > new file mode 100644 > index 0000000000000..b43be20ef8377 > --- /dev/null > +++ b/lib/arm/asm-offsets.h > @@ -0,0 +1,27 @@ > +#ifndef _ARM_ASM_OFFSETS_H_ > +#define _ARM_ASM_OFFSETS_H_ > +/* > + * Generated file. Regenerate with 'make asm-offsets' > + */ > + > +#define S_R0 0x0 > +#define S_R1 0x4 > +#define S_R2 0x8 > +#define S_R3 0xc > +#define S_R4 0x10 > +#define S_R5 0x14 > +#define S_R6 0x18 > +#define S_R7 0x1c > +#define S_R8 0x20 > +#define S_R9 0x24 > +#define S_R10 0x28 > +#define S_FP 0x2c > +#define S_IP 0x30 > +#define S_SP 0x34 > +#define S_LR 0x38 > +#define S_PC 0x3c > +#define S_PSR 0x40 > +#define S_OLD_R0 0x44 > +#define S_FRAME_SIZE 0x48 > + > +#endif /* _ARM_ASM_OFFSETS_H_ */ > diff --git a/lib/arm/cp15.h b/lib/arm/cp15.h > new file mode 100644 > index 0000000000000..6a8a29aadb008 > --- /dev/null > +++ b/lib/arm/cp15.h > @@ -0,0 +1,36 @@ > +#ifndef _ARM_CP15_H_ > +#define _ARM_CP15_H_ > +/* > + * From Linux kernel arch/arm/include/asm/cp15.h > + * > + * CR1 bits (CP#15 CR1) > + */ > +#define CR_M (1 << 0) /* MMU enable */ > +#define CR_A (1 << 1) /* Alignment abort enable */ > +#define CR_C (1 << 2) /* Dcache enable */ > +#define CR_W (1 << 3) /* Write buffer enable */ > +#define CR_P (1 << 4) /* 32-bit exception handler */ > +#define CR_D (1 << 5) /* 32-bit data address range */ > +#define CR_L (1 << 6) /* Implementation defined */ > +#define CR_B (1 << 7) /* Big endian */ > +#define CR_S (1 << 8) /* System MMU protection */ > +#define CR_R (1 << 9) /* ROM MMU protection */ > +#define CR_F (1 << 10) /* Implementation defined */ > +#define CR_Z (1 << 11) /* Implementation defined */ > +#define CR_I (1 << 12) /* Icache enable */ > +#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */ > +#define CR_RR (1 << 14) /* Round Robin cache replacement */ > +#define CR_L4 (1 << 15) /* LDR pc can set T bit */ > +#define CR_DT (1 << 16) > +#define CR_HA (1 << 17) /* Hardware management of Access Flag */ > +#define CR_IT (1 << 18) > +#define CR_ST (1 << 19) > +#define CR_FI (1 << 21) /* Fast interrupt (lower latency mode) */ > +#define CR_U (1 << 22) /* Unaligned access operation */ > +#define CR_XP (1 << 23) /* Extended page tables */ > +#define CR_VE (1 << 24) /* Vectored interrupts */ > +#define CR_EE (1 << 25) /* Exception (Big) Endian */ > +#define CR_TRE (1 << 28) /* TEX remap enable */ > +#define CR_AFE (1 << 29) /* Access flag enable */ > +#define CR_TE (1 << 30) /* Thumb exception enable */ > +#endif > diff --git a/lib/arm/ptrace.h b/lib/arm/ptrace.h > new file mode 100644 > index 0000000000000..3c8781508a72e > --- /dev/null > +++ b/lib/arm/ptrace.h > @@ -0,0 +1,100 @@ > +#ifndef _ARM_PTRACE_H_ > +#define _ARM_PTRACE_H_ > +/* > + * Adapted from Linux kernel headers > + * arch/arm/include/asm/ptrace.h > + * arch/arm/include/uapi/asm/ptrace.h > + */ > + > +/* > + * PSR bits > + */ > +#define USR_MODE 0x00000010 > +#define SVC_MODE 0x00000013 > +#define FIQ_MODE 0x00000011 > +#define IRQ_MODE 0x00000012 > +#define ABT_MODE 0x00000017 > +#define HYP_MODE 0x0000001a > +#define UND_MODE 0x0000001b > +#define SYSTEM_MODE 0x0000001f > +#define MODE32_BIT 0x00000010 > +#define MODE_MASK 0x0000001f > + > +#define PSR_T_BIT 0x00000020 /* >= V4T, but not V7M */ > +#define PSR_F_BIT 0x00000040 /* >= V4, but not V7M */ > +#define PSR_I_BIT 0x00000080 /* >= V4, but not V7M */ > +#define PSR_A_BIT 0x00000100 /* >= V6, but not V7M */ > +#define PSR_E_BIT 0x00000200 /* >= V6, but not V7M */ > +#define PSR_J_BIT 0x01000000 /* >= V5J, but not V7M */ > +#define PSR_Q_BIT 0x08000000 /* >= V5E, including V7M */ > +#define PSR_V_BIT 0x10000000 > +#define PSR_C_BIT 0x20000000 > +#define PSR_Z_BIT 0x40000000 > +#define PSR_N_BIT 0x80000000 > + > +/* > + * Groups of PSR bits > + */ > +#define PSR_f 0xff000000 /* Flags */ > +#define PSR_s 0x00ff0000 /* Status */ > +#define PSR_x 0x0000ff00 /* Extension */ > +#define PSR_c 0x000000ff /* Control */ > + > +/* > + * ARMv7 groups of PSR bits > + */ > +#define APSR_MASK 0xf80f0000 /* N, Z, C, V, Q and GE flags */ > +#define PSR_ISET_MASK 0x01000010 /* ISA state (J, T) mask */ > +#define PSR_IT_MASK 0x0600fc00 /* If-Then execution state mask */ > +#define PSR_ENDIAN_MASK 0x00000200 /* Endianness state mask */ > + > +#ifndef __ASSEMBLY__ > +#include "libcflat.h" > + > +struct pt_regs { > + unsigned long uregs[18]; > +}; > + > +#define ARM_cpsr uregs[16] > +#define ARM_pc uregs[15] > +#define ARM_lr uregs[14] > +#define ARM_sp uregs[13] > +#define ARM_ip uregs[12] > +#define ARM_fp uregs[11] > +#define ARM_r10 uregs[10] > +#define ARM_r9 uregs[9] > +#define ARM_r8 uregs[8] > +#define ARM_r7 uregs[7] > +#define ARM_r6 uregs[6] > +#define ARM_r5 uregs[5] > +#define ARM_r4 uregs[4] > +#define ARM_r3 uregs[3] > +#define ARM_r2 uregs[2] > +#define ARM_r1 uregs[1] > +#define ARM_r0 uregs[0] > +#define ARM_ORIG_r0 uregs[17] > + > +#define user_mode(regs) \ > + (((regs)->ARM_cpsr & 0xf) == 0) > + > +#define processor_mode(regs) \ > + ((regs)->ARM_cpsr & MODE_MASK) > + > +#define interrupts_enabled(regs) \ > + (!((regs)->ARM_cpsr & PSR_I_BIT)) > + > +#define fast_interrupts_enabled(regs) \ > + (!((regs)->ARM_cpsr & PSR_F_BIT)) > + > +#define MAX_REG_OFFSET (offsetof(struct pt_regs, ARM_ORIG_r0)) > + > +static inline unsigned long regs_get_register(struct pt_regs *regs, > + unsigned int offset) > +{ > + if (offset > MAX_REG_OFFSET) > + return 0; > + return *(unsigned long *)((unsigned long)regs + offset); > +} > + > +#endif /* __ASSEMBLY__ */ > +#endif /* _ARM_PTRACE_H_ */ > diff --git a/scripts/arm/asm-offsets.c b/scripts/arm/asm-offsets.c > new file mode 100644 > index 0000000000000..03b22da907d58 > --- /dev/null > +++ b/scripts/arm/asm-offsets.c > @@ -0,0 +1,40 @@ > +/* > + * Adapted from arch/arm/kernel/asm-offsets.c > + */ > +#include "libcflat.h" > +#include "arm/ptrace.h" > + > +#define P(sym, val) \ > + printf("#define " #sym "\t0x%x\n", val) > + > +int main(void) > +{ > + printf("#ifndef _ARM_ASM_OFFSETS_H_\n"); > + printf("#define _ARM_ASM_OFFSETS_H_\n"); > + printf("/*\n"); > + printf(" * Generated file. Regenerate with 'make asm-offsets'\n"); > + printf(" */\n"); > + printf("\n"); > + P(S_R0, offsetof(struct pt_regs, ARM_r0)); > + P(S_R1, offsetof(struct pt_regs, ARM_r1)); > + P(S_R2, offsetof(struct pt_regs, ARM_r2)); > + P(S_R3, offsetof(struct pt_regs, ARM_r3)); > + P(S_R4, offsetof(struct pt_regs, ARM_r4)); > + P(S_R5, offsetof(struct pt_regs, ARM_r5)); > + P(S_R6, offsetof(struct pt_regs, ARM_r6)); > + P(S_R7, offsetof(struct pt_regs, ARM_r7)); > + P(S_R8, offsetof(struct pt_regs, ARM_r8)); > + P(S_R9, offsetof(struct pt_regs, ARM_r9)); > + P(S_R10, offsetof(struct pt_regs, ARM_r10)); > + P(S_FP, offsetof(struct pt_regs, ARM_fp)); > + P(S_IP, offsetof(struct pt_regs, ARM_ip)); > + P(S_SP, offsetof(struct pt_regs, ARM_sp)); > + P(S_LR, offsetof(struct pt_regs, ARM_lr)); > + P(S_PC, offsetof(struct pt_regs, ARM_pc)); > + P(S_PSR, offsetof(struct pt_regs, ARM_cpsr)); > + P(S_OLD_R0, offsetof(struct pt_regs, ARM_ORIG_r0)); > + P(S_FRAME_SIZE, sizeof(struct pt_regs)); > + printf("\n"); > + printf("#endif /* _ARM_ASM_OFFSETS_H_ */\n"); > + return 0; > +} > -- > 1.8.1.4 > -- Christoffer -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html