Solaris Source Insight: PCI system implementation - Part 2

本文介绍PCI总线资源管理中资源的存储结构及设备枚举过程。包括如何组织PCI层次结构、创建设备信息节点、设置属性值等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 Thu Oct 29 10:46:29 CST 2009

The bus resource enumerated in pci_setup_tree() are stored in pci_bus_res array.

common/sys/pci_impl.h
  82 /* pci bus resource maps */
  83 struct pci_bus_resource *pci_bus_res;
... ...
 93 struct pci_bus_resource {
 94 |_______struct memlist *io_avail;|______/* available free io res */
 95 |_______struct memlist *io_used;|_______/* used io res */
 96 |_______struct memlist *mem_avail;|_____/* available free mem res */
 97 |_______struct memlist *mem_used;|______/* used mem res */
 98 |_______struct memlist *pmem_avail; /* available free prefetchable mem res */
 99 |_______struct memlist *pmem_used; /* used prefetchable mem res */
100 |_______struct memlist *bus_avail;|_____/* available free bus res */
101 |_______|_______|_______/* bus_space_used not needed; can read from regs */
102 |_______dev_info_t *dip;|_______/* devinfo node */
103 |_______void *privdata;||_______/* private data for configuration */
104 |_______uchar_t par_bus;|_______/* parent bus number */
105 |_______uchar_t sub_bus;|_______/* highest bus number beyond this bridge */
106 |_______uchar_t root_addr;|_____/* legacy peer bus address assignment */
107 |_______uchar_t num_cbb;|_______/* # of CardBus Bridges on the bus */
108 |_______boolean_t io_reprogram;|/* need io reprog on this bus */
109 |_______boolean_t mem_reprogram;|_______/* need mem reprog on this bus */
110 |_______boolean_t subtractive;|_/* subtractive PPB */
111 |_______uint_t mem_size;|_______/* existing children required MEM space size */
112 |_______uint_t io_size;||_______/* existing children required I/O space size */
113 };

1. Create pci root bus in device tree
This logic is in create_root_bus_dip(uchar_t bus). Since we may have multiple IOH's on some platforms, there may be multiple root bus dev_info nodes under rootnex node. If the root bus does indeed have PCI-Ex in the path, the "device-type" property will be set to "pciex" and "compatible" set to "pciex_root_complex". Otherwise, only "device-type" is set to "pci".

To judge if root bus has PCI-Ex in the path, the common way is to check MCFG in ACPI tables. However in current code, it is hard-coded. That means the logic enumerates each devices under the root bus (exclude the sub-bus) and checks if any device has PCI_Ex capability in it's configure space.

2. Enumerate devices on bus 0 (exclude sub-buses)
This logic is implemented in enumerate_bus_devs().

intel/io/pci/pci_boot.c
1471 /*
1472  * For any fixed configuration (often compatability) pci devices
1473  * and those with their own expansion rom, create device nodes
1474  * to hold the already configured device details.
1475  */
1476 void
1477 enumerate_bus_devs(uchar_t bus, int config_op)

It is used in multiple cases. The "bus" parameter is the bus about to enumerate and "config_op" can be set to:

CONFIG_NEW:  configure the pci bus (called in pci_reprogram() path)
CONFIG_FIX:  fix the pci bus (called in add_pci_fixes() path)
CONFIG_INFO: enumerate the pci bus (called in pci_setup_tree() path)

During enumeration, for each function enumerated, process_devfunc() is called with "config_op" passed.

intel/io/pci/pci_boot.c
1825 static void
1826 process_devfunc(uchar_t bus, uchar_t dev, uchar_t func, uchar_t header,
1827     ushort_t vendorid, int config_op)
1828 {

We are interested at two aspects. i) how the pci hierarchy is organized? Especially how multiple IOH's are supported? ii) which properties are created for each kind of pci device node?

1) How multiple IOH's are support?

