soc/intel/alderlake: Add ADL-P 4+4 with 28W TDP
[coreboot.git] / src / commonlib / storage / bouncebuf.c
blob9edf41aed89c7393b7b441ec6436ef4a72360507
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * Generic bounce buffer implementation
4 */
6 #include <arch/cache.h>
7 #include "bouncebuf.h"
8 #include "storage.h"
9 #include <string.h>
10 #include <commonlib/stdlib.h>
12 static int addr_aligned(struct bounce_buffer *state)
14 const uint32_t align_mask = ARCH_DMA_MINALIGN - 1;
16 // Check if start is aligned
17 if ((uintptr_t)state->user_buffer & align_mask) {
18 sdhc_debug("Unaligned buffer address %p\n", state->user_buffer);
19 return 0;
22 // Check if length is aligned
23 if (state->len != state->len_aligned) {
24 sdhc_debug("Unaligned buffer length %zd\n", state->len);
25 return 0;
28 // Aligned
29 return 1;
32 int bounce_buffer_start(struct bounce_buffer *state, void *data,
33 size_t len, unsigned int flags)
35 state->user_buffer = data;
36 state->bounce_buffer = data;
37 state->len = len;
38 state->len_aligned = ROUND(len, ARCH_DMA_MINALIGN);
39 state->flags = flags;
41 if (!addr_aligned(state)) {
42 state->bounce_buffer = memalign(ARCH_DMA_MINALIGN,
43 state->len_aligned);
44 if (!state->bounce_buffer)
45 return -1;
47 if (state->flags & GEN_BB_READ)
48 memcpy(state->bounce_buffer, state->user_buffer,
49 state->len);
53 * Flush data to RAM so DMA reads can pick it up,
54 * and any CPU writebacks don't race with DMA writes
56 dcache_clean_invalidate_by_mva(state->bounce_buffer,
57 state->len_aligned);
58 return 0;
61 int bounce_buffer_stop(struct bounce_buffer *state)
63 if (state->flags & GEN_BB_WRITE) {
64 // Invalidate cache so that CPU can see any newly DMA'd data
65 dcache_invalidate_by_mva(state->bounce_buffer,
66 state->len_aligned);
69 if (state->bounce_buffer == state->user_buffer)
70 return 0;
72 if (state->flags & GEN_BB_WRITE)
73 memcpy(state->user_buffer, state->bounce_buffer, state->len);
75 free(state->bounce_buffer);
77 return 0;