Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
Software
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Dmytro Levit
Software
Commits
c07a2d68
Commit
c07a2d68
authored
6 years ago
by
Patrick Robbe
Browse files
Options
Downloads
Patches
Plain Diff
Add driver files
parent
ab799193
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
Driver/pcie40_driver/main_emu.c
+226
-0
226 additions, 0 deletions
Driver/pcie40_driver/main_emu.c
with
226 additions
and
0 deletions
Driver/pcie40_driver/main_emu.c
0 → 100644
+
226
−
0
View file @
c07a2d68
//ug`pcie40_driver_emu.description`
// ``lhcb_pcie40_emu.ko`` is a driver emulating the PCIe40 data acquisition card.
#define P40_FMT "P40emu:%s(): "
#define PCIE40_EMU
#include
"common.h"
#include
<linux/init.h>
#include
<linux/module.h>
#include
<linux/moduleparam.h>
#include
<linux/stat.h>
#include
<linux/vmalloc.h>
//ug`pcie40_driver_emu.synopsis`
// modprobe *lhcb_pcie40_emu* [ mainmibs=_M_ ] [ metamibs=_M_ ] [ baseid=_I_ ] [ numboards=_N_ ] [ mpf=_M_ ]
static
LIST_HEAD
(
pcie40_emu_inst_list
);
//ug`pcie40_driver_emu.options`baseid *baseid* = _I_::
// First interface ID for emulated boards (0 by default, increase to avoid conflicts with real boards already detected in the machine).
int
baseid
=
0
;
module_param
(
baseid
,
int
,
S_IRUSR
|
S_IRGRP
|
S_IROTH
);
MODULE_PARM_DESC
(
baseid
,
"First interface ID for emulated boards"
);
//ug`pcie40_driver_emu.options`numboards *numboards* = _N_::
// Number of PCIe40 boards to emulate (1 by default). Two DAQ interfaces will be instantiated for each emulated board.
int
numboards
=
1
;
module_param
(
numboards
,
int
,
S_IRUSR
|
S_IRGRP
|
S_IROTH
);
MODULE_PARM_DESC
(
numboards
,
"Number of PCIe40 boards to emulate"
);
//ug`pcie40_driver_emu.options`mpf *mpf* = _M_::
// Packing factor for metadata blocks (10000 by default).
int
mpf
=
10000
;
module_param
(
mpf
,
int
,
S_IRUSR
|
S_IRGRP
|
S_IROTH
);
MODULE_PARM_DESC
(
mpf
,
"Packing factor for metadata blocks"
);
int
pcie40_ecs_init
(
void
);
void
pcie40_ecs_exit
(
void
);
int
pcie40_ecs_emu_probe
(
struct
pcie40_state
*
common
);
void
pcie40_ecs_emu_remove
(
struct
pcie40_state
*
common
);
int
pcie40_daq_init
(
void
);
void
pcie40_daq_exit
(
void
);
int
pcie40_daq_emu_probe
(
struct
pcie40_state
*
common
);
void
pcie40_daq_emu_remove
(
struct
pcie40_state
*
common
);
static
int
pcie40_emu_probe
(
int
link_id
)
{
int
rc
=
0
;
struct
pcie40_state
*
state
=
NULL
,
*
li
;
printk
(
P40_DIAG
"creating emulated PCIe40 interface (link %d)"
,
P40_PARM
,
link_id
);
state
=
kzalloc
(
sizeof
(
struct
pcie40_state
),
GFP_KERNEL
);
if
(
IS_ERR
(
state
))
{
printk
(
P40_ERR
"kzalloc()
\n
"
,
P40_PARM
);
rc
=
PTR_ERR
(
state
);
goto
err_kzalloc
;
}
printk
(
P40_DIAG
"state = 0x%p
\n
"
,
P40_PARM
,
state
);
INIT_LIST_HEAD
(
&
state
->
list
);
printk
(
P40_INFO
"initializing BARs
\n
"
,
P40_PARM
);
if
(
link_id
==
0
)
{
state
->
bar_start
[
0
]
=
0
;
state
->
bar_size
[
0
]
=
32
*
1024
*
1024
;
}
state
->
bar_start
[
1
]
=
0
;
state
->
bar_size
[
1
]
=
256
*
1024
;
if
(
link_id
==
0
)
{
state
->
bar_start
[
2
]
=
0
;
state
->
bar_size
[
2
]
=
32
*
1024
*
1024
;
}
//TODO: print BAR information
if
(
state
->
bar_size
[
0
])
{
printk
(
P40_INFO
"allocating fake BAR0 (%lu bytes)
\n
"
,
P40_PARM
,
state
->
bar_size
[
0
]);
state
->
bar0_regs
=
vzalloc
(
state
->
bar_size
[
0
]);
if
(
state
->
bar0_regs
==
NULL
)
{
rc
=
-
1
;
goto
err_bar0_alloc
;
}
}
if
(
state
->
bar_size
[
1
])
{
printk
(
P40_INFO
"allocating fake BAR1 (%lu bytes)
\n
"
,
P40_PARM
,
state
->
bar_size
[
1
]);
state
->
bar1_regs
=
vzalloc
(
state
->
bar_size
[
1
]);
if
(
state
->
bar1_regs
==
NULL
)
{
rc
=
-
1
;
goto
err_bar1_alloc
;
}
}
if
(
state
->
bar_size
[
2
])
{
printk
(
P40_INFO
"allocating fake BAR2 (%lu bytes)
\n
"
,
P40_PARM
,
state
->
bar_size
[
2
]);
state
->
bar2_regs
=
vzalloc
(
state
->
bar_size
[
2
]);
if
(
state
->
bar2_regs
==
NULL
)
{
rc
=
-
1
;
goto
err_bar2_alloc
;
}
}
//Fill fake BAR1 with plausible values
pcie40_write32_ctrl
(
state
,
P40_DMA_CTRL_OFF_RWTEST
,
0xCE40FACC
);
pcie40_write32_ctrl
(
state
,
P40_DMA_CTRL_OFF_REGMAP
,
P40_DMA_REGMAP_VERSION
);
pcie40_write32_ctrl
(
state
,
P40_DMA_CTRL_OFF_VERSION
,
0x0400FACC
);
pcie40_write32_ctrl
(
state
,
P40_DMA_CTRL_OFF_LINK_ID
,
link_id
);
pcie40_write32_ctrl
(
state
,
P40_DMA_CTRL_OFF_MAIN_GEN_FIXED
,
0x6243484C
);
pcie40_write32_ctrl
(
state
,
P40_DMA_CTRL_OFF_META_PACKING
,
13
);
pcie40_write32_ctrl
(
state
,
P40_DMA_CTRL_OFF_PCIE_GEN
,
3
);
state
->
link_id
=
link_id
;
if
(
state
->
link_id
==
0
)
{
state
->
dev_id
=
baseid
;
// This device will get an even id
}
else
{
state
->
dev_id
=
baseid
+
1
;
// This device will get an odd id
}
list_for_each_entry
(
li
,
&
pcie40_emu_inst_list
,
list
)
{
if
((
state
->
link_id
==
0
&&
li
->
dev_id
%
2
==
0
)
||
(
state
->
link_id
!=
0
&&
li
->
dev_id
%
2
!=
0
))
{
if
(
li
->
dev_id
>=
state
->
dev_id
)
{
state
->
dev_id
=
li
->
dev_id
+
2
;
}
}
}
list_add
(
&
state
->
list
,
&
pcie40_emu_inst_list
);
pcie40_write32_ctrl
(
state
,
P40_DMA_CTRL_OFF_CHIP_ID_HI
,
0x00CE40
);
pcie40_write32_ctrl
(
state
,
P40_DMA_CTRL_OFF_CHIP_ID_LO
,
state
->
dev_id
/
2
+
1
);
rc
|=
pcie40_ecs_emu_probe
(
state
);
rc
|=
pcie40_daq_emu_probe
(
state
);
return
rc
;
//if (state->bar_size[1]) {
// kfree(state->bar1_regs);
// state->bar1_regs = NULL;
//}
err_bar2_alloc:
if
(
state
->
bar_size
[
1
])
{
vfree
(
state
->
bar1_regs
);
state
->
bar1_regs
=
NULL
;
}
err_bar1_alloc:
if
(
state
->
bar_size
[
0
])
{
vfree
(
state
->
bar0_regs
);
state
->
bar0_regs
=
NULL
;
}
err_bar0_alloc:
kfree
(
state
);
err_kzalloc:
return
rc
;
}
static
void
pcie40_emu_remove
(
struct
pcie40_state
*
state
)
{
list_del
(
&
state
->
list
);
pcie40_ecs_emu_remove
(
state
);
pcie40_daq_emu_remove
(
state
);
if
(
state
->
bar_size
[
0
])
{
vfree
(
state
->
bar0_regs
);
state
->
bar0_regs
=
NULL
;
}
if
(
state
->
bar_size
[
1
])
{
vfree
(
state
->
bar1_regs
);
state
->
bar1_regs
=
NULL
;
}
if
(
state
->
bar_size
[
2
])
{
vfree
(
state
->
bar2_regs
);
state
->
bar2_regs
=
NULL
;
}
kfree
(
state
);
}
static
int
__init
pcie40_emu_init
(
void
)
{
int
rc
=
0
;
int
i
;
baseid
&=
~
1
;
// the base Device ID must be even
rc
=
pcie40_ecs_init
();
if
(
rc
<
0
)
return
rc
;
rc
=
pcie40_daq_init
();
if
(
rc
<
0
)
return
rc
;
for
(
i
=
0
;
i
<
numboards
;
++
i
)
{
pcie40_emu_probe
(
0
);
pcie40_emu_probe
(
1
);
}
return
rc
;
}
static
void
__exit
pcie40_emu_exit
(
void
)
{
struct
pcie40_state
*
li
,
*
ln
;
list_for_each_entry_safe
(
li
,
ln
,
&
pcie40_emu_inst_list
,
list
)
{
pcie40_emu_remove
(
li
);
}
pcie40_daq_exit
();
pcie40_ecs_exit
();
}
module_init
(
pcie40_emu_init
);
module_exit
(
pcie40_emu_exit
);
MODULE_VERSION
(
DAQ40_VER_REL
);
MODULE_LICENSE
(
"GPL"
);
//TODO: MODULE_AUTHOR
//TODO: MODULE_DESCRIPTION
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment