Merge 67c642e0d9 ("Merge tag 'csky-for-linus-5.19-rc1' of https://github.com/c-sky/csky-linux") into android-mainline
Steps on the way to 5.19-rc1 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ifdd37ecce85351120f8ae7d4143bf48d671002d4
This commit is contained in:
@@ -467,3 +467,39 @@ Description: These files provide the maximum powered required for line card
|
||||
feeding and line card configuration Id.
|
||||
|
||||
The files are read only.
|
||||
|
||||
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/phy_reset
|
||||
Date: May 2022
|
||||
KernelVersion: 5.19
|
||||
Contact: Vadim Pasternak <vadimpmellanox.com>
|
||||
Description: This file allows to reset PHY 88E1548 when attribute is set 0
|
||||
due to some abnormal PHY behavior.
|
||||
Expected behavior:
|
||||
When phy_reset is written 1, all PHY 88E1548 are released
|
||||
from the reset state, when 0 - are hold in reset state.
|
||||
|
||||
The files are read/write.
|
||||
|
||||
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/mac_reset
|
||||
Date: May 2022
|
||||
KernelVersion: 5.19
|
||||
Contact: Vadim Pasternak <vadimpmellanox.com>
|
||||
Description: This file allows to reset ASIC MT52132 when attribute is set 0
|
||||
due to some abnormal ASIC behavior.
|
||||
Expected behavior:
|
||||
When mac_reset is written 1, the ASIC MT52132 is released
|
||||
from the reset state, when 0 - is hold in reset state.
|
||||
|
||||
The files are read/write.
|
||||
|
||||
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/qsfp_pwr_good
|
||||
Date: May 2022
|
||||
KernelVersion: 5.19
|
||||
Contact: Vadim Pasternak <vadimpmellanox.com>
|
||||
Description: This file shows QSFP ports power status. The value is set to 0
|
||||
when one of any QSFP ports is plugged. The value is set to 1 when
|
||||
there are no any QSFP ports are plugged.
|
||||
The possible values are:
|
||||
0 - Power good, 1 - Not power good.
|
||||
|
||||
The files are read only.
|
||||
|
||||
@@ -29,7 +29,7 @@ Description:
|
||||
What: /sys/module/xen_blkback/parameters/buffer_squeeze_duration_ms
|
||||
Date: December 2019
|
||||
KernelVersion: 5.6
|
||||
Contact: SeongJae Park <sj@kernel.org>
|
||||
Contact: Maximilian Heyne <mheyne@amazon.de>
|
||||
Description:
|
||||
When memory pressure is reported to blkback this option
|
||||
controls the duration in milliseconds that blkback will not
|
||||
@@ -39,7 +39,7 @@ Description:
|
||||
What: /sys/module/xen_blkback/parameters/feature_persistent
|
||||
Date: September 2020
|
||||
KernelVersion: 5.10
|
||||
Contact: SeongJae Park <sj@kernel.org>
|
||||
Contact: Maximilian Heyne <mheyne@amazon.de>
|
||||
Description:
|
||||
Whether to enable the persistent grants feature or not. Note
|
||||
that this option only takes effect on newly created backends.
|
||||
|
||||
@@ -12,7 +12,7 @@ Description:
|
||||
What: /sys/module/xen_blkfront/parameters/feature_persistent
|
||||
Date: September 2020
|
||||
KernelVersion: 5.10
|
||||
Contact: SeongJae Park <sj@kernel.org>
|
||||
Contact: Maximilian Heyne <mheyne@amazon.de>
|
||||
Description:
|
||||
Whether to enable the persistent grants feature or not. Note
|
||||
that this option only takes effect on newly created frontends.
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
What: /sys/devices/virtual/misc/intel_ifs_<N>/run_test
|
||||
Date: April 21 2022
|
||||
KernelVersion: 5.19
|
||||
Contact: "Jithu Joseph" <jithu.joseph@intel.com>
|
||||
Description: Write <cpu#> to trigger IFS test for one online core.
|
||||
Note that the test is per core. The cpu# can be
|
||||
for any thread on the core. Running on one thread
|
||||
completes the test for the core containing that thread.
|
||||
Example: to test the core containing cpu5: echo 5 >
|
||||
/sys/devices/platform/intel_ifs.<N>/run_test
|
||||
|
||||
What: /sys/devices/virtual/misc/intel_ifs_<N>/status
|
||||
Date: April 21 2022
|
||||
KernelVersion: 5.19
|
||||
Contact: "Jithu Joseph" <jithu.joseph@intel.com>
|
||||
Description: The status of the last test. It can be one of "pass", "fail"
|
||||
or "untested".
|
||||
|
||||
What: /sys/devices/virtual/misc/intel_ifs_<N>/details
|
||||
Date: April 21 2022
|
||||
KernelVersion: 5.19
|
||||
Contact: "Jithu Joseph" <jithu.joseph@intel.com>
|
||||
Description: Additional information regarding the last test. The details file reports
|
||||
the hex value of the SCAN_STATUS MSR. Note that the error_code field
|
||||
may contain driver defined software code not defined in the Intel SDM.
|
||||
|
||||
What: /sys/devices/virtual/misc/intel_ifs_<N>/image_version
|
||||
Date: April 21 2022
|
||||
KernelVersion: 5.19
|
||||
Contact: "Jithu Joseph" <jithu.joseph@intel.com>
|
||||
Description: Version (hexadecimal) of loaded IFS binary image. If no scan image
|
||||
is loaded reports "none".
|
||||
|
||||
What: /sys/devices/virtual/misc/intel_ifs_<N>/reload
|
||||
Date: April 21 2022
|
||||
KernelVersion: 5.19
|
||||
Contact: "Jithu Joseph" <jithu.joseph@intel.com>
|
||||
Description: Write "1" (or "y" or "Y") to reload the IFS image from
|
||||
/lib/firmware/intel/ifs/ff-mm-ss.scan.
|
||||
@@ -27,5 +27,5 @@
|
||||
| sparc: | TODO |
|
||||
| um: | TODO |
|
||||
| x86: | ok |
|
||||
| xtensa: | TODO |
|
||||
| xtensa: | ok |
|
||||
-----------------------
|
||||
|
||||
@@ -27,5 +27,5 @@
|
||||
| sparc: | ok |
|
||||
| um: | TODO |
|
||||
| x86: | ok |
|
||||
| xtensa: | TODO |
|
||||
| xtensa: | ok |
|
||||
-----------------------
|
||||
|
||||
@@ -27,5 +27,5 @@
|
||||
| sparc: | ok |
|
||||
| um: | TODO |
|
||||
| x86: | ok |
|
||||
| xtensa: | TODO |
|
||||
| xtensa: | ok |
|
||||
-----------------------
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
.. kernel-doc:: drivers/platform/x86/intel/ifs/ifs.h
|
||||
@@ -36,6 +36,7 @@ x86-specific Documentation
|
||||
usb-legacy-support
|
||||
i386/index
|
||||
x86_64/index
|
||||
ifs
|
||||
sva
|
||||
sgx
|
||||
features
|
||||
|
||||
@@ -9870,6 +9870,14 @@ B: https://bugzilla.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git
|
||||
F: drivers/idle/intel_idle.c
|
||||
|
||||
INTEL IN FIELD SCAN (IFS) DEVICE
|
||||
M: Jithu Joseph <jithu.joseph@intel.com>
|
||||
R: Ashok Raj <ashok.raj@intel.com>
|
||||
R: Tony Luck <tony.luck@intel.com>
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/intel/ifs
|
||||
F: include/trace/events/intel_ifs.h
|
||||
|
||||
INTEL INTEGRATED SENSOR HUB DRIVER
|
||||
M: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
|
||||
M: Jiri Kosina <jikos@kernel.org>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
obj-y += kernel/ mm/
|
||||
|
||||
# for cleaning
|
||||
subdir- += boot
|
||||
|
||||
@@ -320,6 +320,14 @@ config HOTPLUG_CPU
|
||||
controlled through /sys/devices/system/cpu/cpu1/hotplug/target.
|
||||
|
||||
Say N if you want to disable CPU hotplug.
|
||||
|
||||
config HAVE_EFFICIENT_UNALIGNED_STRING_OPS
|
||||
bool "Enable EFFICIENT_UNALIGNED_STRING_OPS for abiv2"
|
||||
depends on CPU_CK807 || CPU_CK810 || CPU_CK860
|
||||
help
|
||||
Say Y here to enable EFFICIENT_UNALIGNED_STRING_OPS. Some CPU models could
|
||||
deal with unaligned access by hardware.
|
||||
|
||||
endmenu
|
||||
|
||||
source "arch/csky/Kconfig.platforms"
|
||||
|
||||
@@ -61,15 +61,12 @@ KBUILD_AFLAGS += $(KBUILD_CFLAGS)
|
||||
|
||||
head-y := arch/csky/kernel/head.o
|
||||
|
||||
core-y += arch/csky/kernel/
|
||||
core-y += arch/csky/mm/
|
||||
core-y += arch/csky/$(CSKYABI)/
|
||||
|
||||
libs-y += arch/csky/lib/ \
|
||||
$(shell $(CC) $(KBUILD_CFLAGS) $(KCFLAGS) -print-libgcc-file-name)
|
||||
|
||||
boot := arch/csky/boot
|
||||
core-y += $(boot)/dts/
|
||||
|
||||
all: zImage
|
||||
|
||||
|
||||
@@ -4,5 +4,3 @@ obj-y += bswapdi.o
|
||||
obj-y += bswapsi.o
|
||||
obj-y += cacheflush.o
|
||||
obj-y += mmap.o
|
||||
obj-y += memcpy.o
|
||||
obj-y += strksyms.o
|
||||
|
||||
@@ -1,347 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
|
||||
|
||||
#include <linux/linkage.h>
|
||||
|
||||
.macro GET_FRONT_BITS rx y
|
||||
#ifdef __cskyLE__
|
||||
lsri \rx, \y
|
||||
#else
|
||||
lsli \rx, \y
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro GET_AFTER_BITS rx y
|
||||
#ifdef __cskyLE__
|
||||
lsli \rx, \y
|
||||
#else
|
||||
lsri \rx, \y
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/* void *memcpy(void *dest, const void *src, size_t n); */
|
||||
ENTRY(memcpy)
|
||||
mov r7, r2
|
||||
cmplti r4, 4
|
||||
bt .L_copy_by_byte
|
||||
mov r6, r2
|
||||
andi r6, 3
|
||||
cmpnei r6, 0
|
||||
jbt .L_dest_not_aligned
|
||||
mov r6, r3
|
||||
andi r6, 3
|
||||
cmpnei r6, 0
|
||||
jbt .L_dest_aligned_but_src_not_aligned
|
||||
.L0:
|
||||
cmplti r4, 16
|
||||
jbt .L_aligned_and_len_less_16bytes
|
||||
subi sp, 8
|
||||
stw r8, (sp, 0)
|
||||
.L_aligned_and_len_larger_16bytes:
|
||||
ldw r1, (r3, 0)
|
||||
ldw r5, (r3, 4)
|
||||
ldw r8, (r3, 8)
|
||||
stw r1, (r7, 0)
|
||||
ldw r1, (r3, 12)
|
||||
stw r5, (r7, 4)
|
||||
stw r8, (r7, 8)
|
||||
stw r1, (r7, 12)
|
||||
subi r4, 16
|
||||
addi r3, 16
|
||||
addi r7, 16
|
||||
cmplti r4, 16
|
||||
jbf .L_aligned_and_len_larger_16bytes
|
||||
ldw r8, (sp, 0)
|
||||
addi sp, 8
|
||||
cmpnei r4, 0
|
||||
jbf .L_return
|
||||
|
||||
.L_aligned_and_len_less_16bytes:
|
||||
cmplti r4, 4
|
||||
bt .L_copy_by_byte
|
||||
.L1:
|
||||
ldw r1, (r3, 0)
|
||||
stw r1, (r7, 0)
|
||||
subi r4, 4
|
||||
addi r3, 4
|
||||
addi r7, 4
|
||||
cmplti r4, 4
|
||||
jbf .L1
|
||||
br .L_copy_by_byte
|
||||
|
||||
.L_return:
|
||||
rts
|
||||
|
||||
.L_copy_by_byte: /* len less than 4 bytes */
|
||||
cmpnei r4, 0
|
||||
jbf .L_return
|
||||
.L4:
|
||||
ldb r1, (r3, 0)
|
||||
stb r1, (r7, 0)
|
||||
addi r3, 1
|
||||
addi r7, 1
|
||||
decne r4
|
||||
jbt .L4
|
||||
rts
|
||||
|
||||
/*
|
||||
* If dest is not aligned, just copying some bytes makes the dest align.
|
||||
* Afther that, we judge whether the src is aligned.
|
||||
*/
|
||||
.L_dest_not_aligned:
|
||||
mov r5, r3
|
||||
rsub r5, r5, r7
|
||||
abs r5, r5
|
||||
cmplt r5, r4
|
||||
bt .L_copy_by_byte
|
||||
mov r5, r7
|
||||
sub r5, r3
|
||||
cmphs r5, r4
|
||||
bf .L_copy_by_byte
|
||||
mov r5, r6
|
||||
.L5:
|
||||
ldb r1, (r3, 0) /* makes the dest align. */
|
||||
stb r1, (r7, 0)
|
||||
addi r5, 1
|
||||
subi r4, 1
|
||||
addi r3, 1
|
||||
addi r7, 1
|
||||
cmpnei r5, 4
|
||||
jbt .L5
|
||||
cmplti r4, 4
|
||||
jbt .L_copy_by_byte
|
||||
mov r6, r3 /* judge whether the src is aligned. */
|
||||
andi r6, 3
|
||||
cmpnei r6, 0
|
||||
jbf .L0
|
||||
|
||||
/* Judge the number of misaligned, 1, 2, 3? */
|
||||
.L_dest_aligned_but_src_not_aligned:
|
||||
mov r5, r3
|
||||
rsub r5, r5, r7
|
||||
abs r5, r5
|
||||
cmplt r5, r4
|
||||
bt .L_copy_by_byte
|
||||
bclri r3, 0
|
||||
bclri r3, 1
|
||||
ldw r1, (r3, 0)
|
||||
addi r3, 4
|
||||
cmpnei r6, 2
|
||||
bf .L_dest_aligned_but_src_not_aligned_2bytes
|
||||
cmpnei r6, 3
|
||||
bf .L_dest_aligned_but_src_not_aligned_3bytes
|
||||
|
||||
.L_dest_aligned_but_src_not_aligned_1byte:
|
||||
mov r5, r7
|
||||
sub r5, r3
|
||||
cmphs r5, r4
|
||||
bf .L_copy_by_byte
|
||||
cmplti r4, 16
|
||||
bf .L11
|
||||
.L10: /* If the len is less than 16 bytes */
|
||||
GET_FRONT_BITS r1 8
|
||||
mov r5, r1
|
||||
ldw r6, (r3, 0)
|
||||
mov r1, r6
|
||||
GET_AFTER_BITS r6 24
|
||||
or r5, r6
|
||||
stw r5, (r7, 0)
|
||||
subi r4, 4
|
||||
addi r3, 4
|
||||
addi r7, 4
|
||||
cmplti r4, 4
|
||||
bf .L10
|
||||
subi r3, 3
|
||||
br .L_copy_by_byte
|
||||
.L11:
|
||||
subi sp, 16
|
||||
stw r8, (sp, 0)
|
||||
stw r9, (sp, 4)
|
||||
stw r10, (sp, 8)
|
||||
stw r11, (sp, 12)
|
||||
.L12:
|
||||
ldw r5, (r3, 0)
|
||||
ldw r11, (r3, 4)
|
||||
ldw r8, (r3, 8)
|
||||
ldw r9, (r3, 12)
|
||||
|
||||
GET_FRONT_BITS r1 8 /* little or big endian? */
|
||||
mov r10, r5
|
||||
GET_AFTER_BITS r5 24
|
||||
or r5, r1
|
||||
|
||||
GET_FRONT_BITS r10 8
|
||||
mov r1, r11
|
||||
GET_AFTER_BITS r11 24
|
||||
or r11, r10
|
||||
|
||||
GET_FRONT_BITS r1 8
|
||||
mov r10, r8
|
||||
GET_AFTER_BITS r8 24
|
||||
or r8, r1
|
||||
|
||||
GET_FRONT_BITS r10 8
|
||||
mov r1, r9
|
||||
GET_AFTER_BITS r9 24
|
||||
or r9, r10
|
||||
|
||||
stw r5, (r7, 0)
|
||||
stw r11, (r7, 4)
|
||||
stw r8, (r7, 8)
|
||||
stw r9, (r7, 12)
|
||||
subi r4, 16
|
||||
addi r3, 16
|
||||
addi r7, 16
|
||||
cmplti r4, 16
|
||||
jbf .L12
|
||||
ldw r8, (sp, 0)
|
||||
ldw r9, (sp, 4)
|
||||
ldw r10, (sp, 8)
|
||||
ldw r11, (sp, 12)
|
||||
addi sp , 16
|
||||
cmplti r4, 4
|
||||
bf .L10
|
||||
subi r3, 3
|
||||
br .L_copy_by_byte
|
||||
|
||||
.L_dest_aligned_but_src_not_aligned_2bytes:
|
||||
cmplti r4, 16
|
||||
bf .L21
|
||||
.L20:
|
||||
GET_FRONT_BITS r1 16
|
||||
mov r5, r1
|
||||
ldw r6, (r3, 0)
|
||||
mov r1, r6
|
||||
GET_AFTER_BITS r6 16
|
||||
or r5, r6
|
||||
stw r5, (r7, 0)
|
||||
subi r4, 4
|
||||
addi r3, 4
|
||||
addi r7, 4
|
||||
cmplti r4, 4
|
||||
bf .L20
|
||||
subi r3, 2
|
||||
br .L_copy_by_byte
|
||||
rts
|
||||
|
||||
.L21: /* n > 16 */
|
||||
subi sp, 16
|
||||
stw r8, (sp, 0)
|
||||
stw r9, (sp, 4)
|
||||
stw r10, (sp, 8)
|
||||
stw r11, (sp, 12)
|
||||
|
||||
.L22:
|
||||
ldw r5, (r3, 0)
|
||||
ldw r11, (r3, 4)
|
||||
ldw r8, (r3, 8)
|
||||
ldw r9, (r3, 12)
|
||||
|
||||
GET_FRONT_BITS r1 16
|
||||
mov r10, r5
|
||||
GET_AFTER_BITS r5 16
|
||||
or r5, r1
|
||||
|
||||
GET_FRONT_BITS r10 16
|
||||
mov r1, r11
|
||||
GET_AFTER_BITS r11 16
|
||||
or r11, r10
|
||||
|
||||
GET_FRONT_BITS r1 16
|
||||
mov r10, r8
|
||||
GET_AFTER_BITS r8 16
|
||||
or r8, r1
|
||||
|
||||
GET_FRONT_BITS r10 16
|
||||
mov r1, r9
|
||||
GET_AFTER_BITS r9 16
|
||||
or r9, r10
|
||||
|
||||
stw r5, (r7, 0)
|
||||
stw r11, (r7, 4)
|
||||
stw r8, (r7, 8)
|
||||
stw r9, (r7, 12)
|
||||
subi r4, 16
|
||||
addi r3, 16
|
||||
addi r7, 16
|
||||
cmplti r4, 16
|
||||
jbf .L22
|
||||
ldw r8, (sp, 0)
|
||||
ldw r9, (sp, 4)
|
||||
ldw r10, (sp, 8)
|
||||
ldw r11, (sp, 12)
|
||||
addi sp, 16
|
||||
cmplti r4, 4
|
||||
bf .L20
|
||||
subi r3, 2
|
||||
br .L_copy_by_byte
|
||||
|
||||
|
||||
.L_dest_aligned_but_src_not_aligned_3bytes:
|
||||
cmplti r4, 16
|
||||
bf .L31
|
||||
.L30:
|
||||
GET_FRONT_BITS r1 24
|
||||
mov r5, r1
|
||||
ldw r6, (r3, 0)
|
||||
mov r1, r6
|
||||
GET_AFTER_BITS r6 8
|
||||
or r5, r6
|
||||
stw r5, (r7, 0)
|
||||
subi r4, 4
|
||||
addi r3, 4
|
||||
addi r7, 4
|
||||
cmplti r4, 4
|
||||
bf .L30
|
||||
subi r3, 1
|
||||
br .L_copy_by_byte
|
||||
.L31:
|
||||
subi sp, 16
|
||||
stw r8, (sp, 0)
|
||||
stw r9, (sp, 4)
|
||||
stw r10, (sp, 8)
|
||||
stw r11, (sp, 12)
|
||||
.L32:
|
||||
ldw r5, (r3, 0)
|
||||
ldw r11, (r3, 4)
|
||||
ldw r8, (r3, 8)
|
||||
ldw r9, (r3, 12)
|
||||
|
||||
GET_FRONT_BITS r1 24
|
||||
mov r10, r5
|
||||
GET_AFTER_BITS r5 8
|
||||
or r5, r1
|
||||
|
||||
GET_FRONT_BITS r10 24
|
||||
mov r1, r11
|
||||
GET_AFTER_BITS r11 8
|
||||
or r11, r10
|
||||
|
||||
GET_FRONT_BITS r1 24
|
||||
mov r10, r8
|
||||
GET_AFTER_BITS r8 8
|
||||
or r8, r1
|
||||
|
||||
GET_FRONT_BITS r10 24
|
||||
mov r1, r9
|
||||
GET_AFTER_BITS r9 8
|
||||
or r9, r10
|
||||
|
||||
stw r5, (r7, 0)
|
||||
stw r11, (r7, 4)
|
||||
stw r8, (r7, 8)
|
||||
stw r9, (r7, 12)
|
||||
subi r4, 16
|
||||
addi r3, 16
|
||||
addi r7, 16
|
||||
cmplti r4, 16
|
||||
jbf .L32
|
||||
ldw r8, (sp, 0)
|
||||
ldw r9, (sp, 4)
|
||||
ldw r10, (sp, 8)
|
||||
ldw r11, (sp, 12)
|
||||
addi sp, 16
|
||||
cmplti r4, 4
|
||||
bf .L30
|
||||
subi r3, 1
|
||||
br .L_copy_by_byte
|
||||
@@ -1,6 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
EXPORT_SYMBOL(memcpy);
|
||||
@@ -2,9 +2,11 @@
|
||||
obj-y += cacheflush.o
|
||||
obj-$(CONFIG_CPU_HAS_FPU) += fpu.o
|
||||
obj-y += memcmp.o
|
||||
ifeq ($(CONFIG_HAVE_EFFICIENT_UNALIGNED_STRING_OPS), y)
|
||||
obj-y += memcpy.o
|
||||
obj-y += memmove.o
|
||||
obj-y += memset.o
|
||||
endif
|
||||
obj-y += strcmp.o
|
||||
obj-y += strcpy.o
|
||||
obj-y += strlen.o
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_STRING_OPS
|
||||
EXPORT_SYMBOL(memcpy);
|
||||
EXPORT_SYMBOL(memset);
|
||||
EXPORT_SYMBOL(memcmp);
|
||||
EXPORT_SYMBOL(memmove);
|
||||
#endif
|
||||
EXPORT_SYMBOL(memcmp);
|
||||
EXPORT_SYMBOL(strcmp);
|
||||
EXPORT_SYMBOL(strcpy);
|
||||
EXPORT_SYMBOL(strlen);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
targets := Image zImage uImage
|
||||
targets += $(dtb-y)
|
||||
|
||||
$(obj)/Image: vmlinux FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef __ASM_CSKY_ATOMIC_H
|
||||
#define __ASM_CSKY_ATOMIC_H
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#include <asm-generic/atomic64.h>
|
||||
|
||||
#include <asm/cmpxchg.h>
|
||||
#include <asm/barrier.h>
|
||||
|
||||
#define __atomic_acquire_fence() __bar_brarw()
|
||||
|
||||
#define __atomic_release_fence() __bar_brwaw()
|
||||
|
||||
static __always_inline int arch_atomic_read(const atomic_t *v)
|
||||
{
|
||||
return READ_ONCE(v->counter);
|
||||
}
|
||||
static __always_inline void arch_atomic_set(atomic_t *v, int i)
|
||||
{
|
||||
WRITE_ONCE(v->counter, i);
|
||||
}
|
||||
|
||||
#define ATOMIC_OP(op) \
|
||||
static __always_inline \
|
||||
void arch_atomic_##op(int i, atomic_t *v) \
|
||||
{ \
|
||||
unsigned long tmp; \
|
||||
__asm__ __volatile__ ( \
|
||||
"1: ldex.w %0, (%2) \n" \
|
||||
" " #op " %0, %1 \n" \
|
||||
" stex.w %0, (%2) \n" \
|
||||
" bez %0, 1b \n" \
|
||||
: "=&r" (tmp) \
|
||||
: "r" (i), "r" (&v->counter) \
|
||||
: "memory"); \
|
||||
}
|
||||
|
||||
ATOMIC_OP(add)
|
||||
ATOMIC_OP(sub)
|
||||
ATOMIC_OP(and)
|
||||
ATOMIC_OP( or)
|
||||
ATOMIC_OP(xor)
|
||||
|
||||
#undef ATOMIC_OP
|
||||
|
||||
#define ATOMIC_FETCH_OP(op) \
|
||||
static __always_inline \
|
||||
int arch_atomic_fetch_##op##_relaxed(int i, atomic_t *v) \
|
||||
{ \
|
||||
register int ret, tmp; \
|
||||
__asm__ __volatile__ ( \
|
||||
"1: ldex.w %0, (%3) \n" \
|
||||
" mov %1, %0 \n" \
|
||||
" " #op " %0, %2 \n" \
|
||||
" stex.w %0, (%3) \n" \
|
||||
" bez %0, 1b \n" \
|
||||
: "=&r" (tmp), "=&r" (ret) \
|
||||
: "r" (i), "r"(&v->counter) \
|
||||
: "memory"); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define ATOMIC_OP_RETURN(op, c_op) \
|
||||
static __always_inline \
|
||||
int arch_atomic_##op##_return_relaxed(int i, atomic_t *v) \
|
||||
{ \
|
||||
return arch_atomic_fetch_##op##_relaxed(i, v) c_op i; \
|
||||
}
|
||||
|
||||
#define ATOMIC_OPS(op, c_op) \
|
||||
ATOMIC_FETCH_OP(op) \
|
||||
ATOMIC_OP_RETURN(op, c_op)
|
||||
|
||||
ATOMIC_OPS(add, +)
|
||||
ATOMIC_OPS(sub, -)
|
||||
|
||||
#define arch_atomic_fetch_add_relaxed arch_atomic_fetch_add_relaxed
|
||||
#define arch_atomic_fetch_sub_relaxed arch_atomic_fetch_sub_relaxed
|
||||
|
||||
#define arch_atomic_add_return_relaxed arch_atomic_add_return_relaxed
|
||||
#define arch_atomic_sub_return_relaxed arch_atomic_sub_return_relaxed
|
||||
|
||||
#undef ATOMIC_OPS
|
||||
#undef ATOMIC_OP_RETURN
|
||||
|
||||
#define ATOMIC_OPS(op) \
|
||||
ATOMIC_FETCH_OP(op)
|
||||
|
||||
ATOMIC_OPS(and)
|
||||
ATOMIC_OPS( or)
|
||||
ATOMIC_OPS(xor)
|
||||
|
||||
#define arch_atomic_fetch_and_relaxed arch_atomic_fetch_and_relaxed
|
||||
#define arch_atomic_fetch_or_relaxed arch_atomic_fetch_or_relaxed
|
||||
#define arch_atomic_fetch_xor_relaxed arch_atomic_fetch_xor_relaxed
|
||||
|
||||
#undef ATOMIC_OPS
|
||||
|
||||
#undef ATOMIC_FETCH_OP
|
||||
|
||||
static __always_inline int
|
||||
arch_atomic_fetch_add_unless(atomic_t *v, int a, int u)
|
||||
{
|
||||
int prev, tmp;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
RELEASE_FENCE
|
||||
"1: ldex.w %0, (%3) \n"
|
||||
" cmpne %0, %4 \n"
|
||||
" bf 2f \n"
|
||||
" mov %1, %0 \n"
|
||||
" add %1, %2 \n"
|
||||
" stex.w %1, (%3) \n"
|
||||
" bez %1, 1b \n"
|
||||
FULL_FENCE
|
||||
"2:\n"
|
||||
: "=&r" (prev), "=&r" (tmp)
|
||||
: "r" (a), "r" (&v->counter), "r" (u)
|
||||
: "memory");
|
||||
|
||||
return prev;
|
||||
}
|
||||
#define arch_atomic_fetch_add_unless arch_atomic_fetch_add_unless
|
||||
|
||||
static __always_inline bool
|
||||
arch_atomic_inc_unless_negative(atomic_t *v)
|
||||
{
|
||||
int rc, tmp;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
RELEASE_FENCE
|
||||
"1: ldex.w %0, (%2) \n"
|
||||
" movi %1, 0 \n"
|
||||
" blz %0, 2f \n"
|
||||
" movi %1, 1 \n"
|
||||
" addi %0, 1 \n"
|
||||
" stex.w %0, (%2) \n"
|
||||
" bez %0, 1b \n"
|
||||
FULL_FENCE
|
||||
"2:\n"
|
||||
: "=&r" (tmp), "=&r" (rc)
|
||||
: "r" (&v->counter)
|
||||
: "memory");
|
||||
|
||||
return tmp ? true : false;
|
||||
|
||||
}
|
||||
#define arch_atomic_inc_unless_negative arch_atomic_inc_unless_negative
|
||||
|
||||
static __always_inline bool
|
||||
arch_atomic_dec_unless_positive(atomic_t *v)
|
||||
{
|
||||
int rc, tmp;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
RELEASE_FENCE
|
||||
"1: ldex.w %0, (%2) \n"
|
||||
" movi %1, 0 \n"
|
||||
" bhz %0, 2f \n"
|
||||
" movi %1, 1 \n"
|
||||
" subi %0, 1 \n"
|
||||
" stex.w %0, (%2) \n"
|
||||
" bez %0, 1b \n"
|
||||
FULL_FENCE
|
||||
"2:\n"
|
||||
: "=&r" (tmp), "=&r" (rc)
|
||||
: "r" (&v->counter)
|
||||
: "memory");
|
||||
|
||||
return tmp ? true : false;
|
||||
}
|
||||
#define arch_atomic_dec_unless_positive arch_atomic_dec_unless_positive
|
||||
|
||||
static __always_inline int
|
||||
arch_atomic_dec_if_positive(atomic_t *v)
|
||||
{
|
||||
int dec, tmp;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
RELEASE_FENCE
|
||||
"1: ldex.w %0, (%2) \n"
|
||||
" subi %1, %0, 1 \n"
|
||||
" blz %1, 2f \n"
|
||||
" stex.w %1, (%2) \n"
|
||||
" bez %1, 1b \n"
|
||||
FULL_FENCE
|
||||
"2:\n"
|
||||
: "=&r" (dec), "=&r" (tmp)
|
||||
: "r" (&v->counter)
|
||||
: "memory");
|
||||
|
||||
return dec - 1;
|
||||
}
|
||||
#define arch_atomic_dec_if_positive arch_atomic_dec_if_positive
|
||||
|
||||
#define ATOMIC_OP() \
|
||||
static __always_inline \
|
||||
int arch_atomic_xchg_relaxed(atomic_t *v, int n) \
|
||||
{ \
|
||||
return __xchg_relaxed(n, &(v->counter), 4); \
|
||||
} \
|
||||
static __always_inline \
|
||||
int arch_atomic_cmpxchg_relaxed(atomic_t *v, int o, int n) \
|
||||
{ \
|
||||
return __cmpxchg_relaxed(&(v->counter), o, n, 4); \
|
||||
} \
|
||||
static __always_inline \
|
||||
int arch_atomic_cmpxchg_acquire(atomic_t *v, int o, int n) \
|
||||
{ \
|
||||
return __cmpxchg_acquire(&(v->counter), o, n, 4); \
|
||||
} \
|
||||
static __always_inline \
|
||||
int arch_atomic_cmpxchg(atomic_t *v, int o, int n) \
|
||||
{ \
|
||||
return __cmpxchg(&(v->counter), o, n, 4); \
|
||||
}
|
||||
|
||||
#define ATOMIC_OPS() \
|
||||
ATOMIC_OP()
|
||||
|
||||
ATOMIC_OPS()
|
||||
|
||||
#define arch_atomic_xchg_relaxed arch_atomic_xchg_relaxed
|
||||
#define arch_atomic_cmpxchg_relaxed arch_atomic_cmpxchg_relaxed
|
||||
#define arch_atomic_cmpxchg_acquire arch_atomic_cmpxchg_acquire
|
||||
#define arch_atomic_cmpxchg arch_atomic_cmpxchg
|
||||
|
||||
#undef ATOMIC_OPS
|
||||
#undef ATOMIC_OP
|
||||
|
||||
#else
|
||||
#include <asm-generic/atomic.h>
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_CSKY_ATOMIC_H */
|
||||
@@ -37,17 +37,21 @@
|
||||
* bar.brar
|
||||
* bar.bwaw
|
||||
*/
|
||||
#define FULL_FENCE ".long 0x842fc000\n"
|
||||
#define ACQUIRE_FENCE ".long 0x8427c000\n"
|
||||
#define RELEASE_FENCE ".long 0x842ec000\n"
|
||||
|
||||
#define __bar_brw() asm volatile (".long 0x842cc000\n":::"memory")
|
||||
#define __bar_br() asm volatile (".long 0x8424c000\n":::"memory")
|
||||
#define __bar_bw() asm volatile (".long 0x8428c000\n":::"memory")
|
||||
#define __bar_arw() asm volatile (".long 0x8423c000\n":::"memory")
|
||||
#define __bar_ar() asm volatile (".long 0x8421c000\n":::"memory")
|
||||
#define __bar_aw() asm volatile (".long 0x8422c000\n":::"memory")
|
||||
#define __bar_brwarw() asm volatile (".long 0x842fc000\n":::"memory")
|
||||
#define __bar_brarw() asm volatile (".long 0x8427c000\n":::"memory")
|
||||
#define __bar_brwarw() asm volatile (FULL_FENCE:::"memory")
|
||||
#define __bar_brarw() asm volatile (ACQUIRE_FENCE:::"memory")
|
||||
#define __bar_bwarw() asm volatile (".long 0x842bc000\n":::"memory")
|
||||
#define __bar_brwar() asm volatile (".long 0x842dc000\n":::"memory")
|
||||
#define __bar_brwaw() asm volatile (".long 0x842ec000\n":::"memory")
|
||||
#define __bar_brwaw() asm volatile (RELEASE_FENCE:::"memory")
|
||||
#define __bar_brar() asm volatile (".long 0x8425c000\n":::"memory")
|
||||
#define __bar_brar() asm volatile (".long 0x8425c000\n":::"memory")
|
||||
#define __bar_bwaw() asm volatile (".long 0x842ac000\n":::"memory")
|
||||
@@ -56,7 +60,6 @@
|
||||
#define __smp_rmb() __bar_brar()
|
||||
#define __smp_wmb() __bar_bwaw()
|
||||
|
||||
#define ACQUIRE_FENCE ".long 0x8427c000\n"
|
||||
#define __smp_acquire_fence() __bar_brarw()
|
||||
#define __smp_release_fence() __bar_brwaw()
|
||||
|
||||
|
||||
@@ -64,15 +64,71 @@ extern void __bad_xchg(void);
|
||||
#define arch_cmpxchg_relaxed(ptr, o, n) \
|
||||
(__cmpxchg_relaxed((ptr), (o), (n), sizeof(*(ptr))))
|
||||
|
||||
#define arch_cmpxchg(ptr, o, n) \
|
||||
#define __cmpxchg_acquire(ptr, old, new, size) \
|
||||
({ \
|
||||
__typeof__(ptr) __ptr = (ptr); \
|
||||
__typeof__(new) __new = (new); \
|
||||
__typeof__(new) __tmp; \
|
||||
__typeof__(old) __old = (old); \
|
||||
__typeof__(*(ptr)) __ret; \
|
||||
__smp_release_fence(); \
|
||||
__ret = arch_cmpxchg_relaxed(ptr, o, n); \
|
||||
__smp_acquire_fence(); \
|
||||
switch (size) { \
|
||||
case 4: \
|
||||
asm volatile ( \
|
||||
"1: ldex.w %0, (%3) \n" \
|
||||
" cmpne %0, %4 \n" \
|
||||
" bt 2f \n" \
|
||||
" mov %1, %2 \n" \
|
||||
" stex.w %1, (%3) \n" \
|
||||
" bez %1, 1b \n" \
|
||||
ACQUIRE_FENCE \
|
||||
"2: \n" \
|
||||
: "=&r" (__ret), "=&r" (__tmp) \
|
||||
: "r" (__new), "r"(__ptr), "r"(__old) \
|
||||
:); \
|
||||
break; \
|
||||
default: \
|
||||
__bad_xchg(); \
|
||||
} \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define arch_cmpxchg_acquire(ptr, o, n) \
|
||||
(__cmpxchg_acquire((ptr), (o), (n), sizeof(*(ptr))))
|
||||
|
||||
#define __cmpxchg(ptr, old, new, size) \
|
||||
({ \
|
||||
__typeof__(ptr) __ptr = (ptr); \
|
||||
__typeof__(new) __new = (new); \
|
||||
__typeof__(new) __tmp; \
|
||||
__typeof__(old) __old = (old); \
|
||||
__typeof__(*(ptr)) __ret; \
|
||||
switch (size) { \
|
||||
case 4: \
|
||||
asm volatile ( \
|
||||
RELEASE_FENCE \
|
||||
"1: ldex.w %0, (%3) \n" \
|
||||
" cmpne %0, %4 \n" \
|
||||
" bt 2f \n" \
|
||||
" mov %1, %2 \n" \
|
||||
" stex.w %1, (%3) \n" \
|
||||
" bez %1, 1b \n" \
|
||||
FULL_FENCE \
|
||||
"2: \n" \
|
||||
: "=&r" (__ret), "=&r" (__tmp) \
|
||||
: "r" (__new), "r"(__ptr), "r"(__old) \
|
||||
:); \
|
||||
break; \
|
||||
default: \
|
||||
__bad_xchg(); \
|
||||
} \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define arch_cmpxchg(ptr, o, n) \
|
||||
(__cmpxchg((ptr), (o), (n), sizeof(*(ptr))))
|
||||
|
||||
#define arch_cmpxchg_local(ptr, o, n) \
|
||||
(__cmpxchg_relaxed((ptr), (o), (n), sizeof(*(ptr))))
|
||||
#else
|
||||
#include <asm-generic/cmpxchg.h>
|
||||
#endif
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
#include <linux/pgtable.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
/*
|
||||
* I/O memory access primitives. Reads are ordered relative to any
|
||||
@@ -32,6 +31,17 @@
|
||||
#define writel(v,c) ({ wmb(); writel_relaxed((v),(c)); mb(); })
|
||||
#endif
|
||||
|
||||
/*
|
||||
* String version of I/O memory access operations.
|
||||
*/
|
||||
extern void __memcpy_fromio(void *, const volatile void __iomem *, size_t);
|
||||
extern void __memcpy_toio(volatile void __iomem *, const void *, size_t);
|
||||
extern void __memset_io(volatile void __iomem *, int, size_t);
|
||||
|
||||
#define memset_io(c,v,l) __memset_io((c),(v),(l))
|
||||
#define memcpy_fromio(a,c,l) __memcpy_fromio((a),(c),(l))
|
||||
#define memcpy_toio(c,a,l) __memcpy_toio((c),(a),(l))
|
||||
|
||||
/*
|
||||
* I/O memory mapping functions.
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
extra-y := head.o vmlinux.lds
|
||||
|
||||
obj-y += entry.o atomic.o signal.o traps.o irq.o time.o vdso.o vdso/
|
||||
obj-y += power.o syscall.o syscall_table.o setup.o
|
||||
obj-y += power.o syscall.o syscall_table.o setup.o io.o
|
||||
obj-y += process.o cpu-probe.o ptrace.o stacktrace.o
|
||||
obj-y += probes/
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
/*
|
||||
* Copy data from IO memory space to "real" memory space.
|
||||
*/
|
||||
void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
|
||||
{
|
||||
while (count && !IS_ALIGNED((unsigned long)from, 4)) {
|
||||
*(u8 *)to = __raw_readb(from);
|
||||
from++;
|
||||
to++;
|
||||
count--;
|
||||
}
|
||||
|
||||
while (count >= 4) {
|
||||
*(u32 *)to = __raw_readl(from);
|
||||
from += 4;
|
||||
to += 4;
|
||||
count -= 4;
|
||||
}
|
||||
|
||||
while (count) {
|
||||
*(u8 *)to = __raw_readb(from);
|
||||
from++;
|
||||
to++;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(__memcpy_fromio);
|
||||
|
||||
/*
|
||||
* Copy data from "real" memory space to IO memory space.
|
||||
*/
|
||||
void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
|
||||
{
|
||||
while (count && !IS_ALIGNED((unsigned long)to, 4)) {
|
||||
__raw_writeb(*(u8 *)from, to);
|
||||
from++;
|
||||
to++;
|
||||
count--;
|
||||
}
|
||||
|
||||
while (count >= 4) {
|
||||
__raw_writel(*(u32 *)from, to);
|
||||
from += 4;
|
||||
to += 4;
|
||||
count -= 4;
|
||||
}
|
||||
|
||||
while (count) {
|
||||
__raw_writeb(*(u8 *)from, to);
|
||||
from++;
|
||||
to++;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(__memcpy_toio);
|
||||
|
||||
/*
|
||||
* "memset" on IO memory space.
|
||||
*/
|
||||
void __memset_io(volatile void __iomem *dst, int c, size_t count)
|
||||
{
|
||||
u32 qc = (u8)c;
|
||||
|
||||
qc |= qc << 8;
|
||||
qc |= qc << 16;
|
||||
|
||||
while (count && !IS_ALIGNED((unsigned long)dst, 4)) {
|
||||
__raw_writeb(c, dst);
|
||||
dst++;
|
||||
count--;
|
||||
}
|
||||
|
||||
while (count >= 4) {
|
||||
__raw_writel(qc, dst);
|
||||
dst += 4;
|
||||
count -= 4;
|
||||
}
|
||||
|
||||
while (count) {
|
||||
__raw_writeb(c, dst);
|
||||
dst++;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(__memset_io);
|
||||
@@ -68,7 +68,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
|
||||
*location = rel[i].r_addend + sym->st_value;
|
||||
break;
|
||||
case R_CSKY_PC32:
|
||||
/* Add the value, subtract its postition */
|
||||
/* Add the value, subtract its position */
|
||||
*location = rel[i].r_addend + sym->st_value
|
||||
- (uint32_t)location;
|
||||
break;
|
||||
|
||||
@@ -30,7 +30,7 @@ static int __kprobes patch_text_cb(void *priv)
|
||||
struct csky_insn_patch *param = priv;
|
||||
unsigned int addr = (unsigned int)param->addr;
|
||||
|
||||
if (atomic_inc_return(¶m->cpu_count) == 1) {
|
||||
if (atomic_inc_return(¶m->cpu_count) == num_online_cpus()) {
|
||||
*(u16 *) addr = cpu_to_le16(param->opcode);
|
||||
dcache_wb_range(addr, addr + 2);
|
||||
atomic_inc(¶m->cpu_count);
|
||||
|
||||
@@ -102,7 +102,7 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
|
||||
struct uprobe_task *utask = current->utask;
|
||||
|
||||
/*
|
||||
* Task has received a fatal signal, so reset back to probbed
|
||||
* Task has received a fatal signal, so reset back to probed
|
||||
* address.
|
||||
*/
|
||||
instruction_pointer_set(regs, utask->vaddr);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/task_stack.h>
|
||||
#include <linux/sched/debug.h>
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
lib-y := usercopy.o delay.o
|
||||
obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
|
||||
ifneq ($(CONFIG_HAVE_EFFICIENT_UNALIGNED_STRING_OPS), y)
|
||||
lib-y += string.o
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* String functions optimized for hardware which doesn't
|
||||
* handle unaligned memory accesses efficiently.
|
||||
*
|
||||
* Copyright (C) 2021 Matteo Croce
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Minimum size for a word copy to be convenient */
|
||||
#define BYTES_LONG sizeof(long)
|
||||
#define WORD_MASK (BYTES_LONG - 1)
|
||||
#define MIN_THRESHOLD (BYTES_LONG * 2)
|
||||
|
||||
/* convenience union to avoid cast between different pointer types */
|
||||
union types {
|
||||
u8 *as_u8;
|
||||
unsigned long *as_ulong;
|
||||
uintptr_t as_uptr;
|
||||
};
|
||||
|
||||
union const_types {
|
||||
const u8 *as_u8;
|
||||
unsigned long *as_ulong;
|
||||
uintptr_t as_uptr;
|
||||
};
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t count)
|
||||
{
|
||||
union const_types s = { .as_u8 = src };
|
||||
union types d = { .as_u8 = dest };
|
||||
int distance = 0;
|
||||
|
||||
if (count < MIN_THRESHOLD)
|
||||
goto copy_remainder;
|
||||
|
||||
/* Copy a byte at time until destination is aligned. */
|
||||
for (; d.as_uptr & WORD_MASK; count--)
|
||||
*d.as_u8++ = *s.as_u8++;
|
||||
|
||||
distance = s.as_uptr & WORD_MASK;
|
||||
|
||||
if (distance) {
|
||||
unsigned long last, next;
|
||||
|
||||
/*
|
||||
* s is distance bytes ahead of d, and d just reached
|
||||
* the alignment boundary. Move s backward to word align it
|
||||
* and shift data to compensate for distance, in order to do
|
||||
* word-by-word copy.
|
||||
*/
|
||||
s.as_u8 -= distance;
|
||||
|
||||
next = s.as_ulong[0];
|
||||
for (; count >= BYTES_LONG; count -= BYTES_LONG) {
|
||||
last = next;
|
||||
next = s.as_ulong[1];
|
||||
|
||||
d.as_ulong[0] = last >> (distance * 8) |
|
||||
next << ((BYTES_LONG - distance) * 8);
|
||||
|
||||
d.as_ulong++;
|
||||
s.as_ulong++;
|
||||
}
|
||||
|
||||
/* Restore s with the original offset. */
|
||||
s.as_u8 += distance;
|
||||
} else {
|
||||
/*
|
||||
* If the source and dest lower bits are the same, do a simple
|
||||
* 32/64 bit wide copy.
|
||||
*/
|
||||
for (; count >= BYTES_LONG; count -= BYTES_LONG)
|
||||
*d.as_ulong++ = *s.as_ulong++;
|
||||
}
|
||||
|
||||
copy_remainder:
|
||||
while (count--)
|
||||
*d.as_u8++ = *s.as_u8++;
|
||||
|
||||
return dest;
|
||||
}
|
||||
EXPORT_SYMBOL(memcpy);
|
||||
|
||||
/*
|
||||
* Simply check if the buffer overlaps an call memcpy() in case,
|
||||
* otherwise do a simple one byte at time backward copy.
|
||||
*/
|
||||
void *memmove(void *dest, const void *src, size_t count)
|
||||
{
|
||||
if (dest < src || src + count <= dest)
|
||||
return memcpy(dest, src, count);
|
||||
|
||||
if (dest > src) {
|
||||
const char *s = src + count;
|
||||
char *tmp = dest + count;
|
||||
|
||||
while (count--)
|
||||
*--tmp = *--s;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
EXPORT_SYMBOL(memmove);
|
||||
|
||||
void *memset(void *s, int c, size_t count)
|
||||
{
|
||||
union types dest = { .as_u8 = s };
|
||||
|
||||
if (count >= MIN_THRESHOLD) {
|
||||
unsigned long cu = (unsigned long)c;
|
||||
|
||||
/* Compose an ulong with 'c' repeated 4/8 times */
|
||||
cu |= cu << 8;
|
||||
cu |= cu << 16;
|
||||
/* Suppress warning on 32 bit machines */
|
||||
cu |= (cu << 16) << 16;
|
||||
|
||||
for (; count && dest.as_uptr & WORD_MASK; count--)
|
||||
*dest.as_u8++ = c;
|
||||
|
||||
/* Copy using the largest size allowed */
|
||||
for (; count >= BYTES_LONG; count -= BYTES_LONG)
|
||||
*dest.as_ulong++ = cu;
|
||||
}
|
||||
|
||||
/* copy the remainder */
|
||||
while (count--)
|
||||
*dest.as_u8++ = c;
|
||||
|
||||
return s;
|
||||
}
|
||||
EXPORT_SYMBOL(memset);
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/version.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
static inline void cache_op(phys_addr_t paddr, size_t size,
|
||||
|
||||
@@ -17,3 +17,4 @@ obj-$(CONFIG_M68060) += ifpsp060/
|
||||
obj-$(CONFIG_M68KFPU_EMU) += math-emu/
|
||||
obj-$(CONFIG_M68000) += 68000/
|
||||
obj-$(CONFIG_COLDFIRE) += coldfire/
|
||||
obj-$(CONFIG_VIRT) += virt/
|
||||
|
||||
@@ -327,7 +327,7 @@ comment "Processor Specific Options"
|
||||
|
||||
config M68KFPU_EMU
|
||||
bool "Math emulation support"
|
||||
depends on MMU
|
||||
depends on M68KCLASSIC && FPU
|
||||
help
|
||||
At some point in the future, this will cause floating-point math
|
||||
instructions to be emulated by the kernel on machines that lack a
|
||||
|
||||
@@ -149,6 +149,23 @@ config SUN3
|
||||
|
||||
If you don't want to compile a kernel exclusively for a Sun 3, say N.
|
||||
|
||||
config VIRT
|
||||
bool "Virtual M68k Machine support"
|
||||
depends on MMU
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GOLDFISH
|
||||
select GOLDFISH_TIMER
|
||||
select GOLDFISH_TTY
|
||||
select M68040
|
||||
select MMU_MOTOROLA if MMU
|
||||
select RTC_CLASS
|
||||
select RTC_DRV_GOLDFISH
|
||||
select TTY
|
||||
select VIRTIO_MMIO
|
||||
help
|
||||
This options enable a pure virtual machine based on m68k,
|
||||
VIRTIO MMIO devices and GOLDFISH interfaces (TTY, RTC, PIC)
|
||||
|
||||
config PILOT
|
||||
bool
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ CONFIG_MQ_IOSCHED_DEADLINE=m
|
||||
CONFIG_MQ_IOSCHED_KYBER=m
|
||||
CONFIG_IOSCHED_BFQ=m
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_AOUT=m
|
||||
CONFIG_BINFMT_MISC=m
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_ZPOOL=m
|
||||
@@ -581,6 +580,7 @@ CONFIG_CRYPTO_MD4=m
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_SHA3=m
|
||||
CONFIG_CRYPTO_SM3=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_AES_TI=m
|
||||
@@ -613,7 +613,6 @@ CONFIG_CRYPTO_USER_API_AEAD=m
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_PRIME_NUMBERS=m
|
||||
CONFIG_CRC32_SELFTEST=m
|
||||
CONFIG_CRC64=m
|
||||
CONFIG_XZ_DEC_TEST=m
|
||||
CONFIG_GLOB_SELFTEST=m
|
||||
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
|
||||
@@ -638,7 +637,6 @@ CONFIG_TEST_SCANF=m
|
||||
CONFIG_TEST_BITMAP=m
|
||||
CONFIG_TEST_UUID=m
|
||||
CONFIG_TEST_XARRAY=m
|
||||
CONFIG_TEST_OVERFLOW=m
|
||||
CONFIG_TEST_RHASHTABLE=m
|
||||
CONFIG_TEST_SIPHASH=m
|
||||
CONFIG_TEST_IDA=m
|
||||
@@ -659,6 +657,5 @@ CONFIG_TEST_UDELAY=m
|
||||
CONFIG_TEST_STATIC_KEYS=m
|
||||
CONFIG_TEST_KMOD=m
|
||||
CONFIG_TEST_MEMCAT_P=m
|
||||
CONFIG_TEST_STACKINIT=m
|
||||
CONFIG_TEST_MEMINIT=m
|
||||
CONFIG_TEST_FREE_PAGES=m
|
||||
|
||||
@@ -38,7 +38,6 @@ CONFIG_MQ_IOSCHED_DEADLINE=m
|
||||
CONFIG_MQ_IOSCHED_KYBER=m
|
||||
CONFIG_IOSCHED_BFQ=m
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_AOUT=m
|
||||
CONFIG_BINFMT_MISC=m
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_ZPOOL=m
|
||||
@@ -538,6 +537,7 @@ CONFIG_CRYPTO_MD4=m
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_SHA3=m
|
||||
CONFIG_CRYPTO_SM3=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_AES_TI=m
|
||||
@@ -570,7 +570,6 @@ CONFIG_CRYPTO_USER_API_AEAD=m
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_PRIME_NUMBERS=m
|
||||
CONFIG_CRC32_SELFTEST=m
|
||||
CONFIG_CRC64=m
|
||||
CONFIG_XZ_DEC_TEST=m
|
||||
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
@@ -594,7 +593,6 @@ CONFIG_TEST_SCANF=m
|
||||
CONFIG_TEST_BITMAP=m
|
||||
CONFIG_TEST_UUID=m
|
||||
CONFIG_TEST_XARRAY=m
|
||||
CONFIG_TEST_OVERFLOW=m
|
||||
CONFIG_TEST_RHASHTABLE=m
|
||||
CONFIG_TEST_SIPHASH=m
|
||||
CONFIG_TEST_IDA=m
|
||||
@@ -615,6 +613,5 @@ CONFIG_TEST_UDELAY=m
|
||||
CONFIG_TEST_STATIC_KEYS=m
|
||||
CONFIG_TEST_KMOD=m
|
||||
CONFIG_TEST_MEMCAT_P=m
|
||||
CONFIG_TEST_STACKINIT=m
|
||||
CONFIG_TEST_MEMINIT=m
|
||||
CONFIG_TEST_FREE_PAGES=m
|
||||
|
||||
@@ -45,7 +45,6 @@ CONFIG_MQ_IOSCHED_DEADLINE=m
|
||||
CONFIG_MQ_IOSCHED_KYBER=m
|
||||
CONFIG_IOSCHED_BFQ=m
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_AOUT=m
|
||||
CONFIG_BINFMT_MISC=m
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_ZPOOL=m
|
||||
@@ -558,6 +557,7 @@ CONFIG_CRYPTO_MD4=m
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_SHA3=m
|
||||
CONFIG_CRYPTO_SM3=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_AES_TI=m
|
||||
@@ -590,7 +590,6 @@ CONFIG_CRYPTO_USER_API_AEAD=m
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_PRIME_NUMBERS=m
|
||||
CONFIG_CRC32_SELFTEST=m
|
||||
CONFIG_CRC64=m
|
||||
CONFIG_XZ_DEC_TEST=m
|
||||
CONFIG_GLOB_SELFTEST=m
|
||||
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
|
||||
@@ -615,7 +614,6 @@ CONFIG_TEST_SCANF=m
|
||||
CONFIG_TEST_BITMAP=m
|
||||
CONFIG_TEST_UUID=m
|
||||
CONFIG_TEST_XARRAY=m
|
||||
CONFIG_TEST_OVERFLOW=m
|
||||
CONFIG_TEST_RHASHTABLE=m
|
||||
CONFIG_TEST_SIPHASH=m
|
||||
CONFIG_TEST_IDA=m
|
||||
@@ -636,6 +634,5 @@ CONFIG_TEST_UDELAY=m
|
||||
CONFIG_TEST_STATIC_KEYS=m
|
||||
CONFIG_TEST_KMOD=m
|
||||
CONFIG_TEST_MEMCAT_P=m
|
||||
CONFIG_TEST_STACKINIT=m
|
||||
CONFIG_TEST_MEMINIT=m
|
||||
CONFIG_TEST_FREE_PAGES=m
|
||||
|
||||
@@ -35,7 +35,6 @@ CONFIG_MQ_IOSCHED_DEADLINE=m
|
||||
CONFIG_MQ_IOSCHED_KYBER=m
|
||||
CONFIG_IOSCHED_BFQ=m
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_AOUT=m
|
||||
CONFIG_BINFMT_MISC=m
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_ZPOOL=m
|
||||
@@ -530,6 +529,7 @@ CONFIG_CRYPTO_MD4=m
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_SHA3=m
|
||||
CONFIG_CRYPTO_SM3=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_AES_TI=m
|
||||
@@ -562,7 +562,6 @@ CONFIG_CRYPTO_USER_API_AEAD=m
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_PRIME_NUMBERS=m
|
||||
CONFIG_CRC32_SELFTEST=m
|
||||
CONFIG_CRC64=m
|
||||
CONFIG_XZ_DEC_TEST=m
|
||||
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
@@ -586,7 +585,6 @@ CONFIG_TEST_SCANF=m
|
||||
CONFIG_TEST_BITMAP=m
|
||||
CONFIG_TEST_UUID=m
|
||||
CONFIG_TEST_XARRAY=m
|
||||
CONFIG_TEST_OVERFLOW=m
|
||||
CONFIG_TEST_RHASHTABLE=m
|
||||
CONFIG_TEST_SIPHASH=m
|
||||
CONFIG_TEST_IDA=m
|
||||
@@ -607,6 +605,5 @@ CONFIG_TEST_UDELAY=m
|
||||
CONFIG_TEST_STATIC_KEYS=m
|
||||
CONFIG_TEST_KMOD=m
|
||||
CONFIG_TEST_MEMCAT_P=m
|
||||
CONFIG_TEST_STACKINIT=m
|
||||
CONFIG_TEST_MEMINIT=m
|
||||
CONFIG_TEST_FREE_PAGES=m
|
||||
|
||||
@@ -37,7 +37,6 @@ CONFIG_MQ_IOSCHED_DEADLINE=m
|
||||
CONFIG_MQ_IOSCHED_KYBER=m
|
||||
CONFIG_IOSCHED_BFQ=m
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_AOUT=m
|
||||
CONFIG_BINFMT_MISC=m
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_ZPOOL=m
|
||||
@@ -540,6 +539,7 @@ CONFIG_CRYPTO_MD4=m
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_SHA3=m
|
||||
CONFIG_CRYPTO_SM3=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_AES_TI=m
|
||||
@@ -572,7 +572,6 @@ CONFIG_CRYPTO_USER_API_AEAD=m
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_PRIME_NUMBERS=m
|
||||
CONFIG_CRC32_SELFTEST=m
|
||||
CONFIG_CRC64=m
|
||||
CONFIG_XZ_DEC_TEST=m
|
||||
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
@@ -596,7 +595,6 @@ CONFIG_TEST_SCANF=m
|
||||
CONFIG_TEST_BITMAP=m
|
||||
CONFIG_TEST_UUID=m
|
||||
CONFIG_TEST_XARRAY=m
|
||||
CONFIG_TEST_OVERFLOW=m
|
||||
CONFIG_TEST_RHASHTABLE=m
|
||||
CONFIG_TEST_SIPHASH=m
|
||||
CONFIG_TEST_IDA=m
|
||||
@@ -617,6 +615,5 @@ CONFIG_TEST_UDELAY=m
|
||||
CONFIG_TEST_STATIC_KEYS=m
|
||||
CONFIG_TEST_KMOD=m
|
||||
CONFIG_TEST_MEMCAT_P=m
|
||||
CONFIG_TEST_STACKINIT=m
|
||||
CONFIG_TEST_MEMINIT=m
|
||||
CONFIG_TEST_FREE_PAGES=m
|
||||
|
||||
@@ -36,7 +36,6 @@ CONFIG_MQ_IOSCHED_DEADLINE=m
|
||||
CONFIG_MQ_IOSCHED_KYBER=m
|
||||
CONFIG_IOSCHED_BFQ=m
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_AOUT=m
|
||||
CONFIG_BINFMT_MISC=m
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_ZPOOL=m
|
||||
@@ -560,6 +559,7 @@ CONFIG_CRYPTO_MD4=m
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_SHA3=m
|
||||
CONFIG_CRYPTO_SM3=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_AES_TI=m
|
||||
@@ -592,7 +592,6 @@ CONFIG_CRYPTO_USER_API_AEAD=m
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_PRIME_NUMBERS=m
|
||||
CONFIG_CRC32_SELFTEST=m
|
||||
CONFIG_CRC64=m
|
||||
CONFIG_XZ_DEC_TEST=m
|
||||
CONFIG_GLOB_SELFTEST=m
|
||||
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
|
||||
@@ -617,7 +616,6 @@ CONFIG_TEST_SCANF=m
|
||||
CONFIG_TEST_BITMAP=m
|
||||
CONFIG_TEST_UUID=m
|
||||
CONFIG_TEST_XARRAY=m
|
||||
CONFIG_TEST_OVERFLOW=m
|
||||
CONFIG_TEST_RHASHTABLE=m
|
||||
CONFIG_TEST_SIPHASH=m
|
||||
CONFIG_TEST_IDA=m
|
||||
@@ -638,6 +636,5 @@ CONFIG_TEST_UDELAY=m
|
||||
CONFIG_TEST_STATIC_KEYS=m
|
||||
CONFIG_TEST_KMOD=m
|
||||
CONFIG_TEST_MEMCAT_P=m
|
||||
CONFIG_TEST_STACKINIT=m
|
||||
CONFIG_TEST_MEMINIT=m
|
||||
CONFIG_TEST_FREE_PAGES=m
|
||||
|
||||
@@ -56,7 +56,6 @@ CONFIG_MQ_IOSCHED_DEADLINE=m
|
||||
CONFIG_MQ_IOSCHED_KYBER=m
|
||||
CONFIG_IOSCHED_BFQ=m
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_AOUT=m
|
||||
CONFIG_BINFMT_MISC=m
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_ZPOOL=m
|
||||
@@ -646,6 +645,7 @@ CONFIG_CRYPTO_MD4=m
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_SHA3=m
|
||||
CONFIG_CRYPTO_SM3=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_AES_TI=m
|
||||
@@ -678,7 +678,6 @@ CONFIG_CRYPTO_USER_API_AEAD=m
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_PRIME_NUMBERS=m
|
||||
CONFIG_CRC32_SELFTEST=m
|
||||
CONFIG_CRC64=m
|
||||
CONFIG_XZ_DEC_TEST=m
|
||||
CONFIG_GLOB_SELFTEST=m
|
||||
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
|
||||
@@ -703,7 +702,6 @@ CONFIG_TEST_SCANF=m
|
||||
CONFIG_TEST_BITMAP=m
|
||||
CONFIG_TEST_UUID=m
|
||||
CONFIG_TEST_XARRAY=m
|
||||
CONFIG_TEST_OVERFLOW=m
|
||||
CONFIG_TEST_RHASHTABLE=m
|
||||
CONFIG_TEST_SIPHASH=m
|
||||
CONFIG_TEST_IDA=m
|
||||
@@ -724,6 +722,5 @@ CONFIG_TEST_UDELAY=m
|
||||
CONFIG_TEST_STATIC_KEYS=m
|
||||
CONFIG_TEST_KMOD=m
|
||||
CONFIG_TEST_MEMCAT_P=m
|
||||
CONFIG_TEST_STACKINIT=m
|
||||
CONFIG_TEST_MEMINIT=m
|
||||
CONFIG_TEST_FREE_PAGES=m
|
||||
|
||||
@@ -34,7 +34,6 @@ CONFIG_MQ_IOSCHED_DEADLINE=m
|
||||
CONFIG_MQ_IOSCHED_KYBER=m
|
||||
CONFIG_IOSCHED_BFQ=m
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_AOUT=m
|
||||
CONFIG_BINFMT_MISC=m
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_ZPOOL=m
|
||||
@@ -529,6 +528,7 @@ CONFIG_CRYPTO_MD4=m
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_SHA3=m
|
||||
CONFIG_CRYPTO_SM3=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_AES_TI=m
|
||||
@@ -561,7 +561,6 @@ CONFIG_CRYPTO_USER_API_AEAD=m
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_PRIME_NUMBERS=m
|
||||
CONFIG_CRC32_SELFTEST=m
|
||||
CONFIG_CRC64=m
|
||||
CONFIG_XZ_DEC_TEST=m
|
||||
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
@@ -585,7 +584,6 @@ CONFIG_TEST_SCANF=m
|
||||
CONFIG_TEST_BITMAP=m
|
||||
CONFIG_TEST_UUID=m
|
||||
CONFIG_TEST_XARRAY=m
|
||||
CONFIG_TEST_OVERFLOW=m
|
||||
CONFIG_TEST_RHASHTABLE=m
|
||||
CONFIG_TEST_SIPHASH=m
|
||||
CONFIG_TEST_IDA=m
|
||||
@@ -606,6 +604,5 @@ CONFIG_TEST_UDELAY=m
|
||||
CONFIG_TEST_STATIC_KEYS=m
|
||||
CONFIG_TEST_KMOD=m
|
||||
CONFIG_TEST_MEMCAT_P=m
|
||||
CONFIG_TEST_STACKINIT=m
|
||||
CONFIG_TEST_MEMINIT=m
|
||||
CONFIG_TEST_FREE_PAGES=m
|
||||
|
||||
@@ -35,7 +35,6 @@ CONFIG_MQ_IOSCHED_DEADLINE=m
|
||||
CONFIG_MQ_IOSCHED_KYBER=m
|
||||
CONFIG_IOSCHED_BFQ=m
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_AOUT=m
|
||||
CONFIG_BINFMT_MISC=m
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_ZPOOL=m
|
||||
@@ -530,6 +529,7 @@ CONFIG_CRYPTO_MD4=m
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_SHA3=m
|
||||
CONFIG_CRYPTO_SM3=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_AES_TI=m
|
||||
@@ -562,7 +562,6 @@ CONFIG_CRYPTO_USER_API_AEAD=m
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_PRIME_NUMBERS=m
|
||||
CONFIG_CRC32_SELFTEST=m
|
||||
CONFIG_CRC64=m
|
||||
CONFIG_XZ_DEC_TEST=m
|
||||
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
@@ -586,7 +585,6 @@ CONFIG_TEST_SCANF=m
|
||||
CONFIG_TEST_BITMAP=m
|
||||
CONFIG_TEST_UUID=m
|
||||
CONFIG_TEST_XARRAY=m
|
||||
CONFIG_TEST_OVERFLOW=m
|
||||
CONFIG_TEST_RHASHTABLE=m
|
||||
CONFIG_TEST_SIPHASH=m
|
||||
CONFIG_TEST_IDA=m
|
||||
@@ -607,6 +605,5 @@ CONFIG_TEST_UDELAY=m
|
||||
CONFIG_TEST_STATIC_KEYS=m
|
||||
CONFIG_TEST_KMOD=m
|
||||
CONFIG_TEST_MEMCAT_P=m
|
||||
CONFIG_TEST_STACKINIT=m
|
||||
CONFIG_TEST_MEMINIT=m
|
||||
CONFIG_TEST_FREE_PAGES=m
|
||||
|
||||
@@ -36,7 +36,6 @@ CONFIG_MQ_IOSCHED_DEADLINE=m
|
||||
CONFIG_MQ_IOSCHED_KYBER=m
|
||||
CONFIG_IOSCHED_BFQ=m
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_AOUT=m
|
||||
CONFIG_BINFMT_MISC=m
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_ZPOOL=m
|
||||
@@ -547,6 +546,7 @@ CONFIG_CRYPTO_MD4=m
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_SHA3=m
|
||||
CONFIG_CRYPTO_SM3=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_AES_TI=m
|
||||
@@ -579,7 +579,6 @@ CONFIG_CRYPTO_USER_API_AEAD=m
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_PRIME_NUMBERS=m
|
||||
CONFIG_CRC32_SELFTEST=m
|
||||
CONFIG_CRC64=m
|
||||
CONFIG_XZ_DEC_TEST=m
|
||||
CONFIG_GLOB_SELFTEST=m
|
||||
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
|
||||
@@ -604,7 +603,6 @@ CONFIG_TEST_SCANF=m
|
||||
CONFIG_TEST_BITMAP=m
|
||||
CONFIG_TEST_UUID=m
|
||||
CONFIG_TEST_XARRAY=m
|
||||
CONFIG_TEST_OVERFLOW=m
|
||||
CONFIG_TEST_RHASHTABLE=m
|
||||
CONFIG_TEST_SIPHASH=m
|
||||
CONFIG_TEST_IDA=m
|
||||
@@ -625,6 +623,5 @@ CONFIG_TEST_UDELAY=m
|
||||
CONFIG_TEST_STATIC_KEYS=m
|
||||
CONFIG_TEST_KMOD=m
|
||||
CONFIG_TEST_MEMCAT_P=m
|
||||
CONFIG_TEST_STACKINIT=m
|
||||
CONFIG_TEST_MEMINIT=m
|
||||
CONFIG_TEST_FREE_PAGES=m
|
||||
|
||||
@@ -32,7 +32,6 @@ CONFIG_MQ_IOSCHED_DEADLINE=m
|
||||
CONFIG_MQ_IOSCHED_KYBER=m
|
||||
CONFIG_IOSCHED_BFQ=m
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_AOUT=m
|
||||
CONFIG_BINFMT_MISC=m
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_ZPOOL=m
|
||||
@@ -529,6 +528,7 @@ CONFIG_CRYPTO_MD4=m
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_SHA3=m
|
||||
CONFIG_CRYPTO_SM3=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_AES_TI=m
|
||||
@@ -561,7 +561,6 @@ CONFIG_CRYPTO_USER_API_AEAD=m
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_PRIME_NUMBERS=m
|
||||
CONFIG_CRC32_SELFTEST=m
|
||||
CONFIG_CRC64=m
|
||||
CONFIG_XZ_DEC_TEST=m
|
||||
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
@@ -584,7 +583,6 @@ CONFIG_TEST_SCANF=m
|
||||
CONFIG_TEST_BITMAP=m
|
||||
CONFIG_TEST_UUID=m
|
||||
CONFIG_TEST_XARRAY=m
|
||||
CONFIG_TEST_OVERFLOW=m
|
||||
CONFIG_TEST_RHASHTABLE=m
|
||||
CONFIG_TEST_SIPHASH=m
|
||||
CONFIG_TEST_IDA=m
|
||||
@@ -605,6 +603,5 @@ CONFIG_TEST_UDELAY=m
|
||||
CONFIG_TEST_STATIC_KEYS=m
|
||||
CONFIG_TEST_KMOD=m
|
||||
CONFIG_TEST_MEMCAT_P=m
|
||||
CONFIG_TEST_STACKINIT=m
|
||||
CONFIG_TEST_MEMINIT=m
|
||||
CONFIG_TEST_FREE_PAGES=m
|
||||
|
||||
@@ -32,7 +32,6 @@ CONFIG_MQ_IOSCHED_DEADLINE=m
|
||||
CONFIG_MQ_IOSCHED_KYBER=m
|
||||
CONFIG_IOSCHED_BFQ=m
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_BINFMT_AOUT=m
|
||||
CONFIG_BINFMT_MISC=m
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_ZPOOL=m
|
||||
@@ -528,6 +527,7 @@ CONFIG_CRYPTO_MD4=m
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_SHA3=m
|
||||
CONFIG_CRYPTO_SM3=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_AES_TI=m
|
||||
@@ -560,7 +560,6 @@ CONFIG_CRYPTO_USER_API_AEAD=m
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_PRIME_NUMBERS=m
|
||||
CONFIG_CRC32_SELFTEST=m
|
||||
CONFIG_CRC64=m
|
||||
CONFIG_XZ_DEC_TEST=m
|
||||
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
@@ -584,7 +583,6 @@ CONFIG_TEST_SCANF=m
|
||||
CONFIG_TEST_BITMAP=m
|
||||
CONFIG_TEST_UUID=m
|
||||
CONFIG_TEST_XARRAY=m
|
||||
CONFIG_TEST_OVERFLOW=m
|
||||
CONFIG_TEST_RHASHTABLE=m
|
||||
CONFIG_TEST_SIPHASH=m
|
||||
CONFIG_TEST_IDA=m
|
||||
@@ -605,6 +603,5 @@ CONFIG_TEST_UDELAY=m
|
||||
CONFIG_TEST_STATIC_KEYS=m
|
||||
CONFIG_TEST_KMOD=m
|
||||
CONFIG_TEST_MEMCAT_P=m
|
||||
CONFIG_TEST_STACKINIT=m
|
||||
CONFIG_TEST_MEMINIT=m
|
||||
CONFIG_TEST_FREE_PAGES=m
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
CONFIG_LOCALVERSION="-virt"
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_CGROUPS=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_CGROUP_SCHED=y
|
||||
CONFIG_CGROUP_PIDS=y
|
||||
CONFIG_CGROUP_RDMA=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CGROUP_DEVICE=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_VIRT=y
|
||||
CONFIG_PROC_HARDWARE=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_AMIGA_PARTITION=y
|
||||
CONFIG_ATARI_PARTITION=y
|
||||
CONFIG_MAC_PARTITION=y
|
||||
CONFIG_BSD_DISKLABEL=y
|
||||
CONFIG_MINIX_SUBPARTITION=y
|
||||
CONFIG_SOLARIS_X86_PARTITION=y
|
||||
CONFIG_UNIXWARE_DISKLABEL=y
|
||||
CONFIG_LDM_PARTITION=y
|
||||
CONFIG_LDM_DEBUG=y
|
||||
CONFIG_SUN_PARTITION=y
|
||||
CONFIG_SYSV68_PARTITION=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_PNP=y
|
||||
CONFIG_IP_PNP_DHCP=y
|
||||
CONFIG_IP_PNP_BOOTP=y
|
||||
CONFIG_CGROUP_NET_PRIO=y
|
||||
CONFIG_CGROUP_NET_CLASSID=y
|
||||
CONFIG_NET_9P=y
|
||||
CONFIG_NET_9P_VIRTIO=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_VIRTIO_BLK=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SR=y
|
||||
CONFIG_SCSI_VIRTIO=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_VIRTIO_NET=y
|
||||
CONFIG_INPUT_MOUSEDEV=y
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_VIRTIO_CONSOLE=y
|
||||
CONFIG_HW_RANDOM_VIRTIO=y
|
||||
CONFIG_DRM=y
|
||||
CONFIG_DRM_VIRTIO_GPU=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
CONFIG_SND_VIRTIO=y
|
||||
CONFIG_VIRT_DRIVERS=y
|
||||
CONFIG_VIRTIO_INPUT=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_AUTOFS_FS=y
|
||||
CONFIG_ISO9660_FS=y
|
||||
CONFIG_JOLIET=y
|
||||
CONFIG_ZISOFS=y
|
||||
CONFIG_UDF_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_9P_FS=y
|
||||
CONFIG_9P_FS_POSIX_ACL=y
|
||||
CONFIG_9P_FS_SECURITY=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
@@ -17,6 +17,7 @@ extern int mac_parse_bootinfo(const struct bi_record *record);
|
||||
extern int mvme147_parse_bootinfo(const struct bi_record *record);
|
||||
extern int mvme16x_parse_bootinfo(const struct bi_record *record);
|
||||
extern int q40_parse_bootinfo(const struct bi_record *record);
|
||||
extern int virt_parse_bootinfo(const struct bi_record *record);
|
||||
|
||||
extern void config_amiga(void);
|
||||
extern void config_apollo(void);
|
||||
@@ -29,5 +30,6 @@ extern void config_mvme16x(void);
|
||||
extern void config_q40(void);
|
||||
extern void config_sun3(void);
|
||||
extern void config_sun3x(void);
|
||||
extern void config_virt(void);
|
||||
|
||||
#endif /* _M68K_CONFIG_H */
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
#include <asm/io_mm.h>
|
||||
#endif
|
||||
|
||||
#define gf_ioread32 ioread32be
|
||||
#define gf_iowrite32 iowrite32be
|
||||
|
||||
#include <asm-generic/io.h>
|
||||
|
||||
#endif /* _M68K_IO_H */
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
*/
|
||||
#if defined(CONFIG_COLDFIRE)
|
||||
#define NR_IRQS 256
|
||||
#elif defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
|
||||
#elif defined(CONFIG_VME) || defined(CONFIG_SUN3) || \
|
||||
defined(CONFIG_SUN3X) || defined(CONFIG_VIRT)
|
||||
#define NR_IRQS 200
|
||||
#elif defined(CONFIG_ATARI)
|
||||
#define NR_IRQS 141
|
||||
|
||||
@@ -80,6 +80,9 @@
|
||||
#elif defined(CONFIG_COLDFIRE)
|
||||
#define KMAP_START 0xe0000000
|
||||
#define KMAP_END 0xf0000000
|
||||
#elif defined(CONFIG_VIRT)
|
||||
#define KMAP_START 0xdf000000
|
||||
#define KMAP_END 0xff000000
|
||||
#else
|
||||
#define KMAP_START 0xd0000000
|
||||
#define KMAP_END 0xf0000000
|
||||
@@ -92,6 +95,10 @@ extern unsigned long m68k_vmalloc_end;
|
||||
#elif defined(CONFIG_COLDFIRE)
|
||||
#define VMALLOC_START 0xd0000000
|
||||
#define VMALLOC_END 0xe0000000
|
||||
#elif defined(CONFIG_VIRT)
|
||||
#define VMALLOC_OFFSET PAGE_SIZE
|
||||
#define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
|
||||
#define VMALLOC_END KMAP_START
|
||||
#else
|
||||
/* Just any arbitrary offset to the start of the vmalloc VM area: the
|
||||
* current 8MB value just means that there will be a 8MB "hole" after the
|
||||
|
||||
@@ -80,14 +80,14 @@
|
||||
({ u16 __v = le16_to_cpu(*(__force volatile u16 *) (addr)); __v; })
|
||||
|
||||
#define rom_out_8(addr, b) \
|
||||
({u8 __maybe_unused __w, __v = (b); u32 _addr = ((u32) (addr)); \
|
||||
(void)({u8 __maybe_unused __w, __v = (b); u32 _addr = ((u32) (addr)); \
|
||||
__w = ((*(__force volatile u8 *) ((_addr | 0x10000) + (__v<<1)))); })
|
||||
#define rom_out_be16(addr, w) \
|
||||
({u16 __maybe_unused __w, __v = (w); u32 _addr = ((u32) (addr)); \
|
||||
(void)({u16 __maybe_unused __w, __v = (w); u32 _addr = ((u32) (addr)); \
|
||||
__w = ((*(__force volatile u16 *) ((_addr & 0xFFFF0000UL) + ((__v & 0xFF)<<1)))); \
|
||||
__w = ((*(__force volatile u16 *) ((_addr | 0x10000) + ((__v >> 8)<<1)))); })
|
||||
#define rom_out_le16(addr, w) \
|
||||
({u16 __maybe_unused __w, __v = (w); u32 _addr = ((u32) (addr)); \
|
||||
(void)({u16 __maybe_unused __w, __v = (w); u32 _addr = ((u32) (addr)); \
|
||||
__w = ((*(__force volatile u16 *) ((_addr & 0xFFFF0000UL) + ((__v >> 8)<<1)))); \
|
||||
__w = ((*(__force volatile u16 *) ((_addr | 0x10000) + ((__v & 0xFF)<<1)))); })
|
||||
|
||||
|
||||
@@ -37,7 +37,8 @@ extern unsigned long m68k_machtype;
|
||||
#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \
|
||||
|| defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \
|
||||
|| defined(CONFIG_HP300) || defined(CONFIG_Q40) \
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
|
||||
|| defined(CONFIG_VIRT)
|
||||
# define MACH_IS_AMIGA (m68k_machtype == MACH_AMIGA)
|
||||
#else
|
||||
# define MACH_AMIGA_ONLY
|
||||
@@ -50,7 +51,8 @@ extern unsigned long m68k_machtype;
|
||||
#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \
|
||||
|| defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \
|
||||
|| defined(CONFIG_HP300) || defined(CONFIG_Q40) \
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
|
||||
|| defined(CONFIG_VIRT)
|
||||
# define MACH_IS_ATARI (m68k_machtype == MACH_ATARI)
|
||||
#else
|
||||
# define MACH_ATARI_ONLY
|
||||
@@ -63,7 +65,8 @@ extern unsigned long m68k_machtype;
|
||||
#elif defined(CONFIG_AMIGA) || defined(CONFIG_ATARI) || defined(CONFIG_APOLLO) \
|
||||
|| defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \
|
||||
|| defined(CONFIG_HP300) || defined(CONFIG_Q40) \
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
|
||||
|| defined(CONFIG_VIRT)
|
||||
# define MACH_IS_MAC (m68k_machtype == MACH_MAC)
|
||||
#else
|
||||
# define MACH_MAC_ONLY
|
||||
@@ -84,7 +87,8 @@ extern unsigned long m68k_machtype;
|
||||
#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
|
||||
|| defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \
|
||||
|| defined(CONFIG_HP300) || defined(CONFIG_Q40) \
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
|
||||
|| defined(CONFIG_VIRT)
|
||||
# define MACH_IS_APOLLO (m68k_machtype == MACH_APOLLO)
|
||||
#else
|
||||
# define MACH_APOLLO_ONLY
|
||||
@@ -97,7 +101,8 @@ extern unsigned long m68k_machtype;
|
||||
#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
|
||||
|| defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \
|
||||
|| defined(CONFIG_HP300) || defined(CONFIG_Q40) \
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME16x)
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME16x) \
|
||||
|| defined(CONFIG_VIRT)
|
||||
# define MACH_IS_MVME147 (m68k_machtype == MACH_MVME147)
|
||||
#else
|
||||
# define MACH_MVME147_ONLY
|
||||
@@ -110,7 +115,8 @@ extern unsigned long m68k_machtype;
|
||||
#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
|
||||
|| defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \
|
||||
|| defined(CONFIG_HP300) || defined(CONFIG_Q40) \
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
|
||||
|| defined(CONFIG_VIRT)
|
||||
# define MACH_IS_MVME16x (m68k_machtype == MACH_MVME16x)
|
||||
#else
|
||||
# define MACH_MVME16x_ONLY
|
||||
@@ -123,7 +129,8 @@ extern unsigned long m68k_machtype;
|
||||
#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
|
||||
|| defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
|
||||
|| defined(CONFIG_HP300) || defined(CONFIG_Q40) \
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
|
||||
|| defined(CONFIG_VIRT)
|
||||
# define MACH_IS_BVME6000 (m68k_machtype == MACH_BVME6000)
|
||||
#else
|
||||
# define MACH_BVME6000_ONLY
|
||||
@@ -136,7 +143,8 @@ extern unsigned long m68k_machtype;
|
||||
#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
|
||||
|| defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
|
||||
|| defined(CONFIG_BVME6000) || defined(CONFIG_Q40) \
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
|
||||
|| defined(CONFIG_VIRT)
|
||||
# define MACH_IS_HP300 (m68k_machtype == MACH_HP300)
|
||||
#else
|
||||
# define MACH_HP300_ONLY
|
||||
@@ -149,7 +157,8 @@ extern unsigned long m68k_machtype;
|
||||
#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
|
||||
|| defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
|
||||
|| defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
|
||||
|| defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
|
||||
|| defined(CONFIG_VIRT)
|
||||
# define MACH_IS_Q40 (m68k_machtype == MACH_Q40)
|
||||
#else
|
||||
# define MACH_Q40_ONLY
|
||||
@@ -162,7 +171,8 @@ extern unsigned long m68k_machtype;
|
||||
#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
|
||||
|| defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
|
||||
|| defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \
|
||||
|| defined(CONFIG_Q40) || defined(CONFIG_MVME147)
|
||||
|| defined(CONFIG_Q40) || defined(CONFIG_MVME147) \
|
||||
|| defined(CONFIG_VIRT)
|
||||
# define MACH_IS_SUN3X (m68k_machtype == MACH_SUN3X)
|
||||
#else
|
||||
# define CONFIG_SUN3X_ONLY
|
||||
@@ -170,6 +180,20 @@ extern unsigned long m68k_machtype;
|
||||
# define MACH_TYPE (MACH_SUN3X)
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_VIRT)
|
||||
# define MACH_IS_VIRT (0)
|
||||
#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
|
||||
|| defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
|
||||
|| defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \
|
||||
|| defined(CONFIG_Q40) || defined(CONFIG_SUN3X) \
|
||||
|| defined(CONFIG_MVME147)
|
||||
# define MACH_IS_VIRT (m68k_machtype == MACH_VIRT)
|
||||
#else
|
||||
# define MACH_VIRT_ONLY
|
||||
# define MACH_IS_VIRT (1)
|
||||
# define MACH_TYPE (MACH_VIRT)
|
||||
#endif
|
||||
|
||||
#ifndef MACH_TYPE
|
||||
# define MACH_TYPE (m68k_machtype)
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_VIRT_H
|
||||
#define __ASM_VIRT_H
|
||||
|
||||
#define NUM_VIRT_SOURCES 200
|
||||
|
||||
struct virt_booter_device_data {
|
||||
u32 mmio;
|
||||
u32 irq;
|
||||
};
|
||||
|
||||
struct virt_booter_data {
|
||||
u32 qemu_version;
|
||||
struct virt_booter_device_data pic;
|
||||
struct virt_booter_device_data rtc;
|
||||
struct virt_booter_device_data tty;
|
||||
struct virt_booter_device_data ctrl;
|
||||
struct virt_booter_device_data virtio;
|
||||
};
|
||||
|
||||
extern struct virt_booter_data virt_bi_data;
|
||||
|
||||
extern void __init virt_init_IRQ(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
* asm/bootinfo-virt.h -- Virtual-m68k-specific boot information definitions
|
||||
*/
|
||||
|
||||
#ifndef _UAPI_ASM_M68K_BOOTINFO_VIRT_H
|
||||
#define _UAPI_ASM_M68K_BOOTINFO_VIRT_H
|
||||
|
||||
#define BI_VIRT_QEMU_VERSION 0x8000
|
||||
#define BI_VIRT_GF_PIC_BASE 0x8001
|
||||
#define BI_VIRT_GF_RTC_BASE 0x8002
|
||||
#define BI_VIRT_GF_TTY_BASE 0x8003
|
||||
#define BI_VIRT_VIRTIO_BASE 0x8004
|
||||
#define BI_VIRT_CTRL_BASE 0x8005
|
||||
|
||||
#define VIRT_BOOTI_VERSION MK_BI_VERSION(2, 0)
|
||||
|
||||
#endif /* _UAPI_ASM_M68K_BOOTINFO_MAC_H */
|
||||
@@ -83,6 +83,7 @@ struct mem_info {
|
||||
#define MACH_SUN3X 11
|
||||
#define MACH_M54XX 12
|
||||
#define MACH_M5441X 13
|
||||
#define MACH_VIRT 14
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -11,6 +11,7 @@ extra-$(CONFIG_VME) := head.o
|
||||
extra-$(CONFIG_HP300) := head.o
|
||||
extra-$(CONFIG_Q40) := head.o
|
||||
extra-$(CONFIG_SUN3X) := head.o
|
||||
extra-$(CONFIG_VIRT) := head.o
|
||||
extra-$(CONFIG_SUN3) := sun3-head.o
|
||||
extra-y += vmlinux.lds
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ do_trace_entry:
|
||||
movel #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace
|
||||
subql #4,%sp
|
||||
SAVE_SWITCH_STACK
|
||||
jbsr syscall_trace
|
||||
jbsr syscall_trace_enter
|
||||
RESTORE_SWITCH_STACK
|
||||
addql #4,%sp
|
||||
movel %sp@(PT_OFF_ORIG_D0),%d0
|
||||
@@ -194,7 +194,7 @@ badsys:
|
||||
do_trace_exit:
|
||||
subql #4,%sp
|
||||
SAVE_SWITCH_STACK
|
||||
jbsr syscall_trace
|
||||
jbsr syscall_trace_leave
|
||||
RESTORE_SWITCH_STACK
|
||||
addql #4,%sp
|
||||
jra .Lret_from_exception
|
||||
|
||||
@@ -262,6 +262,7 @@
|
||||
#include <asm/bootinfo-hp300.h>
|
||||
#include <asm/bootinfo-mac.h>
|
||||
#include <asm/bootinfo-q40.h>
|
||||
#include <asm/bootinfo-virt.h>
|
||||
#include <asm/bootinfo-vme.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/entry.h>
|
||||
@@ -534,6 +535,7 @@ func_define putn,1
|
||||
#define is_not_apollo(lab) cmpl &MACH_APOLLO,%pc@(m68k_machtype); jne lab
|
||||
#define is_not_q40(lab) cmpl &MACH_Q40,%pc@(m68k_machtype); jne lab
|
||||
#define is_not_sun3x(lab) cmpl &MACH_SUN3X,%pc@(m68k_machtype); jne lab
|
||||
#define is_not_virt(lab) cmpl &MACH_VIRT,%pc@(m68k_machtype); jne lab
|
||||
|
||||
#define hasnt_leds(lab) cmpl &MACH_HP300,%pc@(m68k_machtype); \
|
||||
jeq 42f; \
|
||||
@@ -647,6 +649,14 @@ ENTRY(__start)
|
||||
L(test_notmac):
|
||||
#endif /* CONFIG_MAC */
|
||||
|
||||
#ifdef CONFIG_VIRT
|
||||
is_not_virt(L(test_notvirt))
|
||||
|
||||
get_bi_record BI_VIRT_GF_TTY_BASE
|
||||
lea %pc@(L(virt_gf_tty_base)),%a1
|
||||
movel %a0@,%a1@
|
||||
L(test_notvirt):
|
||||
#endif /* CONFIG_VIRT */
|
||||
|
||||
/*
|
||||
* There are ultimately two pieces of information we want for all kinds of
|
||||
@@ -1237,6 +1247,13 @@ L(mmu_init_not_mac):
|
||||
L(notsun3x):
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VIRT
|
||||
is_not_virt(L(novirt))
|
||||
mmu_map_tt #1,#0xFF000000,#0x01000000,#_PAGE_NOCACHE_S
|
||||
jbra L(mmu_init_done)
|
||||
L(novirt):
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_APOLLO
|
||||
is_not_apollo(L(notapollo))
|
||||
|
||||
@@ -3186,6 +3203,14 @@ func_start serial_putc,%d0/%d1/%a0/%a1
|
||||
3:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VIRT
|
||||
is_not_virt(1f)
|
||||
|
||||
movel L(virt_gf_tty_base),%a1
|
||||
movel %d0,%a1@(GF_PUT_CHAR)
|
||||
1:
|
||||
#endif
|
||||
|
||||
L(serial_putc_done):
|
||||
func_return serial_putc
|
||||
|
||||
@@ -3865,3 +3890,9 @@ q40_mem_cptr:
|
||||
L(q40_do_debug):
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_VIRT)
|
||||
GF_PUT_CHAR = 0x00
|
||||
L(virt_gf_tty_base):
|
||||
.long 0
|
||||
#endif /* CONFIG_VIRT */
|
||||
|
||||
@@ -270,12 +270,6 @@ out_eio:
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
asmlinkage void syscall_trace(void)
|
||||
{
|
||||
ptrace_report_syscall(0);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU)
|
||||
asmlinkage int syscall_trace_enter(void)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -290,4 +284,3 @@ asmlinkage void syscall_trace_leave(void)
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
ptrace_report_syscall_exit(task_pt_regs(current), 0);
|
||||
}
|
||||
#endif /* CONFIG_COLDFIRE */
|
||||
|
||||
@@ -181,6 +181,8 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
|
||||
unknown = hp300_parse_bootinfo(record);
|
||||
else if (MACH_IS_APOLLO)
|
||||
unknown = apollo_parse_bootinfo(record);
|
||||
else if (MACH_IS_VIRT)
|
||||
unknown = virt_parse_bootinfo(record);
|
||||
else
|
||||
unknown = 1;
|
||||
}
|
||||
@@ -311,6 +313,11 @@ void __init setup_arch(char **cmdline_p)
|
||||
cf_mmu_context_init();
|
||||
config_BSP(NULL, 0);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_VIRT
|
||||
case MACH_VIRT:
|
||||
config_virt();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
panic("No configuration setup");
|
||||
|
||||
@@ -243,7 +243,7 @@ fp_fdiv(struct fp_ext *dest, struct fp_ext *src)
|
||||
/* infinity / infinity = NaN (quiet, as always) */
|
||||
if (IS_INF(src))
|
||||
fp_set_nan(dest);
|
||||
/* infinity / anything else = infinity (with approprate sign) */
|
||||
/* infinity / anything else = infinity (with appropriate sign) */
|
||||
return dest;
|
||||
}
|
||||
if (IS_INF(src)) {
|
||||
|
||||
+15
-6
@@ -179,6 +179,12 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla
|
||||
return (void __iomem *)physaddr;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIRT
|
||||
if (MACH_IS_VIRT) {
|
||||
if (physaddr >= 0xff000000 && cacheflag == IOMAP_NOCACHE_SER)
|
||||
return (void __iomem *)physaddr;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_COLDFIRE
|
||||
if (__cf_internalio(physaddr))
|
||||
return (void __iomem *) physaddr;
|
||||
@@ -293,17 +299,20 @@ EXPORT_SYMBOL(__ioremap);
|
||||
void iounmap(void __iomem *addr)
|
||||
{
|
||||
#ifdef CONFIG_AMIGA
|
||||
if ((!MACH_IS_AMIGA) ||
|
||||
(((unsigned long)addr < 0x40000000) ||
|
||||
((unsigned long)addr > 0x60000000)))
|
||||
free_io_area((__force void *)addr);
|
||||
#else
|
||||
if (MACH_IS_AMIGA &&
|
||||
((unsigned long)addr >= 0x40000000) &&
|
||||
((unsigned long)addr < 0x60000000))
|
||||
return;
|
||||
#endif
|
||||
#ifdef CONFIG_VIRT
|
||||
if (MACH_IS_VIRT && (unsigned long)addr >= 0xff000000)
|
||||
return;
|
||||
#endif
|
||||
#ifdef CONFIG_COLDFIRE
|
||||
if (cf_internalio(addr))
|
||||
return;
|
||||
#endif
|
||||
free_io_area((__force void *)addr);
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(iounmap);
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Makefile for Linux arch/m68k/virt source directory
|
||||
#
|
||||
|
||||
obj-y := config.o ints.o platform.o
|
||||
@@ -0,0 +1,130 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/serial_core.h>
|
||||
#include <clocksource/timer-goldfish.h>
|
||||
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/bootinfo-virt.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/virt.h>
|
||||
#include <asm/config.h>
|
||||
|
||||
struct virt_booter_data virt_bi_data;
|
||||
|
||||
#define VIRT_CTRL_REG_FEATURES 0x00
|
||||
#define VIRT_CTRL_REG_CMD 0x04
|
||||
|
||||
static struct resource ctrlres;
|
||||
|
||||
enum {
|
||||
CMD_NOOP,
|
||||
CMD_RESET,
|
||||
CMD_HALT,
|
||||
CMD_PANIC,
|
||||
};
|
||||
|
||||
static void virt_get_model(char *str)
|
||||
{
|
||||
/* str is 80 characters long */
|
||||
sprintf(str, "QEMU Virtual M68K Machine (%u.%u.%u)",
|
||||
(u8)(virt_bi_data.qemu_version >> 24),
|
||||
(u8)(virt_bi_data.qemu_version >> 16),
|
||||
(u8)(virt_bi_data.qemu_version >> 8));
|
||||
}
|
||||
|
||||
static void virt_halt(void)
|
||||
{
|
||||
void __iomem *base = (void __iomem *)virt_bi_data.ctrl.mmio;
|
||||
|
||||
iowrite32be(CMD_HALT, base + VIRT_CTRL_REG_CMD);
|
||||
local_irq_disable();
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
static void virt_reset(void)
|
||||
{
|
||||
void __iomem *base = (void __iomem *)virt_bi_data.ctrl.mmio;
|
||||
|
||||
iowrite32be(CMD_RESET, base + VIRT_CTRL_REG_CMD);
|
||||
local_irq_disable();
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a virtual-m68k-specific record in the bootinfo
|
||||
*/
|
||||
|
||||
int __init virt_parse_bootinfo(const struct bi_record *record)
|
||||
{
|
||||
int unknown = 0;
|
||||
const void *data = record->data;
|
||||
|
||||
switch (be16_to_cpu(record->tag)) {
|
||||
case BI_VIRT_QEMU_VERSION:
|
||||
virt_bi_data.qemu_version = be32_to_cpup(data);
|
||||
break;
|
||||
case BI_VIRT_GF_PIC_BASE:
|
||||
virt_bi_data.pic.mmio = be32_to_cpup(data);
|
||||
data += 4;
|
||||
virt_bi_data.pic.irq = be32_to_cpup(data);
|
||||
break;
|
||||
case BI_VIRT_GF_RTC_BASE:
|
||||
virt_bi_data.rtc.mmio = be32_to_cpup(data);
|
||||
data += 4;
|
||||
virt_bi_data.rtc.irq = be32_to_cpup(data);
|
||||
break;
|
||||
case BI_VIRT_GF_TTY_BASE:
|
||||
virt_bi_data.tty.mmio = be32_to_cpup(data);
|
||||
data += 4;
|
||||
virt_bi_data.tty.irq = be32_to_cpup(data);
|
||||
break;
|
||||
case BI_VIRT_CTRL_BASE:
|
||||
virt_bi_data.ctrl.mmio = be32_to_cpup(data);
|
||||
data += 4;
|
||||
virt_bi_data.ctrl.irq = be32_to_cpup(data);
|
||||
break;
|
||||
case BI_VIRT_VIRTIO_BASE:
|
||||
virt_bi_data.virtio.mmio = be32_to_cpup(data);
|
||||
data += 4;
|
||||
virt_bi_data.virtio.irq = be32_to_cpup(data);
|
||||
break;
|
||||
default:
|
||||
unknown = 1;
|
||||
break;
|
||||
}
|
||||
return unknown;
|
||||
}
|
||||
|
||||
static void __init virt_sched_init(void)
|
||||
{
|
||||
goldfish_timer_init(virt_bi_data.rtc.irq,
|
||||
(void __iomem *)virt_bi_data.rtc.mmio);
|
||||
}
|
||||
|
||||
void __init config_virt(void)
|
||||
{
|
||||
char earlycon[24];
|
||||
|
||||
snprintf(earlycon, sizeof(earlycon), "early_gf_tty,0x%08x",
|
||||
virt_bi_data.tty.mmio);
|
||||
setup_earlycon(earlycon);
|
||||
|
||||
ctrlres = (struct resource)
|
||||
DEFINE_RES_MEM_NAMED(virt_bi_data.ctrl.mmio, 0x100,
|
||||
"virtctrl");
|
||||
|
||||
if (request_resource(&iomem_resource, &ctrlres)) {
|
||||
pr_err("Cannot allocate virt controller resource\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mach_init_IRQ = virt_init_IRQ;
|
||||
mach_sched_init = virt_sched_init;
|
||||
mach_get_model = virt_get_model;
|
||||
mach_reset = virt_reset;
|
||||
mach_halt = virt_halt;
|
||||
mach_power_off = virt_halt;
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/debug.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioport.h>
|
||||
|
||||
#include <asm/hwtest.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/irq_regs.h>
|
||||
#include <asm/virt.h>
|
||||
|
||||
#define GFPIC_REG_IRQ_PENDING 0x04
|
||||
#define GFPIC_REG_IRQ_DISABLE_ALL 0x08
|
||||
#define GFPIC_REG_IRQ_DISABLE 0x0c
|
||||
#define GFPIC_REG_IRQ_ENABLE 0x10
|
||||
|
||||
extern void show_registers(struct pt_regs *regs);
|
||||
|
||||
static struct resource picres[6];
|
||||
static const char *picname[6] = {
|
||||
"goldfish_pic.0",
|
||||
"goldfish_pic.1",
|
||||
"goldfish_pic.2",
|
||||
"goldfish_pic.3",
|
||||
"goldfish_pic.4",
|
||||
"goldfish_pic.5"
|
||||
};
|
||||
|
||||
/*
|
||||
* 6 goldfish-pic for CPU IRQ #1 to IRQ #6
|
||||
* CPU IRQ #1 -> PIC #1
|
||||
* IRQ #1 to IRQ #31 -> unused
|
||||
* IRQ #32 -> goldfish-tty
|
||||
* CPU IRQ #2 -> PIC #2
|
||||
* IRQ #1 to IRQ #32 -> virtio-mmio from 1 to 32
|
||||
* CPU IRQ #3 -> PIC #3
|
||||
* IRQ #1 to IRQ #32 -> virtio-mmio from 33 to 64
|
||||
* CPU IRQ #4 -> PIC #4
|
||||
* IRQ #1 to IRQ #32 -> virtio-mmio from 65 to 96
|
||||
* CPU IRQ #5 -> PIC #5
|
||||
* IRQ #1 to IRQ #32 -> virtio-mmio from 97 to 128
|
||||
* CPU IRQ #6 -> PIC #6
|
||||
* IRQ #1 -> goldfish-timer
|
||||
* IRQ #2 -> goldfish-rtc
|
||||
* IRQ #3 to IRQ #32 -> unused
|
||||
* CPU IRQ #7 -> NMI
|
||||
*/
|
||||
|
||||
static u32 gfpic_read(int pic, int reg)
|
||||
{
|
||||
void __iomem *base = (void __iomem *)(virt_bi_data.pic.mmio +
|
||||
pic * 0x1000);
|
||||
|
||||
return ioread32be(base + reg);
|
||||
}
|
||||
|
||||
static void gfpic_write(u32 value, int pic, int reg)
|
||||
{
|
||||
void __iomem *base = (void __iomem *)(virt_bi_data.pic.mmio +
|
||||
pic * 0x1000);
|
||||
|
||||
iowrite32be(value, base + reg);
|
||||
}
|
||||
|
||||
#define GF_PIC(irq) ((irq - IRQ_USER) / 32)
|
||||
#define GF_IRQ(irq) ((irq - IRQ_USER) % 32)
|
||||
|
||||
static void virt_irq_enable(struct irq_data *data)
|
||||
{
|
||||
gfpic_write(BIT(GF_IRQ(data->irq)), GF_PIC(data->irq),
|
||||
GFPIC_REG_IRQ_ENABLE);
|
||||
}
|
||||
|
||||
static void virt_irq_disable(struct irq_data *data)
|
||||
{
|
||||
gfpic_write(BIT(GF_IRQ(data->irq)), GF_PIC(data->irq),
|
||||
GFPIC_REG_IRQ_DISABLE);
|
||||
}
|
||||
|
||||
static unsigned int virt_irq_startup(struct irq_data *data)
|
||||
{
|
||||
virt_irq_enable(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t virt_nmi_handler(int irq, void *dev_id)
|
||||
{
|
||||
static int in_nmi;
|
||||
|
||||
if (READ_ONCE(in_nmi))
|
||||
return IRQ_HANDLED;
|
||||
WRITE_ONCE(in_nmi, 1);
|
||||
|
||||
pr_warn("Non-Maskable Interrupt\n");
|
||||
show_registers(get_irq_regs());
|
||||
|
||||
WRITE_ONCE(in_nmi, 0);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irq_chip virt_irq_chip = {
|
||||
.name = "virt",
|
||||
.irq_enable = virt_irq_enable,
|
||||
.irq_disable = virt_irq_disable,
|
||||
.irq_startup = virt_irq_startup,
|
||||
.irq_shutdown = virt_irq_disable,
|
||||
};
|
||||
|
||||
static void goldfish_pic_irq(struct irq_desc *desc)
|
||||
{
|
||||
u32 irq_pending;
|
||||
unsigned int irq_num;
|
||||
unsigned int pic = desc->irq_data.irq - 1;
|
||||
|
||||
irq_pending = gfpic_read(pic, GFPIC_REG_IRQ_PENDING);
|
||||
irq_num = IRQ_USER + pic * 32;
|
||||
|
||||
do {
|
||||
if (irq_pending & 1)
|
||||
generic_handle_irq(irq_num);
|
||||
++irq_num;
|
||||
irq_pending >>= 1;
|
||||
} while (irq_pending);
|
||||
}
|
||||
|
||||
void __init virt_init_IRQ(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
m68k_setup_irq_controller(&virt_irq_chip, handle_simple_irq, IRQ_USER,
|
||||
NUM_VIRT_SOURCES - IRQ_USER);
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
|
||||
picres[i] = (struct resource)
|
||||
DEFINE_RES_MEM_NAMED(virt_bi_data.pic.mmio + i * 0x1000,
|
||||
0x1000, picname[i]);
|
||||
if (request_resource(&iomem_resource, &picres[i])) {
|
||||
pr_err("Cannot allocate %s resource\n", picname[i]);
|
||||
return;
|
||||
}
|
||||
|
||||
irq_set_chained_handler(virt_bi_data.pic.irq + i,
|
||||
goldfish_pic_irq);
|
||||
}
|
||||
|
||||
if (request_irq(IRQ_AUTO_7, virt_nmi_handler, 0, "NMI",
|
||||
virt_nmi_handler))
|
||||
pr_err("Couldn't register NMI\n");
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <asm/virt.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#define VIRTIO_BUS_NB 128
|
||||
|
||||
static int __init virt_virtio_init(unsigned int id)
|
||||
{
|
||||
const struct resource res[] = {
|
||||
DEFINE_RES_MEM(virt_bi_data.virtio.mmio + id * 0x200, 0x200),
|
||||
DEFINE_RES_IRQ(virt_bi_data.virtio.irq + id),
|
||||
};
|
||||
struct platform_device *pdev;
|
||||
|
||||
pdev = platform_device_register_simple("virtio-mmio", id,
|
||||
res, ARRAY_SIZE(res));
|
||||
if (IS_ERR(pdev))
|
||||
return PTR_ERR(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init virt_platform_init(void)
|
||||
{
|
||||
const struct resource goldfish_tty_res[] = {
|
||||
DEFINE_RES_MEM(virt_bi_data.tty.mmio, 1),
|
||||
DEFINE_RES_IRQ(virt_bi_data.tty.irq),
|
||||
};
|
||||
/* this is the second gf-rtc, the first one is used by the scheduler */
|
||||
const struct resource goldfish_rtc_res[] = {
|
||||
DEFINE_RES_MEM(virt_bi_data.rtc.mmio + 0x1000, 0x1000),
|
||||
DEFINE_RES_IRQ(virt_bi_data.rtc.irq + 1),
|
||||
};
|
||||
struct platform_device *pdev;
|
||||
unsigned int i;
|
||||
|
||||
if (!MACH_IS_VIRT)
|
||||
return -ENODEV;
|
||||
|
||||
/* We need this to have DMA'able memory provided to goldfish-tty */
|
||||
min_low_pfn = 0;
|
||||
|
||||
pdev = platform_device_register_simple("goldfish_tty",
|
||||
PLATFORM_DEVID_NONE,
|
||||
goldfish_tty_res,
|
||||
ARRAY_SIZE(goldfish_tty_res));
|
||||
if (IS_ERR(pdev))
|
||||
return PTR_ERR(pdev);
|
||||
|
||||
pdev = platform_device_register_simple("goldfish_rtc",
|
||||
PLATFORM_DEVID_NONE,
|
||||
goldfish_rtc_res,
|
||||
ARRAY_SIZE(goldfish_rtc_res));
|
||||
if (IS_ERR(pdev))
|
||||
return PTR_ERR(pdev);
|
||||
|
||||
for (i = 0; i < VIRTIO_BUS_NB; i++) {
|
||||
int err;
|
||||
|
||||
err = virt_virtio_init(i);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(virt_platform_init);
|
||||
@@ -76,4 +76,22 @@ static inline void init_ia32_feat_ctl(struct cpuinfo_x86 *c) {}
|
||||
|
||||
extern __noendbr void cet_disable(void);
|
||||
|
||||
struct ucode_cpu_info;
|
||||
|
||||
int intel_cpu_collect_info(struct ucode_cpu_info *uci);
|
||||
|
||||
static inline bool intel_cpu_signatures_match(unsigned int s1, unsigned int p1,
|
||||
unsigned int s2, unsigned int p2)
|
||||
{
|
||||
if (s1 != s2)
|
||||
return false;
|
||||
|
||||
/* Processor flags are either both 0 ... */
|
||||
if (!p1 && !p2)
|
||||
return true;
|
||||
|
||||
/* ... or they intersect. */
|
||||
return p1 & p2;
|
||||
}
|
||||
|
||||
#endif /* _ASM_X86_CPU_H */
|
||||
|
||||
@@ -76,6 +76,8 @@
|
||||
|
||||
/* Abbreviated from Intel SDM name IA32_CORE_CAPABILITIES */
|
||||
#define MSR_IA32_CORE_CAPS 0x000000cf
|
||||
#define MSR_IA32_CORE_CAPS_INTEGRITY_CAPS_BIT 2
|
||||
#define MSR_IA32_CORE_CAPS_INTEGRITY_CAPS BIT(MSR_IA32_CORE_CAPS_INTEGRITY_CAPS_BIT)
|
||||
#define MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT_BIT 5
|
||||
#define MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT BIT(MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT_BIT)
|
||||
|
||||
@@ -154,6 +156,11 @@
|
||||
#define MSR_IA32_POWER_CTL 0x000001fc
|
||||
#define MSR_IA32_POWER_CTL_BIT_EE 19
|
||||
|
||||
/* Abbreviated from Intel SDM name IA32_INTEGRITY_CAPABILITIES */
|
||||
#define MSR_INTEGRITY_CAPS 0x000002d9
|
||||
#define MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT 4
|
||||
#define MSR_INTEGRITY_CAPS_PERIODIC_BIST BIT(MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT)
|
||||
|
||||
#define MSR_LBR_NHM_FROM 0x00000680
|
||||
#define MSR_LBR_NHM_TO 0x000006c0
|
||||
#define MSR_LBR_CORE_FROM 0x00000040
|
||||
|
||||
@@ -31,9 +31,22 @@ enum hsmp_message_ids {
|
||||
HSMP_GET_CCLK_THROTTLE_LIMIT, /* 10h Get CCLK frequency limit in socket */
|
||||
HSMP_GET_C0_PERCENT, /* 11h Get average C0 residency in socket */
|
||||
HSMP_SET_NBIO_DPM_LEVEL, /* 12h Set max/min LCLK DPM Level for a given NBIO */
|
||||
/* 13h Reserved */
|
||||
HSMP_GET_DDR_BANDWIDTH = 0x14, /* 14h Get theoretical maximum and current DDR Bandwidth */
|
||||
HSMP_GET_TEMP_MONITOR, /* 15h Get per-DIMM temperature and refresh rates */
|
||||
HSMP_GET_NBIO_DPM_LEVEL, /* 13h Get LCLK DPM level min and max for a given NBIO */
|
||||
HSMP_GET_DDR_BANDWIDTH, /* 14h Get theoretical maximum and current DDR Bandwidth */
|
||||
HSMP_GET_TEMP_MONITOR, /* 15h Get socket temperature */
|
||||
HSMP_GET_DIMM_TEMP_RANGE, /* 16h Get per-DIMM temperature range and refresh rate */
|
||||
HSMP_GET_DIMM_POWER, /* 17h Get per-DIMM power consumption */
|
||||
HSMP_GET_DIMM_THERMAL, /* 18h Get per-DIMM thermal sensors */
|
||||
HSMP_GET_SOCKET_FREQ_LIMIT, /* 19h Get current active frequency per socket */
|
||||
HSMP_GET_CCLK_CORE_LIMIT, /* 1Ah Get CCLK frequency limit per core */
|
||||
HSMP_GET_RAILS_SVI, /* 1Bh Get SVI-based Telemetry for all rails */
|
||||
HSMP_GET_SOCKET_FMAX_FMIN, /* 1Ch Get Fmax and Fmin per socket */
|
||||
HSMP_GET_IOLINK_BANDWITH, /* 1Dh Get current bandwidth on IO Link */
|
||||
HSMP_GET_XGMI_BANDWITH, /* 1Eh Get current bandwidth on xGMI Link */
|
||||
HSMP_SET_GMI3_WIDTH, /* 1Fh Set max and min GMI3 Link width */
|
||||
HSMP_SET_PCI_RATE, /* 20h Control link rate on PCIe devices */
|
||||
HSMP_SET_POWER_MODE, /* 21h Select power efficiency profile policy */
|
||||
HSMP_SET_PSTATE_MAX_MIN, /* 22h Set the max and min DF P-State */
|
||||
HSMP_MSG_ID_MAX,
|
||||
};
|
||||
|
||||
@@ -175,8 +188,12 @@ static const struct hsmp_msg_desc hsmp_msg_desc_table[] = {
|
||||
*/
|
||||
{1, 0, HSMP_SET},
|
||||
|
||||
/* RESERVED message */
|
||||
{0, 0, HSMP_RSVD},
|
||||
/*
|
||||
* HSMP_GET_NBIO_DPM_LEVEL, num_args = 1, response_sz = 1
|
||||
* input: args[0] = nbioid[23:16]
|
||||
* output: args[0] = max dpm level[15:8] + min dpm level[7:0]
|
||||
*/
|
||||
{1, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_DDR_BANDWIDTH, num_args = 0, response_sz = 1
|
||||
@@ -191,6 +208,93 @@ static const struct hsmp_msg_desc hsmp_msg_desc_table[] = {
|
||||
* [7:5] fractional part
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_DIMM_TEMP_RANGE, num_args = 1, response_sz = 1
|
||||
* input: args[0] = DIMM address[7:0]
|
||||
* output: args[0] = refresh rate[3] + temperature range[2:0]
|
||||
*/
|
||||
{1, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_DIMM_POWER, num_args = 1, response_sz = 1
|
||||
* input: args[0] = DIMM address[7:0]
|
||||
* output: args[0] = DIMM power in mW[31:17] + update rate in ms[16:8] +
|
||||
* DIMM address[7:0]
|
||||
*/
|
||||
{1, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_DIMM_THERMAL, num_args = 1, response_sz = 1
|
||||
* input: args[0] = DIMM address[7:0]
|
||||
* output: args[0] = temperature in degree celcius[31:21] + update rate in ms[16:8] +
|
||||
* DIMM address[7:0]
|
||||
*/
|
||||
{1, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_SOCKET_FREQ_LIMIT, num_args = 0, response_sz = 1
|
||||
* output: args[0] = frequency in MHz[31:16] + frequency source[15:0]
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_CCLK_CORE_LIMIT, num_args = 1, response_sz = 1
|
||||
* input: args[0] = apic id [31:0]
|
||||
* output: args[0] = frequency in MHz[31:0]
|
||||
*/
|
||||
{1, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_RAILS_SVI, num_args = 0, response_sz = 1
|
||||
* output: args[0] = power in mW[31:0]
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_SOCKET_FMAX_FMIN, num_args = 0, response_sz = 1
|
||||
* output: args[0] = fmax in MHz[31:16] + fmin in MHz[15:0]
|
||||
*/
|
||||
{0, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_IOLINK_BANDWITH, num_args = 1, response_sz = 1
|
||||
* input: args[0] = link id[15:8] + bw type[2:0]
|
||||
* output: args[0] = io bandwidth in Mbps[31:0]
|
||||
*/
|
||||
{1, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_GET_XGMI_BANDWITH, num_args = 1, response_sz = 1
|
||||
* input: args[0] = link id[15:8] + bw type[2:0]
|
||||
* output: args[0] = xgmi bandwidth in Mbps[31:0]
|
||||
*/
|
||||
{1, 1, HSMP_GET},
|
||||
|
||||
/*
|
||||
* HSMP_SET_GMI3_WIDTH, num_args = 1, response_sz = 0
|
||||
* input: args[0] = min link width[15:8] + max link width[7:0]
|
||||
*/
|
||||
{1, 0, HSMP_SET},
|
||||
|
||||
/*
|
||||
* HSMP_SET_PCI_RATE, num_args = 1, response_sz = 1
|
||||
* input: args[0] = link rate control value
|
||||
* output: args[0] = previous link rate control value
|
||||
*/
|
||||
{1, 1, HSMP_SET},
|
||||
|
||||
/*
|
||||
* HSMP_SET_POWER_MODE, num_args = 1, response_sz = 0
|
||||
* input: args[0] = power efficiency mode[2:0]
|
||||
*/
|
||||
{1, 0, HSMP_SET},
|
||||
|
||||
/*
|
||||
* HSMP_SET_PSTATE_MAX_MIN, num_args = 1, response_sz = 0
|
||||
* input: args[0] = min df pstate[15:8] + max df pstate[7:0]
|
||||
*/
|
||||
{1, 0, HSMP_SET},
|
||||
};
|
||||
|
||||
/* Reset to default packing */
|
||||
|
||||
@@ -184,6 +184,38 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
|
||||
return false;
|
||||
}
|
||||
|
||||
int intel_cpu_collect_info(struct ucode_cpu_info *uci)
|
||||
{
|
||||
unsigned int val[2];
|
||||
unsigned int family, model;
|
||||
struct cpu_signature csig = { 0 };
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
|
||||
memset(uci, 0, sizeof(*uci));
|
||||
|
||||
eax = 0x00000001;
|
||||
ecx = 0;
|
||||
native_cpuid(&eax, &ebx, &ecx, &edx);
|
||||
csig.sig = eax;
|
||||
|
||||
family = x86_family(eax);
|
||||
model = x86_model(eax);
|
||||
|
||||
if (model >= 5 || family > 6) {
|
||||
/* get processor flags from MSR 0x17 */
|
||||
native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
|
||||
csig.pf = 1 << ((val[1] >> 18) & 7);
|
||||
}
|
||||
|
||||
csig.rev = intel_get_microcode_revision();
|
||||
|
||||
uci->cpu_sig = csig;
|
||||
uci->valid = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(intel_cpu_collect_info);
|
||||
|
||||
static void early_init_intel(struct cpuinfo_x86 *c)
|
||||
{
|
||||
u64 misc_enable;
|
||||
|
||||
@@ -45,20 +45,6 @@ static struct microcode_intel *intel_ucode_patch;
|
||||
/* last level cache size per core */
|
||||
static int llc_size_per_core;
|
||||
|
||||
static inline bool cpu_signatures_match(unsigned int s1, unsigned int p1,
|
||||
unsigned int s2, unsigned int p2)
|
||||
{
|
||||
if (s1 != s2)
|
||||
return false;
|
||||
|
||||
/* Processor flags are either both 0 ... */
|
||||
if (!p1 && !p2)
|
||||
return true;
|
||||
|
||||
/* ... or they intersect. */
|
||||
return p1 & p2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if update has been found, 0 otherwise.
|
||||
*/
|
||||
@@ -69,7 +55,7 @@ static int find_matching_signature(void *mc, unsigned int csig, int cpf)
|
||||
struct extended_signature *ext_sig;
|
||||
int i;
|
||||
|
||||
if (cpu_signatures_match(csig, cpf, mc_hdr->sig, mc_hdr->pf))
|
||||
if (intel_cpu_signatures_match(csig, cpf, mc_hdr->sig, mc_hdr->pf))
|
||||
return 1;
|
||||
|
||||
/* Look for ext. headers: */
|
||||
@@ -80,7 +66,7 @@ static int find_matching_signature(void *mc, unsigned int csig, int cpf)
|
||||
ext_sig = (void *)ext_hdr + EXT_HEADER_SIZE;
|
||||
|
||||
for (i = 0; i < ext_hdr->count; i++) {
|
||||
if (cpu_signatures_match(csig, cpf, ext_sig->sig, ext_sig->pf))
|
||||
if (intel_cpu_signatures_match(csig, cpf, ext_sig->sig, ext_sig->pf))
|
||||
return 1;
|
||||
ext_sig++;
|
||||
}
|
||||
@@ -342,37 +328,6 @@ next:
|
||||
return patch;
|
||||
}
|
||||
|
||||
static int collect_cpu_info_early(struct ucode_cpu_info *uci)
|
||||
{
|
||||
unsigned int val[2];
|
||||
unsigned int family, model;
|
||||
struct cpu_signature csig = { 0 };
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
|
||||
memset(uci, 0, sizeof(*uci));
|
||||
|
||||
eax = 0x00000001;
|
||||
ecx = 0;
|
||||
native_cpuid(&eax, &ebx, &ecx, &edx);
|
||||
csig.sig = eax;
|
||||
|
||||
family = x86_family(eax);
|
||||
model = x86_model(eax);
|
||||
|
||||
if ((model >= 5) || (family > 6)) {
|
||||
/* get processor flags from MSR 0x17 */
|
||||
native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
|
||||
csig.pf = 1 << ((val[1] >> 18) & 7);
|
||||
}
|
||||
|
||||
csig.rev = intel_get_microcode_revision();
|
||||
|
||||
uci->cpu_sig = csig;
|
||||
uci->valid = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void show_saved_mc(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
@@ -386,7 +341,7 @@ static void show_saved_mc(void)
|
||||
return;
|
||||
}
|
||||
|
||||
collect_cpu_info_early(&uci);
|
||||
intel_cpu_collect_info(&uci);
|
||||
|
||||
sig = uci.cpu_sig.sig;
|
||||
pf = uci.cpu_sig.pf;
|
||||
@@ -502,7 +457,7 @@ void show_ucode_info_early(void)
|
||||
struct ucode_cpu_info uci;
|
||||
|
||||
if (delay_ucode_info) {
|
||||
collect_cpu_info_early(&uci);
|
||||
intel_cpu_collect_info(&uci);
|
||||
print_ucode_info(&uci, current_mc_date);
|
||||
delay_ucode_info = 0;
|
||||
}
|
||||
@@ -604,7 +559,7 @@ int __init save_microcode_in_initrd_intel(void)
|
||||
if (!(cp.data && cp.size))
|
||||
return 0;
|
||||
|
||||
collect_cpu_info_early(&uci);
|
||||
intel_cpu_collect_info(&uci);
|
||||
|
||||
scan_microcode(cp.data, cp.size, &uci, true);
|
||||
|
||||
@@ -637,7 +592,7 @@ static struct microcode_intel *__load_ucode_intel(struct ucode_cpu_info *uci)
|
||||
if (!(cp.data && cp.size))
|
||||
return NULL;
|
||||
|
||||
collect_cpu_info_early(uci);
|
||||
intel_cpu_collect_info(uci);
|
||||
|
||||
return scan_microcode(cp.data, cp.size, uci, false);
|
||||
}
|
||||
@@ -712,7 +667,7 @@ void reload_ucode_intel(void)
|
||||
struct microcode_intel *p;
|
||||
struct ucode_cpu_info uci;
|
||||
|
||||
collect_cpu_info_early(&uci);
|
||||
intel_cpu_collect_info(&uci);
|
||||
|
||||
p = find_patch(&uci);
|
||||
if (!p)
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/edd.h>
|
||||
#include <linux/objtool.h>
|
||||
|
||||
#include <xen/xen.h>
|
||||
#include <xen/events.h>
|
||||
@@ -165,7 +164,6 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
|
||||
|
||||
*bx &= maskebx;
|
||||
}
|
||||
STACK_FRAME_NON_STANDARD(xen_cpuid); /* XEN_EMULATE_PREFIX */
|
||||
|
||||
static bool __init xen_check_mwait(void)
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ config XTENSA
|
||||
select ARCH_32BIT_OFF_T
|
||||
select ARCH_HAS_BINFMT_FLAT if !MMU
|
||||
select ARCH_HAS_CURRENT_STACK_POINTER
|
||||
select ARCH_HAS_DEBUG_VM_PGTABLE
|
||||
select ARCH_HAS_DMA_PREP_COHERENT if MMU
|
||||
select ARCH_HAS_SYNC_DMA_FOR_CPU if MMU
|
||||
select ARCH_HAS_SYNC_DMA_FOR_DEVICE if MMU
|
||||
@@ -29,8 +30,10 @@ config XTENSA
|
||||
select HAVE_ARCH_AUDITSYSCALL
|
||||
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
|
||||
select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL
|
||||
select HAVE_ARCH_KCSAN
|
||||
select HAVE_ARCH_SECCOMP_FILTER
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
select HAVE_CONTEXT_TRACKING
|
||||
select HAVE_DEBUG_KMEMLEAK
|
||||
select HAVE_DMA_CONTIGUOUS
|
||||
select HAVE_EXIT_THREAD
|
||||
@@ -42,6 +45,7 @@ config XTENSA
|
||||
select HAVE_PERF_EVENTS
|
||||
select HAVE_STACKPROTECTOR
|
||||
select HAVE_SYSCALL_TRACEPOINTS
|
||||
select HAVE_VIRT_CPU_ACCOUNTING_GEN
|
||||
select IRQ_DOMAIN
|
||||
select MODULES_USE_ELF_RELA
|
||||
select PERF_USE_VMALLOC
|
||||
@@ -79,6 +83,7 @@ config STACKTRACE_SUPPORT
|
||||
|
||||
config MMU
|
||||
def_bool n
|
||||
select PFAULT
|
||||
|
||||
config HAVE_XTENSA_GPIO32
|
||||
def_bool n
|
||||
@@ -178,6 +183,16 @@ config XTENSA_FAKE_NMI
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PFAULT
|
||||
bool "Handle protection faults" if EXPERT && !MMU
|
||||
default y
|
||||
help
|
||||
Handle protection faults. MMU configurations must enable it.
|
||||
noMMU configurations may disable it if used memory map never
|
||||
generates protection faults or faults are always fatal.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config XTENSA_UNALIGNED_USER
|
||||
bool "Unaligned memory access in user space"
|
||||
help
|
||||
@@ -773,6 +788,9 @@ endmenu
|
||||
|
||||
menu "Power management options"
|
||||
|
||||
config ARCH_HIBERNATION_POSSIBLE
|
||||
def_bool y
|
||||
|
||||
source "kernel/power/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -16,6 +16,7 @@ CFLAGS_REMOVE_inffast.o = -pg
|
||||
endif
|
||||
|
||||
KASAN_SANITIZE := n
|
||||
KCSAN_SANITIZE := n
|
||||
|
||||
CFLAGS_REMOVE_inflate.o += -fstack-protector -fstack-protector-strong
|
||||
CFLAGS_REMOVE_zmem.o += -fstack-protector -fstack-protector-strong
|
||||
|
||||
@@ -11,9 +11,15 @@
|
||||
|
||||
#include <asm/core.h>
|
||||
|
||||
#define mb() ({ __asm__ __volatile__("memw" : : : "memory"); })
|
||||
#define rmb() barrier()
|
||||
#define wmb() mb()
|
||||
#define __mb() ({ __asm__ __volatile__("memw" : : : "memory"); })
|
||||
#define __rmb() barrier()
|
||||
#define __wmb() __mb()
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define __smp_mb() __mb()
|
||||
#define __smp_rmb() __rmb()
|
||||
#define __smp_wmb() __wmb()
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_S32C1I
|
||||
#define __smp_mb__before_atomic() barrier()
|
||||
|
||||
@@ -99,7 +99,7 @@ static inline unsigned long __fls(unsigned long word)
|
||||
#if XCHAL_HAVE_EXCLUSIVE
|
||||
|
||||
#define BIT_OP(op, insn, inv) \
|
||||
static inline void op##_bit(unsigned int bit, volatile unsigned long *p)\
|
||||
static inline void arch_##op##_bit(unsigned int bit, volatile unsigned long *p)\
|
||||
{ \
|
||||
unsigned long tmp; \
|
||||
unsigned long mask = 1UL << (bit & 31); \
|
||||
@@ -119,7 +119,7 @@ static inline void op##_bit(unsigned int bit, volatile unsigned long *p)\
|
||||
|
||||
#define TEST_AND_BIT_OP(op, insn, inv) \
|
||||
static inline int \
|
||||
test_and_##op##_bit(unsigned int bit, volatile unsigned long *p) \
|
||||
arch_test_and_##op##_bit(unsigned int bit, volatile unsigned long *p) \
|
||||
{ \
|
||||
unsigned long tmp, value; \
|
||||
unsigned long mask = 1UL << (bit & 31); \
|
||||
@@ -142,7 +142,7 @@ test_and_##op##_bit(unsigned int bit, volatile unsigned long *p) \
|
||||
#elif XCHAL_HAVE_S32C1I
|
||||
|
||||
#define BIT_OP(op, insn, inv) \
|
||||
static inline void op##_bit(unsigned int bit, volatile unsigned long *p)\
|
||||
static inline void arch_##op##_bit(unsigned int bit, volatile unsigned long *p)\
|
||||
{ \
|
||||
unsigned long tmp, value; \
|
||||
unsigned long mask = 1UL << (bit & 31); \
|
||||
@@ -163,7 +163,7 @@ static inline void op##_bit(unsigned int bit, volatile unsigned long *p)\
|
||||
|
||||
#define TEST_AND_BIT_OP(op, insn, inv) \
|
||||
static inline int \
|
||||
test_and_##op##_bit(unsigned int bit, volatile unsigned long *p) \
|
||||
arch_test_and_##op##_bit(unsigned int bit, volatile unsigned long *p) \
|
||||
{ \
|
||||
unsigned long tmp, value; \
|
||||
unsigned long mask = 1UL << (bit & 31); \
|
||||
@@ -205,6 +205,8 @@ BIT_OPS(change, "xor", )
|
||||
#undef BIT_OP
|
||||
#undef TEST_AND_BIT_OP
|
||||
|
||||
#include <asm-generic/bitops/instrumented-atomic.h>
|
||||
|
||||
#include <asm-generic/bitops/le.h>
|
||||
|
||||
#include <asm-generic/bitops/ext2-atomic-setbit.h>
|
||||
|
||||
@@ -142,11 +142,12 @@ typedef struct { XCHAL_CP6_SA_LIST(2) } xtregs_cp6_t
|
||||
typedef struct { XCHAL_CP7_SA_LIST(2) } xtregs_cp7_t
|
||||
__attribute__ ((aligned (XCHAL_CP7_SA_ALIGN)));
|
||||
|
||||
extern struct thread_info* coprocessor_owner[XCHAL_CP_MAX];
|
||||
extern void coprocessor_flush(struct thread_info*, int);
|
||||
|
||||
extern void coprocessor_release_all(struct thread_info*);
|
||||
extern void coprocessor_flush_all(struct thread_info*);
|
||||
struct thread_info;
|
||||
void coprocessor_flush(struct thread_info *ti, int cp_index);
|
||||
void coprocessor_release_all(struct thread_info *ti);
|
||||
void coprocessor_flush_all(struct thread_info *ti);
|
||||
void coprocessor_flush_release_all(struct thread_info *ti);
|
||||
void local_coprocessors_flush_release_all(void);
|
||||
|
||||
#endif /* XTENSA_HAVE_COPROCESSORS */
|
||||
|
||||
|
||||
@@ -246,6 +246,13 @@ extern unsigned long __get_wchan(struct task_struct *p);
|
||||
v; \
|
||||
})
|
||||
|
||||
#define xtensa_xsr(x, sr) \
|
||||
({ \
|
||||
unsigned int __v__ = (unsigned int)(x); \
|
||||
__asm__ __volatile__ ("xsr %0, " __stringify(sr) : "+a"(__v__)); \
|
||||
__v__; \
|
||||
})
|
||||
|
||||
#if XCHAL_HAVE_EXTERN_REGS
|
||||
|
||||
static inline void set_er(unsigned long value, unsigned long addr)
|
||||
|
||||
@@ -29,7 +29,7 @@ extern char _Level5InterruptVector_text_end[];
|
||||
extern char _Level6InterruptVector_text_start[];
|
||||
extern char _Level6InterruptVector_text_end[];
|
||||
#endif
|
||||
#ifdef CONFIG_SMP
|
||||
#ifdef CONFIG_SECONDARY_RESET_VECTOR
|
||||
extern char _SecondaryResetVector_text_start[];
|
||||
extern char _SecondaryResetVector_text_end[];
|
||||
#endif
|
||||
|
||||
@@ -52,12 +52,21 @@ struct thread_info {
|
||||
__u32 cpu; /* current CPU */
|
||||
__s32 preempt_count; /* 0 => preemptable,< 0 => BUG*/
|
||||
|
||||
unsigned long cpenable;
|
||||
#if XCHAL_HAVE_EXCLUSIVE
|
||||
/* result of the most recent exclusive store */
|
||||
unsigned long atomctl8;
|
||||
#endif
|
||||
#ifdef CONFIG_USER_ABI_CALL0_PROBE
|
||||
/* Address where PS.WOE was enabled by the ABI probing code */
|
||||
unsigned long ps_woe_fix_addr;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If i-th bit is set then coprocessor state is loaded into the
|
||||
* coprocessor i on CPU cp_owner_cpu.
|
||||
*/
|
||||
unsigned long cpenable;
|
||||
u32 cp_owner_cpu;
|
||||
/* Allocate storage for extra user states and coprocessor states. */
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
xtregs_coprocessor_t xtregs_cp;
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
typedef void xtensa_exception_handler(struct pt_regs *regs);
|
||||
|
||||
/*
|
||||
* Per-CPU exception handling data structure.
|
||||
* EXCSAVE1 points to it.
|
||||
@@ -25,31 +27,47 @@ struct exc_table {
|
||||
void *fixup;
|
||||
/* For passing a parameter to fixup */
|
||||
void *fixup_param;
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
/* Pointers to owner struct thread_info */
|
||||
struct thread_info *coprocessor_owner[XCHAL_CP_MAX];
|
||||
#endif
|
||||
/* Fast user exception handlers */
|
||||
void *fast_user_handler[EXCCAUSE_N];
|
||||
/* Fast kernel exception handlers */
|
||||
void *fast_kernel_handler[EXCCAUSE_N];
|
||||
/* Default C-Handlers */
|
||||
void *default_handler[EXCCAUSE_N];
|
||||
xtensa_exception_handler *default_handler[EXCCAUSE_N];
|
||||
};
|
||||
|
||||
/*
|
||||
* handler must be either of the following:
|
||||
* void (*)(struct pt_regs *regs);
|
||||
* void (*)(struct pt_regs *regs, unsigned long exccause);
|
||||
*/
|
||||
extern void * __init trap_set_handler(int cause, void *handler);
|
||||
extern void do_unhandled(struct pt_regs *regs, unsigned long exccause);
|
||||
void fast_second_level_miss(void);
|
||||
DECLARE_PER_CPU(struct exc_table, exc_table);
|
||||
|
||||
xtensa_exception_handler *
|
||||
__init trap_set_handler(int cause, xtensa_exception_handler *handler);
|
||||
|
||||
asmlinkage void fast_illegal_instruction_user(void);
|
||||
asmlinkage void fast_syscall_user(void);
|
||||
asmlinkage void fast_alloca(void);
|
||||
asmlinkage void fast_unaligned(void);
|
||||
asmlinkage void fast_second_level_miss(void);
|
||||
asmlinkage void fast_store_prohibited(void);
|
||||
asmlinkage void fast_coprocessor(void);
|
||||
|
||||
asmlinkage void kernel_exception(void);
|
||||
asmlinkage void user_exception(void);
|
||||
asmlinkage void system_call(struct pt_regs *regs);
|
||||
|
||||
void do_IRQ(int hwirq, struct pt_regs *regs);
|
||||
void do_page_fault(struct pt_regs *regs);
|
||||
void do_unhandled(struct pt_regs *regs);
|
||||
|
||||
/* Initialize minimal exc_table structure sufficient for basic paging */
|
||||
static inline void __init early_trap_init(void)
|
||||
{
|
||||
static struct exc_table exc_table __initdata = {
|
||||
static struct exc_table init_exc_table __initdata = {
|
||||
.fast_kernel_handler[EXCCAUSE_DTLB_MISS] =
|
||||
fast_second_level_miss,
|
||||
};
|
||||
__asm__ __volatile__("wsr %0, excsave1\n" : : "a" (&exc_table));
|
||||
xtensa_set_sr(&init_exc_table, excsave1);
|
||||
}
|
||||
|
||||
void secondary_trap_init(void);
|
||||
|
||||
@@ -19,6 +19,7 @@ obj-$(CONFIG_XTENSA_VARIANT_HAVE_PERF_EVENTS) += perf_event.o
|
||||
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
|
||||
obj-$(CONFIG_S32C1I_SELFTEST) += s32c1i_selftest.o
|
||||
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
|
||||
obj-$(CONFIG_HIBERNATION) += hibernate.o
|
||||
|
||||
# In the Xtensa architecture, assembly generates literals which must always
|
||||
# precede the L32R instruction with a relative offset less than 256 kB.
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/kbuild.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/traps.h>
|
||||
@@ -87,14 +88,19 @@ int main(void)
|
||||
OFFSET(TI_STSTUS, thread_info, status);
|
||||
OFFSET(TI_CPU, thread_info, cpu);
|
||||
OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
|
||||
#ifdef CONFIG_USER_ABI_CALL0_PROBE
|
||||
OFFSET(TI_PS_WOE_FIX_ADDR, thread_info, ps_woe_fix_addr);
|
||||
#endif
|
||||
|
||||
/* struct thread_info (offset from start_struct) */
|
||||
DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra));
|
||||
DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp));
|
||||
DEFINE(THREAD_CPENABLE, offsetof (struct thread_info, cpenable));
|
||||
#if XCHAL_HAVE_EXCLUSIVE
|
||||
DEFINE(THREAD_ATOMCTL8, offsetof (struct thread_info, atomctl8));
|
||||
#endif
|
||||
DEFINE(THREAD_CPENABLE, offsetof(struct thread_info, cpenable));
|
||||
DEFINE(THREAD_CPU, offsetof(struct thread_info, cpu));
|
||||
DEFINE(THREAD_CP_OWNER_CPU, offsetof(struct thread_info, cp_owner_cpu));
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
DEFINE(THREAD_XTREGS_CP0, offsetof(struct thread_info, xtregs_cp.cp0));
|
||||
DEFINE(THREAD_XTREGS_CP1, offsetof(struct thread_info, xtregs_cp.cp1));
|
||||
@@ -137,11 +143,22 @@ int main(void)
|
||||
DEFINE(EXC_TABLE_DOUBLE_SAVE, offsetof(struct exc_table, double_save));
|
||||
DEFINE(EXC_TABLE_FIXUP, offsetof(struct exc_table, fixup));
|
||||
DEFINE(EXC_TABLE_PARAM, offsetof(struct exc_table, fixup_param));
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
DEFINE(EXC_TABLE_COPROCESSOR_OWNER,
|
||||
offsetof(struct exc_table, coprocessor_owner));
|
||||
#endif
|
||||
DEFINE(EXC_TABLE_FAST_USER,
|
||||
offsetof(struct exc_table, fast_user_handler));
|
||||
DEFINE(EXC_TABLE_FAST_KERNEL,
|
||||
offsetof(struct exc_table, fast_kernel_handler));
|
||||
DEFINE(EXC_TABLE_DEFAULT, offsetof(struct exc_table, default_handler));
|
||||
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
DEFINE(PBE_ADDRESS, offsetof(struct pbe, address));
|
||||
DEFINE(PBE_ORIG_ADDRESS, offsetof(struct pbe, orig_address));
|
||||
DEFINE(PBE_NEXT, offsetof(struct pbe, next));
|
||||
DEFINE(PBE_SIZE, sizeof(struct pbe));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,26 @@
|
||||
#include <asm/current.h>
|
||||
#include <asm/regs.h>
|
||||
|
||||
/*
|
||||
* Rules for coprocessor state manipulation on SMP:
|
||||
*
|
||||
* - a task may have live coprocessors only on one CPU.
|
||||
*
|
||||
* - whether coprocessor context of task T is live on some CPU is
|
||||
* denoted by T's thread_info->cpenable.
|
||||
*
|
||||
* - non-zero thread_info->cpenable means that thread_info->cp_owner_cpu
|
||||
* is valid in the T's thread_info. Zero thread_info->cpenable means that
|
||||
* coprocessor context is valid in the T's thread_info.
|
||||
*
|
||||
* - if a coprocessor context of task T is live on CPU X, only CPU X changes
|
||||
* T's thread_info->cpenable, cp_owner_cpu and coprocessor save area.
|
||||
* This is done by making sure that for the task T with live coprocessor
|
||||
* on CPU X cpenable SR is 0 when T runs on any other CPU Y.
|
||||
* When fast_coprocessor exception is taken on CPU Y it goes to the
|
||||
* C-level do_coprocessor that uses IPI to make CPU X flush T's coprocessors.
|
||||
*/
|
||||
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
|
||||
/*
|
||||
@@ -30,34 +50,30 @@
|
||||
.align 4; \
|
||||
.Lsave_cp_regs_cp##x: \
|
||||
xchal_cp##x##_store a2 a3 a4 a5 a6; \
|
||||
jx a0; \
|
||||
ret; \
|
||||
.endif
|
||||
|
||||
#define SAVE_CP_REGS_TAB(x) \
|
||||
.if XTENSA_HAVE_COPROCESSOR(x); \
|
||||
.long .Lsave_cp_regs_cp##x; \
|
||||
.else; \
|
||||
.long 0; \
|
||||
.endif; \
|
||||
.long THREAD_XTREGS_CP##x
|
||||
|
||||
|
||||
#define LOAD_CP_REGS(x) \
|
||||
.if XTENSA_HAVE_COPROCESSOR(x); \
|
||||
.align 4; \
|
||||
.Lload_cp_regs_cp##x: \
|
||||
xchal_cp##x##_load a2 a3 a4 a5 a6; \
|
||||
jx a0; \
|
||||
ret; \
|
||||
.endif
|
||||
|
||||
#define LOAD_CP_REGS_TAB(x) \
|
||||
#define CP_REGS_TAB(x) \
|
||||
.if XTENSA_HAVE_COPROCESSOR(x); \
|
||||
.long .Lsave_cp_regs_cp##x; \
|
||||
.long .Lload_cp_regs_cp##x; \
|
||||
.else; \
|
||||
.long 0; \
|
||||
.long 0, 0; \
|
||||
.endif; \
|
||||
.long THREAD_XTREGS_CP##x
|
||||
|
||||
#define CP_REGS_TAB_SAVE 0
|
||||
#define CP_REGS_TAB_LOAD 4
|
||||
#define CP_REGS_TAB_OFFSET 8
|
||||
|
||||
__XTENSA_HANDLER
|
||||
|
||||
SAVE_CP_REGS(0)
|
||||
@@ -79,25 +95,15 @@
|
||||
LOAD_CP_REGS(7)
|
||||
|
||||
.align 4
|
||||
.Lsave_cp_regs_jump_table:
|
||||
SAVE_CP_REGS_TAB(0)
|
||||
SAVE_CP_REGS_TAB(1)
|
||||
SAVE_CP_REGS_TAB(2)
|
||||
SAVE_CP_REGS_TAB(3)
|
||||
SAVE_CP_REGS_TAB(4)
|
||||
SAVE_CP_REGS_TAB(5)
|
||||
SAVE_CP_REGS_TAB(6)
|
||||
SAVE_CP_REGS_TAB(7)
|
||||
|
||||
.Lload_cp_regs_jump_table:
|
||||
LOAD_CP_REGS_TAB(0)
|
||||
LOAD_CP_REGS_TAB(1)
|
||||
LOAD_CP_REGS_TAB(2)
|
||||
LOAD_CP_REGS_TAB(3)
|
||||
LOAD_CP_REGS_TAB(4)
|
||||
LOAD_CP_REGS_TAB(5)
|
||||
LOAD_CP_REGS_TAB(6)
|
||||
LOAD_CP_REGS_TAB(7)
|
||||
.Lcp_regs_jump_table:
|
||||
CP_REGS_TAB(0)
|
||||
CP_REGS_TAB(1)
|
||||
CP_REGS_TAB(2)
|
||||
CP_REGS_TAB(3)
|
||||
CP_REGS_TAB(4)
|
||||
CP_REGS_TAB(5)
|
||||
CP_REGS_TAB(6)
|
||||
CP_REGS_TAB(7)
|
||||
|
||||
/*
|
||||
* Entry condition:
|
||||
@@ -115,9 +121,37 @@
|
||||
|
||||
ENTRY(fast_coprocessor)
|
||||
|
||||
s32i a3, a2, PT_AREG3
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* Check if any coprocessor context is live on another CPU
|
||||
* and if so go through the C-level coprocessor exception handler
|
||||
* to flush it to memory.
|
||||
*/
|
||||
GET_THREAD_INFO (a0, a2)
|
||||
l32i a3, a0, THREAD_CPENABLE
|
||||
beqz a3, .Lload_local
|
||||
|
||||
/*
|
||||
* Pairs with smp_wmb in local_coprocessor_release_all
|
||||
* and with both memws below.
|
||||
*/
|
||||
memw
|
||||
l32i a3, a0, THREAD_CPU
|
||||
l32i a0, a0, THREAD_CP_OWNER_CPU
|
||||
beq a0, a3, .Lload_local
|
||||
|
||||
rsr a0, ps
|
||||
l32i a3, a2, PT_AREG3
|
||||
bbci.l a0, PS_UM_BIT, 1f
|
||||
call0 user_exception
|
||||
1: call0 kernel_exception
|
||||
#endif
|
||||
|
||||
/* Save remaining registers a1-a3 and SAR */
|
||||
|
||||
s32i a3, a2, PT_AREG3
|
||||
.Lload_local:
|
||||
rsr a3, sar
|
||||
s32i a1, a2, PT_AREG1
|
||||
s32i a3, a2, PT_SAR
|
||||
@@ -125,13 +159,15 @@ ENTRY(fast_coprocessor)
|
||||
rsr a2, depc
|
||||
s32i a2, a1, PT_AREG2
|
||||
|
||||
/*
|
||||
* The hal macros require up to 4 temporary registers. We use a3..a6.
|
||||
*/
|
||||
/* The hal macros require up to 4 temporary registers. We use a3..a6. */
|
||||
|
||||
s32i a4, a1, PT_AREG4
|
||||
s32i a5, a1, PT_AREG5
|
||||
s32i a6, a1, PT_AREG6
|
||||
s32i a7, a1, PT_AREG7
|
||||
s32i a8, a1, PT_AREG8
|
||||
s32i a9, a1, PT_AREG9
|
||||
s32i a10, a1, PT_AREG10
|
||||
|
||||
/* Find coprocessor number. Subtract first CP EXCCAUSE from EXCCAUSE */
|
||||
|
||||
@@ -148,58 +184,74 @@ ENTRY(fast_coprocessor)
|
||||
wsr a0, cpenable
|
||||
rsync
|
||||
|
||||
/* Retrieve previous owner. (a3 still holds CP number) */
|
||||
/* Get coprocessor save/load table entry (a7). */
|
||||
|
||||
movi a0, coprocessor_owner # list of owners
|
||||
movi a7, .Lcp_regs_jump_table
|
||||
addx8 a7, a3, a7
|
||||
addx4 a7, a3, a7
|
||||
|
||||
/* Retrieve previous owner (a8). */
|
||||
|
||||
rsr a0, excsave1 # exc_table
|
||||
addx4 a0, a3, a0 # entry for CP
|
||||
l32i a4, a0, 0
|
||||
l32i a8, a0, EXC_TABLE_COPROCESSOR_OWNER
|
||||
|
||||
beqz a4, 1f # skip 'save' if no previous owner
|
||||
/* Set new owner (a9). */
|
||||
|
||||
GET_THREAD_INFO (a9, a1)
|
||||
l32i a4, a9, THREAD_CPU
|
||||
s32i a9, a0, EXC_TABLE_COPROCESSOR_OWNER
|
||||
s32i a4, a9, THREAD_CP_OWNER_CPU
|
||||
|
||||
/*
|
||||
* Enable coprocessor for the new owner. (a2 = 1 << CP number)
|
||||
* This can be done before loading context into the coprocessor.
|
||||
*/
|
||||
l32i a4, a9, THREAD_CPENABLE
|
||||
or a4, a4, a2
|
||||
|
||||
/*
|
||||
* Make sure THREAD_CP_OWNER_CPU is in memory before updating
|
||||
* THREAD_CPENABLE
|
||||
*/
|
||||
memw # (2)
|
||||
s32i a4, a9, THREAD_CPENABLE
|
||||
|
||||
beqz a8, 1f # skip 'save' if no previous owner
|
||||
|
||||
/* Disable coprocessor for previous owner. (a2 = 1 << CP number) */
|
||||
|
||||
l32i a5, a4, THREAD_CPENABLE
|
||||
xor a5, a5, a2 # (1 << cp-id) still in a2
|
||||
s32i a5, a4, THREAD_CPENABLE
|
||||
l32i a10, a8, THREAD_CPENABLE
|
||||
xor a10, a10, a2
|
||||
|
||||
/* Get context save area and call save routine. */
|
||||
|
||||
l32i a2, a7, CP_REGS_TAB_OFFSET
|
||||
l32i a3, a7, CP_REGS_TAB_SAVE
|
||||
add a2, a2, a8
|
||||
callx0 a3
|
||||
|
||||
/*
|
||||
* Get context save area and 'call' save routine.
|
||||
* (a4 still holds previous owner (thread_info), a3 CP number)
|
||||
* Make sure coprocessor context and THREAD_CP_OWNER_CPU are in memory
|
||||
* before updating THREAD_CPENABLE
|
||||
*/
|
||||
memw # (3)
|
||||
s32i a10, a8, THREAD_CPENABLE
|
||||
1:
|
||||
/* Get context save area and call load routine. */
|
||||
|
||||
movi a5, .Lsave_cp_regs_jump_table
|
||||
movi a0, 2f # a0: 'return' address
|
||||
addx8 a3, a3, a5 # a3: coprocessor number
|
||||
l32i a2, a3, 4 # a2: xtregs offset
|
||||
l32i a3, a3, 0 # a3: jump address
|
||||
add a2, a2, a4
|
||||
jx a3
|
||||
|
||||
/* Note that only a0 and a1 were preserved. */
|
||||
|
||||
2: rsr a3, exccause
|
||||
addi a3, a3, -EXCCAUSE_COPROCESSOR0_DISABLED
|
||||
movi a0, coprocessor_owner
|
||||
addx4 a0, a3, a0
|
||||
|
||||
/* Set new 'owner' (a0 points to the CP owner, a3 contains the CP nr) */
|
||||
|
||||
1: GET_THREAD_INFO (a4, a1)
|
||||
s32i a4, a0, 0
|
||||
|
||||
/* Get context save area and 'call' load routine. */
|
||||
|
||||
movi a5, .Lload_cp_regs_jump_table
|
||||
movi a0, 1f
|
||||
addx8 a3, a3, a5
|
||||
l32i a2, a3, 4 # a2: xtregs offset
|
||||
l32i a3, a3, 0 # a3: jump address
|
||||
add a2, a2, a4
|
||||
jx a3
|
||||
l32i a2, a7, CP_REGS_TAB_OFFSET
|
||||
l32i a3, a7, CP_REGS_TAB_LOAD
|
||||
add a2, a2, a9
|
||||
callx0 a3
|
||||
|
||||
/* Restore all registers and return from exception handler. */
|
||||
|
||||
1: l32i a6, a1, PT_AREG6
|
||||
l32i a10, a1, PT_AREG10
|
||||
l32i a9, a1, PT_AREG9
|
||||
l32i a8, a1, PT_AREG8
|
||||
l32i a7, a1, PT_AREG7
|
||||
l32i a6, a1, PT_AREG6
|
||||
l32i a5, a1, PT_AREG5
|
||||
l32i a4, a1, PT_AREG4
|
||||
|
||||
@@ -230,29 +282,21 @@ ENDPROC(fast_coprocessor)
|
||||
|
||||
ENTRY(coprocessor_flush)
|
||||
|
||||
/* reserve 4 bytes on stack to save a0 */
|
||||
abi_entry(4)
|
||||
abi_entry_default
|
||||
|
||||
s32i a0, a1, 0
|
||||
movi a0, .Lsave_cp_regs_jump_table
|
||||
addx8 a3, a3, a0
|
||||
l32i a4, a3, 4
|
||||
l32i a3, a3, 0
|
||||
add a2, a2, a4
|
||||
beqz a3, 1f
|
||||
callx0 a3
|
||||
1: l32i a0, a1, 0
|
||||
|
||||
abi_ret(4)
|
||||
movi a4, .Lcp_regs_jump_table
|
||||
addx8 a4, a3, a4
|
||||
addx4 a3, a3, a4
|
||||
l32i a4, a3, CP_REGS_TAB_SAVE
|
||||
beqz a4, 1f
|
||||
l32i a3, a3, CP_REGS_TAB_OFFSET
|
||||
add a2, a2, a3
|
||||
mov a7, a0
|
||||
callx0 a4
|
||||
mov a0, a7
|
||||
1:
|
||||
abi_ret_default
|
||||
|
||||
ENDPROC(coprocessor_flush)
|
||||
|
||||
.data
|
||||
|
||||
ENTRY(coprocessor_owner)
|
||||
|
||||
.fill XCHAL_CP_MAX, 4, 0
|
||||
|
||||
END(coprocessor_owner)
|
||||
|
||||
#endif /* XTENSA_HAVE_COPROCESSORS */
|
||||
|
||||
+225
-110
@@ -28,15 +28,6 @@
|
||||
#include <asm/tlbflush.h>
|
||||
#include <variant/tie-asm.h>
|
||||
|
||||
/* Unimplemented features. */
|
||||
|
||||
#undef KERNEL_STACK_OVERFLOW_CHECK
|
||||
|
||||
/* Not well tested.
|
||||
*
|
||||
* - fast_coprocessor
|
||||
*/
|
||||
|
||||
/*
|
||||
* Macro to find first bit set in WINDOWBASE from the left + 1
|
||||
*
|
||||
@@ -178,28 +169,26 @@ _user_exception:
|
||||
|
||||
/* Save only live registers. */
|
||||
|
||||
UABI_W _bbsi.l a2, 1, 1f
|
||||
UABI_W _bbsi.l a2, 1, .Lsave_window_registers
|
||||
s32i a4, a1, PT_AREG4
|
||||
s32i a5, a1, PT_AREG5
|
||||
s32i a6, a1, PT_AREG6
|
||||
s32i a7, a1, PT_AREG7
|
||||
UABI_W _bbsi.l a2, 2, 1f
|
||||
UABI_W _bbsi.l a2, 2, .Lsave_window_registers
|
||||
s32i a8, a1, PT_AREG8
|
||||
s32i a9, a1, PT_AREG9
|
||||
s32i a10, a1, PT_AREG10
|
||||
s32i a11, a1, PT_AREG11
|
||||
UABI_W _bbsi.l a2, 3, 1f
|
||||
UABI_W _bbsi.l a2, 3, .Lsave_window_registers
|
||||
s32i a12, a1, PT_AREG12
|
||||
s32i a13, a1, PT_AREG13
|
||||
s32i a14, a1, PT_AREG14
|
||||
s32i a15, a1, PT_AREG15
|
||||
|
||||
#if defined(USER_SUPPORT_WINDOWED)
|
||||
_bnei a2, 1, 1f # only one valid frame?
|
||||
/* If only one valid frame skip saving regs. */
|
||||
|
||||
/* Only one valid frame, skip saving regs. */
|
||||
|
||||
j 2f
|
||||
beqi a2, 1, common_exception
|
||||
|
||||
/* Save the remaining registers.
|
||||
* We have to save all registers up to the first '1' from
|
||||
@@ -208,8 +197,8 @@ UABI_W _bbsi.l a2, 3, 1f
|
||||
* All register frames starting from the top field to the marked '1'
|
||||
* must be saved.
|
||||
*/
|
||||
|
||||
1: addi a3, a2, -1 # eliminate '1' in bit 0: yyyyxxww0
|
||||
.Lsave_window_registers:
|
||||
addi a3, a2, -1 # eliminate '1' in bit 0: yyyyxxww0
|
||||
neg a3, a3 # yyyyxxww0 -> YYYYXXWW1+1
|
||||
and a3, a3, a2 # max. only one bit is set
|
||||
|
||||
@@ -250,7 +239,7 @@ UABI_W _bbsi.l a2, 3, 1f
|
||||
|
||||
/* We are back to the original stack pointer (a1) */
|
||||
#endif
|
||||
2: /* Now, jump to the common exception handler. */
|
||||
/* Now, jump to the common exception handler. */
|
||||
|
||||
j common_exception
|
||||
|
||||
@@ -350,15 +339,6 @@ KABI_W _bbsi.l a2, 3, 1f
|
||||
l32i a0, a1, PT_AREG0 # restore saved a0
|
||||
wsr a0, depc
|
||||
|
||||
#ifdef KERNEL_STACK_OVERFLOW_CHECK
|
||||
|
||||
/* Stack overflow check, for debugging */
|
||||
extui a2, a1, TASK_SIZE_BITS,XX
|
||||
movi a3, SIZE??
|
||||
_bge a2, a3, out_of_stack_panic
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the common exception handler.
|
||||
* We get here from the user exception handler or simply by falling through
|
||||
@@ -442,7 +422,6 @@ KABI_W or a3, a3, a0
|
||||
moveqz a3, a0, a2 # a3 = LOCKLEVEL iff interrupt
|
||||
KABI_W movi a2, PS_WOE_MASK
|
||||
KABI_W or a3, a3, a2
|
||||
rsr a2, exccause
|
||||
#endif
|
||||
|
||||
/* restore return address (or 0 if return to userspace) */
|
||||
@@ -469,42 +448,56 @@ KABI_W or a3, a3, a2
|
||||
|
||||
save_xtregs_opt a1 a3 a4 a5 a6 a7 PT_XTREGS_OPT
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
rsr abi_tmp0, ps
|
||||
extui abi_tmp0, abi_tmp0, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH
|
||||
beqz abi_tmp0, 1f
|
||||
abi_call trace_hardirqs_off
|
||||
1:
|
||||
#endif
|
||||
#ifdef CONFIG_CONTEXT_TRACKING
|
||||
l32i abi_tmp0, a1, PT_PS
|
||||
bbci.l abi_tmp0, PS_UM_BIT, 1f
|
||||
abi_call context_tracking_user_exit
|
||||
1:
|
||||
#endif
|
||||
|
||||
/* Go to second-level dispatcher. Set up parameters to pass to the
|
||||
* exception handler and call the exception handler.
|
||||
*/
|
||||
|
||||
rsr a4, excsave1
|
||||
addx4 a4, a2, a4
|
||||
l32i a4, a4, EXC_TABLE_DEFAULT # load handler
|
||||
mov abi_arg1, a2 # pass EXCCAUSE
|
||||
mov abi_arg0, a1 # pass stack frame
|
||||
l32i abi_arg1, a1, PT_EXCCAUSE # pass EXCCAUSE
|
||||
rsr abi_tmp0, excsave1
|
||||
addx4 abi_tmp0, abi_arg1, abi_tmp0
|
||||
l32i abi_tmp0, abi_tmp0, EXC_TABLE_DEFAULT # load handler
|
||||
mov abi_arg0, a1 # pass stack frame
|
||||
|
||||
/* Call the second-level handler */
|
||||
|
||||
abi_callx a4
|
||||
abi_callx abi_tmp0
|
||||
|
||||
/* Jump here for exception exit */
|
||||
.global common_exception_return
|
||||
common_exception_return:
|
||||
|
||||
#if XTENSA_FAKE_NMI
|
||||
l32i abi_tmp0, a1, PT_EXCCAUSE
|
||||
movi abi_tmp1, EXCCAUSE_MAPPED_NMI
|
||||
l32i abi_saved1, a1, PT_PS
|
||||
beq abi_tmp0, abi_tmp1, .Lrestore_state
|
||||
l32i abi_tmp0, a1, PT_EXCCAUSE
|
||||
movi abi_tmp1, EXCCAUSE_MAPPED_NMI
|
||||
l32i abi_saved1, a1, PT_PS
|
||||
beq abi_tmp0, abi_tmp1, .Lrestore_state
|
||||
#endif
|
||||
.Ltif_loop:
|
||||
irq_save a2, a3
|
||||
irq_save abi_tmp0, abi_tmp1
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
abi_call trace_hardirqs_off
|
||||
#endif
|
||||
|
||||
/* Jump if we are returning from kernel exceptions. */
|
||||
|
||||
l32i abi_saved1, a1, PT_PS
|
||||
GET_THREAD_INFO(a2, a1)
|
||||
l32i a4, a2, TI_FLAGS
|
||||
_bbci.l abi_saved1, PS_UM_BIT, .Lexit_tif_loop_kernel
|
||||
l32i abi_saved1, a1, PT_PS
|
||||
GET_THREAD_INFO(abi_tmp0, a1)
|
||||
l32i abi_saved0, abi_tmp0, TI_FLAGS
|
||||
_bbci.l abi_saved1, PS_UM_BIT, .Lexit_tif_loop_kernel
|
||||
|
||||
/* Specific to a user exception exit:
|
||||
* We need to check some flags for signal handling and rescheduling,
|
||||
@@ -513,75 +506,80 @@ common_exception_return:
|
||||
* Note that we don't disable interrupts here.
|
||||
*/
|
||||
|
||||
_bbsi.l a4, TIF_NEED_RESCHED, .Lresched
|
||||
movi a2, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NOTIFY_SIGNAL
|
||||
bnone a4, a2, .Lexit_tif_loop_user
|
||||
_bbsi.l abi_saved0, TIF_NEED_RESCHED, .Lresched
|
||||
movi abi_tmp0, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NOTIFY_SIGNAL
|
||||
bnone abi_saved0, abi_tmp0, .Lexit_tif_loop_user
|
||||
|
||||
l32i a4, a1, PT_DEPC
|
||||
bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, .Lrestore_state
|
||||
l32i abi_tmp0, a1, PT_DEPC
|
||||
bgeui abi_tmp0, VALID_DOUBLE_EXCEPTION_ADDRESS, .Lrestore_state
|
||||
|
||||
/* Call do_signal() */
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
abi_call trace_hardirqs_on
|
||||
#endif
|
||||
rsil a2, 0
|
||||
mov abi_arg0, a1
|
||||
rsil abi_tmp0, 0
|
||||
mov abi_arg0, a1
|
||||
abi_call do_notify_resume # int do_notify_resume(struct pt_regs*)
|
||||
j .Ltif_loop
|
||||
j .Ltif_loop
|
||||
|
||||
.Lresched:
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
abi_call trace_hardirqs_on
|
||||
#endif
|
||||
rsil a2, 0
|
||||
rsil abi_tmp0, 0
|
||||
abi_call schedule # void schedule (void)
|
||||
j .Ltif_loop
|
||||
j .Ltif_loop
|
||||
|
||||
.Lexit_tif_loop_kernel:
|
||||
#ifdef CONFIG_PREEMPTION
|
||||
_bbci.l a4, TIF_NEED_RESCHED, .Lrestore_state
|
||||
_bbci.l abi_saved0, TIF_NEED_RESCHED, .Lrestore_state
|
||||
|
||||
/* Check current_thread_info->preempt_count */
|
||||
|
||||
l32i a4, a2, TI_PRE_COUNT
|
||||
bnez a4, .Lrestore_state
|
||||
l32i abi_tmp1, abi_tmp0, TI_PRE_COUNT
|
||||
bnez abi_tmp1, .Lrestore_state
|
||||
abi_call preempt_schedule_irq
|
||||
#endif
|
||||
j .Lrestore_state
|
||||
j .Lrestore_state
|
||||
|
||||
.Lexit_tif_loop_user:
|
||||
#ifdef CONFIG_CONTEXT_TRACKING
|
||||
abi_call context_tracking_user_enter
|
||||
#endif
|
||||
#ifdef CONFIG_HAVE_HW_BREAKPOINT
|
||||
_bbci.l a4, TIF_DB_DISABLED, 1f
|
||||
_bbci.l abi_saved0, TIF_DB_DISABLED, 1f
|
||||
abi_call restore_dbreak
|
||||
1:
|
||||
#endif
|
||||
#ifdef CONFIG_DEBUG_TLB_SANITY
|
||||
l32i a4, a1, PT_DEPC
|
||||
bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, .Lrestore_state
|
||||
l32i abi_tmp0, a1, PT_DEPC
|
||||
bgeui abi_tmp0, VALID_DOUBLE_EXCEPTION_ADDRESS, .Lrestore_state
|
||||
abi_call check_tlb_sanity
|
||||
#endif
|
||||
|
||||
.Lrestore_state:
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
extui a4, abi_saved1, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH
|
||||
bgei a4, LOCKLEVEL, 1f
|
||||
extui abi_tmp0, abi_saved1, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH
|
||||
bgei abi_tmp0, LOCKLEVEL, 1f
|
||||
abi_call trace_hardirqs_on
|
||||
1:
|
||||
#endif
|
||||
/* Restore optional registers. */
|
||||
/*
|
||||
* Restore optional registers.
|
||||
* abi_arg* are used as temporary registers here.
|
||||
*/
|
||||
|
||||
load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
|
||||
load_xtregs_opt a1 abi_tmp0 abi_arg0 abi_arg1 abi_arg2 abi_arg3 PT_XTREGS_OPT
|
||||
|
||||
/* Restore SCOMPARE1 */
|
||||
|
||||
#if XCHAL_HAVE_S32C1I
|
||||
l32i a2, a1, PT_SCOMPARE1
|
||||
wsr a2, scompare1
|
||||
l32i abi_tmp0, a1, PT_SCOMPARE1
|
||||
wsr abi_tmp0, scompare1
|
||||
#endif
|
||||
wsr abi_saved1, ps /* disable interrupts */
|
||||
|
||||
_bbci.l abi_saved1, PS_UM_BIT, kernel_exception_exit
|
||||
wsr abi_saved1, ps /* disable interrupts */
|
||||
_bbci.l abi_saved1, PS_UM_BIT, kernel_exception_exit
|
||||
|
||||
user_exception_exit:
|
||||
|
||||
@@ -795,7 +793,7 @@ ENDPROC(kernel_exception)
|
||||
ENTRY(debug_exception)
|
||||
|
||||
rsr a0, SREG_EPS + XCHAL_DEBUGLEVEL
|
||||
bbsi.l a0, PS_EXCM_BIT, 1f # exception mode
|
||||
bbsi.l a0, PS_EXCM_BIT, .Ldebug_exception_in_exception # exception mode
|
||||
|
||||
/* Set EPC1 and EXCCAUSE */
|
||||
|
||||
@@ -814,10 +812,10 @@ ENTRY(debug_exception)
|
||||
|
||||
/* Switch to kernel/user stack, restore jump vector, and save a0 */
|
||||
|
||||
bbsi.l a2, PS_UM_BIT, 2f # jump if user mode
|
||||
|
||||
bbsi.l a2, PS_UM_BIT, .Ldebug_exception_user # jump if user mode
|
||||
addi a2, a1, -16 - PT_KERNEL_SIZE # assume kernel stack
|
||||
3:
|
||||
|
||||
.Ldebug_exception_continue:
|
||||
l32i a0, a3, DT_DEBUG_SAVE
|
||||
s32i a1, a2, PT_AREG1
|
||||
s32i a0, a2, PT_AREG0
|
||||
@@ -845,10 +843,12 @@ ENTRY(debug_exception)
|
||||
bbsi.l a2, PS_UM_BIT, _user_exception
|
||||
j _kernel_exception
|
||||
|
||||
2: rsr a2, excsave1
|
||||
.Ldebug_exception_user:
|
||||
rsr a2, excsave1
|
||||
l32i a2, a2, EXC_TABLE_KSTK # load kernel stack pointer
|
||||
j 3b
|
||||
j .Ldebug_exception_continue
|
||||
|
||||
.Ldebug_exception_in_exception:
|
||||
#ifdef CONFIG_HAVE_HW_BREAKPOINT
|
||||
/* Debug exception while in exception mode. This may happen when
|
||||
* window overflow/underflow handler or fast exception handler hits
|
||||
@@ -856,8 +856,8 @@ ENTRY(debug_exception)
|
||||
* breakpoints, single-step faulting instruction and restore data
|
||||
* breakpoints.
|
||||
*/
|
||||
1:
|
||||
bbci.l a0, PS_UM_BIT, 1b # jump if kernel mode
|
||||
|
||||
bbci.l a0, PS_UM_BIT, .Ldebug_exception_in_exception # jump if kernel mode
|
||||
|
||||
rsr a0, debugcause
|
||||
bbsi.l a0, DEBUGCAUSE_DBREAK_BIT, .Ldebug_save_dbreak
|
||||
@@ -901,7 +901,7 @@ ENTRY(debug_exception)
|
||||
rfi XCHAL_DEBUGLEVEL
|
||||
#else
|
||||
/* Debug exception while in exception mode. Should not happen. */
|
||||
1: j 1b // FIXME!!
|
||||
j .Ldebug_exception_in_exception // FIXME!!
|
||||
#endif
|
||||
|
||||
ENDPROC(debug_exception)
|
||||
@@ -1056,6 +1056,11 @@ ENTRY(fast_illegal_instruction_user)
|
||||
movi a3, PS_WOE_MASK
|
||||
or a0, a0, a3
|
||||
wsr a0, ps
|
||||
#ifdef CONFIG_USER_ABI_CALL0_PROBE
|
||||
GET_THREAD_INFO(a3, a2)
|
||||
rsr a0, epc1
|
||||
s32i a0, a3, TI_PS_WOE_FIX_ADDR
|
||||
#endif
|
||||
l32i a3, a2, PT_AREG3
|
||||
l32i a0, a2, PT_AREG0
|
||||
rsr a2, depc
|
||||
@@ -1630,12 +1635,13 @@ ENTRY(fast_second_level_miss)
|
||||
|
||||
GET_CURRENT(a1,a2)
|
||||
l32i a0, a1, TASK_MM # tsk->mm
|
||||
beqz a0, 9f
|
||||
beqz a0, .Lfast_second_level_miss_no_mm
|
||||
|
||||
8: rsr a3, excvaddr # fault address
|
||||
.Lfast_second_level_miss_continue:
|
||||
rsr a3, excvaddr # fault address
|
||||
_PGD_OFFSET(a0, a3, a1)
|
||||
l32i a0, a0, 0 # read pmdval
|
||||
beqz a0, 2f
|
||||
beqz a0, .Lfast_second_level_miss_no_pmd
|
||||
|
||||
/* Read ptevaddr and convert to top of page-table page.
|
||||
*
|
||||
@@ -1678,12 +1684,13 @@ ENTRY(fast_second_level_miss)
|
||||
addi a3, a3, DTLB_WAY_PGD
|
||||
add a1, a1, a3 # ... + way_number
|
||||
|
||||
3: wdtlb a0, a1
|
||||
.Lfast_second_level_miss_wdtlb:
|
||||
wdtlb a0, a1
|
||||
dsync
|
||||
|
||||
/* Exit critical section. */
|
||||
|
||||
4: rsr a3, excsave1
|
||||
.Lfast_second_level_miss_skip_wdtlb:
|
||||
rsr a3, excsave1
|
||||
movi a0, 0
|
||||
s32i a0, a3, EXC_TABLE_FIXUP
|
||||
|
||||
@@ -1707,19 +1714,21 @@ ENTRY(fast_second_level_miss)
|
||||
esync
|
||||
rfde
|
||||
|
||||
9: l32i a0, a1, TASK_ACTIVE_MM # unlikely case mm == 0
|
||||
bnez a0, 8b
|
||||
.Lfast_second_level_miss_no_mm:
|
||||
l32i a0, a1, TASK_ACTIVE_MM # unlikely case mm == 0
|
||||
bnez a0, .Lfast_second_level_miss_continue
|
||||
|
||||
/* Even more unlikely case active_mm == 0.
|
||||
* We can get here with NMI in the middle of context_switch that
|
||||
* touches vmalloc area.
|
||||
*/
|
||||
movi a0, init_mm
|
||||
j 8b
|
||||
j .Lfast_second_level_miss_continue
|
||||
|
||||
.Lfast_second_level_miss_no_pmd:
|
||||
#if (DCACHE_WAY_SIZE > PAGE_SIZE)
|
||||
|
||||
2: /* Special case for cache aliasing.
|
||||
/* Special case for cache aliasing.
|
||||
* We (should) only get here if a clear_user_page, copy_user_page
|
||||
* or the aliased cache flush functions got preemptively interrupted
|
||||
* by another task. Re-establish temporary mapping to the
|
||||
@@ -1729,24 +1738,24 @@ ENTRY(fast_second_level_miss)
|
||||
/* We shouldn't be in a double exception */
|
||||
|
||||
l32i a0, a2, PT_DEPC
|
||||
bgeui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, 2f
|
||||
bgeui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, .Lfast_second_level_miss_slow
|
||||
|
||||
/* Make sure the exception originated in the special functions */
|
||||
|
||||
movi a0, __tlbtemp_mapping_start
|
||||
rsr a3, epc1
|
||||
bltu a3, a0, 2f
|
||||
bltu a3, a0, .Lfast_second_level_miss_slow
|
||||
movi a0, __tlbtemp_mapping_end
|
||||
bgeu a3, a0, 2f
|
||||
bgeu a3, a0, .Lfast_second_level_miss_slow
|
||||
|
||||
/* Check if excvaddr was in one of the TLBTEMP_BASE areas. */
|
||||
|
||||
movi a3, TLBTEMP_BASE_1
|
||||
rsr a0, excvaddr
|
||||
bltu a0, a3, 2f
|
||||
bltu a0, a3, .Lfast_second_level_miss_slow
|
||||
|
||||
addi a1, a0, -TLBTEMP_SIZE
|
||||
bgeu a1, a3, 2f
|
||||
bgeu a1, a3, .Lfast_second_level_miss_slow
|
||||
|
||||
/* Check if we have to restore an ITLB mapping. */
|
||||
|
||||
@@ -1772,19 +1781,19 @@ ENTRY(fast_second_level_miss)
|
||||
|
||||
mov a0, a6
|
||||
movnez a0, a7, a3
|
||||
j 3b
|
||||
j .Lfast_second_level_miss_wdtlb
|
||||
|
||||
/* ITLB entry. We only use dst in a6. */
|
||||
|
||||
1: witlb a6, a1
|
||||
isync
|
||||
j 4b
|
||||
j .Lfast_second_level_miss_skip_wdtlb
|
||||
|
||||
|
||||
#endif // DCACHE_WAY_SIZE > PAGE_SIZE
|
||||
|
||||
|
||||
2: /* Invalid PGD, default exception handling */
|
||||
/* Invalid PGD, default exception handling */
|
||||
.Lfast_second_level_miss_slow:
|
||||
|
||||
rsr a1, depc
|
||||
s32i a1, a2, PT_AREG2
|
||||
@@ -1824,12 +1833,13 @@ ENTRY(fast_store_prohibited)
|
||||
|
||||
GET_CURRENT(a1,a2)
|
||||
l32i a0, a1, TASK_MM # tsk->mm
|
||||
beqz a0, 9f
|
||||
beqz a0, .Lfast_store_no_mm
|
||||
|
||||
8: rsr a1, excvaddr # fault address
|
||||
.Lfast_store_continue:
|
||||
rsr a1, excvaddr # fault address
|
||||
_PGD_OFFSET(a0, a1, a3)
|
||||
l32i a0, a0, 0
|
||||
beqz a0, 2f
|
||||
beqz a0, .Lfast_store_slow
|
||||
|
||||
/*
|
||||
* Note that we test _PAGE_WRITABLE_BIT only if PTE is present
|
||||
@@ -1839,8 +1849,8 @@ ENTRY(fast_store_prohibited)
|
||||
_PTE_OFFSET(a0, a1, a3)
|
||||
l32i a3, a0, 0 # read pteval
|
||||
movi a1, _PAGE_CA_INVALID
|
||||
ball a3, a1, 2f
|
||||
bbci.l a3, _PAGE_WRITABLE_BIT, 2f
|
||||
ball a3, a1, .Lfast_store_slow
|
||||
bbci.l a3, _PAGE_WRITABLE_BIT, .Lfast_store_slow
|
||||
|
||||
movi a1, _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_HW_WRITE
|
||||
or a3, a3, a1
|
||||
@@ -1868,7 +1878,6 @@ ENTRY(fast_store_prohibited)
|
||||
l32i a2, a2, PT_DEPC
|
||||
|
||||
bgeui a2, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
|
||||
|
||||
rsr a2, depc
|
||||
rfe
|
||||
|
||||
@@ -1878,11 +1887,17 @@ ENTRY(fast_store_prohibited)
|
||||
esync
|
||||
rfde
|
||||
|
||||
9: l32i a0, a1, TASK_ACTIVE_MM # unlikely case mm == 0
|
||||
j 8b
|
||||
|
||||
2: /* If there was a problem, handle fault in C */
|
||||
.Lfast_store_no_mm:
|
||||
l32i a0, a1, TASK_ACTIVE_MM # unlikely case mm == 0
|
||||
j .Lfast_store_continue
|
||||
|
||||
/* If there was a problem, handle fault in C */
|
||||
.Lfast_store_slow:
|
||||
rsr a1, excvaddr
|
||||
pdtlb a0, a1
|
||||
bbci.l a0, DTLB_HIT_BIT, 1f
|
||||
idtlb a0
|
||||
1:
|
||||
rsr a3, depc # still holds a2
|
||||
s32i a3, a2, PT_AREG2
|
||||
mov a1, a2
|
||||
@@ -2071,8 +2086,16 @@ ENTRY(_switch_to)
|
||||
|
||||
#if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS)
|
||||
l32i a3, a5, THREAD_CPENABLE
|
||||
xsr a3, cpenable
|
||||
s32i a3, a4, THREAD_CPENABLE
|
||||
#ifdef CONFIG_SMP
|
||||
beqz a3, 1f
|
||||
memw # pairs with memw (2) in fast_coprocessor
|
||||
l32i a6, a5, THREAD_CP_OWNER_CPU
|
||||
l32i a7, a5, THREAD_CPU
|
||||
beq a6, a7, 1f # load 0 into CPENABLE if current CPU is not the owner
|
||||
movi a3, 0
|
||||
1:
|
||||
#endif
|
||||
wsr a3, cpenable
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_EXCLUSIVE
|
||||
@@ -2147,3 +2170,95 @@ ENTRY(ret_from_kernel_thread)
|
||||
j common_exception_return
|
||||
|
||||
ENDPROC(ret_from_kernel_thread)
|
||||
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
|
||||
.bss
|
||||
.align 4
|
||||
.Lsaved_regs:
|
||||
#if defined(__XTENSA_WINDOWED_ABI__)
|
||||
.fill 2, 4
|
||||
#elif defined(__XTENSA_CALL0_ABI__)
|
||||
.fill 6, 4
|
||||
#else
|
||||
#error Unsupported Xtensa ABI
|
||||
#endif
|
||||
.align XCHAL_NCP_SA_ALIGN
|
||||
.Lsaved_user_regs:
|
||||
.fill XTREGS_USER_SIZE, 1
|
||||
|
||||
.previous
|
||||
|
||||
ENTRY(swsusp_arch_suspend)
|
||||
|
||||
abi_entry_default
|
||||
|
||||
movi a2, .Lsaved_regs
|
||||
movi a3, .Lsaved_user_regs
|
||||
s32i a0, a2, 0
|
||||
s32i a1, a2, 4
|
||||
save_xtregs_user a3 a4 a5 a6 a7 a8 0
|
||||
#if defined(__XTENSA_WINDOWED_ABI__)
|
||||
spill_registers_kernel
|
||||
#elif defined(__XTENSA_CALL0_ABI__)
|
||||
s32i a12, a2, 8
|
||||
s32i a13, a2, 12
|
||||
s32i a14, a2, 16
|
||||
s32i a15, a2, 20
|
||||
#else
|
||||
#error Unsupported Xtensa ABI
|
||||
#endif
|
||||
abi_call swsusp_save
|
||||
mov a2, abi_rv
|
||||
abi_ret_default
|
||||
|
||||
ENDPROC(swsusp_arch_suspend)
|
||||
|
||||
ENTRY(swsusp_arch_resume)
|
||||
|
||||
abi_entry_default
|
||||
|
||||
#if defined(__XTENSA_WINDOWED_ABI__)
|
||||
spill_registers_kernel
|
||||
#endif
|
||||
|
||||
movi a2, restore_pblist
|
||||
l32i a2, a2, 0
|
||||
|
||||
.Lcopy_pbe:
|
||||
l32i a3, a2, PBE_ADDRESS
|
||||
l32i a4, a2, PBE_ORIG_ADDRESS
|
||||
|
||||
__loopi a3, a9, PAGE_SIZE, 16
|
||||
l32i a5, a3, 0
|
||||
l32i a6, a3, 4
|
||||
l32i a7, a3, 8
|
||||
l32i a8, a3, 12
|
||||
addi a3, a3, 16
|
||||
s32i a5, a4, 0
|
||||
s32i a6, a4, 4
|
||||
s32i a7, a4, 8
|
||||
s32i a8, a4, 12
|
||||
addi a4, a4, 16
|
||||
__endl a3, a9
|
||||
|
||||
l32i a2, a2, PBE_NEXT
|
||||
bnez a2, .Lcopy_pbe
|
||||
|
||||
movi a2, .Lsaved_regs
|
||||
movi a3, .Lsaved_user_regs
|
||||
l32i a0, a2, 0
|
||||
l32i a1, a2, 4
|
||||
load_xtregs_user a3 a4 a5 a6 a7 a8 0
|
||||
#if defined(__XTENSA_CALL0_ABI__)
|
||||
l32i a12, a2, 8
|
||||
l32i a13, a2, 12
|
||||
l32i a14, a2, 16
|
||||
l32i a15, a2, 20
|
||||
#endif
|
||||
movi a2, 0
|
||||
abi_ret_default
|
||||
|
||||
ENDPROC(swsusp_arch_resume)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <asm/coprocessor.h>
|
||||
|
||||
int pfn_is_nosave(unsigned long pfn)
|
||||
{
|
||||
unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin));
|
||||
unsigned long nosave_end_pfn = PFN_UP(__pa(&__nosave_end));
|
||||
|
||||
return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
|
||||
}
|
||||
|
||||
void notrace save_processor_state(void)
|
||||
{
|
||||
WARN_ON(num_online_cpus() != 1);
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
local_coprocessors_flush_release_all();
|
||||
#endif
|
||||
}
|
||||
|
||||
void notrace restore_processor_state(void)
|
||||
{
|
||||
}
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/regs.h>
|
||||
#include <asm/hw_breakpoint.h>
|
||||
#include <asm/traps.h>
|
||||
|
||||
extern void ret_from_fork(void);
|
||||
extern void ret_from_kernel_thread(void);
|
||||
@@ -63,52 +64,114 @@ EXPORT_SYMBOL(__stack_chk_guard);
|
||||
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
|
||||
void coprocessor_release_all(struct thread_info *ti)
|
||||
void local_coprocessors_flush_release_all(void)
|
||||
{
|
||||
unsigned long cpenable;
|
||||
struct thread_info **coprocessor_owner;
|
||||
struct thread_info *unique_owner[XCHAL_CP_MAX];
|
||||
int n = 0;
|
||||
int i, j;
|
||||
|
||||
coprocessor_owner = this_cpu_ptr(&exc_table)->coprocessor_owner;
|
||||
xtensa_set_sr(XCHAL_CP_MASK, cpenable);
|
||||
|
||||
for (i = 0; i < XCHAL_CP_MAX; i++) {
|
||||
struct thread_info *ti = coprocessor_owner[i];
|
||||
|
||||
if (ti) {
|
||||
coprocessor_flush(ti, i);
|
||||
|
||||
for (j = 0; j < n; j++)
|
||||
if (unique_owner[j] == ti)
|
||||
break;
|
||||
if (j == n)
|
||||
unique_owner[n++] = ti;
|
||||
|
||||
coprocessor_owner[i] = NULL;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
/* pairs with memw (1) in fast_coprocessor and memw in switch_to */
|
||||
smp_wmb();
|
||||
unique_owner[i]->cpenable = 0;
|
||||
}
|
||||
xtensa_set_sr(0, cpenable);
|
||||
}
|
||||
|
||||
static void local_coprocessor_release_all(void *info)
|
||||
{
|
||||
struct thread_info *ti = info;
|
||||
struct thread_info **coprocessor_owner;
|
||||
int i;
|
||||
|
||||
/* Make sure we don't switch tasks during this operation. */
|
||||
|
||||
preempt_disable();
|
||||
coprocessor_owner = this_cpu_ptr(&exc_table)->coprocessor_owner;
|
||||
|
||||
/* Walk through all cp owners and release it for the requested one. */
|
||||
|
||||
cpenable = ti->cpenable;
|
||||
|
||||
for (i = 0; i < XCHAL_CP_MAX; i++) {
|
||||
if (coprocessor_owner[i] == ti) {
|
||||
coprocessor_owner[i] = 0;
|
||||
cpenable &= ~(1 << i);
|
||||
}
|
||||
if (coprocessor_owner[i] == ti)
|
||||
coprocessor_owner[i] = NULL;
|
||||
}
|
||||
|
||||
ti->cpenable = cpenable;
|
||||
/* pairs with memw (1) in fast_coprocessor and memw in switch_to */
|
||||
smp_wmb();
|
||||
ti->cpenable = 0;
|
||||
if (ti == current_thread_info())
|
||||
xtensa_set_sr(0, cpenable);
|
||||
}
|
||||
|
||||
preempt_enable();
|
||||
void coprocessor_release_all(struct thread_info *ti)
|
||||
{
|
||||
if (ti->cpenable) {
|
||||
/* pairs with memw (2) in fast_coprocessor */
|
||||
smp_rmb();
|
||||
smp_call_function_single(ti->cp_owner_cpu,
|
||||
local_coprocessor_release_all,
|
||||
ti, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void local_coprocessor_flush_all(void *info)
|
||||
{
|
||||
struct thread_info *ti = info;
|
||||
struct thread_info **coprocessor_owner;
|
||||
unsigned long old_cpenable;
|
||||
int i;
|
||||
|
||||
coprocessor_owner = this_cpu_ptr(&exc_table)->coprocessor_owner;
|
||||
old_cpenable = xtensa_xsr(ti->cpenable, cpenable);
|
||||
|
||||
for (i = 0; i < XCHAL_CP_MAX; i++) {
|
||||
if (coprocessor_owner[i] == ti)
|
||||
coprocessor_flush(ti, i);
|
||||
}
|
||||
xtensa_set_sr(old_cpenable, cpenable);
|
||||
}
|
||||
|
||||
void coprocessor_flush_all(struct thread_info *ti)
|
||||
{
|
||||
unsigned long cpenable, old_cpenable;
|
||||
int i;
|
||||
|
||||
preempt_disable();
|
||||
|
||||
old_cpenable = xtensa_get_sr(cpenable);
|
||||
cpenable = ti->cpenable;
|
||||
xtensa_set_sr(cpenable, cpenable);
|
||||
|
||||
for (i = 0; i < XCHAL_CP_MAX; i++) {
|
||||
if ((cpenable & 1) != 0 && coprocessor_owner[i] == ti)
|
||||
coprocessor_flush(ti, i);
|
||||
cpenable >>= 1;
|
||||
if (ti->cpenable) {
|
||||
/* pairs with memw (2) in fast_coprocessor */
|
||||
smp_rmb();
|
||||
smp_call_function_single(ti->cp_owner_cpu,
|
||||
local_coprocessor_flush_all,
|
||||
ti, true);
|
||||
}
|
||||
xtensa_set_sr(old_cpenable, cpenable);
|
||||
}
|
||||
|
||||
preempt_enable();
|
||||
static void local_coprocessor_flush_release_all(void *info)
|
||||
{
|
||||
local_coprocessor_flush_all(info);
|
||||
local_coprocessor_release_all(info);
|
||||
}
|
||||
|
||||
void coprocessor_flush_release_all(struct thread_info *ti)
|
||||
{
|
||||
if (ti->cpenable) {
|
||||
/* pairs with memw (2) in fast_coprocessor */
|
||||
smp_rmb();
|
||||
smp_call_function_single(ti->cp_owner_cpu,
|
||||
local_coprocessor_flush_release_all,
|
||||
ti, true);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -140,8 +203,7 @@ void flush_thread(void)
|
||||
{
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
struct thread_info *ti = current_thread_info();
|
||||
coprocessor_flush_all(ti);
|
||||
coprocessor_release_all(ti);
|
||||
coprocessor_flush_release_all(ti);
|
||||
#endif
|
||||
flush_ptrace_hw_breakpoint(current);
|
||||
}
|
||||
|
||||
@@ -171,8 +171,7 @@ static int tie_set(struct task_struct *target,
|
||||
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
/* Flush all coprocessors before we overwrite them. */
|
||||
coprocessor_flush_all(ti);
|
||||
coprocessor_release_all(ti);
|
||||
coprocessor_flush_release_all(ti);
|
||||
ti->xtregs_cp.cp0 = newregs->cp0;
|
||||
ti->xtregs_cp.cp1 = newregs->cp1;
|
||||
ti->xtregs_cp.cp2 = newregs->cp2;
|
||||
|
||||
@@ -40,14 +40,13 @@ static inline int probed_compare_swap(int *v, int cmp, int set)
|
||||
|
||||
/* Handle probed exception */
|
||||
|
||||
static void __init do_probed_exception(struct pt_regs *regs,
|
||||
unsigned long exccause)
|
||||
static void __init do_probed_exception(struct pt_regs *regs)
|
||||
{
|
||||
if (regs->pc == rcw_probe_pc) { /* exception on s32c1i ? */
|
||||
regs->pc += 3; /* skip the s32c1i instruction */
|
||||
rcw_exc = exccause;
|
||||
rcw_exc = regs->exccause;
|
||||
} else {
|
||||
do_unhandled(regs, exccause);
|
||||
do_unhandled(regs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -162,8 +162,7 @@ setup_sigcontext(struct rt_sigframe __user *frame, struct pt_regs *regs)
|
||||
return err;
|
||||
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
coprocessor_flush_all(ti);
|
||||
coprocessor_release_all(ti);
|
||||
coprocessor_flush_release_all(ti);
|
||||
err |= __copy_to_user(&frame->xtregs.cp, &ti->xtregs_cp,
|
||||
sizeof (frame->xtregs.cp));
|
||||
#endif
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <linux/thread_info.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/coprocessor.h>
|
||||
#include <asm/kdebug.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/mxregs.h>
|
||||
@@ -272,6 +273,12 @@ int __cpu_disable(void)
|
||||
*/
|
||||
set_cpu_online(cpu, false);
|
||||
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
/*
|
||||
* Flush coprocessor contexts that are active on the current CPU.
|
||||
*/
|
||||
local_coprocessors_flush_release_all();
|
||||
#endif
|
||||
/*
|
||||
* OK - migrate IRQs away from this CPU
|
||||
*/
|
||||
|
||||
+89
-58
@@ -48,25 +48,20 @@
|
||||
* Machine specific interrupt handlers
|
||||
*/
|
||||
|
||||
extern void kernel_exception(void);
|
||||
extern void user_exception(void);
|
||||
|
||||
extern void fast_illegal_instruction_user(void);
|
||||
extern void fast_syscall_user(void);
|
||||
extern void fast_alloca(void);
|
||||
extern void fast_unaligned(void);
|
||||
extern void fast_second_level_miss(void);
|
||||
extern void fast_store_prohibited(void);
|
||||
extern void fast_coprocessor(void);
|
||||
|
||||
extern void do_illegal_instruction (struct pt_regs*);
|
||||
extern void do_interrupt (struct pt_regs*);
|
||||
extern void do_nmi(struct pt_regs *);
|
||||
extern void do_unaligned_user (struct pt_regs*);
|
||||
extern void do_multihit (struct pt_regs*, unsigned long);
|
||||
extern void do_page_fault (struct pt_regs*, unsigned long);
|
||||
extern void do_debug (struct pt_regs*);
|
||||
extern void system_call (struct pt_regs*);
|
||||
static void do_illegal_instruction(struct pt_regs *regs);
|
||||
static void do_div0(struct pt_regs *regs);
|
||||
static void do_interrupt(struct pt_regs *regs);
|
||||
#if XTENSA_FAKE_NMI
|
||||
static void do_nmi(struct pt_regs *regs);
|
||||
#endif
|
||||
#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
|
||||
static void do_unaligned_user(struct pt_regs *regs);
|
||||
#endif
|
||||
static void do_multihit(struct pt_regs *regs);
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
static void do_coprocessor(struct pt_regs *regs);
|
||||
#endif
|
||||
static void do_debug(struct pt_regs *regs);
|
||||
|
||||
/*
|
||||
* The vector table must be preceded by a save area (which
|
||||
@@ -78,7 +73,8 @@ extern void system_call (struct pt_regs*);
|
||||
#define USER 0x02
|
||||
|
||||
#define COPROCESSOR(x) \
|
||||
{ EXCCAUSE_COPROCESSOR ## x ## _DISABLED, USER, fast_coprocessor }
|
||||
{ EXCCAUSE_COPROCESSOR ## x ## _DISABLED, USER|KRNL, fast_coprocessor },\
|
||||
{ EXCCAUSE_COPROCESSOR ## x ## _DISABLED, 0, do_coprocessor }
|
||||
|
||||
typedef struct {
|
||||
int cause;
|
||||
@@ -100,7 +96,7 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = {
|
||||
#ifdef SUPPORT_WINDOWED
|
||||
{ EXCCAUSE_ALLOCA, USER|KRNL, fast_alloca },
|
||||
#endif
|
||||
/* EXCCAUSE_INTEGER_DIVIDE_BY_ZERO unhandled */
|
||||
{ EXCCAUSE_INTEGER_DIVIDE_BY_ZERO, 0, do_div0 },
|
||||
/* EXCCAUSE_PRIVILEGED unhandled */
|
||||
#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
|
||||
#ifdef CONFIG_XTENSA_UNALIGNED_USER
|
||||
@@ -110,21 +106,21 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = {
|
||||
{ EXCCAUSE_UNALIGNED, KRNL, fast_unaligned },
|
||||
#endif
|
||||
#ifdef CONFIG_MMU
|
||||
{ EXCCAUSE_ITLB_MISS, 0, do_page_fault },
|
||||
{ EXCCAUSE_ITLB_MISS, USER|KRNL, fast_second_level_miss},
|
||||
{ EXCCAUSE_ITLB_MULTIHIT, 0, do_multihit },
|
||||
{ EXCCAUSE_ITLB_PRIVILEGE, 0, do_page_fault },
|
||||
/* EXCCAUSE_SIZE_RESTRICTION unhandled */
|
||||
{ EXCCAUSE_FETCH_CACHE_ATTRIBUTE, 0, do_page_fault },
|
||||
{ EXCCAUSE_DTLB_MISS, USER|KRNL, fast_second_level_miss},
|
||||
{ EXCCAUSE_DTLB_MISS, 0, do_page_fault },
|
||||
{ EXCCAUSE_DTLB_MULTIHIT, 0, do_multihit },
|
||||
{ EXCCAUSE_DTLB_PRIVILEGE, 0, do_page_fault },
|
||||
/* EXCCAUSE_DTLB_SIZE_RESTRICTION unhandled */
|
||||
{ EXCCAUSE_ITLB_MISS, 0, do_page_fault },
|
||||
{ EXCCAUSE_ITLB_MISS, USER|KRNL, fast_second_level_miss},
|
||||
{ EXCCAUSE_DTLB_MISS, USER|KRNL, fast_second_level_miss},
|
||||
{ EXCCAUSE_DTLB_MISS, 0, do_page_fault },
|
||||
{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, USER|KRNL, fast_store_prohibited },
|
||||
#endif /* CONFIG_MMU */
|
||||
#ifdef CONFIG_PFAULT
|
||||
{ EXCCAUSE_ITLB_MULTIHIT, 0, do_multihit },
|
||||
{ EXCCAUSE_ITLB_PRIVILEGE, 0, do_page_fault },
|
||||
{ EXCCAUSE_FETCH_CACHE_ATTRIBUTE, 0, do_page_fault },
|
||||
{ EXCCAUSE_DTLB_MULTIHIT, 0, do_multihit },
|
||||
{ EXCCAUSE_DTLB_PRIVILEGE, 0, do_page_fault },
|
||||
{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, 0, do_page_fault },
|
||||
{ EXCCAUSE_LOAD_CACHE_ATTRIBUTE, 0, do_page_fault },
|
||||
#endif /* CONFIG_MMU */
|
||||
#endif
|
||||
/* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */
|
||||
#if XTENSA_HAVE_COPROCESSOR(0)
|
||||
COPROCESSOR(0),
|
||||
@@ -179,7 +175,7 @@ __die_if_kernel(const char *str, struct pt_regs *regs, long err)
|
||||
* Unhandled Exceptions. Kill user task or panic if in kernel space.
|
||||
*/
|
||||
|
||||
void do_unhandled(struct pt_regs *regs, unsigned long exccause)
|
||||
void do_unhandled(struct pt_regs *regs)
|
||||
{
|
||||
__die_if_kernel("Caught unhandled exception - should not happen",
|
||||
regs, SIGKILL);
|
||||
@@ -189,7 +185,7 @@ void do_unhandled(struct pt_regs *regs, unsigned long exccause)
|
||||
"(pid = %d, pc = %#010lx) - should not happen\n"
|
||||
"\tEXCCAUSE is %ld\n",
|
||||
current->comm, task_pid_nr(current), regs->pc,
|
||||
exccause);
|
||||
regs->exccause);
|
||||
force_sig(SIGILL);
|
||||
}
|
||||
|
||||
@@ -197,7 +193,7 @@ void do_unhandled(struct pt_regs *regs, unsigned long exccause)
|
||||
* Multi-hit exception. This if fatal!
|
||||
*/
|
||||
|
||||
void do_multihit(struct pt_regs *regs, unsigned long exccause)
|
||||
static void do_multihit(struct pt_regs *regs)
|
||||
{
|
||||
die("Caught multihit exception", regs, SIGKILL);
|
||||
}
|
||||
@@ -206,8 +202,6 @@ void do_multihit(struct pt_regs *regs, unsigned long exccause)
|
||||
* IRQ handler.
|
||||
*/
|
||||
|
||||
extern void do_IRQ(int, struct pt_regs *);
|
||||
|
||||
#if XTENSA_FAKE_NMI
|
||||
|
||||
#define IS_POW2(v) (((v) & ((v) - 1)) == 0)
|
||||
@@ -240,14 +234,10 @@ irqreturn_t xtensa_pmu_irq_handler(int irq, void *dev_id);
|
||||
|
||||
DEFINE_PER_CPU(unsigned long, nmi_count);
|
||||
|
||||
void do_nmi(struct pt_regs *regs)
|
||||
static void do_nmi(struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *old_regs;
|
||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||
|
||||
if ((regs->ps & PS_INTLEVEL_MASK) < LOCKLEVEL)
|
||||
trace_hardirqs_off();
|
||||
|
||||
old_regs = set_irq_regs(regs);
|
||||
nmi_enter();
|
||||
++*this_cpu_ptr(&nmi_count);
|
||||
check_valid_nmi();
|
||||
@@ -257,7 +247,7 @@ void do_nmi(struct pt_regs *regs)
|
||||
}
|
||||
#endif
|
||||
|
||||
void do_interrupt(struct pt_regs *regs)
|
||||
static void do_interrupt(struct pt_regs *regs)
|
||||
{
|
||||
static const unsigned int_level_mask[] = {
|
||||
0,
|
||||
@@ -269,12 +259,9 @@ void do_interrupt(struct pt_regs *regs)
|
||||
XCHAL_INTLEVEL6_MASK,
|
||||
XCHAL_INTLEVEL7_MASK,
|
||||
};
|
||||
struct pt_regs *old_regs;
|
||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||
unsigned unhandled = ~0u;
|
||||
|
||||
trace_hardirqs_off();
|
||||
|
||||
old_regs = set_irq_regs(regs);
|
||||
irq_enter();
|
||||
|
||||
for (;;) {
|
||||
@@ -306,13 +293,47 @@ void do_interrupt(struct pt_regs *regs)
|
||||
set_irq_regs(old_regs);
|
||||
}
|
||||
|
||||
static bool check_div0(struct pt_regs *regs)
|
||||
{
|
||||
static const u8 pattern[] = {'D', 'I', 'V', '0'};
|
||||
const u8 *p;
|
||||
u8 buf[5];
|
||||
|
||||
if (user_mode(regs)) {
|
||||
if (copy_from_user(buf, (void __user *)regs->pc + 2, 5))
|
||||
return false;
|
||||
p = buf;
|
||||
} else {
|
||||
p = (const u8 *)regs->pc + 2;
|
||||
}
|
||||
|
||||
return memcmp(p, pattern, sizeof(pattern)) == 0 ||
|
||||
memcmp(p + 1, pattern, sizeof(pattern)) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Illegal instruction. Fatal if in kernel space.
|
||||
*/
|
||||
|
||||
void
|
||||
do_illegal_instruction(struct pt_regs *regs)
|
||||
static void do_illegal_instruction(struct pt_regs *regs)
|
||||
{
|
||||
#ifdef CONFIG_USER_ABI_CALL0_PROBE
|
||||
/*
|
||||
* When call0 application encounters an illegal instruction fast
|
||||
* exception handler will attempt to set PS.WOE and retry failing
|
||||
* instruction.
|
||||
* If we get here we know that that instruction is also illegal
|
||||
* with PS.WOE set, so it's not related to the windowed option
|
||||
* hence PS.WOE may be cleared.
|
||||
*/
|
||||
if (regs->pc == current_thread_info()->ps_woe_fix_addr)
|
||||
regs->ps &= ~PS_WOE_MASK;
|
||||
#endif
|
||||
if (check_div0(regs)) {
|
||||
do_div0(regs);
|
||||
return;
|
||||
}
|
||||
|
||||
__die_if_kernel("Illegal instruction in kernel", regs, SIGKILL);
|
||||
|
||||
/* If in user mode, send SIGILL signal to current process. */
|
||||
@@ -322,6 +343,11 @@ do_illegal_instruction(struct pt_regs *regs)
|
||||
force_sig(SIGILL);
|
||||
}
|
||||
|
||||
static void do_div0(struct pt_regs *regs)
|
||||
{
|
||||
__die_if_kernel("Unhandled division by 0 in kernel", regs, SIGKILL);
|
||||
force_sig_fault(SIGFPE, FPE_INTDIV, (void __user *)regs->pc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle unaligned memory accesses from user space. Kill task.
|
||||
@@ -331,8 +357,7 @@ do_illegal_instruction(struct pt_regs *regs)
|
||||
*/
|
||||
|
||||
#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
|
||||
void
|
||||
do_unaligned_user (struct pt_regs *regs)
|
||||
static void do_unaligned_user(struct pt_regs *regs)
|
||||
{
|
||||
__die_if_kernel("Unhandled unaligned exception in kernel",
|
||||
regs, SIGKILL);
|
||||
@@ -347,14 +372,20 @@ do_unaligned_user (struct pt_regs *regs)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
static void do_coprocessor(struct pt_regs *regs)
|
||||
{
|
||||
coprocessor_flush_release_all(current_thread_info());
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Handle debug events.
|
||||
* When CONFIG_HAVE_HW_BREAKPOINT is on this handler is called with
|
||||
* preemption disabled to avoid rescheduling and keep mapping of hardware
|
||||
* breakpoint structures to debug registers intact, so that
|
||||
* DEBUGCAUSE.DBNUM could be used in case of data breakpoint hit.
|
||||
*/
|
||||
void
|
||||
do_debug(struct pt_regs *regs)
|
||||
static void do_debug(struct pt_regs *regs)
|
||||
{
|
||||
#ifdef CONFIG_HAVE_HW_BREAKPOINT
|
||||
int ret = check_hw_breakpoint(regs);
|
||||
@@ -381,7 +412,8 @@ do_debug(struct pt_regs *regs)
|
||||
|
||||
/* Set exception C handler - for temporary use when probing exceptions */
|
||||
|
||||
void * __init trap_set_handler(int cause, void *handler)
|
||||
xtensa_exception_handler *
|
||||
__init trap_set_handler(int cause, xtensa_exception_handler *handler)
|
||||
{
|
||||
void *previous = per_cpu(exc_table, 0).default_handler[cause];
|
||||
|
||||
@@ -392,8 +424,7 @@ void * __init trap_set_handler(int cause, void *handler)
|
||||
|
||||
static void trap_init_excsave(void)
|
||||
{
|
||||
unsigned long excsave1 = (unsigned long)this_cpu_ptr(&exc_table);
|
||||
__asm__ __volatile__("wsr %0, excsave1\n" : : "a" (excsave1));
|
||||
xtensa_set_sr(this_cpu_ptr(&exc_table), excsave1);
|
||||
}
|
||||
|
||||
static void trap_init_debug(void)
|
||||
|
||||
@@ -8,3 +8,5 @@ lib-y += memcopy.o memset.o checksum.o \
|
||||
divsi3.o udivsi3.o modsi3.o umodsi3.o mulsi3.o \
|
||||
usercopy.o strncpy_user.o strnlen_user.o
|
||||
lib-$(CONFIG_PCI) += pci-auto.o
|
||||
lib-$(CONFIG_KCSAN) += kcsan-stubs.o
|
||||
KCSAN_SANITIZE_kcsan-stubs.o := n
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
void __atomic_store_8(volatile void *p, u64 v, int i)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
|
||||
u64 __atomic_load_8(const volatile void *p, int i)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
|
||||
u64 __atomic_exchange_8(volatile void *p, u64 v, int i)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
|
||||
bool __atomic_compare_exchange_8(volatile void *p1, void *p2, u64 v, bool b, int i1, int i2)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
|
||||
u64 __atomic_fetch_add_8(volatile void *p, u64 v, int i)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
|
||||
u64 __atomic_fetch_sub_8(volatile void *p, u64 v, int i)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
|
||||
u64 __atomic_fetch_and_8(volatile void *p, u64 v, int i)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
|
||||
u64 __atomic_fetch_or_8(volatile void *p, u64 v, int i)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
|
||||
u64 __atomic_fetch_xor_8(volatile void *p, u64 v, int i)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
|
||||
u64 __atomic_fetch_nand_8(volatile void *p, u64 v, int i)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
+10
-10
@@ -402,13 +402,13 @@ WEAK(memmove)
|
||||
*/
|
||||
# copy 16 bytes per iteration for word-aligned dst and word-aligned src
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
loopnez a7, .backLoop1done
|
||||
loopnez a7, .LbackLoop1done
|
||||
#else /* !XCHAL_HAVE_LOOPS */
|
||||
beqz a7, .backLoop1done
|
||||
beqz a7, .LbackLoop1done
|
||||
slli a8, a7, 4
|
||||
sub a8, a3, a8 # a8 = start of first 16B source chunk
|
||||
#endif /* !XCHAL_HAVE_LOOPS */
|
||||
.backLoop1:
|
||||
.LbackLoop1:
|
||||
addi a3, a3, -16
|
||||
l32i a7, a3, 12
|
||||
l32i a6, a3, 8
|
||||
@@ -420,9 +420,9 @@ WEAK(memmove)
|
||||
s32i a7, a5, 4
|
||||
s32i a6, a5, 0
|
||||
#if !XCHAL_HAVE_LOOPS
|
||||
bne a3, a8, .backLoop1 # continue loop if a3:src != a8:src_start
|
||||
bne a3, a8, .LbackLoop1 # continue loop if a3:src != a8:src_start
|
||||
#endif /* !XCHAL_HAVE_LOOPS */
|
||||
.backLoop1done:
|
||||
.LbackLoop1done:
|
||||
bbci.l a4, 3, .Lback2
|
||||
# copy 8 bytes
|
||||
addi a3, a3, -8
|
||||
@@ -479,13 +479,13 @@ WEAK(memmove)
|
||||
#endif
|
||||
l32i a6, a3, 0 # load first word
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
loopnez a7, .backLoop2done
|
||||
loopnez a7, .LbackLoop2done
|
||||
#else /* !XCHAL_HAVE_LOOPS */
|
||||
beqz a7, .backLoop2done
|
||||
beqz a7, .LbackLoop2done
|
||||
slli a10, a7, 4
|
||||
sub a10, a3, a10 # a10 = start of first 16B source chunk
|
||||
#endif /* !XCHAL_HAVE_LOOPS */
|
||||
.backLoop2:
|
||||
.LbackLoop2:
|
||||
addi a3, a3, -16
|
||||
l32i a7, a3, 12
|
||||
l32i a8, a3, 8
|
||||
@@ -501,9 +501,9 @@ WEAK(memmove)
|
||||
__src_b a9, a6, a9
|
||||
s32i a9, a5, 0
|
||||
#if !XCHAL_HAVE_LOOPS
|
||||
bne a3, a10, .backLoop2 # continue loop if a3:src != a10:src_start
|
||||
bne a3, a10, .LbackLoop2 # continue loop if a3:src != a10:src_start
|
||||
#endif /* !XCHAL_HAVE_LOOPS */
|
||||
.backLoop2done:
|
||||
.LbackLoop2done:
|
||||
bbci.l a4, 3, .Lback12
|
||||
# copy 8 bytes
|
||||
addi a3, a3, -8
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
#
|
||||
|
||||
obj-y := init.o misc.o
|
||||
obj-$(CONFIG_MMU) += cache.o fault.o ioremap.o mmu.o tlb.o
|
||||
obj-$(CONFIG_PFAULT) += fault.o
|
||||
obj-$(CONFIG_MMU) += cache.o ioremap.o mmu.o tlb.o
|
||||
obj-$(CONFIG_HIGHMEM) += highmem.o
|
||||
obj-$(CONFIG_KASAN) += kasan_init.o
|
||||
|
||||
|
||||
+58
-54
@@ -21,9 +21,61 @@
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/hardirq.h>
|
||||
|
||||
DEFINE_PER_CPU(unsigned long, asid_cache) = ASID_USER_FIRST;
|
||||
void bad_page_fault(struct pt_regs*, unsigned long, int);
|
||||
|
||||
static void vmalloc_fault(struct pt_regs *regs, unsigned int address)
|
||||
{
|
||||
#ifdef CONFIG_MMU
|
||||
/* Synchronize this task's top level page-table
|
||||
* with the 'reference' page table.
|
||||
*/
|
||||
struct mm_struct *act_mm = current->active_mm;
|
||||
int index = pgd_index(address);
|
||||
pgd_t *pgd, *pgd_k;
|
||||
p4d_t *p4d, *p4d_k;
|
||||
pud_t *pud, *pud_k;
|
||||
pmd_t *pmd, *pmd_k;
|
||||
pte_t *pte_k;
|
||||
|
||||
if (act_mm == NULL)
|
||||
goto bad_page_fault;
|
||||
|
||||
pgd = act_mm->pgd + index;
|
||||
pgd_k = init_mm.pgd + index;
|
||||
|
||||
if (!pgd_present(*pgd_k))
|
||||
goto bad_page_fault;
|
||||
|
||||
pgd_val(*pgd) = pgd_val(*pgd_k);
|
||||
|
||||
p4d = p4d_offset(pgd, address);
|
||||
p4d_k = p4d_offset(pgd_k, address);
|
||||
if (!p4d_present(*p4d) || !p4d_present(*p4d_k))
|
||||
goto bad_page_fault;
|
||||
|
||||
pud = pud_offset(p4d, address);
|
||||
pud_k = pud_offset(p4d_k, address);
|
||||
if (!pud_present(*pud) || !pud_present(*pud_k))
|
||||
goto bad_page_fault;
|
||||
|
||||
pmd = pmd_offset(pud, address);
|
||||
pmd_k = pmd_offset(pud_k, address);
|
||||
if (!pmd_present(*pmd) || !pmd_present(*pmd_k))
|
||||
goto bad_page_fault;
|
||||
|
||||
pmd_val(*pmd) = pmd_val(*pmd_k);
|
||||
pte_k = pte_offset_kernel(pmd_k, address);
|
||||
|
||||
if (!pte_present(*pte_k))
|
||||
goto bad_page_fault;
|
||||
return;
|
||||
|
||||
bad_page_fault:
|
||||
bad_page_fault(regs, address, SIGKILL);
|
||||
#else
|
||||
WARN_ONCE(1, "%s in noMMU configuration\n", __func__);
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* This routine handles page faults. It determines the address,
|
||||
* and the problem, and then passes it off to one of the appropriate
|
||||
@@ -49,8 +101,10 @@ void do_page_fault(struct pt_regs *regs)
|
||||
/* We fault-in kernel-space virtual memory on-demand. The
|
||||
* 'reference' page table is init_mm.pgd.
|
||||
*/
|
||||
if (address >= TASK_SIZE && !user_mode(regs))
|
||||
goto vmalloc_fault;
|
||||
if (address >= TASK_SIZE && !user_mode(regs)) {
|
||||
vmalloc_fault(regs, address);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we're in an interrupt or have no user
|
||||
* context, we must not take the fault..
|
||||
@@ -114,7 +168,7 @@ good_area:
|
||||
|
||||
if (fault_signal_pending(fault, regs)) {
|
||||
if (!user_mode(regs))
|
||||
goto bad_page_fault;
|
||||
bad_page_fault(regs, address, SIGKILL);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -181,56 +235,6 @@ do_sigbus:
|
||||
if (!user_mode(regs))
|
||||
bad_page_fault(regs, address, SIGBUS);
|
||||
return;
|
||||
|
||||
vmalloc_fault:
|
||||
{
|
||||
/* Synchronize this task's top level page-table
|
||||
* with the 'reference' page table.
|
||||
*/
|
||||
struct mm_struct *act_mm = current->active_mm;
|
||||
int index = pgd_index(address);
|
||||
pgd_t *pgd, *pgd_k;
|
||||
p4d_t *p4d, *p4d_k;
|
||||
pud_t *pud, *pud_k;
|
||||
pmd_t *pmd, *pmd_k;
|
||||
pte_t *pte_k;
|
||||
|
||||
if (act_mm == NULL)
|
||||
goto bad_page_fault;
|
||||
|
||||
pgd = act_mm->pgd + index;
|
||||
pgd_k = init_mm.pgd + index;
|
||||
|
||||
if (!pgd_present(*pgd_k))
|
||||
goto bad_page_fault;
|
||||
|
||||
pgd_val(*pgd) = pgd_val(*pgd_k);
|
||||
|
||||
p4d = p4d_offset(pgd, address);
|
||||
p4d_k = p4d_offset(pgd_k, address);
|
||||
if (!p4d_present(*p4d) || !p4d_present(*p4d_k))
|
||||
goto bad_page_fault;
|
||||
|
||||
pud = pud_offset(p4d, address);
|
||||
pud_k = pud_offset(p4d_k, address);
|
||||
if (!pud_present(*pud) || !pud_present(*pud_k))
|
||||
goto bad_page_fault;
|
||||
|
||||
pmd = pmd_offset(pud, address);
|
||||
pmd_k = pmd_offset(pud_k, address);
|
||||
if (!pmd_present(*pmd) || !pmd_present(*pmd_k))
|
||||
goto bad_page_fault;
|
||||
|
||||
pmd_val(*pmd) = pmd_val(*pmd_k);
|
||||
pte_k = pte_offset_kernel(pmd_k, address);
|
||||
|
||||
if (!pte_present(*pte_k))
|
||||
goto bad_page_fault;
|
||||
return;
|
||||
}
|
||||
bad_page_fault:
|
||||
bad_page_fault(regs, address, SIGKILL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <asm/initialize_mmu.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
DEFINE_PER_CPU(unsigned long, asid_cache) = ASID_USER_FIRST;
|
||||
|
||||
#if defined(CONFIG_HIGHMEM)
|
||||
static void * __init init_pmd(unsigned long vaddr, unsigned long n_pages)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user