Skip to content

Commit

Permalink
vcsm: set cache config at run time
Browse files Browse the repository at this point in the history
* Will handle ARMv6/ARMv7 multi-platform builds

* With a partial revert of 702b94b to expose
  some dma APIs, we can use those in vcsm so multi-platform kernels will run
  the proper asm.

* Create defines for the cache function indices to make things more clear
  • Loading branch information
invisiblek committed Sep 21, 2017
1 parent 800eea6 commit c30003d
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 35 deletions.
21 changes: 21 additions & 0 deletions arch/arm/include/asm/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,21 @@
* DMA Cache Coherency
* ===================
*
* dma_inv_range(start, end)
*
* Invalidate (discard) the specified virtual address range.
* May not write back any entries. If 'start' or 'end'
* are not cache line aligned, those lines must be written
* back.
* - start - virtual start address
* - end - virtual end address
*
* dma_clean_range(start, end)
*
* Clean (write back) the specified virtual address range.
* - start - virtual start address
* - end - virtual end address
*
* dma_flush_range(start, end)
*
* Clean and invalidate the specified virtual address range.
Expand All @@ -115,6 +130,8 @@ struct cpu_cache_fns {
void (*dma_map_area)(const void *, size_t, int);
void (*dma_unmap_area)(const void *, size_t, int);

void (*dma_inv_range)(const void *, const void *);
void (*dma_clean_range)(const void *, const void *);
void (*dma_flush_range)(const void *, const void *);
};

Expand All @@ -140,6 +157,8 @@ extern struct cpu_cache_fns cpu_cache;
* is visible to DMA, or data written by DMA to system memory is
* visible to the CPU.
*/
#define dmac_inv_range cpu_cache.dma_inv_range
#define dmac_clean_range cpu_cache.dma_clean_range
#define dmac_flush_range cpu_cache.dma_flush_range

#else
Expand All @@ -159,6 +178,8 @@ extern void __cpuc_flush_dcache_area(void *, size_t);
* is visible to DMA, or data written by DMA to system memory is
* visible to the CPU.
*/
extern void dmac_inv_range(const void *, const void *);
extern void dmac_clean_range(const void *, const void *);
extern void dmac_flush_range(const void *, const void *);

#endif
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/mm/proc-macros.S
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,8 @@ ENTRY(\name\()_cache_fns)
.long \name\()_flush_kern_dcache_area
.long \name\()_dma_map_area
.long \name\()_dma_unmap_area
.long \name\()_dma_inv_range
.long \name\()_dma_clean_range
.long \name\()_dma_flush_range
.size \name\()_cache_fns, . - \name\()_cache_fns
.endm
Expand Down
3 changes: 3 additions & 0 deletions arch/arm/mm/proc-syms.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ EXPORT_SYMBOL(__cpuc_flush_user_all);
EXPORT_SYMBOL(__cpuc_flush_user_range);
EXPORT_SYMBOL(__cpuc_coherent_kern_range);
EXPORT_SYMBOL(__cpuc_flush_dcache_area);
EXPORT_SYMBOL(dmac_inv_range);
EXPORT_SYMBOL(dmac_clean_range);
EXPORT_SYMBOL(dmac_flush_range);
#else
EXPORT_SYMBOL(cpu_cache);
#endif
Expand Down
5 changes: 5 additions & 0 deletions drivers/char/broadcom/vc_sm/vc_sm_knl.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ enum vc_sm_lock_cache_mode {
VC_SM_LOCK_NON_CACHED,
};

/* Cache functions */
#define VCSM_CACHE_OP_INV 0x01
#define VCSM_CACHE_OP_FLUSH 0x02
#define VCSM_CACHE_OP_CLEAN 0x03

/* Allocate a shared memory handle and block. */
int vc_sm_alloc(struct vc_sm_alloc_t *alloc, int *handle);

Expand Down
56 changes: 21 additions & 35 deletions drivers/char/broadcom/vc_sm/vmcs_sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,34 +218,6 @@ static const char *const sm_cache_map_vector[] = {
};
#endif

typedef void cache_flush_op_fn(const void *, const void *);

#if defined(CONFIG_CPU_CACHE_V7)
extern cache_flush_op_fn v7_dma_inv_range;
extern cache_flush_op_fn v7_dma_clean_range;
extern cache_flush_op_fn v7_dma_flush_range;
static cache_flush_op_fn * const flushops[4] =
{
0,
v7_dma_inv_range,
v7_dma_clean_range,
v7_dma_flush_range,
};
#elif defined(CONFIG_CPU_CACHE_V6)
extern cache_flush_op_fn v6_dma_inv_range;
extern cache_flush_op_fn v6_dma_clean_range;
extern cache_flush_op_fn v6_dma_flush_range;
static cache_flush_op_fn * const flushops[4] =
{
0,
v6_dma_inv_range,
v6_dma_clean_range,
v6_dma_flush_range,
};
#else
#error Unknown cache config
#endif

/* ---- Private Function Prototypes -------------------------------------- */

/* ---- Private Functions ------------------------------------------------ */
Expand Down Expand Up @@ -2964,12 +2936,9 @@ static long vc_sm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
for (i = 0; i < sizeof(ioparam.s) / sizeof(*ioparam.s); i++) {
switch (ioparam.s[i].cmd) {
default:
case 0:
break; /* NOOP */
case 1: /* L1/L2 invalidate virtual range */
case 2: /* L1/L2 clean physical range */
case 3: /* L1/L2 clean+invalidate all */
case VCSM_CACHE_OP_INV: /* L1/L2 invalidate virtual range */
case VCSM_CACHE_OP_FLUSH: /* L1/L2 clean physical range */
case VCSM_CACHE_OP_CLEAN: /* L1/L2 clean+invalidate all */
/* Locate resource from GUID. */
resource =
vmcs_sm_acquire_resource(file_data, ioparam.s[i].handle);
Expand All @@ -2993,6 +2962,8 @@ static long vc_sm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
vmcs_sm_release_resource(resource, 0);

break;
default:
break; /* NOOP */
}
}
}
Expand Down Expand Up @@ -3029,7 +3000,22 @@ static long vc_sm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

for (i = 0; i < ioparam.op_count; i++) {
const struct vmcs_sm_ioctl_clean_invalid_block * const op = block + i;
cache_flush_op_fn * const op_fn = flushops[op->invalidate_mode & 3];
void (*op_fn)(const void *, const void *);

switch(op->invalidate_mode & 3) {
case VCSM_CACHE_OP_INV:
op_fn = dmac_inv_range;
break;
case VCSM_CACHE_OP_CLEAN:
op_fn = dmac_clean_range;
break;
case VCSM_CACHE_OP_FLUSH:
op_fn = dmac_flush_range;
break;
default:
op_fn = 0;
break;
}

if ((op->invalidate_mode & ~3) != 0) {
ret = -EINVAL;
Expand Down

0 comments on commit c30003d

Please sign in to comment.