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 generated/asm-offsets.h to this framework.
It also adapts cp15.h from the kernel, since we'll need bit defines
from there too.

Signed-off-by: Andrew Jones <drjo...@redhat.com>
Acked-by: Christoffer Dall <christoffer.d...@linaro.org>
---
v4: much improved asm-offsets.h generation based on Kbuild
---
 config/asm-offsets.mak    |  41 +++++++++++++++++++
 config/config-arm.mak     |   9 ++++-
 lib/arm/.gitignore        |   1 +
 lib/arm/asm-offsets.c     |  39 ++++++++++++++++++
 lib/arm/asm/asm-offsets.h |   1 +
 lib/arm/asm/cp15.h        |  37 +++++++++++++++++
 lib/arm/asm/ptrace.h      | 100 ++++++++++++++++++++++++++++++++++++++++++++++
 lib/generated/.gitignore  |   1 +
 8 files changed, 227 insertions(+), 2 deletions(-)
 create mode 100644 config/asm-offsets.mak
 create mode 100644 lib/arm/.gitignore
 create mode 100644 lib/arm/asm-offsets.c
 create mode 100644 lib/arm/asm/asm-offsets.h
 create mode 100644 lib/arm/asm/cp15.h
 create mode 100644 lib/arm/asm/ptrace.h
 create mode 100644 lib/generated/.gitignore

diff --git a/config/asm-offsets.mak b/config/asm-offsets.mak
new file mode 100644
index 0000000000000..b2578a6692f33
--- /dev/null
+++ b/config/asm-offsets.mak
@@ -0,0 +1,41 @@
+#
+# asm-offsets adapted from the kernel, see
+#   Kbuild
+#   scripts/Kbuild.include
+#   scripts/Makefile.build
+#
+#   Authors: Andrew Jones <drjo...@redhat.com>
+#
+
+define sed-y
+       "/^->/{s:->#\(.*\):/* \1 */:; \
+       s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \
+       s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
+       s:->::; p;}"
+endef
+
+define make_asm_offsets
+       (set -e; \
+        echo "#ifndef __ASM_OFFSETS_H__"; \
+        echo "#define __ASM_OFFSETS_H__"; \
+        echo "/*"; \
+        echo " * Generated file. DO NOT MODIFY."; \
+        echo " *"; \
+        echo " */"; \
+        echo ""; \
+        sed -ne $(sed-y) $<; \
+        echo ""; \
+        echo "#endif" ) > $@
+endef
+
+$(asm-offsets:.h=.s): $(asm-offsets:.h=.c)
+       $(CC) $(CFLAGS) -fverbose-asm -S -o $@ $<
+
+$(asm-offsets): $(asm-offsets:.h=.s)
+       $(call make_asm_offsets)
+       cp -f $(asm-offsets) lib/generated
+
+asm_offsets_clean:
+       $(RM) $(asm-offsets) $(asm-offsets:.h=.s) \
+             $(addprefix lib/generated/,$(notdir $(asm-offsets)))
+
diff --git a/config/config-arm.mak b/config/config-arm.mak
index d150807ec6fe4..ead191f4954f4 100644
--- a/config/config-arm.mak
+++ b/config/config-arm.mak
@@ -30,6 +30,9 @@ CFLAGS += -Wextra
 CFLAGS += -O2
 CFLAGS += -I lib -I lib/libfdt
 
+asm-offsets = lib/arm/asm-offsets.h
+include config/asm-offsets.mak
+
 cflatobjs += \
        lib/devicetree.o \
        lib/virtio.o \
@@ -57,7 +60,7 @@ FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) $(libeabi)
 $(libeabi): $(eabiobjs)
        $(AR) rcs $@ $^
 
-arch_clean: libfdt_clean
+arch_clean: libfdt_clean asm_offsets_clean
        $(RM) $(TEST_DIR)/*.{o,flat,elf} $(libeabi) $(eabiobjs) \
              $(TEST_DIR)/.*.d lib/arm/.*.d
 
@@ -67,7 +70,9 @@ tests_and_config = $(TEST_DIR)/*.flat 
$(TEST_DIR)/unittests.cfg
 
 cstart.o = $(TEST_DIR)/cstart.o
 
-test_cases: $(tests-common) $(tests)
+generated_files = $(asm-offsets)
+
+test_cases: $(generated_files) $(tests-common) $(tests)
 
 $(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
 
diff --git a/lib/arm/.gitignore b/lib/arm/.gitignore
new file mode 100644
index 0000000000000..84872bf197c67
--- /dev/null
+++ b/lib/arm/.gitignore
@@ -0,0 +1 @@
+asm-offsets.[hs]
diff --git a/lib/arm/asm-offsets.c b/lib/arm/asm-offsets.c
new file mode 100644
index 0000000000000..a9c349d2d427c
--- /dev/null
+++ b/lib/arm/asm-offsets.c
@@ -0,0 +1,39 @@
+/*
+ * Adapted from arch/arm/kernel/asm-offsets.c
+ *
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjo...@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "libcflat.h"
+#include "asm/ptrace.h"
+
+#define DEFINE(sym, val) \
+       asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+#define OFFSET(sym, str, mem)  DEFINE(sym, offsetof(struct str, mem))
+#define COMMENT(x)             asm volatile("\n->#" x)
+#define BLANK()                        asm volatile("\n->" : : )
+
+int main(void)
+{
+       OFFSET(S_R0, pt_regs, ARM_r0);
+       OFFSET(S_R1, pt_regs, ARM_r1);
+       OFFSET(S_R2, pt_regs, ARM_r2);
+       OFFSET(S_R3, pt_regs, ARM_r3);
+       OFFSET(S_R4, pt_regs, ARM_r4);
+       OFFSET(S_R5, pt_regs, ARM_r5);
+       OFFSET(S_R6, pt_regs, ARM_r6);
+       OFFSET(S_R7, pt_regs, ARM_r7);
+       OFFSET(S_R8, pt_regs, ARM_r8);
+       OFFSET(S_R9, pt_regs, ARM_r9);
+       OFFSET(S_R10, pt_regs, ARM_r10);
+       OFFSET(S_FP, pt_regs, ARM_fp);
+       OFFSET(S_IP, pt_regs, ARM_ip);
+       OFFSET(S_SP, pt_regs, ARM_sp);
+       OFFSET(S_LR, pt_regs, ARM_lr);
+       OFFSET(S_PC, pt_regs, ARM_pc);
+       OFFSET(S_PSR, pt_regs, ARM_cpsr);
+       OFFSET(S_OLD_R0, pt_regs, ARM_ORIG_r0);
+       DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
+       return 0;
+}
diff --git a/lib/arm/asm/asm-offsets.h b/lib/arm/asm/asm-offsets.h
new file mode 100644
index 0000000000000..c2ff2ba6ec417
--- /dev/null
+++ b/lib/arm/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include "generated/asm-offsets.h"
diff --git a/lib/arm/asm/cp15.h b/lib/arm/asm/cp15.h
new file mode 100644
index 0000000000000..7690a48f17f1f
--- /dev/null
+++ b/lib/arm/asm/cp15.h
@@ -0,0 +1,37 @@
+#ifndef _ASMARM_CP15_H_
+#define _ASMARM_CP15_H_
+/*
+ * From the 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 /* _ASMARM_CP15_H_ */
diff --git a/lib/arm/asm/ptrace.h b/lib/arm/asm/ptrace.h
new file mode 100644
index 0000000000000..3a4c7532258f6
--- /dev/null
+++ b/lib/arm/asm/ptrace.h
@@ -0,0 +1,100 @@
+#ifndef _ASMARM_PTRACE_H_
+#define _ASMARM_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 /* _ASMARM_PTRACE_H_ */
diff --git a/lib/generated/.gitignore b/lib/generated/.gitignore
new file mode 100644
index 0000000000000..72e8ffc0db8aa
--- /dev/null
+++ b/lib/generated/.gitignore
@@ -0,0 +1 @@
+*
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to