coreboot学习8:ramstage阶段之资源分配流程

设备枚举后就是资源分配了,在dev_configure函数中完成。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
void dev_configure(void)
{
struct resource *res;
struct device *root;
struct device *child;

set_vga_bridge_bits();

printk(BIOS_INFO, "Allocating resources...\n");

root = &dev_root; // 根设备

/*
* Each domain should create resources which contain the entire address
* space for IO, MEM, and PREFMEM resources in the domain. The
* allocation of device resources will be done from this address space.
*/

/* Read the resources for the entire tree. */
// 先读一次
printk(BIOS_INFO, "Reading resources...\n");
read_resources(root->link_list);
printk(BIOS_INFO, "Done reading resources.\n");

// 打印设备树的资源
print_resource_tree(root, BIOS_SPEW, "After reading.");

/* Compute resources for all domains. */
// 计算资源
for (child = root->link_list->children; child; child = child->sibling) {
if (!(child->path.type == DEVICE_PATH_DOMAIN))
continue;
post_log_path(child);
for (res = child->resource_list; res; res = res->next) {
if (res->flags & IORESOURCE_FIXED)
continue;
if (res->flags & IORESOURCE_MEM) {
compute_resources(child->link_list,
res, IORESOURCE_TYPE_MASK, IORESOURCE_MEM);
continue;
}
if (res->flags & IORESOURCE_IO) {
compute_resources(child->link_list,
res, IORESOURCE_TYPE_MASK, IORESOURCE_IO);
continue;
}
}
}

/* For all domains. */
for (child = root->link_list->children; child; child=child->sibling)
if (child->path.type == DEVICE_PATH_DOMAIN)
avoid_fixed_resources(child); // 此函数作用? 感觉是对范围的限制

/* Store the computed resource allocations into device registers ... */
printk(BIOS_INFO, "Setting resources...\n");
for (child = root->link_list->children; child; child = child->sibling) {
if (!(child->path.type == DEVICE_PATH_DOMAIN))
continue;
post_log_path(child);
// 分mem和io两种资源
for (res = child->resource_list; res; res = res->next) {
if (res->flags & IORESOURCE_FIXED)
continue;
if (res->flags & IORESOURCE_MEM) {
allocate_resources(child->link_list,
res, IORESOURCE_TYPE_MASK, IORESOURCE_MEM);
continue;
}
if (res->flags & IORESOURCE_IO) {
allocate_resources(child->link_list,
res, IORESOURCE_TYPE_MASK, IORESOURCE_IO);
continue;
}
}
}
assign_resources(root->link_list);
printk(BIOS_INFO, "Done setting resources.\n");
print_resource_tree(root, BIOS_SPEW, "After assigning values.");

printk(BIOS_INFO, "Done allocating resources.\n");
}

从该函数看出大概有几个步骤:
1、先读一次设备树上的资源,并打印出来。
2、计算资源,compute_resources。
3、对资源范围做限制,avoid_fixed_resources。
4、申请资源,allocate_resources。
5、分配资源,assign_resources。
6、打印分配好的资源(注:此时设备树的资源有部分是第1步骤打印的不同)。

根据代码整理的流程图如下:
(此处留空)

