Pull more RISC-V updates from Palmer Dabbelt: - DT updates for the PolarFire SOC - a fix to correct the handling of write-only mappings - m{vetndor,arcd,imp}id is now in /proc/cpuinfo - the SiFive L2 cache controller support has been refactored to also support L3 caches - misc fixes, cleanups and improvements throughout the tree * tag 'riscv-for-linus-6.1-mw2' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: (42 commits) MAINTAINERS: add RISC-V's patchwork RISC-V: Make port I/O string accessors actually work riscv: enable software resend of irqs RISC-V: Re-enable counter access from userspace riscv: vdso: fix NULL deference in vdso_join_timens() when vfork riscv: Add cache information in AUX vector soc: sifive: ccache: define the macro for the register shifts soc: sifive: ccache: use pr_fmt() to remove CCACHE: prefixes soc: sifive: ccache: reduce printing on init soc: sifive: ccache: determine the cache level from dts soc: sifive: ccache: Rename SiFive L2 cache to Composable cache. dt-bindings: sifive-ccache: change Sifive L2 cache to Composable cache riscv: check for kernel config option in t-head memory types errata riscv: use BIT() marco for cpufeature probing riscv: use BIT() macros in t-head errata init riscv: drop some idefs from CMO initialization riscv: cleanup svpbmt cpufeature probing riscv: Pass -mno-relax only on lld < 15.0.0 RISC-V: Avoid dereferening NULL regs in die() dt-bindings: riscv: add new riscv,isa strings for emulators ...
Unified · Split
| @@ -66,6 +66,11 @@ properties: · 65 unmodified lines | |||
| 66 | - enum: | 66 | - enum: |
| 67 | - allwinner,sun20i-d1-plic | 67 | - allwinner,sun20i-d1-plic |
| 68 | - const: thead,c900-plic | 68 | - const: thead,c900-plic |
| 69 | - items: | ||
| 70 | - const: sifive,plic-1.0.0 | ||
| 71 | - const: riscv,plic0 | ||
| 72 | deprecated: true | ||
| 73 | description: For the QEMU virt machine only | ||
| 69 | 74 | ||
| 70 | reg: | 75 | reg: |
| 71 | maxItems: 1 | 76 | maxItems: 1 |
| @@ -9,6 +9,7 @@ title: RISC-V bindings for 'cpus' DT nodes · 8 unmodified lines | |||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Paul Walmsley <paul.walmsley@sifive.com> | 10 | - Paul Walmsley <paul.walmsley@sifive.com> |
| 11 | - Palmer Dabbelt <palmer@sifive.com> | 11 | - Palmer Dabbelt <palmer@sifive.com> |
| 12 | - Conor Dooley <conor@kernel.org> | ||
| 12 | 13 | ||
| 13 | description: | | 14 | description: | |
| 14 | This document uses some terminology common to the RISC-V community | 15 | This document uses some terminology common to the RISC-V community |
| @@ -79,9 +80,7 @@ properties: · 64 unmodified lines | |||
| 79 | insensitive, letters in the riscv,isa string must be all | 80 | insensitive, letters in the riscv,isa string must be all |
| 80 | lowercase to simplify parsing. | 81 | lowercase to simplify parsing. |
| 81 | $ref: "/schemas/types.yaml#/definitions/string" | 82 | $ref: "/schemas/types.yaml#/definitions/string" |
| 82 | enum: | 83 | pattern: ^rv(?:64|32)imaf?d?q?c?b?v?k?h?(?:_[hsxz](?:[a-z])+)*$ |
| 83 | - rv64imac | ||
| 84 | - rv64imafdc | ||
| 85 | 84 | ||
| 86 | # RISC-V requires 'timebase-frequency' in /cpus, so disallow it here | 85 | # RISC-V requires 'timebase-frequency' in /cpus, so disallow it here |
| 87 | timebase-frequency: false | 86 | timebase-frequency: false |
| @@ -7,8 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | |||
| 7 | title: Microchip PolarFire SoC-based boards | 7 | title: Microchip PolarFire SoC-based boards |
| 8 | 8 | ||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Cyril Jean <Cyril.Jean@microchip.com> | 10 | - Conor Dooley <conor.dooley@microchip.com> |
| 11 | - Lewis Hanly <lewis.hanly@microchip.com> | 11 | - Daire McNamara <daire.mcnamara@microchip.com> |
| 12 | 12 | ||
| 13 | description: | 13 | description: |
| 14 | Microchip PolarFire SoC-based boards | 14 | Microchip PolarFire SoC-based boards |
| @@ -17,12 +17,20 @@ properties: · 2 unmodified lines | |||
| 17 | $nodename: | 17 | $nodename: |
| 18 | const: '/' | 18 | const: '/' |
| 19 | compatible: | 19 | compatible: |
| 20 | items: | 20 | oneOf: |
| 21 | - enum: | 21 | - items: |
| 22 | - microchip,mpfs-icicle-kit | 22 | - enum: |
| 23 | - microchip,mpfs-icicle-reference-rtlv2203 | 23 | - microchip,mpfs-icicle-reference-rtlv2203 |
| 24 | - sundance,polarberry | 24 | - microchip,mpfs-icicle-reference-rtlv2210 |
| 25 | - const: microchip,mpfs | 25 | - const: microchip,mpfs-icicle-kit |
| 26 | - const: microchip,mpfs | ||
| 27 | |||
| 28 | - items: | ||
| 29 | - enum: | ||
| 30 | - aries,m100pfsevp | ||
| 31 | - microchip,mpfs-sev-kit | ||
| 32 | - sundance,polarberry | ||
| 33 | - const: microchip,mpfs | ||
| 26 | 34 | ||
| 27 | additionalProperties: true | 35 | additionalProperties: true |
| 28 | 36 | ||
| @@ -2,18 +2,18 @@ · 1 unmodified line | |||
| 2 | # Copyright (C) 2020 SiFive, Inc. | 2 | # Copyright (C) 2020 SiFive, Inc. |
| 3 | %YAML 1.2 | 3 | %YAML 1.2 |
| 4 | --- | 4 | --- |
| 5 | $id: http://devicetree.org/schemas/riscv/sifive-l2-cache.yaml# | 5 | $id: http://devicetree.org/schemas/riscv/sifive,ccache0.yaml# |
| 6 | $schema: http://devicetree.org/meta-schemas/core.yaml# | 6 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 7 | 7 | ||
| 8 | title: SiFive L2 Cache Controller | 8 | title: SiFive Composable Cache Controller |
| 9 | 9 | ||
| 10 | maintainers: | 10 | maintainers: |
| 11 | - Sagar Kadam <sagar.kadam@sifive.com> | 11 | - Sagar Kadam <sagar.kadam@sifive.com> |
| 12 | - Paul Walmsley <paul.walmsley@sifive.com> | 12 | - Paul Walmsley <paul.walmsley@sifive.com> |
| 13 | 13 | ||
| 14 | description: | 14 | description: |
| 15 | The SiFive Level 2 Cache Controller is used to provide access to fast copies | 15 | The SiFive Composable Cache Controller is used to provide access to fast copies |
| 16 | of memory for masters in a Core Complex. The Level 2 Cache Controller also | 16 | of memory for masters in a Core Complex. The Composable Cache Controller also |
| 17 | acts as directory-based coherency manager. | 17 | acts as directory-based coherency manager. |
| 18 | All the properties in ePAPR/DeviceTree specification applies for this platform. | 18 | All the properties in ePAPR/DeviceTree specification applies for this platform. |
| 19 | 19 | ||
| @@ -22,6 +22,7 @@ select: · 2 unmodified lines | |||
| 22 | compatible: | 22 | compatible: |
| 23 | contains: | 23 | contains: |
| 24 | enum: | 24 | enum: |
| 25 | - sifive,ccache0 | ||
| 25 | - sifive,fu540-c000-ccache | 26 | - sifive,fu540-c000-ccache |
| 26 | - sifive,fu740-c000-ccache | 27 | - sifive,fu740-c000-ccache |
| 27 | 28 | ||
| @@ -33,6 +34,7 @@ properties: · 5 unmodified lines | |||
| 33 | oneOf: | 34 | oneOf: |
| 34 | - items: | 35 | - items: |
| 35 | - enum: | 36 | - enum: |
| 37 | - sifive,ccache0 | ||
| 36 | - sifive,fu540-c000-ccache | 38 | - sifive,fu540-c000-ccache |
| 37 | - sifive,fu740-c000-ccache | 39 | - sifive,fu740-c000-ccache |
| 38 | - const: cache | 40 | - const: cache |
| @@ -45,7 +47,7 @@ properties: · 6 unmodified lines | |||
| 45 | const: 64 | 47 | const: 64 |
| 46 | 48 | ||
| 47 | cache-level: | 49 | cache-level: |
| 48 | const: 2 | 50 | enum: [2, 3] |
| 49 | 51 | ||
| 50 | cache-sets: | 52 | cache-sets: |
| 51 | enum: [1024, 2048] | 53 | enum: [1024, 2048] |
| @@ -115,6 +117,22 @@ allOf: · 63 unmodified lines | |||
| 115 | cache-sets: | 117 | cache-sets: |
| 116 | const: 1024 | 118 | const: 1024 |
| 117 | 119 | ||
| 120 | - if: | ||
| 121 | properties: | ||
| 122 | compatible: | ||
| 123 | contains: | ||
| 124 | const: sifive,ccache0 | ||
| 125 | |||
| 126 | then: | ||
| 127 | properties: | ||
| 128 | cache-level: | ||
| 129 | enum: [2, 3] | ||
| 130 | |||
| 131 | else: | ||
| 132 | properties: | ||
| 133 | cache-level: | ||
| 134 | const: 2 | ||
| 135 | |||
| 118 | additionalProperties: false | 136 | additionalProperties: false |
| 119 | 137 | ||
| 120 | required: | 138 | required: |
| @@ -22,12 +22,18 @@ description: · 21 unmodified lines | |||
| 22 | 22 | ||
| 23 | properties: | 23 | properties: |
| 24 | compatible: | 24 | compatible: |
| 25 | items: | 25 | oneOf: |
| 26 | - enum: | 26 | - items: |
| 27 | - sifive,fu540-c000-clint | 27 | - enum: |
| 28 | - starfive,jh7100-clint | 28 | - sifive,fu540-c000-clint |
| 29 | - canaan,k210-clint | 29 | - starfive,jh7100-clint |
| 30 | - const: sifive,clint0 | 30 | - canaan,k210-clint |
| 31 | - const: sifive,clint0 | ||
| 32 | - items: | ||
| 33 | - const: sifive,clint0 | ||
| 34 | - const: riscv,clint0 | ||
| 35 | deprecated: true | ||
| 36 | description: For the QEMU virt machine only | ||
| 31 | 37 | ||
| 32 | description: | 38 | description: |
| 33 | Should be "<vendor>,<chip>-clint" and "sifive,clint<version>". | 39 | Should be "<vendor>,<chip>-clint" and "sifive,clint<version>". |
| @@ -8,6 +8,7 @@ RISC-V architecture · 7 unmodified lines | |||
| 8 | boot-image-header | 8 | boot-image-header |
| 9 | vm-layout | 9 | vm-layout |
| 10 | patch-acceptance | 10 | patch-acceptance |
| 11 | uabi | ||
| 11 | 12 | ||
| 12 | features | 13 | features |
| 13 | 14 | ||
| @@ -0,0 +1,6 @@ | |||
| 1 | .. SPDX-License-Identifier: GPL-2.0 | ||
| 2 | |||
| 3 | RISC-V Linux User ABI | ||
| 4 | ===================== | ||
| 5 | |||
| 6 | Misaligned accesses are supported in userspace, but they may perform poorly. | ||
| @@ -17702,6 +17702,7 @@ M: Palmer Dabbelt <palmer@dabbelt.com> · 17701 unmodified lines | |||
| 17702 | M: Albert Ou <aou@eecs.berkeley.edu> | 17702 | M: Albert Ou <aou@eecs.berkeley.edu> |
| 17703 | L: linux-riscv@lists.infradead.org | 17703 | L: linux-riscv@lists.infradead.org |
| 17704 | S: Supported | 17704 | S: Supported |
| 17705 | Q: https://patchwork.kernel.org/project/linux-riscv/list/ | ||
| 17705 | P: Documentation/riscv/patch-acceptance.rst | 17706 | P: Documentation/riscv/patch-acceptance.rst |
| 17706 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git | 17707 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git |
| 17707 | F: arch/riscv/ | 17708 | F: arch/riscv/ |
| @@ -17713,12 +17714,13 @@ M: Conor Dooley <conor.dooley@microchip.com> · 5 unmodified lines | |||
| 17713 | M: Daire McNamara <daire.mcnamara@microchip.com> | 17714 | M: Daire McNamara <daire.mcnamara@microchip.com> |
| 17714 | L: linux-riscv@lists.infradead.org | 17715 | L: linux-riscv@lists.infradead.org |
| 17715 | S: Supported | 17716 | S: Supported |
| 17716 | F: Documentation/devicetree/bindings/clock/microchip,mpfs.yaml | 17717 | F: Documentation/devicetree/bindings/clock/microchip,mpfs*.yaml |
| 17717 | F: Documentation/devicetree/bindings/gpio/microchip,mpfs-gpio.yaml | 17718 | F: Documentation/devicetree/bindings/gpio/microchip,mpfs-gpio.yaml |
| 17718 | F: Documentation/devicetree/bindings/i2c/microchip,corei2c.yaml | 17719 | F: Documentation/devicetree/bindings/i2c/microchip,corei2c.yaml |
| 17719 | F: Documentation/devicetree/bindings/mailbox/microchip,mpfs-mailbox.yaml | 17720 | F: Documentation/devicetree/bindings/mailbox/microchip,mpfs-mailbox.yaml |
| 17720 | F: Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml | 17721 | F: Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml |
| 17721 | F: Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml | 17722 | F: Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml |
| 17723 | F: Documentation/devicetree/bindings/riscv/microchip.yaml | ||
| 17722 | F: Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-sys-controller.yaml | 17724 | F: Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-sys-controller.yaml |
| 17723 | F: Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml | 17725 | F: Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml |
| 17724 | F: Documentation/devicetree/bindings/usb/microchip,mpfs-musb.yaml | 17726 | F: Documentation/devicetree/bindings/usb/microchip,mpfs-musb.yaml |
| @@ -70,6 +70,7 @@ config RISCV · 69 unmodified lines | |||
| 70 | select GENERIC_SMP_IDLE_THREAD | 70 | select GENERIC_SMP_IDLE_THREAD |
| 71 | select GENERIC_TIME_VSYSCALL if MMU && 64BIT | 71 | select GENERIC_TIME_VSYSCALL if MMU && 64BIT |
| 72 | select GENERIC_VDSO_TIME_NS if HAVE_GENERIC_VDSO | 72 | select GENERIC_VDSO_TIME_NS if HAVE_GENERIC_VDSO |
| 73 | select HARDIRQS_SW_RESEND | ||
| 73 | select HAVE_ARCH_AUDITSYSCALL | 74 | select HAVE_ARCH_AUDITSYSCALL |
| 74 | select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL | 75 | select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL |
| 75 | select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL | 76 | select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL |
| @@ -37,6 +37,7 @@ else · 36 unmodified lines | |||
| 37 | endif | 37 | endif |
| 38 | 38 | ||
| 39 | ifeq ($(CONFIG_LD_IS_LLD),y) | 39 | ifeq ($(CONFIG_LD_IS_LLD),y) |
| 40 | ifeq ($(shell test $(CONFIG_LLD_VERSION) -lt 150000; echo $$?),0) | ||
| 40 | KBUILD_CFLAGS += -mno-relax | 41 | KBUILD_CFLAGS += -mno-relax |
| 41 | KBUILD_AFLAGS += -mno-relax | 42 | KBUILD_AFLAGS += -mno-relax |
| 42 | ifndef CONFIG_AS_IS_LLVM | 43 | ifndef CONFIG_AS_IS_LLVM |
| @@ -44,6 +45,7 @@ ifndef CONFIG_AS_IS_LLVM · 1 unmodified line | |||
| 44 | KBUILD_AFLAGS += -Wa,-mno-relax | 45 | KBUILD_AFLAGS += -Wa,-mno-relax |
| 45 | endif | 46 | endif |
| 46 | endif | 47 | endif |
| 48 | endif | ||
| 47 | 49 | ||
| 48 | # ISA string setting | 50 | # ISA string setting |
| 49 | riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima | 51 | riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima |
| @@ -1,4 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | dtb-$(CONFIG_SOC_MICROCHIP_POLARFIRE) += mpfs-icicle-kit.dtb | 2 | dtb-$(CONFIG_SOC_MICROCHIP_POLARFIRE) += mpfs-icicle-kit.dtb |
| 3 | dtb-$(CONFIG_SOC_MICROCHIP_POLARFIRE) += mpfs-m100pfsevp.dtb | ||
| 3 | dtb-$(CONFIG_SOC_MICROCHIP_POLARFIRE) += mpfs-polarberry.dtb | 4 | dtb-$(CONFIG_SOC_MICROCHIP_POLARFIRE) += mpfs-polarberry.dtb |
| 5 | dtb-$(CONFIG_SOC_MICROCHIP_POLARFIRE) += mpfs-sev-kit.dtb | ||
| 4 | obj-$(CONFIG_BUILTIN_DTB) += $(addsuffix .o, $(dtb-y)) | 6 | obj-$(CONFIG_BUILTIN_DTB) += $(addsuffix .o, $(dtb-y)) |
| @@ -2,20 +2,21 @@ · 1 unmodified line | |||
| 2 | /* Copyright (c) 2020-2021 Microchip Technology Inc */ | 2 | /* Copyright (c) 2020-2021 Microchip Technology Inc */ |
| 3 | 3 | ||
| 4 | / { | 4 | / { |
| 5 | compatible = "microchip,mpfs-icicle-reference-rtlv2203", "microchip,mpfs"; | 5 | compatible = "microchip,mpfs-icicle-reference-rtlv2210", "microchip,mpfs-icicle-kit", |
| 6 | "microchip,mpfs"; | ||
| 6 | 7 | ||
| 7 | core_pwm0: pwm@41000000 { | 8 | core_pwm0: pwm@40000000 { |
| 8 | compatible = "microchip,corepwm-rtl-v4"; | 9 | compatible = "microchip,corepwm-rtl-v4"; |
| 9 | reg = <0x0 0x41000000 0x0 0xF0>; | 10 | reg = <0x0 0x40000000 0x0 0xF0>; |
| 10 | microchip,sync-update-mask = /bits/ 32 <0>; | 11 | microchip,sync-update-mask = /bits/ 32 <0>; |
| 11 | #pwm-cells = <2>; | 12 | #pwm-cells = <2>; |
| 12 | clocks = <&fabric_clk3>; | 13 | clocks = <&fabric_clk3>; |
| 13 | status = "disabled"; | 14 | status = "disabled"; |
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | i2c2: i2c@44000000 { | 17 | i2c2: i2c@40000200 { |
| 17 | compatible = "microchip,corei2c-rtl-v7"; | 18 | compatible = "microchip,corei2c-rtl-v7"; |
| 18 | reg = <0x0 0x44000000 0x0 0x1000>; | 19 | reg = <0x0 0x40000200 0x0 0x100>; |
| 19 | #address-cells = <1>; | 20 | #address-cells = <1>; |
| 20 | #size-cells = <0>; | 21 | #size-cells = <0>; |
| 21 | clocks = <&fabric_clk3>; | 22 | clocks = <&fabric_clk3>; |
| @@ -28,7 +29,7 @@ · 6 unmodified lines | |||
| 28 | fabric_clk3: fabric-clk3 { | 29 | fabric_clk3: fabric-clk3 { |
| 29 | compatible = "fixed-clock"; | 30 | compatible = "fixed-clock"; |
| 30 | #clock-cells = <0>; | 31 | #clock-cells = <0>; |
| 31 | clock-frequency = <62500000>; | 32 | clock-frequency = <50000000>; |
| 32 | }; | 33 | }; |
| 33 | 34 | ||
| 34 | fabric_clk1: fabric-clk1 { | 35 | fabric_clk1: fabric-clk1 { |
| @@ -36,4 +37,34 @@ · 1 unmodified line | |||
| 36 | #clock-cells = <0>; | 37 | #clock-cells = <0>; |
| 37 | clock-frequency = <125000000>; | 38 | clock-frequency = <125000000>; |
| 38 | }; | 39 | }; |
| 40 | |||
| 41 | pcie: pcie@3000000000 { | ||
| 42 | compatible = "microchip,pcie-host-1.0"; | ||
| 43 | #address-cells = <0x3>; | ||
| 44 | #interrupt-cells = <0x1>; | ||
| 45 | #size-cells = <0x2>; | ||
| 46 | device_type = "pci"; | ||
| 47 | reg = <0x30 0x0 0x0 0x8000000>, <0x0 0x43000000 0x0 0x10000>; | ||
| 48 | reg-names = "cfg", "apb"; | ||
| 49 | bus-range = <0x0 0x7f>; | ||
| 50 | interrupt-parent = <&plic>; | ||
| 51 | interrupts = <119>; | ||
| 52 | interrupt-map = <0 0 0 1 &pcie_intc 0>, | ||
| 53 | <0 0 0 2 &pcie_intc 1>, | ||
| 54 | <0 0 0 3 &pcie_intc 2>, | ||
| 55 | <0 0 0 4 &pcie_intc 3>; | ||
| 56 | interrupt-map-mask = <0 0 0 7>; | ||
| 57 | clocks = <&fabric_clk1>, <&fabric_clk3>; | ||
| 58 | clock-names = "fic1", "fic3"; | ||
| 59 | ranges = <0x3000000 0x0 0x8000000 0x30 0x8000000 0x0 0x80000000>; | ||
| 60 | dma-ranges = <0x02000000 0x0 0x00000000 0x0 0x00000000 0x1 0x00000000>; | ||
| 61 | msi-parent = <&pcie>; | ||
| 62 | msi-controller; | ||
| 63 | status = "disabled"; | ||
| 64 | pcie_intc: interrupt-controller { | ||
| 65 | #address-cells = <0>; | ||
| 66 | #interrupt-cells = <1>; | ||
| 67 | interrupt-controller; | ||
| 68 | }; | ||
| 69 | }; | ||
| 39 | }; | 70 | }; |
| @@ -11,7 +11,8 @@ · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | / { | 12 | / { |
| 13 | model = "Microchip PolarFire-SoC Icicle Kit"; | 13 | model = "Microchip PolarFire-SoC Icicle Kit"; |
| 14 | compatible = "microchip,mpfs-icicle-kit", "microchip,mpfs"; | 14 | compatible = "microchip,mpfs-icicle-reference-rtlv2210", "microchip,mpfs-icicle-kit", |
| 15 | "microchip,mpfs"; | ||
| 15 | 16 | ||
| 16 | aliases { | 17 | aliases { |
| 17 | ethernet0 = &mac1; | 18 | ethernet0 = &mac1; |
| @@ -32,15 +33,26 @@ · 14 unmodified lines | |||
| 32 | 33 | ||
| 33 | ddrc_cache_lo: memory@80000000 { | 34 | ddrc_cache_lo: memory@80000000 { |
| 34 | device_type = "memory"; | 35 | device_type = "memory"; |
| 35 | reg = <0x0 0x80000000 0x0 0x2e000000>; | 36 | reg = <0x0 0x80000000 0x0 0x40000000>; |
| 36 | status = "okay"; | 37 | status = "okay"; |
| 37 | }; | 38 | }; |
| 38 | 39 | ||
| 39 | ddrc_cache_hi: memory@1000000000 { | 40 | ddrc_cache_hi: memory@1000000000 { |
| 40 | device_type = "memory"; | 41 | device_type = "memory"; |
| 41 | reg = <0x10 0x0 0x0 0x40000000>; | 42 | reg = <0x10 0x40000000 0x0 0x40000000>; |
| 42 | status = "okay"; | 43 | status = "okay"; |
| 43 | }; | 44 | }; |
| 45 | |||
| 46 | reserved-memory { | ||
| 47 | #address-cells = <2>; | ||
| 48 | #size-cells = <2>; | ||
| 49 | ranges; | ||
| 50 | |||
| 51 | hss_payload: region@BFC00000 { | ||
| 52 | reg = <0x0 0xBFC00000 0x0 0x400000>; | ||
| 53 | no-map; | ||
| 54 | }; | ||
| 55 | }; | ||
| 44 | }; | 56 | }; |
| 45 | 57 | ||
| 46 | &core_pwm0 { | 58 | &core_pwm0 { |
| @@ -0,0 +1,45 @@ | |||
| 1 | // SPDX-License-Identifier: (GPL-2.0 OR MIT) | ||
| 2 | /* Copyright (c) 2022 Microchip Technology Inc */ | ||
| 3 | |||
| 4 | / { | ||
| 5 | fabric_clk3: fabric-clk3 { | ||
| 6 | compatible = "fixed-clock"; | ||
| 7 | #clock-cells = <0>; | ||
| 8 | clock-frequency = <62500000>; | ||
| 9 | }; | ||
| 10 | |||
| 11 | fabric_clk1: fabric-clk1 { | ||
| 12 | compatible = "fixed-clock"; | ||
| 13 | #clock-cells = <0>; | ||
| 14 | clock-frequency = <125000000>; | ||
| 15 | }; | ||
| 16 | |||
| 17 | pcie: pcie@2000000000 { | ||
| 18 | compatible = "microchip,pcie-host-1.0"; | ||
| 19 | #address-cells = <0x3>; | ||
| 20 | #interrupt-cells = <0x1>; | ||
| 21 | #size-cells = <0x2>; | ||
| 22 | device_type = "pci"; | ||
| 23 | reg = <0x20 0x0 0x0 0x8000000>, <0x0 0x43000000 0x0 0x10000>; | ||
| 24 | reg-names = "cfg", "apb"; | ||
| 25 | bus-range = <0x0 0x7f>; | ||
| 26 | interrupt-parent = <&plic>; | ||
| 27 | interrupts = <119>; | ||
| 28 | interrupt-map = <0 0 0 1 &pcie_intc 0>, | ||
| 29 | <0 0 0 2 &pcie_intc 1>, | ||
| 30 | <0 0 0 3 &pcie_intc 2>, | ||
| 31 | <0 0 0 4 &pcie_intc 3>; | ||
| 32 | interrupt-map-mask = <0 0 0 7>; | ||
| 33 | clocks = <&fabric_clk1>, <&fabric_clk1>, <&fabric_clk3>; | ||
| 34 | clock-names = "fic0", "fic1", "fic3"; | ||
| 35 | ranges = <0x3000000 0x0 0x8000000 0x20 0x8000000 0x0 0x80000000>; | ||
| 36 | msi-parent = <&pcie>; | ||
| 37 | msi-controller; | ||
| 38 | status = "disabled"; | ||
| 39 | pcie_intc: interrupt-controller { | ||
| 40 | #address-cells = <0>; | ||
| 41 | #interrupt-cells = <1>; | ||
| 42 | interrupt-controller; | ||
| 43 | }; | ||
| 44 | }; | ||
| 45 | }; | ||
| @@ -0,0 +1,179 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Original all-in-one devicetree: | ||
| 4 | * Copyright (C) 2021-2022 - Wolfgang Grandegger <wg@aries-embedded.de> | ||
| 5 | * Rewritten to use includes: | ||
| 6 | * Copyright (C) 2022 - Conor Dooley <conor.dooley@microchip.com> | ||
| 7 | */ | ||
| 8 | /dts-v1/; | ||
| 9 | |||
| 10 | #include "mpfs.dtsi" | ||
| 11 | #include "mpfs-m100pfs-fabric.dtsi" | ||
| 12 | |||
| 13 | /* Clock frequency (in Hz) of the rtcclk */ | ||
| 14 | #define MTIMER_FREQ 1000000 | ||
| 15 | |||
| 16 | / { | ||
| 17 | model = "Aries Embedded M100PFEVPS"; | ||
| 18 | compatible = "aries,m100pfsevp", "microchip,mpfs"; | ||
| 19 | |||
| 20 | aliases { | ||
| 21 | ethernet0 = &mac0; | ||
| 22 | ethernet1 = &mac1; | ||
| 23 | serial0 = &mmuart0; | ||
| 24 | serial1 = &mmuart1; | ||
| 25 | serial2 = &mmuart2; | ||
| 26 | serial3 = &mmuart3; | ||
| 27 | serial4 = &mmuart4; | ||
| 28 | gpio0 = &gpio0; | ||
| 29 | gpio1 = &gpio2; | ||
| 30 | }; | ||
| 31 | |||
| 32 | chosen { | ||
| 33 | stdout-path = "serial1:115200n8"; | ||
| 34 | }; | ||
| 35 | |||
| 36 | cpus { | ||
| 37 | timebase-frequency = <MTIMER_FREQ>; | ||
| 38 | }; | ||
| 39 | |||
| 40 | ddrc_cache_lo: memory@80000000 { | ||
| 41 | device_type = "memory"; | ||
| 42 | reg = <0x0 0x80000000 0x0 0x40000000>; | ||
| 43 | }; | ||
| 44 | ddrc_cache_hi: memory@1040000000 { | ||
| 45 | device_type = "memory"; | ||
| 46 | reg = <0x10 0x40000000 0x0 0x40000000>; | ||
| 47 | }; | ||
| 48 | }; | ||
| 49 | |||
| 50 | &can0 { | ||
| 51 | status = "okay"; | ||
| 52 | }; | ||
| 53 | |||
| 54 | &i2c0 { | ||
| 55 | status = "okay"; | ||
| 56 | }; | ||
| 57 | |||
| 58 | &i2c1 { | ||
| 59 | status = "okay"; | ||
| 60 | }; | ||
| 61 | |||
| 62 | &gpio0 { | ||
| 63 | interrupts = <13>, <14>, <15>, <16>, | ||
| 64 | <17>, <18>, <19>, <20>, | ||
| 65 | <21>, <22>, <23>, <24>, | ||
| 66 | <25>, <26>; | ||
| 67 | ngpios = <14>; | ||
| 68 | status = "okay"; | ||
| 69 | |||
| 70 | pmic-irq-hog { | ||
| 71 | gpio-hog; | ||
| 72 | gpios = <13 0>; | ||
| 73 | input; | ||
| 74 | }; | ||
| 75 | |||
| 76 | /* Set to low for eMMC, high for SD-card */ | ||
| 77 | mmc-sel-hog { | ||
| 78 | gpio-hog; | ||
| 79 | gpios = <12 0>; | ||
| 80 | output-high; | ||
| 81 | }; | ||
| 82 | }; | ||
| 83 | |||
| 84 | &gpio2 { | ||
| 85 | interrupts = <13>, <14>, <15>, <16>, | ||
| 86 | <17>, <18>, <19>, <20>, | ||
| 87 | <21>, <22>, <23>, <24>, | ||
| 88 | <25>, <26>, <27>, <28>, | ||
| 89 | <29>, <30>, <31>, <32>, | ||
| 90 | <33>, <34>, <35>, <36>, | ||
| 91 | <37>, <38>, <39>, <40>, | ||
| 92 | <41>, <42>, <43>, <44>; | ||
| 93 | status = "okay"; | ||
| 94 | }; | ||
| 95 | |||
| 96 | &mac0 { | ||
| 97 | status = "okay"; | ||
| 98 | phy-mode = "gmii"; | ||
| 99 | phy-handle = <&phy0>; | ||
| 100 | phy0: ethernet-phy@0 { | ||
| 101 | reg = <0>; | ||
| 102 | }; | ||
| 103 | }; | ||
| 104 | |||
| 105 | &mac1 { | ||
| 106 | status = "okay"; | ||
| 107 | phy-mode = "gmii"; | ||
| 108 | phy-handle = <&phy1>; | ||
| 109 | phy1: ethernet-phy@0 { | ||
| 110 | reg = <0>; | ||
| 111 | }; | ||
| 112 | }; | ||
| 113 | |||
| 114 | &mbox { | ||
| 115 | status = "okay"; | ||
| 116 | }; | ||
| 117 | |||
| 118 | &mmc { | ||
| 119 | max-frequency = <50000000>; | ||
| 120 | bus-width = <4>; | ||
| 121 | cap-mmc-highspeed; | ||
| 122 | cap-sd-highspeed; | ||
| 123 | no-1-8-v; | ||
| 124 | sd-uhs-sdr12; | ||
| 125 | sd-uhs-sdr25; | ||
| 126 | sd-uhs-sdr50; | ||
| 127 | sd-uhs-sdr104; | ||
| 128 | disable-wp; | ||
| 129 | status = "okay"; | ||
| 130 | }; | ||
| 131 | |||
| 132 | &mmuart1 { | ||
| 133 | status = "okay"; | ||
| 134 | }; | ||
| 135 | |||
| 136 | &mmuart2 { | ||
| 137 | status = "okay"; | ||
| 138 | }; | ||
| 139 | |||
| 140 | &mmuart3 { | ||
| 141 | status = "okay"; | ||
| 142 | }; | ||
| 143 | |||
| 144 | &mmuart4 { | ||
| 145 | status = "okay"; | ||
| 146 | }; | ||
| 147 | |||
| 148 | &pcie { | ||
| 149 | status = "okay"; | ||
| 150 | }; | ||
| 151 | |||
| 152 | &qspi { | ||
| 153 | status = "okay"; | ||
| 154 | }; | ||
| 155 | |||
| 156 | &refclk { | ||
| 157 | clock-frequency = <125000000>; | ||
| 158 | }; | ||
| 159 | |||
| 160 | &rtc { | ||
| 161 | status = "okay"; | ||
| 162 | }; | ||
| 163 | |||
| 164 | &spi0 { | ||
| 165 | status = "okay"; | ||
| 166 | }; | ||
| 167 | |||
| 168 | &spi1 { | ||
| 169 | status = "okay"; | ||
| 170 | }; | ||
| 171 | |||
| 172 | &syscontroller { | ||
| 173 | status = "okay"; | ||
| 174 | }; | ||
| 175 | |||
| 176 | &usb { | ||
| 177 | status = "okay"; | ||
| 178 | dr_mode = "host"; | ||
| 179 | }; | ||
| @@ -13,4 +13,33 @@ · 12 unmodified lines | |||
| 13 | #clock-cells = <0>; | 13 | #clock-cells = <0>; |
| 14 | clock-frequency = <125000000>; | 14 | clock-frequency = <125000000>; |
| 15 | }; | 15 | }; |
| 16 | |||
| 17 | pcie: pcie@2000000000 { | ||
| 18 | compatible = "microchip,pcie-host-1.0"; | ||
| 19 | #address-cells = <0x3>; | ||
| 20 | #interrupt-cells = <0x1>; | ||
| 21 | #size-cells = <0x2>; | ||
| 22 | device_type = "pci"; | ||
| 23 | reg = <0x20 0x0 0x0 0x8000000>, <0x0 0x43000000 0x0 0x10000>; | ||
| 24 | reg-names = "cfg", "apb"; | ||
| 25 | bus-range = <0x0 0x7f>; | ||
| 26 | interrupt-parent = <&plic>; | ||
| 27 | interrupts = <119>; | ||
| 28 | interrupt-map = <0 0 0 1 &pcie_intc 0>, | ||
| 29 | <0 0 0 2 &pcie_intc 1>, | ||
| 30 | <0 0 0 3 &pcie_intc 2>, | ||
| 31 | <0 0 0 4 &pcie_intc 3>; | ||
| 32 | interrupt-map-mask = <0 0 0 7>; | ||
| 33 | clocks = <&fabric_clk1>, <&fabric_clk1>, <&fabric_clk3>; | ||
| 34 | clock-names = "fic0", "fic1", "fic3"; | ||
| 35 | ranges = <0x3000000 0x0 0x8000000 0x20 0x8000000 0x0 0x80000000>; | ||
| 36 | msi-parent = <&pcie>; | ||
| 37 | msi-controller; | ||
| 38 | status = "disabled"; | ||
| 39 | pcie_intc: interrupt-controller { | ||
| 40 | #address-cells = <0>; | ||
| 41 | #interrupt-cells = <1>; | ||
| 42 | interrupt-controller; | ||
| 43 | }; | ||
| 44 | }; | ||
| 16 | }; | 45 | }; |
| @@ -0,0 +1,45 @@ | |||
| 1 | // SPDX-License-Identifier: (GPL-2.0 OR MIT) | ||
| 2 | /* Copyright (c) 2022 Microchip Technology Inc */ | ||
| 3 | |||
| 4 | / { | ||
| 5 | fabric_clk3: fabric-clk3 { | ||
| 6 | compatible = "fixed-clock"; | ||
| 7 | #clock-cells = <0>; | ||
| 8 | clock-frequency = <0>; | ||
| 9 | }; | ||
| 10 | |||
| 11 | fabric_clk1: fabric-clk1 { | ||
| 12 | compatible = "fixed-clock"; | ||
| 13 | #clock-cells = <0>; | ||
| 14 | clock-frequency = <125000000>; | ||
| 15 | }; | ||
| 16 | |||
| 17 | pcie: pcie@2000000000 { | ||
| 18 | compatible = "microchip,pcie-host-1.0"; | ||
| 19 | #address-cells = <0x3>; | ||
| 20 | #interrupt-cells = <0x1>; | ||
| 21 | #size-cells = <0x2>; | ||
| 22 | device_type = "pci"; | ||
| 23 | reg = <0x20 0x0 0x0 0x8000000>, <0x0 0x43000000 0x0 0x10000>; | ||
| 24 | reg-names = "cfg", "apb"; | ||
| 25 | bus-range = <0x0 0x7f>; | ||
| 26 | interrupt-parent = <&plic>; | ||
| 27 | interrupts = <119>; | ||
| 28 | interrupt-map = <0 0 0 1 &pcie_intc 0>, | ||
| 29 | <0 0 0 2 &pcie_intc 1>, | ||
| 30 | <0 0 0 3 &pcie_intc 2>, | ||
| 31 | <0 0 0 4 &pcie_intc 3>; | ||
| 32 | interrupt-map-mask = <0 0 0 7>; | ||
| 33 | clocks = <&fabric_clk1>, <&fabric_clk1>, <&fabric_clk3>; | ||
| 34 | clock-names = "fic0", "fic1", "fic3"; | ||
| 35 | ranges = <0x3000000 0x0 0x8000000 0x20 0x8000000 0x0 0x80000000>; | ||
| 36 | msi-parent = <&pcie>; | ||
| 37 | msi-controller; | ||
| 38 | status = "disabled"; | ||
| 39 | pcie_intc: interrupt-controller { | ||
| 40 | #address-cells = <0>; | ||
| 41 | #interrupt-cells = <1>; | ||
| 42 | interrupt-controller; | ||
| 43 | }; | ||
| 44 | }; | ||
| 45 | }; | ||
| @@ -0,0 +1,145 @@ | |||
| 1 | // SPDX-License-Identifier: (GPL-2.0 OR MIT) | ||
| 2 | /* Copyright (c) 2022 Microchip Technology Inc */ | ||
| 3 | |||
| 4 | /dts-v1/; | ||
| 5 | |||
| 6 | #include "mpfs.dtsi" | ||
| 7 | #include "mpfs-sev-kit-fabric.dtsi" | ||
| 8 | |||
| 9 | /* Clock frequency (in Hz) of the rtcclk */ | ||
| 10 | #define MTIMER_FREQ 1000000 | ||
| 11 | |||
| 12 | / { | ||
| 13 | #address-cells = <2>; | ||
| 14 | #size-cells = <2>; | ||
| 15 | model = "Microchip PolarFire-SoC SEV Kit"; | ||
| 16 | compatible = "microchip,mpfs-sev-kit", "microchip,mpfs"; | ||
| 17 | |||
| 18 | aliases { | ||
| 19 | ethernet0 = &mac1; | ||
| 20 | serial0 = &mmuart0; | ||
| 21 | serial1 = &mmuart1; | ||
| 22 | serial2 = &mmuart2; | ||
| 23 | serial3 = &mmuart3; | ||
| 24 | serial4 = &mmuart4; | ||
| 25 | }; | ||
| 26 | |||
| 27 | chosen { | ||
| 28 | stdout-path = "serial1:115200n8"; | ||
| 29 | }; | ||
| 30 | |||
| 31 | cpus { | ||
| 32 | timebase-frequency = <MTIMER_FREQ>; | ||
| 33 | }; | ||
| 34 | |||
| 35 | reserved-memory { | ||
| 36 | #address-cells = <2>; | ||
| 37 | #size-cells = <2>; | ||
| 38 | ranges; | ||
| 39 | |||
| 40 | fabricbuf0ddrc: buffer@80000000 { | ||
| 41 | compatible = "shared-dma-pool"; | ||
| 42 | reg = <0x0 0x80000000 0x0 0x2000000>; | ||
| 43 | }; | ||
| 44 | |||
| 45 | fabricbuf1ddrnc: buffer@c4000000 { | ||
| 46 | compatible = "shared-dma-pool"; | ||
| 47 | reg = <0x0 0xc4000000 0x0 0x4000000>; | ||
| 48 | }; | ||
| 49 | |||
| 50 | fabricbuf2ddrncwcb: buffer@d4000000 { | ||
| 51 | compatible = "shared-dma-pool"; | ||
| 52 | reg = <0x0 0xd4000000 0x0 0x4000000>; | ||
| 53 | }; | ||
| 54 | }; | ||
| 55 | |||
| 56 | ddrc_cache: memory@1000000000 { | ||
| 57 | device_type = "memory"; | ||
| 58 | reg = <0x10 0x0 0x0 0x76000000>; | ||
| 59 | }; | ||
| 60 | }; | ||
| 61 | |||
| 62 | &i2c0 { | ||
| 63 | status = "okay"; | ||
| 64 | }; | ||
| 65 | |||
| 66 | &gpio2 { | ||
| 67 | interrupts = <53>, <53>, <53>, <53>, | ||
| 68 | <53>, <53>, <53>, <53>, | ||
| 69 | <53>, <53>, <53>, <53>, | ||
| 70 | <53>, <53>, <53>, <53>, | ||
| 71 | <53>, <53>, <53>, <53>, | ||
| 72 | <53>, <53>, <53>, <53>, | ||
| 73 | <53>, <53>, <53>, <53>, | ||
| 74 | <53>, <53>, <53>, <53>; | ||
| 75 | status = "okay"; | ||
| 76 | }; | ||
| 77 | |||
| 78 | &mac0 { | ||
| 79 | status = "okay"; | ||
| 80 | phy-mode = "sgmii"; | ||
| 81 | phy-handle = <&phy0>; | ||
| 82 | phy1: ethernet-phy@9 { | ||
| 83 | reg = <9>; | ||
| 84 | }; | ||
| 85 | phy0: ethernet-phy@8 { | ||
| 86 | reg = <8>; | ||
| 87 | }; | ||
| 88 | }; | ||
| 89 | |||
| 90 | &mac1 { | ||
| 91 | status = "okay"; | ||
| 92 | phy-mode = "sgmii"; | ||
| 93 | phy-handle = <&phy1>; | ||
| 94 | }; | ||
| 95 | |||
| 96 | &mbox { | ||
| 97 | status = "okay"; | ||
| 98 | }; | ||
| 99 | |||
| 100 | &mmc { | ||
| 101 | status = "okay"; | ||
| 102 | bus-width = <4>; | ||
| 103 | disable-wp; | ||
| 104 | cap-sd-highspeed; | ||
| 105 | cap-mmc-highspeed; | ||
| 106 | mmc-ddr-1_8v; | ||
| 107 | mmc-hs200-1_8v; | ||
| 108 | sd-uhs-sdr12; | ||
| 109 | sd-uhs-sdr25; | ||
| 110 | sd-uhs-sdr50; | ||
| 111 | sd-uhs-sdr104; | ||
| 112 | }; | ||
| 113 | |||
| 114 | &mmuart1 { | ||
| 115 | status = "okay"; | ||
| 116 | }; | ||
| 117 | |||
| 118 | &mmuart2 { | ||
| 119 | status = "okay"; | ||
| 120 | }; | ||
| 121 | |||
| 122 | &mmuart3 { | ||
| 123 | status = "okay"; | ||
| 124 | }; | ||
| 125 | |||
| 126 | &mmuart4 { | ||
| 127 | status = "okay"; | ||
| 128 | }; | ||
| 129 | |||
| 130 | &refclk { | ||
| 131 | clock-frequency = <125000000>; | ||
| 132 | }; | ||
| 133 | |||
| 134 | &rtc { | ||
| 135 | status = "okay"; | ||
| 136 | }; | ||
| 137 | |||
| 138 | &syscontroller { | ||
| 139 | status = "okay"; | ||
| 140 | }; | ||
| 141 | |||
| 142 | &usb { | ||
| 143 | status = "okay"; | ||
| 144 | dr_mode = "otg"; | ||
| 145 | }; | ||
| @@ -330,7 +330,7 @@ · 329 unmodified lines | |||
| 330 | }; | 330 | }; |
| 331 | 331 | ||
| 332 | qspi: spi@21000000 { | 332 | qspi: spi@21000000 { |
| 333 | compatible = "microchip,mpfs-qspi"; | 333 | compatible = "microchip,mpfs-qspi", "microchip,coreqspi-rtl-v2"; |
| 334 | #address-cells = <1>; | 334 | #address-cells = <1>; |
| 335 | #size-cells = <0>; | 335 | #size-cells = <0>; |
| 336 | reg = <0x0 0x21000000 0x0 0x1000>; | 336 | reg = <0x0 0x21000000 0x0 0x1000>; |
| @@ -464,35 +464,6 @@ · 127 unmodified lines | |||
| 464 | status = "disabled"; | 464 | status = "disabled"; |
| 465 | }; | 465 | }; |
| 466 | 466 | ||
| 467 | pcie: pcie@2000000000 { | ||
| 468 | compatible = "microchip,pcie-host-1.0"; | ||
| 469 | #address-cells = <0x3>; | ||
| 470 | #interrupt-cells = <0x1>; | ||
| 471 | #size-cells = <0x2>; | ||
| 472 | device_type = "pci"; | ||
| 473 | reg = <0x20 0x0 0x0 0x8000000>, <0x0 0x43000000 0x0 0x10000>; | ||
| 474 | reg-names = "cfg", "apb"; | ||
| 475 | bus-range = <0x0 0x7f>; | ||
| 476 | interrupt-parent = <&plic>; | ||
| 477 | interrupts = <119>; | ||
| 478 | interrupt-map = <0 0 0 1 &pcie_intc 0>, | ||
| 479 | <0 0 0 2 &pcie_intc 1>, | ||
| 480 | <0 0 0 3 &pcie_intc 2>, | ||
| 481 | <0 0 0 4 &pcie_intc 3>; | ||
| 482 | interrupt-map-mask = <0 0 0 7>; | ||
| 483 | clocks = <&fabric_clk1>, <&fabric_clk1>, <&fabric_clk3>; | ||
| 484 | clock-names = "fic0", "fic1", "fic3"; | ||
| 485 | ranges = <0x3000000 0x0 0x8000000 0x20 0x8000000 0x0 0x80000000>; | ||
| 486 | msi-parent = <&pcie>; | ||
| 487 | msi-controller; | ||
| 488 | status = "disabled"; | ||
| 489 | pcie_intc: interrupt-controller { | ||
| 490 | #address-cells = <0>; | ||
| 491 | #interrupt-cells = <1>; | ||
| 492 | interrupt-controller; | ||
| 493 | }; | ||
| 494 | }; | ||
| 495 | |||
| 496 | mbox: mailbox@37020000 { | 467 | mbox: mailbox@37020000 { |
| 497 | compatible = "microchip,mpfs-mailbox"; | 468 | compatible = "microchip,mpfs-mailbox"; |
| 498 | reg = <0x0 0x37020000 0x0 0x1000>, <0x0 0x2000318C 0x0 0x40>; | 469 | reg = <0x0 0x37020000 0x0 0x1000>, <0x0 0x2000318C 0x0 0x40>; |
| @@ -17,6 +17,9 @@ · 16 unmodified lines | |||
| 17 | static bool errata_probe_pbmt(unsigned int stage, | 17 | static bool errata_probe_pbmt(unsigned int stage, |
| 18 | unsigned long arch_id, unsigned long impid) | 18 | unsigned long arch_id, unsigned long impid) |
| 19 | { | 19 | { |
| 20 | if (!IS_ENABLED(CONFIG_ERRATA_THEAD_PBMT)) | ||
| 21 | return false; | ||
| 22 | |||
| 20 | if (arch_id != 0 || impid != 0) | 23 | if (arch_id != 0 || impid != 0) |
| 21 | return false; | 24 | return false; |
| 22 | 25 | ||
| @@ -30,7 +33,9 @@ static bool errata_probe_pbmt(unsigned int stage, · 7 unmodified lines | |||
| 30 | static bool errata_probe_cmo(unsigned int stage, | 33 | static bool errata_probe_cmo(unsigned int stage, |
| 31 | unsigned long arch_id, unsigned long impid) | 34 | unsigned long arch_id, unsigned long impid) |
| 32 | { | 35 | { |
| 33 | #ifdef CONFIG_ERRATA_THEAD_CMO | 36 | if (!IS_ENABLED(CONFIG_ERRATA_THEAD_CMO)) |
| 37 | return false; | ||
| 38 | |||
| 34 | if (arch_id != 0 || impid != 0) | 39 | if (arch_id != 0 || impid != 0) |
| 35 | return false; | 40 | return false; |
| 36 | 41 | ||
| @@ -40,9 +45,6 @@ static bool errata_probe_cmo(unsigned int stage, · 3 unmodified lines | |||
| 40 | riscv_cbom_block_size = L1_CACHE_BYTES; | 45 | riscv_cbom_block_size = L1_CACHE_BYTES; |
| 41 | riscv_noncoherent_supported(); | 46 | riscv_noncoherent_supported(); |
| 42 | return true; | 47 | return true; |
| 43 | #else | ||
| 44 | return false; | ||
| 45 | #endif | ||
| 46 | } | 48 | } |
| 47 | 49 | ||
| 48 | static u32 thead_errata_probe(unsigned int stage, | 50 | static u32 thead_errata_probe(unsigned int stage, |
| @@ -51,10 +53,10 @@ static u32 thead_errata_probe(unsigned int stage, · 2 unmodified lines | |||
| 51 | u32 cpu_req_errata = 0; | 53 | u32 cpu_req_errata = 0; |
| 52 | 54 | ||
| 53 | if (errata_probe_pbmt(stage, archid, impid)) | 55 | if (errata_probe_pbmt(stage, archid, impid)) |
| 54 | cpu_req_errata |= (1U << ERRATA_THEAD_PBMT); | 56 | cpu_req_errata |= BIT(ERRATA_THEAD_PBMT); |
| 55 | 57 | ||
| 56 | if (errata_probe_cmo(stage, archid, impid)) | 58 | if (errata_probe_cmo(stage, archid, impid)) |
| 57 | cpu_req_errata |= (1U << ERRATA_THEAD_CMO); | 59 | cpu_req_errata |= BIT(ERRATA_THEAD_CMO); |
| 58 | 60 | ||
| 59 | return cpu_req_errata; | 61 | return cpu_req_errata; |
| 60 | } | 62 | } |
| @@ -55,6 +55,8 @@ static inline void riscv_init_cbom_blocksize(void) { } · 54 unmodified lines | |||
| 55 | 55 | ||
| 56 | #ifdef CONFIG_RISCV_DMA_NONCOHERENT | 56 | #ifdef CONFIG_RISCV_DMA_NONCOHERENT |
| 57 | void riscv_noncoherent_supported(void); | 57 | void riscv_noncoherent_supported(void); |
| 58 | #else | ||
| 59 | static inline void riscv_noncoherent_supported(void) {} | ||
| 58 | #endif | 60 | #endif |
| 59 | 61 | ||
| 60 | /* | 62 | /* |
| @@ -99,6 +99,10 @@ do { \ · 98 unmodified lines | |||
| 99 | get_cache_size(2, CACHE_TYPE_UNIFIED)); \ | 99 | get_cache_size(2, CACHE_TYPE_UNIFIED)); \ |
| 100 | NEW_AUX_ENT(AT_L2_CACHEGEOMETRY, \ | 100 | NEW_AUX_ENT(AT_L2_CACHEGEOMETRY, \ |
| 101 | get_cache_geometry(2, CACHE_TYPE_UNIFIED)); \ | 101 | get_cache_geometry(2, CACHE_TYPE_UNIFIED)); \ |
| 102 | NEW_AUX_ENT(AT_L3_CACHESIZE, \ | ||
| 103 | get_cache_size(3, CACHE_TYPE_UNIFIED)); \ | ||
| 104 | NEW_AUX_ENT(AT_L3_CACHEGEOMETRY, \ | ||
| 105 | get_cache_geometry(3, CACHE_TYPE_UNIFIED)); \ | ||
| 102 | } while (0) | 106 | } while (0) |
| 103 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES | 107 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES |
| 104 | struct linux_binprm; | 108 | struct linux_binprm; |
| @@ -101,9 +101,9 @@ __io_reads_ins(reads, u32, l, __io_br(), __io_ar(addr)) · 100 unmodified lines | |||
| 101 | __io_reads_ins(ins, u8, b, __io_pbr(), __io_par(addr)) | 101 | __io_reads_ins(ins, u8, b, __io_pbr(), __io_par(addr)) |
| 102 | __io_reads_ins(ins, u16, w, __io_pbr(), __io_par(addr)) | 102 | __io_reads_ins(ins, u16, w, __io_pbr(), __io_par(addr)) |
| 103 | __io_reads_ins(ins, u32, l, __io_pbr(), __io_par(addr)) | 103 | __io_reads_ins(ins, u32, l, __io_pbr(), __io_par(addr)) |
| 104 | #define insb(addr, buffer, count) __insb((void __iomem *)(long)addr, buffer, count) | 104 | #define insb(addr, buffer, count) __insb(PCI_IOBASE + (addr), buffer, count) |
| 105 | #define insw(addr, buffer, count) __insw((void __iomem *)(long)addr, buffer, count) | 105 | #define insw(addr, buffer, count) __insw(PCI_IOBASE + (addr), buffer, count) |
| 106 | #define insl(addr, buffer, count) __insl((void __iomem *)(long)addr, buffer, count) | 106 | #define insl(addr, buffer, count) __insl(PCI_IOBASE + (addr), buffer, count) |
| 107 | 107 | ||
| 108 | __io_writes_outs(writes, u8, b, __io_bw(), __io_aw()) | 108 | __io_writes_outs(writes, u8, b, __io_bw(), __io_aw()) |
| 109 | __io_writes_outs(writes, u16, w, __io_bw(), __io_aw()) | 109 | __io_writes_outs(writes, u16, w, __io_bw(), __io_aw()) |
| @@ -115,22 +115,22 @@ __io_writes_outs(writes, u32, l, __io_bw(), __io_aw()) · 5 unmodified lines | |||
| 115 | __io_writes_outs(outs, u8, b, __io_pbw(), __io_paw()) | 115 | __io_writes_outs(outs, u8, b, __io_pbw(), __io_paw()) |
| 116 | __io_writes_outs(outs, u16, w, __io_pbw(), __io_paw()) | 116 | __io_writes_outs(outs, u16, w, __io_pbw(), __io_paw()) |
| 117 | __io_writes_outs(outs, u32, l, __io_pbw(), __io_paw()) | 117 | __io_writes_outs(outs, u32, l, __io_pbw(), __io_paw()) |
| 118 | #define outsb(addr, buffer, count) __outsb((void __iomem *)(long)addr, buffer, count) | 118 | #define outsb(addr, buffer, count) __outsb(PCI_IOBASE + (addr), buffer, count) |
| 119 | #define outsw(addr, buffer, count) __outsw((void __iomem *)(long)addr, buffer, count) | 119 | #define outsw(addr, buffer, count) __outsw(PCI_IOBASE + (addr), buffer, count) |
| 120 | #define outsl(addr, buffer, count) __outsl((void __iomem *)(long)addr, buffer, count) | 120 | #define outsl(addr, buffer, count) __outsl(PCI_IOBASE + (addr), buffer, count) |
| 121 | 121 | ||
| 122 | #ifdef CONFIG_64BIT | 122 | #ifdef CONFIG_64BIT |
| 123 | __io_reads_ins(reads, u64, q, __io_br(), __io_ar(addr)) | 123 | __io_reads_ins(reads, u64, q, __io_br(), __io_ar(addr)) |
| 124 | #define readsq(addr, buffer, count) __readsq(addr, buffer, count) | 124 | #define readsq(addr, buffer, count) __readsq(addr, buffer, count) |
| 125 | 125 | ||
| 126 | __io_reads_ins(ins, u64, q, __io_pbr(), __io_par(addr)) | 126 | __io_reads_ins(ins, u64, q, __io_pbr(), __io_par(addr)) |
| 127 | #define insq(addr, buffer, count) __insq((void __iomem *)addr, buffer, count) | 127 | #define insq(addr, buffer, count) __insq(PCI_IOBASE + (addr), buffer, count) |
| 128 | 128 | ||
| 129 | __io_writes_outs(writes, u64, q, __io_bw(), __io_aw()) | 129 | __io_writes_outs(writes, u64, q, __io_bw(), __io_aw()) |
| 130 | #define writesq(addr, buffer, count) __writesq(addr, buffer, count) | 130 | #define writesq(addr, buffer, count) __writesq(addr, buffer, count) |
| 131 | 131 | ||
| 132 | __io_writes_outs(outs, u64, q, __io_pbr(), __io_paw()) | 132 | __io_writes_outs(outs, u64, q, __io_pbr(), __io_paw()) |
| 133 | #define outsq(addr, buffer, count) __outsq((void __iomem *)addr, buffer, count) | 133 | #define outsq(addr, buffer, count) __outsq(PCI_IOBASE + (addr), buffer, count) |
| 134 | #endif | 134 | #endif |
| 135 | 135 | ||
| 136 | #include <asm-generic/io.h> | 136 | #include <asm-generic/io.h> |
| @@ -16,7 +16,6 @@ typedef struct { · 15 unmodified lines | |||
| 16 | atomic_long_t id; | 16 | atomic_long_t id; |
| 17 | #endif | 17 | #endif |
| 18 | void *vdso; | 18 | void *vdso; |
| 19 | void *vdso_info; | ||
| 20 | #ifdef CONFIG_SMP | 19 | #ifdef CONFIG_SMP |
| 21 | /* A local icache flush is needed before user execution can resume. */ | 20 | /* A local icache flush is needed before user execution can resume. */ |
| 22 | cpumask_t icache_stale_mask; | 21 | cpumask_t icache_stale_mask; |
| @@ -30,8 +30,10 @@ · 29 unmodified lines | |||
| 30 | #define AT_L1D_CACHEGEOMETRY 43 | 30 | #define AT_L1D_CACHEGEOMETRY 43 |
| 31 | #define AT_L2_CACHESIZE 44 | 31 | #define AT_L2_CACHESIZE 44 |
| 32 | #define AT_L2_CACHEGEOMETRY 45 | 32 | #define AT_L2_CACHEGEOMETRY 45 |
| 33 | #define AT_L3_CACHESIZE 46 | ||
| 34 | #define AT_L3_CACHEGEOMETRY 47 | ||
| 33 | 35 | ||
| 34 | /* entries in ARCH_DLINFO */ | 36 | /* entries in ARCH_DLINFO */ |
| 35 | #define AT_VECTOR_SIZE_ARCH 7 | 37 | #define AT_VECTOR_SIZE_ARCH 9 |
| 36 | 38 | ||
| 37 | #endif /* _UAPI_ASM_RISCV_AUXVEC_H */ | 39 | #endif /* _UAPI_ASM_RISCV_AUXVEC_H */ |
| @@ -3,10 +3,13 @@ · 2 unmodified lines | |||
| 3 | * Copyright (C) 2012 Regents of the University of California | 3 | * Copyright (C) 2012 Regents of the University of California |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <linux/cpu.h> | ||
| 6 | #include <linux/init.h> | 7 | #include <linux/init.h> |
| 7 | #include <linux/seq_file.h> | 8 | #include <linux/seq_file.h> |
| 8 | #include <linux/of.h> | 9 | #include <linux/of.h> |
| 10 | #include <asm/csr.h> | ||
| 9 | #include <asm/hwcap.h> | 11 | #include <asm/hwcap.h> |
| 12 | #include <asm/sbi.h> | ||
| 10 | #include <asm/smp.h> | 13 | #include <asm/smp.h> |
| 11 | #include <asm/pgtable.h> | 14 | #include <asm/pgtable.h> |
| 12 | 15 | ||
| @@ -68,6 +71,50 @@ int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid) · 55 unmodified lines | |||
| 68 | } | 71 | } |
| 69 | 72 | ||
| 70 | #ifdef CONFIG_PROC_FS | 73 | #ifdef CONFIG_PROC_FS |
| 74 | |||
| 75 | struct riscv_cpuinfo { | ||
| 76 | unsigned long mvendorid; | ||
| 77 | unsigned long marchid; | ||
| 78 | unsigned long mimpid; | ||
| 79 | }; | ||
| 80 | static DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo); | ||
| 81 | |||
| 82 | static int riscv_cpuinfo_starting(unsigned int cpu) | ||
| 83 | { | ||
| 84 | struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo); | ||
| 85 | |||
| 86 | #if IS_ENABLED(CONFIG_RISCV_SBI) | ||
| 87 | ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid(); | ||
| 88 | ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid(); | ||
| 89 | ci->mimpid = sbi_spec_is_0_1() ? 0 : sbi_get_mimpid(); | ||
| 90 | #elif IS_ENABLED(CONFIG_RISCV_M_MODE) | ||
| 91 | ci->mvendorid = csr_read(CSR_MVENDORID); | ||
| 92 | ci->marchid = csr_read(CSR_MARCHID); | ||
| 93 | ci->mimpid = csr_read(CSR_MIMPID); | ||
| 94 | #else | ||
| 95 | ci->mvendorid = 0; | ||
| 96 | ci->marchid = 0; | ||
| 97 | ci->mimpid = 0; | ||
| 98 | #endif | ||
| 99 | |||
| 100 | return 0; | ||
| 101 | } | ||
| 102 | |||
| 103 | static int __init riscv_cpuinfo_init(void) | ||
| 104 | { | ||
| 105 | int ret; | ||
| 106 | |||
| 107 | ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "riscv/cpuinfo:starting", | ||
| 108 | riscv_cpuinfo_starting, NULL); | ||
| 109 | if (ret < 0) { | ||
| 110 | pr_err("cpuinfo: failed to register hotplug callbacks.\n"); | ||
| 111 | return ret; | ||
| 112 | } | ||
| 113 | |||
| 114 | return 0; | ||
| 115 | } | ||
| 116 | device_initcall(riscv_cpuinfo_init); | ||
| 117 | |||
| 71 | #define __RISCV_ISA_EXT_DATA(UPROP, EXTID) \ | 118 | #define __RISCV_ISA_EXT_DATA(UPROP, EXTID) \ |
| 72 | { \ | 119 | { \ |
| 73 | .uprop = #UPROP, \ | 120 | .uprop = #UPROP, \ |
| @@ -186,6 +233,7 @@ static int c_show(struct seq_file *m, void *v) · 112 unmodified lines | |||
| 186 | { | 233 | { |
| 187 | unsigned long cpu_id = (unsigned long)v - 1; | 234 | unsigned long cpu_id = (unsigned long)v - 1; |
| 188 | struct device_node *node = of_get_cpu_node(cpu_id, NULL); | 235 | struct device_node *node = of_get_cpu_node(cpu_id, NULL); |
| 236 | struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id); | ||
| 189 | const char *compat, *isa; | 237 | const char *compat, *isa; |
| 190 | 238 | ||
| 191 | seq_printf(m, "processor\t: %lu\n", cpu_id); | 239 | seq_printf(m, "processor\t: %lu\n", cpu_id); |
| @@ -196,6 +244,9 @@ static int c_show(struct seq_file *m, void *v) · 4 unmodified lines | |||
| 196 | if (!of_property_read_string(node, "compatible", &compat) | 244 | if (!of_property_read_string(node, "compatible", &compat) |
| 197 | && strcmp(compat, "riscv")) | 245 | && strcmp(compat, "riscv")) |
| 198 | seq_printf(m, "uarch\t\t: %s\n", compat); | 246 | seq_printf(m, "uarch\t\t: %s\n", compat); |
| 247 | seq_printf(m, "mvendorid\t: 0x%lx\n", ci->mvendorid); | ||
| 248 | seq_printf(m, "marchid\t\t: 0x%lx\n", ci->marchid); | ||
| 249 | seq_printf(m, "mimpid\t\t: 0x%lx\n", ci->mimpid); | ||
| 199 | seq_puts(m, "\n"); | 250 | seq_puts(m, "\n"); |
| 200 | of_node_put(node); | 251 | of_node_put(node); |
| 201 | 252 | ||
| @@ -254,35 +254,28 @@ void __init riscv_fill_hwcap(void) · 253 unmodified lines | |||
| 254 | #ifdef CONFIG_RISCV_ALTERNATIVE | 254 | #ifdef CONFIG_RISCV_ALTERNATIVE |
| 255 | static bool __init_or_module cpufeature_probe_svpbmt(unsigned int stage) | 255 | static bool __init_or_module cpufeature_probe_svpbmt(unsigned int stage) |
| 256 | { | 256 | { |
| 257 | #ifdef CONFIG_RISCV_ISA_SVPBMT | 257 | if (!IS_ENABLED(CONFIG_RISCV_ISA_SVPBMT)) |
| 258 | switch (stage) { | 258 | return false; |
| 259 | case RISCV_ALTERNATIVES_EARLY_BOOT: | 259 | |
| 260 | if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) | ||
| 260 | return false; | 261 | return false; |
| 261 | default: | ||
| 262 | return riscv_isa_extension_available(NULL, SVPBMT); | ||
| 263 | } | ||
| 264 | #endif | ||
| 265 | 262 | ||
| 266 | return false; | 263 | return riscv_isa_extension_available(NULL, SVPBMT); |
| 267 | } | 264 | } |
| 268 | 265 | ||
| 269 | static bool __init_or_module cpufeature_probe_zicbom(unsigned int stage) | 266 | static bool __init_or_module cpufeature_probe_zicbom(unsigned int stage) |
| 270 | { | 267 | { |
| 271 | #ifdef CONFIG_RISCV_ISA_ZICBOM | 268 | if (!IS_ENABLED(CONFIG_RISCV_ISA_ZICBOM)) |
| 272 | switch (stage) { | 269 | return false; |
| 273 | case RISCV_ALTERNATIVES_EARLY_BOOT: | 270 | |
| 271 | if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) | ||
| 272 | return false; | ||
| 273 | |||
| 274 | if (!riscv_isa_extension_available(NULL, ZICBOM)) | ||
| 274 | return false; | 275 | return false; |
| 275 | default: | ||
| 276 | if (riscv_isa_extension_available(NULL, ZICBOM)) { | ||
| 277 | riscv_noncoherent_supported(); | ||
| 278 | return true; | ||
| 279 | } else { | ||
| 280 | return false; | ||
| 281 | } | ||
| 282 | } | ||
| 283 | #endif | ||
| 284 | 276 | ||
| 285 | return false; | 277 | riscv_noncoherent_supported(); |
| 278 | return true; | ||
| 286 | } | 279 | } |
| 287 | 280 | ||
| 288 | /* | 281 | /* |
| @@ -297,10 +290,10 @@ static u32 __init_or_module cpufeature_probe(unsigned int stage) · 8 unmodified lines | |||
| 297 | u32 cpu_req_feature = 0; | 290 | u32 cpu_req_feature = 0; |
| 298 | 291 | ||
| 299 | if (cpufeature_probe_svpbmt(stage)) | 292 | if (cpufeature_probe_svpbmt(stage)) |
| 300 | cpu_req_feature |= (1U << CPUFEATURE_SVPBMT); | 293 | cpu_req_feature |= BIT(CPUFEATURE_SVPBMT); |
| 301 | 294 | ||
| 302 | if (cpufeature_probe_zicbom(stage)) | 295 | if (cpufeature_probe_zicbom(stage)) |
| 303 | cpu_req_feature |= (1U << CPUFEATURE_ZICBOM); | 296 | cpu_req_feature |= BIT(CPUFEATURE_ZICBOM); |
| 304 | 297 | ||
| 305 | return cpu_req_feature; | 298 | return cpu_req_feature; |
| 306 | } | 299 | } |
| @@ -252,10 +252,10 @@ static void __init parse_dtb(void) · 251 unmodified lines | |||
| 252 | pr_info("Machine model: %s\n", name); | 252 | pr_info("Machine model: %s\n", name); |
| 253 | dump_stack_set_arch_desc("%s (DT)", name); | 253 | dump_stack_set_arch_desc("%s (DT)", name); |
| 254 | } | 254 | } |
| 255 | return; | 255 | } else { |
| 256 | pr_err("No DTB passed to the kernel\n"); | ||
| 256 | } | 257 | } |
| 257 | 258 | ||
| 258 | pr_err("No DTB passed to the kernel\n"); | ||
| 259 | #ifdef CONFIG_CMDLINE_FORCE | 259 | #ifdef CONFIG_CMDLINE_FORCE |
| 260 | strscpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); | 260 | strscpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); |
| 261 | pr_info("Forcing kernel command line to: %s\n", boot_command_line); | 261 | pr_info("Forcing kernel command line to: %s\n", boot_command_line); |
| @@ -18,9 +18,6 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long len, · 17 unmodified lines | |||
| 18 | if (unlikely(offset & (~PAGE_MASK >> page_shift_offset))) | 18 | if (unlikely(offset & (~PAGE_MASK >> page_shift_offset))) |
| 19 | return -EINVAL; | 19 | return -EINVAL; |
| 20 | 20 | ||
| 21 | if (unlikely((prot & PROT_WRITE) && !(prot & PROT_READ))) | ||
| 22 | return -EINVAL; | ||
| 23 | |||
| 24 | return ksys_mmap_pgoff(addr, len, prot, flags, fd, | 21 | return ksys_mmap_pgoff(addr, len, prot, flags, fd, |
| 25 | offset >> (PAGE_SHIFT - page_shift_offset)); | 22 | offset >> (PAGE_SHIFT - page_shift_offset)); |
| 26 | } | 23 | } |
| @@ -33,6 +33,7 @@ void die(struct pt_regs *regs, const char *str) · 32 unmodified lines | |||
| 33 | { | 33 | { |
| 34 | static int die_counter; | 34 | static int die_counter; |
| 35 | int ret; | 35 | int ret; |
| 36 | long cause; | ||
| 36 | 37 | ||
| 37 | oops_enter(); | 38 | oops_enter(); |
| 38 | 39 | ||
| @@ -42,11 +43,13 @@ void die(struct pt_regs *regs, const char *str) · 3 unmodified lines | |||
| 42 | 43 | ||
| 43 | pr_emerg("%s [#%d]\n", str, ++die_counter); | 44 | pr_emerg("%s [#%d]\n", str, ++die_counter); |
| 44 | print_modules(); | 45 | print_modules(); |
| 45 | show_regs(regs); | 46 | if (regs) |
| 47 | show_regs(regs); | ||
| 46 | 48 | ||
| 47 | ret = notify_die(DIE_OOPS, str, regs, 0, regs->cause, SIGSEGV); | 49 | cause = regs ? regs->cause : -1; |
| 50 | ret = notify_die(DIE_OOPS, str, regs, 0, cause, SIGSEGV); | ||
| 48 | 51 | ||
| 49 | if (regs && kexec_should_crash(current)) | 52 | if (kexec_should_crash(current)) |
| 50 | crash_kexec(regs); | 53 | crash_kexec(regs); |
| 51 | 54 | ||
| 52 | bust_spinlocks(0); | 55 | bust_spinlocks(0); |
| @@ -60,6 +60,11 @@ struct __vdso_info { · 59 unmodified lines | |||
| 60 | struct vm_special_mapping *cm; | 60 | struct vm_special_mapping *cm; |
| 61 | }; | 61 | }; |
| 62 | 62 | ||
| 63 | static struct __vdso_info vdso_info; | ||
| 64 | #ifdef CONFIG_COMPAT | ||
| 65 | static struct __vdso_info compat_vdso_info; | ||
| 66 | #endif | ||
| 67 | |||
| 63 | static int vdso_mremap(const struct vm_special_mapping *sm, | 68 | static int vdso_mremap(const struct vm_special_mapping *sm, |
| 64 | struct vm_area_struct *new_vma) | 69 | struct vm_area_struct *new_vma) |
| 65 | { | 70 | { |
| @@ -115,15 +120,18 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns) · 49 unmodified lines | |||
| 115 | struct mm_struct *mm = task->mm; | 120 | struct mm_struct *mm = task->mm; |
| 116 | struct vm_area_struct *vma; | 121 | struct vm_area_struct *vma; |
| 117 | VMA_ITERATOR(vmi, mm, 0); | 122 | VMA_ITERATOR(vmi, mm, 0); |
| 118 | struct __vdso_info *vdso_info = mm->context.vdso_info; | ||
| 119 | 123 | ||
| 120 | mmap_read_lock(mm); | 124 | mmap_read_lock(mm); |
| 121 | 125 | ||
| 122 | for_each_vma(vmi, vma) { | 126 | for_each_vma(vmi, vma) { |
| 123 | unsigned long size = vma->vm_end - vma->vm_start; | 127 | unsigned long size = vma->vm_end - vma->vm_start; |
| 124 | 128 | ||
| 125 | if (vma_is_special_mapping(vma, vdso_info->dm)) | 129 | if (vma_is_special_mapping(vma, vdso_info.dm)) |
| 126 | zap_page_range(vma, vma->vm_start, size); | 130 | zap_page_range(vma, vma->vm_start, size); |
| 131 | #ifdef CONFIG_COMPAT | ||
| 132 | if (vma_is_special_mapping(vma, compat_vdso_info.dm)) | ||
| 133 | zap_page_range(vma, vma->vm_start, size); | ||
| 134 | #endif | ||
| 127 | } | 135 | } |
| 128 | 136 | ||
| 129 | mmap_read_unlock(mm); | 137 | mmap_read_unlock(mm); |
| @@ -265,7 +273,6 @@ static int __setup_additional_pages(struct mm_struct *mm, · 135 unmodified lines | |||
| 265 | 273 | ||
| 266 | vdso_base += VVAR_SIZE; | 274 | vdso_base += VVAR_SIZE; |
| 267 | mm->context.vdso = (void *)vdso_base; | 275 | mm->context.vdso = (void *)vdso_base; |
| 268 | mm->context.vdso_info = (void *)vdso_info; | ||
| 269 | 276 | ||
| 270 | ret = | 277 | ret = |
| 271 | _install_special_mapping(mm, vdso_base, vdso_text_len, | 278 | _install_special_mapping(mm, vdso_base, vdso_text_len, |
| @@ -184,7 +184,8 @@ static inline bool access_error(unsigned long cause, struct vm_area_struct *vma) · 183 unmodified lines | |||
| 184 | } | 184 | } |
| 185 | break; | 185 | break; |
| 186 | case EXC_LOAD_PAGE_FAULT: | 186 | case EXC_LOAD_PAGE_FAULT: |
| 187 | if (!(vma->vm_flags & VM_READ)) { | 187 | /* Write implies read */ |
| 188 | if (!(vma->vm_flags & (VM_READ | VM_WRITE))) { | ||
| 188 | return true; | 189 | return true; |
| 189 | } | 190 | } |
| 190 | break; | 191 | break; |
| @@ -473,7 +473,7 @@ config EDAC_ALTERA_SDMMC · 472 unmodified lines | |||
| 473 | 473 | ||
| 474 | config EDAC_SIFIVE | 474 | config EDAC_SIFIVE |
| 475 | bool "Sifive platform EDAC driver" | 475 | bool "Sifive platform EDAC driver" |
| 476 | depends on EDAC=y && SIFIVE_L2 | 476 | depends on EDAC=y && SIFIVE_CCACHE |
| 477 | help | 477 | help |
| 478 | Support for error detection and correction on the SiFive SoCs. | 478 | Support for error detection and correction on the SiFive SoCs. |
| 479 | 479 | ||
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | /* | 2 | /* |
| 3 | * SiFive Platform EDAC Driver | 3 | * SiFive Platform EDAC Driver |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2018-2019 SiFive, Inc. | 5 | * Copyright (C) 2018-2022 SiFive, Inc. |
| 6 | * | 6 | * |
| 7 | * This driver is partially based on octeon_edac-pc.c | 7 | * This driver is partially based on octeon_edac-pc.c |
| 8 | * | 8 | * |
| @@ -10,7 +10,7 @@ · 1 unmodified line | |||
| 10 | #include <linux/edac.h> | 10 | #include <linux/edac.h> |
| 11 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
| 12 | #include "edac_module.h" | 12 | #include "edac_module.h" |
| 13 | #include <soc/sifive/sifive_l2_cache.h> | 13 | #include <soc/sifive/sifive_ccache.h> |
| 14 | 14 | ||
| 15 | #define DRVNAME "sifive_edac" | 15 | #define DRVNAME "sifive_edac" |
| 16 | 16 | ||
| @@ -32,9 +32,9 @@ int ecc_err_event(struct notifier_block *this, unsigned long event, void *ptr) · 15 unmodified lines | |||
| 32 | 32 | ||
| 33 | p = container_of(this, struct sifive_edac_priv, notifier); | 33 | p = container_of(this, struct sifive_edac_priv, notifier); |
| 34 | 34 | ||
| 35 | if (event == SIFIVE_L2_ERR_TYPE_UE) | 35 | if (event == SIFIVE_CCACHE_ERR_TYPE_UE) |
| 36 | edac_device_handle_ue(p->dci, 0, 0, msg); | 36 | edac_device_handle_ue(p->dci, 0, 0, msg); |
| 37 | else if (event == SIFIVE_L2_ERR_TYPE_CE) | 37 | else if (event == SIFIVE_CCACHE_ERR_TYPE_CE) |
| 38 | edac_device_handle_ce(p->dci, 0, 0, msg); | 38 | edac_device_handle_ce(p->dci, 0, 0, msg); |
| 39 | 39 | ||
| 40 | return NOTIFY_OK; | 40 | return NOTIFY_OK; |
| @@ -67,7 +67,7 @@ static int ecc_register(struct platform_device *pdev) · 26 unmodified lines | |||
| 67 | goto err; | 67 | goto err; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | register_sifive_l2_error_notifier(&p->notifier); | 70 | register_sifive_ccache_error_notifier(&p->notifier); |
| 71 | 71 | ||
| 72 | return 0; | 72 | return 0; |
| 73 | 73 | ||
| @@ -81,7 +81,7 @@ static int ecc_unregister(struct platform_device *pdev) · 7 unmodified lines | |||
| 81 | { | 81 | { |
| 82 | struct sifive_edac_priv *p = platform_get_drvdata(pdev); | 82 | struct sifive_edac_priv *p = platform_get_drvdata(pdev); |
| 83 | 83 | ||
| 84 | unregister_sifive_l2_error_notifier(&p->notifier); | 84 | unregister_sifive_ccache_error_notifier(&p->notifier); |
| 85 | edac_device_del_device(&pdev->dev); | 85 | edac_device_del_device(&pdev->dev); |
| 86 | edac_device_free_ctl_info(p->dci); | 86 | edac_device_free_ctl_info(p->dci); |
| 87 | 87 | ||
| @@ -652,8 +652,11 @@ static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node) · 651 unmodified lines | |||
| 652 | struct riscv_pmu *pmu = hlist_entry_safe(node, struct riscv_pmu, node); | 652 | struct riscv_pmu *pmu = hlist_entry_safe(node, struct riscv_pmu, node); |
| 653 | struct cpu_hw_events *cpu_hw_evt = this_cpu_ptr(pmu->hw_events); | 653 | struct cpu_hw_events *cpu_hw_evt = this_cpu_ptr(pmu->hw_events); |
| 654 | 654 | ||
| 655 | /* Enable the access for TIME csr only from the user mode now */ | 655 | /* |
| 656 | csr_write(CSR_SCOUNTEREN, 0x2); | 656 | * Enable the access for CYCLE, TIME, and INSTRET CSRs from userspace, |
| 657 | * as is necessary to maintain uABI compatibility. | ||
| 658 | */ | ||
| 659 | csr_write(CSR_SCOUNTEREN, 0x7); | ||
| 657 | 660 | ||
| 658 | /* Stop all the counters so that they can be enabled from perf */ | 661 | /* Stop all the counters so that they can be enabled from perf */ |
| 659 | pmu_sbi_stop_all(pmu); | 662 | pmu_sbi_stop_all(pmu); |
| @@ -2,9 +2,9 @@ · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | if SOC_SIFIVE | 3 | if SOC_SIFIVE |
| 4 | 4 | ||
| 5 | config SIFIVE_L2 | 5 | config SIFIVE_CCACHE |
| 6 | bool "Sifive L2 Cache controller" | 6 | bool "Sifive Composable Cache controller" |
| 7 | help | 7 | help |
| 8 | Support for the L2 cache controller on SiFive platforms. | 8 | Support for the composable cache controller on SiFive platforms. |
| 9 | 9 | ||
| 10 | endif | 10 | endif |
| @@ -1,3 +1,3 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | ||
| 3 | obj-$(CONFIG_SIFIVE_L2) += sifive_l2_cache.o | 3 | obj-$(CONFIG_SIFIVE_CCACHE) += sifive_ccache.o |
| @@ -0,0 +1,255 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * SiFive composable cache controller Driver | ||
| 4 | * | ||
| 5 | * Copyright (C) 2018-2022 SiFive, Inc. | ||
| 6 | * | ||
| 7 | */ | ||
| 8 | |||
| 9 | #define pr_fmt(fmt) "CCACHE: " fmt | ||
| 10 | |||
| 11 | #include <linux/debugfs.h> | ||
| 12 | #include <linux/interrupt.h> | ||
| 13 | #include <linux/of_irq.h> | ||
| 14 | #include <linux/of_address.h> | ||
| 15 | #include <linux/device.h> | ||
| 16 | #include <linux/bitfield.h> | ||
| 17 | #include <asm/cacheinfo.h> | ||
| 18 | #include <soc/sifive/sifive_ccache.h> | ||
| 19 | |||
| 20 | #define SIFIVE_CCACHE_DIRECCFIX_LOW 0x100 | ||
| 21 | #define SIFIVE_CCACHE_DIRECCFIX_HIGH 0x104 | ||
| 22 | #define SIFIVE_CCACHE_DIRECCFIX_COUNT 0x108 | ||
| 23 | |||
| 24 | #define SIFIVE_CCACHE_DIRECCFAIL_LOW 0x120 | ||
| 25 | #define SIFIVE_CCACHE_DIRECCFAIL_HIGH 0x124 | ||
| 26 | #define SIFIVE_CCACHE_DIRECCFAIL_COUNT 0x128 | ||
| 27 | |||
| 28 | #define SIFIVE_CCACHE_DATECCFIX_LOW 0x140 | ||
| 29 | #define SIFIVE_CCACHE_DATECCFIX_HIGH 0x144 | ||
| 30 | #define SIFIVE_CCACHE_DATECCFIX_COUNT 0x148 | ||
| 31 | |||
| 32 | #define SIFIVE_CCACHE_DATECCFAIL_LOW 0x160 | ||
| 33 | #define SIFIVE_CCACHE_DATECCFAIL_HIGH 0x164 | ||
| 34 | #define SIFIVE_CCACHE_DATECCFAIL_COUNT 0x168 | ||
| 35 | |||
| 36 | #define SIFIVE_CCACHE_CONFIG 0x00 | ||
| 37 | #define SIFIVE_CCACHE_CONFIG_BANK_MASK GENMASK_ULL(7, 0) | ||
| 38 | #define SIFIVE_CCACHE_CONFIG_WAYS_MASK GENMASK_ULL(15, 8) | ||
| 39 | #define SIFIVE_CCACHE_CONFIG_SETS_MASK GENMASK_ULL(23, 16) | ||
| 40 | #define SIFIVE_CCACHE_CONFIG_BLKS_MASK GENMASK_ULL(31, 24) | ||
| 41 | |||
| 42 | #define SIFIVE_CCACHE_WAYENABLE 0x08 | ||
| 43 | #define SIFIVE_CCACHE_ECCINJECTERR 0x40 | ||
| 44 | |||
| 45 | #define SIFIVE_CCACHE_MAX_ECCINTR 4 | ||
| 46 | |||
| 47 | static void __iomem *ccache_base; | ||
| 48 | static int g_irq[SIFIVE_CCACHE_MAX_ECCINTR]; | ||
| 49 | static struct riscv_cacheinfo_ops ccache_cache_ops; | ||
| 50 | static int level; | ||
| 51 | |||
| 52 | enum { | ||
| 53 | DIR_CORR = 0, | ||
| 54 | DATA_CORR, | ||
| 55 | DATA_UNCORR, | ||
| 56 | DIR_UNCORR, | ||
| 57 | }; | ||
| 58 | |||
| 59 | #ifdef CONFIG_DEBUG_FS | ||
| 60 | static struct dentry *sifive_test; | ||
| 61 | |||
| 62 | static ssize_t ccache_write(struct file *file, const char __user *data, | ||
| 63 | size_t count, loff_t *ppos) | ||
| 64 | { | ||
| 65 | unsigned int val; | ||
| 66 | |||
| 67 | if (kstrtouint_from_user(data, count, 0, &val)) | ||
| 68 | return -EINVAL; | ||
| 69 | if ((val < 0xFF) || (val >= 0x10000 && val < 0x100FF)) | ||
| 70 | writel(val, ccache_base + SIFIVE_CCACHE_ECCINJECTERR); | ||
| 71 | else | ||
| 72 | return -EINVAL; | ||
| 73 | return count; | ||
| 74 | } | ||
| 75 | |||
| 76 | static const struct file_operations ccache_fops = { | ||
| 77 | .owner = THIS_MODULE, | ||
| 78 | .open = simple_open, | ||
| 79 | .write = ccache_write | ||
| 80 | }; | ||
| 81 | |||
| 82 | static void setup_sifive_debug(void) | ||
| 83 | { | ||
| 84 | sifive_test = debugfs_create_dir("sifive_ccache_cache", NULL); | ||
| 85 | |||
| 86 | debugfs_create_file("sifive_debug_inject_error", 0200, | ||
| 87 | sifive_test, NULL, &ccache_fops); | ||
| 88 | } | ||
| 89 | #endif | ||
| 90 | |||
| 91 | static void ccache_config_read(void) | ||
| 92 | { | ||
| 93 | u32 cfg; | ||
| 94 | |||
| 95 | cfg = readl(ccache_base + SIFIVE_CCACHE_CONFIG); | ||
| 96 | pr_info("%llu banks, %llu ways, sets/bank=%llu, bytes/block=%llu\n", | ||
| 97 | FIELD_GET(SIFIVE_CCACHE_CONFIG_BANK_MASK, cfg), | ||
| 98 | FIELD_GET(SIFIVE_CCACHE_CONFIG_WAYS_MASK, cfg), | ||
| 99 | BIT_ULL(FIELD_GET(SIFIVE_CCACHE_CONFIG_SETS_MASK, cfg)), | ||
| 100 | BIT_ULL(FIELD_GET(SIFIVE_CCACHE_CONFIG_BLKS_MASK, cfg))); | ||
| 101 | |||
| 102 | cfg = readl(ccache_base + SIFIVE_CCACHE_WAYENABLE); | ||
| 103 | pr_info("Index of the largest way enabled: %u\n", cfg); | ||
| 104 | } | ||
| 105 | |||
| 106 | static const struct of_device_id sifive_ccache_ids[] = { | ||
| 107 | { .compatible = "sifive,fu540-c000-ccache" }, | ||
| 108 | { .compatible = "sifive,fu740-c000-ccache" }, | ||
| 109 | { .compatible = "sifive,ccache0" }, | ||
| 110 | { /* end of table */ } | ||
| 111 | }; | ||
| 112 | |||
| 113 | static ATOMIC_NOTIFIER_HEAD(ccache_err_chain); | ||
| 114 | |||
| 115 | int register_sifive_ccache_error_notifier(struct notifier_block *nb) | ||
| 116 | { | ||
| 117 | return atomic_notifier_chain_register(&ccache_err_chain, nb); | ||
| 118 | } | ||
| 119 | EXPORT_SYMBOL_GPL(register_sifive_ccache_error_notifier); | ||
| 120 | |||
| 121 | int unregister_sifive_ccache_error_notifier(struct notifier_block *nb) | ||
| 122 | { | ||
| 123 | return atomic_notifier_chain_unregister(&ccache_err_chain, nb); | ||
| 124 | } | ||
| 125 | EXPORT_SYMBOL_GPL(unregister_sifive_ccache_error_notifier); | ||
| 126 | |||
| 127 | static int ccache_largest_wayenabled(void) | ||
| 128 | { | ||
| 129 | return readl(ccache_base + SIFIVE_CCACHE_WAYENABLE) & 0xFF; | ||
| 130 | } | ||
| 131 | |||
| 132 | static ssize_t number_of_ways_enabled_show(struct device *dev, | ||
| 133 | struct device_attribute *attr, | ||
| 134 | char *buf) | ||
| 135 | { | ||
| 136 | return sprintf(buf, "%u\n", ccache_largest_wayenabled()); | ||
| 137 | } | ||
| 138 | |||
| 139 | static DEVICE_ATTR_RO(number_of_ways_enabled); | ||
| 140 | |||
| 141 | static struct attribute *priv_attrs[] = { | ||
| 142 | &dev_attr_number_of_ways_enabled.attr, | ||
| 143 | NULL, | ||
| 144 | }; | ||
| 145 | |||
| 146 | static const struct attribute_group priv_attr_group = { | ||
| 147 | .attrs = priv_attrs, | ||
| 148 | }; | ||
| 149 | |||
| 150 | static const struct attribute_group *ccache_get_priv_group(struct cacheinfo | ||
| 151 | *this_leaf) | ||
| 152 | { | ||
| 153 | /* We want to use private group for composable cache only */ | ||
| 154 | if (this_leaf->level == level) | ||
| 155 | return &priv_attr_group; | ||
| 156 | else | ||
| 157 | return NULL; | ||
| 158 | } | ||
| 159 | |||
| 160 | static irqreturn_t ccache_int_handler(int irq, void *device) | ||
| 161 | { | ||
| 162 | unsigned int add_h, add_l; | ||
| 163 | |||
| 164 | if (irq == g_irq[DIR_CORR]) { | ||
| 165 | add_h = readl(ccache_base + SIFIVE_CCACHE_DIRECCFIX_HIGH); | ||
| 166 | add_l = readl(ccache_base + SIFIVE_CCACHE_DIRECCFIX_LOW); | ||
| 167 | pr_err("DirError @ 0x%08X.%08X\n", add_h, add_l); | ||
| 168 | /* Reading this register clears the DirError interrupt sig */ | ||
| 169 | readl(ccache_base + SIFIVE_CCACHE_DIRECCFIX_COUNT); | ||
| 170 | atomic_notifier_call_chain(&ccache_err_chain, | ||
| 171 | SIFIVE_CCACHE_ERR_TYPE_CE, | ||
| 172 | "DirECCFix"); | ||
| 173 | } | ||
| 174 | if (irq == g_irq[DIR_UNCORR]) { | ||
| 175 | add_h = readl(ccache_base + SIFIVE_CCACHE_DIRECCFAIL_HIGH); | ||
| 176 | add_l = readl(ccache_base + SIFIVE_CCACHE_DIRECCFAIL_LOW); | ||
| 177 | /* Reading this register clears the DirFail interrupt sig */ | ||
| 178 | readl(ccache_base + SIFIVE_CCACHE_DIRECCFAIL_COUNT); | ||
| 179 | atomic_notifier_call_chain(&ccache_err_chain, | ||
| 180 | SIFIVE_CCACHE_ERR_TYPE_UE, | ||
| 181 | "DirECCFail"); | ||
| 182 | panic("CCACHE: DirFail @ 0x%08X.%08X\n", add_h, add_l); | ||
| 183 | } | ||
| 184 | if (irq == g_irq[DATA_CORR]) { | ||
| 185 | add_h = readl(ccache_base + SIFIVE_CCACHE_DATECCFIX_HIGH); | ||
| 186 | add_l = readl(ccache_base + SIFIVE_CCACHE_DATECCFIX_LOW); | ||
| 187 | pr_err("DataError @ 0x%08X.%08X\n", add_h, add_l); | ||
| 188 | /* Reading this register clears the DataError interrupt sig */ | ||
| 189 | readl(ccache_base + SIFIVE_CCACHE_DATECCFIX_COUNT); | ||
| 190 | atomic_notifier_call_chain(&ccache_err_chain, | ||
| 191 | SIFIVE_CCACHE_ERR_TYPE_CE, | ||
| 192 | "DatECCFix"); | ||
| 193 | } | ||
| 194 | if (irq == g_irq[DATA_UNCORR]) { | ||
| 195 | add_h = readl(ccache_base + SIFIVE_CCACHE_DATECCFAIL_HIGH); | ||
| 196 | add_l = readl(ccache_base + SIFIVE_CCACHE_DATECCFAIL_LOW); | ||
| 197 | pr_err("DataFail @ 0x%08X.%08X\n", add_h, add_l); | ||
| 198 | /* Reading this register clears the DataFail interrupt sig */ | ||
| 199 | readl(ccache_base + SIFIVE_CCACHE_DATECCFAIL_COUNT); | ||
| 200 | atomic_notifier_call_chain(&ccache_err_chain, | ||
| 201 | SIFIVE_CCACHE_ERR_TYPE_UE, | ||
| 202 | "DatECCFail"); | ||
| 203 | } | ||
| 204 | |||
| 205 | return IRQ_HANDLED; | ||
| 206 | } | ||
| 207 | |||
| 208 | static int __init sifive_ccache_init(void) | ||
| 209 | { | ||
| 210 | struct device_node *np; | ||
| 211 | struct resource res; | ||
| 212 | int i, rc, intr_num; | ||
| 213 | |||
| 214 | np = of_find_matching_node(NULL, sifive_ccache_ids); | ||
| 215 | if (!np) | ||
| 216 | return -ENODEV; | ||
| 217 | |||
| 218 | if (of_address_to_resource(np, 0, &res)) | ||
| 219 | return -ENODEV; | ||
| 220 | |||
| 221 | ccache_base = ioremap(res.start, resource_size(&res)); | ||
| 222 | if (!ccache_base) | ||
| 223 | return -ENOMEM; | ||
| 224 | |||
| 225 | if (of_property_read_u32(np, "cache-level", &level)) | ||
| 226 | return -ENOENT; | ||
| 227 | |||
| 228 | intr_num = of_property_count_u32_elems(np, "interrupts"); | ||
| 229 | if (!intr_num) { | ||
| 230 | pr_err("No interrupts property\n"); | ||
| 231 | return -ENODEV; | ||
| 232 | } | ||
| 233 | |||
| 234 | for (i = 0; i < intr_num; i++) { | ||
| 235 | g_irq[i] = irq_of_parse_and_map(np, i); | ||
| 236 | rc = request_irq(g_irq[i], ccache_int_handler, 0, "ccache_ecc", | ||
| 237 | NULL); | ||
| 238 | if (rc) { | ||
| 239 | pr_err("Could not request IRQ %d\n", g_irq[i]); | ||
| 240 | return rc; | ||
| 241 | } | ||
| 242 | } | ||
| 243 | |||
| 244 | ccache_config_read(); | ||
| 245 | |||
| 246 | ccache_cache_ops.get_priv_group = ccache_get_priv_group; | ||
| 247 | riscv_set_cacheinfo_ops(&ccache_cache_ops); | ||
| 248 | |||
| 249 | #ifdef CONFIG_DEBUG_FS | ||
| 250 | setup_sifive_debug(); | ||
| 251 | #endif | ||
| 252 | return 0; | ||
| 253 | } | ||
| 254 | |||
| 255 | device_initcall(sifive_ccache_init); | ||
| @@ -1,237 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * SiFive L2 cache controller Driver | ||
| 4 | * | ||
| 5 | * Copyright (C) 2018-2019 SiFive, Inc. | ||
| 6 | * | ||
| 7 | */ | ||
| 8 | #include <linux/debugfs.h> | ||
| 9 | #include <linux/interrupt.h> | ||
| 10 | #include <linux/of_irq.h> | ||
| 11 | #include <linux/of_address.h> | ||
| 12 | #include <linux/device.h> | ||
| 13 | #include <asm/cacheinfo.h> | ||
| 14 | #include <soc/sifive/sifive_l2_cache.h> | ||
| 15 | |||
| 16 | #define SIFIVE_L2_DIRECCFIX_LOW 0x100 | ||
| 17 | #define SIFIVE_L2_DIRECCFIX_HIGH 0x104 | ||
| 18 | #define SIFIVE_L2_DIRECCFIX_COUNT 0x108 | ||
| 19 | |||
| 20 | #define SIFIVE_L2_DIRECCFAIL_LOW 0x120 | ||
| 21 | #define SIFIVE_L2_DIRECCFAIL_HIGH 0x124 | ||
| 22 | #define SIFIVE_L2_DIRECCFAIL_COUNT 0x128 | ||
| 23 | |||
| 24 | #define SIFIVE_L2_DATECCFIX_LOW 0x140 | ||
| 25 | #define SIFIVE_L2_DATECCFIX_HIGH 0x144 | ||
| 26 | #define SIFIVE_L2_DATECCFIX_COUNT 0x148 | ||
| 27 | |||
| 28 | #define SIFIVE_L2_DATECCFAIL_LOW 0x160 | ||
| 29 | #define SIFIVE_L2_DATECCFAIL_HIGH 0x164 | ||
| 30 | #define SIFIVE_L2_DATECCFAIL_COUNT 0x168 | ||
| 31 | |||
| 32 | #define SIFIVE_L2_CONFIG 0x00 | ||
| 33 | #define SIFIVE_L2_WAYENABLE 0x08 | ||
| 34 | #define SIFIVE_L2_ECCINJECTERR 0x40 | ||
| 35 | |||
| 36 | #define SIFIVE_L2_MAX_ECCINTR 4 | ||
| 37 | |||
| 38 | static void __iomem *l2_base; | ||
| 39 | static int g_irq[SIFIVE_L2_MAX_ECCINTR]; | ||
| 40 | static struct riscv_cacheinfo_ops l2_cache_ops; | ||
| 41 | |||
| 42 | enum { | ||
| 43 | DIR_CORR = 0, | ||
| 44 | DATA_CORR, | ||
| 45 | DATA_UNCORR, | ||
| 46 | DIR_UNCORR, | ||
| 47 | }; | ||
| 48 | |||
| 49 | #ifdef CONFIG_DEBUG_FS | ||
| 50 | static struct dentry *sifive_test; | ||
| 51 | |||
| 52 | static ssize_t l2_write(struct file *file, const char __user *data, | ||
| 53 | size_t count, loff_t *ppos) | ||
| 54 | { | ||
| 55 | unsigned int val; | ||
| 56 | |||
| 57 | if (kstrtouint_from_user(data, count, 0, &val)) | ||
| 58 | return -EINVAL; | ||
| 59 | if ((val < 0xFF) || (val >= 0x10000 && val < 0x100FF)) | ||
| 60 | writel(val, l2_base + SIFIVE_L2_ECCINJECTERR); | ||
| 61 | else | ||
| 62 | return -EINVAL; | ||
| 63 | return count; | ||
| 64 | } | ||
| 65 | |||
| 66 | static const struct file_operations l2_fops = { | ||
| 67 | .owner = THIS_MODULE, | ||
| 68 | .open = simple_open, | ||
| 69 | .write = l2_write | ||
| 70 | }; | ||
| 71 | |||
| 72 | static void setup_sifive_debug(void) | ||
| 73 | { | ||
| 74 | sifive_test = debugfs_create_dir("sifive_l2_cache", NULL); | ||
| 75 | |||
| 76 | debugfs_create_file("sifive_debug_inject_error", 0200, | ||
| 77 | sifive_test, NULL, &l2_fops); | ||
| 78 | } | ||
| 79 | #endif | ||
| 80 | |||
| 81 | static void l2_config_read(void) | ||
| 82 | { | ||
| 83 | u32 regval, val; | ||
| 84 | |||
| 85 | regval = readl(l2_base + SIFIVE_L2_CONFIG); | ||
| 86 | val = regval & 0xFF; | ||
| 87 | pr_info("L2CACHE: No. of Banks in the cache: %d\n", val); | ||
| 88 | val = (regval & 0xFF00) >> 8; | ||
| 89 | pr_info("L2CACHE: No. of ways per bank: %d\n", val); | ||
| 90 | val = (regval & 0xFF0000) >> 16; | ||
| 91 | pr_info("L2CACHE: Sets per bank: %llu\n", (uint64_t)1 << val); | ||
| 92 | val = (regval & 0xFF000000) >> 24; | ||
| 93 | pr_info("L2CACHE: Bytes per cache block: %llu\n", (uint64_t)1 << val); | ||
| 94 | |||
| 95 | regval = readl(l2_base + SIFIVE_L2_WAYENABLE); | ||
| 96 | pr_info("L2CACHE: Index of the largest way enabled: %d\n", regval); | ||
| 97 | } | ||
| 98 | |||
| 99 | static const struct of_device_id sifive_l2_ids[] = { | ||
| 100 | { .compatible = "sifive,fu540-c000-ccache" }, | ||
| 101 | { .compatible = "sifive,fu740-c000-ccache" }, | ||
| 102 | { /* end of table */ }, | ||
| 103 | }; | ||
| 104 | |||
| 105 | static ATOMIC_NOTIFIER_HEAD(l2_err_chain); | ||
| 106 | |||
| 107 | int register_sifive_l2_error_notifier(struct notifier_block *nb) | ||
| 108 | { | ||
| 109 | return atomic_notifier_chain_register(&l2_err_chain, nb); | ||
| 110 | } | ||
| 111 | EXPORT_SYMBOL_GPL(register_sifive_l2_error_notifier); | ||
| 112 | |||
| 113 | int unregister_sifive_l2_error_notifier(struct notifier_block *nb) | ||
| 114 | { | ||
| 115 | return atomic_notifier_chain_unregister(&l2_err_chain, nb); | ||
| 116 | } | ||
| 117 | EXPORT_SYMBOL_GPL(unregister_sifive_l2_error_notifier); | ||
| 118 | |||
| 119 | static int l2_largest_wayenabled(void) | ||
| 120 | { | ||
| 121 | return readl(l2_base + SIFIVE_L2_WAYENABLE) & 0xFF; | ||
| 122 | } | ||
| 123 | |||
| 124 | static ssize_t number_of_ways_enabled_show(struct device *dev, | ||
| 125 | struct device_attribute *attr, | ||
| 126 | char *buf) | ||
| 127 | { | ||
| 128 | return sprintf(buf, "%u\n", l2_largest_wayenabled()); | ||
| 129 | } | ||
| 130 | |||
| 131 | static DEVICE_ATTR_RO(number_of_ways_enabled); | ||
| 132 | |||
| 133 | static struct attribute *priv_attrs[] = { | ||
| 134 | &dev_attr_number_of_ways_enabled.attr, | ||
| 135 | NULL, | ||
| 136 | }; | ||
| 137 | |||
| 138 | static const struct attribute_group priv_attr_group = { | ||
| 139 | .attrs = priv_attrs, | ||
| 140 | }; | ||
| 141 | |||
| 142 | static const struct attribute_group *l2_get_priv_group(struct cacheinfo *this_leaf) | ||
| 143 | { | ||
| 144 | /* We want to use private group for L2 cache only */ | ||
| 145 | if (this_leaf->level == 2) | ||
| 146 | return &priv_attr_group; | ||
| 147 | else | ||
| 148 | return NULL; | ||
| 149 | } | ||
| 150 | |||
| 151 | static irqreturn_t l2_int_handler(int irq, void *device) | ||
| 152 | { | ||
| 153 | unsigned int add_h, add_l; | ||
| 154 | |||
| 155 | if (irq == g_irq[DIR_CORR]) { | ||
| 156 | add_h = readl(l2_base + SIFIVE_L2_DIRECCFIX_HIGH); | ||
| 157 | add_l = readl(l2_base + SIFIVE_L2_DIRECCFIX_LOW); | ||
| 158 | pr_err("L2CACHE: DirError @ 0x%08X.%08X\n", add_h, add_l); | ||
| 159 | /* Reading this register clears the DirError interrupt sig */ | ||
| 160 | readl(l2_base + SIFIVE_L2_DIRECCFIX_COUNT); | ||
| 161 | atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_CE, | ||
| 162 | "DirECCFix"); | ||
| 163 | } | ||
| 164 | if (irq == g_irq[DIR_UNCORR]) { | ||
| 165 | add_h = readl(l2_base + SIFIVE_L2_DIRECCFAIL_HIGH); | ||
| 166 | add_l = readl(l2_base + SIFIVE_L2_DIRECCFAIL_LOW); | ||
| 167 | /* Reading this register clears the DirFail interrupt sig */ | ||
| 168 | readl(l2_base + SIFIVE_L2_DIRECCFAIL_COUNT); | ||
| 169 | atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_UE, | ||
| 170 | "DirECCFail"); | ||
| 171 | panic("L2CACHE: DirFail @ 0x%08X.%08X\n", add_h, add_l); | ||
| 172 | } | ||
| 173 | if (irq == g_irq[DATA_CORR]) { | ||
| 174 | add_h = readl(l2_base + SIFIVE_L2_DATECCFIX_HIGH); | ||
| 175 | add_l = readl(l2_base + SIFIVE_L2_DATECCFIX_LOW); | ||
| 176 | pr_err("L2CACHE: DataError @ 0x%08X.%08X\n", add_h, add_l); | ||
| 177 | /* Reading this register clears the DataError interrupt sig */ | ||
| 178 | readl(l2_base + SIFIVE_L2_DATECCFIX_COUNT); | ||
| 179 | atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_CE, | ||
| 180 | "DatECCFix"); | ||
| 181 | } | ||
| 182 | if (irq == g_irq[DATA_UNCORR]) { | ||
| 183 | add_h = readl(l2_base + SIFIVE_L2_DATECCFAIL_HIGH); | ||
| 184 | add_l = readl(l2_base + SIFIVE_L2_DATECCFAIL_LOW); | ||
| 185 | pr_err("L2CACHE: DataFail @ 0x%08X.%08X\n", add_h, add_l); | ||
| 186 | /* Reading this register clears the DataFail interrupt sig */ | ||
| 187 | readl(l2_base + SIFIVE_L2_DATECCFAIL_COUNT); | ||
| 188 | atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_UE, | ||
| 189 | "DatECCFail"); | ||
| 190 | } | ||
| 191 | |||
| 192 | return IRQ_HANDLED; | ||
| 193 | } | ||
| 194 | |||
| 195 | static int __init sifive_l2_init(void) | ||
| 196 | { | ||
| 197 | struct device_node *np; | ||
| 198 | struct resource res; | ||
| 199 | int i, rc, intr_num; | ||
| 200 | |||
| 201 | np = of_find_matching_node(NULL, sifive_l2_ids); | ||
| 202 | if (!np) | ||
| 203 | return -ENODEV; | ||
| 204 | |||
| 205 | if (of_address_to_resource(np, 0, &res)) | ||
| 206 | return -ENODEV; | ||
| 207 | |||
| 208 | l2_base = ioremap(res.start, resource_size(&res)); | ||
| 209 | if (!l2_base) | ||
| 210 | return -ENOMEM; | ||
| 211 | |||
| 212 | intr_num = of_property_count_u32_elems(np, "interrupts"); | ||
| 213 | if (!intr_num) { | ||
| 214 | pr_err("L2CACHE: no interrupts property\n"); | ||
| 215 | return -ENODEV; | ||
| 216 | } | ||
| 217 | |||
| 218 | for (i = 0; i < intr_num; i++) { | ||
| 219 | g_irq[i] = irq_of_parse_and_map(np, i); | ||
| 220 | rc = request_irq(g_irq[i], l2_int_handler, 0, "l2_ecc", NULL); | ||
| 221 | if (rc) { | ||
| 222 | pr_err("L2CACHE: Could not request IRQ %d\n", g_irq[i]); | ||
| 223 | return rc; | ||
| 224 | } | ||
| 225 | } | ||
| 226 | |||
| 227 | l2_config_read(); | ||
| 228 | |||
| 229 | l2_cache_ops.get_priv_group = l2_get_priv_group; | ||
| 230 | riscv_set_cacheinfo_ops(&l2_cache_ops); | ||
| 231 | |||
| 232 | #ifdef CONFIG_DEBUG_FS | ||
| 233 | setup_sifive_debug(); | ||
| 234 | #endif | ||
| 235 | return 0; | ||
| 236 | } | ||
| 237 | device_initcall(sifive_l2_init); | ||
| @@ -0,0 +1,16 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * SiFive Composable Cache Controller header file | ||
| 4 | * | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef __SOC_SIFIVE_CCACHE_H | ||
| 8 | #define __SOC_SIFIVE_CCACHE_H | ||
| 9 | |||
| 10 | extern int register_sifive_ccache_error_notifier(struct notifier_block *nb); | ||
| 11 | extern int unregister_sifive_ccache_error_notifier(struct notifier_block *nb); | ||
| 12 | |||
| 13 | #define SIFIVE_CCACHE_ERR_TYPE_CE 0 | ||
| 14 | #define SIFIVE_CCACHE_ERR_TYPE_UE 1 | ||
| 15 | |||
| 16 | #endif /* __SOC_SIFIVE_CCACHE_H */ | ||
| @@ -1,16 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * SiFive L2 Cache Controller header file | ||
| 4 | * | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef __SOC_SIFIVE_L2_CACHE_H | ||
| 8 | #define __SOC_SIFIVE_L2_CACHE_H | ||
| 9 | |||
| 10 | extern int register_sifive_l2_error_notifier(struct notifier_block *nb); | ||
| 11 | extern int unregister_sifive_l2_error_notifier(struct notifier_block *nb); | ||
| 12 | |||
| 13 | #define SIFIVE_L2_ERR_TYPE_CE 0 | ||
| 14 | #define SIFIVE_L2_ERR_TYPE_UE 1 | ||
| 15 | |||
| 16 | #endif /* __SOC_SIFIVE_L2_CACHE_H */ | ||