|
5 | 5 | //! |
6 | 6 | //! Copyright (C) The Asahi Linux Contributors |
7 | 7 |
|
8 | | -use core::slice; |
9 | 8 | use core::sync::atomic::{AtomicBool, Ordering}; |
10 | 9 |
|
11 | 10 | use kernel::{ |
@@ -39,76 +38,68 @@ const MSG_DATA_SHIFT: u32 = 32; |
39 | 38 |
|
40 | 39 | const IOVA_SHIFT: u32 = 0xC; |
41 | 40 |
|
42 | | -type ShMem = dma::CoherentAllocation<u8, dma::CoherentAllocator>; |
| 41 | +type ShMem = dma::CoherentAllocation<u8>; |
43 | 42 |
|
44 | 43 | fn align_up(v: usize, a: usize) -> usize { |
45 | 44 | (v + a - 1) & !(a - 1) |
46 | 45 | } |
47 | 46 |
|
48 | | -fn memcpy_to_iomem( |
49 | | - iomem: &ShMem, |
50 | | - dev: &ARef<device::Device>, |
51 | | - off: usize, |
52 | | - src: &[u8], |
53 | | -) -> Result<()> { |
54 | | - if off + src.len() > iomem.count() { |
55 | | - dev_err!(dev, "Out of bounds iomem write"); |
56 | | - return Err(EIO); |
57 | | - } |
58 | | - // SAFETY: We checked that it is in bounds above |
| 47 | +fn memcpy_to_iomem(iomem: &ShMem, off: usize, src: &[u8]) -> Result<()> { |
| 48 | + // SAFETY: |
| 49 | + // as_slice_mut() checks that off and src.len() are whithin iomem's limits. |
| 50 | + // memcpy_to_iomem is only called from within probe() ansuring there are no |
| 51 | + // concurrent read and write accesses to the same region while the slice is |
| 52 | + // alive per as_slice_mut()'s requiremnts. |
59 | 53 | unsafe { |
60 | | - let ptr = iomem.first_ptr_mut().offset(off as isize); |
61 | | - let target = slice::from_raw_parts_mut(ptr, src.len()); |
| 54 | + let target = iomem.as_slice_mut(off, src.len())?; |
62 | 55 | target.copy_from_slice(src); |
63 | 56 | } |
64 | 57 | Ok(()) |
65 | 58 | } |
66 | 59 |
|
67 | 60 | fn build_shmem(dev: ARef<device::Device>) -> Result<ShMem> { |
68 | 61 | let of = dev.of_node().ok_or(EIO)?; |
69 | | - let iomem = dma::try_alloc_coherent(dev.clone(), SHMEM_SIZE, false)?; |
| 62 | + let iomem = dma::CoherentAllocation::<u8>::alloc_coherent(dev.clone(), SHMEM_SIZE, GFP_KERNEL)?; |
70 | 63 |
|
71 | 64 | let panic_offset = 0x4000; |
72 | 65 | let panic_size = 0x8000; |
73 | | - memcpy_to_iomem(&iomem, &dev, panic_offset, &1u32.to_le_bytes())?; |
| 66 | + memcpy_to_iomem(&iomem, panic_offset, &1u32.to_le_bytes())?; |
74 | 67 |
|
75 | 68 | let lpol_offset = panic_offset + panic_size; |
76 | 69 | let lpol = of |
77 | 70 | .find_property(c_str!("local-policy-manifest")) |
78 | 71 | .ok_or(EIO)?; |
79 | 72 | memcpy_to_iomem( |
80 | 73 | &iomem, |
81 | | - &dev, |
82 | 74 | lpol_offset, |
83 | 75 | &(lpol.value().len() as u32).to_le_bytes(), |
84 | 76 | )?; |
85 | | - memcpy_to_iomem(&iomem, &dev, lpol_offset + 4, lpol.value())?; |
| 77 | + memcpy_to_iomem(&iomem, lpol_offset + 4, lpol.value())?; |
86 | 78 | let lpol_size = align_up(lpol.value().len() + 4, 0x4000); |
87 | 79 |
|
88 | 80 | let ibot_offset = lpol_offset + lpol_size; |
89 | 81 | let ibot = of.find_property(c_str!("iboot-manifest")).ok_or(EIO)?; |
90 | 82 | memcpy_to_iomem( |
91 | 83 | &iomem, |
92 | | - &dev, |
93 | 84 | ibot_offset, |
94 | 85 | &(ibot.value().len() as u32).to_le_bytes(), |
95 | 86 | )?; |
96 | | - memcpy_to_iomem(&iomem, &dev, ibot_offset + 4, ibot.value())?; |
| 87 | + memcpy_to_iomem(&iomem, ibot_offset + 4, ibot.value())?; |
97 | 88 | let ibot_size = align_up(ibot.value().len() + 4, 0x4000); |
98 | 89 |
|
99 | | - memcpy_to_iomem(&iomem, &dev, 0, b"CNIP")?; |
100 | | - memcpy_to_iomem(&iomem, &dev, 4, &(panic_size as u32).to_le_bytes())?; |
101 | | - memcpy_to_iomem(&iomem, &dev, 8, &(panic_offset as u32).to_le_bytes())?; |
| 90 | + memcpy_to_iomem(&iomem, 0, b"CNIP")?; |
| 91 | + memcpy_to_iomem(&iomem, 4, &(panic_size as u32).to_le_bytes())?; |
| 92 | + memcpy_to_iomem(&iomem, 8, &(panic_offset as u32).to_le_bytes())?; |
102 | 93 |
|
103 | | - memcpy_to_iomem(&iomem, &dev, 16, b"OPLA")?; |
104 | | - memcpy_to_iomem(&iomem, &dev, 16 + 4, &(lpol_size as u32).to_le_bytes())?; |
105 | | - memcpy_to_iomem(&iomem, &dev, 16 + 8, &(lpol_offset as u32).to_le_bytes())?; |
| 94 | + memcpy_to_iomem(&iomem, 16, b"OPLA")?; |
| 95 | + memcpy_to_iomem(&iomem, 16 + 4, &(lpol_size as u32).to_le_bytes())?; |
| 96 | + memcpy_to_iomem(&iomem, 16 + 8, &(lpol_offset as u32).to_le_bytes())?; |
106 | 97 |
|
107 | | - memcpy_to_iomem(&iomem, &dev, 32, b"IPIS")?; |
108 | | - memcpy_to_iomem(&iomem, &dev, 32 + 4, &(ibot_size as u32).to_le_bytes())?; |
109 | | - memcpy_to_iomem(&iomem, &dev, 32 + 8, &(ibot_offset as u32).to_le_bytes())?; |
| 98 | + memcpy_to_iomem(&iomem, 32, b"IPIS")?; |
| 99 | + memcpy_to_iomem(&iomem, 32 + 4, &(ibot_size as u32).to_le_bytes())?; |
| 100 | + memcpy_to_iomem(&iomem, 32 + 8, &(ibot_offset as u32).to_le_bytes())?; |
110 | 101 |
|
111 | | - memcpy_to_iomem(&iomem, &dev, 48, b"llun")?; |
| 102 | + memcpy_to_iomem(&iomem, 48, b"llun")?; |
112 | 103 | Ok(iomem) |
113 | 104 | } |
114 | 105 |
|
@@ -207,7 +198,7 @@ impl SepData { |
207 | 198 | }, |
208 | 199 | false, |
209 | 200 | )?; |
210 | | - let shm_addr = self.shmem.dma_handle >> IOVA_SHIFT; |
| 201 | + let shm_addr = self.shmem.dma_handle() >> IOVA_SHIFT; |
211 | 202 | mbox.send( |
212 | 203 | Message { |
213 | 204 | msg0: EP_SHMEM | (MSG_SET_SHMEM << MSG_TYPE_SHIFT) | (shm_addr << MSG_DATA_SHIFT), |
|
0 commit comments