Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/blackfin/mm/maccess.c
10817 views
1
/*
2
* safe read and write memory routines callable while atomic
3
*
4
* Copyright 2005-2008 Analog Devices Inc.
5
*
6
* Licensed under the GPL-2 or later.
7
*/
8
9
#include <linux/uaccess.h>
10
#include <asm/dma.h>
11
12
static int validate_memory_access_address(unsigned long addr, int size)
13
{
14
if (size < 0 || addr == 0)
15
return -EFAULT;
16
return bfin_mem_access_type(addr, size);
17
}
18
19
long probe_kernel_read(void *dst, const void *src, size_t size)
20
{
21
unsigned long lsrc = (unsigned long)src;
22
int mem_type;
23
24
mem_type = validate_memory_access_address(lsrc, size);
25
if (mem_type < 0)
26
return mem_type;
27
28
if (lsrc >= SYSMMR_BASE) {
29
if (size == 2 && lsrc % 2 == 0) {
30
u16 mmr = bfin_read16(src);
31
memcpy(dst, &mmr, sizeof(mmr));
32
return 0;
33
} else if (size == 4 && lsrc % 4 == 0) {
34
u32 mmr = bfin_read32(src);
35
memcpy(dst, &mmr, sizeof(mmr));
36
return 0;
37
}
38
} else {
39
switch (mem_type) {
40
case BFIN_MEM_ACCESS_CORE:
41
case BFIN_MEM_ACCESS_CORE_ONLY:
42
return __probe_kernel_read(dst, src, size);
43
/* XXX: should support IDMA here with SMP */
44
case BFIN_MEM_ACCESS_DMA:
45
if (dma_memcpy(dst, src, size))
46
return 0;
47
break;
48
case BFIN_MEM_ACCESS_ITEST:
49
if (isram_memcpy(dst, src, size))
50
return 0;
51
break;
52
}
53
}
54
55
return -EFAULT;
56
}
57
58
long probe_kernel_write(void *dst, const void *src, size_t size)
59
{
60
unsigned long ldst = (unsigned long)dst;
61
int mem_type;
62
63
mem_type = validate_memory_access_address(ldst, size);
64
if (mem_type < 0)
65
return mem_type;
66
67
if (ldst >= SYSMMR_BASE) {
68
if (size == 2 && ldst % 2 == 0) {
69
u16 mmr;
70
memcpy(&mmr, src, sizeof(mmr));
71
bfin_write16(dst, mmr);
72
return 0;
73
} else if (size == 4 && ldst % 4 == 0) {
74
u32 mmr;
75
memcpy(&mmr, src, sizeof(mmr));
76
bfin_write32(dst, mmr);
77
return 0;
78
}
79
} else {
80
switch (mem_type) {
81
case BFIN_MEM_ACCESS_CORE:
82
case BFIN_MEM_ACCESS_CORE_ONLY:
83
return __probe_kernel_write(dst, src, size);
84
/* XXX: should support IDMA here with SMP */
85
case BFIN_MEM_ACCESS_DMA:
86
if (dma_memcpy(dst, src, size))
87
return 0;
88
break;
89
case BFIN_MEM_ACCESS_ITEST:
90
if (isram_memcpy(dst, src, size))
91
return 0;
92
break;
93
}
94
}
95
96
return -EFAULT;
97
}
98
99