1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2% Copyright (c) 2009, 2011, ETH Zurich. 3% All rights reserved. 4% 5% This file is distributed under the terms in the attached LICENSE file. 6% If you do not find this file, copies can be found by writing to: 7% ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 8%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9 10:-lib(ic). 11:-lib(ic_global). 12:-use_module(library(ic_edge_finder)). 13 14:-dynamic(currentbar/5). 15 16bridge_programming(Plan, NrElements) :- 17 get_devices(Devices), 18 convert_devices(Devices,DeviceElements), 19 get_bridges(Bridges), 20 convert_bridges(Bridges,BridgeElements), 21 append(DeviceElements, BridgeElements, Plan), 22 length(Plan, NrElements). 23 24% note: device with addr(-1,-1,-1) will be removed because it has no 25% regions -> nuet. The clean way would be to really remove it which leads 26% to other prolog problems... (two solutions). 27convert_devices([], []). 28convert_devices([buselement(device, Addr ,Regions)|T], L) :- 29 subtract(Regions,[nuet],RegionsClean), 30 ( foreach(R,RegionsClean), 31 foreach(El,Elements), 32 param(Addr) 33 do 34 region(BAR,Base,Bits,Prefetch,Sz,MulL) = R, 35 ( MulL = b -> 36 Mul is 1 37 ; 38 MulL = k -> 39 Mul is 1024 40 ; 41 MulL = g -> 42 Mul is 1024 * 1024 * 1024 43 ; 44 Mul is 1024 * 1024 45 ), 46 Size is Sz * Mul, 47 High is Base + Size, 48 El = buselement(device, Addr, BAR, Base, High, Size, mem, Prefetch, pcie, Bits), 49 assert(bar(Addr,BAR,_,Size,_,_,_)) 50 ), 51 convert_devices(T, L2), 52 append(L2, Elements, L). 53 54convert_bridges([], []). 55convert_bridges([buselement(bridge, _, _)|T], L) :- 56 convert_bridges(T, L). 57convert_bridges([buselement(bridge, Addr, S, m(B1,H1), p(B2, H2),_)|T], L) :- 58 ( H1 >= B1 -> 59 S1 is H1 - B1, 60 Bridge1 = [buselement(bridge, Addr, S, B1, H1+1, S1+1, mem, nonprefetchable, pcie, 0)]; 61 Bridge1 = [] 62 ), 63 ( H2 >= B2 -> 64 S2 is H2 - B2, 65 Bridge2 = [buselement(bridge, Addr, S, B2, H2+1, S2+1, mem, prefetchable, pcie, 0)]; 66 Bridge2 = [] 67 ), 68 append(Bridge1,Bridge2,BridgeList), 69 convert_bridges(T, L2), 70 append(L2, BridgeList, L). 71 72 73 74%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 75% tools 76%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 77 78 79base(buselement(_,_,_,Base,_,_,_,_,_,_),Base). 80high(buselement(_,_,_,_,High,_,_,_,_,_),High). 81size(buselement(_,_,_,_,_,Size,_,_,_,_),Size). 82 83get_devices(Devices) :- 84 Devices = [buselement(device, addr(-1,-1,-1),[ 85 nuet]), 86 buselement(device, addr(16'00,16'00,16'0),[ 87 nuet]), 88 buselement(device, addr(16'00,16'01,16'0),[ 89 nuet]), 90 buselement(device, addr(16'00,16'01,16'1),[ 91 nuet]), 92 buselement(device, addr(16'00,16'02,16'0),[ 93 nuet]), 94 buselement(device, addr(16'00,16'02,16'2),[ 95 nuet]), 96 buselement(device, addr(16'00,16'03,16'0),[ 97 nuet]), 98 buselement(device, addr(16'00,16'04,16'0),[ 99 region(0,16'3803fff90000,64,nonprefetchable,16,k), 100 nuet]), 101 buselement(device, addr(16'00,16'04,16'1),[ 102 region(0,16'3803fff80000,64,nonprefetchable,16,k), 103 nuet]), 104 buselement(device, addr(16'00,16'04,16'2),[ 105 region(0,16'3803fff70000,64,nonprefetchable,16,k), 106 nuet]), 107 buselement(device, addr(16'00,16'04,16'3),[ 108 region(0,16'3803fff60000,64,nonprefetchable,16,k), 109 nuet]), 110 buselement(device, addr(16'00,16'04,16'4),[ 111 region(0,16'3803fff50000,64,nonprefetchable,16,k), 112 nuet]), 113 buselement(device, addr(16'00,16'04,16'5),[ 114 region(0,16'3803fff40000,64,nonprefetchable,16,k), 115 nuet]), 116 buselement(device, addr(16'00,16'04,16'6),[ 117 region(0,16'3803fff30000,64,nonprefetchable,16,k), 118 nuet]), 119 buselement(device, addr(16'00,16'04,16'7),[ 120 region(0,16'3803fff20000,64,nonprefetchable,16,k), 121 nuet]), 122 buselement(device, addr(16'00,16'05,16'0),[ 123 nuet]), 124 buselement(device, addr(16'00,16'05,16'1),[ 125 nuet]), 126 buselement(device, addr(16'00,16'05,16'2),[ 127 nuet]), 128 buselement(device, addr(16'00,16'05,16'4),[ 129 region(0,16'd0f60000,32,nonprefetchable,4,k), 130 nuet]), 131 buselement(device, addr(16'00,16'11,16'0),[ 132 nuet]), 133 buselement(device, addr(16'00,16'16,16'0),[ 134 region(0,16'd0f50000,64,nonprefetchable,16,b), 135 nuet]), 136 buselement(device, addr(16'00,16'16,16'1),[ 137 region(0,16'd0f40000,64,nonprefetchable,16,b), 138 nuet]), 139 buselement(device, addr(16'00,16'1a,16'0),[ 140 region(0,16'd0f20000,32,nonprefetchable,1,k), 141 nuet]), 142 buselement(device, addr(16'00,16'1c,16'0),[ 143 nuet]), 144 buselement(device, addr(16'00,16'1c,16'7),[ 145 nuet]), 146 buselement(device, addr(16'00,16'1d,16'0),[ 147 region(0,16'd0f10000,32,nonprefetchable,1,k), 148 nuet]), 149 buselement(device, addr(16'00,16'1e,16'0),[ 150 nuet]), 151 buselement(device, addr(16'00,16'1f,16'0),[ 152 nuet]), 153 buselement(device, addr(16'00,16'1f,16'2),[ 154 region(5,16'd0f00000,32,nonprefetchable,2,k), 155 nuet]), 156 buselement(device, addr(16'00,16'1f,16'3),[ 157 region(0,16'3803fff10000,64,nonprefetchable,256,b), 158 nuet]), 159 buselement(device, addr(16'02,16'00,16'0),[ 160 region(0,16'd0960000,32,nonprefetchable,128,k), 161 region(3,16'd09b0000,32,nonprefetchable,16,k), 162 nuet]), 163 buselement(device, addr(16'02,16'00,16'1),[ 164 region(0,16'd0940000,32,nonprefetchable,128,k), 165 region(3,16'd09a0000,32,nonprefetchable,16,k), 166 nuet]), 167 buselement(device, addr(16'02,16'00,16'2),[ 168 region(0,16'd0920000,32,nonprefetchable,128,k), 169 region(3,16'd0990000,32,nonprefetchable,16,k), 170 nuet]), 171 buselement(device, addr(16'02,16'00,16'3),[ 172 region(0,16'd0900000,32,nonprefetchable,128,k), 173 region(3,16'd0980000,32,nonprefetchable,16,k), 174 nuet]), 175 buselement(device, addr(16'04,16'00,16'0),[ 176 region(0,16'd0e20000,64,nonprefetchable,128,k), 177 region(4,16'd0e50000,64,nonprefetchable,16,k), 178 nuet]), 179 buselement(device, addr(16'04,16'00,16'1),[ 180 region(0,16'd0e00000,64,nonprefetchable,128,k), 181 region(4,16'd0e40000,64,nonprefetchable,16,k), 182 nuet]), 183 buselement(device, addr(16'06,16'00,16'0),[ 184 region(1,16'd0d60000,64,nonprefetchable,16,k), 185 region(3,16'd0d00000,64,nonprefetchable,256,k), 186 nuet]), 187 buselement(device, addr(16'07,16'00,16'0),[ 188 region(0,16'380000000000,64,prefetchable,8,g), 189 region(4,16'd0c00000,64,nonprefetchable,128,k), 190 nuet]), 191 buselement(device, addr(16'08,16'00,16'0),[ 192 region(0,16'380200400000,64,prefetchable,16,k), 193 region(2,16'380200000000,64,prefetchable,4,m), 194 nuet]), 195 buselement(device, addr(16'08,16'00,16'3),[ 196 region(0,16'd0b00000,32,nonprefetchable,4,k), 197 nuet]), 198 buselement(device, addr(16'0a,16'00,16'0),[ 199 region(0,16'ea000000,32,prefetchable,16,m), 200 region(1,16'd0810000,32,nonprefetchable,16,k), 201 region(2,16'd0000000,32,nonprefetchable,8,m), 202 nuet]), 203 buselement(device, addr(16'7f,16'08,16'0),[ 204 nuet]), 205 buselement(device, addr(16'7f,16'09,16'0),[ 206 nuet]), 207 buselement(device, addr(16'7f,16'0a,16'0),[ 208 nuet]), 209 buselement(device, addr(16'7f,16'0a,16'1),[ 210 nuet]), 211 buselement(device, addr(16'7f,16'0a,16'2),[ 212 nuet]), 213 buselement(device, addr(16'7f,16'0a,16'3),[ 214 nuet]), 215 buselement(device, addr(16'7f,16'0b,16'0),[ 216 nuet]), 217 buselement(device, addr(16'7f,16'0b,16'3),[ 218 nuet]), 219 buselement(device, addr(16'7f,16'0c,16'0),[ 220 nuet]), 221 buselement(device, addr(16'7f,16'0c,16'1),[ 222 nuet]), 223 buselement(device, addr(16'7f,16'0c,16'2),[ 224 nuet]), 225 buselement(device, addr(16'7f,16'0c,16'3),[ 226 nuet]), 227 buselement(device, addr(16'7f,16'0c,16'4),[ 228 nuet]), 229 buselement(device, addr(16'7f,16'0d,16'0),[ 230 nuet]), 231 buselement(device, addr(16'7f,16'0d,16'1),[ 232 nuet]), 233 buselement(device, addr(16'7f,16'0d,16'2),[ 234 nuet]), 235 buselement(device, addr(16'7f,16'0d,16'3),[ 236 nuet]), 237 buselement(device, addr(16'7f,16'0d,16'4),[ 238 nuet]), 239 buselement(device, addr(16'7f,16'0e,16'0),[ 240 nuet]), 241 buselement(device, addr(16'7f,16'0e,16'1),[ 242 nuet]), 243 buselement(device, addr(16'7f,16'0f,16'0),[ 244 nuet]), 245 buselement(device, addr(16'7f,16'0f,16'1),[ 246 nuet]), 247 buselement(device, addr(16'7f,16'0f,16'2),[ 248 nuet]), 249 buselement(device, addr(16'7f,16'0f,16'3),[ 250 nuet]), 251 buselement(device, addr(16'7f,16'0f,16'4),[ 252 nuet]), 253 buselement(device, addr(16'7f,16'0f,16'5),[ 254 nuet]), 255 buselement(device, addr(16'7f,16'10,16'0),[ 256 nuet]), 257 buselement(device, addr(16'7f,16'10,16'1),[ 258 nuet]), 259 buselement(device, addr(16'7f,16'10,16'2),[ 260 nuet]), 261 buselement(device, addr(16'7f,16'10,16'3),[ 262 nuet]), 263 buselement(device, addr(16'7f,16'10,16'4),[ 264 nuet]), 265 buselement(device, addr(16'7f,16'10,16'5),[ 266 nuet]), 267 buselement(device, addr(16'7f,16'10,16'6),[ 268 nuet]), 269 buselement(device, addr(16'7f,16'10,16'7),[ 270 nuet]), 271 buselement(device, addr(16'7f,16'13,16'0),[ 272 nuet]), 273 buselement(device, addr(16'7f,16'13,16'1),[ 274 nuet]), 275 buselement(device, addr(16'7f,16'13,16'4),[ 276 nuet]), 277 buselement(device, addr(16'7f,16'13,16'5),[ 278 nuet]), 279 buselement(device, addr(16'7f,16'13,16'6),[ 280 nuet]), 281 buselement(device, addr(16'7f,16'16,16'0),[ 282 nuet]), 283 buselement(device, addr(16'7f,16'16,16'1),[ 284 nuet]), 285 buselement(device, addr(16'7f,16'16,16'2),[ 286 nuet]), 287 buselement(device, addr(16'80,16'01,16'0),[ 288 nuet]), 289 buselement(device, addr(16'80,16'02,16'0),[ 290 nuet]), 291 buselement(device, addr(16'80,16'03,16'0),[ 292 nuet]), 293 buselement(device, addr(16'80,16'03,16'2),[ 294 nuet]), 295 buselement(device, addr(16'80,16'04,16'0),[ 296 region(0,16'3805fff70000,64,nonprefetchable,16,k), 297 nuet]), 298 buselement(device, addr(16'80,16'04,16'1),[ 299 region(0,16'3805fff60000,64,nonprefetchable,16,k), 300 nuet]), 301 buselement(device, addr(16'80,16'04,16'2),[ 302 region(0,16'3805fff50000,64,nonprefetchable,16,k), 303 nuet]), 304 buselement(device, addr(16'80,16'04,16'3),[ 305 region(0,16'3805fff40000,64,nonprefetchable,16,k), 306 nuet]), 307 buselement(device, addr(16'80,16'04,16'4),[ 308 region(0,16'3805fff30000,64,nonprefetchable,16,k), 309 nuet]), 310 buselement(device, addr(16'80,16'04,16'5),[ 311 region(0,16'3805fff20000,64,nonprefetchable,16,k), 312 nuet]), 313 buselement(device, addr(16'80,16'04,16'6),[ 314 region(0,16'3805fff10000,64,nonprefetchable,16,k), 315 nuet]), 316 buselement(device, addr(16'80,16'04,16'7),[ 317 region(0,16'3805fff00000,64,nonprefetchable,16,k), 318 nuet]), 319 buselement(device, addr(16'80,16'05,16'0),[ 320 nuet]), 321 buselement(device, addr(16'80,16'05,16'1),[ 322 nuet]), 323 buselement(device, addr(16'80,16'05,16'2),[ 324 nuet]), 325 buselement(device, addr(16'80,16'05,16'4),[ 326 region(0,16'ec100000,32,nonprefetchable,4,k), 327 nuet]), 328 buselement(device, addr(16'82,16'00,16'0),[ 329 region(0,16'380600000000,64,prefetchable,8,g), 330 region(4,16'ec000000,64,nonprefetchable,128,k), 331 nuet])]. 332 333get_bridges(Bridges) :- 334 Bridges = [buselement(bridge, addr(-1,-1,-1), 335 _), 336 buselement(bridge, addr(16'00,16'00,16'0), 337 _), 338 buselement(bridge, addr(16'00,16'01,16'0), 339 secondary(16'01), 340 m(16'fff00000,16'000fffff), 341 p(16'00000000fff00000,16'00000000000fffff), 342 _), 343 buselement(bridge, addr(16'00,16'01,16'1), 344 secondary(16'02), 345 m(16'd0900000,16'd0afffff), 346 p(16'00000000fff00000,16'00000000000fffff), 347 _), 348 buselement(bridge, addr(16'00,16'02,16'0), 349 secondary(16'04), 350 m(16'd0e00000,16'd0efffff), 351 p(16'0000380200600000,16'00003802009fffff), 352 _), 353 buselement(bridge, addr(16'00,16'02,16'2), 354 secondary(16'06), 355 m(16'd0d00000,16'd0dfffff), 356 p(16'00000000fff00000,16'00000000000fffff), 357 _), 358 buselement(bridge, addr(16'00,16'03,16'0), 359 secondary(16'07), 360 m(16'd0c00000,16'd0cfffff), 361 p(16'0000380000000000,16'00003801ffffffff), 362 _), 363 buselement(bridge, addr(16'00,16'04,16'0), 364 _), 365 buselement(bridge, addr(16'00,16'04,16'1), 366 _), 367 buselement(bridge, addr(16'00,16'04,16'2), 368 _), 369 buselement(bridge, addr(16'00,16'04,16'3), 370 _), 371 buselement(bridge, addr(16'00,16'04,16'4), 372 _), 373 buselement(bridge, addr(16'00,16'04,16'5), 374 _), 375 buselement(bridge, addr(16'00,16'04,16'6), 376 _), 377 buselement(bridge, addr(16'00,16'04,16'7), 378 _), 379 buselement(bridge, addr(16'00,16'05,16'0), 380 _), 381 buselement(bridge, addr(16'00,16'05,16'1), 382 _), 383 buselement(bridge, addr(16'00,16'05,16'2), 384 _), 385 buselement(bridge, addr(16'00,16'05,16'4), 386 _), 387 buselement(bridge, addr(16'00,16'11,16'0), 388 secondary(16'08), 389 m(16'd0b00000,16'd0bfffff), 390 p(16'0000380200000000,16'00003802004fffff), 391 _), 392 buselement(bridge, addr(16'00,16'16,16'0), 393 _), 394 buselement(bridge, addr(16'00,16'16,16'1), 395 _), 396 buselement(bridge, addr(16'00,16'1a,16'0), 397 _), 398 buselement(bridge, addr(16'00,16'1c,16'0), 399 secondary(16'09), 400 m(16'fff00000,16'000fffff), 401 p(16'00000000fff00000,16'00000000000fffff), 402 _), 403 buselement(bridge, addr(16'00,16'1c,16'7), 404 secondary(16'0a), 405 m(16'd0000000,16'd08fffff), 406 p(16'00000000ea000000,16'00000000eaffffff), 407 _), 408 buselement(bridge, addr(16'00,16'1d,16'0), 409 _), 410 buselement(bridge, addr(16'00,16'1e,16'0), 411 secondary(16'0b), 412 m(16'fff00000,16'000fffff), 413 p(16'00000000fff00000,16'00000000000fffff), 414 _), 415 buselement(bridge, addr(16'00,16'1f,16'0), 416 _), 417 buselement(bridge, addr(16'00,16'1f,16'2), 418 _), 419 buselement(bridge, addr(16'00,16'1f,16'3), 420 _), 421 buselement(bridge, addr(16'02,16'00,16'0), 422 _), 423 buselement(bridge, addr(16'02,16'00,16'1), 424 _), 425 buselement(bridge, addr(16'02,16'00,16'2), 426 _), 427 buselement(bridge, addr(16'02,16'00,16'3), 428 _), 429 buselement(bridge, addr(16'04,16'00,16'0), 430 _), 431 buselement(bridge, addr(16'04,16'00,16'1), 432 _), 433 buselement(bridge, addr(16'06,16'00,16'0), 434 _), 435 buselement(bridge, addr(16'07,16'00,16'0), 436 _), 437 buselement(bridge, addr(16'08,16'00,16'0), 438 _), 439 buselement(bridge, addr(16'08,16'00,16'3), 440 _), 441 buselement(bridge, addr(16'0a,16'00,16'0), 442 _), 443 buselement(bridge, addr(16'7f,16'08,16'0), 444 _), 445 buselement(bridge, addr(16'7f,16'09,16'0), 446 _), 447 buselement(bridge, addr(16'7f,16'0a,16'0), 448 _), 449 buselement(bridge, addr(16'7f,16'0a,16'1), 450 _), 451 buselement(bridge, addr(16'7f,16'0a,16'2), 452 _), 453 buselement(bridge, addr(16'7f,16'0a,16'3), 454 _), 455 buselement(bridge, addr(16'7f,16'0b,16'0), 456 _), 457 buselement(bridge, addr(16'7f,16'0b,16'3), 458 _), 459 buselement(bridge, addr(16'7f,16'0c,16'0), 460 _), 461 buselement(bridge, addr(16'7f,16'0c,16'1), 462 _), 463 buselement(bridge, addr(16'7f,16'0c,16'2), 464 _), 465 buselement(bridge, addr(16'7f,16'0c,16'3), 466 _), 467 buselement(bridge, addr(16'7f,16'0c,16'4), 468 _), 469 buselement(bridge, addr(16'7f,16'0d,16'0), 470 _), 471 buselement(bridge, addr(16'7f,16'0d,16'1), 472 _), 473 buselement(bridge, addr(16'7f,16'0d,16'2), 474 _), 475 buselement(bridge, addr(16'7f,16'0d,16'3), 476 _), 477 buselement(bridge, addr(16'7f,16'0d,16'4), 478 _), 479 buselement(bridge, addr(16'7f,16'0e,16'0), 480 _), 481 buselement(bridge, addr(16'7f,16'0e,16'1), 482 _), 483 buselement(bridge, addr(16'7f,16'0f,16'0), 484 _), 485 buselement(bridge, addr(16'7f,16'0f,16'1), 486 _), 487 buselement(bridge, addr(16'7f,16'0f,16'2), 488 _), 489 buselement(bridge, addr(16'7f,16'0f,16'3), 490 _), 491 buselement(bridge, addr(16'7f,16'0f,16'4), 492 _), 493 buselement(bridge, addr(16'7f,16'0f,16'5), 494 _), 495 buselement(bridge, addr(16'7f,16'10,16'0), 496 _), 497 buselement(bridge, addr(16'7f,16'10,16'1), 498 _), 499 buselement(bridge, addr(16'7f,16'10,16'2), 500 _), 501 buselement(bridge, addr(16'7f,16'10,16'3), 502 _), 503 buselement(bridge, addr(16'7f,16'10,16'4), 504 _), 505 buselement(bridge, addr(16'7f,16'10,16'5), 506 _), 507 buselement(bridge, addr(16'7f,16'10,16'6), 508 _), 509 buselement(bridge, addr(16'7f,16'10,16'7), 510 _), 511 buselement(bridge, addr(16'7f,16'13,16'0), 512 _), 513 buselement(bridge, addr(16'7f,16'13,16'1), 514 _), 515 buselement(bridge, addr(16'7f,16'13,16'4), 516 _), 517 buselement(bridge, addr(16'7f,16'13,16'5), 518 _), 519 buselement(bridge, addr(16'7f,16'13,16'6), 520 _), 521 buselement(bridge, addr(16'7f,16'16,16'0), 522 _), 523 buselement(bridge, addr(16'7f,16'16,16'1), 524 _), 525 buselement(bridge, addr(16'7f,16'16,16'2), 526 _), 527 buselement(bridge, addr(16'80,16'01,16'0), 528 secondary(16'81), 529 m(16'fff00000,16'000fffff), 530 p(16'00000000fff00000,16'00000000000fffff), 531 _), 532 buselement(bridge, addr(16'80,16'02,16'0), 533 secondary(16'82), 534 m(16'ec000000,16'ec0fffff), 535 p(16'0000380600000000,16'00003807ffffffff), 536 _), 537 buselement(bridge, addr(16'80,16'03,16'0), 538 secondary(16'83), 539 m(16'fff00000,16'000fffff), 540 p(16'00000000fff00000,16'00000000000fffff), 541 _), 542 buselement(bridge, addr(16'80,16'03,16'2), 543 secondary(16'84), 544 m(16'fff00000,16'000fffff), 545 p(16'00000000fff00000,16'00000000000fffff), 546 _), 547 buselement(bridge, addr(16'80,16'04,16'0), 548 _), 549 buselement(bridge, addr(16'80,16'04,16'1), 550 _), 551 buselement(bridge, addr(16'80,16'04,16'2), 552 _), 553 buselement(bridge, addr(16'80,16'04,16'3), 554 _), 555 buselement(bridge, addr(16'80,16'04,16'4), 556 _), 557 buselement(bridge, addr(16'80,16'04,16'5), 558 _), 559 buselement(bridge, addr(16'80,16'04,16'6), 560 _), 561 buselement(bridge, addr(16'80,16'04,16'7), 562 _), 563 buselement(bridge, addr(16'80,16'05,16'0), 564 _), 565 buselement(bridge, addr(16'80,16'05,16'1), 566 _), 567 buselement(bridge, addr(16'80,16'05,16'2), 568 _), 569 buselement(bridge, addr(16'80,16'05,16'4), 570 _), 571 buselement(bridge, addr(16'82,16'00,16'0), 572 _)]. 573 574 575%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 576% small tools 577%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 578 579adjust_range(X, buselement(T,A,Sec,B1,H1,S,Tp,PF, PCIe, Bits), buselement(T,A,Sec,B2,H2,S,Tp,PF, PCIe, Bits)) :- 580 B2 is B1 + X, 581 H2 is H1 + X. 582 583back_to_bytes(Granularity, buselement(T,A,Sec,BP,HP,SP,Tp,PF, PCIe, Bits), buselement(T,A,Sec,B,H,S,Tp,PF, PCIe, Bits)) :- 584 B is BP * Granularity, 585 H is HP * Granularity, 586 S is SP * Granularity. 587 588 589%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 590% the main part of the allocation. Called once per root bridge 591%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 592 593bridge_assignment(Plan, Root, Granularity, ExclRanges, IOAPICs) :- 594 root(Addr,childbus(MinBus,MaxBus),mem(LMem,HMem)) = Root, 595 X is HMem - LMem, 596 Type = mem, 597 598% prefetchable 599 constrain_bus(Granularity, Type, prefetchable, Addr,MinBus,MaxBus,LMem,HMem,BusElementListP), 600 RBaseP::[LMem..HMem], 601 RHighP::[LMem..HMem], 602 RSizeP::[0..X], 603 devicetree(BusElementListP,buselement(bridge,Addr,secondary(MinBus),RBaseP,RHighP,RSizeP, Type, prefetchable, _, _),TP), 604 605% nonprefetchable 606 constrain_bus(Granularity, Type, nonprefetchable, Addr,MinBus,MaxBus,LMem,HMem,BusElementListNP), 607 RBaseNP::[LMem..HMem], 608 RHighNP::[LMem..HMem], 609 RSizeNP::[0..X], 610 devicetree(BusElementListNP,buselement(bridge,Addr,secondary(MinBus),RBaseNP,RHighNP,RSizeNP, Type, nonprefetchable, _, _),TNP), 611 612% pseudo-root of both trees 613 PseudoBase::[LMem..HMem], 614 PseudoHigh::[LMem..HMem], 615 PseudoSize::[0..X], 616 T = t(buselement(bridge, addr(-1, -1, -1), childbus(-1, -1), PseudoBase, PseudoHigh, PseudoSize, _, _, _, _), [TP, TNP]), 617 setrange(T,_,_,_), 618 nonoverlap(T), 619 naturally_aligned(T, 256, LMem, HMem), 620 tree2list(T,ListaU), 621 sort(6, >=, ListaU, Lista), 622 not_overlap_memory_ranges(Lista, ExclRanges), 623 keep_orig_addr(Lista, 12, 3, _, _, _, _), 624 keep_ioapic_bars(Lista, IOAPICs), 625 labelall(Lista), 626 subtract(Lista,[buselement(bridge,Addr,_,_,_,_,_,prefetchable,_,_)],Pl3), 627 subtract(Pl3,[buselement(bridge,Addr,_,_,_,_,_,nonprefetchable,_,_)],Pl2), 628 subtract(Pl2,[buselement(bridge,addr(-1,-1,-1),_,_,_,_,_,_,_,_)],Pl), 629 maplist(adjust_range(0),Pl,PR), 630 maplist(back_to_bytes(Granularity),PR,Plan). 631 632% dot output: 633% PrBaseBytePref is RBaseP * Granularity, 634% PrHighBytePref is RHighP * Granularity, 635% PrBaseByteNonPref is RBaseNP * Granularity, 636% PrHighByteNonPref is RHighNP * Granularity, 637% plan_to_dot(Granularity, Plan, Root, PrBaseBytePref, PrHighBytePref, PrBaseByteNonPref, PrHighByteNonPref). 638 639 640%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 641% instantiating the variables 642%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 643 644 645labelall(BusElementList) :- 646 maplist(base, BusElementList, Base), 647 maplist(high, BusElementList, High), 648 maplist(size, BusElementList, Size), 649 append(Base, High, L1), 650 append(L1, Size, L2), 651 labeling(L2). 652 653 654 655%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 656% create the list of devices and bridges in form of buselements and create the 657% variables. 658% we care about the allocation of memory mapped registers here, therefore we only 659% look at bar located in "mem", not "io" 660%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 661 662constrain_bus(Granularity, Type, Prefetch, RootAddr,Bus,MaxBus,LMem,HMem,OutBusElementList) :- 663 constrain_bus_ex(Granularity, Type, Prefetch, RootAddr,Bus,MaxBus,LMem,HMem,[],OutBusElementList). 664 665constrain_bus_ex(_, _, _, _,Bus,MaxBus,_,_,InL,InL) :- Bus > MaxBus. 666constrain_bus_ex(Granularity, Type, Prefetch, RootAddr,Bus,MaxBus,LMem,HMem,InBusElementList,OutBusElementList) :- 667 Bus =< MaxBus, 668 SMax is HMem - LMem, 669 ( is_predicate(bridge/8) -> 670 findall(buselement(bridge,addr(Bus,Dev,Fun),secondary(Sec),Base,High,Size,Type,Prefetch, PCIe, 0), 671 ( bridge(PCIe, addr(Bus,Dev,Fun), _, _, _, _, _, secondary(Sec)), 672 not addr(Bus,Dev,Fun) = RootAddr, 673 Base::[LMem..HMem],High::[LMem..HMem],Size::[0..SMax] 674 ),BridgeList); 675 BridgeList = [] 676 ), 677 ( is_predicate(device/8) -> 678 findall(buselement(device,addr(Bus,Dev,Fun),BAR,Base,High,SizeP,Type,Prefetch, PCIe, Bits), 679 ( device(PCIe, addr(Bus,Dev,Fun),_,_,_,_,_,_), 680 bar(addr(Bus,Dev,Fun),BAR,_,Size, Type, Prefetch, Bits), 681 Base::[LMem..HMem],High::[LMem..HMem], 682 ST1 is Size / Granularity, 683 ceiling(ST1, ST2), 684 integer(ST2, SizeP) 685 ),DeviceList); 686 DeviceList = [] 687 ), 688 append(BridgeList, DeviceList, MyBusElementList), 689 append(InBusElementList, MyBusElementList, NewBusElementList), 690 NextBus is Bus + 1, 691 constrain_bus_ex(Granularity, Type, Prefetch, RootAddr, NextBus, MaxBus, LMem,HMem,NewBusElementList,OutBusElementList). 692 693 694%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 695% create the PCI(e) device tree from a list of "buselement" and return it in Tree 696%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 697 698devicetree(List,CurrRoot,Tree) :- 699 buselement(bridge,_,secondary(Sec),_,_,_,_,_,_,_) = CurrRoot, 700 findall(X,( 701 member(Y,List), 702 buselement(_,addr(Sec,_,_),_,_,_,_,_,_,_,_) = Y, 703 devicetree(List, Y, X)),Children 704 ), 705 Tree = t(CurrRoot,Children). 706devicetree(_,CurrRoot,Tree) :- 707 buselement(device,_,_,_,_,_,_,_,_,_) = CurrRoot, 708 Tree = t(CurrRoot, []). 709 710 711%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 712% convert a tree to a list of buselements 713%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 714 715tree2list([],[]). 716tree2list(Tree, List) :- 717 t(Node,Children) = Tree, 718 ( foreach(El,Children), 719 foreach(L1,ChildList) 720 do 721 tree2list(El,L1) 722 ), 723 flatten(ChildList,L2), 724 List = [Node|L2]. 725 726 727 728%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 729% store the new values of the BARs 730%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 731replace_current_BAR_values(L) :- 732 delete_current_BAR_values(L), 733 store_current_BAR_values(L). 734 735store_current_BAR_values([]). 736store_current_BAR_values([H|T]) :- 737 ( buselement(device,Addr,BAR,Base,High,Size,_,_,_,_) = H -> 738 assert(currentbar(Addr,BAR,Base,High,Size)); 739 true 740 ), 741 store_current_BAR_values(T). 742 743 744delete_current_BAR_values([]). 745delete_current_BAR_values([H|T]) :- 746 ( buselement(device,Addr,BAR,_,_,_,_,_,_,_) = H -> 747 ( currentbar(Addr,BAR,_,_,_) -> 748 retract(currentbar(Addr,BAR,_,_,_)); 749 true 750 ); 751 true 752 ), 753 delete_current_BAR_values(T). 754 755 756 757 758%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 759% add constraints to the tree 760%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 761 762% make sure that the bridge has a range which includes all the children 763setrange(Tree,SubTreeSize,SubTreeMin,SubTreeMax) :- 764 t(Node,Children) = Tree, 765 ( foreach(El,Children), 766 foreach(Sz,SizeList), 767 foreach(Mi,MinList), 768 foreach(Ma,MaxList) 769 do 770 setrange(El,Sz,Mi,Ma) 771 ), 772 ic_global:sumlist(SizeList,Size), 773 buselement(_,_,_,Base,High,ElemSize,_,_,_,_) = Node, 774 ElemSize $>= Size, 775 ( not MinList=[] -> 776 ic:minlist(MinList,Min), 777 ic:maxlist(MaxList,Max), 778 Min $>= Base, 779 Max $=< High; 780 true 781 ), 782 High $= Base + ElemSize, 783 SubTreeSize $= ElemSize, 784 SubTreeMin $= Base, 785 SubTreeMax $= High. 786setrange([],0,_,_). 787 788 789% make sure that the children do not overlap 790child(t(C,_),C). 791nonoverlap(Tree) :- 792 t(_ ,Children) = Tree, 793 maplist(child,Children,ChildList), 794 ( not ChildList=[] -> 795 maplist(base,ChildList,Base), 796 maplist(size,ChildList,Size), 797 disjunctive(Base,Size); 798 true 799 ), 800 ( foreach(El, Children) 801 do 802 nonoverlap(El) 803 ). 804 805 806naturally_aligned(Tree, BridgeAlignment, LMem, HMem) :- 807 t(Node,Children) = Tree, 808 ( buselement(device,_,_,Base,High,Size,_,_,_,_) = Node -> 809 Divisor is Size 810 ; 811 buselement(bridge,_,_,Base,High,_,_,_,_,_) = Node -> 812 Divisor is BridgeAlignment 813 ), 814 815 T1 is (HMem - LMem) / Divisor, 816 ceiling(T1, T2), 817 integer(T2, Nr), 818 N::[0..Nr], 819 N2::[0..Nr], 820 mod(LMem,Divisor,Remainder), 821 ( Remainder =:= 0 -> 822 Corr is 0; 823 Corr is Divisor - Remainder 824 ), 825 Base $= N*Divisor + LMem + Corr, 826 High $>= Base, 827 High $= N2*Divisor + LMem + Corr, 828 ( foreach(El, Children), 829 param(BridgeAlignment), 830 param(LMem), 831 param(HMem) 832 do 833 naturally_aligned(El, BridgeAlignment, LMem, HMem) 834 ). 835 836 837% do not overlap with the given list of memory ranges 838not_overlap_memory_ranges([], _). 839not_overlap_memory_ranges(_, []). 840not_overlap_memory_ranges([buselement(bridge,_,_,_,_,_,_,_,_,_)|PCIList], MemoryRanges) :- 841 not_overlap_memory_ranges(PCIList, MemoryRanges). 842not_overlap_memory_ranges([H|PCIList], MemoryRanges) :- 843 ( foreach(range(RBase,RSize),MemoryRanges), 844 param(H) 845 do 846 buselement(device,_,_,Base,_,Size,_,_,_,_) = H, 847 append([Base],[RBase],Bases), 848 append([Size],[RSize],Sizes), 849 disjunctive(Bases,Sizes) 850 ), 851 not_overlap_memory_ranges(PCIList, MemoryRanges). 852 853 854keep_orig_addr([], _, _, _, _, _, _). 855keep_orig_addr([H|Buselements], Class, SubClass, ProgIf, Bus, Dev, Fun) :- 856 ( buselement(device,addr(Bus,Dev,Fun),BAR,Base,_,_,_,_,_,_) = H,device(_,addr(Bus,Dev,Fun),_,_,Class, SubClass, ProgIf,_),bar(addr(Bus,Dev,Fun),BAR,OrigBase,_,_,_,_) -> 857 T1 is OrigBase / 4096, 858 floor(T1,T2), 859 integer(T2,KeepBase), 860 Base $= KeepBase; 861 true 862 ), 863 keep_orig_addr(Buselements, Class, SubClass, ProgIf, Bus, Dev, Fun). 864 865% on some machines (sbrinz1) one of the two IOAPICs appears as a BAR 866% on a device which claims to be a RAM memory controller. If this occurs, 867% we want to avoid moving this BAR as otherwise the IOAPIC cannot be reached 868% anymore. 869keep_ioapic_bars(_, []). 870keep_ioapic_bars(Buselements, [H|IOAPICList]) :- 871 ( 872 range(B, _) = H, 873 bar(addr(Bus,Dev,Fun),_,OrigBase,_,_,_,_), 874 T1 is OrigBase / 4096, 875 floor(T1,T2), 876 integer(T2,KeepBase), 877 KeepBase =:= B -> 878 keep_orig_addr(Buselements, _, _, _, Bus, Dev, Fun); 879 true 880 ), 881 keep_ioapic_bars(Buselements, IOAPICList). 882