diff mbox

[2/3] arm: add useful headers from the linux kernel

Message ID 1386932286-10723-3-git-send-email-drjones@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Andrew Jones Dec. 13, 2013, 10:58 a.m. UTC
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.

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

Comments

Christoffer Dall Dec. 29, 2013, 6:31 a.m. UTC | #1
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
>
Andrew Jones Jan. 2, 2014, 5:24 p.m. UTC | #2
On Sat, Dec 28, 2013 at 10:31:58PM -0800, Christoffer Dall wrote:
> 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...

Hmm, it doesn't for me. For me you need to do 'make asm-offsets' to
regenerate it, which will likely only be necessary when we add more
structs. Possibly we'll be adding structs frequently at first, but
eventually we'll have what we need, and then the churn will be low.
Anyway, whatever, it just didn't seem necessary to me, and also nice
to be able to git-diff the asm-offsets.h file, rather than just the
generator.

> > 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?

yeah...

> 
> >  
> >  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?

Actually, I'm not, because we commit the asm-offsets.h file :-) So unless
you're changing it, you don't need the above target. I'm not sure what
part of Kbuild you're referring to. I certainly don't want to over-engineer
the build process of these unit tests though.

> 
> 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 :((

Ahh, maybe we should commit the dts that mach-virt generates too then.

drew
--
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
Christoffer Dall Jan. 2, 2014, 6:08 p.m. UTC | #3
On Thu, Jan 02, 2014 at 06:24:10PM +0100, Andrew Jones wrote:
> On Sat, Dec 28, 2013 at 10:31:58PM -0800, Christoffer Dall wrote:
> > 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...
> 
> Hmm, it doesn't for me. For me you need to do 'make asm-offsets' to
> regenerate it, which will likely only be necessary when we add more
> structs. Possibly we'll be adding structs frequently at first, but
> eventually we'll have what we need, and then the churn will be low.
> Anyway, whatever, it just didn't seem necessary to me, and also nice
> to be able to git-diff the asm-offsets.h file, rather than just the
> generator.

So, it actually doesn't work for me to do 'make asm-offsets' if I do 'rm
lib/arm/asm-offsets.h'.  It complains about the file missing from other
tools that it tries to build first before producing the header file.  If
I do a 'touch lib/arm/asm-offsets.h', I get warnings about the missing
defines from building cstart.o and also if I do a make clean the 'make
asm-offsets' doesn't work for me anymore, because it depends on the
iomaps being generated, which doesn't work on my machine, so I manually
have to copy the iomaps.gen.c (which I generated by hand for now) first,
but still I don't get anywhere.

All this to say that with this appraoch, the 'make asm-offsets' relies
on a lot of logic to be in place, and it doesn't seem particularly easy
to make the compilation portable...

> 
> > > 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?
> 
> yeah...
> 
> > 
> > >  
> > >  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?
> 
> Actually, I'm not, because we commit the asm-offsets.h file :-) So unless
> you're changing it, you don't need the above target. I'm not sure what
> part of Kbuild you're referring to. I certainly don't want to over-engineer
> the build process of these unit tests though.
> 
I don't think constructing a mechanism (which you can copy from the
kernel) that makes it possible to compile this tool without relying on a
another set of tools (that needs to be of a quite recent revision) is
over-engineering a build-process.  If you are going this approach, you
really need to check for the available tools as part of configure and
give nice user messages saying "you need a version of qemu newer than
1.7 compiled for your host architecture with target-arm support on your
build system) or something like that.

But again, since we can, I think this tool should really just build
without relying on that.

> > 
> > 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 :((
> 
> Ahh, maybe we should commit the dts that mach-virt generates too then.
> 

I would advise very strongly against that.  We want this tool to be
something that is broadly applied and used by KVM developers, and since
we really don't want another place where the whole
keep-the-kernel-and-device-tree-in-sync problem can be an issue.
Ideally QEMU just gives you a DTB and the test tool consumes this.

-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
diff mbox

Patch

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
 
 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
+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;
+}