Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FPGA Configuration Space
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
FPGA Configuration Space
Commits
7019dabd
Commit
7019dabd
authored
Apr 27, 2016
by
Wesley W. Terpstra
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wishbone: support config-space-based MSI claiming
parent
ce4f5155
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
77 additions
and
5 deletions
+77
-5
pcie_wb.c
pcie-wb/pcie_wb.c
+1
-0
spec_wb.c
pcie-wb/spec_wb.c
+1
-0
wishbone.c
pcie-wb/wishbone.c
+62
-4
wishbone.h
pcie-wb/wishbone.h
+12
-1
vme_wb_external.c
vme-wb/vme_wb_external.c
+1
-0
No files found.
pcie-wb/pcie_wb.c
View file @
7019dabd
...
...
@@ -345,6 +345,7 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *id)
dev
->
msi
=
1
;
dev
->
wb
.
wops
=
&
wb_ops
;
dev
->
wb
.
parent
=
&
pdev
->
dev
;
dev
->
wb
.
mask
=
0xffff
;
mutex_init
(
&
dev
->
mutex
);
dev
->
window_offset
=
0
;
dev
->
low_addr
=
0
;
...
...
pcie-wb/spec_wb.c
View file @
7019dabd
...
...
@@ -268,6 +268,7 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *id)
dev
->
pci_dev
=
pdev
;
dev
->
wb
.
wops
=
&
wb_ops
;
dev
->
wb
.
parent
=
&
pdev
->
dev
;
dev
->
wb
.
mask
=
0
;
// not MSI capable
dev
->
msi
=
1
;
mutex_init
(
&
dev
->
mutex
);
dev
->
window_offset
=
0
;
...
...
pcie-wb/wishbone.c
View file @
7019dabd
...
...
@@ -19,7 +19,7 @@
#include "wishbone.h"
/* Module parameters */
static
unsigned
int
max_devices
=
WISHONE_MAX_DEVICES
;
static
unsigned
int
max_devices
=
WISH
B
ONE_MAX_DEVICES
;
/* Module globals */
static
LIST_HEAD
(
wishbone_list
);
/* Sorted by ascending minor number */
...
...
@@ -109,6 +109,49 @@ static inline void eb_from_cpu(unsigned char* x, wb_data_t dat)
}
}
static
void
claim_msi
(
struct
etherbone_master_context
*
context
)
{
unsigned
i
;
struct
wishbone
*
wb
=
context
->
wishbone
;
if
(
context
->
msi_index
!=
-
1
)
return
;
mutex_lock
(
&
wb
->
mutex
);
for
(
i
=
0
;
i
<
WISHBONE_MAX_MSI_OPEN
;
++
i
)
{
if
(
!
wb
->
msi_map
[
i
])
{
context
->
msi_index
=
i
;
wb
->
msi_map
[
i
]
=
context
;
break
;
}
}
mutex_unlock
(
&
wb
->
mutex
);
}
static
wb_data_t
handle_read_cfg
(
struct
etherbone_master_context
*
context
,
wb_addr_t
addr
)
{
struct
wishbone
*
wb
=
context
->
wishbone
;
wb_data_t
wide
=
(
wb
->
mask
/
WISHBONE_MAX_MSI_OPEN
)
+
1
;
switch
(
addr
)
{
case
32
:
return
0
;
// request high
case
36
:
return
0
;
// request low
case
40
:
return
0
;
// granted high
case
44
:
return
context
->
msi_index
!=
-
1
;
// granted low
case
48
:
return
0
;
// low high
case
52
:
return
wide
*
(
context
->
msi_index
+
0
)
-
0
;
// low low
case
56
:
return
0
;
// high high
case
60
:
return
wide
*
(
context
->
msi_index
+
1
)
-
1
;
// high low
default:
return
wb
->
wops
->
read_cfg
(
wb
,
addr
);
}
}
static
void
handle_write_cfg
(
struct
etherbone_master_context
*
context
,
wb_addr_t
addr
,
wb_data_t
data
)
{
switch
(
addr
)
{
case
36
:
if
(
data
==
1
)
claim_msi
(
context
);
break
;
default:
break
;
}
}
static
void
etherbone_master_process
(
struct
etherbone_master_context
*
context
)
{
struct
wishbone
*
wb
;
...
...
@@ -176,6 +219,7 @@ static void etherbone_master_process(struct etherbone_master_context* context)
if
(
wca
)
{
for
(
j
=
wcount
;
j
>
0
;
--
j
)
{
handle_write_cfg
(
context
,
base_address
,
eb_to_cpu
(
buf
+
i
));
eb_from_cpu
(
buf
+
i
,
0
);
i
=
RING_INDEX
(
i
+
sizeof
(
wb_data_t
));
}
...
...
@@ -205,7 +249,7 @@ static void etherbone_master_process(struct etherbone_master_context* context)
if
(
rca
)
{
for
(
j
=
rcount
;
j
>
0
;
--
j
)
{
eb_from_cpu
(
buf
+
i
,
wops
->
read_cfg
(
wb
,
eb_to_cpu
(
buf
+
i
)));
eb_from_cpu
(
buf
+
i
,
handle_read_cfg
(
context
,
eb_to_cpu
(
buf
+
i
)));
i
=
RING_INDEX
(
i
+
sizeof
(
wb_data_t
));
}
}
else
{
...
...
@@ -242,6 +286,8 @@ static int char_master_open(struct inode *inode, struct file *filep)
context
->
sent
=
0
;
context
->
processed
=
0
;
context
->
received
=
0
;
context
->
msi_unread
=
0
;
context
->
msi_index
=
-
1
;
filep
->
private_data
=
context
;
...
...
@@ -251,10 +297,18 @@ static int char_master_open(struct inode *inode, struct file *filep)
static
int
char_master_release
(
struct
inode
*
inode
,
struct
file
*
filep
)
{
struct
etherbone_master_context
*
context
=
filep
->
private_data
;
struct
wishbone
*
wb
=
context
->
wishbone
;
/* Did the bad user forget to drop the cycle line? */
if
(
context
->
state
==
cycle
)
{
context
->
wishbone
->
wops
->
cycle
(
context
->
wishbone
,
0
);
wb
->
wops
->
cycle
(
wb
,
0
);
}
/* Unhook any MSI access */
if
(
context
->
msi_index
!=
-
1
)
{
mutex_lock
(
&
wb
->
mutex
);
wb
->
msi_map
[
context
->
msi_index
]
=
0
;
mutex_unlock
(
&
wb
->
mutex
);
}
kfree
(
context
);
...
...
@@ -381,9 +435,13 @@ static const struct file_operations etherbone_master_fops = {
int
wishbone_register
(
struct
wishbone
*
wb
)
{
struct
list_head
*
list_pos
;
unsigned
int
devoff
;
unsigned
int
devoff
,
i
;
INIT_LIST_HEAD
(
&
wb
->
list
);
mutex_init
(
&
wb
->
mutex
);
for
(
i
=
0
;
i
<
WISHBONE_MAX_MSI_OPEN
;
++
i
)
{
wb
->
msi_map
[
i
]
=
0
;
}
mutex_lock
(
&
wishbone_mutex
);
...
...
pcie-wb/wishbone.h
View file @
7019dabd
...
...
@@ -6,7 +6,8 @@
#include <linux/cdev.h>
#define WISHBONE_VERSION "0.1"
#define WISHONE_MAX_DEVICES 32
/* default only */
#define WISHBONE_MAX_DEVICES 32
/* default only */
#define WISHBONE_MAX_MSI_OPEN 16
/* fixed */
#define ETHERBONE_BCA 0x80
#define ETHERBONE_RCA 0x40
...
...
@@ -55,12 +56,17 @@ struct wishbone
{
const
struct
wishbone_operations
*
wops
;
struct
device
*
parent
;
wb_addr_t
mask
;
/* internal (guarded by global mutex--register/unregister): */
struct
list_head
list
;
dev_t
master_dev
;
struct
cdev
master_cdev
;
struct
device
*
master_device
;
/* internal (EB-MSI mapping for this hardware) */
struct
mutex
mutex
;
struct
etherbone_master_context
*
msi_map
[
WISHBONE_MAX_MSI_OPEN
];
};
#define RING_SIZE 8192
...
...
@@ -79,6 +85,11 @@ struct etherbone_master_context
unsigned
int
sent
,
processed
,
received
;
/* sent <= processed <= received */
unsigned
char
buf
[
RING_SIZE
];
/* Ring buffer */
/* MSI record data */
unsigned
char
msi
[
sizeof
(
wb_data_t
)
*
6
];
int
msi_unread
;
int
msi_index
;
};
#define RING_READ_LEN(ctx) RING_POS((ctx)->processed - (ctx)->sent)
...
...
vme-wb/vme_wb_external.c
View file @
7019dabd
...
...
@@ -453,6 +453,7 @@ static int vme_probe(struct device *pdev, unsigned int ndev)
mutex_init
(
&
dev
->
mutex
);
dev
->
wb
.
wops
=
&
wb_ops
;
dev
->
wb
.
parent
=
pdev
;
dev
->
wb
.
mask
=
0xffff
;
dev
->
window_offset
=
0
;
/* Map CR/CSR space */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment