Go to file
Maciej W. Rozycki f3235d3207 MIPS: MIPS16e2: Subdecode extended LWSP/SWSP instructions
Implement extended LWSP/SWSP instruction subdecoding for the purpose of
unaligned GP-relative memory access emulation.

With the introduction of the MIPS16e2 ASE[1] the previously must-be-zero
3-bit field at bits 7..5 of the extended encodings of the instructions
selected with the LWSP and SWSP major opcodes has become a `sel' field,
acting as an opcode extension for additional operations.  In both cases
the `sel' value of 0 has retained the original operation, that is:

	LW	rx, offset(sp)

and:

	SW	rx, offset(sp)

for LWSP and SWSP respectively.  In hardware predating the MIPS16e2 ASE
other values may or may not have been decoded, architecturally yielding
unpredictable results, and in our unaligned memory access emulation we
have treated the 3-bit field as a don't-care, that is effectively making
all the possible encodings of the field alias to the architecturally
defined encoding of 0.

For the non-zero values of the `sel' field the MIPS16e2 ASE has in
particular defined these GP-relative operations:

	LW	rx, offset(gp)		# sel = 1
	LH	rx, offset(gp)		# sel = 2
	LHU	rx, offset(gp)		# sel = 4

and

	SW	rx, offset(gp)		# sel = 1
	SH	rx, offset(gp)		# sel = 2

for LWSP and SWSP respectively, which will trap with an Address Error
exception if the effective address calculated is not naturally-aligned
for the operation requested.  These operations have been selected for
unaligned access emulation, for consistency with the corresponding
regular MIPS and microMIPS operations.

For other non-zero values of the `sel' field the MIPS16e2 ASE has
defined further operations, which however either never trap with an
Address Error exception, such as LWL or GP-relative SB, or are not
supposed to be emulated, such as LL or SC.  These operations have been
selected to exclude from unaligned access emulation, should an Address
Error exception ever happen with them.

Subdecode the `sel' field in unaligned access emulation then for the
extended encodings of the instructions selected with the LWSP and SWSP
major opcodes, whenever support for the MIPS16e2 ASE has been detected
in hardware, and either emulate the operation requested or send SIGBUS
to the originating process, according to the selection described above.
For hardware implementing the MIPS16 ASE, however lacking MIPS16e2 ASE
support retain the original interpretation of the `sel' field.

The effects of this change are illustrated with the following user
program:

$ cat mips16e2-test.c
#include <inttypes.h>
#include <stdio.h>

int main(void)
{
	int64_t scratch[16] = { 0 };
	int32_t *tmp0, *tmp1, *tmp2;
	int i;

	scratch[0] = 0xc8c7c6c5c4c3c2c1;
	scratch[1] = 0xd0cfcecdcccbcac9;

	asm volatile(
		"move	%0, $sp\n\t"
		"move	%1, $gp\n\t"
		"move	$sp, %4\n\t"
		"addiu	%2, %4, 8\n\t"
		"move	$gp, %2\n\t"

		"lw	%2, 2($sp)\n\t"
		"sw	%2, 16(%4)\n\t"
		"lw	%2, 2($gp)\n\t"
		"sw	%2, 24(%4)\n\t"

		"lw	%2, 1($sp)\n\t"
		"sw	%2, 32(%4)\n\t"
		"lh	%2, 1($gp)\n\t"
		"sw	%2, 40(%4)\n\t"

		"lw	%2, 3($sp)\n\t"
		"sw	%2, 48(%4)\n\t"
		"lhu	%2, 3($gp)\n\t"
		"sw	%2, 56(%4)\n\t"

		"lw	%2, 0(%4)\n\t"
		"sw	%2, 66($sp)\n\t"
		"lw	%2, 8(%4)\n\t"
		"sw	%2, 82($gp)\n\t"

		"lw	%2, 0(%4)\n\t"
		"sw	%2, 97($sp)\n\t"
		"lw	%2, 8(%4)\n\t"
		"sh	%2, 113($gp)\n\t"

		"move	$gp, %1\n\t"
		"move	$sp, %0"
		: "=&d" (tmp0), "=&d" (tmp1), "=&d" (tmp2), "=m" (scratch)
		: "d" (scratch));

	for (i = 0; i < sizeof(scratch) / sizeof(*scratch); i += 2)
		printf("%016" PRIx64 "\t%016" PRIx64 "\n",
		       scratch[i], scratch[i + 1]);

	return 0;
}
$

to be compiled with:

$ gcc -mips16 -mips32r2 -Wa,-mmips16e2 -o mips16e2-test mips16e2-test.c
$

With 74Kf hardware, which does not implement the MIPS16e2 ASE, this
program produces the following output:

$ ./mips16e2-test
c8c7c6c5c4c3c2c1        d0cfcecdcccbcac9
00000000c6c5c4c3        00000000c6c5c4c3
00000000c5c4c3c2        00000000c5c4c3c2
00000000c7c6c5c4        00000000c7c6c5c4
0000c4c3c2c10000        0000000000000000
0000cccbcac90000        0000000000000000
000000c4c3c2c100        0000000000000000
000000cccbcac900        0000000000000000
$

regardless of whether the change has been applied or not.

With the change not applied and interAptive MR2 hardware[2], which does
implement the MIPS16e2 ASE, it produces the following output:

$ ./mips16e2-test
c8c7c6c5c4c3c2c1        d0cfcecdcccbcac9
00000000c6c5c4c3        00000000cecdcccb
00000000c5c4c3c2        00000000cdcccbca
00000000c7c6c5c4        00000000cfcecdcc
0000c4c3c2c10000        0000000000000000
0000000000000000        0000cccbcac90000
000000c4c3c2c100        0000000000000000
0000000000000000        000000cccbcac900
$

which shows that for GP-relative operations the correct trapping address
calculated from $gp has been obtained from the CP0 BadVAddr register and
so has data from the source operand, however masking and extension has
not been applied for halfword operations.

With the change applied and interAptive MR2 hardware the program
produces the following output:

$ ./mips16e2-test
c8c7c6c5c4c3c2c1        d0cfcecdcccbcac9
00000000c6c5c4c3        00000000cecdcccb
00000000c5c4c3c2        00000000ffffcbca
00000000c7c6c5c4        000000000000cdcc
0000c4c3c2c10000        0000000000000000
0000000000000000        0000cccbcac90000
000000c4c3c2c100        0000000000000000
0000000000000000        0000000000cac900
$

as expected.

References:

[1] "MIPS32 Architecture for Programmers: MIPS16e2 Application-Specific
    Extension Technical Reference Manual", Imagination Technologies
    Ltd., Document Number: MD01172, Revision 01.00, April 26, 2016

[2] "MIPS32 interAptiv Multiprocessing System Software User's Manual",
    Imagination Technologies Ltd., Document Number: MD00904, Revision
    02.01, June 15, 2016, Chapter 24 "MIPS16e Application-Specific
    Extension to the MIPS32 Instruction Set", pp. 871-883

Signed-off-by: Maciej W. Rozycki <macro@imgtec.com>
Reviewed-by: James Hogan <james.hogan@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/16095/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2017-07-05 14:07:20 +02:00
Documentation A single GPIO patch fixing the compatible string for the 2017-06-23 17:40:41 -07:00
arch MIPS: MIPS16e2: Subdecode extended LWSP/SWSP instructions 2017-07-05 14:07:20 +02:00
block blk-mq: fix performance regression with shared tags 2017-06-21 10:17:49 -06:00
certs scripts/spelling.txt: add "intialise(d)" pattern and fix typo instances 2017-05-08 17:15:13 -07:00
crypto crypto : asymmetric_keys : verify_pefile:zero memory content before freeing 2017-06-09 13:29:50 +10:00
drivers MIPS: Loongson-3: Support 4 packages in CPU Hwmon driver 2017-06-29 02:42:22 +02:00
firmware firmware/Makefile: force recompilation if makefile changes 2017-05-08 17:15:10 -07:00
fs Merge branch 'akpm' (patches from Andrew) 2017-06-23 16:30:52 -07:00
include Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2017-06-25 11:59:19 -07:00
init Merge branch 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2017-05-10 10:30:46 -07:00
ipc mm: introduce kv[mz]alloc helpers 2017-05-08 17:15:12 -07:00
kernel Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2017-06-25 11:59:19 -07:00
lib lib/cmdline.c: fix get_options() overflow while parsing ranges 2017-06-23 16:15:55 -07:00
mm slub: make sysfs file removal asynchronous 2017-06-23 16:15:55 -07:00
net igmp: add a missing spin_lock_init() 2017-06-20 15:51:57 -04:00
samples samples/bpf: run cleanup routines when receiving SIGTERM 2017-05-11 21:43:30 -04:00
scripts Kbuild fixes for v4.12 (2nd) 2017-06-24 16:18:00 -07:00
security selinux: fix double free in selinux_parse_opts_str() 2017-06-13 17:34:22 +10:00
sound ALSA: hda - Apply quirks to Broxton-T, too 2017-06-20 07:52:49 +02:00
tools perf probe: Fix probe definition for inlined functions 2017-06-22 16:08:09 -03:00
usr initramfs: fix disabling of initramfs (and its compression) 2017-06-02 15:07:37 -07:00
virt KVM: arm/arm64: Handle possible NULL stage2 pud when ageing pages 2017-06-06 15:28:40 +02:00
.cocciconfig scripts: add Linux .cocciconfig for coccinelle 2016-07-22 12:13:39 +02:00
.get_maintainer.ignore Add hch to .get_maintainer.ignore 2015-08-21 14:30:10 -07:00
.gitattributes .gitattributes: set git diff driver for C source code files 2016-10-07 18:46:30 -07:00
.gitignore kbuild: Add support to generate LLVM assembly files 2017-04-25 08:13:52 +09:00
.mailmap power supply and reset changes for the v4.12 series (part 2) 2017-05-12 12:02:21 -07:00
COPYING
CREDITS avr32: remove support for AVR32 architecture 2017-05-01 09:27:15 +02:00
Kbuild kbuild: Consolidate header generation from ASM offset information 2017-04-13 05:43:37 +09:00
Kconfig
MAINTAINERS MIPS: generic: Add a MAINTAINERS entry 2017-06-28 12:22:41 +02:00
Makefile Linux 4.12-rc7 2017-06-25 18:30:05 -07:00
README README: add a new README file, pointing to the Documentation/ 2016-10-24 08:12:35 -02:00

README

Linux kernel
============

This file was moved to Documentation/admin-guide/README.rst

Please notice that there are several guides for kernel developers and users.
These guides can be rendered in a number of formats, like HTML and PDF.

In order to build the documentation, use ``make htmldocs`` or
``make pdfdocs``.

There are various text files in the Documentation/ subdirectory,
several of them using the Restructured Text markup notation.
See Documentation/00-INDEX for a list of what is contained in each file.

Please read the Documentation/process/changes.rst file, as it contains the
requirements for building and running the kernel, and information about
the problems which may result by upgrading your kernel.