1904 |_______/* make sure parent bus dip has been created */
1905 |_______if (pci_bus_res[bus].dip == NULL)
1906 |_______|_______create_root_bus_dip(bus);

So if a bus doesn't start from a pci bridge, it should be a seperated root complex.

2) How the pci hierarchy information are stored during enumeration?

common/sys/pci_impl.h
 93 struct pci_bus_resource {
 94 |_______struct memlist *io_avail;|______/* available free io res */
 95 |_______struct memlist *io_used;|_______/* used io res */
 96 |_______struct memlist *mem_avail;|_____/* available free mem res */
 97 |_______struct memlist *mem_used;|______/* used mem res */
 98 |_______struct memlist *pmem_avail; /* available free prefetchable mem res */
 99 |_______struct memlist *pmem_used; /* used prefetchable mem res */
100 |_______struct memlist *bus_avail;|_____/* available free bus res */
101 |_______|_______|_______/* bus_space_used not needed; can read from regs */
102 |_______dev_info_t *dip;|_______/* devinfo node */
103 |_______void *privdata;||_______/* private data for configuration */
104 |_______uchar_t par_bus;|_______/* parent bus number */
105 |_______uchar_t sub_bus;|_______/* highest bus number beyond this bridge */
106 |_______uchar_t root_addr;|_____/* legacy peer bus address assignment */
107 |_______uchar_t num_cbb;|_______/* # of CardBus Bridges on the bus */
108 |_______boolean_t io_reprogram;|/* need io reprog on this bus */
109 |_______boolean_t mem_reprogram;|_______/* need mem reprog on this bus */
110 |_______boolean_t subtractive;|_/* subtractive PPB */
111 |_______uint_t mem_size;|_______/* existing children required MEM space size */
112 |_______uint_t io_size;||_______/* existing children required I/O space size */
113 };

"dip" holds the dev_info nodes on the system device tree. PCI nodes were created during enumeration according to their position in the PCI hierarchy. All devices/functions attached on the bus were linked to a list hooked on "privdata". The "par_bus" and "sub_bus" were used to mentain the hierarchy of the PCI system. The io/mem/prefetchable mem/bus resources consumed by the children buses and devices were recorded in the various "memlist".

In general, for each compatible PCI device, enumeration logic (process_devfunc() with CONFIG_INFO op type) will do the following items.

(a) create a dev_info node in the system device tree
If the device is under a bridge in the PCI hierarchy, the created device node will be placed under the node for the bridge; If the device is that integrated in the root complex, the logic will first create a special node under ddi_root_node() which present the root complex and the PCI device node would be under the root complex node.

(b) set the property values compliant with IEEE Std 1275-1994, refer to "PCI bus binding to IEEE Std 1275-1994"

(c) Set the device PM state to D0

(d) If the device is a normal PCI function, it will be put in the list hooked on the pci_bus_resource; if it is a bridge, the responding pci_bus_resouce is updated and the relationship between the parent bus and the secondary bus is built through updating the par_bus, sec_bus members in pci_bus_resource.

(e) Special handling of IOAPIC nodes
If the device/function is an IOAPIC node, a dev_info node will be created as the child of IOAPIC nexus node (located directly under ddi_root_node()). Some properties are created/updated: "vendor-id", "device-id", "device_type"(ioapic), "reg".

(f) for ck8-04 based PCI ISA bridge, some special properties created/updated

(g) set the compatible property values compliant with IEEE Std 1275-1994, refer to "PCI bus binding to IEEE Std 1275-1994". compatible property will be used for driver binding.

Here is how compatible property organized:

"compatible" Construct a list of names in most-specific to least-specific order. The names shall be derived from
values of the Vendor ID, Device ID, Subsystem Vendor ID, Subsystem ID, Revision ID and Class Code
bytes, and shall have the following form, and be placed in the list in the following order:
              pciVVVV,DDDD.SSSS.ssss.RR                  (1)
              pciVVVV,DDDD.SSSS.ssss                     (2)
              pciSSSS,ssss                               (3)
              pciVVVV,DDDD.RR                            (4)
              pciVVVV,DDDD                               (5)
              pciclass,CCSSPP                            (6)
              pciclass,CCSS                              (7)
    where:
              VVVV is the Vendor ID
              DDDD is the Device ID
              SSSS is the Subsystem Vendor ID
              ssss is the Subsystem ID
              RR is the Revision ID
              CC is the most-significant byte of the Class Code (base class code, at 0x0b).
              SS is the second-most-significant byte of the Class Code (sub-class code, at 0x0a).
              PP is the least-significant byte of the Class Code (programming interface, at 0x09).
Entries (1), (2) and (3) shall be included if and only if the Subsystem Vendor ID is non-zero.
Entry (3) is supplied only for backwards compatiblity with versions of the PCI Binding prior to Revision
2.1; new OS binding mechanisms should instead use forms (1) or (2) to select a driver based on the values
of the Subsystem Vendor ID and Subsystem ID.
VVVV, DDDD, SSSS, ssss and RR are lower-case ASCII hexadecimal numbers without leading zeroes.
CC, SS and PP are lower-case ASCII hexadecimal numbers including leading zeroes.

(h) special case for disk controller

2025 |_______/*
2026 |_______ * See if this device is a controller that advertises
2027 |_______ * itself to be a standard ATA task file controller, or one that
2028 |_______ * has been hard coded.
2029 |_______ *
2030 |_______ * If it is, check if any other higher precedence driver listed in
2031 |_______ * driver_aliases will claim the node by calling
2032 |_______ * ddi_compatibile_driver_major.  If so, clear pciide and do not
2033 |_______ * create a pci-ide node or any other special handling.
2034 |_______ *
2035 |_______ * If another driver does not bind, set the node name to pci-ide
2036 |_______ * and then let the special pci-ide handling for registers and
2037 |_______ * child pci-ide nodes proceed below.
2038 |_______ */

(i) Add the "reg" and "assigned-addresses" property.
Read the mem/IO/rom resources from BAR and ROM register in PCI configure space. Create the "reg" and "assigned-addresses" properties compliant with IEEE Std 1275-1994. Refer to the spec for decoding of "reg" and "assigned-addresses" properties.

The resources allocation will be recorded in pci_bus_resource[].

(j) Bind the driver with this device node

ndi_devi_bind_driver() is called here.

To be continued ...

资源下载链接为: https://pan.quark.cn/s/5c50e6120579 在Android移动应用开发中,定位功能扮演着极为关键的角色,尤其是在提供导航、本地搜索等服务时,它能够帮助应用获取用户的位置信息。以“baiduGPS.rar”为例,这是一个基于百度地图API实现定位功能的示例项目,旨在展示如何在Android应用中集成百度地图的GPS定位服务。以下是对该技术的详细阐述。 百度地图API简介 百度地图API是由百度提供的一系列开放接口,开发者可以利用这些接口将百度地图的功能集成到自己的应用中,涵盖地图展示、定位、路径规划等多个方面。借助它,开发者能够开发出满足不同业务需求的定制化地图应用。 Android定位方式 Android系统支持多种定位方式,包括GPS(全球定位系统)和网络定位(通过Wi-Fi及移动网络)。开发者可以根据应用的具体需求选择合适的定位方法。在本示例中,主要采用GPS实现高精度定位。 权限声明 在Android应用中使用定位功能前,必须在Manifest.xml文件中声明相关权限。例如,添加<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />,以获取用户的精确位置信息。 百度地图SDK初始化 集成百度地图API时,需要在应用启动时初始化地图SDK。通常在Application类或Activity的onCreate()方法中调用BMapManager.init(),并设置回调监听器以处理初始化结果。 MapView的创建 在布局文件中添加MapView组件,它是地图显示的基础。通过设置其属性(如mapType、zoomLevel等),可以控制地图的显示效果。 定位服务的管理 使用百度地图API的LocationClient类来管理定位服务
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值