Main features:
- Versatile Express SoC (model) support - DT files and Kconfig entries (there are no arch/arm64/mach-* directories). The bulk of the code has already been moved to drivers/ as part of the ARM SoC clean-up. - Basic multi-cluster support (CPU logical map initialised from the DT). - Simple earlyprintk support for UART 8250/16550 and FastModel console output. - Optimised kernel library bitops and string functions. - Automatic initialisation of the irqchip and clocks via DT. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iQIcBAABAgAGBQJRf+a/AAoJEGvWsS0AyF7x4cAP/199we5Q3IvXnOiyoiJSwk/v FJ8i+B/cICd8LiSRhpUkDYDWboBWq+LkG+SxmhPGjvWp0GXt6RFgSuT7okQrQy4l a3UpRNLAc7HRamehreWqdIXuD1JwkrUwRC5hxVjQBrI0Q2JeQgEbghtFwiK2qRAg yLo9PPRfrBHq3jEJXhaiHyb/oQm9jNUbgJ5KSes6gjgwBtnsATiaSyLe5FbZqzIV aYPKblFMUjR38TQE7uAxWtA8hPDG558dkiBJfs1GHRtkGt7odrEvAdscxw0mjDSd rvP+XW8URVDYUhZVSaDKB8z4l436jCSAg3GYCWf/CC+sQDdxBBa1Lp5ADg/xQLrh L+oICtDeX3v3LGhGs0x4RG4hdvyCATyHI+P/bIKA9sWUWbKTTCqEQahG0puyiun+ 7nB89xGKZDIcy7yc+2UivHXIsTIRXETLmEFDKciit3f7ua4maoIvJ8oOHkJaPJRQ imWRRg1BVMvq3L1IPCwuoIirasXzcrAkONw5Gw5ZHKVps0+xarNd4T/RWp1rmjXt R4ZdgWNMyC3PHoP7CwG9h7Ia4CUYuaxqnmWQRALrHahr1Cxb/rnU98xadjkkBTwX Xh1b6fdz4yKXgVBiirfPPRA3xjSYJkwEBqFwO5IAPhYulUw10U56+K0I77ixYQ8G IDtjzKiHu/P05Nwncgn6 =Uvte -----END PGP SIGNATURE----- Merge tag 'arm64-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux-aarch64 Pull arm64 update from Catalin Marinas: "Main features: - Versatile Express SoC (model) support - DT files and Kconfig entries (there are no arch/arm64/mach-* directories). The bulk of the code has already been moved to drivers/ as part of the ARM SoC clean-up. - Basic multi-cluster support (CPU logical map initialised from the DT) - Simple earlyprintk support for UART 8250/16550 and FastModel console output - Optimised kernel library bitops and string functions. - Automatic initialisation of the irqchip and clocks via DT" * tag 'arm64-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux-aarch64: (26 commits) arm64: Use acquire/release semantics instead of explicit DMB arm64: klib: bitops: fix unpredictable stxr usage arm64: vexpress: Enable ARMv8 RTSM model (SoC) support arm64: vexpress: Add dts files for the ARMv8 RTSM models arm64: Survive invalid cpu enable-methods arm64: mm: Correct show_pte behaviour arm64: Fix compat types affecting struct compat_stat arm64: Execute DSB during thread switching for TLB/cache maintenance arm64: compiling issue, need add include/asm/vga.h file arm64: smp: honour #address-size when parsing CPU reg property arm64: Define cmpxchg64 and cmpxchg64_local for outside use arm64: Define readq and writeq for driver module using arm64: Fix task tracing arm64: add explicit symbols to ESR_EL1 decoding arm64: Use irqchip_init() for interrupt controller initialisation arm64: psci: Use the MPIDR values from cpu_logical_map for cpu ids. arm64: klib: Optimised atomic bitops arm64: klib: Optimised string functions arm64: klib: Optimised memory functions arm64: head: match all affinity levels in the pen of the secondaries ...
This commit is contained in:
commit
c9ef713993
38 changed files with 1410 additions and 90 deletions
|
@ -99,7 +99,16 @@ source "init/Kconfig"
|
|||
|
||||
source "kernel/Kconfig.freezer"
|
||||
|
||||
menu "System Type"
|
||||
menu "Platform selection"
|
||||
|
||||
config ARCH_VEXPRESS
|
||||
bool "ARMv8 software model (Versatile Express)"
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select COMMON_CLK_VERSATILE
|
||||
select VEXPRESS_CONFIG
|
||||
help
|
||||
This enables support for the ARMv8 software model (Versatile
|
||||
Express).
|
||||
|
||||
endmenu
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb foundation-v8.dtb
|
||||
|
||||
targets += dtbs
|
||||
targets += $(dtb-y)
|
||||
|
||||
|
|
230
arch/arm64/boot/dts/foundation-v8.dts
Normal file
230
arch/arm64/boot/dts/foundation-v8.dts
Normal file
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* ARM Ltd.
|
||||
*
|
||||
* ARMv8 Foundation model DTS
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
model = "Foundation-v8A";
|
||||
compatible = "arm,foundation-aarch64", "arm,vexpress";
|
||||
interrupt-parent = <&gic>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
chosen { };
|
||||
|
||||
aliases {
|
||||
serial0 = &v2m_serial0;
|
||||
serial1 = &v2m_serial1;
|
||||
serial2 = &v2m_serial2;
|
||||
serial3 = &v2m_serial3;
|
||||
};
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,armv8";
|
||||
reg = <0x0 0x0>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0x0 0x8000fff8>;
|
||||
};
|
||||
cpu@1 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,armv8";
|
||||
reg = <0x0 0x1>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0x0 0x8000fff8>;
|
||||
};
|
||||
cpu@2 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,armv8";
|
||||
reg = <0x0 0x2>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0x0 0x8000fff8>;
|
||||
};
|
||||
cpu@3 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,armv8";
|
||||
reg = <0x0 0x3>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0x0 0x8000fff8>;
|
||||
};
|
||||
};
|
||||
|
||||
memory@80000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x00000000 0x80000000 0 0x80000000>,
|
||||
<0x00000008 0x80000000 0 0x80000000>;
|
||||
};
|
||||
|
||||
gic: interrupt-controller@2c001000 {
|
||||
compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
|
||||
#interrupt-cells = <3>;
|
||||
#address-cells = <0>;
|
||||
interrupt-controller;
|
||||
reg = <0x0 0x2c001000 0 0x1000>,
|
||||
<0x0 0x2c002000 0 0x1000>,
|
||||
<0x0 0x2c004000 0 0x2000>,
|
||||
<0x0 0x2c006000 0 0x2000>;
|
||||
interrupts = <1 9 0xf04>;
|
||||
};
|
||||
|
||||
timer {
|
||||
compatible = "arm,armv8-timer";
|
||||
interrupts = <1 13 0xff01>,
|
||||
<1 14 0xff01>,
|
||||
<1 11 0xff01>,
|
||||
<1 10 0xff01>;
|
||||
clock-frequency = <100000000>;
|
||||
};
|
||||
|
||||
pmu {
|
||||
compatible = "arm,armv8-pmuv3";
|
||||
interrupts = <0 60 4>,
|
||||
<0 61 4>,
|
||||
<0 62 4>,
|
||||
<0 63 4>;
|
||||
};
|
||||
|
||||
smb {
|
||||
compatible = "arm,vexpress,v2m-p1", "simple-bus";
|
||||
arm,v2m-memory-map = "rs1";
|
||||
#address-cells = <2>; /* SMB chipselect number and offset */
|
||||
#size-cells = <1>;
|
||||
|
||||
ranges = <0 0 0 0x08000000 0x04000000>,
|
||||
<1 0 0 0x14000000 0x04000000>,
|
||||
<2 0 0 0x18000000 0x04000000>,
|
||||
<3 0 0 0x1c000000 0x04000000>,
|
||||
<4 0 0 0x0c000000 0x04000000>,
|
||||
<5 0 0 0x10000000 0x04000000>;
|
||||
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 63>;
|
||||
interrupt-map = <0 0 0 &gic 0 0 4>,
|
||||
<0 0 1 &gic 0 1 4>,
|
||||
<0 0 2 &gic 0 2 4>,
|
||||
<0 0 3 &gic 0 3 4>,
|
||||
<0 0 4 &gic 0 4 4>,
|
||||
<0 0 5 &gic 0 5 4>,
|
||||
<0 0 6 &gic 0 6 4>,
|
||||
<0 0 7 &gic 0 7 4>,
|
||||
<0 0 8 &gic 0 8 4>,
|
||||
<0 0 9 &gic 0 9 4>,
|
||||
<0 0 10 &gic 0 10 4>,
|
||||
<0 0 11 &gic 0 11 4>,
|
||||
<0 0 12 &gic 0 12 4>,
|
||||
<0 0 13 &gic 0 13 4>,
|
||||
<0 0 14 &gic 0 14 4>,
|
||||
<0 0 15 &gic 0 15 4>,
|
||||
<0 0 16 &gic 0 16 4>,
|
||||
<0 0 17 &gic 0 17 4>,
|
||||
<0 0 18 &gic 0 18 4>,
|
||||
<0 0 19 &gic 0 19 4>,
|
||||
<0 0 20 &gic 0 20 4>,
|
||||
<0 0 21 &gic 0 21 4>,
|
||||
<0 0 22 &gic 0 22 4>,
|
||||
<0 0 23 &gic 0 23 4>,
|
||||
<0 0 24 &gic 0 24 4>,
|
||||
<0 0 25 &gic 0 25 4>,
|
||||
<0 0 26 &gic 0 26 4>,
|
||||
<0 0 27 &gic 0 27 4>,
|
||||
<0 0 28 &gic 0 28 4>,
|
||||
<0 0 29 &gic 0 29 4>,
|
||||
<0 0 30 &gic 0 30 4>,
|
||||
<0 0 31 &gic 0 31 4>,
|
||||
<0 0 32 &gic 0 32 4>,
|
||||
<0 0 33 &gic 0 33 4>,
|
||||
<0 0 34 &gic 0 34 4>,
|
||||
<0 0 35 &gic 0 35 4>,
|
||||
<0 0 36 &gic 0 36 4>,
|
||||
<0 0 37 &gic 0 37 4>,
|
||||
<0 0 38 &gic 0 38 4>,
|
||||
<0 0 39 &gic 0 39 4>,
|
||||
<0 0 40 &gic 0 40 4>,
|
||||
<0 0 41 &gic 0 41 4>,
|
||||
<0 0 42 &gic 0 42 4>;
|
||||
|
||||
ethernet@2,02000000 {
|
||||
compatible = "smsc,lan91c111";
|
||||
reg = <2 0x02000000 0x10000>;
|
||||
interrupts = <15>;
|
||||
};
|
||||
|
||||
v2m_clk24mhz: clk24mhz {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <24000000>;
|
||||
clock-output-names = "v2m:clk24mhz";
|
||||
};
|
||||
|
||||
v2m_refclk1mhz: refclk1mhz {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <1000000>;
|
||||
clock-output-names = "v2m:refclk1mhz";
|
||||
};
|
||||
|
||||
v2m_refclk32khz: refclk32khz {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <32768>;
|
||||
clock-output-names = "v2m:refclk32khz";
|
||||
};
|
||||
|
||||
iofpga@3,00000000 {
|
||||
compatible = "arm,amba-bus", "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0 3 0 0x200000>;
|
||||
|
||||
v2m_sysreg: sysreg@010000 {
|
||||
compatible = "arm,vexpress-sysreg";
|
||||
reg = <0x010000 0x1000>;
|
||||
};
|
||||
|
||||
v2m_serial0: uart@090000 {
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
reg = <0x090000 0x1000>;
|
||||
interrupts = <5>;
|
||||
clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
|
||||
clock-names = "uartclk", "apb_pclk";
|
||||
};
|
||||
|
||||
v2m_serial1: uart@0a0000 {
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
reg = <0x0a0000 0x1000>;
|
||||
interrupts = <6>;
|
||||
clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
|
||||
clock-names = "uartclk", "apb_pclk";
|
||||
};
|
||||
|
||||
v2m_serial2: uart@0b0000 {
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
reg = <0x0b0000 0x1000>;
|
||||
interrupts = <7>;
|
||||
clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
|
||||
clock-names = "uartclk", "apb_pclk";
|
||||
};
|
||||
|
||||
v2m_serial3: uart@0c0000 {
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
reg = <0x0c0000 0x1000>;
|
||||
interrupts = <8>;
|
||||
clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
|
||||
clock-names = "uartclk", "apb_pclk";
|
||||
};
|
||||
|
||||
virtio_block@0130000 {
|
||||
compatible = "virtio,mmio";
|
||||
reg = <0x130000 0x1000>;
|
||||
interrupts = <42>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
159
arch/arm64/boot/dts/rtsm_ve-aemv8a.dts
Normal file
159
arch/arm64/boot/dts/rtsm_ve-aemv8a.dts
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* ARM Ltd. Fast Models
|
||||
*
|
||||
* Architecture Envelope Model (AEM) ARMv8-A
|
||||
* ARMAEMv8AMPCT
|
||||
*
|
||||
* RTSM_VE_AEMv8A.lisa
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/memreserve/ 0x80000000 0x00010000;
|
||||
|
||||
/ {
|
||||
model = "RTSM_VE_AEMv8A";
|
||||
compatible = "arm,rtsm_ve,aemv8a", "arm,vexpress";
|
||||
interrupt-parent = <&gic>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
chosen { };
|
||||
|
||||
aliases {
|
||||
serial0 = &v2m_serial0;
|
||||
serial1 = &v2m_serial1;
|
||||
serial2 = &v2m_serial2;
|
||||
serial3 = &v2m_serial3;
|
||||
};
|
||||
|
||||
cpus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,armv8";
|
||||
reg = <0x0 0x0>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0x0 0x8000fff8>;
|
||||
};
|
||||
cpu@1 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,armv8";
|
||||
reg = <0x0 0x1>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0x0 0x8000fff8>;
|
||||
};
|
||||
cpu@2 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,armv8";
|
||||
reg = <0x0 0x2>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0x0 0x8000fff8>;
|
||||
};
|
||||
cpu@3 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,armv8";
|
||||
reg = <0x0 0x3>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0x0 0x8000fff8>;
|
||||
};
|
||||
};
|
||||
|
||||
memory@80000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x00000000 0x80000000 0 0x80000000>,
|
||||
<0x00000008 0x80000000 0 0x80000000>;
|
||||
};
|
||||
|
||||
gic: interrupt-controller@2c001000 {
|
||||
compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
|
||||
#interrupt-cells = <3>;
|
||||
#address-cells = <0>;
|
||||
interrupt-controller;
|
||||
reg = <0x0 0x2c001000 0 0x1000>,
|
||||
<0x0 0x2c002000 0 0x1000>,
|
||||
<0x0 0x2c004000 0 0x2000>,
|
||||
<0x0 0x2c006000 0 0x2000>;
|
||||
interrupts = <1 9 0xf04>;
|
||||
};
|
||||
|
||||
timer {
|
||||
compatible = "arm,armv8-timer";
|
||||
interrupts = <1 13 0xff01>,
|
||||
<1 14 0xff01>,
|
||||
<1 11 0xff01>,
|
||||
<1 10 0xff01>;
|
||||
clock-frequency = <100000000>;
|
||||
};
|
||||
|
||||
pmu {
|
||||
compatible = "arm,armv8-pmuv3";
|
||||
interrupts = <0 60 4>,
|
||||
<0 61 4>,
|
||||
<0 62 4>,
|
||||
<0 63 4>;
|
||||
};
|
||||
|
||||
smb {
|
||||
compatible = "simple-bus";
|
||||
|
||||
#address-cells = <2>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0 0 0 0x08000000 0x04000000>,
|
||||
<1 0 0 0x14000000 0x04000000>,
|
||||
<2 0 0 0x18000000 0x04000000>,
|
||||
<3 0 0 0x1c000000 0x04000000>,
|
||||
<4 0 0 0x0c000000 0x04000000>,
|
||||
<5 0 0 0x10000000 0x04000000>;
|
||||
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 63>;
|
||||
interrupt-map = <0 0 0 &gic 0 0 4>,
|
||||
<0 0 1 &gic 0 1 4>,
|
||||
<0 0 2 &gic 0 2 4>,
|
||||
<0 0 3 &gic 0 3 4>,
|
||||
<0 0 4 &gic 0 4 4>,
|
||||
<0 0 5 &gic 0 5 4>,
|
||||
<0 0 6 &gic 0 6 4>,
|
||||
<0 0 7 &gic 0 7 4>,
|
||||
<0 0 8 &gic 0 8 4>,
|
||||
<0 0 9 &gic 0 9 4>,
|
||||
<0 0 10 &gic 0 10 4>,
|
||||
<0 0 11 &gic 0 11 4>,
|
||||
<0 0 12 &gic 0 12 4>,
|
||||
<0 0 13 &gic 0 13 4>,
|
||||
<0 0 14 &gic 0 14 4>,
|
||||
<0 0 15 &gic 0 15 4>,
|
||||
<0 0 16 &gic 0 16 4>,
|
||||
<0 0 17 &gic 0 17 4>,
|
||||
<0 0 18 &gic 0 18 4>,
|
||||
<0 0 19 &gic 0 19 4>,
|
||||
<0 0 20 &gic 0 20 4>,
|
||||
<0 0 21 &gic 0 21 4>,
|
||||
<0 0 22 &gic 0 22 4>,
|
||||
<0 0 23 &gic 0 23 4>,
|
||||
<0 0 24 &gic 0 24 4>,
|
||||
<0 0 25 &gic 0 25 4>,
|
||||
<0 0 26 &gic 0 26 4>,
|
||||
<0 0 27 &gic 0 27 4>,
|
||||
<0 0 28 &gic 0 28 4>,
|
||||
<0 0 29 &gic 0 29 4>,
|
||||
<0 0 30 &gic 0 30 4>,
|
||||
<0 0 31 &gic 0 31 4>,
|
||||
<0 0 32 &gic 0 32 4>,
|
||||
<0 0 33 &gic 0 33 4>,
|
||||
<0 0 34 &gic 0 34 4>,
|
||||
<0 0 35 &gic 0 35 4>,
|
||||
<0 0 36 &gic 0 36 4>,
|
||||
<0 0 37 &gic 0 37 4>,
|
||||
<0 0 38 &gic 0 38 4>,
|
||||
<0 0 39 &gic 0 39 4>,
|
||||
<0 0 40 &gic 0 40 4>,
|
||||
<0 0 41 &gic 0 41 4>,
|
||||
<0 0 42 &gic 0 42 4>;
|
||||
|
||||
/include/ "rtsm_ve-motherboard.dtsi"
|
||||
};
|
||||
};
|
234
arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi
Normal file
234
arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi
Normal file
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* ARM Ltd. Fast Models
|
||||
*
|
||||
* Versatile Express (VE) system model
|
||||
* Motherboard component
|
||||
*
|
||||
* VEMotherBoard.lisa
|
||||
*/
|
||||
|
||||
motherboard {
|
||||
arm,v2m-memory-map = "rs1";
|
||||
compatible = "arm,vexpress,v2m-p1", "simple-bus";
|
||||
#address-cells = <2>; /* SMB chipselect number and offset */
|
||||
#size-cells = <1>;
|
||||
#interrupt-cells = <1>;
|
||||
ranges;
|
||||
|
||||
flash@0,00000000 {
|
||||
compatible = "arm,vexpress-flash", "cfi-flash";
|
||||
reg = <0 0x00000000 0x04000000>,
|
||||
<4 0x00000000 0x04000000>;
|
||||
bank-width = <4>;
|
||||
};
|
||||
|
||||
vram@2,00000000 {
|
||||
compatible = "arm,vexpress-vram";
|
||||
reg = <2 0x00000000 0x00800000>;
|
||||
};
|
||||
|
||||
ethernet@2,02000000 {
|
||||
compatible = "smsc,lan91c111";
|
||||
reg = <2 0x02000000 0x10000>;
|
||||
interrupts = <15>;
|
||||
};
|
||||
|
||||
v2m_clk24mhz: clk24mhz {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <24000000>;
|
||||
clock-output-names = "v2m:clk24mhz";
|
||||
};
|
||||
|
||||
v2m_refclk1mhz: refclk1mhz {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <1000000>;
|
||||
clock-output-names = "v2m:refclk1mhz";
|
||||
};
|
||||
|
||||
v2m_refclk32khz: refclk32khz {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <32768>;
|
||||
clock-output-names = "v2m:refclk32khz";
|
||||
};
|
||||
|
||||
iofpga@3,00000000 {
|
||||
compatible = "arm,amba-bus", "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0 3 0 0x200000>;
|
||||
|
||||
v2m_sysreg: sysreg@010000 {
|
||||
compatible = "arm,vexpress-sysreg";
|
||||
reg = <0x010000 0x1000>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
v2m_sysctl: sysctl@020000 {
|
||||
compatible = "arm,sp810", "arm,primecell";
|
||||
reg = <0x020000 0x1000>;
|
||||
clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>;
|
||||
clock-names = "refclk", "timclk", "apb_pclk";
|
||||
#clock-cells = <1>;
|
||||
clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
|
||||
};
|
||||
|
||||
aaci@040000 {
|
||||
compatible = "arm,pl041", "arm,primecell";
|
||||
reg = <0x040000 0x1000>;
|
||||
interrupts = <11>;
|
||||
clocks = <&v2m_clk24mhz>;
|
||||
clock-names = "apb_pclk";
|
||||
};
|
||||
|
||||
mmci@050000 {
|
||||
compatible = "arm,pl180", "arm,primecell";
|
||||
reg = <0x050000 0x1000>;
|
||||
interrupts = <9 10>;
|
||||
cd-gpios = <&v2m_sysreg 0 0>;
|
||||
wp-gpios = <&v2m_sysreg 1 0>;
|
||||
max-frequency = <12000000>;
|
||||
vmmc-supply = <&v2m_fixed_3v3>;
|
||||
clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
|
||||
clock-names = "mclk", "apb_pclk";
|
||||
};
|
||||
|
||||
kmi@060000 {
|
||||
compatible = "arm,pl050", "arm,primecell";
|
||||
reg = <0x060000 0x1000>;
|
||||
interrupts = <12>;
|
||||
clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
|
||||
clock-names = "KMIREFCLK", "apb_pclk";
|
||||
};
|
||||
|
||||
kmi@070000 {
|
||||
compatible = "arm,pl050", "arm,primecell";
|
||||
reg = <0x070000 0x1000>;
|
||||
interrupts = <13>;
|
||||
clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
|
||||
clock-names = "KMIREFCLK", "apb_pclk";
|
||||
};
|
||||
|
||||
v2m_serial0: uart@090000 {
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
reg = <0x090000 0x1000>;
|
||||
interrupts = <5>;
|
||||
clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
|
||||
clock-names = "uartclk", "apb_pclk";
|
||||
};
|
||||
|
||||
v2m_serial1: uart@0a0000 {
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
reg = <0x0a0000 0x1000>;
|
||||
interrupts = <6>;
|
||||
clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
|
||||
clock-names = "uartclk", "apb_pclk";
|
||||
};
|
||||
|
||||
v2m_serial2: uart@0b0000 {
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
reg = <0x0b0000 0x1000>;
|
||||
interrupts = <7>;
|
||||
clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
|
||||
clock-names = "uartclk", "apb_pclk";
|
||||
};
|
||||
|
||||
v2m_serial3: uart@0c0000 {
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
reg = <0x0c0000 0x1000>;
|
||||
interrupts = <8>;
|
||||
clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
|
||||
clock-names = "uartclk", "apb_pclk";
|
||||
};
|
||||
|
||||
wdt@0f0000 {
|
||||
compatible = "arm,sp805", "arm,primecell";
|
||||
reg = <0x0f0000 0x1000>;
|
||||
interrupts = <0>;
|
||||
clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>;
|
||||
clock-names = "wdogclk", "apb_pclk";
|
||||
};
|
||||
|
||||
v2m_timer01: timer@110000 {
|
||||
compatible = "arm,sp804", "arm,primecell";
|
||||
reg = <0x110000 0x1000>;
|
||||
interrupts = <2>;
|
||||
clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>;
|
||||
clock-names = "timclken1", "timclken2", "apb_pclk";
|
||||
};
|
||||
|
||||
v2m_timer23: timer@120000 {
|
||||
compatible = "arm,sp804", "arm,primecell";
|
||||
reg = <0x120000 0x1000>;
|
||||
interrupts = <3>;
|
||||
clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>;
|
||||
clock-names = "timclken1", "timclken2", "apb_pclk";
|
||||
};
|
||||
|
||||
rtc@170000 {
|
||||
compatible = "arm,pl031", "arm,primecell";
|
||||
reg = <0x170000 0x1000>;
|
||||
interrupts = <4>;
|
||||
clocks = <&v2m_clk24mhz>;
|
||||
clock-names = "apb_pclk";
|
||||
};
|
||||
|
||||
clcd@1f0000 {
|
||||
compatible = "arm,pl111", "arm,primecell";
|
||||
reg = <0x1f0000 0x1000>;
|
||||
interrupts = <14>;
|
||||
clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>;
|
||||
clock-names = "clcdclk", "apb_pclk";
|
||||
};
|
||||
};
|
||||
|
||||
v2m_fixed_3v3: fixedregulator@0 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "3V3";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
mcc {
|
||||
compatible = "arm,vexpress,config-bus", "simple-bus";
|
||||
arm,vexpress,config-bridge = <&v2m_sysreg>;
|
||||
|
||||
v2m_oscclk1: osc@1 {
|
||||
/* CLCD clock */
|
||||
compatible = "arm,vexpress-osc";
|
||||
arm,vexpress-sysreg,func = <1 1>;
|
||||
freq-range = <23750000 63500000>;
|
||||
#clock-cells = <0>;
|
||||
clock-output-names = "v2m:oscclk1";
|
||||
};
|
||||
|
||||
reset@0 {
|
||||
compatible = "arm,vexpress-reset";
|
||||
arm,vexpress-sysreg,func = <5 0>;
|
||||
};
|
||||
|
||||
muxfpga@0 {
|
||||
compatible = "arm,vexpress-muxfpga";
|
||||
arm,vexpress-sysreg,func = <7 0>;
|
||||
};
|
||||
|
||||
shutdown@0 {
|
||||
compatible = "arm,vexpress-shutdown";
|
||||
arm,vexpress-sysreg,func = <8 0>;
|
||||
};
|
||||
|
||||
reboot@0 {
|
||||
compatible = "arm,vexpress-reboot";
|
||||
arm,vexpress-sysreg,func = <9 0>;
|
||||
};
|
||||
|
||||
dvimode@0 {
|
||||
compatible = "arm,vexpress-dvimode";
|
||||
arm,vexpress-sysreg,func = <11 0>;
|
||||
};
|
||||
};
|
||||
};
|
13
arch/arm64/boot/dts/skeleton.dtsi
Normal file
13
arch/arm64/boot/dts/skeleton.dtsi
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Skeleton device tree; the bare minimum needed to boot; just include and
|
||||
* add a compatible value. The bootloader will typically populate the memory
|
||||
* node.
|
||||
*/
|
||||
|
||||
/ {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <1>;
|
||||
chosen { };
|
||||
aliases { };
|
||||
memory { device_type = "memory"; reg = <0 0 0>; };
|
||||
};
|
|
@ -23,6 +23,7 @@ CONFIG_MODULES=y
|
|||
CONFIG_MODULE_UNLOAD=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
CONFIG_ARCH_VEXPRESS=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_PREEMPT_VOLUNTARY=y
|
||||
CONFIG_CMDLINE="console=ttyAMA0"
|
||||
|
@ -47,11 +48,14 @@ CONFIG_BLK_DEV_SD=y
|
|||
# CONFIG_SCSI_LOWLEVEL is not set
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_MII=y
|
||||
CONFIG_SMC91X=y
|
||||
# CONFIG_WLAN is not set
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
# CONFIG_SERIO_I8042 is not set
|
||||
# CONFIG_SERIO_SERPORT is not set
|
||||
CONFIG_LEGACY_PTY_COUNT=16
|
||||
CONFIG_SERIAL_AMBA_PL011=y
|
||||
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_FB=y
|
||||
|
|
|
@ -39,7 +39,6 @@ generic-y += shmbuf.h
|
|||
generic-y += sizes.h
|
||||
generic-y += socket.h
|
||||
generic-y += sockios.h
|
||||
generic-y += string.h
|
||||
generic-y += switch_to.h
|
||||
generic-y += swab.h
|
||||
generic-y += termbits.h
|
||||
|
@ -49,4 +48,5 @@ generic-y += trace_clock.h
|
|||
generic-y += types.h
|
||||
generic-y += unaligned.h
|
||||
generic-y += user.h
|
||||
generic-y += vga.h
|
||||
generic-y += xor.h
|
||||
|
|
|
@ -32,6 +32,16 @@
|
|||
#error only <linux/bitops.h> can be included directly
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Little endian assembly atomic bitops.
|
||||
*/
|
||||
extern void set_bit(int nr, volatile unsigned long *p);
|
||||
extern void clear_bit(int nr, volatile unsigned long *p);
|
||||
extern void change_bit(int nr, volatile unsigned long *p);
|
||||
extern int test_and_set_bit(int nr, volatile unsigned long *p);
|
||||
extern int test_and_clear_bit(int nr, volatile unsigned long *p);
|
||||
extern int test_and_change_bit(int nr, volatile unsigned long *p);
|
||||
|
||||
#include <asm-generic/bitops/builtin-__ffs.h>
|
||||
#include <asm-generic/bitops/builtin-ffs.h>
|
||||
#include <asm-generic/bitops/builtin-__fls.h>
|
||||
|
@ -45,9 +55,13 @@
|
|||
#include <asm-generic/bitops/hweight.h>
|
||||
#include <asm-generic/bitops/lock.h>
|
||||
|
||||
#include <asm-generic/bitops/atomic.h>
|
||||
#include <asm-generic/bitops/non-atomic.h>
|
||||
#include <asm-generic/bitops/le.h>
|
||||
#include <asm-generic/bitops/ext2-atomic.h>
|
||||
|
||||
/*
|
||||
* Ext2 is defined to use little-endian byte ordering.
|
||||
*/
|
||||
#define ext2_set_bit_atomic(lock, nr, p) test_and_set_bit_le(nr, p)
|
||||
#define ext2_clear_bit_atomic(lock, nr, p) test_and_clear_bit_le(nr, p)
|
||||
|
||||
#endif /* __ASM_BITOPS_H */
|
||||
|
|
|
@ -170,4 +170,7 @@ static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old,
|
|||
(unsigned long)(n), \
|
||||
sizeof(*(ptr))))
|
||||
|
||||
#define cmpxchg64(ptr,o,n) cmpxchg((ptr),(o),(n))
|
||||
#define cmpxchg64_local(ptr,o,n) cmpxchg_local((ptr),(o),(n))
|
||||
|
||||
#endif /* __ASM_CMPXCHG_H */
|
||||
|
|
|
@ -35,14 +35,16 @@ typedef s32 compat_clock_t;
|
|||
typedef s32 compat_pid_t;
|
||||
typedef u32 __compat_uid_t;
|
||||
typedef u32 __compat_gid_t;
|
||||
typedef u16 __compat_uid16_t;
|
||||
typedef u16 __compat_gid16_t;
|
||||
typedef u32 __compat_uid32_t;
|
||||
typedef u32 __compat_gid32_t;
|
||||
typedef u32 compat_mode_t;
|
||||
typedef u16 compat_mode_t;
|
||||
typedef u32 compat_ino_t;
|
||||
typedef u32 compat_dev_t;
|
||||
typedef s32 compat_off_t;
|
||||
typedef s64 compat_loff_t;
|
||||
typedef s16 compat_nlink_t;
|
||||
typedef s32 compat_nlink_t;
|
||||
typedef u16 compat_ipc_pid_t;
|
||||
typedef s32 compat_daddr_t;
|
||||
typedef u32 compat_caddr_t;
|
||||
|
@ -50,9 +52,11 @@ typedef __kernel_fsid_t compat_fsid_t;
|
|||
typedef s32 compat_key_t;
|
||||
typedef s32 compat_timer_t;
|
||||
|
||||
typedef s16 compat_short_t;
|
||||
typedef s32 compat_int_t;
|
||||
typedef s32 compat_long_t;
|
||||
typedef s64 compat_s64;
|
||||
typedef u16 compat_ushort_t;
|
||||
typedef u32 compat_uint_t;
|
||||
typedef u32 compat_ulong_t;
|
||||
typedef u64 compat_u64;
|
||||
|
@ -72,20 +76,20 @@ struct compat_stat {
|
|||
compat_dev_t st_dev;
|
||||
compat_ino_t st_ino;
|
||||
compat_mode_t st_mode;
|
||||
compat_nlink_t st_nlink;
|
||||
__compat_uid32_t st_uid;
|
||||
__compat_gid32_t st_gid;
|
||||
compat_ushort_t st_nlink;
|
||||
__compat_uid16_t st_uid;
|
||||
__compat_gid16_t st_gid;
|
||||
compat_dev_t st_rdev;
|
||||
compat_off_t st_size;
|
||||
compat_off_t st_blksize;
|
||||
compat_off_t st_blocks;
|
||||
compat_time_t st_atime;
|
||||
u32 st_atime_nsec;
|
||||
compat_ulong_t st_atime_nsec;
|
||||
compat_time_t st_mtime;
|
||||
u32 st_mtime_nsec;
|
||||
compat_ulong_t st_mtime_nsec;
|
||||
compat_time_t st_ctime;
|
||||
u32 st_ctime_nsec;
|
||||
u32 __unused4[2];
|
||||
compat_ulong_t st_ctime_nsec;
|
||||
compat_ulong_t __unused4[2];
|
||||
};
|
||||
|
||||
struct compat_flock {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#define __ASM_CPUTYPE_H
|
||||
|
||||
#define ID_MIDR_EL1 "midr_el1"
|
||||
#define ID_MPIDR_EL1 "mpidr_el1"
|
||||
#define ID_CTR_EL0 "ctr_el0"
|
||||
|
||||
#define ID_AA64PFR0_EL1 "id_aa64pfr0_el1"
|
||||
|
@ -25,12 +26,24 @@
|
|||
#define ID_AA64ISAR0_EL1 "id_aa64isar0_el1"
|
||||
#define ID_AA64MMFR0_EL1 "id_aa64mmfr0_el1"
|
||||
|
||||
#define INVALID_HWID ULONG_MAX
|
||||
|
||||
#define MPIDR_HWID_BITMASK 0xff00ffffff
|
||||
|
||||
#define read_cpuid(reg) ({ \
|
||||
u64 __val; \
|
||||
asm("mrs %0, " reg : "=r" (__val)); \
|
||||
__val; \
|
||||
})
|
||||
|
||||
#define ARM_CPU_IMP_ARM 0x41
|
||||
|
||||
#define ARM_CPU_PART_AEM_V8 0xD0F0
|
||||
#define ARM_CPU_PART_FOUNDATION 0xD000
|
||||
#define ARM_CPU_PART_CORTEX_A57 0xD070
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* The CPU ID never changes at run time, so we might as well tell the
|
||||
* compiler that it's constant. Use this function to read the CPU ID
|
||||
|
@ -41,9 +54,26 @@ static inline u32 __attribute_const__ read_cpuid_id(void)
|
|||
return read_cpuid(ID_MIDR_EL1);
|
||||
}
|
||||
|
||||
static inline u64 __attribute_const__ read_cpuid_mpidr(void)
|
||||
{
|
||||
return read_cpuid(ID_MPIDR_EL1);
|
||||
}
|
||||
|
||||
static inline unsigned int __attribute_const__ read_cpuid_implementor(void)
|
||||
{
|
||||
return (read_cpuid_id() & 0xFF000000) >> 24;
|
||||
}
|
||||
|
||||
static inline unsigned int __attribute_const__ read_cpuid_part_number(void)
|
||||
{
|
||||
return (read_cpuid_id() & 0xFFF0);
|
||||
}
|
||||
|
||||
static inline u32 __attribute_const__ read_cpuid_cachetype(void)
|
||||
{
|
||||
return read_cpuid(ID_CTR_EL0);
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif
|
||||
|
|
55
arch/arm64/include/asm/esr.h
Normal file
55
arch/arm64/include/asm/esr.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2013 - ARM Ltd
|
||||
* Author: Marc Zyngier <marc.zyngier@arm.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ESR_H
|
||||
#define __ASM_ESR_H
|
||||
|
||||
#define ESR_EL1_EC_SHIFT (26)
|
||||
#define ESR_EL1_IL (1U << 25)
|
||||
|
||||
#define ESR_EL1_EC_UNKNOWN (0x00)
|
||||
#define ESR_EL1_EC_WFI (0x01)
|
||||
#define ESR_EL1_EC_CP15_32 (0x03)
|
||||
#define ESR_EL1_EC_CP15_64 (0x04)
|
||||
#define ESR_EL1_EC_CP14_MR (0x05)
|
||||
#define ESR_EL1_EC_CP14_LS (0x06)
|
||||
#define ESR_EL1_EC_FP_ASIMD (0x07)
|
||||
#define ESR_EL1_EC_CP10_ID (0x08)
|
||||
#define ESR_EL1_EC_CP14_64 (0x0C)
|
||||
#define ESR_EL1_EC_ILL_ISS (0x0E)
|
||||
#define ESR_EL1_EC_SVC32 (0x11)
|
||||
#define ESR_EL1_EC_SVC64 (0x15)
|
||||
#define ESR_EL1_EC_SYS64 (0x18)
|
||||
#define ESR_EL1_EC_IABT_EL0 (0x20)
|
||||
#define ESR_EL1_EC_IABT_EL1 (0x21)
|
||||
#define ESR_EL1_EC_PC_ALIGN (0x22)
|
||||
#define ESR_EL1_EC_DABT_EL0 (0x24)
|
||||
#define ESR_EL1_EC_DABT_EL1 (0x25)
|
||||
#define ESR_EL1_EC_SP_ALIGN (0x26)
|
||||
#define ESR_EL1_EC_FP_EXC32 (0x28)
|
||||
#define ESR_EL1_EC_FP_EXC64 (0x2C)
|
||||
#define ESR_EL1_EC_SERRROR (0x2F)
|
||||
#define ESR_EL1_EC_BREAKPT_EL0 (0x30)
|
||||
#define ESR_EL1_EC_BREAKPT_EL1 (0x31)
|
||||
#define ESR_EL1_EC_SOFTSTP_EL0 (0x32)
|
||||
#define ESR_EL1_EC_SOFTSTP_EL1 (0x33)
|
||||
#define ESR_EL1_EC_WATCHPT_EL0 (0x34)
|
||||
#define ESR_EL1_EC_WATCHPT_EL1 (0x35)
|
||||
#define ESR_EL1_EC_BKPT32 (0x38)
|
||||
#define ESR_EL1_EC_BRK64 (0x3C)
|
||||
|
||||
#endif /* __ASM_ESR_H */
|
|
@ -19,5 +19,6 @@
|
|||
#define __ASM_EXCEPTION_H
|
||||
|
||||
#define __exception __attribute__((section(".exception.text")))
|
||||
#define __exception_irq_entry __exception
|
||||
|
||||
#endif /* __ASM_EXCEPTION_H */
|
||||
|
|
|
@ -49,4 +49,9 @@ static inline void ack_bad_irq(unsigned int irq)
|
|||
|
||||
extern void handle_IRQ(unsigned int, struct pt_regs *);
|
||||
|
||||
/*
|
||||
* No arch-specific IRQ flags.
|
||||
*/
|
||||
#define set_irq_flags(irq, flags)
|
||||
|
||||
#endif /* __ASM_HARDIRQ_H */
|
||||
|
|
|
@ -92,10 +92,12 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
|
|||
#define readb_relaxed(c) ({ u8 __v = __raw_readb(c); __v; })
|
||||
#define readw_relaxed(c) ({ u16 __v = le16_to_cpu((__force __le16)__raw_readw(c)); __v; })
|
||||
#define readl_relaxed(c) ({ u32 __v = le32_to_cpu((__force __le32)__raw_readl(c)); __v; })
|
||||
#define readq_relaxed(c) ({ u64 __v = le64_to_cpu((__force __le64)__raw_readq(c)); __v; })
|
||||
|
||||
#define writeb_relaxed(v,c) ((void)__raw_writeb((v),(c)))
|
||||
#define writew_relaxed(v,c) ((void)__raw_writew((__force u16)cpu_to_le16(v),(c)))
|
||||
#define writel_relaxed(v,c) ((void)__raw_writel((__force u32)cpu_to_le32(v),(c)))
|
||||
#define writeq_relaxed(v,c) ((void)__raw_writeq((__force u64)cpu_to_le64(v),(c)))
|
||||
|
||||
/*
|
||||
* I/O memory access primitives. Reads are ordered relative to any
|
||||
|
@ -105,10 +107,12 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
|
|||
#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; })
|
||||
#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
|
||||
#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; })
|
||||
#define readq(c) ({ u64 __v = readq_relaxed(c); __iormb(); __v; })
|
||||
|
||||
#define writeb(v,c) ({ __iowmb(); writeb_relaxed((v),(c)); })
|
||||
#define writew(v,c) ({ __iowmb(); writew_relaxed((v),(c)); })
|
||||
#define writel(v,c) ({ __iowmb(); writel_relaxed((v),(c)); })
|
||||
#define writeq(v,c) ({ __iowmb(); writeq_relaxed((v),(c)); })
|
||||
|
||||
/*
|
||||
* I/O port access primitives.
|
||||
|
|
|
@ -4,5 +4,6 @@
|
|||
#include <asm-generic/irq.h>
|
||||
|
||||
extern void (*handle_arch_irq)(struct pt_regs *);
|
||||
extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
/*
|
||||
* Copyright (C) 2012 ARM Limited
|
||||
* Definitions specific to SMP platforms.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* Copyright (C) 2013 ARM Ltd.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
|
@ -14,12 +16,15 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/atomic.h>
|
||||
#ifndef __ASM_SMP_PLAT_H
|
||||
#define __ASM_SMP_PLAT_H
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = {
|
||||
[0 ... (ATOMIC_HASH_SIZE-1)] = __ARCH_SPIN_LOCK_UNLOCKED
|
||||
};
|
||||
#endif
|
||||
#include <asm/types.h>
|
||||
|
||||
/*
|
||||
* Logical CPU mapping.
|
||||
*/
|
||||
extern u64 __cpu_logical_map[NR_CPUS];
|
||||
#define cpu_logical_map(cpu) __cpu_logical_map[cpu]
|
||||
|
||||
#endif /* __ASM_SMP_PLAT_H */
|
37
arch/arm64/include/asm/string.h
Normal file
37
arch/arm64/include/asm/string.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) 2013 ARM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __ASM_STRING_H
|
||||
#define __ASM_STRING_H
|
||||
|
||||
#define __HAVE_ARCH_STRRCHR
|
||||
extern char *strrchr(const char *, int c);
|
||||
|
||||
#define __HAVE_ARCH_STRCHR
|
||||
extern char *strchr(const char *, int c);
|
||||
|
||||
#define __HAVE_ARCH_MEMCPY
|
||||
extern void *memcpy(void *, const void *, __kernel_size_t);
|
||||
|
||||
#define __HAVE_ARCH_MEMMOVE
|
||||
extern void *memmove(void *, const void *, __kernel_size_t);
|
||||
|
||||
#define __HAVE_ARCH_MEMCHR
|
||||
extern void *memchr(const void *, int, __kernel_size_t);
|
||||
|
||||
#define __HAVE_ARCH_MEMSET
|
||||
extern void *memset(void *, int, __kernel_size_t);
|
||||
|
||||
#endif
|
|
@ -39,10 +39,21 @@ EXPORT_SYMBOL(__copy_from_user);
|
|||
EXPORT_SYMBOL(__copy_to_user);
|
||||
EXPORT_SYMBOL(__clear_user);
|
||||
|
||||
/* bitops */
|
||||
#ifdef CONFIG_SMP
|
||||
EXPORT_SYMBOL(__atomic_hash);
|
||||
#endif
|
||||
|
||||
/* physical memory */
|
||||
EXPORT_SYMBOL(memstart_addr);
|
||||
|
||||
/* string / mem functions */
|
||||
EXPORT_SYMBOL(strchr);
|
||||
EXPORT_SYMBOL(strrchr);
|
||||
EXPORT_SYMBOL(memset);
|
||||
EXPORT_SYMBOL(memcpy);
|
||||
EXPORT_SYMBOL(memmove);
|
||||
EXPORT_SYMBOL(memchr);
|
||||
|
||||
/* atomic bitops */
|
||||
EXPORT_SYMBOL(set_bit);
|
||||
EXPORT_SYMBOL(test_and_set_bit);
|
||||
EXPORT_SYMBOL(clear_bit);
|
||||
EXPORT_SYMBOL(test_and_clear_bit);
|
||||
EXPORT_SYMBOL(change_bit);
|
||||
EXPORT_SYMBOL(test_and_change_bit);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/io.h>
|
||||
|
||||
#include <linux/amba/serial.h>
|
||||
#include <linux/serial_reg.h>
|
||||
|
||||
static void __iomem *early_base;
|
||||
static void (*printch)(char ch);
|
||||
|
@ -40,6 +41,37 @@ static void pl011_printch(char ch)
|
|||
;
|
||||
}
|
||||
|
||||
/*
|
||||
* Semihosting-based debug console
|
||||
*/
|
||||
static void smh_printch(char ch)
|
||||
{
|
||||
asm volatile("mov x1, %0\n"
|
||||
"mov x0, #3\n"
|
||||
"hlt 0xf000\n"
|
||||
: : "r" (&ch) : "x0", "x1", "memory");
|
||||
}
|
||||
|
||||
/*
|
||||
* 8250/16550 (8-bit aligned registers) single character TX.
|
||||
*/
|
||||
static void uart8250_8bit_printch(char ch)
|
||||
{
|
||||
while (!(readb_relaxed(early_base + UART_LSR) & UART_LSR_THRE))
|
||||
;
|
||||
writeb_relaxed(ch, early_base + UART_TX);
|
||||
}
|
||||
|
||||
/*
|
||||
* 8250/16550 (32-bit aligned registers) single character TX.
|
||||
*/
|
||||
static void uart8250_32bit_printch(char ch)
|
||||
{
|
||||
while (!(readl_relaxed(early_base + (UART_LSR << 2)) & UART_LSR_THRE))
|
||||
;
|
||||
writel_relaxed(ch, early_base + (UART_TX << 2));
|
||||
}
|
||||
|
||||
struct earlycon_match {
|
||||
const char *name;
|
||||
void (*printch)(char ch);
|
||||
|
@ -47,6 +79,9 @@ struct earlycon_match {
|
|||
|
||||
static const struct earlycon_match earlycon_match[] __initconst = {
|
||||
{ .name = "pl011", .printch = pl011_printch, },
|
||||
{ .name = "smh", .printch = smh_printch, },
|
||||
{ .name = "uart8250-8bit", .printch = uart8250_8bit_printch, },
|
||||
{ .name = "uart8250-32bit", .printch = uart8250_32bit_printch, },
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <asm/assembler.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/esr.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/unistd32.h>
|
||||
|
@ -239,18 +240,18 @@ ENDPROC(el1_error_invalid)
|
|||
el1_sync:
|
||||
kernel_entry 1
|
||||
mrs x1, esr_el1 // read the syndrome register
|
||||
lsr x24, x1, #26 // exception class
|
||||
cmp x24, #0x25 // data abort in EL1
|
||||
lsr x24, x1, #ESR_EL1_EC_SHIFT // exception class
|
||||
cmp x24, #ESR_EL1_EC_DABT_EL1 // data abort in EL1
|
||||
b.eq el1_da
|
||||
cmp x24, #0x18 // configurable trap
|
||||
cmp x24, #ESR_EL1_EC_SYS64 // configurable trap
|
||||
b.eq el1_undef
|
||||
cmp x24, #0x26 // stack alignment exception
|
||||
cmp x24, #ESR_EL1_EC_SP_ALIGN // stack alignment exception
|
||||
b.eq el1_sp_pc
|
||||
cmp x24, #0x22 // pc alignment exception
|
||||
cmp x24, #ESR_EL1_EC_PC_ALIGN // pc alignment exception
|
||||
b.eq el1_sp_pc
|
||||
cmp x24, #0x00 // unknown exception in EL1
|
||||
cmp x24, #ESR_EL1_EC_UNKNOWN // unknown exception in EL1
|
||||
b.eq el1_undef
|
||||
cmp x24, #0x30 // debug exception in EL1
|
||||
cmp x24, #ESR_EL1_EC_BREAKPT_EL1 // debug exception in EL1
|
||||
b.ge el1_dbg
|
||||
b el1_inv
|
||||
el1_da:
|
||||
|
@ -346,27 +347,27 @@ el1_preempt:
|
|||
el0_sync:
|
||||
kernel_entry 0
|
||||
mrs x25, esr_el1 // read the syndrome register
|
||||
lsr x24, x25, #26 // exception class
|
||||
cmp x24, #0x15 // SVC in 64-bit state
|
||||
lsr x24, x25, #ESR_EL1_EC_SHIFT // exception class
|
||||
cmp x24, #ESR_EL1_EC_SVC64 // SVC in 64-bit state
|
||||
b.eq el0_svc
|
||||
adr lr, ret_from_exception
|
||||
cmp x24, #0x24 // data abort in EL0
|
||||
cmp x24, #ESR_EL1_EC_DABT_EL0 // data abort in EL0
|
||||
b.eq el0_da
|
||||
cmp x24, #0x20 // instruction abort in EL0
|
||||
cmp x24, #ESR_EL1_EC_IABT_EL0 // instruction abort in EL0
|
||||
b.eq el0_ia
|
||||
cmp x24, #0x07 // FP/ASIMD access
|
||||
cmp x24, #ESR_EL1_EC_FP_ASIMD // FP/ASIMD access
|
||||
b.eq el0_fpsimd_acc
|
||||
cmp x24, #0x2c // FP/ASIMD exception
|
||||
cmp x24, #ESR_EL1_EC_FP_EXC64 // FP/ASIMD exception
|
||||
b.eq el0_fpsimd_exc
|
||||
cmp x24, #0x18 // configurable trap
|
||||
cmp x24, #ESR_EL1_EC_SYS64 // configurable trap
|
||||
b.eq el0_undef
|
||||
cmp x24, #0x26 // stack alignment exception
|
||||
cmp x24, #ESR_EL1_EC_SP_ALIGN // stack alignment exception
|
||||
b.eq el0_sp_pc
|
||||
cmp x24, #0x22 // pc alignment exception
|
||||
cmp x24, #ESR_EL1_EC_PC_ALIGN // pc alignment exception
|
||||
b.eq el0_sp_pc
|
||||
cmp x24, #0x00 // unknown exception in EL0
|
||||
cmp x24, #ESR_EL1_EC_UNKNOWN // unknown exception in EL0
|
||||
b.eq el0_undef
|
||||
cmp x24, #0x30 // debug exception in EL0
|
||||
cmp x24, #ESR_EL1_EC_BREAKPT_EL0 // debug exception in EL0
|
||||
b.ge el0_dbg
|
||||
b el0_inv
|
||||
|
||||
|
@ -375,21 +376,21 @@ el0_sync:
|
|||
el0_sync_compat:
|
||||
kernel_entry 0, 32
|
||||
mrs x25, esr_el1 // read the syndrome register
|
||||
lsr x24, x25, #26 // exception class
|
||||
cmp x24, #0x11 // SVC in 32-bit state
|
||||
lsr x24, x25, #ESR_EL1_EC_SHIFT // exception class
|
||||
cmp x24, #ESR_EL1_EC_SVC32 // SVC in 32-bit state
|
||||
b.eq el0_svc_compat
|
||||
adr lr, ret_from_exception
|
||||
cmp x24, #0x24 // data abort in EL0
|
||||
cmp x24, #ESR_EL1_EC_DABT_EL0 // data abort in EL0
|
||||
b.eq el0_da
|
||||
cmp x24, #0x20 // instruction abort in EL0
|
||||
cmp x24, #ESR_EL1_EC_IABT_EL0 // instruction abort in EL0
|
||||
b.eq el0_ia
|
||||
cmp x24, #0x07 // FP/ASIMD access
|
||||
cmp x24, #ESR_EL1_EC_FP_ASIMD // FP/ASIMD access
|
||||
b.eq el0_fpsimd_acc
|
||||
cmp x24, #0x28 // FP/ASIMD exception
|
||||
cmp x24, #ESR_EL1_EC_FP_EXC32 // FP/ASIMD exception
|
||||
b.eq el0_fpsimd_exc
|
||||
cmp x24, #0x00 // unknown exception in EL0
|
||||
cmp x24, #ESR_EL1_EC_UNKNOWN // unknown exception in EL0
|
||||
b.eq el0_undef
|
||||
cmp x24, #0x30 // debug exception in EL0
|
||||
cmp x24, #ESR_EL1_EC_BREAKPT_EL0 // debug exception in EL0
|
||||
b.ge el0_dbg
|
||||
b el0_inv
|
||||
el0_svc_compat:
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <asm/assembler.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/cputype.h>
|
||||
#include <asm/memory.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/pgtable-hwdef.h>
|
||||
|
@ -229,7 +230,8 @@ ENTRY(secondary_holding_pen)
|
|||
bl __calc_phys_offset // x24=phys offset
|
||||
bl el2_setup // Drop to EL1
|
||||
mrs x0, mpidr_el1
|
||||
and x0, x0, #15 // CPU number
|
||||
ldr x1, =MPIDR_HWID_BITMASK
|
||||
and x0, x0, x1
|
||||
adr x1, 1b
|
||||
ldp x2, x3, [x1]
|
||||
sub x1, x1, x2
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <linux/irq.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/ratelimit.h>
|
||||
|
||||
|
@ -67,18 +67,17 @@ void handle_IRQ(unsigned int irq, struct pt_regs *regs)
|
|||
set_irq_regs(old_regs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt controllers supported by the kernel.
|
||||
*/
|
||||
static const struct of_device_id intctrl_of_match[] __initconst = {
|
||||
/* IRQ controllers { .compatible, .data } info to go here */
|
||||
{}
|
||||
};
|
||||
void __init set_handle_irq(void (*handle_irq)(struct pt_regs *))
|
||||
{
|
||||
if (handle_arch_irq)
|
||||
return;
|
||||
|
||||
handle_arch_irq = handle_irq;
|
||||
}
|
||||
|
||||
void __init init_IRQ(void)
|
||||
{
|
||||
of_irq_init(intctrl_of_match);
|
||||
|
||||
irqchip_init();
|
||||
if (!handle_arch_irq)
|
||||
panic("No interrupt controller found.");
|
||||
}
|
||||
|
|
|
@ -278,11 +278,17 @@ struct task_struct *__switch_to(struct task_struct *prev,
|
|||
fpsimd_thread_switch(next);
|
||||
tls_thread_switch(next);
|
||||
hw_breakpoint_thread_switch(next);
|
||||
contextidr_thread_switch(next);
|
||||
|
||||
/*
|
||||
* Complete any pending TLB or cache maintenance on this CPU in case
|
||||
* the thread migrates to a different CPU.
|
||||
*/
|
||||
dsb();
|
||||
|
||||
/* the actual thread switch */
|
||||
last = cpu_switch_to(prev, next);
|
||||
|
||||
contextidr_thread_switch(next);
|
||||
return last;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/kexec.h>
|
||||
#include <linux/crash_dump.h>
|
||||
#include <linux/root_dev.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/smp.h>
|
||||
|
@ -46,6 +47,7 @@
|
|||
#include <asm/cputable.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/traps.h>
|
||||
|
@ -240,6 +242,8 @@ static void __init request_standard_resources(void)
|
|||
}
|
||||
}
|
||||
|
||||
u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID };
|
||||
|
||||
void __init setup_arch(char **cmdline_p)
|
||||
{
|
||||
setup_processor();
|
||||
|
@ -264,6 +268,7 @@ void __init setup_arch(char **cmdline_p)
|
|||
|
||||
psci_init();
|
||||
|
||||
cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
|
||||
#ifdef CONFIG_SMP
|
||||
smp_init_cpus();
|
||||
#endif
|
||||
|
@ -277,6 +282,13 @@ void __init setup_arch(char **cmdline_p)
|
|||
#endif
|
||||
}
|
||||
|
||||
static int __init arm64_of_clk_init(void)
|
||||
{
|
||||
of_clk_init(NULL);
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(arm64_of_clk_init);
|
||||
|
||||
static DEFINE_PER_CPU(struct cpu, cpu_data);
|
||||
|
||||
static int __init topology_init(void)
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <asm/pgtable.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
@ -53,7 +54,7 @@
|
|||
* where to place its SVC stack
|
||||
*/
|
||||
struct secondary_data secondary_data;
|
||||
volatile unsigned long secondary_holding_pen_release = -1;
|
||||
volatile unsigned long secondary_holding_pen_release = INVALID_HWID;
|
||||
|
||||
enum ipi_msg_type {
|
||||
IPI_RESCHEDULE,
|
||||
|
@ -70,7 +71,7 @@ static DEFINE_RAW_SPINLOCK(boot_lock);
|
|||
* in coherency or not. This is necessary for the hotplug code to work
|
||||
* reliably.
|
||||
*/
|
||||
static void __cpuinit write_pen_release(int val)
|
||||
static void __cpuinit write_pen_release(u64 val)
|
||||
{
|
||||
void *start = (void *)&secondary_holding_pen_release;
|
||||
unsigned long size = sizeof(secondary_holding_pen_release);
|
||||
|
@ -96,7 +97,7 @@ static int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
|
|||
/*
|
||||
* Update the pen release flag.
|
||||
*/
|
||||
write_pen_release(cpu);
|
||||
write_pen_release(cpu_logical_map(cpu));
|
||||
|
||||
/*
|
||||
* Send an event, causing the secondaries to read pen_release.
|
||||
|
@ -105,7 +106,7 @@ static int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
|
|||
|
||||
timeout = jiffies + (1 * HZ);
|
||||
while (time_before(jiffies, timeout)) {
|
||||
if (secondary_holding_pen_release == -1UL)
|
||||
if (secondary_holding_pen_release == INVALID_HWID)
|
||||
break;
|
||||
udelay(10);
|
||||
}
|
||||
|
@ -116,7 +117,7 @@ static int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
|
|||
*/
|
||||
raw_spin_unlock(&boot_lock);
|
||||
|
||||
return secondary_holding_pen_release != -1 ? -ENOSYS : 0;
|
||||
return secondary_holding_pen_release != INVALID_HWID ? -ENOSYS : 0;
|
||||
}
|
||||
|
||||
static DECLARE_COMPLETION(cpu_running);
|
||||
|
@ -190,7 +191,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
|
|||
* Let the primary processor know we're out of the
|
||||
* pen, then head off into the C entry point
|
||||
*/
|
||||
write_pen_release(-1);
|
||||
write_pen_release(INVALID_HWID);
|
||||
|
||||
/*
|
||||
* Synchronise with the boot thread.
|
||||
|
@ -244,11 +245,11 @@ static const struct smp_enable_ops *smp_enable_ops[NR_CPUS];
|
|||
|
||||
static const struct smp_enable_ops * __init smp_get_enable_ops(const char *name)
|
||||
{
|
||||
const struct smp_enable_ops *ops = enable_ops[0];
|
||||
const struct smp_enable_ops **ops = enable_ops;
|
||||
|
||||
while (ops) {
|
||||
if (!strcmp(name, ops->name))
|
||||
return ops;
|
||||
while (*ops) {
|
||||
if (!strcmp(name, (*ops)->name))
|
||||
return *ops;
|
||||
|
||||
ops++;
|
||||
}
|
||||
|
@ -257,15 +258,80 @@ static const struct smp_enable_ops * __init smp_get_enable_ops(const char *name)
|
|||
}
|
||||
|
||||
/*
|
||||
* Enumerate the possible CPU set from the device tree.
|
||||
* Enumerate the possible CPU set from the device tree and build the
|
||||
* cpu logical map array containing MPIDR values related to logical
|
||||
* cpus. Assumes that cpu_logical_map(0) has already been initialized.
|
||||
*/
|
||||
void __init smp_init_cpus(void)
|
||||
{
|
||||
const char *enable_method;
|
||||
struct device_node *dn = NULL;
|
||||
int cpu = 0;
|
||||
int i, cpu = 1;
|
||||
bool bootcpu_valid = false;
|
||||
|
||||
while ((dn = of_find_node_by_type(dn, "cpu"))) {
|
||||
const u32 *cell;
|
||||
u64 hwid;
|
||||
|
||||
/*
|
||||
* A cpu node with missing "reg" property is
|
||||
* considered invalid to build a cpu_logical_map
|
||||
* entry.
|
||||
*/
|
||||
cell = of_get_property(dn, "reg", NULL);
|
||||
if (!cell) {
|
||||
pr_err("%s: missing reg property\n", dn->full_name);
|
||||
goto next;
|
||||
}
|
||||
hwid = of_read_number(cell, of_n_addr_cells(dn));
|
||||
|
||||
/*
|
||||
* Non affinity bits must be set to 0 in the DT
|
||||
*/
|
||||
if (hwid & ~MPIDR_HWID_BITMASK) {
|
||||
pr_err("%s: invalid reg property\n", dn->full_name);
|
||||
goto next;
|
||||
}
|
||||
|
||||
/*
|
||||
* Duplicate MPIDRs are a recipe for disaster. Scan
|
||||
* all initialized entries and check for
|
||||
* duplicates. If any is found just ignore the cpu.
|
||||
* cpu_logical_map was initialized to INVALID_HWID to
|
||||
* avoid matching valid MPIDR values.
|
||||
*/
|
||||
for (i = 1; (i < cpu) && (i < NR_CPUS); i++) {
|
||||
if (cpu_logical_map(i) == hwid) {
|
||||
pr_err("%s: duplicate cpu reg properties in the DT\n",
|
||||
dn->full_name);
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The numbering scheme requires that the boot CPU
|
||||
* must be assigned logical id 0. Record it so that
|
||||
* the logical map built from DT is validated and can
|
||||
* be used.
|
||||
*/
|
||||
if (hwid == cpu_logical_map(0)) {
|
||||
if (bootcpu_valid) {
|
||||
pr_err("%s: duplicate boot cpu reg property in DT\n",
|
||||
dn->full_name);
|
||||
goto next;
|
||||
}
|
||||
|
||||
bootcpu_valid = true;
|
||||
|
||||
/*
|
||||
* cpu_logical_map has already been
|
||||
* initialized and the boot cpu doesn't need
|
||||
* the enable-method so continue without
|
||||
* incrementing cpu.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cpu >= NR_CPUS)
|
||||
goto next;
|
||||
|
||||
|
@ -274,22 +340,24 @@ void __init smp_init_cpus(void)
|
|||
*/
|
||||
enable_method = of_get_property(dn, "enable-method", NULL);
|
||||
if (!enable_method) {
|
||||
pr_err("CPU %d: missing enable-method property\n", cpu);
|
||||
pr_err("%s: missing enable-method property\n",
|
||||
dn->full_name);
|
||||
goto next;
|
||||
}
|
||||
|
||||
smp_enable_ops[cpu] = smp_get_enable_ops(enable_method);
|
||||
|
||||
if (!smp_enable_ops[cpu]) {
|
||||
pr_err("CPU %d: invalid enable-method property: %s\n",
|
||||
cpu, enable_method);
|
||||
pr_err("%s: invalid enable-method property: %s\n",
|
||||
dn->full_name, enable_method);
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (smp_enable_ops[cpu]->init_cpu(dn, cpu))
|
||||
goto next;
|
||||
|
||||
set_cpu_possible(cpu, true);
|
||||
pr_debug("cpu logical map 0x%llx\n", hwid);
|
||||
cpu_logical_map(cpu) = hwid;
|
||||
next:
|
||||
cpu++;
|
||||
}
|
||||
|
@ -298,6 +366,19 @@ next:
|
|||
if (cpu > NR_CPUS)
|
||||
pr_warning("no. of cores (%d) greater than configured maximum of %d - clipping\n",
|
||||
cpu, NR_CPUS);
|
||||
|
||||
if (!bootcpu_valid) {
|
||||
pr_err("DT missing boot CPU MPIDR, not enabling secondaries\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* All the cpus that made it to the cpu_logical_map have been
|
||||
* validated so set them as possible cpus.
|
||||
*/
|
||||
for (i = 0; i < NR_CPUS; i++)
|
||||
if (cpu_logical_map(i) != INVALID_HWID)
|
||||
set_cpu_possible(i, true);
|
||||
}
|
||||
|
||||
void __init smp_prepare_cpus(unsigned int max_cpus)
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/smp.h>
|
||||
|
||||
#include <asm/psci.h>
|
||||
#include <asm/smp_plat.h>
|
||||
|
||||
static int __init smp_psci_init_cpu(struct device_node *dn, int cpu)
|
||||
{
|
||||
|
@ -36,7 +37,7 @@ static int __init smp_psci_prepare_cpu(int cpu)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = psci_ops.cpu_on(cpu, __pa(secondary_holding_pen));
|
||||
err = psci_ops.cpu_on(cpu_logical_map(cpu), __pa(secondary_holding_pen));
|
||||
if (err) {
|
||||
pr_err("psci: failed to boot CPU%d (%d)\n", cpu, err);
|
||||
return err;
|
||||
|
@ -47,6 +48,6 @@ static int __init smp_psci_prepare_cpu(int cpu)
|
|||
|
||||
const struct smp_enable_ops smp_psci_ops __initconst = {
|
||||
.name = "psci",
|
||||
.init_cpu = smp_psci_init_cpu,
|
||||
.init_cpu = smp_psci_init_cpu,
|
||||
.prepare_cpu = smp_psci_prepare_cpu,
|
||||
};
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
lib-y := bitops.o delay.o \
|
||||
strncpy_from_user.o strnlen_user.o clear_user.o \
|
||||
copy_from_user.o copy_to_user.o copy_in_user.o \
|
||||
copy_page.o clear_page.o
|
||||
copy_page.o clear_page.o \
|
||||
memchr.o memcpy.o memmove.o memset.o \
|
||||
strchr.o strrchr.o
|
||||
|
|
68
arch/arm64/lib/bitops.S
Normal file
68
arch/arm64/lib/bitops.S
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Based on arch/arm/lib/bitops.h
|
||||
*
|
||||
* Copyright (C) 2013 ARM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
/*
|
||||
* x0: bits 5:0 bit offset
|
||||
* bits 63:6 word offset
|
||||
* x1: address
|
||||
*/
|
||||
.macro bitop, name, instr
|
||||
ENTRY( \name )
|
||||
and x3, x0, #63 // Get bit offset
|
||||
eor x0, x0, x3 // Clear low bits
|
||||
mov x2, #1
|
||||
add x1, x1, x0, lsr #3 // Get word offset
|
||||
lsl x3, x2, x3 // Create mask
|
||||
1: ldxr x2, [x1]
|
||||
\instr x2, x2, x3
|
||||
stxr w0, x2, [x1]
|
||||
cbnz w0, 1b
|
||||
ret
|
||||
ENDPROC(\name )
|
||||
.endm
|
||||
|
||||
.macro testop, name, instr
|
||||
ENTRY( \name )
|
||||
and x3, x0, #63 // Get bit offset
|
||||
eor x0, x0, x3 // Clear low bits
|
||||
mov x2, #1
|
||||
add x1, x1, x0, lsr #3 // Get word offset
|
||||
lsl x4, x2, x3 // Create mask
|
||||
1: ldaxr x2, [x1]
|
||||
lsr x0, x2, x3 // Save old value of bit
|
||||
\instr x2, x2, x4 // toggle bit
|
||||
stlxr w5, x2, [x1]
|
||||
cbnz w5, 1b
|
||||
and x0, x0, #1
|
||||
3: ret
|
||||
ENDPROC(\name )
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Atomic bit operations.
|
||||
*/
|
||||
bitop change_bit, eor
|
||||
bitop clear_bit, bic
|
||||
bitop set_bit, orr
|
||||
|
||||
testop test_and_change_bit, eor
|
||||
testop test_and_clear_bit, bic
|
||||
testop test_and_set_bit, orr
|
44
arch/arm64/lib/memchr.S
Normal file
44
arch/arm64/lib/memchr.S
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Based on arch/arm/lib/memchr.S
|
||||
*
|
||||
* Copyright (C) 1995-2000 Russell King
|
||||
* Copyright (C) 2013 ARM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
/*
|
||||
* Find a character in an area of memory.
|
||||
*
|
||||
* Parameters:
|
||||
* x0 - buf
|
||||
* x1 - c
|
||||
* x2 - n
|
||||
* Returns:
|
||||
* x0 - address of first occurrence of 'c' or 0
|
||||
*/
|
||||
ENTRY(memchr)
|
||||
and w1, w1, #0xff
|
||||
1: subs x2, x2, #1
|
||||
b.mi 2f
|
||||
ldrb w3, [x0], #1
|
||||
cmp w3, w1
|
||||
b.ne 1b
|
||||
sub x0, x0, #1
|
||||
ret
|
||||
2: mov x0, #0
|
||||
ret
|
||||
ENDPROC(memchr)
|
53
arch/arm64/lib/memcpy.S
Normal file
53
arch/arm64/lib/memcpy.S
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) 2013 ARM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
/*
|
||||
* Copy a buffer from src to dest (alignment handled by the hardware)
|
||||
*
|
||||
* Parameters:
|
||||
* x0 - dest
|
||||
* x1 - src
|
||||
* x2 - n
|
||||
* Returns:
|
||||
* x0 - dest
|
||||
*/
|
||||
ENTRY(memcpy)
|
||||
mov x4, x0
|
||||
subs x2, x2, #8
|
||||
b.mi 2f
|
||||
1: ldr x3, [x1], #8
|
||||
subs x2, x2, #8
|
||||
str x3, [x4], #8
|
||||
b.pl 1b
|
||||
2: adds x2, x2, #4
|
||||
b.mi 3f
|
||||
ldr w3, [x1], #4
|
||||
sub x2, x2, #4
|
||||
str w3, [x4], #4
|
||||
3: adds x2, x2, #2
|
||||
b.mi 4f
|
||||
ldrh w3, [x1], #2
|
||||
sub x2, x2, #2
|
||||
strh w3, [x4], #2
|
||||
4: adds x2, x2, #1
|
||||
b.mi 5f
|
||||
ldrb w3, [x1]
|
||||
strb w3, [x4]
|
||||
5: ret
|
||||
ENDPROC(memcpy)
|
57
arch/arm64/lib/memmove.S
Normal file
57
arch/arm64/lib/memmove.S
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2013 ARM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
/*
|
||||
* Move a buffer from src to test (alignment handled by the hardware).
|
||||
* If dest <= src, call memcpy, otherwise copy in reverse order.
|
||||
*
|
||||
* Parameters:
|
||||
* x0 - dest
|
||||
* x1 - src
|
||||
* x2 - n
|
||||
* Returns:
|
||||
* x0 - dest
|
||||
*/
|
||||
ENTRY(memmove)
|
||||
cmp x0, x1
|
||||
b.ls memcpy
|
||||
add x4, x0, x2
|
||||
add x1, x1, x2
|
||||
subs x2, x2, #8
|
||||
b.mi 2f
|
||||
1: ldr x3, [x1, #-8]!
|
||||
subs x2, x2, #8
|
||||
str x3, [x4, #-8]!
|
||||
b.pl 1b
|
||||
2: adds x2, x2, #4
|
||||
b.mi 3f
|
||||
ldr w3, [x1, #-4]!
|
||||
sub x2, x2, #4
|
||||
str w3, [x4, #-4]!
|
||||
3: adds x2, x2, #2
|
||||
b.mi 4f
|
||||
ldrh w3, [x1, #-2]!
|
||||
sub x2, x2, #2
|
||||
strh w3, [x4, #-2]!
|
||||
4: adds x2, x2, #1
|
||||
b.mi 5f
|
||||
ldrb w3, [x1, #-1]
|
||||
strb w3, [x4, #-1]
|
||||
5: ret
|
||||
ENDPROC(memmove)
|
53
arch/arm64/lib/memset.S
Normal file
53
arch/arm64/lib/memset.S
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) 2013 ARM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
/*
|
||||
* Fill in the buffer with character c (alignment handled by the hardware)
|
||||
*
|
||||
* Parameters:
|
||||
* x0 - buf
|
||||
* x1 - c
|
||||
* x2 - n
|
||||
* Returns:
|
||||
* x0 - buf
|
||||
*/
|
||||
ENTRY(memset)
|
||||
mov x4, x0
|
||||
and w1, w1, #0xff
|
||||
orr w1, w1, w1, lsl #8
|
||||
orr w1, w1, w1, lsl #16
|
||||
orr x1, x1, x1, lsl #32
|
||||
subs x2, x2, #8
|
||||
b.mi 2f
|
||||
1: str x1, [x4], #8
|
||||
subs x2, x2, #8
|
||||
b.pl 1b
|
||||
2: adds x2, x2, #4
|
||||
b.mi 3f
|
||||
sub x2, x2, #4
|
||||
str w1, [x4], #4
|
||||
3: adds x2, x2, #2
|
||||
b.mi 4f
|
||||
sub x2, x2, #2
|
||||
strh w1, [x4], #2
|
||||
4: adds x2, x2, #1
|
||||
b.mi 5f
|
||||
strb w1, [x4]
|
||||
5: ret
|
||||
ENDPROC(memset)
|
42
arch/arm64/lib/strchr.S
Normal file
42
arch/arm64/lib/strchr.S
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Based on arch/arm/lib/strchr.S
|
||||
*
|
||||
* Copyright (C) 1995-2000 Russell King
|
||||
* Copyright (C) 2013 ARM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
/*
|
||||
* Find the first occurrence of a character in a string.
|
||||
*
|
||||
* Parameters:
|
||||
* x0 - str
|
||||
* x1 - c
|
||||
* Returns:
|
||||
* x0 - address of first occurrence of 'c' or 0
|
||||
*/
|
||||
ENTRY(strchr)
|
||||
and w1, w1, #0xff
|
||||
1: ldrb w2, [x0], #1
|
||||
cmp w2, w1
|
||||
ccmp w2, wzr, #4, ne
|
||||
b.ne 1b
|
||||
sub x0, x0, #1
|
||||
cmp w2, w1
|
||||
csel x0, x0, xzr, eq
|
||||
ret
|
||||
ENDPROC(strchr)
|
43
arch/arm64/lib/strrchr.S
Normal file
43
arch/arm64/lib/strrchr.S
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Based on arch/arm/lib/strrchr.S
|
||||
*
|
||||
* Copyright (C) 1995-2000 Russell King
|
||||
* Copyright (C) 2013 ARM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
/*
|
||||
* Find the last occurrence of a character in a string.
|
||||
*
|
||||
* Parameters:
|
||||
* x0 - str
|
||||
* x1 - c
|
||||
* Returns:
|
||||
* x0 - address of last occurrence of 'c' or 0
|
||||
*/
|
||||
ENTRY(strrchr)
|
||||
mov x3, #0
|
||||
and w1, w1, #0xff
|
||||
1: ldrb w2, [x0], #1
|
||||
cbz w2, 2f
|
||||
cmp w2, w1
|
||||
b.ne 1b
|
||||
sub x3, x0, #1
|
||||
b 1b
|
||||
2: mov x0, x3
|
||||
ret
|
||||
ENDPROC(strrchr)
|
|
@ -57,16 +57,16 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
|
|||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
|
||||
if (pgd_none_or_clear_bad(pgd))
|
||||
if (pgd_none(*pgd) || pgd_bad(*pgd))
|
||||
break;
|
||||
|
||||
pud = pud_offset(pgd, addr);
|
||||
if (pud_none_or_clear_bad(pud))
|
||||
if (pud_none(*pud) || pud_bad(*pud))
|
||||
break;
|
||||
|
||||
pmd = pmd_offset(pud, addr);
|
||||
printk(", *pmd=%016llx", pmd_val(*pmd));
|
||||
if (pmd_none_or_clear_bad(pmd))
|
||||
if (pmd_none(*pmd) || pmd_bad(*pmd))
|
||||
break;
|
||||
|
||||
pte = pte_offset_map(pmd, addr);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
config NET_VENDOR_SMSC
|
||||
bool "SMC (SMSC)/Western Digital devices"
|
||||
default y
|
||||
depends on ARM || ISA || MAC || ARM || MIPS || M32R || SUPERH || \
|
||||
depends on ARM || ISA || MAC || ARM64 || MIPS || M32R || SUPERH || \
|
||||
BLACKFIN || MN10300 || COLDFIRE || PCI || PCMCIA
|
||||
---help---
|
||||
If you have a network (Ethernet) card belonging to this class, say Y
|
||||
|
@ -40,7 +40,7 @@ config SMC91X
|
|||
select NET_CORE
|
||||
select MII
|
||||
depends on (ARM || M32R || SUPERH || MIPS || BLACKFIN || \
|
||||
MN10300 || COLDFIRE)
|
||||
MN10300 || COLDFIRE || ARM64)
|
||||
---help---
|
||||
This is a driver for SMC's 91x series of Ethernet chipsets,
|
||||
including the SMC91C94 and the SMC91C111. Say Y if you want it
|
||||
|
|
Loading…
Reference in a new issue