现在的位置: 首页 > 综合 > 正文

Solaris Source Insight: PCI bus driver moduls – npe Part 3

2013年07月06日 ⁄ 综合 ⁄ 共 6544字 ⁄ 字号 评论关闭

Wed Nov 11 13:41:56 CST
2009

 

driver operation

Driver operation is defined for leaf device drivers or bus nexus
drivers supporting
direct user process access (open/close/etc).
Driver operation for npe module is very simple.

 

[i86pc/io/pciex/npe.c]

120 struct cb_ops npe_cb_ops = {

121 |_______npe_open,|______|_______|_______/* open
*/

122 |_______npe_close,|_____|_______|_______/* close
*/

123 |_______nodev,|_|_______|_______|_______/*
strategy */

124 |_______nodev,|_|_______|_______|_______/* print
*/

125 |_______nodev,|_|_______|_______|_______/* dump
*/

126 |_______nodev,|_|_______|_______|_______/* read
*/

127 |_______nodev,|_|_______|_______|_______/* write
*/

128 |_______npe_ioctl,|_____|_______|_______/* ioctl
*/

129 |_______nodev,|_|_______|_______|_______/*
devmap */

130 |_______nodev,|_|_______|_______|_______/* mmap
*/

131 |_______nodev,|_|_______|_______|_______/*
segmap */

132 |_______nochpoll,|______|_______|_______/* poll
*/

133 |_______pcie_prop_op,|__|_______|_______/*
cb_prop_op */

134 |_______NULL,|__|_______|_______|_______/*
streamtab */

135 |_______D_NEW | D_MP | D_HOTPLUG,|______/*
Driver compatibility flag */

136 |_______CB_REV,||_______|_______|_______/* rev
*/

137 |_______nodev,|_|_______|_______|_______/* int
(*cb_aread)() */

138 |_______nodev|__|_______|_______|_______/* int
(*cb_awrite)() */

139 };

 

It defines a character driver interface. User level
applications can open/close the corresponding device file and issue
some ioctl command again it. In npe's open() and close() functions,
locks and state machine are used to serialize the controls. Two types
of ioctl controls are supported by now, one is for pci tool, which is
a common interface for user level applications to read/write pci
configure spaces, bind the interrupt and so on (we will come back to
the implementation later); another is for common device control,
which is routed to pcie_ioclt() for further action.

Bus operations

Npe is a nexus bus driver module, so the its sole is the bus
operations.

 

[i86pc/io/pciex/npe.c]

83 struct bus_ops npe_bus_ops = {

84 |_______BUSO_REV,

85 |_______npe_bus_map,

86 |_______NULL,

87 |_______NULL,

88 |_______NULL,

89 |_______i_ddi_map_fault,

90 |_______ddi_dma_map,

91 |_______ddi_dma_allochdl,

92 |_______ddi_dma_freehdl,

93 |_______ddi_dma_bindhdl,

94 |_______ddi_dma_unbindhdl,

95 |_______ddi_dma_flush,

96 |_______ddi_dma_win,

97 |_______ddi_dma_mctl,

98 |_______npe_ctlops,

99 |_______ddi_bus_prop_op,

100 |_______0,|_____|_______|_______/*
(*bus_get_eventcookie)();|___*/

101 |_______0,|_____|_______|_______/*
(*bus_add_eventcall)();|_____*/

102 |_______0,|_____|_______|_______/*
(*bus_remove_eventcall)();|__*/

103 |_______0,|_____|_______|_______/*
(*bus_post_event)();||_______*/

104 |_______0,|_____|_______|_______/*
(*bus_intr_ctl)(); */

105 |_______0,|_____|_______|_______/*
(*bus_config)(); */

106 |_______0,|_____|_______|_______/*
(*bus_unconfig)(); */

107 |_______npe_fm_init,|___|_______/*
(*bus_fm_init)(); */

108 |_______NULL,|__|_______|_______/*
(*bus_fm_fini)(); */

109 |_______NULL,|__|_______|_______/*
(*bus_fm_access_enter)(); */

110 |_______NULL,|__|_______|_______/*
(*bus_fm_access_exit)(); */

111 |_______NULL,|__|_______|_______/*
(*bus_power)(); */

112 |_______npe_intr_ops,|__|_______/*
(*bus_intr_op)(); */

113 |_______pcie_hp_common_ops|_____/*
(*bus_hp_op)(); */

114 };

 

The definition of “struct bus_ops” is in
common/sys/devops.h. Not all entries are valid for a specific bus
operation version. The comments along with the structure definition
is enough for understanding.

 

[common/sys/devops.h]

118 /*

119 * bus_ops:|____bus nexus drivers only.

120 *

121 * These functions are used to implement the Sun
DDI functions

122 * described elsewhere.

123 *

124 * Only nexus drivers support these entry
points.

125 *

126 * The following bus nexus functions are provided
in the bus nexus

127 * driver operations structure. Note that all
functions take both

128 * their dip and the requesters dip except for
the child functions since

129 * they will be called from outside the ddi.

130 *

131 *|_____bus_map||_______|_______-
Map/unmap/control IU -> device mappings.

132 *|_____bus_get_intrspec|_______- get interrupt
specification by number

133 *|_____bus_add_intrspec|_______- add interrupt
specification, return cookie

134 *|_____bus_remove_intrspec|____- remove
interrupt specification

135 *|_____bus_map_fault|__|_______- bus fault
handler

136 *|_____bus_dma_map|____|_______- setup dma
mapping

137 *|_____bus_dma_mapctl|_|_______- control (and
free) dma mapping

138 *|_____bus_ctl||_______|_______- generic
control operations

139 *|_____bus_prop_op|____|________ request for
property

140 */

  • bus_map()

We have looked at
npe_bus_map() when we tried to find the answer for how PCI leaf
drviers access the configure space. The address spaces for a device
were encoded in “reg” and “assigned-addresses” properties.
Below comments describe the decoding logic.

 

[common/sys/pci.h]

1100 /*

1101 * This structure
represents one entry of the 1275 "reg" property and

1102 *
"assigned-addresses" property for a PCI node. For the
"reg" property, it

1103 * may be one of an
arbitrary length array for devices with multiple address

1104 * windows. For the
"assigned-addresses" property, it denotes an assigned

1105 * physical address
on the PCI bus. It may be one entry of the six entries

1106 * for devices with
multiple base registers.

1107 *

1108 * The physical
address format is:

1109 *

1110 * Bit#:
33222222 22221111 11111100 00000000

1111 *
10987654 32109876 54321098 76543210

1112 *

1113 * pci_phys_hi cell:
npt000ss bbbbbbbb dddddfff rrrrrrrr

1114 * pci_phys_mid
cell: hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh

1115 * pci_phys_low
cell: llllllll llllllll llllllll llllllll

1116 *

1117 * n is 0
if the address is relocatable, 1 otherwise

1118 * p is 1
if the addressable region is "prefetchable", 0 otherwise

1119 * t is 1
if the address is aliased (for non-relocatable I/O), below

1120 *|_____ 1MB
(for mem), or below 64 KB (for relocatable I/O).

1121 * ss is the
type code, denoting which address space

1122 * bbbbbbbb is the
8-bit bus number

1123 * ddddd is the
5-bit device number

1124 * fff is the
3-bit function number

1125 * rrrrrrrr is the
8-bit register number

1126 *|_____ should
be zero for non-relocatable, when ss is 01, or 10

1127 * hh...hhh is the
32-bit unsigned number

1128 * ll...lll is the
32-bit unsigned number

1129 *

1130 * The physical size
format is:

1131 *

1132 * pci_size_hi cell:
hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh

1133 * pci_size_low
cell: llllllll llllllll llllllll llllllll

1134 *

1135 * hh...hhh is the
32-bit unsigned number

1136 * ll...lll is the
32-bit unsigned number

1137 */

1138 struct pci_phys_spec
{

1139 |_______uint_t
pci_phys_hi;|____|_______/* child's address, hi word */

1140 |_______uint_t
pci_phys_mid;|___|_______/* child's address, middle word */

1141 |_______uint_t
pci_phys_low;|___|_______/* child's address, low word */

1142 |_______uint_t
pci_size_hi;|____|_______/* high word of size field */

1143 |_______uint_t
pci_size_low;|___|_______/* low word of size field */

1144 };

1145

1146 typedef struct
pci_phys_spec pci_regspec_t;

 

 

The actual map operation
is passed to npe's parent (rootnex). However, pci system has
different “reg” and “assigned-addresses” encoding logic.
Hence, in this bus map function, most part is to convert the data
from “pci_regspec_t” to “struct regspec” according to the map
type and the encoding logic.

  • bus_ctl()

 

To be continued …

抱歉!评论已关闭.