diff options
author | 2020-11-19 08:53:14 +0000 | |
---|---|---|
committer | 2020-11-19 08:53:14 +0000 | |
commit | 9e1dc75e2daa85a654de4a3aeb461dca3f921917 (patch) | |
tree | 0764d0645374a32194bc6fa869dd1ea853a00070 | |
parent | Allow specific devices to be used for play-only and rec-only modes. (diff) | |
download | wireguard-openbsd-9e1dc75e2daa85a654de4a3aeb461dca3f921917.tar.xz wireguard-openbsd-9e1dc75e2daa85a654de4a3aeb461dca3f921917.zip |
The conversion of the IO BAR access did not completely mirror the
behaviour of Linux' implementation: arm64's bus space operations
have no barriers, so while Linux' iowrite32/ioread32 explicitly
contain barriers, using bus space read/write is not enough on arm64.
Add read barriers after a read to make sure that all reads have
completed before the following reads. Add write barriers before a
write to make sure all previous writes have completed before that
write. This fixes panics on the HoneyComb LX2K with amdgpu(4).
ok kettenis@
-rw-r--r-- | sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c index b3e7d8da763..45eff483e86 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c @@ -378,14 +378,24 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev, uint32_t reg, uint32_t */ u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg) { - if ((reg * 4) < adev->rio_mem_size) - return bus_space_read_4(adev->rio_mem_bst, adev->rio_mem_bsh, reg); - else { + u32 val; + + if ((reg * 4) < adev->rio_mem_size) { + val = bus_space_read_4(adev->rio_mem_bst, adev->rio_mem_bsh, reg); + bus_space_barrier(adev->rio_mem_bst, adev->rio_mem_bsh, 0, + adev->rio_mem_size, BUS_SPACE_BARRIER_READ); + } else { + bus_space_barrier(adev->rio_mem_bst, adev->rio_mem_bsh, 0, + adev->rio_mem_size, BUS_SPACE_BARRIER_WRITE); bus_space_write_4(adev->rio_mem_bst, adev->rio_mem_bsh, mmMM_INDEX * 4, reg * 4); - return bus_space_read_4(adev->rio_mem_bst, adev->rio_mem_bsh, + val = bus_space_read_4(adev->rio_mem_bst, adev->rio_mem_bsh, mmMM_INDEX * 4); + bus_space_barrier(adev->rio_mem_bst, adev->rio_mem_bsh, 0, + adev->rio_mem_size, BUS_SPACE_BARRIER_READ); } + + return val; } /** @@ -403,12 +413,18 @@ void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v) adev->last_mm_index = v; } - if ((reg * 4) < adev->rio_mem_size) + if ((reg * 4) < adev->rio_mem_size) { + bus_space_barrier(adev->rio_mem_bst, adev->rio_mem_bsh, 0, + adev->rio_mem_size, BUS_SPACE_BARRIER_WRITE); bus_space_write_4(adev->rio_mem_bst, adev->rio_mem_bsh, reg * 4, v); - else { + } else { + bus_space_barrier(adev->rio_mem_bst, adev->rio_mem_bsh, 0, + adev->rio_mem_size, BUS_SPACE_BARRIER_WRITE); bus_space_write_4(adev->rio_mem_bst, adev->rio_mem_bsh, mmMM_INDEX * 4, reg * 4); + bus_space_barrier(adev->rio_mem_bst, adev->rio_mem_bsh, 0, + adev->rio_mem_size, BUS_SPACE_BARRIER_WRITE); bus_space_write_4(adev->rio_mem_bst, adev->rio_mem_bsh, mmMM_DATA * 4, v); |