附上此过程的打印信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
[LL DEBUG]: in bs_dev_resources()...
found VGA at PCI: 00:02.0
Setting up VGA for PCI: 00:02.0
Setting PCI_BRIDGE_CTL_VGA for bridge DOMAIN: 0000
Setting PCI_BRIDGE_CTL_VGA for bridge Root Device
Allocating resources...
Reading resources...
Root Device read_resources bus 0 link: 0
CPU_CLUSTER: 0 read_resources bus 0 link: 0
CPU_CLUSTER: 0 read_resources bus 0 link: 0 done
QEMU: 8 files in fw_cfg
QEMU: etc/boot-fail-wait [size=4]
QEMU: etc/e820 [size=20]
QEMU: genroms/kvmvapic.bin [size=9216]
QEMU: etc/system-states [size=6]
QEMU: bootorder [size=0]
QEMU: etc/acpi/tables [size=8192]
QEMU: etc/table-loader [size=4096]
QEMU: etc/acpi/rsdp [size=36]
QEMU: e820/ram: 0x00000000 +0x08000000
QEMU: reserve ioports 0x0510-0x0511 [firmware-config]
QEMU: reserve ioports 0x5658-0x5658 [vmware-port]
QEMU: reserve ioports 0xae00-0xae0f [pci-hotplug]
QEMU: reserve ioports 0xaf00-0xaf1f [cpu-hotplug]
QEMU: reserve ioports 0xafe0-0xafe3 [piix4-gpe0]
DOMAIN: 0000 read_resources bus 0 link: 0
DOMAIN: 0000 read_resources bus 0 link: 0 done
Root Device read_resources bus 0 link: 0 done
Done reading resources.
Show resources in subtree (Root Device)...After reading.
Root Device child on link 0 CPU_CLUSTER: 0
CPU_CLUSTER: 0 child on link 0 APIC: 00
APIC: 00
DOMAIN: 0000 child on link 0 PCI: 00:00.0
DOMAIN: 0000 resource base 0 size 0 align 0 gran 0 limit ffff flags 40040100 index 10000000
DOMAIN: 0000 resource base 0 size 0 align 0 gran 0 limit ffffffff flags 40040200 index 10000100
DOMAIN: 0000 resource base 0 size a0000 align 0 gran 0 limit 0 flags e0004200 index a
DOMAIN: 0000 resource base c0000 size 7f40000 align 0 gran 0 limit 0 flags e0004200 index b
DOMAIN: 0000 resource base 510 size 2 align 0 gran 0 limit ffff flags e0000100 index c
DOMAIN: 0000 resource base 5658 size 1 align 0 gran 0 limit ffff flags e0000100 index d
DOMAIN: 0000 resource base ae00 size 10 align 0 gran 0 limit ffff flags e0000100 index e
DOMAIN: 0000 resource base af00 size 20 align 0 gran 0 limit ffff flags e0000100 index f
DOMAIN: 0000 resource base afe0 size 4 align 0 gran 0 limit ffff flags e0000100 index 10
DOMAIN: 0000 resource base fec00000 size 100000 align 0 gran 0 limit ffffffff flags e0000200 index 2
DOMAIN: 0000 resource base fee00000 size 10000 align 0 gran 0 limit ffffffff flags e0000200 index 3
PCI: 00:00.0
PCI: 00:01.0
PCI: 00:01.0 resource base 0 size 1000 align 0 gran 0 limit ffff flags c0000100 index 1
PCI: 00:01.0 resource base ff800000 size 800000 align 0 gran 0 limit 0 flags d0000200 index 2
PCI: 00:01.1
PCI: 00:01.1 resource base 0 size 10 align 4 gran 4 limit ffff flags 100 index 20
PCI: 00:01.3
PCI: 00:01.3 resource base e400 size 40 align 0 gran 0 limit ffff flags d0000100 index 1
PCI: 00:01.3 resource base f00 size 10 align 0 gran 0 limit ffff flags d0000100 index 2
PCI: 00:02.0
PCI: 00:02.0 resource base 0 size 2000000 align 25 gran 25 limit ffffffff flags 1200 index 10
PCI: 00:02.0 resource base 0 size 1000 align 12 gran 12 limit ffffffff flags 200 index 14
PCI: 00:02.0 resource base 0 size 10000 align 16 gran 16 limit ffffffff flags 2200 index 30
PCI: 00:03.0
PCI: 00:03.0 resource base 0 size 20000 align 17 gran 17 limit ffffffff flags 200 index 10
PCI: 00:03.0 resource base 0 size 40 align 6 gran 6 limit ffff flags 100 index 14
PCI: 00:03.0 resource base 0 size 40000 align 18 gran 18 limit ffffffff flags 2200 index 30
DOMAIN: 0000 io: base: 0 size: 0 align: 0 gran: 0 limit: ffff
PCI: 00:03.0 14 * [0x0 - 0x3f] io
PCI: 00:01.1 20 * [0x40 - 0x4f] io
DOMAIN: 0000 io: base: 50 size: 50 align: 6 gran: 0 limit: ffff done
DOMAIN: 0000 mem: base: 0 size: 0 align: 0 gran: 0 limit: ffffffff
PCI: 00:02.0 10 * [0x0 - 0x1ffffff] prefmem
PCI: 00:03.0 30 * [0x2000000 - 0x203ffff] mem
PCI: 00:03.0 10 * [0x2040000 - 0x205ffff] mem
PCI: 00:02.0 30 * [0x2060000 - 0x206ffff] mem
PCI: 00:02.0 14 * [0x2070000 - 0x2070fff] mem
DOMAIN: 0000 mem: base: 2071000 size: 2071000 align: 25 gran: 0 limit: ffffffff done
avoid_fixed_resources: DOMAIN: 0000
avoid_fixed_resources:@DOMAIN: 0000 10000000 limit 0000ffff
avoid_fixed_resources:@DOMAIN: 0000 10000100 limit ffffffff
constrain_resources: DOMAIN: 0000 0a base 00000000 limit 0009ffff mem (fixed)
constrain_resources: DOMAIN: 0000 0b base 000c0000 limit 07ffffff mem (fixed)
constrain_resources: DOMAIN: 0000 0c base 00000510 limit 00000511 io (fixed)
constrain_resources: DOMAIN: 0000 0d base 00005658 limit 00005658 io (fixed)
constrain_resources: DOMAIN: 0000 0e base 0000ae00 limit 0000ae0f io (fixed)
constrain_resources: DOMAIN: 0000 02 base fec00000 limit fecfffff mem (fixed)
avoid_fixed_resources:@DOMAIN: 0000 10000000 base 00005659 limit 0000adff
avoid_fixed_resources:@DOMAIN: 0000 10000100 base fc000000 limit febfffff
Setting resources...
DOMAIN: 0000 io: base:5659 size:50 align:6 gran:0 limit:adff
PCI: 00:03.0 14 * [0x5800 - 0x583f] io
PCI: 00:01.1 20 * [0x5840 - 0x584f] io
DOMAIN: 0000 io: next_base: 5850 size: 50 align: 6 gran: 0 done
DOMAIN: 0000 mem: base:fc000000 size:2071000 align:25 gran:0 limit:febfffff
PCI: 00:02.0 10 * [0xfc000000 - 0xfdffffff] prefmem
PCI: 00:03.0 30 * [0xfe000000 - 0xfe03ffff] mem
PCI: 00:03.0 10 * [0xfe040000 - 0xfe05ffff] mem
PCI: 00:02.0 30 * [0xfe060000 - 0xfe06ffff] mem
PCI: 00:02.0 14 * [0xfe070000 - 0xfe070fff] mem
DOMAIN: 0000 mem: next_base: fe071000 size: 2071000 align: 25 gran: 0 done
Root Device assign_resources, bus 0 link: 0
DOMAIN: 0000 assign_resources, bus 0 link: 0
PCI: 00:01.1 20 <- [0x0000005840 - 0x000000584f] size 0x00000010 gran 0x04 io
PCI: 00:02.0 10 <- [0x00fc000000 - 0x00fdffffff] size 0x02000000 gran 0x19 prefmem
PCI: 00:02.0 14 <- [0x00fe070000 - 0x00fe070fff] size 0x00001000 gran 0x0c mem
PCI: 00:02.0 30 <- [0x00fe060000 - 0x00fe06ffff] size 0x00010000 gran 0x10 romem
PCI: 00:03.0 10 <- [0x00fe040000 - 0x00fe05ffff] size 0x00020000 gran 0x11 mem
PCI: 00:03.0 14 <- [0x0000005800 - 0x000000583f] size 0x00000040 gran 0x06 io
PCI: 00:03.0 30 <- [0x00fe000000 - 0x00fe03ffff] size 0x00040000 gran 0x12 romem
DOMAIN: 0000 assign_resources, bus 0 link: 0
Root Device assign_resources, bus 0 link: 0
Done setting resources.
Show resources in subtree (Root Device)...After assigning values.
Root Device child on link 0 CPU_CLUSTER: 0
CPU_CLUSTER: 0 child on link 0 APIC: 00
APIC: 00
DOMAIN: 0000 child on link 0 PCI: 00:00.0
DOMAIN: 0000 resource base 5659 size 50 align 6 gran 0 limit adff flags 40040100 index 10000000
DOMAIN: 0000 resource base fc000000 size 2071000 align 25 gran 0 limit febfffff flags 40040200 index 10000100
DOMAIN: 0000 resource base 0 size a0000 align 0 gran 0 limit 0 flags e0004200 index a
DOMAIN: 0000 resource base c0000 size 7f40000 align 0 gran 0 limit 0 flags e0004200 index b
DOMAIN: 0000 resource base 510 size 2 align 0 gran 0 limit ffff flags e0000100 index c
DOMAIN: 0000 resource base 5658 size 1 align 0 gran 0 limit ffff flags e0000100 index d
DOMAIN: 0000 resource base ae00 size 10 align 0 gran 0 limit ffff flags e0000100 index e
DOMAIN: 0000 resource base af00 size 20 align 0 gran 0 limit ffff flags e0000100 index f
DOMAIN: 0000 resource base afe0 size 4 align 0 gran 0 limit ffff flags e0000100 index 10
DOMAIN: 0000 resource base fec00000 size 100000 align 0 gran 0 limit ffffffff flags e0000200 index 2
DOMAIN: 0000 resource base fee00000 size 10000 align 0 gran 0 limit ffffffff flags e0000200 index 3
PCI: 00:00.0
PCI: 00:01.0
PCI: 00:01.0 resource base 0 size 1000 align 0 gran 0 limit ffff flags c0000100 index 1
PCI: 00:01.0 resource base ff800000 size 800000 align 0 gran 0 limit 0 flags d0000200 index 2
PCI: 00:01.1
PCI: 00:01.1 resource base 5840 size 10 align 4 gran 4 limit 584f flags 60000100 index 20
PCI: 00:01.3
PCI: 00:01.3 resource base e400 size 40 align 0 gran 0 limit ffff flags d0000100 index 1
PCI: 00:01.3 resource base f00 size 10 align 0 gran 0 limit ffff flags d0000100 index 2
PCI: 00:02.0
PCI: 00:02.0 resource base fc000000 size 2000000 align 25 gran 25 limit fdffffff flags 60001200 index 10
PCI: 00:02.0 resource base fe070000 size 1000 align 12 gran 12 limit fe070fff flags 60000200 index 14
PCI: 00:02.0 resource base fe060000 size 10000 align 16 gran 16 limit fe06ffff flags 60002200 index 30
PCI: 00:03.0
PCI: 00:03.0 resource base fe040000 size 20000 align 17 gran 17 limit fe05ffff flags 60000200 index 10
PCI: 00:03.0 resource base 5800 size 40 align 6 gran 6 limit 583f flags 60000100 index 14
PCI: 00:03.0 resource base fe000000 size 40000 align 18 gran 18 limit fe03ffff flags 60002200 index 30
Done allocating resources.

注:
由于coreboot方面资料较少,笔者第一次尝试分析代码,还有众多未能参透的地方,难免出错。任何问题,欢迎一起交流学习。
李迟 2016.4.4 周一 清明节