[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kvm
Subject:    Re: [PATCH 2/3] arm: add useful headers from the linux kernel
From:       Christoffer Dall <christoffer.dall () linaro ! org>
Date:       2013-12-29 6:31:58
Message-ID: 20131229063158.GJ13601 () cbox
[Download RAW message or body]

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@redhat.com>
> ---
>  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@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic