`
javasee
  • 浏览: 960948 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Solaris Source Insight: PCI system implementation - Part 4

阅读更多

continue with pci_reprogram()

(b) Fix-up unit-address assignments for peer bus, and create a devcache for this assignment
The unit-address is stored in the first integer of "reg" property. "unit-address" is assigned from 0 and increased for each root bus in the system. "Non-root bus" is equal to "peer bus" here.

(c) root-bus resource discovery
c.1 find resources associated with this root bus
The resources for a root bus can be enumerated in these ways: (i) call ACPI "_CRS" method to find the current resource settings for the device (root bus); (ii) search them in PCI Hot-Plug Resource Table starting at 0xF0000 if that exists; (iii) search them in MP spec table if that exists. The implementation relies on the methods in order and returns if one is successful. Resources include IO range, memory range, prefetchable memory range and bus number range.

The resources are stored in pci_bus_res[] array:

intel/io/pci/pci_boot.c
1406 |_______/* scan BIOS structures */
1407 |_______pci_bus_res[bus].pmem_avail = find_bus_res(bus, PREFETCH_TYPE);
1408 |_______pci_bus_res[bus].mem_avail = find_bus_res(bus, MEM_TYPE);
1409 |_______pci_bus_res[bus].io_avail = find_bus_res(bus, IO_TYPE);
1410 |_______pci_bus_res[bus].bus_avail = find_bus_res(bus, BUSRANGE_TYPE);

c.2 extend pci_bus_res[bus].sub_bus according to bus ranges in pci_bus_res[bus].bus_avail

c.3 code comments
intel/io/pci/pci_boot.c
1430 |_______|_______/*
1431 |_______|_______ * Special treatment of bus 0:
1432 |_______|_______ * If no IO/MEM resource from ACPI/MPSPEC/HRT, copy
1433 |_______|_______ * pcimem from boot and make I/O space the entire range
1434 |_______|_______ * starting at 0x100.
1435 |_______|_______ */

c.4 code comments
intel/io/pci/pci_boot.c
1444 |_______/*
1445 |_______ * Create 'ranges' property here before any resources are
1446 |_______ * removed from the resource lists
1447 |_______ */

Question:
We saw many ACPI-related funcation calls on the way. It was assumed that root bus device node has been built a 1-1 map with PCI root complex object in ACPI name space. Peaple can use acpica_get_handle() to retrieve the ACPI handle from the dip and acpica_get_devinfo() to retrive dip vice vasa. But when did this relationship built?

Answer:
The system does maintain the mapping of a node in device tree and an object in ACPI name space, if they present the same physical devices. For a device node, "acpinamespace" property is created, which is the string of the path of an ACPI object in ACPI name space; while, in acpi object struct, there is data related to device node dip. Global variable "d2a_done" marks if the mapping between them has been built.

101 static int d2a_done = 0;

If not, scan_d2a_map() will be called to establish the map.

[intel/io/acpica/osl.c]
1811 |_______if (!d2a_done)
1812 |_______|_______scan_d2a_map();

End of the answer...

(d) Remove used PCI and ISA resources from bus resource map
[intel/io/pci/pci_boot.c]
1321 |_______|_______memlist_remove_list(&pci_bus_res[bus].io_avail,
1322 |_______|_______ pci_bus_res[bus].io_used);
1323 |_______|_______memlist_remove_list(&pci_bus_res[bus].mem_avail,
1324 |_______|_______ pci_bus_res[bus].mem_used);
1325 |_______|_______memlist_remove_list(&pci_bus_res[bus].pmem_avail,
1326 |_______|_______ pci_bus_res[bus].pmem_used);
1327 |_______|_______memlist_remove_list(&pci_bus_res[bus].mem_avail,
1328 |_______|_______ pci_bus_res[bus].pmem_used);
1329 |_______|_______memlist_remove_list(&pci_bus_res[bus].pmem_avail,
1330 |_______|_______ pci_bus_res[bus].mem_used);
1331
1332 |_______|_______memlist_remove_list(&pci_bus_res[bus].io_avail,
1333 |_______|_______ isa_res.io_used);
1334 |_______|_______memlist_remove_list(&pci_bus_res[bus].mem_avail,
1335 |_______|_______ isa_res.mem_used);

(e) Reserve <1M space
[intel/io/pci/pci_boot.c]
1337 |_______|_______/*
1338 |_______|_______ * 3. Exclude <1M address range here in case below reserved
1339 |_______|_______ * ranges for BIOS data area, ROM area etc are wrongly reported
1340 |_______|_______ * in ACPI resource producer entries for PCI root bus.
1341 |_______|_______ * |____00000000 - 000003FF|____RAM
1342 |_______|_______ * |____00000400 - 000004FF|____BIOS data area
1343 |_______|_______ * |____00000500 - 0009FFFF|____RAM
1344 |_______|_______ * |____000A0000 - 000BFFFF|____VGA RAM
1345 |_______|_______ * |____000C0000 - 000FFFFF|____ROM area
1346 |_______|_______ */

(f) add bus-range property for root/peer bus nodes
[intel/io/pci/pci_boot.c]
1355 |_______/* add bus-range property for root/peer bus nodes */
1356 |_______for (i = 0; i <= pci_bios_maxbus; i++) {
1357 |_______|_______/* create bus-range property on root/peer buses */
1358 |_______|_______if (pci_bus_res[i].par_bus == (uchar_t)-1)
1359 |_______|_______|_______add_bus_range_prop(i);
1360
1361 |_______|_______/* setup bus range resource on each bus */
1362 |_______|_______setup_bus_res(i);
1363 |_______}

(g) get user option "pci-reprog" and set pci_reconfig according to the value.

(h) Remove the resources which are already used by devices under a subtractive bridge from the bus's resources lists

619 /*
620 * Remove the resources which are already used by devices under a subtractive
621 * bridge from the bus's resources lists, because they're not available, and
622 * shouldn't be allocated to other buses. This is necessary because tracking
623 * resources for subtractive bridges is not complete. (Subtractive bridges only
624 * track some of their claimed resources, not "the rest of the address space" as
625 * they should, so that allocation to peer non-subtractive PPBs is easier. We
626 * need a fully-capable global resource allocator).
627 */

What's PCI subtractive decoding?

This description of a PCI bus transaction assumes that both initiating and target devices are PCI devices. However, even today most PCs require an ISA or other expansion bus in order to be able to install legacy peripherals. This is achieved using a PCI to expansion bus bridge. In this configuration, the PCI bus is the primary bus, and the legacy bus is the secondary bus.
If an initiator begins a transaction for a device that is on a secondary expansion bus, no PCI device will acknowledge that it is the target. One of two things could happen next. The PCI to expansion bus bridge could claim the transaction on behalf of its own peripherals; however, this would require that the bridge be programmed with the addresses of all the devices on the other side of it. This is a possibility in the case of MCA, EISA and plug-and-play ISA boards. However, ordinary ISA boards are not plug-and-play so a PCI to ISA bridge can have no knowledge of what memory and I/O addresses are on the ISA bus.
The method normally used to handle transactions destined for an ISA expansion bus is to use a process of subtractive decoding, or "if nobody else wants it, it must be for me." The expansion bus bridge claims the transaction if it is for a memory address in the first 16MB of address space or an I/O port address in the first 64KB, and no PCI device has claimed the transaction within a set delay period. The delay period depends on the speed of the PCI device address decoders, which can take from one to three clock cycles to respond with an acknowledgement.
The speed, and hence the length of the delay, is determined during the power on configuration process. The presence of even one slow device will require a delay of four bus clock cycles for every ISA bus transfer. This will degrade the performance of peripherals on the ISA expansion bus.

Citing from "How the PCI Bus Works"

(i) reprogram the non-subtractive PPB, root PCI bus will not reconfigured

intel/io/pci/pci_boot.c
865 /*
866 * Assign valid resources to unconfigured pci(e) bridges. We are trying
867 * to reprogram the bridge when its
868 * |____|_______i) SECBUS == SUBBUS|__||
869 * |____|_______ii) IOBASE > IOLIM|____||
870 * |____|_______iii) MEMBASE > MEMLIM
871 * This must be done after one full pass through the PCI tree to collect
872 * all BIOS-configured resources, so that we know what resources are
873 * free and available to assign to the unconfigured PPBs.
874 */
875 static void
876 fix_ppb_res(uchar_t secbus, boolean_t prog_sub)
877 {

Questions:
How to retrive PCI BDF (bus, device, function) numbers from a PCI dev_info?

Answer:
PCI BDF numbers are encoded in the first integer of "reg" property.

[intel/io/pci/pci_boot.c]
2327 |_______devloc = (uint_t)bus << 16 | (uint_t)dev << 11 | (uint_t)func << 8;
2328 |_______regs[0].pci_phys_hi = devloc;

[intel/io/pci/pci_boot.c]
903 |_______rv = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
904 |_______ "reg", &regp, &reglen);
905 |_______if (rv != DDI_PROP_SUCCESS || reglen == 0)
906 |_______|_______return;
907 |_______physhi = regp[0];
908 |_______ddi_prop_free(regp);
909
910 |_______func = (uchar_t)PCI_REG_FUNC_G(physhi);
911 |_______dev = (uchar_t)PCI_REG_DEV_G(physhi);
912 |_______bus = (uchar_t)PCI_REG_BUS_G(physhi);

This is how acpica_get_bdf() implemented in

[intel/io/acpica/osl.c]
1774 /*
1775 * Return bus/dev/fn for PCI dip (note: not the parent "pci" node).
1776 */
1777 int
1778 acpica_get_bdf(dev_info_t *dip, int *bus, int *device, int *func)
1779 {

But, don't trust this function if you are not sure the passed dip is really for a PCI device. For example, if you pass a device node under "isa", acpica_get_bdf() will return a bdf of (0,0,0).

End of answer ...

The following things have been done in fix_ppb_res().
(i) If we have a Cardbus bridge, but no bus space, Try to find and allocate a bus-range starting at subbus+1 from the parent of the PPB.
(ii) Calculate the io size and mem size. Let the code say what's the algorithm.

968 |_______/*
969 |_______ * Calculate required IO size and alignment
970 |_______ * If bus io_size is zero, we are going to assign 512 bytes per bus,
971 |_______ * otherwise, we'll choose the maximum value of such calculation and
972 |_______ * bus io_size. The size needs to be 4K aligned.
973 |_______ *
974 |_______ * We calculate alignment as the largest power of two less than the
975 |_______ * the sum of all children's IO size requirements, because this will
976 |_______ * align to the size of the largest child request within that size
977 |_______ * (which is always a power of two).
978 |_______ */
979 |_______io_size = (subbus - secbus + 1) * 0x200;
980 |_______if (io_size < pci_bus_res[secbus].io_size)
981 |_______|_______io_size = pci_bus_res[secbus].io_size;
982 |_______io_size = P2ROUNDUP(io_size, PPB_IO_ALIGNMENT);
983 |_______io_align = io_size;
984 |_______P2LE(io_align);
985
986 |_______/*
987 |_______ * Calculate required MEM size and alignment
988 |_______ * If bus mem_size is zero, we are going to assign 1M bytes per bus,
989 |_______ * otherwise, we'll choose the maximum value of such calculation and
990 |_______ * bus mem_size. The size needs to be 1M aligned.
991 |_______ *
992 |_______ * For the alignment, refer to the I/O comment above.
993 |_______ */
994 |_______mem_size = (subbus - secbus + 1) * PPB_MEM_ALIGNMENT;
995 |_______if (mem_size < pci_bus_res[secbus].mem_size) {
996 |_______|_______mem_size = pci_bus_res[secbus].mem_size;
997 |_______|_______mem_size = P2ROUNDUP(mem_size, PPB_MEM_ALIGNMENT);
998 |_______}
999 |_______mem_align = mem_size;
1000 |_______P2LE(mem_align);

(iii) do the real reprogram job for unconfigured PPB.

(j) Reprogram the subtractive PPB
At this time, all its siblings should have got their resources already.

(k) Configure the devices/functions attached to this bus.
enumerate_bus_devs(i, CONFIG_NEW);

The actual reprogram logic is in add_reg_props()

1509 |_______|_______|_______if (entry->reprogram ||
1510 |_______|_______|_______ pci_bus_res[bus].io_reprogram ||
1511 |_______|_______|_______ pci_bus_res[bus].mem_reprogram) {
1512 |_______|_______|_______|_______/* reprogram device(s) */
1513 |_______|_______|_______|_______(void) add_reg_props(entry->dip, bus,
1514 |_______|_______|_______|_______ entry->dev, entry->func, CONFIG_NEW, 0);
1515 |_______|_______|_______}

(l) All dev programmed, so we can create available prop

Summary, pci_reprogram() configures all the PCI devices/functions which were not configured by BIOS.

Question:
I only saw PCI resource reprogramed, is there any reconfiguration for bus numbering?


Answer:
Yes, it's possible that pci_reprogram() could renumber PCI buses by modifying the secondary and suboridinary bus numbers in registers of a PPB (PCI-to-PCI bridges).


934 |_______/*
935 |_______ * If we have a Cardbus bridge, but no bus space
936 |_______ */
937 |_______if (pci_bus_res[secbus].num_cbb != 0 &&
938 |_______ pci_bus_res[secbus].bus_avail == NULL) {
939 |_______|_______uchar_t range;
940
941 |_______|_______/* normally there are 2 buses under a cardbus bridge */
942 |_______|_______range = pci_bus_res[secbus].num_cbb * 2;
943
944 |_______|_______/*
945 |_______|_______ * Try to find and allocate a bus-range starting at subbus+1
946 |_______|_______ * from the parent of the PPB.
947 |_______|_______ */
948 |_______|_______for (; range != 0; range--) {
949 |_______|_______|_______if (memlist_find_with_startaddr(
950 |_______|_______|_______ &pci_bus_res[parbus].bus_avail,
951 |_______|_______|_______ subbus + 1, range, 1) != NULL)
952 |_______|_______|_______|_______break; /* find bus range resource at parent */
953 |_______|_______}
954 |_______|_______if (range != 0) {
955 |_______|_______|_______memlist_insert(&pci_bus_res[secbus].bus_avail,
956 |_______|_______|_______ subbus + 1, range);
957 |_______|_______|_______subbus = subbus + range;
958 |_______|_______|_______pci_bus_res[secbus].sub_bus = subbus;
959 |_______|_______|_______pci_putb(bus, dev, func, PCI_BCNF_SUBBUS, subbus);
960 |_______|_______|_______add_bus_range_prop(secbus);
961
962 |_______|_______|_______cmn_err(CE_NOTE, "!reprogram bus-range on ppb"
963 |_______|_______|_______ "[%x/%x/%x]: %x ~ %x\n", bus, dev, func,
964 |_______|_______|_______ secbus, subbus);
965 |_______|_______}
966 |_______}

分享到:
评论

相关推荐

    source insight 3.5 UTF-8中文乱码插件_sourceinsight3.5_utf-8_插件补丁_中文乱码_

    4. 重启Source Insight,打开包含中文字符的文件,检查是否成功解决了乱码问题。 需要注意的是,不同的操作系统(如Windows、Mac OS或Linux)以及Source Insight的不同版本,其配置和插件管理方式可能存在差异,...

    sourceinsight_4.0.86.0-setup.zip

    4. 多语言支持:Source Insight支持C、C++、Java、Python等多种编程语言,适用于多种开发场景。 5. 版本控制集成:可与常见的版本控制系统如Git、SVN等无缝对接,方便查看代码历史和差异。 三、初次使用指南 1. ...

    sourceinsight_4.0.86.0-setup安装+破解码

    sourceinsight_4.0.86.0-setup.exe,加破解码

    sourceinsight_4.0.86.0-setup安装文件

    sourceinsight_4.0.86.0-setup安装及破解,不求发家致富,但求有口饭吃

    SourceInsight4配色xml文件-深色

    标题提到的"SourceInsight4配色xml文件-深色",意味着这是针对SourceInsight4版本的一个深色调的配色方案。深色主题通常被认为对长时间编程的眼睛更为友好,因为它可以减少屏幕反射,减轻眼睛疲劳。深色背景与浅色...

    Source Insight 3支持Utf-8

    Source Insight 3是一款广受欢迎的源代码阅读器和编辑器,尤其在软件开发领域中,它为程序员提供了强大的代码浏览、分析和编辑功能。对于处理各种编码格式的源代码文件,Source Insight 3表现出了良好的兼容性,其中...

    sourceinsight-4.0.86.0-密码123.zip

    SourceInsight是一款强大的源代码分析和浏览工具,尤其在C/C++、Java和C#等编程语言中广泛应用。它提供了一种高效的方式来查看、搜索、理解和编辑源代码,深受程序员喜爱。版本4.0.86.0是SourceInsight的一个特定...

    sourceinsight_4.0.86.0-setup软件

    4. 代码分析:SourceInsight会自动分析源代码,提供语法高亮、调用图等,帮助理解代码结构。 五、常见问题与解决方案 1. 安装失败:检查是否满足操作系统和硬件需求,或者尝试以管理员权限运行安装程序。 2. 打不开...

    linux Ubuntu下安装 Source insight

    "Linux Ubuntu下安装Source Insight" Linux Ubuntu下安装Source Insight是指在Ubuntu操作系统下安装Source Insight软件,从而实现在Linux平台下使用Source Insight编辑和阅读源码。本文将详细介绍如何在Ubuntu下...

    Source Insight 语言文件 -- MIPS ASM

    **Source Insight 语言文件介绍** Source Insight是一款广泛使用的源代码编辑器和分析工具,尤其在软件开发领域,它提供了一种高效的方式来进行代码浏览、编辑和理解。该工具的一个核心特性是其支持多种编程语言的...

    source insight UTF-8插件

    Source Insight是一款广受欢迎的源代码阅读和分析工具,尤其在软件开发领域中,它以其强大的代码导航、搜索和理解功能而备受赞誉。然而,对于处理包含非英文字符,特别是中文字符的UTF-8编码文件时,原生的Source ...

    source insight 4.0自用黑色配色主题

    注意:这是source insight 4.0的主题。解压缩后,在source insight菜单进行导入操作:Source Insight 4-&gt;Options-&gt;load configurations-&gt;选择下载的配置文件

    source insight 编辑器快捷键

    ### Source Insight 编辑器快捷键详解 #### 一、基本操作 - **退出程序**:Alt + F4 - 这个快捷键用于快速关闭 Source Insight 编辑器。 - **重绘屏幕**:Ctrl + Alt + Space - 当编辑器窗口显示异常时,可以...

    sourceInsight_4.0.0087 破解版 + 漂亮theme

    2. 替换原主程序:sourceinsight4.exe 3. 导入授权文件(Import a new license file):si4.pediy.lic Patched sourceinsight4.exe: Size Date Time Checksum Name --------- ---------- ----- -------- ---- ...

    Source Insight 3.5 序列号

    在探讨“Source Insight 3.5 序列号”这一主题时,首先需要明确的是,序列号(serial number)通常是指软件开发商为了控制软件的分发与使用而提供的一种授权方式。通过序列号,可以验证用户是否拥有使用该软件的合法...

    解决source insight3.5不支持中文utf8问题

    4. **安装第三方插件**:有些开发者社区提供了扩展Source Insight以支持UTF-8的插件。安装这些插件后,Source Insight 3.5就能正确识别和显示UTF-8编码的文件了。 5. **升级到新版本**:如果可能,升级到Source ...

    source Insight---- Quicker

    **源码洞察——Source Insight更快捷使用指南** Source Insight是一款广受程序员喜爱的源代码查看和编辑工具,尤其在C/C++、Java等语言的开发中,它的智能高亮、语法分析、代码跳转等功能极大地提高了开发效率。...

    让source insight支持AT&T汇编语法高亮

    ### 让Source Insight支持AT&T汇编语法高亮 #### 背景介绍 Source Insight是一款功能强大的编辑器,能够帮助开发者高效地进行代码编写、分析及管理等工作。它不仅支持多种编程语言,还能通过自定义配置来扩展对特定...

    pc-lint用于sourceinsight上静态代码检测

    4. **运行PC-lint**: 在Source Insight中打开要检查的源文件后,通过工具栏或快捷键触发PC-lint分析。分析结果将在Source Insight的输出窗口中显示,通常包括警告和错误信息,以及对应的代码位置。 5. **查看和处理...

Global site tag (gtag.js) - Google Analytics