Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'riscv-for-linus-5.20-mw2' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux

Pull more RISC-V updates from Palmer Dabbelt:
"There's still a handful of new features in here, but there are a lot
of fixes/cleanups as well:

- Support for the Zicbom extension for explicit cache-block
management, along with the necessary bits to make the non-standard
cache management ops on the Allwinner D1 function

- Support for the Zihintpause extension, which codifies a go-slow
instruction used for cpu_relax()

- Support for the Sstc extension for supervisor-mode timer/counter
management

- Many device tree fixes and cleanups, including a large set for the
Canaan device trees

- A handful of fixes and cleanups for the PMU driver"

* tag 'riscv-for-linus-5.20-mw2' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: (43 commits)
dt-bindings: gpio: sifive: add gpio-line-names
wireguard: selftests: set CONFIG_NONPORTABLE on riscv32
RISC-V: KVM: Support sstc extension
RISC-V: Improve SBI definitions
RISC-V: Move counter info definition to sbi header file
RISC-V: Fix SBI PMU calls for RV32
RISC-V: Update user page mapping only once during start
RISC-V: Fix counter restart during overflow for RV32
RISC-V: Prefer sstc extension if available
RISC-V: Enable sstc extension parsing from DT
RISC-V: Add SSTC extension CSR details
riscv:uprobe fix SR_SPIE set/clear handling
dt-bindings: riscv: fix SiFive l2-cache's cache-sets
riscv: ensure cpu_ops_sbi is declared
RISC-V: cpu_ops_spinwait.c should include head.h
RISC-V: Declare cpu_ops_spinwait in <asm/cpu_ops.h>
riscv: dts: starfive: correct number of external interrupts
riscv: dts: sifive unmatched: Add PWM controlled LEDs
riscv/purgatory: Omit use of bin2c
riscv/purgatory: hard-code obj-y in Makefile
...

+822 -144
-27
Documentation/devicetree/bindings/display/ilitek,ili9341.txt
··· 1 - Ilitek ILI9341 display panels 2 - 3 - This binding is for display panels using an Ilitek ILI9341 controller in SPI 4 - mode. 5 - 6 - Required properties: 7 - - compatible: "adafruit,yx240qv29", "ilitek,ili9341" 8 - - dc-gpios: D/C pin 9 - - reset-gpios: Reset pin 10 - 11 - The node for this driver must be a child node of a SPI controller, hence 12 - all mandatory properties described in ../spi/spi-bus.txt must be specified. 13 - 14 - Optional properties: 15 - - rotation: panel rotation in degrees counter clockwise (0,90,180,270) 16 - - backlight: phandle of the backlight device attached to the panel 17 - 18 - Example: 19 - display@0{ 20 - compatible = "adafruit,yx240qv29", "ilitek,ili9341"; 21 - reg = <0>; 22 - spi-max-frequency = <32000000>; 23 - dc-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; 24 - reset-gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; 25 - rotation = <270>; 26 - backlight = <&backlight>; 27 - };
+35 -14
Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml
··· 21 21 compatible: 22 22 items: 23 23 - enum: 24 + - adafruit,yx240qv29 24 25 # ili9341 240*320 Color on stm32f429-disco board 25 26 - st,sf-tc240t-9370-t 27 + - canaan,kd233-tft 26 28 - const: ilitek,ili9341 27 29 28 30 reg: true ··· 49 47 vddi-led-supply: 50 48 description: Voltage supply for the LED driver (1.65 .. 3.3 V) 51 49 52 - additionalProperties: false 50 + unevaluatedProperties: false 53 51 54 52 required: 55 53 - compatible 56 54 - reg 57 55 - dc-gpios 58 - - port 56 + 57 + if: 58 + properties: 59 + compatible: 60 + contains: 61 + enum: 62 + - st,sf-tc240t-9370-t 63 + then: 64 + required: 65 + - port 59 66 60 67 examples: 61 68 - |+ 69 + #include <dt-bindings/gpio/gpio.h> 62 70 spi { 63 71 #address-cells = <1>; 64 72 #size-cells = <0>; 65 73 panel: display@0 { 66 - compatible = "st,sf-tc240t-9370-t", 67 - "ilitek,ili9341"; 68 - reg = <0>; 69 - spi-3wire; 70 - spi-max-frequency = <10000000>; 71 - dc-gpios = <&gpiod 13 0>; 72 - port { 73 - panel_in: endpoint { 74 - remote-endpoint = <&display_out>; 75 - }; 76 - }; 77 - }; 74 + compatible = "st,sf-tc240t-9370-t", 75 + "ilitek,ili9341"; 76 + reg = <0>; 77 + spi-3wire; 78 + spi-max-frequency = <10000000>; 79 + dc-gpios = <&gpiod 13 0>; 80 + port { 81 + panel_in: endpoint { 82 + remote-endpoint = <&display_out>; 83 + }; 84 + }; 78 85 }; 86 + display@1{ 87 + compatible = "adafruit,yx240qv29", "ilitek,ili9341"; 88 + reg = <1>; 89 + spi-max-frequency = <10000000>; 90 + dc-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; 91 + reset-gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; 92 + rotation = <270>; 93 + backlight = <&backlight>; 94 + }; 95 + }; 79 96 ...
+4
Documentation/devicetree/bindings/gpio/sifive,gpio.yaml
··· 46 46 maximum: 32 47 47 default: 16 48 48 49 + gpio-line-names: 50 + minItems: 1 51 + maxItems: 32 52 + 49 53 gpio-controller: true 50 54 51 55 required:
+52
Documentation/devicetree/bindings/memory-controllers/canaan,k210-sram.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/memory-controllers/canaan,k210-sram.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Canaan K210 SRAM memory controller 8 + 9 + description: 10 + The Canaan K210 SRAM memory controller is responsible for the system's 8 MiB 11 + of SRAM. The controller is initialised by the bootloader, which configures 12 + its clocks, before OS bringup. 13 + 14 + maintainers: 15 + - Conor Dooley <conor@kernel.org> 16 + 17 + properties: 18 + compatible: 19 + enum: 20 + - canaan,k210-sram 21 + 22 + clocks: 23 + minItems: 1 24 + items: 25 + - description: sram0 clock 26 + - description: sram1 clock 27 + - description: aisram clock 28 + 29 + clock-names: 30 + minItems: 1 31 + items: 32 + - const: sram0 33 + - const: sram1 34 + - const: aisram 35 + 36 + required: 37 + - compatible 38 + - clocks 39 + - clock-names 40 + 41 + additionalProperties: false 42 + 43 + examples: 44 + - | 45 + #include <dt-bindings/clock/k210-clk.h> 46 + memory-controller { 47 + compatible = "canaan,k210-sram"; 48 + clocks = <&sysclk K210_CLK_SRAM0>, 49 + <&sysclk K210_CLK_SRAM1>, 50 + <&sysclk K210_CLK_AI>; 51 + clock-names = "sram0", "sram1", "aisram"; 52 + };
+5
Documentation/devicetree/bindings/riscv/cpus.yaml
··· 63 63 - riscv,sv48 64 64 - riscv,none 65 65 66 + riscv,cbom-block-size: 67 + $ref: /schemas/types.yaml#/definitions/uint32 68 + description: 69 + The blocksize in bytes for the Zicbom cache operations. 70 + 66 71 riscv,isa: 67 72 description: 68 73 Identifies the specific RISC-V instruction set architecture
+5 -1
Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml
··· 46 46 const: 2 47 47 48 48 cache-sets: 49 - const: 1024 49 + enum: [1024, 2048] 50 50 51 51 cache-size: 52 52 const: 2097152 ··· 84 84 description: | 85 85 Must contain entries for DirError, DataError and DataFail signals. 86 86 maxItems: 3 87 + cache-sets: 88 + const: 1024 87 89 88 90 else: 89 91 properties: ··· 93 91 description: | 94 92 Must contain entries for DirError, DataError, DataFail, DirFail signals. 95 93 minItems: 4 94 + cache-sets: 95 + const: 2048 96 96 97 97 additionalProperties: false 98 98
+31 -1
arch/riscv/Kconfig
··· 113 113 select MODULES_USE_ELF_RELA if MODULES 114 114 select MODULE_SECTIONS if MODULES 115 115 select OF 116 + select OF_DMA_DEFAULT_COHERENT 116 117 select OF_EARLY_FLATTREE 117 118 select OF_IRQ 118 119 select PCI_DOMAINS_GENERIC if PCI ··· 218 217 219 218 config LOCKDEP_SUPPORT 220 219 def_bool y 220 + 221 + config RISCV_DMA_NONCOHERENT 222 + bool 223 + select ARCH_HAS_DMA_PREP_COHERENT 224 + select ARCH_HAS_SYNC_DMA_FOR_DEVICE 225 + select ARCH_HAS_SYNC_DMA_FOR_CPU 226 + select ARCH_HAS_SETUP_DMA_OPS 227 + select DMA_DIRECT_REMAP 221 228 222 229 source "arch/riscv/Kconfig.socs" 223 230 source "arch/riscv/Kconfig.erratas" ··· 401 392 402 393 If you don't know what to do here, say Y. 403 394 395 + config CC_HAS_ZICBOM 396 + bool 397 + default y if 64BIT && $(cc-option,-mabi=lp64 -march=rv64ima_zicbom) 398 + default y if 32BIT && $(cc-option,-mabi=ilp32 -march=rv32ima_zicbom) 399 + 400 + config RISCV_ISA_ZICBOM 401 + bool "Zicbom extension support for non-coherent DMA operation" 402 + depends on CC_HAS_ZICBOM 403 + depends on !XIP_KERNEL && MMU 404 + select RISCV_DMA_NONCOHERENT 405 + select RISCV_ALTERNATIVE 406 + default y 407 + help 408 + Adds support to dynamically detect the presence of the ZICBOM 409 + extension (Cache Block Management Operations) and enable its 410 + usage. 411 + 412 + The Zicbom extension can be used to handle for example 413 + non-coherent DMA support on devices that need it. 414 + 415 + If you don't know what to do here, say Y. 416 + 404 417 config FPU 405 418 bool "FPU support" 406 419 default y ··· 494 463 495 464 config ARCH_HAS_KEXEC_PURGATORY 496 465 def_bool KEXEC_FILE 497 - select BUILD_BIN2C 498 466 depends on CRYPTO=y 499 467 depends on CRYPTO_SHA256=y 500 468
+11
arch/riscv/Kconfig.erratas
··· 55 55 56 56 If you don't know what to do here, say "Y". 57 57 58 + config ERRATA_THEAD_CMO 59 + bool "Apply T-Head cache management errata" 60 + depends on ERRATA_THEAD 61 + select RISCV_DMA_NONCOHERENT 62 + default y 63 + help 64 + This will apply the cache management errata to handle the 65 + non-standard handling on non-coherent operations on T-Head SoCs. 66 + 67 + If you don't know what to do here, say "Y". 68 + 58 69 endmenu # "CPU errata selection"
+8
arch/riscv/Makefile
··· 56 56 toolchain-need-zicsr-zifencei := $(call cc-option-yn, -march=$(riscv-march-y)_zicsr_zifencei) 57 57 riscv-march-$(toolchain-need-zicsr-zifencei) := $(riscv-march-y)_zicsr_zifencei 58 58 59 + # Check if the toolchain supports Zicbom extension 60 + toolchain-supports-zicbom := $(call cc-option-yn, -march=$(riscv-march-y)_zicbom) 61 + riscv-march-$(toolchain-supports-zicbom) := $(riscv-march-y)_zicbom 62 + 63 + # Check if the toolchain supports Zihintpause extension 64 + toolchain-supports-zihintpause := $(call cc-option-yn, -march=$(riscv-march-y)_zihintpause) 65 + riscv-march-$(toolchain-supports-zihintpause) := $(riscv-march-y)_zihintpause 66 + 59 67 KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y)) 60 68 KBUILD_AFLAGS += -march=$(riscv-march-y) 61 69
+8 -2
arch/riscv/boot/dts/canaan/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 - dtb-$(CONFIG_SOC_CANAAN_K210_DTB_BUILTIN) += $(addsuffix .dtb, $(CONFIG_SOC_CANAAN_K210_DTB_SOURCE)) 3 - obj-$(CONFIG_SOC_CANAAN_K210_DTB_BUILTIN) += $(addsuffix .o, $(dtb-y)) 2 + dtb-$(CONFIG_SOC_CANAAN) += canaan_kd233.dtb 3 + dtb-$(CONFIG_SOC_CANAAN) += k210_generic.dtb 4 + dtb-$(CONFIG_SOC_CANAAN) += sipeed_maix_bit.dtb 5 + dtb-$(CONFIG_SOC_CANAAN) += sipeed_maix_dock.dtb 6 + dtb-$(CONFIG_SOC_CANAAN) += sipeed_maix_go.dtb 7 + dtb-$(CONFIG_SOC_CANAAN) += sipeed_maixduino.dtb 8 + 9 + obj-$(CONFIG_SOC_CANAAN_K210_DTB_BUILTIN) += $(addsuffix .dtb.o, $(CONFIG_SOC_CANAAN_K210_DTB_SOURCE))
+3 -3
arch/riscv/boot/dts/canaan/canaan_kd233.dts
··· 127 127 cs-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; 128 128 129 129 panel@0 { 130 - compatible = "ilitek,ili9341"; 130 + compatible = "canaan,kd233-tft", "ilitek,ili9341"; 131 131 reg = <0>; 132 132 dc-gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>; 133 - spi-max-frequency = <15000000>; 133 + spi-max-frequency = <10000000>; 134 134 status = "disabled"; 135 135 }; 136 136 }; ··· 142 142 cs-gpios = <&gpio0 16 GPIO_ACTIVE_LOW>; 143 143 status = "okay"; 144 144 145 - slot@0 { 145 + mmc@0 { 146 146 compatible = "mmc-spi-slot"; 147 147 reg = <0>; 148 148 voltage-ranges = <3300 3300>;
+51 -22
arch/riscv/boot/dts/canaan/k210.dtsi
··· 81 81 82 82 sram: memory@80000000 { 83 83 device_type = "memory"; 84 + reg = <0x80000000 0x400000>, /* sram0 4 MiB */ 85 + <0x80400000 0x200000>, /* sram1 2 MiB */ 86 + <0x80600000 0x200000>; /* aisram 2 MiB */ 87 + }; 88 + 89 + sram_controller: memory-controller { 84 90 compatible = "canaan,k210-sram"; 85 - reg = <0x80000000 0x400000>, 86 - <0x80400000 0x200000>, 87 - <0x80600000 0x200000>; 88 - reg-names = "sram0", "sram1", "aisram"; 89 91 clocks = <&sysclk K210_CLK_SRAM0>, 90 92 <&sysclk K210_CLK_SRAM1>, 91 93 <&sysclk K210_CLK_AI>; ··· 175 173 #address-cells = <1>; 176 174 #size-cells = <1>; 177 175 compatible = "simple-pm-bus"; 178 - ranges; 176 + ranges = <0x50200000 0x50200000 0x200000>; 179 177 clocks = <&sysclk K210_CLK_APB0>; 180 178 181 179 gpio1: gpio@50200000 { ··· 263 261 }; 264 262 265 263 i2s0: i2s@50250000 { 266 - compatible = "snps,designware-i2s"; 264 + compatible = "canaan,k210-i2s", "snps,designware-i2s"; 267 265 reg = <0x50250000 0x200>; 268 266 interrupts = <5>; 269 267 clocks = <&sysclk K210_CLK_I2S0>; ··· 272 270 }; 273 271 274 272 i2s1: i2s@50260000 { 275 - compatible = "snps,designware-i2s"; 273 + compatible = "canaan,k210-i2s", "snps,designware-i2s"; 276 274 reg = <0x50260000 0x200>; 277 275 interrupts = <6>; 278 276 clocks = <&sysclk K210_CLK_I2S1>; ··· 281 279 }; 282 280 283 281 i2s2: i2s@50270000 { 284 - compatible = "snps,designware-i2s"; 282 + compatible = "canaan,k210-i2s", "snps,designware-i2s"; 285 283 reg = <0x50270000 0x200>; 286 284 interrupts = <7>; 287 285 clocks = <&sysclk K210_CLK_I2S2>; ··· 331 329 332 330 timer0: timer@502d0000 { 333 331 compatible = "snps,dw-apb-timer"; 334 - reg = <0x502D0000 0x100>; 335 - interrupts = <14>, <15>; 332 + reg = <0x502D0000 0x14>; 333 + interrupts = <14>; 336 334 clocks = <&sysclk K210_CLK_TIMER0>, 337 335 <&sysclk K210_CLK_APB0>; 338 336 clock-names = "timer", "pclk"; 339 337 resets = <&sysrst K210_RST_TIMER0>; 340 338 }; 341 339 342 - timer1: timer@502e0000 { 340 + timer1: timer@502d0014 { 343 341 compatible = "snps,dw-apb-timer"; 344 - reg = <0x502E0000 0x100>; 345 - interrupts = <16>, <17>; 342 + reg = <0x502D0014 0x14>; 343 + interrupts = <15>; 344 + clocks = <&sysclk K210_CLK_TIMER0>, 345 + <&sysclk K210_CLK_APB0>; 346 + clock-names = "timer", "pclk"; 347 + resets = <&sysrst K210_RST_TIMER0>; 348 + }; 349 + 350 + timer2: timer@502e0000 { 351 + compatible = "snps,dw-apb-timer"; 352 + reg = <0x502E0000 0x14>; 353 + interrupts = <16>; 346 354 clocks = <&sysclk K210_CLK_TIMER1>, 347 355 <&sysclk K210_CLK_APB0>; 348 356 clock-names = "timer", "pclk"; 349 357 resets = <&sysrst K210_RST_TIMER1>; 350 358 }; 351 359 352 - timer2: timer@502f0000 { 360 + timer3: timer@502e0014 { 353 361 compatible = "snps,dw-apb-timer"; 354 - reg = <0x502F0000 0x100>; 355 - interrupts = <18>, <19>; 362 + reg = <0x502E0014 0x114>; 363 + interrupts = <17>; 364 + clocks = <&sysclk K210_CLK_TIMER1>, 365 + <&sysclk K210_CLK_APB0>; 366 + clock-names = "timer", "pclk"; 367 + resets = <&sysrst K210_RST_TIMER1>; 368 + }; 369 + 370 + timer4: timer@502f0000 { 371 + compatible = "snps,dw-apb-timer"; 372 + reg = <0x502F0000 0x14>; 373 + interrupts = <18>; 374 + clocks = <&sysclk K210_CLK_TIMER2>, 375 + <&sysclk K210_CLK_APB0>; 376 + clock-names = "timer", "pclk"; 377 + resets = <&sysrst K210_RST_TIMER2>; 378 + }; 379 + 380 + timer5: timer@502f0014 { 381 + compatible = "snps,dw-apb-timer"; 382 + reg = <0x502F0014 0x14>; 383 + interrupts = <19>; 356 384 clocks = <&sysclk K210_CLK_TIMER2>, 357 385 <&sysclk K210_CLK_APB0>; 358 386 clock-names = "timer", "pclk"; ··· 394 362 #address-cells = <1>; 395 363 #size-cells = <1>; 396 364 compatible = "simple-pm-bus"; 397 - ranges; 365 + ranges = <0x50400000 0x50400000 0x40100>; 398 366 clocks = <&sysclk K210_CLK_APB1>; 399 367 400 368 wdt0: watchdog@50400000 { ··· 449 417 #address-cells = <1>; 450 418 #size-cells = <1>; 451 419 compatible = "simple-pm-bus"; 452 - ranges; 420 + ranges = <0x52000000 0x52000000 0x2000200>; 453 421 clocks = <&sysclk K210_CLK_APB2>; 454 422 455 423 spi0: spi@52000000 { ··· 463 431 clock-names = "ssi_clk", "pclk"; 464 432 resets = <&sysrst K210_RST_SPI0>; 465 433 reset-names = "spi"; 466 - spi-max-frequency = <25000000>; 467 434 num-cs = <4>; 468 435 reg-io-width = <4>; 469 436 }; ··· 478 447 clock-names = "ssi_clk", "pclk"; 479 448 resets = <&sysrst K210_RST_SPI1>; 480 449 reset-names = "spi"; 481 - spi-max-frequency = <25000000>; 482 450 num-cs = <4>; 483 451 reg-io-width = <4>; 484 452 }; ··· 493 463 clock-names = "ssi_clk", "pclk"; 494 464 resets = <&sysrst K210_RST_SPI3>; 495 465 reset-names = "spi"; 496 - /* Could possibly go up to 200 MHz */ 497 - spi-max-frequency = <100000000>; 466 + 498 467 num-cs = <4>; 499 468 reg-io-width = <4>; 500 469 };
+1 -1
arch/riscv/boot/dts/canaan/sipeed_maix_bit.dts
··· 189 189 cs-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; 190 190 status = "okay"; 191 191 192 - slot@0 { 192 + mmc@0 { 193 193 compatible = "mmc-spi-slot"; 194 194 reg = <0>; 195 195 voltage-ranges = <3300 3300>;
+1 -1
arch/riscv/boot/dts/canaan/sipeed_maix_dock.dts
··· 191 191 cs-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; 192 192 status = "okay"; 193 193 194 - slot@0 { 194 + mmc@0 { 195 195 compatible = "mmc-spi-slot"; 196 196 reg = <0>; 197 197 voltage-ranges = <3300 3300>;
+1 -1
arch/riscv/boot/dts/canaan/sipeed_maix_go.dts
··· 199 199 cs-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; 200 200 status = "okay"; 201 201 202 - slot@0 { 202 + mmc@0 { 203 203 compatible = "mmc-spi-slot"; 204 204 reg = <0>; 205 205 voltage-ranges = <3300 3300>;
+1 -1
arch/riscv/boot/dts/canaan/sipeed_maixduino.dts
··· 164 164 cs-gpios = <&gpio1_0 2 GPIO_ACTIVE_LOW>; 165 165 status = "okay"; 166 166 167 - slot@0 { 167 + mmc@0 { 168 168 compatible = "mmc-spi-slot"; 169 169 reg = <0>; 170 170 voltage-ranges = <3300 3300>;
+42
arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
··· 4 4 #include "fu740-c000.dtsi" 5 5 #include <dt-bindings/gpio/gpio.h> 6 6 #include <dt-bindings/interrupt-controller/irq.h> 7 + #include <dt-bindings/leds/common.h> 8 + #include <dt-bindings/pwm/pwm.h> 7 9 8 10 /* Clock frequency (in Hz) of the PCB crystal for rtcclk */ 9 11 #define RTCCLK_FREQ 1000000 ··· 45 43 gpio-poweroff { 46 44 compatible = "gpio-poweroff"; 47 45 gpios = <&gpio 2 GPIO_ACTIVE_LOW>; 46 + }; 47 + 48 + led-controller-1 { 49 + compatible = "pwm-leds"; 50 + 51 + led-d12 { 52 + pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>; 53 + active-low; 54 + color = <LED_COLOR_ID_GREEN>; 55 + max-brightness = <255>; 56 + label = "d12"; 57 + }; 58 + }; 59 + 60 + led-controller-2 { 61 + compatible = "pwm-leds-multicolor"; 62 + 63 + multi-led { 64 + color = <LED_COLOR_ID_RGB>; 65 + max-brightness = <255>; 66 + label = "d2"; 67 + 68 + led-red { 69 + pwms = <&pwm0 2 7812500 PWM_POLARITY_INVERTED>; 70 + active-low; 71 + color = <LED_COLOR_ID_RED>; 72 + }; 73 + 74 + led-green { 75 + pwms = <&pwm0 1 7812500 PWM_POLARITY_INVERTED>; 76 + active-low; 77 + color = <LED_COLOR_ID_GREEN>; 78 + }; 79 + 80 + led-blue { 81 + pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>; 82 + active-low; 83 + color = <LED_COLOR_ID_BLUE>; 84 + }; 85 + }; 48 86 }; 49 87 }; 50 88
+1 -1
arch/riscv/boot/dts/starfive/jh7100.dtsi
··· 130 130 interrupt-controller; 131 131 #address-cells = <0>; 132 132 #interrupt-cells = <1>; 133 - riscv,ndev = <127>; 133 + riscv,ndev = <133>; 134 134 }; 135 135 136 136 clkgen: clock-controller@11800000 {
+20
arch/riscv/errata/thead/errata.c
··· 27 27 return false; 28 28 } 29 29 30 + static bool errata_probe_cmo(unsigned int stage, 31 + unsigned long arch_id, unsigned long impid) 32 + { 33 + #ifdef CONFIG_ERRATA_THEAD_CMO 34 + if (arch_id != 0 || impid != 0) 35 + return false; 36 + 37 + if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) 38 + return false; 39 + 40 + riscv_noncoherent_supported(); 41 + return true; 42 + #else 43 + return false; 44 + #endif 45 + } 46 + 30 47 static u32 thead_errata_probe(unsigned int stage, 31 48 unsigned long archid, unsigned long impid) 32 49 { ··· 51 34 52 35 if (errata_probe_pbmt(stage, archid, impid)) 53 36 cpu_req_errata |= (1U << ERRATA_THEAD_PBMT); 37 + 38 + if (errata_probe_cmo(stage, archid, impid)) 39 + cpu_req_errata |= (1U << ERRATA_THEAD_CMO); 54 40 55 41 return cpu_req_errata; 56 42 }
+4
arch/riscv/include/asm/cache.h
··· 11 11 12 12 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) 13 13 14 + #ifdef CONFIG_RISCV_DMA_NONCOHERENT 15 + #define ARCH_DMA_MINALIGN L1_CACHE_BYTES 16 + #endif 17 + 14 18 /* 15 19 * RISC-V requires the stack pointer to be 16-byte aligned, so ensure that 16 20 * the flat loader aligns it accordingly.
+10
arch/riscv/include/asm/cacheflush.h
··· 42 42 43 43 #endif /* CONFIG_SMP */ 44 44 45 + #ifdef CONFIG_RISCV_ISA_ZICBOM 46 + void riscv_init_cbom_blocksize(void); 47 + #else 48 + static inline void riscv_init_cbom_blocksize(void) { } 49 + #endif 50 + 51 + #ifdef CONFIG_RISCV_DMA_NONCOHERENT 52 + void riscv_noncoherent_supported(void); 53 + #endif 54 + 45 55 /* 46 56 * Bits in sys_riscv_flush_icache()'s flags argument. 47 57 */
+1
arch/riscv/include/asm/cpu_ops.h
··· 38 38 #endif 39 39 }; 40 40 41 + extern const struct cpu_operations cpu_ops_spinwait; 41 42 extern const struct cpu_operations *cpu_ops[NR_CPUS]; 42 43 void __init cpu_set_ops(int cpu); 43 44
+2
arch/riscv/include/asm/cpu_ops_sbi.h
··· 10 10 #include <linux/sched.h> 11 11 #include <linux/threads.h> 12 12 13 + extern const struct cpu_operations cpu_ops_sbi; 14 + 13 15 /** 14 16 * struct sbi_hart_boot_data - Hart specific boot used during booting and 15 17 * cpu hotplug.
+5
arch/riscv/include/asm/csr.h
··· 247 247 #define CSR_SIP 0x144 248 248 #define CSR_SATP 0x180 249 249 250 + #define CSR_STIMECMP 0x14D 251 + #define CSR_STIMECMPH 0x15D 252 + 250 253 #define CSR_VSSTATUS 0x200 251 254 #define CSR_VSIE 0x204 252 255 #define CSR_VSTVEC 0x205 ··· 259 256 #define CSR_VSTVAL 0x243 260 257 #define CSR_VSIP 0x244 261 258 #define CSR_VSATP 0x280 259 + #define CSR_VSTIMECMP 0x24D 260 + #define CSR_VSTIMECMPH 0x25D 262 261 263 262 #define CSR_HSTATUS 0x600 264 263 #define CSR_HEDELEG 0x602
+57 -2
arch/riscv/include/asm/errata_list.h
··· 16 16 17 17 #ifdef CONFIG_ERRATA_THEAD 18 18 #define ERRATA_THEAD_PBMT 0 19 - #define ERRATA_THEAD_NUMBER 1 19 + #define ERRATA_THEAD_CMO 1 20 + #define ERRATA_THEAD_NUMBER 2 20 21 #endif 21 22 22 23 #define CPUFEATURE_SVPBMT 0 23 - #define CPUFEATURE_NUMBER 1 24 + #define CPUFEATURE_ZICBOM 1 25 + #define CPUFEATURE_NUMBER 2 24 26 25 27 #ifdef __ASSEMBLY__ 26 28 ··· 88 86 #else 89 87 #define ALT_THEAD_PMA(_val) 90 88 #endif 89 + 90 + /* 91 + * dcache.ipa rs1 (invalidate, physical address) 92 + * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | 93 + * 0000001 01010 rs1 000 00000 0001011 94 + * dache.iva rs1 (invalida, virtual address) 95 + * 0000001 00110 rs1 000 00000 0001011 96 + * 97 + * dcache.cpa rs1 (clean, physical address) 98 + * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | 99 + * 0000001 01001 rs1 000 00000 0001011 100 + * dcache.cva rs1 (clean, virtual address) 101 + * 0000001 00100 rs1 000 00000 0001011 102 + * 103 + * dcache.cipa rs1 (clean then invalidate, physical address) 104 + * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | 105 + * 0000001 01011 rs1 000 00000 0001011 106 + * dcache.civa rs1 (... virtual address) 107 + * 0000001 00111 rs1 000 00000 0001011 108 + * 109 + * sync.s (make sure all cache operations finished) 110 + * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | 111 + * 0000000 11001 00000 000 00000 0001011 112 + */ 113 + #define THEAD_inval_A0 ".long 0x0265000b" 114 + #define THEAD_clean_A0 ".long 0x0245000b" 115 + #define THEAD_flush_A0 ".long 0x0275000b" 116 + #define THEAD_SYNC_S ".long 0x0190000b" 117 + 118 + #define ALT_CMO_OP(_op, _start, _size, _cachesize) \ 119 + asm volatile(ALTERNATIVE_2( \ 120 + __nops(6), \ 121 + "mv a0, %1\n\t" \ 122 + "j 2f\n\t" \ 123 + "3:\n\t" \ 124 + "cbo." __stringify(_op) " (a0)\n\t" \ 125 + "add a0, a0, %0\n\t" \ 126 + "2:\n\t" \ 127 + "bltu a0, %2, 3b\n\t" \ 128 + "nop", 0, CPUFEATURE_ZICBOM, CONFIG_RISCV_ISA_ZICBOM, \ 129 + "mv a0, %1\n\t" \ 130 + "j 2f\n\t" \ 131 + "3:\n\t" \ 132 + THEAD_##_op##_A0 "\n\t" \ 133 + "add a0, a0, %0\n\t" \ 134 + "2:\n\t" \ 135 + "bltu a0, %2, 3b\n\t" \ 136 + THEAD_SYNC_S, THEAD_VENDOR_ID, \ 137 + ERRATA_THEAD_CMO, CONFIG_ERRATA_THEAD_CMO) \ 138 + : : "r"(_cachesize), \ 139 + "r"((unsigned long)(_start) & ~((_cachesize) - 1UL)), \ 140 + "r"((unsigned long)(_start) + (_size)) \ 141 + : "a0") 91 142 92 143 #endif /* __ASSEMBLY__ */ 93 144
+7
arch/riscv/include/asm/hwcap.h
··· 8 8 #ifndef _ASM_RISCV_HWCAP_H 9 9 #define _ASM_RISCV_HWCAP_H 10 10 11 + #include <asm/errno.h> 11 12 #include <linux/bits.h> 12 13 #include <uapi/asm/hwcap.h> 13 14 ··· 55 54 enum riscv_isa_ext_id { 56 55 RISCV_ISA_EXT_SSCOFPMF = RISCV_ISA_EXT_BASE, 57 56 RISCV_ISA_EXT_SVPBMT, 57 + RISCV_ISA_EXT_ZICBOM, 58 + RISCV_ISA_EXT_ZIHINTPAUSE, 59 + RISCV_ISA_EXT_SSTC, 58 60 RISCV_ISA_EXT_ID_MAX = RISCV_ISA_EXT_MAX, 59 61 }; 60 62 ··· 68 64 */ 69 65 enum riscv_isa_ext_key { 70 66 RISCV_ISA_EXT_KEY_FPU, /* For 'F' and 'D' */ 67 + RISCV_ISA_EXT_KEY_ZIHINTPAUSE, 71 68 RISCV_ISA_EXT_KEY_MAX, 72 69 }; 73 70 ··· 88 83 return RISCV_ISA_EXT_KEY_FPU; 89 84 case RISCV_ISA_EXT_d: 90 85 return RISCV_ISA_EXT_KEY_FPU; 86 + case RISCV_ISA_EXT_ZIHINTPAUSE: 87 + return RISCV_ISA_EXT_KEY_ZIHINTPAUSE; 91 88 default: 92 89 return -EINVAL; 93 90 }
+7
arch/riscv/include/asm/kvm_vcpu_timer.h
··· 28 28 u64 next_cycles; 29 29 /* Underlying hrtimer instance */ 30 30 struct hrtimer hrt; 31 + 32 + /* Flag to check if sstc is enabled or not */ 33 + bool sstc_enabled; 34 + /* A function pointer to switch between stimecmp or hrtimer at runtime */ 35 + int (*timer_next_event)(struct kvm_vcpu *vcpu, u64 ncycles); 31 36 }; 32 37 33 38 int kvm_riscv_vcpu_timer_next_event(struct kvm_vcpu *vcpu, u64 ncycles); ··· 45 40 int kvm_riscv_vcpu_timer_reset(struct kvm_vcpu *vcpu); 46 41 void kvm_riscv_vcpu_timer_restore(struct kvm_vcpu *vcpu); 47 42 void kvm_riscv_guest_timer_init(struct kvm *kvm); 43 + void kvm_riscv_vcpu_timer_save(struct kvm_vcpu *vcpu); 44 + bool kvm_riscv_vcpu_timer_pending(struct kvm_vcpu *vcpu); 48 45 49 46 #endif
+30 -2
arch/riscv/include/asm/sbi.h
··· 122 122 SBI_EXT_PMU_COUNTER_FW_READ, 123 123 }; 124 124 125 - #define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(55, 0) 125 + union sbi_pmu_ctr_info { 126 + unsigned long value; 127 + struct { 128 + unsigned long csr:12; 129 + unsigned long width:6; 130 + #if __riscv_xlen == 32 131 + unsigned long reserved:13; 132 + #else 133 + unsigned long reserved:45; 134 + #endif 135 + unsigned long type:1; 136 + }; 137 + }; 138 + 139 + #define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(47, 0) 126 140 #define RISCV_PMU_RAW_EVENT_IDX 0x20000 127 141 128 142 /** General pmu event codes specified in SBI PMU extension */ ··· 203 189 SBI_PMU_CTR_TYPE_FW, 204 190 }; 205 191 192 + /* Helper macros to decode event idx */ 193 + #define SBI_PMU_EVENT_IDX_OFFSET 20 194 + #define SBI_PMU_EVENT_IDX_MASK 0xFFFFF 195 + #define SBI_PMU_EVENT_IDX_CODE_MASK 0xFFFF 196 + #define SBI_PMU_EVENT_IDX_TYPE_MASK 0xF0000 197 + #define SBI_PMU_EVENT_RAW_IDX 0x20000 198 + #define SBI_PMU_FIXED_CTR_MASK 0x07 199 + 200 + #define SBI_PMU_EVENT_CACHE_ID_CODE_MASK 0xFFF8 201 + #define SBI_PMU_EVENT_CACHE_OP_ID_CODE_MASK 0x06 202 + #define SBI_PMU_EVENT_CACHE_RESULT_ID_CODE_MASK 0x01 203 + 204 + #define SBI_PMU_EVENT_IDX_INVALID 0xFFFFFFFF 205 + 206 206 /* Flags defined for config matching function */ 207 207 #define SBI_PMU_CFG_FLAG_SKIP_MATCH (1 << 0) 208 208 #define SBI_PMU_CFG_FLAG_CLEAR_VALUE (1 << 1) 209 209 #define SBI_PMU_CFG_FLAG_AUTO_START (1 << 2) 210 210 #define SBI_PMU_CFG_FLAG_SET_VUINH (1 << 3) 211 - #define SBI_PMU_CFG_FLAG_SET_VSNH (1 << 4) 211 + #define SBI_PMU_CFG_FLAG_SET_VSINH (1 << 4) 212 212 #define SBI_PMU_CFG_FLAG_SET_UINH (1 << 5) 213 213 #define SBI_PMU_CFG_FLAG_SET_SINH (1 << 6) 214 214 #define SBI_PMU_CFG_FLAG_SET_MINH (1 << 7)
+18 -3
arch/riscv/include/asm/vdso/processor.h
··· 4 4 5 5 #ifndef __ASSEMBLY__ 6 6 7 + #include <linux/jump_label.h> 7 8 #include <asm/barrier.h> 9 + #include <asm/hwcap.h> 8 10 9 11 static inline void cpu_relax(void) 10 12 { 13 + if (!static_branch_likely(&riscv_isa_ext_keys[RISCV_ISA_EXT_KEY_ZIHINTPAUSE])) { 11 14 #ifdef __riscv_muldiv 12 - int dummy; 13 - /* In lieu of a halt instruction, induce a long-latency stall. */ 14 - __asm__ __volatile__ ("div %0, %0, zero" : "=r" (dummy)); 15 + int dummy; 16 + /* In lieu of a halt instruction, induce a long-latency stall. */ 17 + __asm__ __volatile__ ("div %0, %0, zero" : "=r" (dummy)); 15 18 #endif 19 + } else { 20 + /* 21 + * Reduce instruction retirement. 22 + * This assumes the PC changes. 23 + */ 24 + #ifdef __riscv_zihintpause 25 + __asm__ __volatile__ ("pause"); 26 + #else 27 + /* Encoding of the pause instruction */ 28 + __asm__ __volatile__ (".4byte 0x100000F"); 29 + #endif 30 + } 16 31 barrier(); 17 32 } 18 33
+1
arch/riscv/include/uapi/asm/kvm.h
··· 97 97 KVM_RISCV_ISA_EXT_I, 98 98 KVM_RISCV_ISA_EXT_M, 99 99 KVM_RISCV_ISA_EXT_SVPBMT, 100 + KVM_RISCV_ISA_EXT_SSTC, 100 101 KVM_RISCV_ISA_EXT_MAX, 101 102 }; 102 103
+3
arch/riscv/kernel/cpu.c
··· 93 93 static struct riscv_isa_ext_data isa_ext_arr[] = { 94 94 __RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF), 95 95 __RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT), 96 + __RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM), 97 + __RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE), 98 + __RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC), 96 99 __RISCV_ISA_EXT_DATA("", RISCV_ISA_EXT_MAX), 97 100 }; 98 101
+2 -3
arch/riscv/kernel/cpu_ops.c
··· 9 9 #include <linux/string.h> 10 10 #include <linux/sched.h> 11 11 #include <asm/cpu_ops.h> 12 + #include <asm/cpu_ops_sbi.h> 12 13 #include <asm/sbi.h> 13 14 #include <asm/smp.h> 14 15 15 16 const struct cpu_operations *cpu_ops[NR_CPUS] __ro_after_init; 16 17 17 18 extern const struct cpu_operations cpu_ops_sbi; 18 - #ifdef CONFIG_RISCV_BOOT_SPINWAIT 19 - extern const struct cpu_operations cpu_ops_spinwait; 20 - #else 19 + #ifndef CONFIG_RISCV_BOOT_SPINWAIT 21 20 const struct cpu_operations cpu_ops_spinwait = { 22 21 .name = "", 23 22 .cpu_prepare = NULL,
+2
arch/riscv/kernel/cpu_ops_spinwait.c
··· 11 11 #include <asm/sbi.h> 12 12 #include <asm/smp.h> 13 13 14 + #include "head.h" 15 + 14 16 const struct cpu_operations cpu_ops_spinwait; 15 17 void *__cpu_spinwait_stack_pointer[NR_CPUS] __section(".data"); 16 18 void *__cpu_spinwait_task_pointer[NR_CPUS] __section(".data");
+26
arch/riscv/kernel/cpufeature.c
··· 12 12 #include <linux/module.h> 13 13 #include <linux/of.h> 14 14 #include <asm/alternative.h> 15 + #include <asm/cacheflush.h> 15 16 #include <asm/errata_list.h> 16 17 #include <asm/hwcap.h> 17 18 #include <asm/patch.h> ··· 201 200 } else { 202 201 SET_ISA_EXT_MAP("sscofpmf", RISCV_ISA_EXT_SSCOFPMF); 203 202 SET_ISA_EXT_MAP("svpbmt", RISCV_ISA_EXT_SVPBMT); 203 + SET_ISA_EXT_MAP("zicbom", RISCV_ISA_EXT_ZICBOM); 204 + SET_ISA_EXT_MAP("zihintpause", RISCV_ISA_EXT_ZIHINTPAUSE); 205 + SET_ISA_EXT_MAP("sstc", RISCV_ISA_EXT_SSTC); 204 206 } 205 207 #undef SET_ISA_EXT_MAP 206 208 } ··· 265 261 return false; 266 262 } 267 263 264 + static bool __init_or_module cpufeature_probe_zicbom(unsigned int stage) 265 + { 266 + #ifdef CONFIG_RISCV_ISA_ZICBOM 267 + switch (stage) { 268 + case RISCV_ALTERNATIVES_EARLY_BOOT: 269 + return false; 270 + default: 271 + if (riscv_isa_extension_available(NULL, ZICBOM)) { 272 + riscv_noncoherent_supported(); 273 + return true; 274 + } else { 275 + return false; 276 + } 277 + } 278 + #endif 279 + 280 + return false; 281 + } 282 + 268 283 /* 269 284 * Probe presence of individual extensions. 270 285 * ··· 297 274 298 275 if (cpufeature_probe_svpbmt(stage)) 299 276 cpu_req_feature |= (1U << CPUFEATURE_SVPBMT); 277 + 278 + if (cpufeature_probe_zicbom(stage)) 279 + cpu_req_feature |= (1U << CPUFEATURE_ZICBOM); 300 280 301 281 return cpu_req_feature; 302 282 }
+1 -1
arch/riscv/kernel/crash_save_regs.S
··· 44 44 REG_S t6, PT_T6(a0) /* x31 */ 45 45 46 46 csrr t1, CSR_STATUS 47 - csrr t2, CSR_EPC 47 + auipc t2, 0x0 48 48 csrr t3, CSR_TVAL 49 49 csrr t4, CSR_CAUSE 50 50
+23 -5
arch/riscv/kernel/machine_kexec.c
··· 138 138 #endif 139 139 } 140 140 141 + /* Override the weak function in kernel/panic.c */ 142 + void crash_smp_send_stop(void) 143 + { 144 + static int cpus_stopped; 145 + 146 + /* 147 + * This function can be called twice in panic path, but obviously 148 + * we execute this only once. 149 + */ 150 + if (cpus_stopped) 151 + return; 152 + 153 + smp_send_stop(); 154 + cpus_stopped = 1; 155 + } 156 + 141 157 /* 142 158 * machine_crash_shutdown - Prepare to kexec after a kernel crash 143 159 * 144 160 * This function is called by crash_kexec just before machine_kexec 145 - * below and its goal is similar to machine_shutdown, but in case of 146 - * a kernel crash. Since we don't handle such cases yet, this function 147 - * is empty. 161 + * and its goal is to shutdown non-crashing cpus and save registers. 148 162 */ 149 163 void 150 164 machine_crash_shutdown(struct pt_regs *regs) 151 165 { 166 + local_irq_disable(); 167 + 168 + /* shutdown non-crashing cpus */ 169 + crash_smp_send_stop(); 170 + 152 171 crash_save_cpu(regs, smp_processor_id()); 153 - machine_shutdown(); 154 172 pr_info("Starting crashdump kernel...\n"); 155 173 } 156 174 ··· 189 171 struct kimage_arch *internal = &image->arch; 190 172 unsigned long jump_addr = (unsigned long) image->start; 191 173 unsigned long first_ind_entry = (unsigned long) &image->head; 192 - unsigned long this_cpu_id = smp_processor_id(); 174 + unsigned long this_cpu_id = __smp_processor_id(); 193 175 unsigned long this_hart_id = cpuid_to_hartid_map(this_cpu_id); 194 176 unsigned long fdt_addr = internal->fdt_addr; 195 177 void *control_code_buffer = page_address(image->control_code_page);
-6
arch/riscv/kernel/probes/uprobes.c
··· 59 59 60 60 instruction_pointer_set(regs, utask->xol_vaddr); 61 61 62 - regs->status &= ~SR_SPIE; 63 - 64 62 return 0; 65 63 } 66 64 ··· 69 71 WARN_ON_ONCE(current->thread.bad_cause != UPROBE_TRAP_NR); 70 72 71 73 instruction_pointer_set(regs, utask->vaddr + auprobe->insn_size); 72 - 73 - regs->status |= SR_SPIE; 74 74 75 75 return 0; 76 76 } ··· 107 111 * address. 108 112 */ 109 113 instruction_pointer_set(regs, utask->vaddr); 110 - 111 - regs->status &= ~SR_SPIE; 112 114 } 113 115 114 116 bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx,
+2
arch/riscv/kernel/setup.c
··· 22 22 #include <linux/crash_dump.h> 23 23 24 24 #include <asm/alternative.h> 25 + #include <asm/cacheflush.h> 25 26 #include <asm/cpu_ops.h> 26 27 #include <asm/early_ioremap.h> 27 28 #include <asm/pgtable.h> ··· 297 296 #endif 298 297 299 298 riscv_fill_hwcap(); 299 + riscv_init_cbom_blocksize(); 300 300 apply_boot_alternatives(); 301 301 } 302 302
+3 -5
arch/riscv/kernel/traps_misaligned.c
··· 7 7 #include <linux/mm.h> 8 8 #include <linux/module.h> 9 9 #include <linux/irq.h> 10 + #include <linux/stringify.h> 10 11 11 12 #include <asm/processor.h> 12 13 #include <asm/ptrace.h> ··· 151 150 #define PRECISION_S 0 152 151 #define PRECISION_D 1 153 152 154 - #define STR(x) XSTR(x) 155 - #define XSTR(x) #x 156 - 157 153 #define DECLARE_UNPRIVILEGED_LOAD_FUNCTION(type, insn) \ 158 154 static inline type load_##type(const type *addr) \ 159 155 { \ ··· 205 207 asm ("and %[tmp], %[addr], 2\n" 206 208 "bnez %[tmp], 1f\n" 207 209 #if defined(CONFIG_64BIT) 208 - STR(LWU) " %[insn], (%[addr])\n" 210 + __stringify(LWU) " %[insn], (%[addr])\n" 209 211 #else 210 - STR(LW) " %[insn], (%[addr])\n" 212 + __stringify(LW) " %[insn], (%[addr])\n" 211 213 #endif 212 214 "and %[tmp], %[insn], %[rvc_mask]\n" 213 215 "beq %[tmp], %[rvc_mask], 2f\n"
+7 -1
arch/riscv/kvm/vcpu.c
··· 52 52 RISCV_ISA_EXT_i, 53 53 RISCV_ISA_EXT_m, 54 54 RISCV_ISA_EXT_SVPBMT, 55 + RISCV_ISA_EXT_SSTC, 55 56 }; 56 57 57 58 static unsigned long kvm_riscv_vcpu_base2isa_ext(unsigned long base_ext) ··· 86 85 case KVM_RISCV_ISA_EXT_C: 87 86 case KVM_RISCV_ISA_EXT_I: 88 87 case KVM_RISCV_ISA_EXT_M: 88 + case KVM_RISCV_ISA_EXT_SSTC: 89 89 return false; 90 90 default: 91 91 break; ··· 205 203 206 204 int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) 207 205 { 208 - return kvm_riscv_vcpu_has_interrupts(vcpu, 1UL << IRQ_VS_TIMER); 206 + return kvm_riscv_vcpu_timer_pending(vcpu); 209 207 } 210 208 211 209 void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) ··· 787 785 if (__riscv_isa_extension_available(isa, RISCV_ISA_EXT_SVPBMT)) 788 786 henvcfg |= ENVCFG_PBMTE; 789 787 788 + if (__riscv_isa_extension_available(isa, RISCV_ISA_EXT_SSTC)) 789 + henvcfg |= ENVCFG_STCE; 790 790 csr_write(CSR_HENVCFG, henvcfg); 791 791 #ifdef CONFIG_32BIT 792 792 csr_write(CSR_HENVCFGH, henvcfg >> 32); ··· 831 827 kvm_riscv_vcpu_guest_fp_save(&vcpu->arch.guest_context, 832 828 vcpu->arch.isa); 833 829 kvm_riscv_vcpu_host_fp_restore(&vcpu->arch.host_context); 830 + 831 + kvm_riscv_vcpu_timer_save(vcpu); 834 832 835 833 csr->vsstatus = csr_read(CSR_VSSTATUS); 836 834 csr->vsie = csr_read(CSR_VSIE);
+139 -7
arch/riscv/kvm/vcpu_timer.c
··· 69 69 return 0; 70 70 } 71 71 72 - int kvm_riscv_vcpu_timer_next_event(struct kvm_vcpu *vcpu, u64 ncycles) 72 + static int kvm_riscv_vcpu_update_vstimecmp(struct kvm_vcpu *vcpu, u64 ncycles) 73 + { 74 + #if defined(CONFIG_32BIT) 75 + csr_write(CSR_VSTIMECMP, ncycles & 0xFFFFFFFF); 76 + csr_write(CSR_VSTIMECMPH, ncycles >> 32); 77 + #else 78 + csr_write(CSR_VSTIMECMP, ncycles); 79 + #endif 80 + return 0; 81 + } 82 + 83 + static int kvm_riscv_vcpu_update_hrtimer(struct kvm_vcpu *vcpu, u64 ncycles) 73 84 { 74 85 struct kvm_vcpu_timer *t = &vcpu->arch.timer; 75 86 struct kvm_guest_timer *gt = &vcpu->kvm->arch.timer; ··· 97 86 t->next_set = true; 98 87 99 88 return 0; 89 + } 90 + 91 + int kvm_riscv_vcpu_timer_next_event(struct kvm_vcpu *vcpu, u64 ncycles) 92 + { 93 + struct kvm_vcpu_timer *t = &vcpu->arch.timer; 94 + 95 + return t->timer_next_event(vcpu, ncycles); 96 + } 97 + 98 + static enum hrtimer_restart kvm_riscv_vcpu_vstimer_expired(struct hrtimer *h) 99 + { 100 + u64 delta_ns; 101 + struct kvm_vcpu_timer *t = container_of(h, struct kvm_vcpu_timer, hrt); 102 + struct kvm_vcpu *vcpu = container_of(t, struct kvm_vcpu, arch.timer); 103 + struct kvm_guest_timer *gt = &vcpu->kvm->arch.timer; 104 + 105 + if (kvm_riscv_current_cycles(gt) < t->next_cycles) { 106 + delta_ns = kvm_riscv_delta_cycles2ns(t->next_cycles, gt, t); 107 + hrtimer_forward_now(&t->hrt, ktime_set(0, delta_ns)); 108 + return HRTIMER_RESTART; 109 + } 110 + 111 + t->next_set = false; 112 + kvm_vcpu_kick(vcpu); 113 + 114 + return HRTIMER_NORESTART; 115 + } 116 + 117 + bool kvm_riscv_vcpu_timer_pending(struct kvm_vcpu *vcpu) 118 + { 119 + struct kvm_vcpu_timer *t = &vcpu->arch.timer; 120 + struct kvm_guest_timer *gt = &vcpu->kvm->arch.timer; 121 + 122 + if (!kvm_riscv_delta_cycles2ns(t->next_cycles, gt, t) || 123 + kvm_riscv_vcpu_has_interrupts(vcpu, 1UL << IRQ_VS_TIMER)) 124 + return true; 125 + else 126 + return false; 127 + } 128 + 129 + static void kvm_riscv_vcpu_timer_blocking(struct kvm_vcpu *vcpu) 130 + { 131 + struct kvm_vcpu_timer *t = &vcpu->arch.timer; 132 + struct kvm_guest_timer *gt = &vcpu->kvm->arch.timer; 133 + u64 delta_ns; 134 + 135 + if (!t->init_done) 136 + return; 137 + 138 + delta_ns = kvm_riscv_delta_cycles2ns(t->next_cycles, gt, t); 139 + if (delta_ns) { 140 + hrtimer_start(&t->hrt, ktime_set(0, delta_ns), HRTIMER_MODE_REL); 141 + t->next_set = true; 142 + } 143 + } 144 + 145 + static void kvm_riscv_vcpu_timer_unblocking(struct kvm_vcpu *vcpu) 146 + { 147 + kvm_riscv_vcpu_timer_cancel(&vcpu->arch.timer); 100 148 } 101 149 102 150 int kvm_riscv_vcpu_get_reg_timer(struct kvm_vcpu *vcpu, ··· 250 180 return -EINVAL; 251 181 252 182 hrtimer_init(&t->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 253 - t->hrt.function = kvm_riscv_vcpu_hrtimer_expired; 254 183 t->init_done = true; 255 184 t->next_set = false; 185 + 186 + /* Enable sstc for every vcpu if available in hardware */ 187 + if (riscv_isa_extension_available(NULL, SSTC)) { 188 + t->sstc_enabled = true; 189 + t->hrt.function = kvm_riscv_vcpu_vstimer_expired; 190 + t->timer_next_event = kvm_riscv_vcpu_update_vstimecmp; 191 + } else { 192 + t->sstc_enabled = false; 193 + t->hrt.function = kvm_riscv_vcpu_hrtimer_expired; 194 + t->timer_next_event = kvm_riscv_vcpu_update_hrtimer; 195 + } 256 196 257 197 return 0; 258 198 } ··· 279 199 280 200 int kvm_riscv_vcpu_timer_reset(struct kvm_vcpu *vcpu) 281 201 { 202 + struct kvm_vcpu_timer *t = &vcpu->arch.timer; 203 + 204 + t->next_cycles = -1ULL; 282 205 return kvm_riscv_vcpu_timer_cancel(&vcpu->arch.timer); 206 + } 207 + 208 + static void kvm_riscv_vcpu_update_timedelta(struct kvm_vcpu *vcpu) 209 + { 210 + struct kvm_guest_timer *gt = &vcpu->kvm->arch.timer; 211 + 212 + #if defined(CONFIG_32BIT) 213 + csr_write(CSR_HTIMEDELTA, (u32)(gt->time_delta)); 214 + csr_write(CSR_HTIMEDELTAH, (u32)(gt->time_delta >> 32)); 215 + #else 216 + csr_write(CSR_HTIMEDELTA, gt->time_delta); 217 + #endif 283 218 } 284 219 285 220 void kvm_riscv_vcpu_timer_restore(struct kvm_vcpu *vcpu) 286 221 { 287 - struct kvm_guest_timer *gt = &vcpu->kvm->arch.timer; 222 + struct kvm_vcpu_csr *csr; 223 + struct kvm_vcpu_timer *t = &vcpu->arch.timer; 288 224 289 - #ifdef CONFIG_64BIT 290 - csr_write(CSR_HTIMEDELTA, gt->time_delta); 225 + kvm_riscv_vcpu_update_timedelta(vcpu); 226 + 227 + if (!t->sstc_enabled) 228 + return; 229 + 230 + csr = &vcpu->arch.guest_csr; 231 + #if defined(CONFIG_32BIT) 232 + csr_write(CSR_VSTIMECMP, (u32)t->next_cycles); 233 + csr_write(CSR_VSTIMECMPH, (u32)(t->next_cycles >> 32)); 291 234 #else 292 - csr_write(CSR_HTIMEDELTA, (u32)(gt->time_delta)); 293 - csr_write(CSR_HTIMEDELTAH, (u32)(gt->time_delta >> 32)); 235 + csr_write(CSR_VSTIMECMP, t->next_cycles); 294 236 #endif 237 + 238 + /* timer should be enabled for the remaining operations */ 239 + if (unlikely(!t->init_done)) 240 + return; 241 + 242 + kvm_riscv_vcpu_timer_unblocking(vcpu); 243 + } 244 + 245 + void kvm_riscv_vcpu_timer_save(struct kvm_vcpu *vcpu) 246 + { 247 + struct kvm_vcpu_csr *csr; 248 + struct kvm_vcpu_timer *t = &vcpu->arch.timer; 249 + 250 + if (!t->sstc_enabled) 251 + return; 252 + 253 + csr = &vcpu->arch.guest_csr; 254 + t = &vcpu->arch.timer; 255 + #if defined(CONFIG_32BIT) 256 + t->next_cycles = csr_read(CSR_VSTIMECMP); 257 + t->next_cycles |= (u64)csr_read(CSR_VSTIMECMPH) << 32; 258 + #else 259 + t->next_cycles = csr_read(CSR_VSTIMECMP); 260 + #endif 261 + /* timer should be enabled for the remaining operations */ 262 + if (unlikely(!t->init_done)) 263 + return; 264 + 265 + if (kvm_vcpu_is_blocking(vcpu)) 266 + kvm_riscv_vcpu_timer_blocking(vcpu); 295 267 } 296 268 297 269 void kvm_riscv_guest_timer_init(struct kvm *kvm)
+2 -2
arch/riscv/lib/uaccess.S
··· 175 175 /* Exception fixup code */ 176 176 10: 177 177 /* Disable access to user memory */ 178 - csrs CSR_STATUS, t6 178 + csrc CSR_STATUS, t6 179 179 mv a0, t5 180 180 ret 181 181 ENDPROC(__asm_copy_to_user) ··· 227 227 /* Exception fixup code */ 228 228 11: 229 229 /* Disable access to user memory */ 230 - csrs CSR_STATUS, t6 230 + csrc CSR_STATUS, t6 231 231 mv a0, a1 232 232 ret 233 233 ENDPROC(__clear_user)
+1
arch/riscv/mm/Makefile
··· 30 30 endif 31 31 32 32 obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o 33 + obj-$(CONFIG_RISCV_DMA_NONCOHERENT) += dma-noncoherent.o
+116
arch/riscv/mm/dma-noncoherent.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * RISC-V specific functions to support DMA for non-coherent devices 4 + * 5 + * Copyright (c) 2021 Western Digital Corporation or its affiliates. 6 + */ 7 + 8 + #include <linux/dma-direct.h> 9 + #include <linux/dma-map-ops.h> 10 + #include <linux/mm.h> 11 + #include <linux/of.h> 12 + #include <linux/of_device.h> 13 + #include <asm/cacheflush.h> 14 + 15 + static unsigned int riscv_cbom_block_size = L1_CACHE_BYTES; 16 + static bool noncoherent_supported; 17 + 18 + void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, 19 + enum dma_data_direction dir) 20 + { 21 + void *vaddr = phys_to_virt(paddr); 22 + 23 + switch (dir) { 24 + case DMA_TO_DEVICE: 25 + ALT_CMO_OP(clean, vaddr, size, riscv_cbom_block_size); 26 + break; 27 + case DMA_FROM_DEVICE: 28 + ALT_CMO_OP(clean, vaddr, size, riscv_cbom_block_size); 29 + break; 30 + case DMA_BIDIRECTIONAL: 31 + ALT_CMO_OP(flush, vaddr, size, riscv_cbom_block_size); 32 + break; 33 + default: 34 + break; 35 + } 36 + } 37 + 38 + void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, 39 + enum dma_data_direction dir) 40 + { 41 + void *vaddr = phys_to_virt(paddr); 42 + 43 + switch (dir) { 44 + case DMA_TO_DEVICE: 45 + break; 46 + case DMA_FROM_DEVICE: 47 + case DMA_BIDIRECTIONAL: 48 + ALT_CMO_OP(flush, vaddr, size, riscv_cbom_block_size); 49 + break; 50 + default: 51 + break; 52 + } 53 + } 54 + 55 + void arch_dma_prep_coherent(struct page *page, size_t size) 56 + { 57 + void *flush_addr = page_address(page); 58 + 59 + ALT_CMO_OP(flush, flush_addr, size, riscv_cbom_block_size); 60 + } 61 + 62 + void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, 63 + const struct iommu_ops *iommu, bool coherent) 64 + { 65 + WARN_TAINT(!coherent && riscv_cbom_block_size > ARCH_DMA_MINALIGN, 66 + TAINT_CPU_OUT_OF_SPEC, 67 + "%s %s: ARCH_DMA_MINALIGN smaller than riscv,cbom-block-size (%d < %d)", 68 + dev_driver_string(dev), dev_name(dev), 69 + ARCH_DMA_MINALIGN, riscv_cbom_block_size); 70 + 71 + WARN_TAINT(!coherent && !noncoherent_supported, TAINT_CPU_OUT_OF_SPEC, 72 + "%s %s: device non-coherent but no non-coherent operations supported", 73 + dev_driver_string(dev), dev_name(dev)); 74 + 75 + dev->dma_coherent = coherent; 76 + } 77 + 78 + #ifdef CONFIG_RISCV_ISA_ZICBOM 79 + void riscv_init_cbom_blocksize(void) 80 + { 81 + struct device_node *node; 82 + int ret; 83 + u32 val; 84 + 85 + for_each_of_cpu_node(node) { 86 + unsigned long hartid; 87 + int cbom_hartid; 88 + 89 + ret = riscv_of_processor_hartid(node, &hartid); 90 + if (ret) 91 + continue; 92 + 93 + if (hartid < 0) 94 + continue; 95 + 96 + /* set block-size for cbom extension if available */ 97 + ret = of_property_read_u32(node, "riscv,cbom-block-size", &val); 98 + if (ret) 99 + continue; 100 + 101 + if (!riscv_cbom_block_size) { 102 + riscv_cbom_block_size = val; 103 + cbom_hartid = hartid; 104 + } else { 105 + if (riscv_cbom_block_size != val) 106 + pr_warn("cbom-block-size mismatched between harts %d and %lu\n", 107 + cbom_hartid, hartid); 108 + } 109 + } 110 + } 111 + #endif 112 + 113 + void riscv_noncoherent_supported(void) 114 + { 115 + noncoherent_supported = true; 116 + }
+4
arch/riscv/mm/init.c
··· 135 135 (unsigned long)VMEMMAP_END); 136 136 print_ml("vmalloc", (unsigned long)VMALLOC_START, 137 137 (unsigned long)VMALLOC_END); 138 + #ifdef CONFIG_64BIT 139 + print_ml("modules", (unsigned long)MODULES_VADDR, 140 + (unsigned long)MODULES_END); 141 + #endif 138 142 print_ml("lowmem", (unsigned long)PAGE_OFFSET, 139 143 (unsigned long)high_memory); 140 144 if (IS_ENABLED(CONFIG_64BIT)) {
-1
arch/riscv/purgatory/.gitignore
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 purgatory.chk 3 3 purgatory.ro 4 - kexec-purgatory.c
+2 -8
arch/riscv/purgatory/Makefile
··· 84 84 $(obj)/purgatory.chk: $(obj)/purgatory.ro FORCE 85 85 $(call if_changed,ld) 86 86 87 - targets += kexec-purgatory.c 87 + $(obj)/kexec-purgatory.o: $(obj)/purgatory.ro $(obj)/purgatory.chk 88 88 89 - quiet_cmd_bin2c = BIN2C $@ 90 - cmd_bin2c = $(objtree)/scripts/bin2c kexec_purgatory < $< > $@ 91 - 92 - $(obj)/kexec-purgatory.c: $(obj)/purgatory.ro $(obj)/purgatory.chk FORCE 93 - $(call if_changed,bin2c) 94 - 95 - obj-$(CONFIG_ARCH_HAS_KEXEC_PURGATORY) += kexec-purgatory.o 89 + obj-y += kexec-purgatory.o
+14
arch/riscv/purgatory/kexec-purgatory.S
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + .section .rodata, "a" 4 + 5 + .align 8 6 + kexec_purgatory: 7 + .globl kexec_purgatory 8 + .incbin "arch/riscv/purgatory/purgatory.ro" 9 + .Lkexec_purgatroy_end: 10 + 11 + .align 8 12 + kexec_purgatory_size: 13 + .globl kexec_purgatory_size 14 + .quad .Lkexec_purgatroy_end - kexec_purgatory
+24 -1
drivers/clocksource/timer-riscv.c
··· 7 7 * either be read from the "time" and "timeh" CSRs, and can use the SBI to 8 8 * setup events, or directly accessed using MMIO registers. 9 9 */ 10 + 11 + #define pr_fmt(fmt) "riscv-timer: " fmt 12 + 10 13 #include <linux/clocksource.h> 11 14 #include <linux/clockchips.h> 12 15 #include <linux/cpu.h> ··· 23 20 #include <linux/of_irq.h> 24 21 #include <clocksource/timer-riscv.h> 25 22 #include <asm/smp.h> 23 + #include <asm/hwcap.h> 26 24 #include <asm/sbi.h> 27 25 #include <asm/timex.h> 26 + 27 + static DEFINE_STATIC_KEY_FALSE(riscv_sstc_available); 28 28 29 29 static int riscv_clock_next_event(unsigned long delta, 30 30 struct clock_event_device *ce) 31 31 { 32 + u64 next_tval = get_cycles64() + delta; 33 + 32 34 csr_set(CSR_IE, IE_TIE); 33 - sbi_set_timer(get_cycles64() + delta); 35 + if (static_branch_likely(&riscv_sstc_available)) { 36 + #if defined(CONFIG_32BIT) 37 + csr_write(CSR_STIMECMP, next_tval & 0xFFFFFFFF); 38 + csr_write(CSR_STIMECMPH, next_tval >> 32); 39 + #else 40 + csr_write(CSR_STIMECMP, next_tval); 41 + #endif 42 + } else 43 + sbi_set_timer(next_tval); 44 + 34 45 return 0; 35 46 } 36 47 ··· 183 166 if (error) 184 167 pr_err("cpu hp setup state failed for RISCV timer [%d]\n", 185 168 error); 169 + 170 + if (riscv_isa_extension_available(NULL, SSTC)) { 171 + pr_info("Timer interrupt in S-mode is available via sstc extension\n"); 172 + static_branch_enable(&riscv_sstc_available); 173 + } 174 + 186 175 return error; 187 176 } 188 177
+10 -7
drivers/of/address.c
··· 1045 1045 * 1046 1046 * It returns true if "dma-coherent" property was found 1047 1047 * for this device in the DT, or if DMA is coherent by 1048 - * default for OF devices on the current platform. 1048 + * default for OF devices on the current platform and no 1049 + * "dma-noncoherent" property was found for this device. 1049 1050 */ 1050 1051 bool of_dma_is_coherent(struct device_node *np) 1051 1052 { 1052 1053 struct device_node *node; 1053 - 1054 - if (IS_ENABLED(CONFIG_OF_DMA_DEFAULT_COHERENT)) 1055 - return true; 1054 + bool is_coherent = IS_ENABLED(CONFIG_OF_DMA_DEFAULT_COHERENT); 1056 1055 1057 1056 node = of_node_get(np); 1058 1057 1059 1058 while (node) { 1060 1059 if (of_property_read_bool(node, "dma-coherent")) { 1061 - of_node_put(node); 1062 - return true; 1060 + is_coherent = true; 1061 + break; 1062 + } 1063 + if (of_property_read_bool(node, "dma-noncoherent")) { 1064 + is_coherent = false; 1065 + break; 1063 1066 } 1064 1067 node = of_get_next_dma_parent(node); 1065 1068 } 1066 1069 of_node_put(node); 1067 - return false; 1070 + return is_coherent; 1068 1071 } 1069 1072 EXPORT_SYMBOL_GPL(of_dma_is_coherent); 1070 1073
-1
drivers/perf/riscv_pmu.c
··· 170 170 left = (max_period >> 1); 171 171 172 172 local64_set(&hwc->prev_count, (u64)-left); 173 - perf_event_update_userpage(event); 174 173 175 174 return overflow; 176 175 }
+16 -14
drivers/perf/riscv_pmu_sbi.c
··· 41 41 NULL, 42 42 }; 43 43 44 - union sbi_pmu_ctr_info { 45 - unsigned long value; 46 - struct { 47 - unsigned long csr:12; 48 - unsigned long width:6; 49 - #if __riscv_xlen == 32 50 - unsigned long reserved:13; 51 - #else 52 - unsigned long reserved:45; 53 - #endif 54 - unsigned long type:1; 55 - }; 56 - }; 57 - 58 44 /* 59 45 * RISC-V doesn't have hetergenous harts yet. This need to be part of 60 46 * per_cpu in case of harts with different pmu counters ··· 280 294 cflags |= SBI_PMU_CFG_FLAG_SET_UINH; 281 295 282 296 /* retrieve the available counter index */ 297 + #if defined(CONFIG_32BIT) 298 + ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase, cmask, 299 + cflags, hwc->event_base, hwc->config, hwc->config >> 32); 300 + #else 283 301 ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase, cmask, 284 302 cflags, hwc->event_base, hwc->config, 0); 303 + #endif 285 304 if (ret.error) { 286 305 pr_debug("Not able to find a counter for event %lx config %llx\n", 287 306 hwc->event_base, hwc->config); ··· 428 437 struct hw_perf_event *hwc = &event->hw; 429 438 unsigned long flag = SBI_PMU_START_FLAG_SET_INIT_VALUE; 430 439 440 + #if defined(CONFIG_32BIT) 431 441 ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, hwc->idx, 432 442 1, flag, ival, ival >> 32, 0); 443 + #else 444 + ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, hwc->idx, 445 + 1, flag, ival, 0, 0); 446 + #endif 433 447 if (ret.error && (ret.error != SBI_ERR_ALREADY_STARTED)) 434 448 pr_err("Starting counter idx %d failed with error %d\n", 435 449 hwc->idx, sbi_err_map_linux_errno(ret.error)); ··· 541 545 hwc = &event->hw; 542 546 max_period = riscv_pmu_ctr_get_width_mask(event); 543 547 init_val = local64_read(&hwc->prev_count) & max_period; 548 + #if defined(CONFIG_32BIT) 549 + sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, idx, 1, 550 + flag, init_val, init_val >> 32, 0); 551 + #else 544 552 sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, idx, 1, 545 553 flag, init_val, 0, 0); 554 + #endif 555 + perf_event_update_userpage(event); 546 556 } 547 557 ctr_ovf_mask = ctr_ovf_mask >> 1; 548 558 idx++;
+2
scripts/remove-stale-files
··· 42 42 done 43 43 fi 44 44 45 + rm -f arch/riscv/purgatory/kexec-purgatory.c 46 + 45 47 rm -f scripts/extract-cert 46 48 47 49 rm -f arch/x86/purgatory/kexec-purgatory.c
+1
tools/testing/selftests/wireguard/qemu/arch/riscv32.config
··· 1 + CONFIG_NONPORTABLE=y 1 2 CONFIG_ARCH_RV32I=y 2 3 CONFIG_MMU=y 3 4 CONFIG_FPU=y