Solaris Source Insight: PCI bus driver moduls - npe Part 2

Tue Nov 10 12:47:45 CST 2009

npe_attach()

Come back to the attach() function.

 

For resume attach, restore config_regs for each children devinfo node of npe. Otherwise, initialize all the npe related things.

 

  • allocate the state structure

 

[i86pc/io/pciex/npe.c]

302 |_______if (ddi_soft_state_zalloc(npe_statep, instance) == DDI_SUCCESS)

303 |_______|_______pcip = ddi_get_soft_state(npe_statep, instance);

304

305 |_______if (pcip == NULL)

306 |_______|_______return (DDI_FAILURE);

 

The state structure defined in pci_common.h.

 

[i86pc/io/pci/pci_common.h]

39 /* State structure. */

40 typedef struct pci_state {

41 |_______dev_info_t *pci_dip;

42 |_______int pci_fmcap;

43 |_______uint_t pci_soft_state;

44 |_______ddi_iblock_cookie_t pci_fm_ibc;

45 |_______kmutex_t pci_mutex;

46 |_______kmutex_t pci_peek_poke_mutex;

47 |_______kmutex_t pci_err_mutex;

48 } pci_state_t;

 

pci_dip and pci_soft_state are initialized immediately.

 

308 |_______pcip->pci_dip = devi;

309 |_______pcip->pci_soft_state = PCI_SOFT_STATE_CLOSED;

  • Initialize the pcie bus private date for root complex. PCIe Bus Private Data contains commonly used PCI/PCIe information and offsets to key registers. pcie_init_bus() is used for common pcie devices, while pcie_rc_init_bus() is designed for root complex. In pcie_rc_init_bus(), pcie bus private data struture is allocated and set to the hook pointer in devinfo structure.

 

[common/io/pciex/pcie.c]

711 void

712 pcie_rc_init_bus(dev_info_t *dip)

713 {

714 |_______pcie_bus_t *bus_p;

715

716 |_______bus_p = (pcie_bus_t *)kmem_zalloc(sizeof (pcie_bus_t), KM_SLEEP);

717 |_______bus_p->bus_dip = dip;

718 |_______bus_p->bus_dev_type = PCIE_PCIECAP_DEV_TYPE_RC_PSEUDO;

719 |_______bus_p->bus_hdr_type = PCI_HEADER_ONE;

720

721 |_______/* Fake that there are AER logs */

722 |_______bus_p->bus_aer_off = (uint16_t)-1;

723

724 |_______/* Needed only for handle lookup */

725 |_______bus_p->bus_fm_flags |= PF_FM_READY;

726

727 |_______ndi_set_bus_private(dip, B_FALSE, DEVI_PORT_TYPE_PCI, bus_p);

728 }

 

The device type is a pseudo root complex. This bridge only has down port (B_FALSE) and the bus type is defined as below. PCI_CLASS_BRIDGE is “Bridge Controller class” defined by PCI class codes specification. PCI_BRIDGE_PCI is sub-class code based on PCI_CLASS_BRIDGE. And, PCI_BRIDGE_PCI_IF_PCI2PCI is the program interface. It means that this bridge is a PCI-2-PCI bridge, not a subattractive decode bridge.

 

[common/sys/pcie_impl.h]

42 #define|DEVI_PORT_TYPE_PCI /

43 |_______((PCI_CLASS_BRIDGE << 16) | (PCI_BRIDGE_PCI << 8) | /

44 |_______PCI_BRIDGE_PCI_IF_PCI2PCI)

 

Bus private data is embedded in struct dev_info. Functions ndi_set_bus_private() and ndi_get_bus_private() are used to set and retrieve the bus private structure.

 

[common/sys/ddi_impldefs.h]

105 typedef struct devi_port {

106 |_______union {

107 |_______|_______struct {

108 |_______|_______|_______uint32_t type;

109 |_______|_______|_______uint32_t pad;

110 |_______|_______} port;

111 |_______|_______uint64_t type64;

112 |_______} info;

113 |_______void|___*priv_p;

114 } devi_port_t;

115

116 typedef struct devi_bus_priv {

117 |_______devi_port_t port_up;

118 |_______devi_port_t port_down;

119 } devi_bus_priv_t;

 

126 struct dev_info {

… …

253 |_______/* owned by bus framework */

254 |_______devi_bus_priv_t|devi_bus;|______|_______/* bus private data */

… …

 

  • Initialize a PCI-ex device with pcie_init()

  1.  
    1. Create a "devctl" minor node to support DEVCTL_DEVICE_* and DEVCTL_BUS_* ioctls to this bus.

    2. Call pcie_hp_init() to initialize pcie hot-plug framework. We will look into pci hotplug later.

    3. If ARI (Alternative Routing-ID Interpretation) is supported by this device and not enabled, enable it. Actually, this function will always returen failure and keep the ARI disabled. It isn't a suitable point to enable ARI.

  • Initialize pcitool framework with pcitool_init(). We will look into pcitool later.

  • Initialize pci FMA framework with ddi_fm_init() and register FMA handler. We will look into PCI FMA later.

  • Allocate and initialize fault data cache

  • Query the MCFG table using ACPI. If MCFG is found, setup the 'ecfg' property accordingly. Otherwise, set the values to the default values. Note, MCFG, PCI Express memory mapped configuration space base address Description Table, is not defined by ACPI sepc, but PCI Firmware Specification, Revision 3.0. Below is a description of MCFG in PCI Firmware Specification, R3.0.

 

The MCFG table is an ACPI table that is used to communicate the base addresses corresponding to the non-hot removable PCI Segment Groups range within a PCI Segment Group available to the operating system at boot. This is required for the PC-compatible systems.

The MCFG table is only used to communicate the base addresses corresponding to the PCI

Segment Groups available to the system at boot. This table directly refers to PCI Segment Groups defined in the system via the _SEG object in the ACPI name space for the applicable host bridge device. For systems containing only a single PCI Segment Group, the default PCI Segment Group number, namely, PCI Segment Group 0, is implied. In such a case, the default PCI Segment Group need not be represented in the ACPI Name Space (i.e., no _SEG method is required in such a hierarchy).

The size of the memory mapped configuration region is indicated by the start and end bus number fields in the Memory mapped Enhanced configuration space base address allocation structure.

 

The default “ecfg” property is set to:

 

[i86pc/io/pciex/npe_misc.c]

147 |_______/*

148 |_______ * If MCFG is not found or ecfga_base is not found in MCFG table,

149 |_______ * set the property to the default values.

150 |_______ */

151 |_______ecfginfo[0] = npe_default_ecfga_base;

152 |_______ecfginfo[1] = 0;|_______|_______/* segment 0 */

153 |_______ecfginfo[2] = 0;|_______|_______/* first bus 0 */

154 |_______ecfginfo[3] = 0xff;|____|_______/* last bus ff */

155 |_______(void) ndi_prop_update_int64_array(DDI_DEV_T_NONE, dip,

156 |_______ "ecfg", ecfginfo, 4);

 

Here, default base address for the enhanced configuration access mechanism is set to 0xE0000000.

 

[i86pc/io/pciex/npe_misc.c]

53 /*

54 * Default ecfga base address

55 */

56 int64_t npe_default_ecfga_base = 0xE0000000;

  • Everything seems to be ready, report this device.

 

[i86pc/io/pciex/npe.c]

332 |_______ddi_report_dev(devi);

Questions

  • Where does the start bus number stored? How to retrieve it?

I didn't find any place to retrieve and store the start bus number of a root complexin npe_attach(). The only place intented to save start bus number as far as I can see is in the “reg” property, which was created in create_root_bus_dip().

 

[intel/io/pci/pci_boot.c]

1470 |_______pci_regs[0] = pci_bus_res[bus].root_addr;

1471 |_______(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,

1472 |_______ "reg", (int *)pci_regs, 3);

 

Unfortunately, the first integer of “reg” property for root bus is not defined for start bus. So the following logic will not work for root bus devinfo node.

acpica_get_bdf

PCI_REG_BUS_G

PCI_REG_DEV_G

PCI_REG_FUNC_G

Let's put it here and try to answer it later.

npe_detach()

npe_detach() does the opposite operation again npe_attach().

 

 

To be continued ...

提供了一个基于51单片机的RFID门禁系统的完整资源文件,包括PCB图、原理图、论文以及源程序。该系统设计由单片机、RFID-RC522频射卡模块、LCD显示、灯控电路、蜂鸣器报警电路、存储模块和按键组成。系统支持通过密码和刷卡两种方式进行门禁控制,灯亮表示开门成功,蜂鸣器响表示开门失败。 资源内容 PCB图:包含系统的PCB设计图,方便用户进行硬件电路的制作和调试。 原理图:详细展示了系统的电路连接和模块布局,帮助用户理解系统的工作原理。 论文:提供了系统的详细设计思路、实现方法以及测试结果,适合学习和研究使用。 源程序:包含系统的全部源代码,用户可以根据需要进行修改和优化。 系统功能 刷卡开门:用户可以通过刷RFID卡进行门禁控制,系统会自动识别卡片并判断是否允许开门。 密码开门:用户可以通过输入预设密码进行门禁控制,系统会验证密码的正确性。 状态显示:系统通过LCD显示屏显示当前状态,如刷卡成功、密码错误等。 灯光提示:灯亮表示开门成功,灯灭表示开门失败或未操作。 蜂鸣器报警:当刷卡或密码输入错误时,蜂鸣器会发出报警声,提示用户操作失败。 适用人群 电子工程、自动化等相关专业的学生和研究人员。 对单片机和RFID技术感兴趣的爱好者。 需要开发类似门禁系统的工程师和开发者。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值