Skip to contentSkip to conversation

Hexagon: Add support for Qualcomm Hexagon architecture

PATCH Superseded Richard Kuo 7 participants 82 messages Aug 30, 2011 – Aug 31, 2011

Subsystems (9)

v2 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v2 cover Hexagon: Add support for Qualcomm Hexagon architecture

This is the second version of the patchset to the Linux kernel to support the Qualcomm Hexagon architecture. These patches have been organized like the last time, in a somewhat logically grouped fashion.

A summary of changes from the last patchset:

* use Kbuild method for strictly asm-generic headers
* clean up dma sync and implement clean/invalidate
* bitops fl*/ff* cleanup
* added inline assembly version of atomic_add_unless
* removed deprecated syscalls/defines
* call __vmyield for cpu_relax and fix cpu_idle
* clean up thread_info; use arch allocator to allow kernel stack sizes smaller than page size
* implement read_timer_counter
* changed checksum to pull non-asm functions from generic code
* delete module functions which already have generic equivalents
* cleaned up IO routines
* reduced comet_defconfig
* remove ugly platform code

These patches are available on Code Aurora as well as git:

https://www.codeaurora.org/patches/quic/hlk/hexagon-linux-20110830.tar.gz

git://git.kernel.org/pub/scm/linux/kernel/git/rkuo/linux-hexagon.git hexagon

Thanks to everyone for their comments/feedback! If I missed anything or there's something else that needs cleanup, please let me know.

-Richard Kuo

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#1 lore raw

PATCH v2 1/35 Hexagon: Add generic headers

Reworked to use the Kbuild generic headers mechanism.

---
 arch/hexagon/include/asm/Kbuild        |   59 ++++++++++++++++++++++++
 arch/hexagon/include/asm/bitsperlong.h |   26 ++++++++++
 arch/hexagon/include/asm/mutex.h       |    8 +++
 arch/hexagon/include/asm/setup.h       |   29 ++++++++++++
 arch/hexagon/include/asm/user.h        |   79 +++++++++++++++++++++++++++++++++
 5 files changed, 201 insertions(+)
arch/hexagon/include/asm/Kbuild new file +59 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/Kbuild
===================================================================
@@ -0,0 +1,59 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += registers.h
+header-y += ucontext.h
+
+generic-y += auxvec.h
+generic-y += bug.h
+generic-y += bugs.h
+generic-y += cpumask.h
+generic-y += cputime.h
+generic-y += current.h
+generic-y += device.h
+generic-y += div64.h
+generic-y += emergency-restart.h
+generic-y += errno.h
+generic-y += fb.h
+generic-y += fcntl.h
+generic-y += ftrace.h
+generic-y += hardirq.h
+generic-y += hw_irq.h
+generic-y += ioctl.h
+generic-y += ioctls.h
+generic-y += iomap.h
+generic-y += ipcbuf.h
+generic-y += ipc.h
+generic-y += irq_regs.h
+generic-y += kdebug.h
+generic-y += kmap_types.h
+generic-y += local64.h
+generic-y += local.h
+generic-y += local.h
+generic-y += mman.h
+generic-y += msgbuf.h
+generic-y += pci.h
+generic-y += percpu.h
+generic-y += poll.h
+generic-y += posix_types.h
+generic-y += resource.h
+generic-y += scatterlist.h
+generic-y += sections.h
+generic-y += segment.h
+generic-y += sembuf.h
+generic-y += shmbuf.h
+generic-y += shmparam.h
+generic-y += siginfo.h
+generic-y += socket.h
+generic-y += sockios.h
+generic-y += statfs.h
+generic-y += stat.h
+generic-y += termbits.h
+generic-y += termios.h
+generic-y += topology.h
+generic-y += types.h
+generic-y += ucontext.h
+generic-y += unaligned.h
+generic-y += xor.h
+
+
+
arch/hexagon/include/asm/bitsperlong.h new file +26 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/bitsperlong.h
===================================================================
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __ASM_HEXAGON_BITSPERLONG_H
+#define __ASM_HEXAGON_BITSPERLONG_H
+
+#define __BITS_PER_LONG 32
+
+#include <asm-generic/bitsperlong.h>
+
+#endif
arch/hexagon/include/asm/mutex.h new file +8 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/mutex.h
===================================================================
@@ -0,0 +1,8 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+#include <asm-generic/mutex-xchg.h>
arch/hexagon/include/asm/setup.h new file +29 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/setup.h
===================================================================
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_SETUP_H
+#define _ASM_SETUP_H
+
+#include <linux/init.h>
+#include <asm-generic/setup.h>
+
+extern char external_cmdline_buffer;
+
+void __init setup_arch_memory(void);
+
+#endif
arch/hexagon/include/asm/user.h new file +79 -0

79 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#3 lore raw

Re: [patch v2 01/35] Hexagon: Add generic headers

Quoted 6 lines · Arnd Bergmann
Quoted 3 lines · Richard Kuo

Reworked to use the Kbuild generic headers mechanism.

Any suggestions on what path this code should flow to get into the kernel?

Thanks,
David

Signature · 2 lines
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
#4 lore raw

Re: [patch v2 01/35] Hexagon: Add generic headers

Quoted 10 lines · On Wednesday 31 August 2011 12:51:11 David Brown wrote:
Quoted 6 lines · Arnd Bergmann
Quoted 3 lines · Richard Kuo

Reworked to use the Kbuild generic headers mechanism.

Any suggestions on what path this code should flow to get into the kernel?

It should get into linux-next now and then get submitted directly to Linus at the start of the merge window.

I'm happy to take anything that concerns hexagon and arm likewise into the arm-soc tree.

While I am the de-facto gatekeeper for new architectures, I have not seen a reason to start a consolidated minor-architectures tree to collect these.

Arnd

#5 lore raw

PATCH v2 2/35 Hexagon: Core arch-specific header files

In reply to Richard Kuo
---
 arch/hexagon/include/asm/byteorder.h  |   28 ++++
 arch/hexagon/include/asm/elf.h        |  222 ++++++++++++++++++++++++++++++++++
 arch/hexagon/include/asm/fpu.h        |    4 
 arch/hexagon/include/asm/futex.h      |  137 ++++++++++++++++++++
 arch/hexagon/include/asm/linkage.h    |   25 +++
 arch/hexagon/include/asm/module.h     |   26 +++
 arch/hexagon/include/asm/param.h      |   26 +++
 arch/hexagon/include/asm/perf_event.h |   24 +++
 arch/hexagon/include/asm/string.h     |   32 ++++
 arch/hexagon/include/asm/suspend.h    |   27 ++++
 arch/hexagon/include/asm/swab.h       |   24 +++
 arch/hexagon/include/asm/timex.h      |   37 +++++
 12 files changed, 612 insertions(+)
arch/hexagon/include/asm/byteorder.h new file +28 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/byteorder.h
===================================================================
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_BYTEORDER_H
+#define _ASM_BYTEORDER_H
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#endif
+
+#include <linux/byteorder/little_endian.h>
+
+#endif /* _ASM_BYTEORDER_H */
arch/hexagon/include/asm/elf.h new file +222 -0

222 lines not on this page · raw message

arch/hexagon/include/asm/fpu.h new file +4 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/fpu.h
===================================================================
@@ -0,0 +1,4 @@
+/*
+ * If the FPU is used inside the kernel,
+ * kernel_fpu_end() will be defined here.
+ */
arch/hexagon/include/asm/futex.h new file +137 -0

137 lines not on this page · raw message

arch/hexagon/include/asm/linkage.h new file +25 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/linkage.h
===================================================================
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#define __ALIGN		.align 4
+#define __ALIGN_STR	".align 4"
+
+#endif
arch/hexagon/include/asm/module.h new file +26 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/module.h
===================================================================
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_MODULE_H
+#define _ASM_MODULE_H
+
+#include <asm-generic/module.h>
+
+#define MODULE_ARCH_VERMAGIC __stringify(PROCESSOR_MODEL_NAME) " "
+
+#endif
arch/hexagon/include/asm/param.h new file +26 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/param.h
===================================================================
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_PARAM_H
+#define _ASM_PARAM_H
+
+#define EXEC_PAGESIZE	16384
+
+#include <asm-generic/param.h>
+
+#endif
arch/hexagon/include/asm/string.h new file +32 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/string.h
===================================================================
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_STRING_H_
+#define _ASM_STRING_H_
+
+#ifdef __KERNEL__
+#define __HAVE_ARCH_MEMCPY
+extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
+
+/*  ToDo:  use dczeroa, accelerate the compiler-constant zero case  */
+#define __HAVE_ARCH_MEMSET
+extern void *memset(void *__to, int c, size_t __n);
+#endif
+
+
+#endif /* _ASM_STRING_H_ */
arch/hexagon/include/asm/suspend.h new file +27 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/suspend.h
===================================================================
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_SUSPEND_H
+#define _ASM_SUSPEND_H
+
+static inline int arch_prepare_suspend(void)
+{
+	return 0;
+}
+
+#endif
arch/hexagon/include/asm/swab.h new file +24 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/swab.h
===================================================================
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_SWAB_H
+#define _ASM_SWAB_H
+
+#define __SWAB_64_THRU_32__
+
+#endif
arch/hexagon/include/asm/timex.h new file +37 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/timex.h
===================================================================
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_TIMEX_H
+#define _ASM_TIMEX_H
+
+#include <asm-generic/timex.h>
+#include <asm/timer-regs.h>
+
+/* Using TCX0 as our clock.  CLOCK_TICK_RATE scheduled to be removed. */
+#define CLOCK_TICK_RATE              TCX0_CLK_RATE
+
+#define ARCH_HAS_READ_CURRENT_TIMER
+
+static inline int read_current_timer(unsigned long *timer_val)
+{
+	*timer_val = (unsigned long) __vmgettime();
+	return 0;
+}
+
+#endif
+
arch/hexagon/include/asm/perf_event.h new file +24 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/perf_event.h
===================================================================
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_PERF_EVENT_H
+#define _ASM_PERF_EVENT_H
+
+#define PERF_EVENT_INDEX_OFFSET	0
+
+#endif /* _ASM_PERF_EVENT_H */

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#7 lore raw

PATCH v2 3/35 Hexagon: Add bitops support

In reply to Richard Kuo

Merged sub-files into bitops.h; fixed return types and volatiles.

---
 arch/hexagon/include/asm/bitops.h |  301 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 301 insertions(+)
arch/hexagon/include/asm/bitops.h new file +301 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/bitops.h
===================================================================
@@ -0,0 +1,301 @@
+/*
+ * Bit operations for the Hexagon architecture
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_BITOPS_H
+#define _ASM_BITOPS_H
+
+#include <linux/compiler.h>
+#include <asm/byteorder.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
+
+#ifdef __KERNEL__
+
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+
+/*
+ * The offset calculations for these are based on BITS_PER_LONG == 32
+ * (i.e. I get to shift by #5-2 (32 bits per long, 4 bytes per access),
+ * mask by 0x0000001F)
+ *
+ * Typically, R10 is clobbered for address, R11 bit nr, and R12 is temp
+ */
+
+/**
+ * test_and_clear_bit - clear a bit and return its old value
+ * @nr:  bit number to clear
+ * @addr:  pointer to memory
+ */
+static inline int test_and_clear_bit(int nr, volatile void *addr)
+{
+	int oldval;
+
+	__asm__ __volatile__ (
+	"	{R10 = %1; R11 = asr(%2,#5); }\n"
+	"	{R10 += asl(R11,#2); R11 = and(%2,#0x1f)}\n"
+	"1:	R12 = memw_locked(R10);\n"
+	"	{ P0 = tstbit(R12,R11); R12 = clrbit(R12,R11); }\n"
+	"	memw_locked(R10,P1) = R12;\n"
+	"	{if !P1 jump 1b; %0 = mux(P0,#1,#0);}\n"
+	: "=&r" (oldval)
+	: "r" (addr), "r" (nr)
+	: "r10", "r11", "r12", "p0", "p1", "memory"
+	);
+
+	return oldval;
+}
+
+/**
+ * test_and_set_bit - set a bit and return its old value
+ * @nr:  bit number to set
+ * @addr:  pointer to memory
+ */
+static inline int test_and_set_bit(int nr, volatile void *addr)
+{
+	int oldval;
+
+	__asm__ __volatile__ (
+	"	{R10 = %1; R11 = asr(%2,#5); }\n"
+	"	{R10 += asl(R11,#2); R11 = and(%2,#0x1f)}\n"
+	"1:	R12 = memw_locked(R10);\n"
+	"	{ P0 = tstbit(R12,R11); R12 = setbit(R12,R11); }\n"
+	"	memw_locked(R10,P1) = R12;\n"
+	"	{if !P1 jump 1b; %0 = mux(P0,#1,#0);}\n"
+	: "=&r" (oldval)
+	: "r" (addr), "r" (nr)
+	: "r10", "r11", "r12", "p0", "p1", "memory"
+	);
+
+
+	return oldval;
+
+}
+
+/**
+ * test_and_change_bit - toggle a bit and return its old value
+ * @nr:  bit number to set
+ * @addr:  pointer to memory
+ */
+static inline int test_and_change_bit(int nr, volatile void *addr)
+{
+	int oldval;
+
+	__asm__ __volatile__ (
+	"	{R10 = %1; R11 = asr(%2,#5); }\n"
+	"	{R10 += asl(R11,#2); R11 = and(%2,#0x1f)}\n"
+	"1:	R12 = memw_locked(R10);\n"
+	"	{ P0 = tstbit(R12,R11); R12 = togglebit(R12,R11); }\n"
+	"	memw_locked(R10,P1) = R12;\n"
+	"	{if !P1 jump 1b; %0 = mux(P0,#1,#0);}\n"
+	: "=&r" (oldval)
+	: "r" (addr), "r" (nr)
+	: "r10", "r11", "r12", "p0", "p1", "memory"
+	);
+
+	return oldval;
+
+}
+
+/*
+ * Atomic, but doesn't care about the return value.
+ * Rewrite later to save a cycle or two.
+ */
+
+static inline void clear_bit(int nr, volatile void *addr)
+{
+	test_and_clear_bit(nr, addr);
+}
+
+static inline void set_bit(int nr, volatile void *addr)
+{
+	test_and_set_bit(nr, addr);
+}
+
+static inline void change_bit(int nr, volatile void *addr)
+{
+	test_and_change_bit(nr, addr);
+}
+
+
+/*
+ * These are allowed to be non-atomic.  In fact the generic flavors are
+ * in non-atomic.h.  Would it be better to use intrinsics for this?
+ *
+ * OK, writes in our architecture do not invalidate LL/SC, so this has to
+ * be atomic, particularly for things like slab_lock and slab_unlock.
+ *
+ */
+static inline void __clear_bit(int nr, volatile unsigned long *addr)
+{
+	test_and_clear_bit(nr, addr);
+}
+
+static inline void __set_bit(int nr, volatile unsigned long *addr)
+{
+	test_and_set_bit(nr, addr);
+}
+
+static inline void __change_bit(int nr, volatile unsigned long *addr)
+{
+	test_and_change_bit(nr, addr);
+}
+
+/*  Apparently, at least some of these are allowed to be non-atomic  */
+static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
+{
+	return test_and_clear_bit(nr, addr);
+}
+
+static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
+{
+	return test_and_set_bit(nr, addr);
+}
+
+static inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
+{
+	return test_and_change_bit(nr, addr);
+}
+
+static inline int __test_bit(int nr, const volatile unsigned long *addr)
+{
+	int retval;
+
+	asm volatile(
+	"{P0 = tstbit(%1,%2); if (P0.new) %0 = #1; if (!P0.new) %0 = #0;}\n"
+	: "=&r" (retval)
+	: "r" (addr[BIT_WORD(nr)]), "r" (nr % BITS_PER_LONG)
+	: "p0"
+	);
+
+	return retval;
+}
+
+#define test_bit(nr, addr) __test_bit(nr, addr)
+
+/*
+ * ffz - find first zero in word.
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+static inline long ffz(int x)
+{
+	int r;
+
+	asm("%0 = ct1(%1);\n"
+		: "=&r" (r)
+		: "r" (x));
+	return r;
+}
+
+/*
+ * fls - find last (most-significant) bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as ffs.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+static inline long fls(int x)
+{
+	int r;
+
+	asm("{ %0 = cl0(%1);}\n"
+		"%0 = sub(#32,%0);\n"
+		: "=&r" (r)
+		: "r" (x)
+		: "p0");
+
+	return r;
+}
+
+/*
+ * ffs - find first bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+static inline long ffs(int x)
+{
+	int r;
+
+	asm("{ P0 = cmp.eq(%1,#0); %0 = ct0(%1);}\n"
+		"{ if P0 %0 = #0; if !P0 %0 = add(%0,#1);}\n"
+		: "=&r" (r)
+		: "r" (x)
+		: "p0");
+
+	return r;
+}
+
+/*
+ * __ffs - find first bit in word.
+ * @word: The word to search
+ *
+ * Undefined if no bit exists, so code should check against 0 first.
+ *
+ * bits_per_long assumed to be 32
+ * numbering starts at 0 I think (instead of 1 like ffs)
+ */
+static inline unsigned long __ffs(unsigned long word)
+{
+	int num;
+
+	asm("%0 = ct0(%1);\n"
+		: "=&r" (num)
+		: "r" (word));
+
+	return num;
+}
+
+/*
+ * __fls - find last (most-significant) set bit in a long word
+ * @word: the word to search
+ *
+ * Undefined if no set bit exists, so code should check against 0 first.
+ * bits_per_long assumed to be 32
+ */
+static inline unsigned long __fls(unsigned long word)
+{
+	int num;
+
+	asm("%0 = cl0(%1);\n"
+		"%0 = sub(#31,%0);\n"
+		: "=&r" (num)
+		: "r" (word));
+
+	return num;
+}
+
+#include <asm-generic/bitops/lock.h>
+#include <asm-generic/bitops/find.h>
+
+#include <asm-generic/bitops/fls64.h>
+#include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/hweight.h>
+
+#include <asm-generic/bitops/le.h>
+#include <asm-generic/bitops/ext2-atomic.h>
+
+#endif /* __KERNEL__ */
+#endif

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#9 lore raw

PATCH v2 4/35 Hexagon: Add atomic ops support

In reply to Richard Kuo

Our architecture uses load locked/store conditional type semantics for atomic ops.

Added inline assembly version of atomic_add_unless.

---
 arch/hexagon/include/asm/atomic.h |  164 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 164 insertions(+)
arch/hexagon/include/asm/atomic.h new file +164 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/atomic.h
===================================================================
@@ -0,0 +1,164 @@
+/*
+ * Atomic operations for the Hexagon architecture
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_ATOMIC_H
+#define _ASM_ATOMIC_H
+
+#include <linux/types.h>
+
+#define ATOMIC_INIT(i)		{ (i) }
+#define atomic_set(v, i)	((v)->counter = (i))
+
+/**
+ * atomic_read - reads a word, atomically
+ * @v: pointer to atomic value
+ *
+ * Assumes all word reads on our architecture are atomic.
+ */
+#define atomic_read(v)		((v)->counter)
+
+/**
+ * atomic_xchg - atomic
+ * @v: pointer to memory to change
+ * @new: new value (technically passed in a register -- see xchg)
+ */
+#define atomic_xchg(v, new)	(xchg(&((v)->counter), (new)))
+
+
+/**
+ * atomic_cmpxchg - atomic compare-and-exchange values
+ * @v: pointer to value to change
+ * @old:  desired old value to match
+ * @new:  new value to put in
+ *
+ * Parameters are then pointer, value-in-register, value-in-register,
+ * and the output is the old value.
+ *
+ * Apparently this is complicated for archs that don't support
+ * the memw_locked like we do (or it's broken or whatever).
+ *
+ * Kind of the lynchpin of the rest of the generically defined routines.
+ * Remember V2 had that bug with dotnew predicate set by memw_locked.
+ *
+ * "old" is "expected" old val, __oldval is actual old value
+ */
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+	int __oldval;
+
+	asm volatile(
+		"1:	%0 = memw_locked(%1);\n"
+		"	{ P0 = cmp.eq(%0,%2);\n"
+		"	  if (!P0.new) jump:nt 2f; }\n"
+		"	memw_locked(%1,P0) = %3;\n"
+		"	if (!P0) jump 1b;\n"
+		"2:\n"
+		: "=&r" (__oldval)
+		: "r" (&v->counter), "r" (old), "r" (new)
+		: "memory", "p0"
+	);
+
+	return __oldval;
+}
+
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+	int output;
+
+	__asm__ __volatile__ (
+		"1:	%0 = memw_locked(%1);\n"
+		"	%0 = add(%0,%2);\n"
+		"	memw_locked(%1,P3)=%0;\n"
+		"	if !P3 jump 1b;\n"
+		: "=&r" (output)
+		: "r" (&v->counter), "r" (i)
+		: "memory", "p3"
+	);
+	return output;
+
+}
+
+#define atomic_add(i, v) atomic_add_return(i, (v))
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+	int output;
+	__asm__ __volatile__ (
+		"1:	%0 = memw_locked(%1);\n"
+		"	%0 = sub(%0,%2);\n"
+		"	memw_locked(%1,P3)=%0\n"
+		"	if !P3 jump 1b;\n"
+		: "=&r" (output)
+		: "r" (&v->counter), "r" (i)
+		: "memory", "p3"
+	);
+	return output;
+}
+
+#define atomic_sub(i, v) atomic_sub_return(i, (v))
+
+/**
+ * atomic_add_unless - add unless the number is a given value
+ * @v: pointer to value
+ * @a: amount to add
+ * @u: unless value is equal to u
+ *
+ * Returns 1 if the add happened, 0 if it didn't.
+ */
+static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+{
+	int output;
+	asm volatile(
+		"1:	R15 = memw_locked(%1);"
+		"	{"
+		"		p3 = cmp.eq(R15, %3);"
+		"		if (p3.new) jump:nt 2f;"
+		"		R15 = add(R15,%2);"
+		"		%0 = #0;"
+		"	}"
+		"	memw_locked(%1,p3) = r15;"
+		"	{"
+		"		if !p3 jump 1b;"
+		"		%0 = #1;"
+		"	}"
+		"2:"
+		: "=&r" (output)
+		: "r" (v), "r" (a), "r" (u)
+		: "memory", "p3", "r15"
+	);
+	return output;
+}
+
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
+#define atomic_inc(v) atomic_add(1, (v))
+#define atomic_dec(v) atomic_sub(1, (v))
+
+#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+#define atomic_sub_and_test(i, v) (atomic_sub_return(i, (v)) == 0)
+#define atomic_add_negative(i, v) (atomic_add_return(i, (v)) < 0)
+
+
+#define atomic_inc_return(v) (atomic_add_return(1, v))
+#define atomic_dec_return(v) (atomic_sub_return(1, v))
+
+#endif

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#11 lore raw

PATCH v2 5/35 Hexagon: Add syscalls

In reply to Richard Kuo

Deprecated syscalls and defines were removed.

---
 arch/hexagon/include/asm/syscall.h |   40 +++++++++
 arch/hexagon/include/asm/unistd.h  |   34 ++++++++
 arch/hexagon/kernel/syscall.c      |  149 +++++++++++++++++++++++++++++++++++++
 arch/hexagon/kernel/syscalltab.c   |   32 +++++++
 4 files changed, 255 insertions(+)
arch/hexagon/include/asm/syscall.h new file +40 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/syscall.h
===================================================================
@@ -0,0 +1,40 @@
+/*
+ * Syscall support for the Hexagon architecture
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_HEXAGON_SYSCALL_H
+#define _ASM_HEXAGON_SYSCALL_H
+
+typedef long (*syscall_fn)(unsigned long, unsigned long,
+	unsigned long, unsigned long,
+	unsigned long, unsigned long);
+
+asmlinkage int sys_execve(char __user *ufilename, char __user * __user *argv,
+			  char __user * __user *envp);
+asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
+			 unsigned long parent_tidp, unsigned long child_tidp);
+
+#define sys_execve	sys_execve
+#define sys_clone	sys_clone
+
+#include <asm-generic/syscalls.h>
+
+extern void *sys_call_table[];
+
+#endif
arch/hexagon/include/asm/unistd.h new file +34 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/unistd.h
===================================================================
@@ -0,0 +1,34 @@
+/*
+ * Syscall support for Hexagon
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#if !defined(_ASM_HEXAGON_UNISTD_H) || defined(__SYSCALL)
+#define _ASM_HEXAGON_UNISTD_H
+
+/*
+ *  The kernel pulls this unistd.h in three different ways:
+ *  1.  the "normal" way which gets all the __NR defines
+ *  2.  with __SYSCALL defined to produce function declarations
+ *  3.  with __SYSCALL defined to produce syscall table initialization
+ *  See also:  syscalltab.c
+ */
+
+#include <asm-generic/unistd.h>
+
+#endif
arch/hexagon/kernel/syscall.c new file +149 -0

149 lines not on this page · raw message

arch/hexagon/kernel/syscalltab.c new file +32 -0
Index: linux-hexagon-kernel/arch/hexagon/kernel/syscalltab.c
===================================================================
@@ -0,0 +1,32 @@
+/*
+ * System call table for Hexagon
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/syscalls.h>
+#include <linux/signal.h>
+#include <linux/unistd.h>
+
+#include <asm/syscall.h>
+
+#undef __SYSCALL
+#define __SYSCALL(nr, call) [nr] = (call),
+
+void *sys_call_table[__NR_syscalls] = {
+#include <asm/unistd.h>
+};

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#12 lore raw

Re: [patch v2 05/35] Hexagon: Add syscalls

Quoted 6 lines · Richard Kuo
arch/hexagon/kernel/syscall.c new file +6 -0
+/*
+ * Many archictures support both sys_mmap and sys_mmap2, which use
+ * a common do_mmap2 function to do the work.  So long as we support
+ * only mmap2, we do it all in-line here.
+ */
+asmlinkage int sys_mmap2(unsigned long addr, size_t len, unsigned long prot,

arch/hexagon/kernel/syscall.c line 99

Quoted 10 lines
arch/hexagon/kernel/syscall.c new file +9 -0
+                        unsigned long flags, unsigned long fd,
+                        unsigned long pgoff)
+{
 
+}
+
+/*  apparently this should only map on page boundaries  */
+asmlinkage int sys_mmap(unsigned long addr, size_t len,
+                       unsigned long prot, unsigned long flags,
+                       unsigned long fd, off_t off)

The first comment doesn't make sense when you have the seconf function as well. I thought I had commented that you should not provide either one anyway and just use sys_mmap_pgoff() directly, like openrisc does.

It would probably be useful to change asm-generic/unistd.h to do that by default, and change the architectures that still use mmap2 with asm-generic/unistd.h to do a manual override.

Arnd

#13 lore raw

PATCH v2 6/35 Hexagon: Add processor and system headers

In reply to Richard Kuo

Adds Hexagon information for processor/system type stuff like context switching, register access, and irqflags.

Changed cpu_relax() to call __vmyield().

---
 arch/hexagon/include/asm/asm-offsets.h |    1 
 arch/hexagon/include/asm/irqflags.h    |   62 ++++++++
 arch/hexagon/include/asm/processor.h   |  123 +++++++++++++++++
 arch/hexagon/include/asm/registers.h   |  236 +++++++++++++++++++++++++++++++++
 arch/hexagon/include/asm/system.h      |  126 +++++++++++++++++
 5 files changed, 548 insertions(+)
arch/hexagon/include/asm/irqflags.h new file +62 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/irqflags.h
===================================================================
@@ -0,0 +1,62 @@
+/*
+ * IRQ support for the Hexagon architecture
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_IRQFLAGS_H
+#define _ASM_IRQFLAGS_H
+
+#include <asm/hexagon_vm.h>
+#include <linux/types.h>
+
+static inline unsigned long arch_local_save_flags(void)
+{
+	return __vmgetie();
+}
+
+static inline unsigned long arch_local_irq_save(void)
+{
+	return __vmsetie(VM_INT_DISABLE);
+}
+
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
+{
+	return !flags;
+}
+
+static inline bool arch_irqs_disabled(void)
+{
+	return !__vmgetie();
+}
+
+static inline void arch_local_irq_enable(void)
+{
+	__vmsetie(VM_INT_ENABLE);
+}
+
+static inline void arch_local_irq_disable(void)
+{
+	__vmsetie(VM_INT_DISABLE);
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+	__vmsetie(flags);
+}
+
+#endif
arch/hexagon/include/asm/processor.h new file +123 -0

123 lines not on this page · raw message

arch/hexagon/include/asm/registers.h new file +236 -0

236 lines not on this page · raw message

arch/hexagon/include/asm/system.h new file +126 -0

126 lines not on this page · raw message

arch/hexagon/include/asm/asm-offsets.h new file +1 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/asm-offsets.h
===================================================================
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#15 lore raw

PATCH v2 7/35 Hexagon: Add threadinfo

In reply to Richard Kuo

Removed some cruft and changed to allow kernel stack to be smaller than a page size.

I left the thread_info alignment alone for the time being; may revisit that in the future.

---
 arch/hexagon/include/asm/thread_info.h |  154 +++++++++++++++++++++++++++++++++
 1 file changed, 154 insertions(+)
arch/hexagon/include/asm/thread_info.h new file +154 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/thread_info.h
===================================================================
@@ -0,0 +1,154 @@
+/*
+ * Thread support for the Hexagon architecture
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_THREAD_INFO_H
+#define _ASM_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+#include <asm/processor.h>
+#include <asm/registers.h>
+#include <asm/page.h>
+#endif
+
+#define THREAD_SHIFT		12
+#define THREAD_SIZE		(1<<THREAD_SHIFT)
+
+#if THREAD_SHIFT >= PAGE_SHIFT
+#define THREAD_SIZE_ORDER	(THREAD_SHIFT - PAGE_SHIFT)
+#else  /*  don't use standard allocator  */
+#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
+extern struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node);
+extern void free_thread_info(struct thread_info *ti);
+#endif
+
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+/*
+ * This is union'd with the "bottom" of the kernel stack.
+ * It keeps track of thread info which is handy for routines
+ * to access quickly.
+ */
+
+struct thread_info {
+	struct task_struct	*task;		/* main task structure */
+	struct exec_domain      *exec_domain;   /* execution domain */
+	unsigned long		flags;          /* low level flags */
+	__u32                   cpu;            /* current cpu */
+	int                     preempt_count;  /* 0=>preemptible,<0=>BUG */
+	mm_segment_t            addr_limit;     /* segmentation sux */
+	/*
+	 * used for syscalls somehow;
+	 * seems to have a function pointer and four arguments
+	 */
+	struct restart_block    restart_block;
+	/* Points to the current pt_regs frame  */
+	struct pt_regs		*regs;
+	/*
+	 * saved kernel sp at switch_to time;
+	 * not sure if this is used (it's not in the VM model it seems;
+	 * see thread_struct)
+	 */
+	unsigned long		sp;
+};
+
+#else /* !__ASSEMBLY__ */
+
+#include <asm/asm-offsets.h>
+
+#endif  /* __ASSEMBLY__  */
+
+/*  looks like "linux/hardirq.h" uses this.  */
+
+#define PREEMPT_ACTIVE		0x10000000
+
+#ifndef __ASSEMBLY__
+
+#define INIT_THREAD_INFO(tsk)                   \
+{                                               \
+	.task           = &tsk,                 \
+	.exec_domain    = &default_exec_domain, \
+	.flags          = 0,                    \
+	.cpu            = 0,                    \
+	.preempt_count  = 1,                    \
+	.addr_limit     = KERNEL_DS,            \
+	.restart_block = {                      \
+		.fn = do_no_restart_syscall,    \
+	},                                      \
+	.sp = 0,				\
+	.regs = NULL,			\
+}
+
+#define init_thread_info        (init_thread_union.thread_info)
+#define init_stack              (init_thread_union.stack)
+
+/* Tacky preprocessor trickery */
+#define	qqstr(s) qstr(s)
+#define qstr(s) #s
+#define QUOTED_THREADINFO_REG qqstr(THREADINFO_REG)
+
+register struct thread_info *__current_thread_info asm(QUOTED_THREADINFO_REG);
+#define current_thread_info()  __current_thread_info
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * thread information flags
+ * - these are process state flags that various assembly files
+ *   may need to access
+ * - pending work-to-be-done flags are in LSW
+ * - other flags in MSW
+ */
+
+#define TIF_SYSCALL_TRACE       0       /* syscall trace active */
+#define TIF_NOTIFY_RESUME       1       /* resumption notification requested */
+#define TIF_SIGPENDING          2       /* signal pending */
+#define TIF_NEED_RESCHED        3       /* rescheduling necessary */
+#define TIF_SINGLESTEP          4       /* restore ss @ return to usr mode */
+#define TIF_IRET                5       /* return with iret */
+#define TIF_RESTORE_SIGMASK     6       /* restore sig mask in do_signal() */
+/* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_POLLING_NRFLAG      16
+#define TIF_MEMDIE              17      /* OOM killer killed process */
+
+#define _TIF_SYSCALL_TRACE      (1 << TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME      (1 << TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING         (1 << TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED       (1 << TIF_NEED_RESCHED)
+#define _TIF_SINGLESTEP         (1 << TIF_SINGLESTEP)
+#define _TIF_IRET               (1 << TIF_IRET)
+#define _TIF_RESTORE_SIGMASK    (1 << TIF_RESTORE_SIGMASK)
+#define _TIF_POLLING_NRFLAG     (1 << TIF_POLLING_NRFLAG)
+
+/* work to do on interrupt/exception return - All but TIF_SYSCALL_TRACE */
+#define _TIF_WORK_MASK          (0x0000FFFF & ~_TIF_SYSCALL_TRACE)
+
+/* work to do on any return to u-space */
+#define _TIF_ALLWORK_MASK       0x0000FFFF
+
+#endif /* __KERNEL__ */
+
+#endif

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#17 lore raw

PATCH v2 8/35 Hexagon: Add delay functions

In reply to Richard Kuo

Added read_current_timer elsewhere, so __delay isn't really used.

udelay is based off of __vmgettime() which returns processor ticks.

---
 arch/hexagon/include/asm/delay.h |   34 ++++++++++++++++++++++++++++++++++
 arch/hexagon/kernel/delay.S      |   30 ++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+)
arch/hexagon/include/asm/delay.h new file +34 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/delay.h
===================================================================
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_DELAY_H
+#define _ASM_DELAY_H
+
+#include <asm/param.h>
+
+extern void __udelay(unsigned long usecs);
+
+#define udelay(usecs) __udelay((usecs))
+
+/*
+ * This isn't really used on our arch; __udelay is based on a
+ * vmgettime() call.
+ */
+extern void __delay(unsigned long loops);
+
+#endif /* _ASM_DELAY_H */
arch/hexagon/kernel/delay.S new file +30 -0
Index: linux-hexagon-kernel/arch/hexagon/kernel/delay.S
===================================================================
@@ -0,0 +1,30 @@
+/*
+ * __delay loop implementation for Hexagon
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/linkage.h>
+#include <asm/hexagon_vm.h>
+
+ENTRY(__delay)
+	loop0(1f,r0)
+1:
+	{
+		nop
+	}:endloop0
+	jumpr	R31

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#18 lore raw

Re: [patch v2 08/35] Hexagon: Add delay functions

Quoted 5 lines · Richard Kuo

Added read_current_timer elsewhere, so __delay isn't really used.

udelay is based off of __vmgettime() which returns processor ticks.

Why do you still provide __delay then?

If you disable CONFIG_GENERIC_CALIBRATE_DELAY, it should just never be called at all so you can remove it.

Arnd

#19 lore raw

PATCH v2 9/35 Hexagon: Add checksum functions

In reply to Richard Kuo

Removed most non-assembly functions and use the generic ones instead.

---
 arch/hexagon/include/asm/checksum.h   |   92 +++++++++++++++
 arch/hexagon/include/asm/intrinsics.h |   26 ++++
 arch/hexagon/lib/checksum.c           |  203 ++++++++++++++++++++++++++++++++++
 3 files changed, 321 insertions(+)
arch/hexagon/include/asm/checksum.h new file +92 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/checksum.h
===================================================================
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_CHECKSUM_H
+#define _ASM_CHECKSUM_H
+
+#include <linux/in6.h>
+
+#define do_csum	do_csum
+
+unsigned int do_csum(const void *voidptr, int len);
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+__wsum csum_partial(const void *buff, int len, __wsum sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+__wsum csum_partial_copy_nocheck(const void *src, void *dst,
+					int len, __wsum sum);
+
+/*
+ * the same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ *
+ * Using generic version; strange this doesn't appear in header...
+ */
+__wsum csum_partial_copy_from_user(const void __user *src, void *dst,
+					int len, __wsum sum, int *csum_err);
+
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ *
+ */
+__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
+
+/*
+ *	Fold a partial checksum
+ */
+static inline __sum16 csum_fold(__wsum csum)
+{
+	u32 sum = (__force u32)csum;
+	sum = (sum & 0xffff) + (sum >> 16);
+	sum = (sum & 0xffff) + (sum >> 16);
+	return (__force __sum16)~sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+#define csum_tcpudp_nofold csum_tcpudp_nofold
+__wsum csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
+	unsigned short len, unsigned short proto, __wsum sum);
+__sum16 csum_tcpudp_magic(unsigned long saddr, unsigned long daddr,
+	unsigned short len, unsigned short proto, __wsum sum);
+
+#endif
arch/hexagon/include/asm/intrinsics.h new file +26 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/intrinsics.h
===================================================================
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_HEXAGON_INTRINSICS_H
+#define _ASM_HEXAGON_INTRINSICS_H
+
+#define HEXAGON_P_vrmpyhacc_PP	__builtin_HEXAGON_M2_vrmac_s0
+#define HEXAGON_P_vrmpyh_PP	__builtin_HEXAGON_M2_vrmpy_s0
+#define HEXAGON_R_cl0_R		__builtin_HEXAGON_S2_cl0
+
+#endif
arch/hexagon/lib/checksum.c new file +203 -0

203 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#20 lore raw

Re: [patch v2 09/35] Hexagon: Add checksum functions

Quoted 1 line · Richard Kuo

Removed most non-assembly functions and use the generic ones instead.

[]

Quoted 1 line

+++ linux-hexagon-kernel/arch/hexagon/include/asm/checksum.h 2011-08-24 18:45:48.133877105 -0500

[]

Quoted 1 line

+#define do_csum do_csum

That looks pretty odd.
I have a hard time believing that's useful or necessary.

#21 lore raw

Re: [patch v2 09/35] Hexagon: Add checksum functions

Quoted 9 lines · Joe Perches
Quoted 1 line · Richard Kuo

Removed most non-assembly functions and use the generic ones instead.

[]

Quoted 1 line

+++ linux-hexagon-kernel/arch/hexagon/include/asm/checksum.h 2011-08-24 18:45:48.133877105 -0500

[]

Quoted 1 line

+#define do_csum do_csum

That looks pretty odd.
I have a hard time believing that's useful or necessary.

This is "the new way" to tell that an arch supply an arch specific variant of a function. See lib/checksum.c.

It does:

#ifndef do_csum
...
#endif

So archs that do not define do_csum will get a generic version of do_csum. And "do_csum" nicely shows up in grep - so it makes sense to do so.

Sam

#23 lore raw

PATCH v2 10/35 Hexagon: Add memcpy and memset accelerated functions

In reply to Richard Kuo
---
 arch/hexagon/lib/memcpy.S |  543 ++++++++++++++++++++++++++++++++++++++++++++++
 arch/hexagon/lib/memset.S |  316 ++++++++++++++++++++++++++
 2 files changed, 859 insertions(+)
arch/hexagon/lib/memcpy.S new file +543 -0
Index: linux-hexagon-kernel/arch/hexagon/lib/memcpy.S
===================================================================
@@ -0,0 +1,543 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/*
+ * Description
+ *
+ *   library function for memcpy where length bytes are copied from
+ *   ptr_in to ptr_out. ptr_out is returned unchanged.
+ *   Allows any combination of alignment on input and output pointers
+ *   and length from 0 to 2^32-1
+ *
+ * Restrictions
+ *   The arrays should not overlap, the program will produce undefined output
+ *   if they do.
+ *   For blocks less than 16 bytes a byte by byte copy is performed. For
+ *   8byte alignments, and length multiples, a dword copy is performed up to
+ *   96bytes
+ * History
+ *
+ *   DJH  5/15/09 Initial version 1.0
+ *   DJH  6/ 1/09 Version 1.1 modified ABI to inlcude R16-R19
+ *   DJH  7/12/09 Version 1.2 optimized codesize down to 760 was 840
+ *   DJH 10/14/09 Version 1.3 added special loop for aligned case, was
+ *                            overreading bloated codesize back up to 892
+ *   DJH  4/20/10 Version 1.4 fixed Ldword_loop_epilog loop to prevent loads
+ *                            occuring if only 1 left outstanding, fixes bug
+ *                            # 3888, corrected for all alignments. Peeled off
+ *                            1 32byte chunk from kernel loop and extended 8byte
+ *                            loop at end to solve all combinations and prevent
+ *                            over read.  Fixed Ldword_loop_prolog to prevent
+ *                            overread for blocks less than 48bytes. Reduced
+ *                            codesize to 752 bytes
+ *   DJH  4/21/10 version 1.5 1.4 fix broke code for input block ends not
+ *                            aligned to dword boundaries,underwriting by 1
+ *                            byte, added detection for this and fixed. A
+ *                            little bloat.
+ *   DJH  4/23/10 version 1.6 corrected stack error, R20 was not being restored
+ *                            always, fixed the error of R20 being modified
+ *                            before it was being saved
+ * Natural c model
+ * ===============
+ * void * memcpy(char * ptr_out, char * ptr_in, int length) {
+ *   int i;
+ *   if(length) for(i=0; i < length; i++) { ptr_out[i] = ptr_in[i]; }
+ *   return(ptr_out);
+ * }
+ *
+ * Optimized memcpy function
+ * =========================
+ * void * memcpy(char * ptr_out, char * ptr_in, int len) {
+ *   int i, prolog, kernel, epilog, mask;
+ *   u8 offset;
+ *   s64 data0, dataF8, data70;
+ *
+ *   s64 * ptr8_in;
+ *   s64 * ptr8_out;
+ *   s32 * ptr4;
+ *   s16 * ptr2;
+ *
+ *   offset = ((int) ptr_in) & 7;
+ *   ptr8_in = (s64 *) &ptr_in[-offset];   //read in the aligned pointers
+ *
+ *   data70 = *ptr8_in++;
+ *   dataF8 = *ptr8_in++;
+ *
+ *   data0 = HEXAGON_P_valignb_PPp(dataF8, data70, offset);
+ *
+ *   prolog = 32 - ((int) ptr_out);
+ *   mask  = 0x7fffffff >> HEXAGON_R_cl0_R(len);
+ *   prolog = prolog & mask;
+ *   kernel = len - prolog;
+ *   epilog = kernel & 0x1F;
+ *   kernel = kernel>>5;
+ *
+ *   if (prolog & 1) { ptr_out[0] = (u8) data0; data0 >>= 8; ptr_out += 1;}
+ *   ptr2 = (s16 *) &ptr_out[0];
+ *   if (prolog & 2) { ptr2[0] = (u16) data0;  data0 >>= 16; ptr_out += 2;}
+ *   ptr4 = (s32 *) &ptr_out[0];
+ *   if (prolog & 4) { ptr4[0] = (u32) data0;  data0 >>= 32; ptr_out += 4;}
+ *
+ *   offset = offset + (prolog & 7);
+ *   if (offset >= 8) {
+ *     data70 = dataF8;
+ *     dataF8 = *ptr8_in++;
+ *   }
+ *   offset = offset & 0x7;
+ *
+ *   prolog = prolog >> 3;
+ *   if (prolog) for (i=0; i < prolog; i++) {
+ *       data0 = HEXAGON_P_valignb_PPp(dataF8, data70, offset);
+ *       ptr8_out = (s64 *) &ptr_out[0]; *ptr8_out = data0; ptr_out += 8;
+ *       data70 = dataF8;
+ *       dataF8 = *ptr8_in++;
+ *   }
+ *   if(kernel) { kernel -= 1; epilog += 32; }
+ *   if(kernel) for(i=0; i < kernel; i++) {
+ *       data0 = HEXAGON_P_valignb_PPp(dataF8, data70, offset);
+ *       ptr8_out = (s64 *) &ptr_out[0]; *ptr8_out = data0; ptr_out += 8;
+ *       data70 = *ptr8_in++;
+ *
+ *       data0 = HEXAGON_P_valignb_PPp(data70, dataF8, offset);
+ *       ptr8_out = (s64 *) &ptr_out[0]; *ptr8_out = data0; ptr_out += 8;
+ *       dataF8 = *ptr8_in++;
+ *
+ *       data0 = HEXAGON_P_valignb_PPp(dataF8, data70, offset);
+ *       ptr8_out = (s64 *) &ptr_out[0]; *ptr8_out = data0; ptr_out += 8;
+ *       data70 = *ptr8_in++;
+ *
+ *       data0 = HEXAGON_P_valignb_PPp(data70, dataF8, offset);
+ *       ptr8_out = (s64 *) &ptr_out[0]; *ptr8_out = data0; ptr_out += 8;
+ *       dataF8 = *ptr8_in++;
+ *   }
+ *   epilogdws = epilog >> 3;
+ *   if (epilogdws) for (i=0; i < epilogdws; i++) {
+ *       data0 = HEXAGON_P_valignb_PPp(dataF8, data70, offset);
+ *       ptr8_out = (s64 *) &ptr_out[0]; *ptr8_out = data0; ptr_out += 8;
+ *       data70 = dataF8;
+ *       dataF8 = *ptr8_in++;
+ *   }
+ *   data0 = HEXAGON_P_valignb_PPp(dataF8, data70, offset);
+ *
+ *   ptr4 = (s32 *) &ptr_out[0];
+ *   if (epilog & 4) { ptr4[0] = (u32) data0; data0 >>= 32; ptr_out += 4;}
+ *   ptr2 = (s16 *) &ptr_out[0];
+ *   if (epilog & 2) { ptr2[0] = (u16) data0; data0 >>= 16; ptr_out += 2;}
+ *   if (epilog & 1) { *ptr_out++ = (u8) data0; }
+ *
+ *   return(ptr_out - length);
+ * }
+ *
+ * Codesize : 784 bytes
+ */
+
+
+#define ptr_out		R0	/*  destination  pounter  */
+#define ptr_in		R1	/*  source pointer  */
+#define len		R2	/*  length of copy in bytes  */
+
+#define data70		R13:12	/*  lo 8 bytes of non-aligned transfer  */
+#define dataF8		R11:10	/*  hi 8 bytes of non-aligned transfer  */
+#define ldata0		R7:6	/*  even 8 bytes chunks  */
+#define ldata1		R25:24	/*  odd 8 bytes chunks  */
+#define data1		R7	/*  lower 8 bytes of ldata1  */
+#define data0		R6	/*  lower 8 bytes of ldata0  */
+
+#define ifbyte		p0	/*  if transfer has bytes in epilog/prolog  */
+#define ifhword		p0	/*  if transfer has shorts in epilog/prolog  */
+#define ifword		p0	/*  if transfer has words in epilog/prolog  */
+#define noprolog	p0	/*  no prolog, xfer starts at 32byte  */
+#define nokernel	p1	/*  no 32byte multiple block in the transfer  */
+#define noepilog	p0	/*  no epilog, xfer ends on 32byte boundary  */
+#define align		p2	/*  alignment of input rel to 8byte boundary  */
+#define kernel1		p0	/*  kernel count == 1  */
+
+#define dalign		R25	/*  rel alignment of input to output data  */
+#define star3		R16	/*  number bytes in prolog - dwords  */
+#define rest		R8	/*  length - prolog bytes  */
+#define back		R7	/*  nr bytes > dword boundary in src block  */
+#define epilog		R3	/*  bytes in epilog  */
+#define inc		R15:14	/*  inc kernel by -1 and defetch ptr by 32  */
+#define kernel		R4	/*  number of 32byte chunks in kernel  */
+#define ptr_in_p_128	R5	/*  pointer for prefetch of input data  */
+#define mask		R8	/*  mask used to determine prolog size  */
+#define shift		R8	/*  used to work a shifter to extract bytes  */
+#define shift2		R5	/*  in epilog to workshifter to extract bytes */
+#define prolog		R15	/*  bytes in  prolog  */
+#define epilogdws	R15	/*  number dwords in epilog  */
+#define shiftb		R14	/*  used to extract bytes  */
+#define offset		R9	/*  same as align in reg  */
+#define ptr_out_p_32	R17	/*  pointer to output dczero  */
+#define align888	R14	/*  if simple dword loop can be used  */
+#define len8		R9	/*  number of dwords in length  */
+#define over		R20	/*  nr of bytes > last inp buf dword boundary */
+
+#define ptr_in_p_128kernel	R5:4	/*  packed fetch pointer & kernel cnt */
+
+	.section .text
+	.p2align 4
+        .global memcpy
+        .type memcpy, @function
+memcpy:
+{
+	p2 = cmp.eq(len, #0);		/*  =0 */
+	align888 = or(ptr_in, ptr_out);	/*  %8 < 97 */
+	p0 = cmp.gtu(len, #23);		/*  %1, <24 */
+	p1 = cmp.eq(ptr_in, ptr_out);	/*  attempt to overwrite self */
+}
+{
+	p1 = or(p2, p1);
+	p3 = cmp.gtu(len, #95);		/*  %8 < 97 */
+	align888 = or(align888, len);	/*  %8 < 97 */
+	len8 = lsr(len, #3);		/*  %8 < 97 */
+}
+{
+	dcfetch(ptr_in);		/*  zero/ptrin=ptrout causes fetch */
+	p2 = bitsclr(align888, #7);	/*  %8 < 97  */
+	if(p1) jumpr r31;		/*  =0  */
+}
+{
+	p2 = and(p2,!p3);			/*  %8 < 97  */
+	if (p2.new) len = add(len, #-8);	/*  %8 < 97  */
+	if (p2.new) jump:NT .Ldwordaligned; 	/*  %8 < 97  */
+}
+{
+	if(!p0) jump .Lbytes23orless;	/*  %1, <24  */
+	mask.l = #LO(0x7fffffff);
+	/*  all bytes before line multiples of data  */
+	prolog = sub(#0, ptr_out);
+}
+{
+	/*  save r31 on stack, decrement sp by 16  */
+	allocframe(#24);
+	mask.h = #HI(0x7fffffff);
+	ptr_in_p_128 = add(ptr_in, #32);
+	back = cl0(len);
+}
+{
+	memd(sp+#0) = R17:16;		/*  save r16,r17 on stack6  */
+	r31.l = #LO(.Lmemcpy_return);	/*  set up final return pointer  */
+	prolog &= lsr(mask, back);
+	offset = and(ptr_in, #7);
+}
+{
+	memd(sp+#8) = R25:24;		/*  save r25,r24 on stack  */
+	dalign = sub(ptr_out, ptr_in);
+	r31.h = #HI(.Lmemcpy_return);	/*  set up final return pointer  */
+}
+{
+	/*  see if there if input buffer end if aligned  */
+	over = add(len, ptr_in);
+	back = add(len, offset);
+	memd(sp+#16) = R21:20;		/*  save r20,r21 on stack  */
+}
+{
+	noprolog = bitsclr(prolog, #7);
+	prolog = and(prolog, #31);
+	dcfetch(ptr_in_p_128);
+	ptr_in_p_128 = add(ptr_in_p_128, #32);
+}
+{
+	kernel = sub(len, prolog);
+	shift = asl(prolog, #3);
+	star3 = and(prolog, #7);
+	ptr_in = and(ptr_in, #-8);
+}
+{
+	prolog = lsr(prolog, #3);
+	epilog = and(kernel, #31);
+	ptr_out_p_32 = add(ptr_out, prolog);
+	over = and(over, #7);
+}
+{
+	p3 = cmp.gtu(back, #8);
+	kernel = lsr(kernel, #5);
+	dcfetch(ptr_in_p_128);
+	ptr_in_p_128 = add(ptr_in_p_128, #32);
+}
+{
+	p1 = cmp.eq(prolog, #0);
+	if(!p1.new) prolog = add(prolog, #1);
+	dcfetch(ptr_in_p_128);	/*  reserve the line 64bytes on  */
+	ptr_in_p_128 = add(ptr_in_p_128, #32);
+}
+{
+	nokernel = cmp.eq(kernel,#0);
+	dcfetch(ptr_in_p_128);	/* reserve the line 64bytes on  */
+	ptr_in_p_128 = add(ptr_in_p_128, #32);
+	shiftb = and(shift, #8);
+}
+{
+	dcfetch(ptr_in_p_128);		/*  reserve the line 64bytes on  */
+	ptr_in_p_128 = add(ptr_in_p_128, #32);
+	if(nokernel) jump .Lskip64;
+	p2 = cmp.eq(kernel, #1);	/*  skip ovr if kernel == 0  */
+}
+{
+	dczeroa(ptr_out_p_32);
+	/*  don't advance pointer  */
+	if(!p2) ptr_out_p_32 = add(ptr_out_p_32, #32);
+}
+{
+	dalign = and(dalign, #31);
+	dczeroa(ptr_out_p_32);
+}
+.Lskip64:
+{
+	data70 = memd(ptr_in++#16);
+	if(p3) dataF8 = memd(ptr_in+#8);
+	if(noprolog) jump .Lnoprolog32;
+	align = offset;
+}
+/*  upto initial 7 bytes  */
+{
+	ldata0 = valignb(dataF8, data70, align);
+	ifbyte = tstbit(shift,#3);
+	offset = add(offset, star3);
+}
+{
+	if(ifbyte) memb(ptr_out++#1) = data0;
+	ldata0 = lsr(ldata0, shiftb);
+	shiftb = and(shift, #16);
+	ifhword = tstbit(shift,#4);
+}
+{
+	if(ifhword) memh(ptr_out++#2) = data0;
+	ldata0 = lsr(ldata0, shiftb);
+	ifword = tstbit(shift,#5);
+	p2 = cmp.gtu(offset, #7);
+}
+{
+	if(ifword) memw(ptr_out++#4) = data0;
+	if(p2) data70 = dataF8;
+	if(p2) dataF8 = memd(ptr_in++#8);	/*  another 8 bytes  */
+	align = offset;
+}
+.Lnoprolog32:
+{
+	p3 = sp1loop0(.Ldword_loop_prolog, prolog)
+	rest = sub(len, star3);	/*  whats left after the loop  */
+	p0 = cmp.gt(over, #0);
+}
+	if(p0) rest = add(rest, #16);
+.Ldword_loop_prolog:
+{
+	if(p3) memd(ptr_out++#8) = ldata0;
+	ldata0 = valignb(dataF8, data70, align);
+	p0 = cmp.gt(rest, #16);
+}
+{
+	data70 = dataF8;
+	if(p0) dataF8 = memd(ptr_in++#8);
+	rest = add(rest, #-8);
+}:endloop0
+.Lkernel:
+{
+	/*  kernel is at least 32bytes  */
+	p3 = cmp.gtu(kernel, #0);
+	/*  last itn. remove edge effects  */
+	if(p3.new) kernel = add(kernel, #-1);
+	/*  dealt with in last dword loop  */
+	if(p3.new) epilog = add(epilog, #32);
+}
+{
+	nokernel = cmp.eq(kernel, #0);		/*  after adjustment, recheck */
+	if(nokernel.new) jump:NT .Lepilog;	/*  likely not taken  */
+	inc = combine(#32, #-1);
+	p3 = cmp.gtu(dalign, #24);
+}
+{
+	if(p3) jump .Lodd_alignment;
+}
+{
+	loop0(.Loword_loop_25to31, kernel);
+	kernel1 = cmp.gtu(kernel, #1);
+	rest = kernel;
+}
+	.falign
+.Loword_loop_25to31:
+{
+	dcfetch(ptr_in_p_128);	/*  prefetch 4 lines ahead  */
+	if(kernel1) ptr_out_p_32 = add(ptr_out_p_32, #32);
+}
+{
+	dczeroa(ptr_out_p_32);	/*  reserve the next 32bytes in cache  */
+	p3 = cmp.eq(kernel, rest);
+}
+{
+	/*  kernel -= 1  */
+	ptr_in_p_128kernel = vaddw(ptr_in_p_128kernel, inc);
+	/*  kill write on first iteration  */
+	if(!p3) memd(ptr_out++#8) = ldata1;
+	ldata1 = valignb(dataF8, data70, align);
+	data70 = memd(ptr_in++#8);
+}
+{
+	memd(ptr_out++#8) = ldata0;
+	ldata0 = valignb(data70, dataF8, align);
+	dataF8 = memd(ptr_in++#8);
+}
+{
+	memd(ptr_out++#8) = ldata1;
+	ldata1 = valignb(dataF8, data70, align);
+	data70 = memd(ptr_in++#8);
+}
+{
+	memd(ptr_out++#8) = ldata0;
+	ldata0 = valignb(data70, dataF8, align);
+	dataF8 = memd(ptr_in++#8);
+	kernel1 = cmp.gtu(kernel, #1);
+}:endloop0
+{
+	memd(ptr_out++#8) = ldata1;
+	jump .Lepilog;
+}
+.Lodd_alignment:
+{
+	loop0(.Loword_loop_00to24, kernel);
+	kernel1 = cmp.gtu(kernel, #1);
+	rest = add(kernel, #-1);
+}
+	.falign
+.Loword_loop_00to24:
+{
+	dcfetch(ptr_in_p_128);	/*  prefetch 4 lines ahead  */
+	ptr_in_p_128kernel = vaddw(ptr_in_p_128kernel, inc);
+	if(kernel1) ptr_out_p_32 = add(ptr_out_p_32, #32);
+}
+{
+	dczeroa(ptr_out_p_32);	/*  reserve the next 32bytes in cache  */
+}
+{
+	memd(ptr_out++#8) = ldata0;
+	ldata0 = valignb(dataF8, data70, align);
+	data70 = memd(ptr_in++#8);
+}
+{
+	memd(ptr_out++#8) = ldata0;
+	ldata0 = valignb(data70, dataF8, align);
+	dataF8 = memd(ptr_in++#8);
+}
+{
+	memd(ptr_out++#8) = ldata0;
+	ldata0 = valignb(dataF8, data70, align);
+	data70 = memd(ptr_in++#8);
+}
+{
+	memd(ptr_out++#8) = ldata0;
+	ldata0 = valignb(data70, dataF8, align);
+	dataF8 = memd(ptr_in++#8);
+	kernel1 = cmp.gtu(kernel, #1);
+}:endloop0
+.Lepilog:
+{
+	noepilog = cmp.eq(epilog,#0);
+	epilogdws = lsr(epilog, #3);
+	kernel = and(epilog, #7);
+}
+{
+	if(noepilog) jumpr r31;
+	if(noepilog) ptr_out = sub(ptr_out, len);
+	p3 = cmp.eq(epilogdws, #0);
+	shift2 = asl(epilog, #3);
+}
+{
+	shiftb = and(shift2, #32);
+	ifword = tstbit(epilog,#2);
+	if(p3) jump .Lepilog60;
+	if(!p3) epilog = add(epilog, #-16);
+}
+{
+	loop0(.Ldword_loop_epilog, epilogdws);
+	/*  stop criteria is lsbs unless = 0 then its 8  */
+	p3 = cmp.eq(kernel, #0);
+	if(p3.new) kernel= #8;
+	p1 = cmp.gt(over, #0);
+}
+	/*  if not aligned to end of buffer execute 1 more iteration  */
+	if(p1) kernel= #0;
+.Ldword_loop_epilog:
+{
+	memd(ptr_out++#8) = ldata0;
+	ldata0 = valignb(dataF8, data70, align);
+	p3 = cmp.gt(epilog, kernel);
+}
+{
+	data70 = dataF8;
+	if(p3) dataF8 = memd(ptr_in++#8);
+	epilog = add(epilog, #-8);
+}:endloop0
+/* copy last 7 bytes */
+.Lepilog60:
+{
+	if(ifword) memw(ptr_out++#4) = data0;
+	ldata0 = lsr(ldata0, shiftb);
+	ifhword = tstbit(epilog,#1);
+	shiftb = and(shift2, #16);
+}
+{
+	if(ifhword) memh(ptr_out++#2) = data0;
+	ldata0 = lsr(ldata0, shiftb);
+	ifbyte = tstbit(epilog,#0);
+	if(ifbyte.new) len = add(len, #-1);
+}
+{
+	if(ifbyte) memb(ptr_out) = data0;
+	ptr_out = sub(ptr_out, len);	/*  return dest pointer  */
+        jumpr r31;
+}
+/*  do byte copy for small n  */
+.Lbytes23orless:
+{
+	p3 = sp1loop0(.Lbyte_copy, len);
+	len = add(len, #-1);
+}
+.Lbyte_copy:
+{
+	data0 = memb(ptr_in++#1);
+	if(p3) memb(ptr_out++#1) = data0;
+}:endloop0
+{
+	memb(ptr_out) = data0;
+	ptr_out = sub(ptr_out, len);
+	jumpr r31;
+}
+/*  do dword copies for aligned in, out and length  */
+.Ldwordaligned:
+{
+	p3 = sp1loop0(.Ldword_copy, len8);
+}
+.Ldword_copy:
+{
+	if(p3) memd(ptr_out++#8) = ldata0;
+	ldata0 = memd(ptr_in++#8);
+}:endloop0
+{
+	memd(ptr_out) = ldata0;
+	ptr_out = sub(ptr_out, len);
+	jumpr r31;	/*  return to function caller  */
+}
+.Lmemcpy_return:
+	r21:20 = memd(sp+#16);	/*  restore r20+r21  */
+{
+	r25:24 = memd(sp+#8);	/*  restore r24+r25  */
+	r17:16 = memd(sp+#0);	/*  restore r16+r17  */
+}
+	deallocframe;	/*  restore r31 and incrment stack by 16  */
+	jumpr r31
arch/hexagon/lib/memset.S new file +316 -0

316 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#25 lore raw

PATCH v2 11/35 Hexagon: Add hypervisor interface

In reply to Richard Kuo

The port of Linux for Hexagon runs on top of a hypervisor layer, which presents an interface for memory management, events, hardware control, etc.

---
 arch/hexagon/include/asm/hexagon_vm.h  |  280 ++++++++++++++++++++
 arch/hexagon/include/asm/vm_mmu.h      |  111 ++++++++
 arch/hexagon/kernel/vm_entry.S         |  269 ++++++++++++++++++++
 arch/hexagon/kernel/vm_events.c        |  101 +++++++
 arch/hexagon/kernel/vm_init_segtable.S |  442 +++++++++++++++++++++++++++++++++
 arch/hexagon/kernel/vm_ops.S           |  101 +++++++
 arch/hexagon/kernel/vm_switch.S        |   95 +++++++
 arch/hexagon/kernel/vm_vectors.S       |   50 +++
 8 files changed, 1449 insertions(+)
arch/hexagon/include/asm/hexagon_vm.h new file +280 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/hexagon_vm.h
===================================================================
@@ -0,0 +1,280 @@
+/*
+ * Declarations for to Hexagon Virtal Machine.
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef ASM_HEXAGON_VM_H
+#define ASM_HEXAGON_VM_H
+
+/*
+ * In principle, a Linux kernel for the VM could
+ * selectively define the virtual instructions
+ * as inline assembler macros, but for a first pass,
+ * we'll use subroutines for both the VM and the native
+ * kernels.  It's costing a subroutine call/return,
+ * but it makes for a single set of entry points
+ * for tracing/debugging.
+ */
+
+/*
+ * Lets make this stuff visible only if configured,
+ * so we can unconditionally include the file.
+ */
+
+#ifndef __ASSEMBLY__
+
+enum VM_CACHE_OPS {
+	ickill,
+	dckill,
+	l2kill,
+	dccleaninva,
+	icinva,
+	idsync,
+	fetch_cfg
+};
+
+enum VM_INT_OPS {
+	nop,
+	globen,
+	globdis,
+	locen,
+	locdis,
+	affinity,
+	get,
+	peek,
+	status,
+	post,
+	clear
+};
+
+extern void _K_VM_event_vector(void);
+
+void __vmrte(void);
+long __vmsetvec(void *);
+long __vmsetie(long);
+long __vmgetie(void);
+long __vmintop(enum VM_INT_OPS, long, long, long, long);
+long __vmclrmap(void *, unsigned long);
+long __vmnewmap(void *);
+long __vmcache(enum VM_CACHE_OPS op, unsigned long addr, unsigned long len);
+unsigned long long __vmgettime(void);
+long __vmsettime(unsigned long long);
+long __vmstart(void *, void *);
+void __vmstop(void);
+long __vmwait(void);
+void __vmyield(void);
+long __vmvpid(void);
+
+static inline long __vmcache_ickill(void)
+{
+	return __vmcache(ickill, 0, 0);
+}
+
+static inline long __vmcache_dckill(void)
+{
+	return __vmcache(dckill, 0, 0);
+}
+
+static inline long __vmcache_l2kill(void)
+{
+	return __vmcache(l2kill, 0, 0);
+}
+
+static inline long __vmcache_dccleaninva(unsigned long addr, unsigned long len)
+{
+	return __vmcache(dccleaninva, addr, len);
+}
+
+static inline long __vmcache_icinva(unsigned long addr, unsigned long len)
+{
+	return __vmcache(icinva, addr, len);
+}
+
+static inline long __vmcache_idsync(unsigned long addr,
+					   unsigned long len)
+{
+	return __vmcache(idsync, addr, len);
+}
+
+static inline long __vmcache_fetch_cfg(unsigned long val)
+{
+	return __vmcache(fetch_cfg, val, 0);
+}
+
+/* interrupt operations  */
+
+static inline long __vmintop_nop(void)
+{
+	return __vmintop(nop, 0, 0, 0, 0);
+}
+
+static inline long __vmintop_globen(long i)
+{
+	return __vmintop(globen, i, 0, 0, 0);
+}
+
+static inline long __vmintop_globdis(long i)
+{
+	return __vmintop(globdis, i, 0, 0, 0);
+}
+
+static inline long __vmintop_locen(long i)
+{
+	return __vmintop(locen, i, 0, 0, 0);
+}
+
+static inline long __vmintop_locdis(long i)
+{
+	return __vmintop(locdis, i, 0, 0, 0);
+}
+
+static inline long __vmintop_affinity(long i, long cpu)
+{
+	return __vmintop(locdis, i, cpu, 0, 0);
+}
+
+static inline long __vmintop_get(void)
+{
+	return __vmintop(get, 0, 0, 0, 0);
+}
+
+static inline long __vmintop_peek(void)
+{
+	return __vmintop(peek, 0, 0, 0, 0);
+}
+
+static inline long __vmintop_status(long i)
+{
+	return __vmintop(status, i, 0, 0, 0);
+}
+
+static inline long __vmintop_post(long i)
+{
+	return __vmintop(post, i, 0, 0, 0);
+}
+
+static inline long __vmintop_clear(long i)
+{
+	return __vmintop(clear, i, 0, 0, 0);
+}
+
+#else /* Only assembly code should reference these */
+
+#define HVM_TRAP1_VMRTE			1
+#define HVM_TRAP1_VMSETVEC		2
+#define HVM_TRAP1_VMSETIE		3
+#define HVM_TRAP1_VMGETIE		4
+#define HVM_TRAP1_VMINTOP		5
+#define HVM_TRAP1_VMCLRMAP		10
+#define HVM_TRAP1_VMNEWMAP		11
+#define HVM_TRAP1_FORMERLY_VMWIRE	12
+#define HVM_TRAP1_VMCACHE		13
+#define HVM_TRAP1_VMGETTIME		14
+#define HVM_TRAP1_VMSETTIME		15
+#define HVM_TRAP1_VMWAIT		16
+#define HVM_TRAP1_VMYIELD		17
+#define HVM_TRAP1_VMSTART		18
+#define HVM_TRAP1_VMSTOP		19
+#define HVM_TRAP1_VMVPID		20
+#define HVM_TRAP1_VMSETREGS		21
+#define HVM_TRAP1_VMGETREGS		22
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Constants for virtual instruction parameters and return values
+ */
+
+/* vmsetie arguments */
+
+#define VM_INT_DISABLE	0
+#define VM_INT_ENABLE	1
+
+/* vmsetimask arguments */
+
+#define VM_INT_UNMASK	0
+#define VM_INT_MASK	1
+
+/* vmcache arguments */
+
+
+/*
+ * Event Record definitions useful to both C and Assembler
+ */
+
+/* VMEST Layout */
+
+#define HVM_VMEST_UM_SFT	31
+#define HVM_VMEST_UM_MSK	1
+#define HVM_VMEST_IE_SFT	30
+#define HVM_VMEST_IE_MSK	1
+#define HVM_VMEST_EVENTNUM_SFT	16
+#define HVM_VMEST_EVENTNUM_MSK	0xff
+#define HVM_VMEST_CAUSE_SFT	0
+#define HVM_VMEST_CAUSE_MSK	0xffff
+
+/*
+ * The initial program gets to find a system environment descriptor
+ * on its stack when it begins exection. The first word is a version
+ * code to indicate what is there.  Zero means nothing more.
+ */
+
+#define HEXAGON_VM_SED_NULL	0
+
+/*
+ * Event numbers for vector binding
+ */
+
+#define HVM_EV_RESET		0
+#define HVM_EV_MACHCHECK	1
+#define HVM_EV_GENEX		2
+#define HVM_EV_TRAP		8
+#define HVM_EV_INTR		15
+/* These shoud be nuked as soon as we know the VM is up to spec v0.1.1 */
+#define HVM_EV_INTR_0		16
+#define HVM_MAX_INTR		240
+
+/*
+ * Cause values for General Exception
+ */
+
+#define HVM_GE_C_BUS	0x01
+#define HVM_GE_C_XPROT	0x11
+#define HVM_GE_C_XUSER	0x14
+#define HVM_GE_C_INVI	0x15
+#define HVM_GE_C_PRIVI	0x1B
+#define HVM_GE_C_XMAL	0x1C
+#define HVM_GE_C_RMAL	0x20
+#define HVM_GE_C_WMAL	0x21
+#define HVM_GE_C_RPROT	0x22
+#define HVM_GE_C_WPROT	0x23
+#define HVM_GE_C_RUSER	0x24
+#define HVM_GE_C_WUSER	0x25
+#define HVM_GE_C_CACHE	0x28
+
+/*
+ * Cause codes for Machine Check
+ */
+
+#define	HVM_MCHK_C_DOWN		0x00
+#define	HVM_MCHK_C_BADSP	0x01
+#define	HVM_MCHK_C_BADEX	0x02
+#define	HVM_MCHK_C_BADPT	0x03
+#define	HVM_MCHK_C_REGWR	0x29
+
+#endif
arch/hexagon/include/asm/vm_mmu.h new file +111 -0

111 lines not on this page · raw message

arch/hexagon/kernel/vm_entry.S new file +269 -0

269 lines not on this page · raw message

arch/hexagon/kernel/vm_events.c new file +101 -0

101 lines not on this page · raw message

arch/hexagon/kernel/vm_init_segtable.S new file +442 -0

442 lines not on this page · raw message

arch/hexagon/kernel/vm_ops.S new file +101 -0

101 lines not on this page · raw message

arch/hexagon/kernel/vm_switch.S new file +95 -0

95 lines not on this page · raw message

arch/hexagon/kernel/vm_vectors.S new file +50 -0

50 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#27 lore raw

PATCH v2 12/35 Hexagon: Export ksyms defined in assembly files.

In reply to Richard Kuo
---
 arch/hexagon/kernel/hexagon_ksyms.c |   42 ++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)
arch/hexagon/kernel/hexagon_ksyms.c new file +42 -0
Index: linux-hexagon-kernel/arch/hexagon/kernel/hexagon_ksyms.c
===================================================================
@@ -0,0 +1,42 @@
+/*
+ * Export of symbols defined in assembly files and/or libgcc.
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <asm/hexagon_vm.h>
+#include <asm/uaccess.h>
+
+EXPORT_SYMBOL(__copy_from_user_hexagon);
+EXPORT_SYMBOL(__copy_to_user_hexagon);
+EXPORT_SYMBOL(__vmgetie);
+EXPORT_SYMBOL(__vmsetie);
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memset);
+
+#define DECLARE_EXPORT(name)     \
+	extern void name(void); EXPORT_SYMBOL(name)
+
+/* Symbols found in libgcc that assorted kernel modules need */
+DECLARE_EXPORT(__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes);
+
+DECLARE_EXPORT(__hexagon_divsi3);
+DECLARE_EXPORT(__hexagon_modsi3);
+DECLARE_EXPORT(__hexagon_udivsi3);
+DECLARE_EXPORT(__hexagon_umodsi3);
+
+

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#29 lore raw

PATCH v2 13/35 Hexagon: Support dynamic module loading.

In reply to Richard Kuo

Modules should be compiled as ordinary .o's; shared objects are not supported.

Deleted module functions that already have generic equivalents.

---
 arch/hexagon/kernel/module.c |  162 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 162 insertions(+)
arch/hexagon/kernel/module.c new file +162 -0
Index: linux-hexagon-kernel/arch/hexagon/kernel/module.c
===================================================================
@@ -0,0 +1,162 @@
+/*
+ * Kernel module loader for Hexagon
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <asm/module.h>
+#include <linux/elf.h>
+#include <linux/module.h>
+#include <linux/moduleloader.h>
+#include <linux/vmalloc.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(fmt , ...)
+#endif
+
+/*
+ * module_frob_arch_sections - tweak got/plt sections.
+ * @hdr - pointer to elf header
+ * @sechdrs - pointer to elf load section headers
+ * @secstrings - symbol names
+ * @mod - pointer to module
+ */
+int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
+				char *secstrings,
+				struct module *mod)
+{
+	unsigned int i;
+	int found = 0;
+
+	/* Look for .plt and/or .got.plt and/or .init.plt sections */
+	for (i = 0; i < hdr->e_shnum; i++) {
+		DEBUGP("Section %d is %s\n", i,
+		       secstrings + sechdrs[i].sh_name);
+		if (strcmp(secstrings + sechdrs[i].sh_name, ".plt") == 0)
+			found = i+1;
+		if (strcmp(secstrings + sechdrs[i].sh_name, ".got.plt") == 0)
+			found = i+1;
+		if (strcmp(secstrings + sechdrs[i].sh_name, ".rela.plt") == 0)
+			found = i+1;
+	}
+
+	/* At this time, we don't support modules comiled with -shared */
+	if (found) {
+		printk(KERN_WARNING
+			"Module '%s' contains unexpected .plt/.got sections.\n",
+			mod->name);
+		/*  return -ENOEXEC;  */
+	}
+
+	return 0;
+}
+
+/*
+ * apply_relocate_add - perform rela relocations.
+ * @sechdrs - pointer to section headers
+ * @strtab - some sort of start address?
+ * @symindex - symbol index offset or something?
+ * @relsec - address to relocate to?
+ * @module - pointer to module
+ *
+ * Perform rela relocations.
+ */
+int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
+			unsigned int symindex, unsigned int relsec,
+			struct module *module)
+{
+	unsigned int i;
+	Elf32_Sym *sym;
+	uint32_t *location;
+	uint32_t value;
+	unsigned int nrelocs = sechdrs[relsec].sh_size / sizeof(Elf32_Rela);
+	Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
+	Elf32_Word sym_info = sechdrs[relsec].sh_info;
+	Elf32_Sym *sym_base = (Elf32_Sym *) sechdrs[symindex].sh_addr;
+	void *loc_base = (void *) sechdrs[sym_info].sh_addr;
+
+	DEBUGP("Applying relocations in section %u to section %u base=%p\n",
+	       relsec, sym_info, loc_base);
+
+	for (i = 0; i < nrelocs; i++) {
+
+		/* Symbol to relocate */
+		sym = sym_base + ELF32_R_SYM(rela[i].r_info);
+
+		/* Where to make the change */
+		location = loc_base + rela[i].r_offset;
+
+		/* `Everything is relative'. */
+		value = sym->st_value + rela[i].r_addend;
+
+		DEBUGP("%d: value=%08x loc=%p reloc=%d symbol=%s\n",
+		       i, value, location, ELF32_R_TYPE(rela[i].r_info),
+		       sym->st_name ?
+		       &strtab[sym->st_name] : "(anonymous)");
+
+		switch (ELF32_R_TYPE(rela[i].r_info)) {
+		case R_HEXAGON_B22_PCREL: {
+			int dist = (int)(value - (uint32_t)location);
+			if ((dist < -0x00800000) ||
+			    (dist >= 0x00800000)) {
+				printk(KERN_ERR
+				       "%s: %s: %08x=%08x-%08x %s\n",
+				       module->name,
+				       "R_HEXAGON_B22_PCREL reloc out of range",
+				       dist, value, (uint32_t)location,
+				       sym->st_name ?
+				       &strtab[sym->st_name] : "(anonymous)");
+				return -ENOEXEC;
+			}
+			DEBUGP("B22_PCREL contents: %08X.\n", *location);
+			*location &= ~0x01ff3fff;
+			*location |= 0x00003fff & dist;
+			*location |= 0x01ff0000 & (dist<<2);
+			DEBUGP("Contents after reloc: %08x\n", *location);
+			break;
+		}
+		case R_HEXAGON_HI16:
+			value = (value>>16) & 0xffff;
+			/* fallthrough */
+		case R_HEXAGON_LO16:
+			*location &= ~0x00c03fff;
+			*location |= value & 0x3fff;
+			*location |= (value & 0xc000) << 8;
+			break;
+		case R_HEXAGON_32:
+			*location = value;
+			break;
+		case R_HEXAGON_32_PCREL:
+			*location = value - (uint32_t)location;
+			break;
+		case R_HEXAGON_PLT_B22_PCREL:
+		case R_HEXAGON_GOTOFF_LO16:
+		case R_HEXAGON_GOTOFF_HI16:
+			printk(KERN_ERR "%s: GOT/PLT relocations unsupported\n",
+			       module->name);
+			return -ENOEXEC;
+		default:
+			printk(KERN_ERR "%s: unknown relocation: %u\n",
+			       module->name,
+			       ELF32_R_TYPE(rela[i].r_info));
+			return -ENOEXEC;
+		}
+	}
+	return 0;
+}

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#31 lore raw

PATCH v2 14/35 Hexagon: Add signal functions

In reply to Richard Kuo
---
 arch/hexagon/include/asm/sigcontext.h |   32 +++
 arch/hexagon/include/asm/signal.h     |   26 ++
 arch/hexagon/kernel/signal.c          |  325 ++++++++++++++++++++++++++++++++++
 arch/hexagon/kernel/trampoline.S      |   35 +++
 4 files changed, 418 insertions(+)
arch/hexagon/include/asm/sigcontext.h new file +32 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/sigcontext.h
===================================================================
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_SIGCONTEXT_H
+#define _ASM_SIGCONTEXT_H
+
+#include <asm/registers.h>
+
+/*
+ * Signal context structure - contains all info to do with the state
+ * before the signal handler was invoked.
+ */
+struct sigcontext {
+	struct pt_regs sc_regs;
+};
+
+#endif
arch/hexagon/include/asm/signal.h new file +26 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/signal.h
===================================================================
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_SIGNAL_H
+#define _ASM_SIGNAL_H
+
+extern unsigned long __rt_sigtramp_template[2];
+
+#include <asm-generic/signal.h>
+
+#endif
arch/hexagon/kernel/signal.c new file +325 -0

325 lines not on this page · raw message

arch/hexagon/kernel/trampoline.S new file +35 -0
Index: linux-hexagon-kernel/arch/hexagon/kernel/trampoline.S
===================================================================
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/*
+ * Trampoline sequences to be copied onto user stack.
+ * This consumes a little more space than hand-assembling
+ * immediate constants for use in C, but is more portable
+ * to future tweaks to the Hexagon instruction set.
+ */
+
+#include <asm/unistd.h>
+
+/*  Sig trampolines - call sys_sigreturn or sys_rt_sigreturn as appropriate */
+
+/*  plain sigreturn is gone.  */
+
+	.globl __rt_sigtramp_template
+__rt_sigtramp_template:
+	r6 = #__NR_rt_sigreturn;
+	trap0(#1);

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#33 lore raw

PATCH v2 15/35 Hexagon: Add init_task and process functions

In reply to Richard Kuo

Fixed potential race-to-sleep condition in cpu_idle(). I hope.

If called with interrupts disabled, our __vmwait() actually just returns without servicing it. Let me know if there's any other condition that I've missed...

---
 arch/hexagon/kernel/init_task.c |   54 +++++++
 arch/hexagon/kernel/process.c   |  278 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 332 insertions(+)
arch/hexagon/kernel/init_task.c new file +54 -0
Index: linux-hexagon-kernel/arch/hexagon/kernel/init_task.c
===================================================================
@@ -0,0 +1,54 @@
+/*
+ * Init task definition
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init_task.h>
+#include <linux/fs.h>
+#include <linux/mqueue.h>
+#include <asm/thread_info.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is 8192-byte aligned due to the
+ * way process stacks are handled. This is done by making sure
+ * the linker maps this in the .text segment right after head.S,
+ * and making head.S ensure the proper alignment.
+ */
+union thread_union init_thread_union
+	__attribute__((__section__(".data.init_task"),
+		__aligned__(THREAD_SIZE))) = {
+			INIT_THREAD_INFO(init_task)
+		};
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK(init_task);
+EXPORT_SYMBOL(init_task);
arch/hexagon/kernel/process.c new file +278 -0

278 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#34 lore raw

Re: [patch v2 15/35] Hexagon: Add init_task and process functions

Quoted 5 lines · Richard Kuo

Fixed potential race-to-sleep condition in cpu_idle(). I hope.

If called with interrupts disabled, our __vmwait() actually just returns without servicing it. Let me know if there's any other condition that I've missed...

The race should be gone now, but

Quoted 5 lines
arch/hexagon/kernel/process.c new file +5 -0
+void cpu_idle(void)
+{
+	while (1) {
+		tick_nohz_stop_sched_tick(1);
+		local_irq_disable();

arch/hexagon/kernel/process.c line 102

Quoted 10 lines
arch/hexagon/kernel/process.c new file +10 -0
+		while (!need_resched()) {
+			idle_sleep();
+			/*  interrupts wake us up, but aren't serviced  */
+			local_irq_enable();	/* service interrupt   */
+			local_irq_disable();
+		}
+		tick_nohz_restart_sched_tick();
+		schedule();
+	}
+}

you now call schedule() with interrupts disabled, which isn't strictly allowed.

I think it should all be fine if you write it as

	while (1) {
		tick_nohz_stop_sched_tick(1);
		local_irq_disable();
		while (!need_resched()) {
			idle_sleep();
		}
		local_irq_enable();
		tick_nohz_restart_sched_tick();
		schedule();
	}


	Arnd
#35 lore raw

PATCH v2 16/35 Hexagon: Add startup code

In reply to Richard Kuo
---
 arch/hexagon/kernel/head.S  |  162 ++++++++++++++++++++++++++++++++++++++++++++
 arch/hexagon/kernel/reset.c |   38 ++++++++++
 arch/hexagon/kernel/setup.c |  131 +++++++++++++++++++++++++++++++++++
 3 files changed, 331 insertions(+)
arch/hexagon/kernel/head.S new file +162 -0
Index: linux-hexagon-kernel/arch/hexagon/kernel/head.S
===================================================================
@@ -0,0 +1,162 @@
+/*
+ * Early kernel startup code for Hexagon
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/asm-offsets.h>
+#include <asm/mem-layout.h>
+#include <asm/vm_mmu.h>
+#include <asm/page.h>
+
+       	__INIT
+ENTRY(stext)
+	/*
+	 * VMM will already have set up true vector page, MMU, etc.
+	 * To set up initial kernel identity map, we have to pass
+	 * the VMM a pointer to some canonical page tables. In
+	 * this implementation, we're assuming that we've got
+	 * them precompiled. Generate value in R24, as we'll need
+	 * it again shortly.
+	 */
+	r24.L = #LO(swapper_pg_dir)
+	r24.H = #HI(swapper_pg_dir)
+
+	/*
+	 * Symbol is kernel segment address, but we need
+	 * the logical/physical address.
+	 */
+	r24 = asl(r24, #2)
+	r24 = lsr(r24, #2)
+
+	r0 = r24
+
+	/*
+	 * Initialize a 16MB PTE to make the virtual and physical
+	 * addresses where the kernel was loaded be identical.
+	 */
+#define PTE_BITS ( __HVM_PTE_R | __HVM_PTE_W | __HVM_PTE_X	\
+		  | __HEXAGON_C_WB_L2 << 6			\
+		  | __HVM_PDE_S_4MB)
+
+	r1 = pc
+	r2.H = #0xffc0
+	r2.L = #0x0000
+	r1 = and(r1,r2)		/* round PC to 4MB boundary	*/
+	r2 = lsr(r1, #22)	/* 4MB page number		*/
+	r2 = asl(r2, #2)	/* times sizeof(PTE) (4bytes)	*/
+	r0 = add(r0,r2)		/* r0 = address of correct PTE	*/
+	r2 = #PTE_BITS
+	r1 = add(r1,r2)		/* r1 = 4MB PTE for the first entry	*/
+	r2.h = #0x0040
+	r2.l = #0x0000		/* 4MB	*/
+	memw(r0 ++ #4) = r1
+	r1 = add(r1, r2)
+	memw(r0 ++ #4) = r1
+
+	r0 = r24
+
+	/*
+	 * The subroutine wrapper around the virtual instruction touches
+	 * no memory, so we should be able to use it even here.
+	 */
+	call	__vmnewmap;
+
+	/*  Jump into virtual address range.  */
+
+	r31.h = #hi(__head_s_vaddr_target)
+	r31.l = #lo(__head_s_vaddr_target)
+	jumpr r31
+
+	/*  Insert trippy space effects.  */
+
+__head_s_vaddr_target:
+	/*
+	 * Tear down VA=PA translation now that we are running
+	 * in the desgnated kernel segments.
+	 */
+	r0 = #__HVM_PDE_S_INVALID
+	r1 = r24
+	loop0(1f,#0x100)
+1:
+	{
+		memw(R1 ++ #4) = R0
+	}:endloop0
+
+	r0 = r24
+	call __vmnewmap
+
+	/*  Go ahead and install the trap0 return so angel calls work  */
+	r0.h = #hi(_K_provisional_vec)
+	r0.l = #lo(_K_provisional_vec)
+	call __vmsetvec
+
+	/*
+	 * OK, at this point we should start to be much more careful,
+	 * we're going to enter C code and start touching memory
+	 * in all sorts of places.
+	 * This means:
+	 *      SGP needs to be OK
+	 *	Need to lock shared resources
+	 *	A bunch of other things that will cause
+	 * 	all kinds of painful bugs
+	 */
+
+	/*
+	 * Stack pointer should be pointed at the init task's
+	 * thread stack, which should have been declared in arch/init_task.c.
+	 * So uhhhhh...
+	 * It's accessible via the init_thread_union, which is a union
+	 * of a thread_info struct and a stack; of course, the top
+	 * of the stack is not for you.  The end of the stack
+	 * is simply init_thread_union + THREAD_SIZE.
+	 */
+
+	{r29.H = #HI(init_thread_union); r0.H = #HI(_THREAD_SIZE); }
+	{r29.L = #LO(init_thread_union); r0.L = #LO(_THREAD_SIZE); }
+
+	/*  initialize the register used to point to current_thread_info */
+	/*  Fixme:  THREADINFO_REG can't be R2 because of that memset thing. */
+	{r29 = add(r29,r0); THREADINFO_REG = r29; }
+
+	/*  Hack:  zero bss; */
+	{ r0.L = #LO(__bss_start);  r1 = #0; r2.l = #LO(__bss_stop); }
+	{ r0.H = #HI(__bss_start);           r2.h = #HI(__bss_stop); }
+
+	r2 = sub(r2,r0);
+	call memset;
+
+	/* Time to make the doughnuts.   */
+	call start_kernel
+
+	/*
+	 * Should not reach here.
+	 */
+1:
+	jump 1b
+
+.p2align PAGE_SHIFT
+ENTRY(external_cmdline_buffer)
+        .fill _PAGE_SIZE,1,0
+
+.data
+.p2align PAGE_SHIFT
+ENTRY(empty_zero_page)
+        .fill _PAGE_SIZE,1,0
arch/hexagon/kernel/reset.c new file +38 -0
Index: linux-hexagon-kernel/arch/hexagon/kernel/reset.c
===================================================================
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/smp.h>
+#include <asm/hexagon_vm.h>
+
+void machine_power_off(void)
+{
+	smp_send_stop();
+	__vmstop();
+}
+
+void machine_halt(void)
+{
+}
+
+void machine_restart(char *cmd)
+{
+}
+
+void pm_power_off(void)
+{
+}
arch/hexagon/kernel/setup.c new file +131 -0

131 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#37 lore raw

PATCH v2 17/35 Hexagon: Add interrupts

In reply to Richard Kuo
---
 arch/hexagon/include/asm/irq.h |   36 ++++++++++++++++
 arch/hexagon/kernel/irq.c      |   73 +++++++++++++++++++++++++++++++++
 arch/hexagon/kernel/irq_cpu.c  |   90 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 199 insertions(+)
arch/hexagon/include/asm/irq.h new file +36 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/irq.h
===================================================================
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_IRQ_H_
+#define _ASM_IRQ_H_
+
+/* Number of first-level interrupts associated with the CPU core. */
+#define HEXAGON_CPUINTS 32
+
+/*
+ * XXX TODO FIXME this should be pulled from a platform file!
+ * Must define NR_IRQS before including <asm-generic/irq.h>
+ * 64 == the two SIRC's, 176 == the two gpio's
+ */
+#define NR_IRQS (HEXAGON_CPUINTS + 64 + 176)
+
+#include <asm-generic/irq.h>
+
+extern void __init hexagon_cpu_irq_init(void);
+
+#endif
arch/hexagon/kernel/irq.c new file +73 -0

73 lines not on this page · raw message

arch/hexagon/kernel/irq_cpu.c new file +90 -0

90 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

Acked-by on v2 17/35
#38 lore raw

Re: [patch v2 17/35] Hexagon: Add interrupts

Quoted 1 line · Richard Kuo

arch/hexagon/include/asm/irq.h line 30

Quoted 10 lines
arch/hexagon/include/asm/irq.h new file +10 -0
+
+/* Number of first-level interrupts associated with the CPU core. */
+#define HEXAGON_CPUINTS 32
+
+/*
+ * XXX TODO FIXME this should be pulled from a platform file!
+ * Must define NR_IRQS before including <asm-generic/irq.h>
+ * 64 == the two SIRC's, 176 == the two gpio's
+ */
+#define NR_IRQS (HEXAGON_CPUINTS + 64 + 176)

I disagree with that comment: NR_IRQS is a constant and should not be platform specific. There should be no compile-time settings that are strictly specific to one platform, otherwise you are not able to run the same kernel on multiple platforms, which is very valuable for testing purposes.

Just make the constant large enough to always fit. Use sparse IRQs if necessary.

arch/hexagon/include/asm/irq.h line 35

Quoted 4 lines
arch/hexagon/include/asm/irq.h new file +4 -0
+#include <asm-generic/irq.h>
+
+extern void __init hexagon_cpu_irq_init(void);
+

I don't think you actually need to declare hexagon_cpu_irq_init(), just rename that function to init_IRQ() and remove the wrapper.

Arnd

#39 lore raw

Re: [patch v2 17/35] Hexagon: Add interrupts

Quoted 10 lines · Arnd Bergmann

arch/hexagon/include/asm/irq.h line 30

Quoted 6 lines
arch/hexagon/include/asm/irq.h new file +6 -0
+/*
+ * XXX TODO FIXME this should be pulled from a platform file!
+ * Must define NR_IRQS before including <asm-generic/irq.h>
+ * 64 == the two SIRC's, 176 == the two gpio's
+ */
+#define NR_IRQS (HEXAGON_CPUINTS + 64 + 176)

I disagree with that comment: NR_IRQS is a constant and should not be platform specific. There should be no compile-time settings that are strictly specific to one platform, otherwise you are not

OK. The interrupt handling on hexagon really is under construction:
not only do we need to finish support for the device tree, but there's also a bunch of nasty ugliness in how the second & third-level interrupt cntrollers are handled. Some of the difficulties are due the fact that we are re-cycling some of the msm drivers in the arm platform directories. The hexagon and the arm are on the same chip, and see the same controllers, more or less, just with different address ranges and sometimes with different permissions, different pin numberings, etc.

Some of these patches are missing Signed-off-by-me lines, I take full responsibility for all triple-X's that are lingering.

-- Linas

Signature · 2 lines
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
#40 lore raw

PATCH v2 18/35 Hexagon: Add time and timer functions

In reply to Richard Kuo
---
 arch/hexagon/include/asm/time.h       |   27 +++
 arch/hexagon/include/asm/timer-regs.h |   39 ++++
 arch/hexagon/kernel/time.c            |  283 ++++++++++++++++++++++++++++++++++
 3 files changed, 349 insertions(+)
arch/hexagon/include/asm/time.h new file +27 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/time.h
===================================================================
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef ASM_TIME_H
+#define ASM_TIME_H
+
+#ifdef CONFIG_SMP
+void setup_percpu_clockdev(void);
+void ipi_timer(void);
+#endif
+
+#endif
arch/hexagon/include/asm/timer-regs.h new file +39 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/timer-regs.h
===================================================================
@@ -0,0 +1,39 @@
+/*
+ * Timer support for Hexagon
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_TIMER_REGS_H
+#define _ASM_TIMER_REGS_H
+
+/*  This stuff should go into a platform specific file  */
+#define TCX0_CLK_RATE		19200
+#define TIMER_ENABLE		0
+#define TIMER_CLR_ON_MATCH	1
+
+/*
+ * 8x50 HDD Specs 5-8.  Simulator co-sim not fixed until
+ * release 1.1, and then it's "adjustable" and probably not defaulted.
+ */
+#define RTOS_TIMER_INT		3
+#ifdef CONFIG_HEXAGON_COMET
+#define RTOS_TIMER_REGS_ADDR	0xAB000000UL
+#endif
+#define SLEEP_CLK_RATE		32000
+
+#endif
arch/hexagon/kernel/time.c new file +283 -0

283 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#41 lore raw

Re: [patch v2 18/35] Hexagon: Add time and timer functions

arch/hexagon/include/asm/time.h line 25

Quoted 6 lines · Richard Kuo
arch/hexagon/include/asm/time.h new file +4 -0
+#ifdef CONFIG_SMP
+void setup_percpu_clockdev(void);
+void ipi_timer(void);
+#endif

You should never need to wrap declarations with #ifdef like this.

arch/hexagon/include/asm/timer-regs.h line 27

Quoted 8 lines
arch/hexagon/include/asm/timer-regs.h new file +8 -0
+
+#ifndef _ASM_TIMER_REGS_H
+#define _ASM_TIMER_REGS_H
+
+/*  This stuff should go into a platform specific file  */
+#define TCX0_CLK_RATE		19200
+#define TIMER_ENABLE		0
+#define TIMER_CLR_ON_MATCH	1

Same comment as for NR_IRQS. If this is platform specific, it should not be a compile-time constant.

arch/hexagon/kernel/time.c line 47

Quoted 13 lines
arch/hexagon/kernel/time.c new file +13 -0
+/*
+ * For now, hard wire the simulated CPU/pcycle frequency.
+ * XXX TODO fish it out of device tree!
+ */
+#define CPU_MHZ 600
+
+static struct resource rtos_timer_resources[] = {
+       {
+               .start  = RTOS_TIMER_REGS_ADDR,
+               .end    = RTOS_TIMER_REGS_ADDR+PAGE_SIZE-1,
+               .flags  = IORESOURCE_MEM,
+       },
+};

Yes, please do get it out of the device tree before merging the driver upstream.

arch/hexagon/kernel/time.c line 65

Quoted 10 lines
arch/hexagon/kernel/time.c new file +10 -0
+/*  A lot of this stuff should move into a platform specific section.  */
+struct adsp_hw_timer_struct {
+	unsigned int match;   /*  Match value  */
+	unsigned int count;
+	unsigned int enable;  /*  [1] - CLR_ON_MATCH_EN, [0] - EN  */
+	unsigned int clear;   /*  one-shot register that clears the count  */
+};
+
+/*  Look for "TCX0" for related constants.  */
+static volatile struct adsp_hw_timer_struct *rtos_timer = (void *) 0x0;

There are multiple things wrong with this:

* No need to initialize static variables to zero

* This is an MMIO register, so the pointer must be "__iomem", not "volatile", see Documentation/volatile-considered-harmful.txt

* You should have found this when building with 'make C=1' using sparse. I would hope that all your code was compiled this way to find common errors. If not, please do so now.

* Use u32 instead of unsigned int when describing hardware structures. They are always identical, but u32 is more descriptive. Alternatively, use no structure at all but constant register numbers.

arch/hexagon/kernel/time.c line 134

Quoted 12 lines
arch/hexagon/kernel/time.c new file +12 -0
+static struct clock_event_device hexagon_clockevent_dev = {
+	.name		= "clockevent",
+	.features	= CLOCK_EVT_FEAT_ONESHOT,
+	.rating		= 400,
+	.shift		= 32,
+	.irq		= RTOS_TIMER_INT,
+	.set_next_event = set_next_event,
+	.set_mode	= set_mode,
+#ifdef CONFIG_SMP
+	.broadcast	= broadcast
+#endif
+};

Always put a comma at the last entry, to allow adding more members as necessary.

Quoted 12 lines
arch/hexagon/kernel/time.c new file +12 -0
+/*
+ * time_init_deferred - called by start_kernel to set up timer/clock source
+ *
+ * Install the IRQ handler for the clock, setup timers.
+ * This is done late, as that way, we can use ioremap().
+ *
+ * This runs just before the delay loop is calibrated, and
+ * is used for delay calibration.
+ */
+void __init time_init_deferred(void)
+{
+	struct resource *resource = NULL;

arch/hexagon/kernel/time.c line 217

Quoted 10 lines
arch/hexagon/kernel/time.c new file +10 -0
+	struct clock_event_device *ce_dev = &hexagon_clockevent_dev;
+	struct device_node *dn;
+	struct resource r;
+	int err;
+
+#ifdef CONFIG_SMP
+	ce_dev->cpumask = cpu_all_mask;
+#else
+	ce_dev->cpumask = cpumask_of(0);
+#endif

No need for the #ifdef AFAICT, because the two cases are the same.

arch/hexagon/kernel/time.c line 224

Quoted 6 lines
arch/hexagon/kernel/time.c new file +6 -0
+	if (!resource)
+		resource = rtos_timer_device.resource;
+
+	/*  ioremap here means this has to run later, after paging init  */
+	rtos_timer = ioremap(resource->start, resource->end
+		- resource->start + 1);

When the device is in the device tree, you can simplify this a lot by using of_iomap().

arch/hexagon/kernel/time.c line 282

Quoted 8 lines
arch/hexagon/kernel/time.c new file +8 -0
+void __udelay(unsigned long usecs)
+{
+	unsigned long long start = __vmgettime();
+	unsigned long long finish = (CPU_MHZ * usecs) - fudgefactor;
+
+	while ((__vmgettime() - start) < finish)
+		; /*  not sure how this improves readability  */
+}

Better use cpu_relax() or a direct hypervisor yield call here instead of the ';'. It should improve both readability and power consumption during long delays.

Arnd

#42 lore raw

PATCH v2 19/35 Hexagon: Add ptrace support

In reply to Richard Kuo
---
 arch/hexagon/include/asm/ptrace.h |   46 +++++
 arch/hexagon/kernel/ptrace.c      |  333 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 379 insertions(+)
arch/hexagon/include/asm/ptrace.h new file +46 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/ptrace.h
===================================================================
@@ -0,0 +1,46 @@
+/*
+ * Ptrace definitions for the Hexagon architecture
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_PTRACE_H
+#define _ASM_PTRACE_H
+
+#include <asm/registers.h>
+
+/*  arch_ptrace and ptrace_disable use task_struct in arg lists  */
+struct task_struct;
+
+/*
+ * ptrace commands not part of Linux base set (but common to essentially
+ * all supported architectures).
+ */
+
+#define PTRACE_GETREGS	12
+#define PTRACE_SETREGS	13
+
+#define N_PTRACE_REGS	44
+
+#define profile_pc(regs) instruction_pointer(regs)
+#define instruction_pointer(regs) pt_elr(regs)
+
+/* kprobe-based event tracer support */
+extern int regs_query_register_offset(const char *name);
+extern const char *regs_query_register_name(unsigned int offset);
+
+#endif
arch/hexagon/kernel/ptrace.c new file +333 -0

333 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#43 lore raw

Re: [patch v2 19/35] Hexagon: Add ptrace support

Quoted 7 lines · Richard Kuo
arch/hexagon/kernel/ptrace.c new file +7 -0
+
+       switch (request) {
+       case PTRACE_POKETEXT:   /* write the word at location addr. */
+       case PTRACE_POKEDATA:
+               return generic_ptrace_pokedata(child, addr, data);
+       case PTRACE_POKEUSR:    /* write register specified by addr. */
+               return ptrace_pokeusr(child, addr, data);

arch/hexagon/kernel/ptrace.c line 327

Quoted 10 lines
arch/hexagon/kernel/ptrace.c new file +10 -0
+       case PTRACE_GETREGS:
+               return copy_regset_to_user(child, &hexagon_user_view,
+                                          REGSET_GPR, 0,
+                                          sizeof(struct user_regs_struct),
+                                          udata);
+       case PTRACE_SETREGS:
+               return copy_regset_from_user(child, &hexagon_user_view,
+                                            REGSET_GPR, 0,
+                                            sizeof(struct user_regs_struct),
+                                            udata);

I don't remember if I commented on this or if it was for the c6x architecture submission. Anyway, I think you should let all of this be handled through the generic ptrace support like openrisc does.

Arnd

#44 lore raw

PATCH v2 20/35 Hexagon: Provide basic debugging and system trap support.

In reply to Richard Kuo
---
 arch/hexagon/include/asm/traps.h |   29 +++
 arch/hexagon/kernel/traps.c      |  356 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 385 insertions(+)
arch/hexagon/kernel/traps.c new file +356 -0
Index: linux-hexagon-kernel/arch/hexagon/kernel/traps.c
===================================================================
@@ -0,0 +1,356 @@
+/*
+ * Kernel traps/events for Hexagon processor
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+#include <linux/kdebug.h>
+#include <linux/syscalls.h>
+#include <linux/signal.h>
+#include <linux/tracehook.h>
+#include <asm/traps.h>
+#include <asm/vm_fault.h>
+#include <asm/syscall.h>
+#include <asm/registers.h>
+#include <asm/unistd.h>
+#ifdef CONFIG_KGDB
+# include <linux/kgdb.h>
+#endif
+
+#define TRAP_SYSCALL	1
+#define TRAP_DEBUG	0xdb
+
+void __init trap_init(void)
+{
+}
+
+#ifdef CONFIG_GENERIC_BUG
+/* Maybe should resemble arch/sh/kernel/traps.c ?? */
+int is_valid_bugaddr(unsigned long addr)
+{
+	return 1;
+}
+#endif /* CONFIG_GENERIC_BUG */
+
+void show_stack(struct task_struct *task, unsigned long *fp)
+{
+	int kstack_depth_to_print = 20;
+	unsigned long offset, size;
+	const char *name = NULL;
+	unsigned long *newfp;
+	unsigned long ip;
+	char tmpstr[128];
+	char *modname;
+	int i;
+
+	if (task == NULL)
+		task = current;
+
+	if (fp == NULL) {
+		if (task == current) {
+			asm("%0 = r30" : "=r" (fp));
+		} else {
+			fp = (unsigned long *)
+			     ((struct hexagon_switch_stack *)
+			     task->thread.switch_sp)->fp;
+		}
+	}
+
+	printk(KERN_INFO "CPU#%d, %s/%d, Call Trace:\n",
+	       raw_smp_processor_id(), current->comm,
+	       task_pid_nr(current));
+	for (i = 0; i < kstack_depth_to_print; i++) {
+		if (0 /* Check irq stack at some point */)
+			printk(KERN_INFO " <EOI> ");
+		else if (((long) fp & (THREAD_SIZE-1)) == 0)
+			break;
+
+		newfp = (unsigned long *) *fp;
+
+		ip = *(unsigned long *)((char *)fp + sizeof(unsigned long));
+		name = kallsyms_lookup(ip, &size, &offset, &modname, tmpstr);
+
+		printk(KERN_INFO "[%p] 0x%lx: %s + 0x%lx", fp, ip, name,
+			offset);
+		if (modname)
+			printk(KERN_CONT " [%s] ", modname);
+		if (i == 0)
+			printk(KERN_CONT " (unreliable)");
+		printk(KERN_CONT "\n");
+
+		/* If newfp isn't larger, we're tracing garbage */
+		if (newfp > fp)
+			fp = newfp;
+		else
+			break;
+	}
+}
+
+void dump_state(struct pt_regs *regs)
+{
+	show_regs(regs);
+	show_stack(current, &regs->r30);
+}
+
+void dump_stack(void)
+{
+	show_stack(current, NULL);
+}
+EXPORT_SYMBOL(dump_stack);
+
+int die(const char *str, struct pt_regs *regs, long err)
+{
+	static struct {
+		spinlock_t lock;
+		int counter;
+	} die = {
+		.lock = __SPIN_LOCK_UNLOCKED(die.lock),
+		.counter = 0
+	};
+
+	spin_lock_irq(&die.lock);
+	bust_spinlocks(1);
+	printk(KERN_INFO "%s[#%d]:\n", str, ++die.counter);
+
+	if (notify_die(DIE_OOPS, str, regs, err, pt_cause(regs), SIGSEGV) ==
+	    NOTIFY_STOP)
+		return 1;
+
+	print_modules();
+	dump_state(regs);
+
+	do_exit(err);
+	return 0;
+}
+
+int die_if_kernel(char *str, struct pt_regs *regs, long err)
+{
+	if (!user_mode(regs))
+		return die(str, regs, err);
+	else
+		return 0;
+}
+
+/*
+ * It's not clear that misaligned fetches are ever recoverable.
+ */
+static void misaligned_instruction(struct pt_regs *regs)
+{
+	die_if_kernel("Misaligned Instruction", regs, 0);
+	force_sig(SIGBUS, current);
+}
+
+/*
+ * Misaligned loads and stores, on the other hand, can be
+ * emulated, and probably should be, some day.  But for now
+ * they will be considered fatal.
+ */
+static void misaligned_data_load(struct pt_regs *regs)
+{
+	die_if_kernel("Misaligned Data Load", regs, 0);
+	force_sig(SIGBUS, current);
+}
+
+static void misaligned_data_store(struct pt_regs *regs)
+{
+	die_if_kernel("Misaligned Data Store", regs, 0);
+	force_sig(SIGBUS, current);
+}
+
+static void illegal_instruction(struct pt_regs *regs)
+{
+	die_if_kernel("Illegal Instruction", regs, 0);
+	force_sig(SIGILL, current);
+}
+
+/*
+ * Precise bus errors may be recoverable with a a retry,
+ * but for now, treat them as irrecoverable.
+ */
+static void precise_bus_error(struct pt_regs *regs)
+{
+	die_if_kernel("Precise Bus Error", regs, 0);
+	force_sig(SIGBUS, current);
+}
+
+/*
+ * If anything is to be done here other than panic,
+ * it will probably be complex and migrate to another
+ * source module.  For now, just die.
+ */
+static void cache_error(struct pt_regs *regs)
+{
+	die("Cache Error", regs, 0);
+}
+
+/*
+ * General exception handler
+ */
+void do_genex(struct pt_regs *regs)
+{
+
+	/*
+	 * Decode Cause and Dispatch
+	 */
+	switch (pt_cause(regs)) {
+	case HVM_GE_C_XPROT:
+	case HVM_GE_C_XUSER:
+		execute_protection_fault(regs);
+		break;
+	case HVM_GE_C_RPROT:
+	case HVM_GE_C_RUSER:
+		read_protection_fault(regs);
+		break;
+	case HVM_GE_C_WPROT:
+	case HVM_GE_C_WUSER:
+		write_protection_fault(regs);
+		break;
+	case HVM_GE_C_XMAL:
+		misaligned_instruction(regs);
+		break;
+	case HVM_GE_C_RMAL:
+		misaligned_data_load(regs);
+		break;
+	case HVM_GE_C_WMAL:
+		misaligned_data_store(regs);
+		break;
+	case HVM_GE_C_INVI:
+	case HVM_GE_C_PRIVI:
+		illegal_instruction(regs);
+		break;
+	case HVM_GE_C_BUS:
+		precise_bus_error(regs);
+		break;
+	case HVM_GE_C_CACHE:
+		cache_error(regs);
+		break;
+	default:
+		/* Halt and catch fire */
+		panic("Unrecognized exception 0x%lx\n", pt_cause(regs));
+		break;
+	}
+}
+
+/* Indirect system call dispatch */
+long sys_syscall(void)
+{
+	printk(KERN_ERR "sys_syscall invoked!\n");
+	return -ENOSYS;
+}
+
+void do_trap0(struct pt_regs *regs)
+{
+	unsigned long syscallret = 0;
+	syscall_fn syscall;
+
+	switch (pt_cause(regs)) {
+	case TRAP_SYSCALL:
+		/* System call is trap0 #1 */
+
+		/* allow strace to catch syscall args  */
+		if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE) &&
+			tracehook_report_syscall_entry(regs)))
+			return;  /*  return -ENOSYS somewhere?  */
+
+		/* Interrupts should be re-enabled for syscall processing */
+		__vmsetie(VM_INT_ENABLE);
+
+		/*
+		 * System call number is in r6, arguments in r0..r5.
+		 * Fortunately, no Linux syscall has more than 6 arguments,
+		 * and Hexagon ABI passes first 6 arguments in registers.
+		 * 64-bit arguments are passed in odd/even register pairs.
+		 * Fortunately, we have no system calls that take more
+		 * than three arguments with more than one 64-bit value.
+		 * Should that change, we'd need to redesign to copy
+		 * between user and kernel stacks.
+		 */
+		regs->syscall_nr = regs->r06;
+
+		/*
+		 * GPR R0 carries the first parameter, and is also used
+		 * to report the return value.  We need a backup of
+		 * the user's value in case we need to do a late restart
+		 * of the system call.
+		 */
+		regs->restart_r0 = regs->r00;
+
+		if ((unsigned long) regs->syscall_nr >= __NR_syscalls) {
+			regs->r00 = -1;
+		} else {
+			syscall = (syscall_fn)
+				  (sys_call_table[regs->syscall_nr]);
+			syscallret = syscall(regs->r00, regs->r01,
+				   regs->r02, regs->r03,
+				   regs->r04, regs->r05);
+		}
+
+		/*
+		 * If it was a sigreturn system call, don't overwrite
+		 * r0 value in stack frame with return value.
+		 *
+		 * __NR_sigreturn doesn't seem to exist in new unistd.h
+		 */
+
+		if (regs->syscall_nr != __NR_rt_sigreturn)
+			regs->r00 = syscallret;
+
+		/* allow strace to get the syscall return state  */
+		if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE)))
+			tracehook_report_syscall_exit(regs, 0);
+
+		break;
+	case TRAP_DEBUG:
+		/* Trap0 0xdb is debug breakpoint */
+		if (user_mode(regs)) {
+			struct siginfo info;
+
+			info.si_signo = SIGTRAP;
+			info.si_errno = 0;
+			/*
+			 * Some architecures add some per-thread state
+			 * to distinguish between breakpoint traps and
+			 * trace traps.  We may want to do that, and
+			 * set the si_code value appropriately, or we
+			 * may want to use a different trap0 flavor.
+			 */
+			info.si_code = TRAP_BRKPT;
+			info.si_addr = (void __user *) pt_elr(regs);
+			send_sig_info(SIGTRAP, &info, current);
+		} else {
+#ifdef CONFIG_KGDB
+			kgdb_handle_exception(pt_cause(regs), SIGTRAP,
+					      TRAP_BRKPT, regs);
+#endif
+		}
+		break;
+	}
+	/* Ignore other trap0 codes for now, especially 0 (Angel calls) */
+}
+
+/*
+ * Machine check exception handler
+ */
+void do_machcheck(struct pt_regs *regs)
+{
+	/* Halt and catch fire */
+	__vmstop();
+}
arch/hexagon/include/asm/traps.h new file +29 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/traps.h
===================================================================
@@ -0,0 +1,29 @@
+/*
+ * Trap support for Hexagon
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_HEXAGON_TRAPS_H
+#define _ASM_HEXAGON_TRAPS_H
+
+#include <asm/registers.h>
+
+extern int die(const char *str, struct pt_regs *regs, long err);
+extern int die_if_kernel(char *str, struct pt_regs *regs, long err);
+
+#endif /* _ASM_HEXAGON_TRAPS_H */

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#46 lore raw

PATCH v2 21/35 Hexagon: Add SMP support

In reply to Richard Kuo
---
 arch/hexagon/include/asm/smp.h |   40 ++++
 arch/hexagon/kernel/smp.c      |  365 +++++++++++++++++++++++++++++++++++++++++
 arch/hexagon/kernel/topology.c |   52 +++++
 3 files changed, 457 insertions(+)
arch/hexagon/include/asm/smp.h new file +40 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/smp.h
===================================================================
@@ -0,0 +1,40 @@
+/*
+ * SMP definitions for the Hexagon architecture
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __ASM_SMP_H
+#define __ASM_SMP_H
+
+#include <linux/cpumask.h>
+
+#define raw_smp_processor_id() (current_thread_info()->cpu)
+
+enum ipi_message_type {
+	IPI_RESCHEDULE,
+	IPI_CALL_FUNC,
+	IPI_CPU_STOP,
+	IPI_TIMER
+};
+
+extern void send_ipi(const struct cpumask *cpumask, enum ipi_message_type msg);
+extern void smp_start_cpus(void);
+
+void smp_vm_unmask_irq(void *info);
+
+#endif
arch/hexagon/kernel/smp.c new file +365 -0

365 lines not on this page · raw message

arch/hexagon/kernel/topology.c new file +52 -0

52 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#47 lore raw

Re: [patch v2 21/35] Hexagon: Add SMP support

Quoted 2 lines · Richard Kuo

plain text document attachment (smp.diff)

[]

arch/hexagon/kernel/smp.c line 68

Quoted 5 lines
arch/hexagon/kernel/smp.c new file +5 -0
+static inline void __handle_ipi(unsigned long *ops, struct ipi_data *ipi,
+				int cpu)
+{
+	do {
+		unsigned long msg = msg = ffz(~*ops);

Really? That's unlikely to be the right code.
Maybe just one msg?

Quoted 4 lines
arch/hexagon/kernel/smp.c new file +4 -0
+
+		*ops &= ~(1 << msg);
+
+		switch (msg) {

arch/hexagon/kernel/smp.c line 81

Quoted 10 lines
arch/hexagon/kernel/smp.c new file +9 -0
+		case IPI_TIMER:
+			ipi_timer();
+			break;
+		case IPI_CALL_FUNC:
+		{
 
+			struct smp_call_struct *data =
+				smp_call_function_data;
+			void (*func) (void *info) =
+				data->func;

No need to wrap either of these.

arch/hexagon/kernel/smp.c line 93

Quoted 12 lines
arch/hexagon/kernel/smp.c new file +12 -0
+			void *info = data->info;
+			int wait = data->wait;
+
+			smp_mb();
+			cpumask_clear_cpu(cpu, &data->pending);
+
+			(*func)(info);
+
+			smp_mb();
+			if (wait)
+				cpumask_clear_cpu(cpu,
+					&data->unfinished);

or here.

#48 lore raw

Re: [patch v2 21/35] Hexagon: Add SMP support

Quoted 4 lines · Joe Perches

arch/hexagon/kernel/smp.c line 68

Quoted 1 line
arch/hexagon/kernel/smp.c new file +1 -0
+		unsigned long msg = msg = ffz(~*ops);

Really? That's unlikely to be the right code.
Maybe just one msg?

Whoah, you're right. Although the code does actually work. Just need one msg though.

Quoted 4 lines

arch/hexagon/kernel/smp.c line 81

Quoted 2 lines
arch/hexagon/kernel/smp.c new file +2 -0
+			void (*func) (void *info) =
+				data->func;

No need to wrap either of these.

OK, fixed.

Thanks,
Richard Kuo

Signature · 2 lines
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
#50 lore raw

PATCH v2 22/35 Hexagon: Add locking types and functions

In reply to Richard Kuo

We pretty much just reused the PPC version of rwsem.h. Spinlocks use ll/sc.

---
 arch/hexagon/include/asm/rwsem.h          |  132 +++++++++++++++++++++
 arch/hexagon/include/asm/spinlock.h       |  186 ++++++++++++++++++++++++++++++
 arch/hexagon/include/asm/spinlock_types.h |   42 ++++++
 3 files changed, 360 insertions(+)
arch/hexagon/include/asm/rwsem.h new file +132 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/rwsem.h
===================================================================
@@ -0,0 +1,132 @@
+#ifndef _ASM_POWERPC_RWSEM_H
+#define _ASM_POWERPC_RWSEM_H
+
+#ifndef _LINUX_RWSEM_H
+#error "Please don't include <asm/rwsem.h> directly, use <linux/rwsem.h> instead."
+#endif
+
+#ifdef __KERNEL__
+
+/*
+ * R/W semaphores for PPC using the stuff in lib/rwsem.c.
+ * Adapted largely from include/asm-i386/rwsem.h
+ * by Paul Mackerras <[email protected]>.
+ */
+
+/*
+ * the semaphore definition
+ */
+#ifdef CONFIG_PPC64
+# define RWSEM_ACTIVE_MASK		0xffffffffL
+#else
+# define RWSEM_ACTIVE_MASK		0x0000ffffL
+#endif
+
+#define RWSEM_UNLOCKED_VALUE		0x00000000L
+#define RWSEM_ACTIVE_BIAS		0x00000001L
+#define RWSEM_WAITING_BIAS		(-RWSEM_ACTIVE_MASK-1)
+#define RWSEM_ACTIVE_READ_BIAS		RWSEM_ACTIVE_BIAS
+#define RWSEM_ACTIVE_WRITE_BIAS		(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
+
+/*
+ * lock for reading
+ */
+static inline void __down_read(struct rw_semaphore *sem)
+{
+	if (unlikely(atomic_long_inc_return((atomic_long_t *)&sem->count) <= 0))
+		rwsem_down_read_failed(sem);
+}
+
+static inline int __down_read_trylock(struct rw_semaphore *sem)
+{
+	long tmp;
+
+	while ((tmp = sem->count) >= 0) {
+		if (tmp == cmpxchg(&sem->count, tmp,
+				   tmp + RWSEM_ACTIVE_READ_BIAS)) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/*
+ * lock for writing
+ */
+static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
+{
+	long tmp;
+
+	tmp = atomic_long_add_return(RWSEM_ACTIVE_WRITE_BIAS,
+				     (atomic_long_t *)&sem->count);
+	if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS))
+		rwsem_down_write_failed(sem);
+}
+
+static inline void __down_write(struct rw_semaphore *sem)
+{
+	__down_write_nested(sem, 0);
+}
+
+static inline int __down_write_trylock(struct rw_semaphore *sem)
+{
+	long tmp;
+
+	tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
+		      RWSEM_ACTIVE_WRITE_BIAS);
+	return tmp == RWSEM_UNLOCKED_VALUE;
+}
+
+/*
+ * unlock after reading
+ */
+static inline void __up_read(struct rw_semaphore *sem)
+{
+	long tmp;
+
+	tmp = atomic_long_dec_return((atomic_long_t *)&sem->count);
+	if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0))
+		rwsem_wake(sem);
+}
+
+/*
+ * unlock after writing
+ */
+static inline void __up_write(struct rw_semaphore *sem)
+{
+	if (unlikely(atomic_long_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
+				 (atomic_long_t *)&sem->count) < 0))
+		rwsem_wake(sem);
+}
+
+/*
+ * implement atomic add functionality
+ */
+static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
+{
+	atomic_long_add(delta, (atomic_long_t *)&sem->count);
+}
+
+/*
+ * downgrade write lock to read lock
+ */
+static inline void __downgrade_write(struct rw_semaphore *sem)
+{
+	long tmp;
+
+	tmp = atomic_long_add_return(-RWSEM_WAITING_BIAS,
+				     (atomic_long_t *)&sem->count);
+	if (tmp < 0)
+		rwsem_downgrade_wake(sem);
+}
+
+/*
+ * implement exchange and add functionality
+ */
+static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
+{
+	return atomic_long_add_return(delta, (atomic_long_t *)&sem->count);
+}
+
+#endif	/* __KERNEL__ */
+#endif	/* _ASM_POWERPC_RWSEM_H */
arch/hexagon/include/asm/spinlock.h new file +186 -0

186 lines not on this page · raw message

arch/hexagon/include/asm/spinlock_types.h new file +42 -0

42 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#51 lore raw

Re: [patch v2 22/35] Hexagon: Add locking types and functions

Quoted 9 lines · Richard Kuo

We pretty much just reused the PPC version of rwsem.h. Spinlocks use ll/sc.

---
 arch/hexagon/include/asm/rwsem.h          |  132 +++++++++++++++++++++
 arch/hexagon/include/asm/spinlock.h       |  186 ++++++++++++++++++++++++++++++
 arch/hexagon/include/asm/spinlock_types.h |   42 ++++++
 3 files changed, 360 insertions(+)

If you have reused an existing version of the rwsem.h file, please move that into asm-generic and change powerpc and hexagon to just use it from there.

Arnd

#52 lore raw

PATCH v2 23/35 Hexagon: Add user access functions

In reply to Richard Kuo
---
 arch/hexagon/include/asm/uaccess.h   |  116 +++++++++++++++++++++
 arch/hexagon/mm/copy_from_user.S     |  114 +++++++++++++++++++++
 arch/hexagon/mm/copy_to_user.S       |   92 +++++++++++++++++
 arch/hexagon/mm/copy_user_template.S |  185 +++++++++++++++++++++++++++++++++++
 arch/hexagon/mm/strnlen_user.S       |  140 ++++++++++++++++++++++++++
 arch/hexagon/mm/uaccess.c            |   59 +++++++++++
 6 files changed, 706 insertions(+)
arch/hexagon/include/asm/uaccess.h new file +116 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/uaccess.h
===================================================================
@@ -0,0 +1,116 @@
+/*
+ * User memory access support for Hexagon
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_UACCESS_H
+#define _ASM_UACCESS_H
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/segment.h>
+#include <asm/sections.h>
+
+/*
+ * access_ok: - Checks if a user space pointer is valid
+ * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE.  Note that
+ *        %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
+ *        to write to a block, it is always safe to read from it.
+ * @addr: User space pointer to start of block to check
+ * @size: Size of block to check
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * Checks if a pointer to a block of memory in user space is valid.
+ *
+ * Returns true (nonzero) if the memory block *may* be valid, false (zero)
+ * if it is definitely invalid.
+ *
+ * User address space in Hexagon, like x86, goes to 0xbfffffff, so the
+ * simple MSB-based tests used by MIPS won't work.  Some further
+ * optimization is probably possible here, but for now, keep it
+ * reasonably simple and not *too* slow.  After all, we've got the
+ * MMU for backup.
+ */
+#define VERIFY_READ     0
+#define VERIFY_WRITE    1
+
+#define __access_ok(addr, size) \
+	((get_fs().seg == KERNEL_DS.seg) || \
+	(((unsigned long)addr < get_fs().seg) && \
+	  (unsigned long)size < (get_fs().seg - (unsigned long)addr)))
+
+/*
+ * When a kernel-mode page fault is taken, the faulting instruction
+ * address is checked against a table of exception_table_entries.
+ * Each entry is a tuple of the address of an instruction that may
+ * be authorized to fault, and the address at which execution should
+ * be resumed instead of the faulting instruction, so as to effect
+ * a workaround.
+ */
+
+/*  Assembly somewhat optimized copy routines  */
+unsigned long __copy_from_user_hexagon(void *to, const void __user *from,
+				     unsigned long n);
+unsigned long __copy_to_user_hexagon(void __user *to, const void *from,
+				   unsigned long n);
+
+#define __copy_from_user(to, from, n) __copy_from_user_hexagon(to, from, n)
+#define __copy_to_user(to, from, n) __copy_to_user_hexagon(to, from, n)
+
+/*
+ * XXX todo: some additonal performance gain is possible by
+ * implementing __copy_to/from_user_inatomic, which is much
+ * like __copy_to/from_user, but performs slightly less checking.
+ */
+
+__kernel_size_t __clear_user_hexagon(void __user *dest, unsigned long count);
+#define __clear_user(a, s) __clear_user_hexagon((a), (s))
+
+#define __strncpy_from_user(dst, src, n) hexagon_strncpy_from_user(dst, src, n)
+
+/*  get around the ifndef in asm-generic/uaccess.h  */
+#define __strnlen_user __strnlen_user
+
+extern long __strnlen_user(const char __user *src, long n);
+
+static inline long hexagon_strncpy_from_user(char *dst, const char __user *src,
+					     long n);
+
+#include <asm-generic/uaccess.h>
+
+/*  Todo:  an actual accelerated version of this.  */
+static inline long hexagon_strncpy_from_user(char *dst, const char __user *src,
+					     long n)
+{
+	long res = __strnlen_user(src, n);
+
+	/* return from strnlen can't be zero -- that would be rubbish. */
+
+	if (res > n) {
+		copy_from_user(dst, src, n);
+		return n;
+	} else {
+		copy_from_user(dst, src, res);
+		return res-1;
+	}
+}
+
+#endif
arch/hexagon/mm/copy_from_user.S new file +114 -0

114 lines not on this page · raw message

arch/hexagon/mm/copy_to_user.S new file +92 -0

92 lines not on this page · raw message

arch/hexagon/mm/copy_user_template.S new file +185 -0

185 lines not on this page · raw message

arch/hexagon/mm/uaccess.c new file +59 -0

59 lines not on this page · raw message

arch/hexagon/mm/strnlen_user.S new file +140 -0

140 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#54 lore raw

PATCH v2 24/35 Hexagon: Provide basic implementation and/or stubs for I/O routines.

In reply to Richard Kuo

Changed read/write to use inline assembly.

Rearranged the file and put all the ioport stuff at the bottom. For now I'd like to just leave the stubs in there in case they need to be filled out later; plus things don't compile.

We still seem to need IO_SPACE_LIMIT to be defined, particularly to something large, as we have drivers that request resources with IORESOURCE_IO that are memory mapped IO. The ioread/iowrites work as they select the correct routine to use.

---
 arch/hexagon/include/asm/io.h |  297 ++++++++++++++++++++++++++++++++++++++++++
 arch/hexagon/lib/io.c         |   91 ++++++++++++
 2 files changed, 388 insertions(+)
arch/hexagon/include/asm/io.h new file +297 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/io.h
===================================================================
@@ -0,0 +1,297 @@
+/*
+ * IO definitions for the Hexagon architecture
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/vmalloc.h>
+#include <asm/string.h>
+#include <asm/mem-layout.h>
+#include <asm/iomap.h>
+#include <asm/page.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+
+/*
+ * We don't have PCI yet.
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+#define _IO_BASE 0x0
+
+extern int remap_area_pages(unsigned long start, unsigned long phys_addr,
+				unsigned long end, unsigned long flags);
+
+extern void __iounmap(const volatile void __iomem *addr);
+
+/* Defined in lib/io.c, needed for smc91x driver. */
+extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen);
+extern void __raw_writesw(void __iomem *addr, const void *data, int wordlen);
+
+extern void __raw_readsl(const void __iomem *addr, void *data, int wordlen);
+extern void __raw_writesl(void __iomem *addr, const void *data, int wordlen);
+
+#define readsw(p, d, l)	__raw_readsw(p, d, l)
+#define writesw(p, d, l) __raw_writesw(p, d, l)
+
+#define readsl(p, d, l)   __raw_readsl(p, d, l)
+#define writesl(p, d, l)  __raw_writesl(p, d, l)
+
+/*
+ * virt_to_phys - map virtual address to physical
+ * @address:  address to map
+ */
+static inline unsigned long virt_to_phys(volatile void *address)
+{
+	return __pa(address);
+}
+
+/*
+ * phys_to_virt - map physical address to virtual
+ * @address: address to map
+ */
+static inline void *phys_to_virt(unsigned long address)
+{
+	return __va(address);
+}
+
+/*
+ * convert a physical pointer to a virtual kernel pointer for
+ * /dev/mem access.
+ */
+#define xlate_dev_kmem_ptr(p)    __va(p)
+#define xlate_dev_mem_ptr(p)    __va(p)
+
+/*
+ * IO port access primitives.  Hexagon doesn't have special IO access
+ * instructions; all I/O is memory mapped.
+ *
+ * in/out are used for "ports", but we don't have "port instructions",
+ * so these are really just memory mapped too.
+ */
+
+/*
+ * readb - read byte from memory mapped device
+ * @addr:  pointer to memory
+ *
+ * Operates on "I/O bus memory space"
+ */
+static inline u8 readb(const volatile void __iomem *addr)
+{
+	u8 val;
+	asm volatile(
+		"%0 = memb(%1);"
+		: "=&r" (val)
+		: "r" (addr)
+	);
+	return val;
+}
+
+static inline u16 readw(const volatile void __iomem *addr)
+{
+	u16 val;
+	asm volatile(
+		"%0 = memh(%1);"
+		: "=&r" (val)
+		: "r" (addr)
+	);
+	return val;
+}
+
+static inline u32 readl(const volatile void __iomem *addr)
+{
+	u32 val;
+	asm volatile(
+		"%0 = memw(%1);"
+		: "=&r" (val)
+		: "r" (addr)
+	);
+	return val;
+}
+
+/*
+ * writeb - write a byte to a memory location
+ * @data: data to write to
+ * @addr:  pointer to memory
+ *
+ */
+static inline void writeb(u8 data, volatile void __iomem *addr)
+{
+	asm volatile(
+		"memb(%0) = %1;"
+		:
+		: "r" (addr), "r" (data)
+	);
+}
+
+static inline void writew(u16 data, volatile void __iomem *addr)
+{
+	asm volatile(
+		"memh(%0) = %1;"
+		:
+		: "r" (addr), "r" (data)
+	);
+
+}
+
+static inline void writel(u32 data, volatile void __iomem *addr)
+{
+	asm volatile(
+		"memw(%0) = %1;"
+		:
+		: "r" (addr), "r" (data)
+	);
+}
+
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
+
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
+
+/*
+ * Need an mtype somewhere in here, for cache type deals?
+ * This is probably too long for an inline.
+ */
+void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size);
+
+static inline void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
+{
+	return ioremap_nocache(phys_addr, size);
+}
+
+static inline void iounmap(volatile void __iomem *addr)
+{
+	__iounmap(addr);
+}
+
+#define __raw_writel writel
+
+static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
+	int count)
+{
+	memcpy(dst, (void *) src, count);
+}
+
+static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
+	int count)
+{
+	memcpy((void *) dst, src, count);
+}
+
+#define PCI_IO_ADDR	volatile void __iomem *
+
+/*
+ * inb - read byte from I/O port or something
+ * @port:  address in I/O space
+ *
+ * Operates on "I/O bus I/O space"
+ */
+static inline u8 inb(unsigned long port)
+{
+	printk(KERN_INFO "inb not implemented\n");
+	return 0;
+}
+
+static inline u16 inw(unsigned long port)
+{
+	printk(KERN_INFO "inw not implemented\n");
+	return 0;
+}
+
+static inline u32 inl(unsigned long port)
+{
+	printk(KERN_INFO "inl not implemented\n");
+	return 0;
+}
+
+/*
+ * outb - write a byte to a memory location
+ * @data: data to write to
+ * @addr:  address in I/O space
+ */
+static inline void outb(u8 data, unsigned long port)
+{
+	writeb(data, (PCI_IO_ADDR)_IO_BASE+port);
+}
+
+static inline void outw(u16 data, unsigned long port)
+{
+	writew(data, (PCI_IO_ADDR)_IO_BASE+port);
+}
+
+static inline void outl(u32 data, unsigned long port)
+{
+	writel(data, (PCI_IO_ADDR)_IO_BASE+port);
+}
+
+/*  _p means "pause until the I/O completes"  */
+#define outb_p outb
+#define outw_p outw
+#define outl_p outl
+
+#define inb_p inb
+#define inw_p inw
+#define inl_p inl
+
+static inline void insb(unsigned long addr, void *buffer, int count)
+{
+	printk(KERN_INFO "insb not implemented\n");
+}
+
+static inline void insw(unsigned long addr, void *buffer, int count)
+{
+	printk(KERN_INFO "insw not implemented\n");
+}
+
+static inline void insl(unsigned long addr, void *buffer, int count)
+{
+	printk(KERN_INFO "insl not implemented\n");
+}
+
+static inline void outsb(unsigned long addr, const void *buffer, int count)
+{
+	printk(KERN_INFO "outsb not implemented\n");
+}
+
+static inline void outsw(unsigned long addr, const void *buffer, int count)
+{
+	printk(KERN_INFO "outsw not implemented\n");
+}
+
+static inline void outsl(unsigned long addr, const void *buffer, int count)
+{
+	printk(KERN_INFO "outsl not implemented\n");
+}
+
+/*  generic versions defined in lib/iomap.c  */
+extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
+extern void ioport_unmap(void __iomem *addr);
+
+#define flush_write_buffers() do { } while (0)
+
+#endif /* __KERNEL__ */
+
+#endif
arch/hexagon/lib/io.c new file +91 -0

91 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#55 lore raw

Re: [patch v2 24/35] Hexagon: Provide basic implementation and/or stubs for I/O routines.

Quoted 10 lines · Richard Kuo

Changed read/write to use inline assembly.

Rearranged the file and put all the ioport stuff at the bottom. For now I'd like to just leave the stubs in there in case they need to be filled out later; plus things don't compile.

We still seem to need IO_SPACE_LIMIT to be defined, particularly to something large, as we have drivers that request resources with IORESOURCE_IO that are memory mapped IO. The ioread/iowrites work as they select the correct routine to use.

Which drivers? If the drivers are buggy, better fix them than working around in the architecture.

I have experimental patches in the tmp/randconfig3 branch of the arm-soc.git tree to remove the need for PIO functions in ARM. Please have a look there if you are interested.

arch/hexagon/include/asm/io.h line 40

Quoted 5 lines
arch/hexagon/include/asm/io.h new file +5 -0
+/*
+ * We don't have PCI yet.
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+#define _IO_BASE 0x0

If you absolutely insist on defining these, at least make them meaningful, e.g. defining _IO_BASE to an unused location in the virtual address space, and IO_SPACE_LIMIT small enough to be harmless, at most 0xffff.

If you ever gain PCI support, you can then map the PCI I/O space into that area.

arch/hexagon/include/asm/io.h line 202

Quoted 11 lines
arch/hexagon/include/asm/io.h new file +11 -0
+static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
+	int count)
+{
+	memcpy(dst, (void *) src, count);
+}
+
+static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
+	int count)
+{
+	memcpy((void *) dst, src, count);
+}

This will need __force in order to build with sparse.

Quoted 1 line

+#define PCI_IO_ADDR volatile void __iomem *

Better make _IO_BASE have the right type to start with, like

#define _IO_BASE ((void __iomem *)0xefff0000)
static inline u8 inb(unsigned long port)

{
	return readb(_IO_BASE + (port & IO_SPACE_LIMIT));
}

static inline void outb(u8 data, unsigned long port)

{
	writeb(data, _IO_BASE + (port & IO_SPACE_LIMIT));
}

arch/hexagon/include/asm/io.h line 257

Quoted 8 lines
arch/hexagon/include/asm/io.h new file +8 -0
+/*  _p means "pause until the I/O completes"  */
+#define outb_p outb
+#define outw_p outw
+#define outl_p outl
+
+#define inb_p inb
+#define inw_p inw
+#define inl_p inl

It doesn't actually mean that. It means 'pause for a bit longer'. The inb/outb family of functions is already required to wait for the I/O to complete, unlike readb/writeb, which only needs to wait for inbound data, while outbound writes are posted to the bus without waiting for the data to arrive.

Quoted 19 lines
arch/hexagon/include/asm/io.h new file +19 -0
+static inline void insb(unsigned long addr, void *buffer, int count)
+{
+	printk(KERN_INFO "insb not implemented\n");
+}
+
+static inline void insw(unsigned long addr, void *buffer, int count)
+{
+	printk(KERN_INFO "insw not implemented\n");
+}
+
+static inline void insl(unsigned long addr, void *buffer, int count)
+{
+	printk(KERN_INFO "insl not implemented\n");
+}
+
+static inline void outsb(unsigned long addr, const void *buffer, int count)
+{
+	printk(KERN_INFO "outsb not implemented\n");
+}

arch/hexagon/include/asm/io.h line 287

Quoted 10 lines
arch/hexagon/include/asm/io.h new file +10 -0
+
+static inline void outsw(unsigned long addr, const void *buffer, int count)
+{
+	printk(KERN_INFO "outsw not implemented\n");
+}
+
+static inline void outsl(unsigned long addr, const void *buffer, int count)
+{
+	printk(KERN_INFO "outsl not implemented\n");
+}

Either just add the obvious implementations adding _IO_BASE as above or stub these out to create a link time error in drivers using them. If a driver relies on these functions, it won't work anyway, so it's better to not even build it.

arch/hexagon/include/asm/io.h line 291

Quoted 3 lines
arch/hexagon/include/asm/io.h new file +3 -0
+/*  generic versions defined in lib/iomap.c  */
+extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
+extern void ioport_unmap(void __iomem *addr);

You can also just set CONFIG_NO_IOPORT (CONFIG_NO_IOPORT_MAP once my patches went in) to remove support for ioport_map.

Arnd

#56 lore raw

Re: [patch v2 24/35] Hexagon: Provide basic implementation and/or stubs for I/O routines.

In reply to Richard Kuo
Quoted 10 lines · Richard Kuo

Changed read/write to use inline assembly.

Rearranged the file and put all the ioport stuff at the bottom. For now I'd like to just leave the stubs in there in case they need to be filled out later; plus things don't compile.

We still seem to need IO_SPACE_LIMIT to be defined, particularly to something large, as we have drivers that request resources with IORESOURCE_IO that are memory mapped IO. The ioread/iowrites work as they select the correct routine to use.

Which drivers? If the drivers are buggy, better fix them than working around in the architecture.

I have experimental patches in the tmp/randconfig3 branch of the arm-soc.git tree to remove the need for PIO functions in ARM. Please have a look there if you are interested.

arch/hexagon/include/asm/io.h line 40

Quoted 5 lines
arch/hexagon/include/asm/io.h new file +5 -0
+/*
+ * We don't have PCI yet.
+ */
+#define IO_SPACE_LIMIT 0xffffffff
+#define _IO_BASE 0x0

If you absolutely insist on defining these, at least make them meaningful, e.g. defining _IO_BASE to an unused location in the virtual address space, and IO_SPACE_LIMIT small enough to be harmless, at most 0xffff.

If you ever gain PCI support, you can then map the PCI I/O space into that area.

arch/hexagon/include/asm/io.h line 202

Quoted 11 lines
arch/hexagon/include/asm/io.h new file +11 -0
+static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
+	int count)
+{
+	memcpy(dst, (void *) src, count);
+}
+
+static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
+	int count)
+{
+	memcpy((void *) dst, src, count);
+}

This will need __force in order to build with sparse.

Quoted 1 line

+#define PCI_IO_ADDR volatile void __iomem *

Better make _IO_BASE have the right type to start with, like

#define _IO_BASE ((void __iomem *)0xefff0000)
static inline u8 inb(unsigned long port)

{
	return readb(_IO_BASE + (port & IO_SPACE_LIMIT));
}

static inline void outb(u8 data, unsigned long port)

{
	writeb(data, _IO_BASE + (port & IO_SPACE_LIMIT));
}

arch/hexagon/include/asm/io.h line 257

Quoted 8 lines
arch/hexagon/include/asm/io.h new file +8 -0
+/*  _p means "pause until the I/O completes"  */
+#define outb_p outb
+#define outw_p outw
+#define outl_p outl
+
+#define inb_p inb
+#define inw_p inw
+#define inl_p inl

It doesn't actually mean that. It means 'pause for a bit longer'. The inb/outb family of functions is already required to wait for the I/O to complete, unlike readb/writeb, which only needs to wait for inbound data, while outbound writes are posted to the bus without waiting for the data to arrive.

Quoted 19 lines
arch/hexagon/include/asm/io.h new file +19 -0
+static inline void insb(unsigned long addr, void *buffer, int count)
+{
+	printk(KERN_INFO "insb not implemented\n");
+}
+
+static inline void insw(unsigned long addr, void *buffer, int count)
+{
+	printk(KERN_INFO "insw not implemented\n");
+}
+
+static inline void insl(unsigned long addr, void *buffer, int count)
+{
+	printk(KERN_INFO "insl not implemented\n");
+}
+
+static inline void outsb(unsigned long addr, const void *buffer, int count)
+{
+	printk(KERN_INFO "outsb not implemented\n");
+}

arch/hexagon/include/asm/io.h line 287

Quoted 10 lines
arch/hexagon/include/asm/io.h new file +10 -0
+
+static inline void outsw(unsigned long addr, const void *buffer, int count)
+{
+	printk(KERN_INFO "outsw not implemented\n");
+}
+
+static inline void outsl(unsigned long addr, const void *buffer, int count)
+{
+	printk(KERN_INFO "outsl not implemented\n");
+}

Either just add the obvious implementations adding _IO_BASE as above or stub these out to create a link time error in drivers using them. If a driver relies on these functions, it won't work anyway, so it's better to not even build it.

arch/hexagon/include/asm/io.h line 291

Quoted 3 lines
arch/hexagon/include/asm/io.h new file +3 -0
+/*  generic versions defined in lib/iomap.c  */
+extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
+extern void ioport_unmap(void __iomem *addr);

You can also just set CONFIG_NO_IOPORT (CONFIG_NO_IOPORT_MAP once my patches went in) to remove support for ioport_map.

Arnd

#57 lore raw

PATCH v2 25/35 Hexagon: Implement basic cache-flush support

In reply to Richard Kuo

We have separate I/D caches. Data caches are physically indexed.

---
 arch/hexagon/include/asm/cache.h      |   34 +++++++++
 arch/hexagon/include/asm/cacheflush.h |   99 ++++++++++++++++++++++++++
 arch/hexagon/mm/cache.c               |  128 ++++++++++++++++++++++++++++++++++
 3 files changed, 261 insertions(+)
arch/hexagon/include/asm/cacheflush.h new file +99 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/cacheflush.h
===================================================================
@@ -0,0 +1,99 @@
+/*
+ * Cache flush operations for the Hexagon architecture
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_CACHEFLUSH_H
+#define _ASM_CACHEFLUSH_H
+
+#include <linux/cache.h>
+#include <linux/mm.h>
+#include <asm/string.h>
+#include <asm-generic/cacheflush.h>
+
+/* Cache flushing:
+ *
+ *  - flush_cache_all() flushes entire cache
+ *  - flush_cache_mm(mm) flushes the specified mm context's cache lines
+ *  - flush_cache_page(mm, vmaddr, pfn) flushes a single page
+ *  - flush_cache_range(vma, start, end) flushes a range of pages
+ *  - flush_icache_range(start, end) flush a range of instructions
+ *  - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache
+ *  - flush_icache_page(vma, pg) flushes(invalidates) a page for icache
+ *
+ *  Need to doublecheck which one is really needed for ptrace stuff to work.
+ */
+#define LINESIZE	32
+#define LINEBITS	5
+
+/*
+ * Flush Dcache range through current map.
+ */
+extern void flush_dcache_range(unsigned long start, unsigned long end);
+
+/*
+ * Flush Icache range through current map.
+ */
+#undef flush_icache_range
+extern void flush_icache_range(unsigned long start, unsigned long end);
+
+/*
+ * Memory-management related flushes are there to ensure in non-physically
+ * indexed cache schemes that stale lines belonging to a given ASID aren't
+ * in the cache to confuse things.  The prototype Hexagon Virtual Machine
+ * only uses a single ASID for all user-mode maps, which should
+ * mean that they aren't necessary.  A brute-force, flush-everything
+ * implementation, with the name xxxxx_hexagon() is present in
+ * arch/hexagon/mm/cache.c, but let's not wire it up until we know
+ * it is needed.
+ */
+extern void flush_cache_all_hexagon(void);
+
+/*
+ * This may or may not ever have to be non-null, depending on the
+ * virtual machine MMU.  For a native kernel, it's definitiely  a no-op
+ *
+ * This is also the place where deferred cache coherency stuff seems
+ * to happen, classically...  but instead we do it like ia64 and
+ * clean the cache when the PTE is set.
+ *
+ */
+static inline void update_mmu_cache(struct vm_area_struct *vma,
+					unsigned long address, pte_t *ptep)
+{
+	/*  generic_ptrace_pokedata doesn't wind up here, does it?  */
+}
+
+#undef copy_to_user_page
+static inline void copy_to_user_page(struct vm_area_struct *vma,
+					     struct page *page,
+					     unsigned long vaddr,
+					     void *dst, void *src, int len)
+{
+	memcpy(dst, src, len);
+	if (vma->vm_flags & VM_EXEC) {
+		flush_icache_range((unsigned long) dst,
+		(unsigned long) dst + len);
+	}
+}
+
+
+extern void hexagon_inv_dcache_range(unsigned long start, unsigned long end);
+extern void hexagon_clean_dcache_range(unsigned long start, unsigned long end);
+
+#endif
arch/hexagon/include/asm/cache.h new file +34 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/cache.h
===================================================================
@@ -0,0 +1,34 @@
+/*
+ * Cache definitions for the Hexagon architecture
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __ASM_CACHE_H
+#define __ASM_CACHE_H
+
+/* Bytes per L1 cache line */
+#define L1_CACHE_SHIFT		(5)
+#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
+
+#define __cacheline_aligned	__attribute__((aligned(L1_CACHE_BYTES)))
+#define ____cacheline_aligned	__attribute__((aligned(L1_CACHE_BYTES)))
+
+/* See http://kerneltrap.org/node/15100  */
+#define __read_mostly
+
+#endif
arch/hexagon/mm/cache.c new file +128 -0

128 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#59 lore raw

PATCH v2 26/35 Hexagon: Implement basic TLB management routines for Hexagon.

In reply to Richard Kuo

Mostly all stubs, as the TLB is managed by the hypervisor.

---
 arch/hexagon/include/asm/tlb.h      |   39 +++++++++++++++
 arch/hexagon/include/asm/tlbflush.h |   58 ++++++++++++++++++++++
 arch/hexagon/mm/vm_tlb.c            |   93 ++++++++++++++++++++++++++++++++++++
 3 files changed, 190 insertions(+)
arch/hexagon/include/asm/tlbflush.h new file +58 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/tlbflush.h
===================================================================
@@ -0,0 +1,58 @@
+/*
+ * TLB flush support for Hexagon
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_TLBFLUSH_H
+#define _ASM_TLBFLUSH_H
+
+#include <linux/mm.h>
+#include <asm/processor.h>
+
+/*
+ * TLB flushing -- in "SMP", these routines get defined to be the
+ * ones from smp.c, else they are some local flavors.
+ */
+
+/*
+ * These functions are commonly macros, but in the interests of
+ * VM vs. native implementation and code size, we simply declare
+ * the function prototypes here.
+ */
+extern void tlb_flush_all(void);
+extern void flush_tlb_mm(struct mm_struct *mm);
+extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
+extern void flush_tlb_range(struct vm_area_struct *vma,
+				unsigned long start, unsigned long end);
+extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
+extern void flush_tlb_one(unsigned long);
+
+/*
+ * "This is called in munmap when we have freed up some page-table pages.
+ * We don't need to do anything here..."
+ *
+ * The VM kernel doesn't walk page tables, and they are passed to the VMM
+ * by logical address. There doesn't seem to be any possibility that they
+ * could be referenced by the VM kernel based on a stale mapping, since
+ * they would only be located by consulting the mm structure, and they
+ * will have been purged from that structure by the munmap.  Seems like
+ * a noop on HVM as well.
+ */
+#define flush_tlb_pgtables(mm, start, end)
+
+#endif
arch/hexagon/include/asm/tlb.h new file +39 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/tlb.h
===================================================================
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_TLB_H
+#define _ASM_TLB_H
+
+#include <linux/pagemap.h>
+#include <asm/tlbflush.h>
+
+/*
+ * We don't need any special per-pte or per-vma handling...
+ */
+#define tlb_start_vma(tlb, vma)				do { } while (0)
+#define tlb_end_vma(tlb, vma)				do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, ptep, address)	do { } while (0)
+
+/*
+ * .. because we flush the whole mm when it fills up
+ */
+#define tlb_flush(tlb)		flush_tlb_mm((tlb)->mm)
+
+#include <asm-generic/tlb.h>
+
+#endif
arch/hexagon/mm/vm_tlb.c new file +93 -0

93 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#61 lore raw

PATCH v2 27/35 Hexagon: Provide DMA implementation

In reply to Richard Kuo

Basic DMA implementation for our architecture.

Added sync_single_for_* routines; hexagon_map_page() still seems to be a convenient place to flush/invalidate.

---
 arch/hexagon/include/asm/dma-mapping.h |  101 +++++++++++++++
 arch/hexagon/include/asm/dma.h         |   29 ++++
 arch/hexagon/kernel/dma.c              |  220 +++++++++++++++++++++++++++++++++
 3 files changed, 350 insertions(+)
arch/hexagon/include/asm/dma.h new file +29 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/dma.h
===================================================================
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_DMA_H
+#define _ASM_DMA_H
+
+#include <asm/io.h>
+
+#define MAX_DMA_CHANNELS 1
+#define MAX_DMA_ADDRESS  (PAGE_OFFSET)
+
+extern size_t hexagon_coherent_pool_size;
+
+#endif
arch/hexagon/include/asm/dma-mapping.h new file +101 -0

101 lines not on this page · raw message

arch/hexagon/kernel/dma.c new file +220 -0

220 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#63 lore raw

PATCH v2 28/35 Hexagon: Add ioremap support

In reply to Richard Kuo
---
 arch/hexagon/mm/ioremap.c |   57 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)
arch/hexagon/mm/ioremap.c new file +57 -0
Index: linux-hexagon-kernel/arch/hexagon/mm/ioremap.c
===================================================================
@@ -0,0 +1,57 @@
+/*
+ * I/O remap functions for Hexagon
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/io.h>
+#include <linux/vmalloc.h>
+
+void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size)
+{
+	unsigned long last_addr, addr;
+	unsigned long offset = phys_addr & ~PAGE_MASK;
+	struct vm_struct *area;
+
+	pgprot_t prot = __pgprot(_PAGE_PRESENT|_PAGE_READ|_PAGE_WRITE
+					|(__HEXAGON_C_DEV << 6));
+
+	last_addr = phys_addr + size - 1;
+
+	/*  Wrapping not allowed  */
+	if (!size || (last_addr < phys_addr))
+		return NULL;
+
+	/*  Rounds up to next page size, including whole-page offset */
+	size = PAGE_ALIGN(offset + size);
+
+	area = get_vm_area(size, VM_IOREMAP);
+	addr = (unsigned long)area->addr;
+
+	if (ioremap_page_range(addr, addr+size, phys_addr, prot)) {
+		vunmap((void *)addr);
+		return NULL;
+	}
+
+	flush_cache_vmap(addr, addr+size);
+	return (void __iomem *) (offset + addr);
+}
+
+void __iounmap(const volatile void __iomem *addr)
+{
+	vunmap((void *) ((unsigned long) addr & PAGE_MASK));
+}

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

Acked-by on v2 28/35
#64 lore raw

Re: [patch v2 28/35] Hexagon: Add ioremap support

Quoted 1 line · Richard Kuo

arch/hexagon/mm/ioremap.c line 50

Quoted 6 lines
arch/hexagon/mm/ioremap.c new file +6 -0
+       if (ioremap_page_range(addr, addr+size, phys_addr, prot)) {
+               vunmap((void *)addr);
+               return NULL;
+       }
+
+       flush_cache_vmap(addr, addr+size);

I think that ioremap_page_range implies the flush_cache_vmap already, so there is no reason to do it again.

Arnd

#65 lore raw

PATCH v2 29/35 Hexagon: Add page table header files & etc.

In reply to Richard Kuo

Removed highmem as we currently don't need it (and it didn't quite work).

---
 arch/hexagon/include/asm/fixmap.h      |   73 ++++
 arch/hexagon/include/asm/highmem.h     |  111 +++++++
 arch/hexagon/include/asm/mmu.h         |   34 ++
 arch/hexagon/include/asm/mmu_context.h |  100 ++++++
 arch/hexagon/include/asm/page.h        |  157 ++++++++++
 arch/hexagon/include/asm/pgalloc.h     |  146 +++++++++
 arch/hexagon/include/asm/pgtable.h     |  518 +++++++++++++++++++++++++++++++++
 arch/hexagon/mm/pgalloc.c              |   25 +
 8 files changed, 1164 insertions(+)
arch/hexagon/include/asm/fixmap.h new file +73 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/fixmap.h
===================================================================
@@ -0,0 +1,73 @@
+/*
+ * Fixmap support for Hexagon - enough to support highmem features
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_FIXMAP_H
+#define _ASM_FIXMAP_H
+
+/*
+ * A lot of the fixmap info is already in mem-layout.h
+ */
+#include <asm/mem-layout.h>
+
+/*
+ * Full fixmap support involves set_fixmap() functions, but
+ * these may not be needed if all we're after is an area for
+ * highmem kernel mappings.
+ */
+#define	__fix_to_virt(x)	(FIXADDR_TOP - ((x) << PAGE_SHIFT))
+#define	__virt_to_fix(x)	((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
+
+extern void __this_fixmap_does_not_exist(void);
+
+/**
+ * fix_to_virt -- "index to address" translation.
+ *
+ * If anyone tries to use the idx directly without translation,
+ * we catch the bug with a NULL-deference kernel oops. Illegal
+ * ranges of incoming indices are caught too.
+ */
+static inline unsigned long fix_to_virt(const unsigned int idx)
+{
+	/*
+	 * This branch gets completely eliminated after inlining,
+	 * except when someone tries to use fixaddr indices in an
+	 * illegal way. (such as mixing up address types or using
+	 * out-of-range indices).
+	 *
+	 * If it doesn't get removed, the linker will complain
+	 * loudly with a reasonably clear error message..
+	 */
+	if (idx >= __end_of_fixed_addresses)
+		__this_fixmap_does_not_exist();
+
+	return __fix_to_virt(idx);
+}
+
+static inline unsigned long virt_to_fix(const unsigned long vaddr)
+{
+	BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
+	return __virt_to_fix(vaddr);
+}
+
+#define kmap_get_fixmap_pte(vaddr) \
+	pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), \
+				(vaddr)), (vaddr)), (vaddr))
+
+#endif
arch/hexagon/include/asm/highmem.h new file +111 -0

111 lines not on this page · raw message

arch/hexagon/include/asm/mmu_context.h new file +100 -0

100 lines not on this page · raw message

arch/hexagon/include/asm/mmu.h new file +34 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/mmu.h
===================================================================
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_MMU_H
+#define _ASM_MMU_H
+
+/*
+ * Architecture-specific state for a mm_struct.
+ * For the Hexagon Virtual Machine, it can be a copy
+ * of the pointer to the page table base.
+ */
+struct mm_context {
+	unsigned long long generation;
+	unsigned long ptbase;
+};
+
+typedef struct mm_context mm_context_t;
+
+#endif
arch/hexagon/include/asm/page.h new file +157 -0

157 lines not on this page · raw message

arch/hexagon/include/asm/pgalloc.h new file +146 -0

146 lines not on this page · raw message

arch/hexagon/include/asm/pgtable.h new file +518 -0

518 lines not on this page · raw message

arch/hexagon/mm/pgalloc.c new file +25 -0
Index: linux-hexagon-kernel/arch/hexagon/mm/pgalloc.c
===================================================================
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/init.h>
+
+void __init pgtable_cache_init(void)
+{
+}
+
+

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#66 lore raw

Re: [patch v2 29/35] Hexagon: Add page table header files & etc.

Quoted 5 lines · Richard Kuo

Removed highmem as we currently don't need it (and it didn't quite work).

Apparently you haven't removed it completely yet:

Quoted 17 lines
arch/hexagon/include/asm/highmem.h new file +17 -0
+/**
+ * kunmap - unmaps a kernel mapping
+ * @page: pointer to page struct
+ *
+ * If it's not in highmem, then you ain't unmapping anybody.
+ *
+ * If it is in highmem, it calls kunmap_high, which magically
+ * removes the mapping or something.  Seems to only decrement pkmap_count
+ * for the page.  If the pkmap_count was decremented to 1, that means it's
+ * ready to be flushed.
+ *
+ * It also is responsible for waking anybody up that was waiting for a kmap
+ * to free up.
+ */
+extern void kunmap_hexagon(struct page *page);
+#define kunmap(p)      kunmap_hexagon((p))
+

arch/hexagon/include/asm/highmem.h line 107

Quoted 10 lines
arch/hexagon/include/asm/highmem.h new file +10 -0
+extern struct page *kmap_atomic_to_page_hexagon(void *ptr);
+#define kmap_atomic_to_page(p) kmap_atomic_to_page_hexagon((p))
+
+extern void *kmap_atomic_prot(struct page *page, pgprot_t prot);
+extern void __kunmap_atomic(void *);
+
+static inline void *__kmap_atomic(struct page *page)
+{
+       return kmap_atomic_prot(page, kmap_prot);
+}

I think if you disable CONFIG_ARCH_HAS_KMAP you can use the trivial functions provided by include/linux/highmem.h.

Arnd

#67 lore raw

PATCH v2 30/35 Hexagon: Add page-fault support.

In reply to Richard Kuo
---
 arch/hexagon/include/asm/mem-layout.h |  112 +++++++++++++
 arch/hexagon/include/asm/vm_fault.h   |   26 +++
 arch/hexagon/mm/init.c                |  278 ++++++++++++++++++++++++++++++++++
 arch/hexagon/mm/vm_fault.c            |  188 ++++++++++++++++++++++
 4 files changed, 604 insertions(+)
arch/hexagon/include/asm/mem-layout.h new file +112 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/mem-layout.h
===================================================================
@@ -0,0 +1,112 @@
+/*
+ * Memory layout definitions for the Hexagon architecture
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_HEXAGON_MEM_LAYOUT_H
+#define _ASM_HEXAGON_MEM_LAYOUT_H
+
+#include <linux/const.h>
+
+/*
+ * Have to do this for ginormous numbers, else they get printed as
+ * negative numbers, which the linker no likey when you try to
+ * assign it to the location counter.
+ */
+
+#define PAGE_OFFSET			_AC(0xc0000000, UL)
+
+/*
+ * LOAD_ADDRESS is the physical/linear address of where in memory
+ * the kernel gets loaded. The 12 least significant bits must be zero (0)
+ * due to limitations on setting the EVB
+ *
+ */
+
+#ifndef LOAD_ADDRESS
+#define LOAD_ADDRESS			0x00000000
+#endif
+
+#define TASK_SIZE			(PAGE_OFFSET)
+
+/*  not sure how these are used yet  */
+#define STACK_TOP			TASK_SIZE
+#define STACK_TOP_MAX			TASK_SIZE
+
+#ifndef __ASSEMBLY__
+enum fixed_addresses {
+	FIX_KMAP_BEGIN,
+	FIX_KMAP_END,  /*  check for per-cpuism  */
+	__end_of_fixed_addresses
+};
+
+#define MIN_KERNEL_SEG 0x300   /* From 0xc0000000 */
+extern int max_kernel_seg;
+
+/*
+ * Start of vmalloc virtual address space for kernel;
+ * supposed to be based on the amount of physical memory available
+ */
+
+#define VMALLOC_START (PAGE_OFFSET + VMALLOC_OFFSET + \
+	(unsigned long)high_memory)
+
+/* Gap between physical ram and vmalloc space for guard purposes. */
+#define VMALLOC_OFFSET PAGE_SIZE
+
+/*
+ * Create the space between VMALLOC_START and FIXADDR_TOP backwards
+ * from the ... "top".
+ *
+ * Permanent IO mappings will live at 0xfexx_xxxx
+ * Hypervisor occupies the last 16MB page at 0xffxxxxxx
+ */
+
+#define FIXADDR_TOP     0xfe000000
+#define FIXADDR_SIZE    (__end_of_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_START   (FIXADDR_TOP - FIXADDR_SIZE)
+
+/*
+ * "permanent kernel mappings", defined as long-lasting mappings of
+ * high-memory page frames into the kernel address space.
+ */
+
+#define LAST_PKMAP	PTRS_PER_PTE
+#define LAST_PKMAP_MASK	(LAST_PKMAP - 1)
+#define PKMAP_NR(virt)	((virt - PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr)	(PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+/*
+ * To the "left" of the fixed map space is the kmap space
+ *
+ * "Permanent Kernel Mappings"; fancy (or less fancy) PTE table
+ * that looks like it's actually walked.
+ * Need to check the alignment/shift usage; some archs use
+ * PMD_MASK on this value
+ */
+#define PKMAP_BASE (FIXADDR_START-PAGE_SIZE*LAST_PKMAP)
+
+/*
+ * 2 pages of guard gap between where vmalloc area ends
+ * and pkmap_base begins.
+ */
+#define VMALLOC_END (PKMAP_BASE-PAGE_SIZE*2)
+#endif /*  !__ASSEMBLY__  */
+
+
+#endif /* _ASM_HEXAGON_MEM_LAYOUT_H */
arch/hexagon/mm/init.c new file +278 -0

278 lines not on this page · raw message

arch/hexagon/mm/vm_fault.c new file +188 -0

188 lines not on this page · raw message

arch/hexagon/include/asm/vm_fault.h new file +26 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/vm_fault.h
===================================================================
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_HEXAGON_VM_FAULT_H
+#define _ASM_HEXAGON_VM_FAULT_H
+
+extern void execute_protection_fault(struct pt_regs *);
+extern void write_protection_fault(struct pt_regs *);
+extern void read_protection_fault(struct pt_regs *);
+
+#endif

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#69 lore raw

PATCH v2 31/35 Hexagon: kgdb support files

In reply to Richard Kuo
---
 arch/hexagon/include/asm/kgdb.h |   39 ++++++
 arch/hexagon/kernel/kgdb.c      |  241 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 280 insertions(+)
arch/hexagon/include/asm/kgdb.h new file +39 -0
Index: linux-hexagon-kernel/arch/hexagon/include/asm/kgdb.h
===================================================================
@@ -0,0 +1,39 @@
+/*
+ * arch/hexagon/include/asm/kgdb.h - Hexagon KGDB Support
+ *
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __HEXAGON_KGDB_H__
+#define __HEXAGON_KGDB_H__
+
+#define BREAK_INSTR_SIZE 4
+#define CACHE_FLUSH_IS_SAFE   1
+#define BUFMAX       ((NUMREGBYTES * 2) + 512)
+
+static inline void arch_kgdb_breakpoint(void)
+{
+	asm("trap0(#0xDB)");
+}
+
+/* Registers:
+ * 32 gpr + sa0/1 + lc0/1 + m0/1 + gp + ugp + pred + pc = 42 total.
+ */
+#define NUMREGBYTES  (42*4)
+#define DBG_MAX_REG_NUM 42
+
+#endif /* __HEXAGON_KGDB_H__ */
arch/hexagon/kernel/kgdb.c new file +241 -0

241 lines not on this page · raw message

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#71 lore raw

PATCH v2 32/35 Hexagon: Comet platform support

In reply to Richard Kuo

Used the shortened version of the config; other platform stuff moved out until it's ready.

---
 arch/hexagon/configs/comet_defconfig |   85 +++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)
arch/hexagon/configs/comet_defconfig new file +85 -0
Index: linux-hexagon-kernel/arch/hexagon/configs/comet_defconfig
===================================================================
@@ -0,0 +1,85 @@
+CONFIG_SMP=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=0
+CONFIG_HZ_100=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_CROSS_COMPILE="hexagon-"
+CONFIG_LOCALVERSION="-smp"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+CONFIG_CONNECTOR=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_PHYLIB=y
+CONFIG_NET_ETHERNET=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_CONSOLE_TRANSLATIONS is not set
+CONFIG_LEGACY_PTY_COUNT=64
+# CONFIG_DEVKMEM is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_SPI=y
+CONFIG_SPI_DEBUG=y
+CONFIG_SPI_BITBANG=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_QUOTA=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+CONFIG_LIBCRC32C=y
+CONFIG_FRAME_WARN=0
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_DEBUG_INFO=y

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#73 lore raw

PATCH v2 33/35 Hexagon: Add configuration and makefiles for the Hexagon architecture.

In reply to Richard Kuo
---
 arch/hexagon/Kconfig              |  221 ++++++++++++++++++++++++++++++++++++++
 arch/hexagon/Makefile             |   59 ++++++++++
 arch/hexagon/kernel/Makefile      |   19 +++
 arch/hexagon/kernel/asm-offsets.c |  104 +++++++++++++++++
 arch/hexagon/kernel/vmlinux.lds.S |   93 +++++++++++++++
 arch/hexagon/lib/Makefile         |    4 
 arch/hexagon/mm/Makefile          |    7 +
 7 files changed, 507 insertions(+)
arch/hexagon/Kconfig new file +221 -0
Index: linux-hexagon-kernel/arch/hexagon/Kconfig
===================================================================
@@ -0,0 +1,221 @@
+# Hexagon configuration
+comment "Linux Kernel Configuration for Hexagon"
+
+config HEXAGON
+	def_bool y
+	select HAVE_OPROFILE
+	# We will need this to get tickless NOHZ
+	# select USE_GENERIC_SMP_HELPERS if SMP
+	# Other pending projects/to-do items.
+	# select HAVE_REGS_AND_STACK_ACCESS_API
+	# select HAVE_HW_BREAKPOINT if PERF_EVENTS
+	# select ARCH_HAS_CPU_IDLE_WAIT
+	# select ARCH_WANT_OPTIONAL_GPIOLIB
+	# select ARCH_REQUIRE_GPIOLIB
+	# select HAVE_CLK
+	# select IRQ_PER_CPU
+	select HAVE_IRQ_WORK
+	# select GENERIC_PENDING_IRQ if SMP
+	select GENERIC_ATOMIC64
+	select HAVE_PERF_EVENTS
+	select HAVE_GENERIC_HARDIRQS
+	select GENERIC_HARDIRQS_NO__DO_IRQ
+	select GENERIC_HARDIRQS_NO_DEPRECATED
+	# GENERIC_ALLOCATOR is used by dma_alloc_coherent()
+	select GENERIC_ALLOCATOR
+	select HAVE_ARCH_KGDB
+	# mostly generic routines, with some accelerated ones
+	---help---
+	  Qualcomm Hexagon is a processor architecture designed for high
+	  performance and low power across a wide variety of applications.
+
+config HEXAGON_ARCH_V1
+	bool
+
+config HEXAGON_ARCH_V2
+	bool
+
+config HEXAGON_ARCH_V3
+	bool
+
+config HEXAGON_ARCH_V4
+	bool
+
+config FRAME_POINTER
+	def_bool y
+
+config LOCKDEP_SUPPORT
+	def_bool y
+
+config PCI
+	def_bool n
+
+config EARLY_PRINTK
+	def_bool y
+
+config KTIME_SCALAR
+	def_bool y
+
+config MMU
+	def_bool y
+
+config TRACE_IRQFLAGS_SUPPORT
+	def_bool y
+
+config GENERIC_CSUM
+	def_bool y
+
+#
+# Use the generic interrupt handling code in kernel/irq/:
+#
+config GENERIC_IRQ_PROBE
+	def_bool y
+
+config GENERIC_IOMAP
+	def_bool y
+
+#config ZONE_DMA
+#	bool
+#	default y
+
+config HAS_DMA
+	bool
+	select HAVE_DMA_ATTRS
+	default y
+
+config NEED_SG_DMA_LENGTH
+	def_bool y
+
+config RWSEM_GENERIC_SPINLOCK
+	def_bool n
+
+config RWSEM_XCHGADD_ALGORITHM
+	def_bool y
+
+config GENERIC_CALIBRATE_DELAY
+	def_bool y
+
+config GENERIC_FIND_NEXT_BIT
+	def_bool y
+
+config GENERIC_HWEIGHT
+	def_bool y
+
+config GENERIC_TIME
+	def_bool y
+
+config GENERIC_CLOCKEVENTS
+	def_bool y
+
+config GENERIC_CLOCKEVENTS_BROADCAST
+	def_bool y
+
+config STACKTRACE_SUPPORT
+	def_bool y
+	select STACKTRACE
+
+config GENERIC_BUG
+	def_bool y
+	depends on BUG
+
+config BUG
+	def_bool y
+
+menu "Machine selection"
+
+choice
+	prompt "System type"
+	default HEXAGON_ARCH_V2
+
+config HEXAGON_COMET
+	bool "Comet Board"
+	select HEXAGON_ARCH_V2
+	---help---
+	  Support for the Comet platform.
+
+endchoice
+
+config HEXAGON_VM
+	def_bool y
+
+config CMDLINE
+	string "Default kernel command string"
+	default ""
+	help
+	  On some platforms, there is currently no way for the boot loader
+	  to pass arguments to the kernel. For these, you should supply some
+	  command-line options at build time by entering them here.  At a
+	  minimum, you should specify the memory size and the root device
+	  (e.g., mem=64M root=/dev/nfs).
+
+config HEXAGON_ANGEL_TRAPS
+	bool "Use Angel Traps"
+	default n
+	---help---
+	  Enable angel debug traps (for printk's).
+
+config SMP
+	bool "Multi-Processing support"
+	---help---
+	  Enables SMP support in the kernel.  If unsure, say "Y"
+
+config NR_CPUS
+	int "Maximum number of CPUs" if SMP
+	range 2 6 if SMP
+	default "1" if !SMP
+	default "6" if SMP
+	---help---
+	  This allows you to specify the maximum number of CPUs which this
+	  kernel will support.  The maximum supported value is 6 and the
+	  minimum value which makes sense is 2.
+
+	  This is purely to save memory - each supported CPU adds
+	  approximately eight kilobytes to the kernel image.
+
+choice
+	prompt "Kernel page size"
+	default PAGE_SIZE_4KB
+	---help---
+	  Changes the default page size; use with caution.
+
+config PAGE_SIZE_4KB
+	bool "4KB"
+
+config PAGE_SIZE_16KB
+	bool "16KB"
+
+config PAGE_SIZE_64KB
+	bool "64KB"
+
+config PAGE_SIZE_256KB
+	bool "256KB"
+
+endchoice
+
+source "mm/Kconfig"
+
+source "kernel/Kconfig.hz"
+source "kernel/time/Kconfig"
+
+config GENERIC_GPIO
+	bool "Generic GPIO support"
+	default n
+
+endmenu
+
+source "init/Kconfig"
+source "drivers/Kconfig"
+source "fs/Kconfig"
+
+menu "Executable File Formats"
+source "fs/Kconfig.binfmt"
+endmenu
+
+source "net/Kconfig"
+source "security/Kconfig"
+source "crypto/Kconfig"
+source "lib/Kconfig"
+
+menu "Kernel hacking"
+source "lib/Kconfig.debug"
+endmenu
arch/hexagon/kernel/asm-offsets.c new file +104 -0

104 lines not on this page · raw message

arch/hexagon/kernel/vmlinux.lds.S new file +93 -0

93 lines not on this page · raw message

arch/hexagon/lib/Makefile new file +4 -0
Index: linux-hexagon-kernel/arch/hexagon/lib/Makefile
===================================================================
@@ -0,0 +1,4 @@
+#
+# Makefile for hexagon-specific library files.
+#
+obj-y = checksum.o io.o memcpy.o memset.o
arch/hexagon/Makefile new file +59 -0

59 lines not on this page · raw message

arch/hexagon/mm/Makefile new file +7 -0
Index: linux-hexagon-kernel/arch/hexagon/mm/Makefile
===================================================================
@@ -0,0 +1,7 @@
+#
+# Makefile for Hexagon memory management subsystem
+#
+
+obj-y := init.o pgalloc.o ioremap.o uaccess.o vm_fault.o cache.o
+obj-y += copy_to_user.o copy_from_user.o strnlen_user.o vm_tlb.o
+
arch/hexagon/kernel/Makefile new file +19 -0
Index: linux-hexagon-kernel/arch/hexagon/kernel/Makefile
===================================================================
@@ -0,0 +1,19 @@
+extra-y := head.o vmlinux.lds init_task.o
+
+obj-$(CONFIG_SMP) += smp.o topology.o
+
+obj-y += irq.o setup.o irq_cpu.o traps.o syscalltab.o signal.o time.o
+obj-y += process.o syscall.o trampoline.o reset.o ptrace.o
+obj-y += delay.o
+
+obj-$(CONFIG_KGDB)    += kgdb.o
+obj-$(CONFIG_MODULES) += module.o hexagon_ksyms.o
+
+# Modules required to work with the Hexagon Virtual Machine
+obj-y += vm_entry.o vm_events.o vm_switch.o vm_ops.o vm_init_segtable.o
+obj-y += vm_vectors.o
+
+obj-$(CONFIG_HAS_DMA) += dma.o
+
+obj-$(CONFIG_STACKTRACE) += stacktrace.o
+

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#75 lore raw

PATCH v2 34/35 Hexagon: Add basic stacktrace functionality for Hexagon architecture.

In reply to Richard Kuo
---
 arch/hexagon/kernel/stacktrace.c |   66 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)
arch/hexagon/kernel/stacktrace.c new file +66 -0
Index: linux-hexagon-kernel/arch/hexagon/kernel/stacktrace.c
===================================================================
@@ -0,0 +1,66 @@
+/*
+ * Stacktrace support for Hexagon
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+#include <linux/thread_info.h>
+#include <linux/module.h>
+
+register unsigned long current_frame_pointer asm("r30");
+
+struct stackframe {
+	unsigned long fp;
+	unsigned long rets;
+};
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer.
+ */
+void save_stack_trace(struct stack_trace *trace)
+{
+	unsigned long low, high;
+	unsigned long fp;
+	struct stackframe *frame;
+	int skip = trace->skip;
+
+	low = (unsigned long)task_stack_page(current);
+	high = low + THREAD_SIZE;
+	fp = current_frame_pointer;
+
+	while (fp >= low && fp <= (high - sizeof(*frame))) {
+		frame = (struct stackframe *)fp;
+
+		if (skip) {
+			skip--;
+		} else {
+			trace->entries[trace->nr_entries++] = frame->rets;
+			if (trace->nr_entries >= trace->max_entries)
+				break;
+		}
+
+		/*
+		 * The next frame must be at a higher address than the
+		 * current frame.
+		 */
+		low = fp + sizeof(*frame);
+		fp = frame->fp;
+	}
+}
+EXPORT_SYMBOL_GPL(save_stack_trace);

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#77 lore raw

PATCH v2 35/35 Hexagon: Add self to MAINTAINERS

In reply to Richard Kuo
---
 MAINTAINERS |    6 ++++++
 1 file changed, 6 insertions(+)
MAINTAINERS +6 -0
Index: linux-hexagon-kernel/MAINTAINERS
===================================================================
@@ -5279,6 +5279,12 @@
 F:	include/linux/qnx4_fs.h
 F:	include/linux/qnxtypes.h
 
+QUALCOMM HEXAGON ARCHITECTURE
+M:	Richard Kuo <[email protected]>
+L:	[email protected]
+S:	Supported
+F:	arch/hexagon/
+
 RADOS BLOCK DEVICE (RBD)
 F:	include/linux/qnxtypes.h
 M:	Yehuda Sadeh <[email protected]>

--

Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

#79 lore raw
In reply to Richard Kuo
Quoted 2 lines · Richard Kuo

Thanks to everyone for their comments/feedback!  If I missed anything or there's something else that needs cleanup, please let me know.

Are there any publicly available references for the architecture? Googling for "Qualcomm Hexagon" doesn't seem to find anything interesting.
--
To unsubscribe from this list: send the line "unsubscribe linux-hexagon" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#80 lore raw
Quoted 7 lines · Pekka Enberg
Quoted 2 lines · Richard Kuo

Thanks to everyone for their comments/feedback!  If I missed anything or there's something else that needs cleanup, please let me know.

Are there any publicly available references for the architecture? Googling for "Qualcomm Hexagon" doesn't seem to find anything interesting.

The main developer page is at
https://developer.qualcomm.com/hexagon-processor

The specs listed there include:

|> Hexagon V2 Programmer’s Reference Manual (80-NB419-1)
|> https://developer.qualcomm.com/file/5117/80-nb419-1ahexagonv2programmersref.pdf
|> Describes the Hexagon V2 processor architecture and instruction set.
|> 
|> Hexagon Application Binary Interface Specification (80-NB419-2)
|> https://developer.qualcomm.com/file/5119/80-nb419-2ahexagonabispec.pdf
|> Describes the application binary interface (ABI) for the Hexagon V2, V3, and V4 processor versions. Topics covered include the hardware representation of C data types, software stack configuration, parameter passing, register usage across function calls, and C++ exception handling.
|> 
|> Hexagon Virtual Machine Specification (80-NB419-3)
|> https://developer.qualcomm.com/file/5118/80-nb419-3ahexagonvirtualmachinespec.pdf
|> Describes the Hexagon Virtual Machine (HVM), a software abstraction layer which enables multiple operating systems and other clients to execute concurrently on a single Hexagon processor, through the virtualization and partitioning of physical hardware resources.

Access to these seems to require registration ...

--linas

Signature · 6 lines
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
--
To unsubscribe from this list: send the line "unsubscribe linux-hexagon" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#81 lore raw
In reply to Richard Kuo
Quoted 7 lines · Richard Kuo

This is the second version of the patchset to the Linux kernel to support the Qualcomm Hexagon architecture. These patches have been organized like the last time, in a somewhat logically grouped fashion.

A summary of changes from the last patchset:

Quoted 14 lines

* use Kbuild method for strictly asm-generic headers
* clean up dma sync and implement clean/invalidate
* bitops fl*/ff* cleanup
* added inline assembly version of atomic_add_unless
* removed deprecated syscalls/defines
* call __vmyield for cpu_relax and fix cpu_idle
* clean up thread_info; use arch allocator to allow kernel stack sizes smaller than page size
* implement read_timer_counter
* changed checksum to pull non-asm functions from generic code
* delete module functions which already have generic equivalents
* cleaned up IO routines
* reduced comet_defconfig
* remove ugly platform code

Excellent work!

I've looked through it again and noticed a few things that I had not seen in the first round and some that you changed but that I still think need to be changed again.

On the whole, I think this is good to go into 3.2.

Arnd