1 /* 2 * Copyright 2020 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "internal_sys_mock.hpp" 18 #include "pci.hpp" 19 #include "pciaccess_mock.hpp" 20 #include "tool_errors.hpp" 21 22 #include <stdplus/raw.hpp> 23 24 #include <algorithm> 25 #include <cstdlib> 26 #include <string> 27 #include <vector> 28 29 #include <gtest/gtest.h> 30 31 namespace host_tool 32 { 33 namespace 34 { 35 36 using namespace std::string_literals; 37 38 using ::testing::Assign; 39 using ::testing::ContainerEq; 40 using ::testing::DoAll; 41 using ::testing::Each; 42 using ::testing::Eq; 43 using ::testing::InSequence; 44 using ::testing::NotNull; 45 using ::testing::Return; 46 using ::testing::SetArgPointee; 47 48 // TODO: switch to ConainerEq for C++20 49 MATCHER_P(SpanEq, s, "") 50 { 51 return arg.size() == s.size() && !memcmp(arg.data(), s.data(), s.size()); 52 } 53 54 MATCHER_P(PciIdMatch, m, "") 55 { 56 return (arg->vendor_id == m->vendor_id && arg->device_id == m->device_id && 57 arg->subvendor_id == m->subvendor_id && 58 arg->subdevice_id == m->subdevice_id); 59 } 60 61 pci_device_iterator* mockIter = reinterpret_cast<pci_device_iterator*>(0x42); 62 63 constexpr pciaddr_t mockBaseAddr = 0xdeadbeef; 64 constexpr pciaddr_t mockRegionSize = 0x20000; 65 66 class Device 67 { 68 public: 69 virtual ~Device() = default; 70 virtual const struct pci_id_match* getMatch() const = 0; 71 virtual struct pci_device getDevice() const = 0; 72 virtual void expectSetup(PciAccessMock& pciMock, 73 const struct pci_device& dev) const {}; 74 virtual std::unique_ptr<PciBridgeIntf> getBridge(PciAccess* pci) const = 0; 75 virtual std::string getName() const = 0; 76 }; 77 78 class NuvotonDevice : public Device 79 { 80 public: 81 const struct pci_id_match* getMatch() const override 82 { 83 return &match; 84 } 85 86 struct pci_device getDevice() const override 87 { 88 struct pci_device dev; 89 90 dev.vendor_id = match.vendor_id; 91 dev.device_id = match.device_id; 92 93 dev.regions[0].is_IO = false; 94 dev.regions[0].base_addr = mockBaseAddr; 95 dev.regions[0].size = mockRegionSize; 96 97 return dev; 98 } 99 100 void expectSetup(PciAccessMock& pciMock, 101 const struct pci_device& dev) const override 102 { 103 static constexpr std::uint8_t defaultVal = 0x40; 104 105 InSequence in; 106 107 EXPECT_CALL(pciMock, 108 pci_device_cfg_read_u8(Eq(&dev), NotNull(), config)) 109 .WillOnce(DoAll(SetArgPointee<1>(defaultVal), Return(0))); 110 EXPECT_CALL(pciMock, pci_device_cfg_write_u8( 111 Eq(&dev), defaultVal | bridgeEnabled, config)) 112 .WillOnce(Return(0)); 113 114 EXPECT_CALL(pciMock, 115 pci_device_cfg_read_u8(Eq(&dev), NotNull(), config)) 116 .WillOnce( 117 DoAll(SetArgPointee<1>(defaultVal | bridgeEnabled), Return(0))); 118 EXPECT_CALL(pciMock, 119 pci_device_cfg_write_u8(Eq(&dev), defaultVal, config)) 120 .WillOnce(Return(0)); 121 } 122 123 std::unique_ptr<PciBridgeIntf> getBridge(PciAccess* pci) const override 124 { 125 return std::make_unique<NuvotonPciBridge>(pci); 126 } 127 128 std::string getName() const override 129 { 130 return "Nuvoton"s; 131 } 132 133 /* Offset to the config register */ 134 static constexpr int config = 0x04; 135 /* Second bit determines whether bridge is enabled */ 136 static constexpr std::uint8_t bridgeEnabled = 0x02; 137 138 private: 139 static constexpr struct pci_id_match match 140 { 141 0x1050, 0x0750, PCI_MATCH_ANY, PCI_MATCH_ANY 142 }; 143 }; 144 145 class AspeedDevice : public Device 146 { 147 public: 148 const struct pci_id_match* getMatch() const override 149 { 150 return &match; 151 } 152 153 struct pci_device getDevice() const override 154 { 155 struct pci_device dev; 156 157 dev.vendor_id = match.vendor_id; 158 dev.device_id = match.device_id; 159 160 dev.regions[1].is_IO = false; 161 dev.regions[1].base_addr = mockBaseAddr; 162 dev.regions[1].size = mockRegionSize; 163 164 return dev; 165 } 166 167 std::unique_ptr<PciBridgeIntf> getBridge(PciAccess* pci) const override 168 { 169 return std::make_unique<AspeedPciBridge>(pci); 170 } 171 172 std::string getName() const override 173 { 174 return "Aspeed"s; 175 } 176 177 /* Offset to the config region */ 178 static constexpr int config = 0x0f000; 179 /* Lower bit determines whether bridge is enabled */ 180 static constexpr std::uint8_t bridgeEnabled = 0x01; 181 /* Offset to the MMIO address configuration */ 182 static constexpr int bridge = 0x0f004; 183 184 private: 185 static constexpr struct pci_id_match match 186 { 187 0x1a03, 0x2000, PCI_MATCH_ANY, PCI_MATCH_ANY 188 }; 189 }; 190 191 NuvotonDevice nuvotonDevice; 192 AspeedDevice aspeedDevice; 193 194 class PciSetupTest : public testing::TestWithParam<Device*> 195 {}; 196 197 /* Handle device not found */ 198 TEST_P(PciSetupTest, NotFound) 199 { 200 PciAccessMock pciMock; 201 202 InSequence in; 203 204 EXPECT_CALL(pciMock, pci_id_match_iterator_create( 205 PciIdMatch(GetParam()->getMatch()))) 206 .WillOnce(Return(mockIter)); 207 EXPECT_CALL(pciMock, pci_device_next(Eq(mockIter))) 208 .WillOnce(Return(nullptr)); 209 EXPECT_CALL(pciMock, pci_iterator_destroy(Eq(mockIter))).Times(1); 210 211 EXPECT_THROW(GetParam()->getBridge(&pciMock), NotFoundException); 212 } 213 214 /* Test finding device but probe fails */ 215 TEST_P(PciSetupTest, ProbeFail) 216 { 217 PciAccessMock pciMock; 218 struct pci_device dev; 219 220 EXPECT_CALL(pciMock, pci_id_match_iterator_create( 221 PciIdMatch(GetParam()->getMatch()))) 222 .WillOnce(Return(mockIter)); 223 EXPECT_CALL(pciMock, pci_device_next(Eq(mockIter))) 224 .WillOnce(Return(&dev)) 225 .WillRepeatedly(Return(nullptr)); 226 227 EXPECT_CALL(pciMock, pci_device_probe(Eq(&dev))).WillOnce(Return(EFAULT)); 228 229 EXPECT_CALL(pciMock, pci_iterator_destroy(Eq(mockIter))).Times(1); 230 231 EXPECT_THROW(GetParam()->getBridge(&pciMock), std::system_error); 232 } 233 234 /* Test finding device but mapping fails */ 235 TEST_P(PciSetupTest, MapFail) 236 { 237 PciAccessMock pciMock; 238 struct pci_device dev; 239 240 EXPECT_CALL(pciMock, pci_id_match_iterator_create( 241 PciIdMatch(GetParam()->getMatch()))) 242 .WillOnce(Return(mockIter)); 243 EXPECT_CALL(pciMock, pci_device_next(Eq(mockIter))) 244 .WillOnce(Return(&dev)) 245 .WillRepeatedly(Return(nullptr)); 246 247 EXPECT_CALL(pciMock, pci_device_probe(Eq(&dev))) 248 .WillOnce(DoAll(Assign(&dev, GetParam()->getDevice()), Return(0))); 249 250 EXPECT_CALL(pciMock, 251 pci_device_map_range(Eq(&dev), mockBaseAddr, mockRegionSize, 252 PCI_DEV_MAP_FLAG_WRITABLE, NotNull())) 253 .WillOnce(Return(EFAULT)); 254 255 EXPECT_CALL(pciMock, pci_iterator_destroy(Eq(mockIter))).Times(1); 256 257 EXPECT_THROW(GetParam()->getBridge(&pciMock), std::system_error); 258 } 259 260 /* Test finding device but unmapping fails */ 261 TEST_P(PciSetupTest, UnmapFail) 262 { 263 PciAccessMock pciMock; 264 struct pci_device dev; 265 std::vector<std::uint8_t> region(mockRegionSize); 266 267 EXPECT_CALL(pciMock, pci_id_match_iterator_create( 268 PciIdMatch(GetParam()->getMatch()))) 269 .WillOnce(Return(mockIter)); 270 EXPECT_CALL(pciMock, pci_device_next(Eq(mockIter))) 271 .WillOnce(Return(&dev)) 272 .WillRepeatedly(Return(nullptr)); 273 274 EXPECT_CALL(pciMock, pci_device_probe(Eq(&dev))) 275 .WillOnce(DoAll(Assign(&dev, GetParam()->getDevice()), Return(0))); 276 277 EXPECT_CALL(pciMock, 278 pci_device_map_range(Eq(&dev), mockBaseAddr, mockRegionSize, 279 PCI_DEV_MAP_FLAG_WRITABLE, NotNull())) 280 .WillOnce(DoAll(SetArgPointee<4>(region.data()), Return(0))); 281 282 EXPECT_CALL(pciMock, pci_iterator_destroy(Eq(mockIter))).Times(1); 283 EXPECT_CALL(pciMock, pci_device_unmap_range(Eq(&dev), Eq(region.data()), 284 mockRegionSize)) 285 .WillOnce(Return(EFAULT)); 286 287 GetParam()->expectSetup(pciMock, dev); 288 // This will print an error but not throw 289 GetParam()->getBridge(&pciMock); 290 } 291 292 /* Create expectations on pciMock for finding device and mapping memory region 293 */ 294 void expectSetup(PciAccessMock& pciMock, struct pci_device& dev, Device* param, 295 std::uint8_t* region, bool deviceExpectations = true) 296 { 297 EXPECT_CALL(pciMock, 298 pci_id_match_iterator_create(PciIdMatch(param->getMatch()))) 299 .WillOnce(Return(mockIter)); 300 EXPECT_CALL(pciMock, pci_device_next(Eq(mockIter))) 301 .WillOnce(Return(&dev)) 302 .WillRepeatedly(Return(nullptr)); 303 304 EXPECT_CALL(pciMock, pci_device_probe(Eq(&dev))) 305 .WillOnce(DoAll(Assign(&dev, param->getDevice()), Return(0))); 306 307 EXPECT_CALL(pciMock, 308 pci_device_map_range(Eq(&dev), mockBaseAddr, mockRegionSize, 309 PCI_DEV_MAP_FLAG_WRITABLE, NotNull())) 310 .WillOnce(DoAll(SetArgPointee<4>(region), Return(0))); 311 312 EXPECT_CALL(pciMock, pci_iterator_destroy(Eq(mockIter))).Times(1); 313 EXPECT_CALL(pciMock, 314 pci_device_unmap_range(Eq(&dev), Eq(region), mockRegionSize)) 315 .WillOnce(Return(0)); 316 317 if (deviceExpectations) 318 param->expectSetup(pciMock, dev); 319 } 320 321 /* Test finding device and mapping memory region */ 322 TEST_P(PciSetupTest, Success) 323 { 324 PciAccessMock pciMock; 325 struct pci_device dev; 326 std::vector<std::uint8_t> region(mockRegionSize); 327 328 expectSetup(pciMock, dev, GetParam(), region.data()); 329 330 GetParam()->getBridge(&pciMock); 331 } 332 333 INSTANTIATE_TEST_SUITE_P(Default, PciSetupTest, 334 ::testing::Values(&nuvotonDevice, &aspeedDevice), 335 [](const testing::TestParamInfo<Device*>& info) { 336 return info.param->getName(); 337 }); 338 339 TEST(NuvotonWriteTest, TooLarge) 340 { 341 PciAccessMock pciMock; 342 struct pci_device dev; 343 std::vector<std::uint8_t> region(mockRegionSize); 344 std::vector<std::uint8_t> data(0x4001); 345 346 expectSetup(pciMock, dev, &nuvotonDevice, region.data()); 347 348 std::unique_ptr<PciBridgeIntf> bridge = nuvotonDevice.getBridge(&pciMock); 349 EXPECT_THROW(bridge->write(stdplus::span<std::uint8_t>(data)), 350 ToolException); 351 } 352 353 TEST(NuvotonWriteTest, Success) 354 { 355 PciAccessMock pciMock; 356 struct pci_device dev; 357 std::vector<std::uint8_t> region(mockRegionSize); 358 std::vector<std::uint8_t> data(0x4000); 359 360 std::generate(data.begin(), data.end(), std::rand); 361 362 expectSetup(pciMock, dev, &nuvotonDevice, region.data()); 363 364 std::unique_ptr<PciBridgeIntf> bridge = nuvotonDevice.getBridge(&pciMock); 365 bridge->write(stdplus::span<std::uint8_t>(data)); 366 367 EXPECT_THAT(stdplus::span<uint8_t>(®ion[0], data.size()), 368 SpanEq(stdplus::span<uint8_t>(data))); 369 } 370 371 TEST(NuvotonConfigureTest, Success) 372 { 373 PciAccessMock pciMock; 374 struct pci_device dev; 375 std::vector<std::uint8_t> region(mockRegionSize); 376 ipmi_flash::PciConfigResponse config{0x123bea51}; 377 378 expectSetup(pciMock, dev, &nuvotonDevice, region.data()); 379 380 std::unique_ptr<PciBridgeIntf> bridge = nuvotonDevice.getBridge(&pciMock); 381 bridge->configure(config); 382 383 /* No effect from calling configure(), so the whole region should be 0 */ 384 EXPECT_THAT(region, Each(0)); 385 } 386 387 TEST(NuvotonDataLengthTest, Success) 388 { 389 PciAccessMock pciMock; 390 struct pci_device dev; 391 std::vector<std::uint8_t> region(mockRegionSize); 392 393 expectSetup(pciMock, dev, &nuvotonDevice, region.data()); 394 395 std::unique_ptr<PciBridgeIntf> bridge = nuvotonDevice.getBridge(&pciMock); 396 EXPECT_EQ(bridge->getDataLength(), 0x4000); 397 } 398 399 /* Make sure config register is left alone if the bridge is already enabled */ 400 TEST(NuvotonBridgeTest, AlreadyEnabledSuccess) 401 { 402 PciAccessMock pciMock; 403 struct pci_device dev; 404 std::vector<std::uint8_t> region(mockRegionSize); 405 406 constexpr std::uint8_t defaultVal = 0x40; 407 408 /* Only set standard expectations; not those from nuvotonDevice */ 409 expectSetup(pciMock, dev, &nuvotonDevice, region.data(), false); 410 411 { 412 InSequence in; 413 414 EXPECT_CALL(pciMock, pci_device_cfg_read_u8(Eq(&dev), NotNull(), 415 NuvotonDevice::config)) 416 .WillOnce(DoAll( 417 SetArgPointee<1>(defaultVal | NuvotonDevice::bridgeEnabled), 418 Return(0))); 419 420 EXPECT_CALL(pciMock, pci_device_cfg_read_u8(Eq(&dev), NotNull(), 421 NuvotonDevice::config)) 422 .WillOnce(DoAll( 423 SetArgPointee<1>(defaultVal | NuvotonDevice::bridgeEnabled), 424 Return(0))); 425 EXPECT_CALL(pciMock, pci_device_cfg_write_u8(Eq(&dev), defaultVal, 426 NuvotonDevice::config)) 427 .WillOnce(Return(0)); 428 } 429 430 nuvotonDevice.getBridge(&pciMock); 431 } 432 433 /* Read fails when attempting to setup the bridge */ 434 TEST(NuvotonBridgeTest, ReadSetupFail) 435 { 436 PciAccessMock pciMock; 437 struct pci_device dev; 438 std::vector<std::uint8_t> region(mockRegionSize); 439 440 /* Only set standard expectations; not those from nuvotonDevice */ 441 expectSetup(pciMock, dev, &nuvotonDevice, region.data(), false); 442 443 EXPECT_CALL(pciMock, pci_device_cfg_read_u8(Eq(&dev), NotNull(), 444 NuvotonDevice::config)) 445 .WillOnce(Return(EFAULT)); 446 447 EXPECT_THROW(nuvotonDevice.getBridge(&pciMock), std::system_error); 448 } 449 450 /* Write fails when attempting to setup the bridge */ 451 TEST(NuvotonBridgeTest, WriteSetupFail) 452 { 453 PciAccessMock pciMock; 454 struct pci_device dev; 455 std::vector<std::uint8_t> region(mockRegionSize); 456 457 constexpr std::uint8_t defaultVal = 0x40; 458 459 /* Only set standard expectations; not those from nuvotonDevice */ 460 expectSetup(pciMock, dev, &nuvotonDevice, region.data(), false); 461 462 EXPECT_CALL(pciMock, pci_device_cfg_read_u8(Eq(&dev), NotNull(), 463 NuvotonDevice::config)) 464 .WillOnce(DoAll(SetArgPointee<1>(defaultVal), Return(0))); 465 EXPECT_CALL(pciMock, 466 pci_device_cfg_write_u8( 467 Eq(&dev), defaultVal | NuvotonDevice::bridgeEnabled, 468 NuvotonDevice::config)) 469 .WillOnce(Return(EFAULT)); 470 471 EXPECT_THROW(nuvotonDevice.getBridge(&pciMock), std::system_error); 472 } 473 474 /* Read fails when attempting to disable the bridge */ 475 TEST(NuvotonBridgeTest, ReadDisableFail) 476 { 477 PciAccessMock pciMock; 478 struct pci_device dev; 479 std::vector<std::uint8_t> region(mockRegionSize); 480 481 constexpr std::uint8_t defaultVal = 0x40; 482 483 /* Only set standard expectations; not those from nuvotonDevice */ 484 expectSetup(pciMock, dev, &nuvotonDevice, region.data(), false); 485 486 { 487 InSequence in; 488 489 EXPECT_CALL(pciMock, pci_device_cfg_read_u8(Eq(&dev), NotNull(), 490 NuvotonDevice::config)) 491 .WillOnce(DoAll(SetArgPointee<1>(defaultVal), Return(0))); 492 EXPECT_CALL(pciMock, 493 pci_device_cfg_write_u8( 494 Eq(&dev), defaultVal | NuvotonDevice::bridgeEnabled, 495 NuvotonDevice::config)) 496 .WillOnce(Return(0)); 497 498 EXPECT_CALL(pciMock, pci_device_cfg_read_u8(Eq(&dev), NotNull(), 499 NuvotonDevice::config)) 500 .WillOnce(Return(EFAULT)); 501 } 502 503 nuvotonDevice.getBridge(&pciMock); 504 } 505 506 /* Write fails when attempting to disable the bridge */ 507 TEST(NuvotonBridgeTest, WriteDisableFail) 508 { 509 PciAccessMock pciMock; 510 struct pci_device dev; 511 std::vector<std::uint8_t> region(mockRegionSize); 512 513 constexpr std::uint8_t defaultVal = 0x40; 514 515 /* Only set standard expectations; not those from nuvotonDevice */ 516 expectSetup(pciMock, dev, &nuvotonDevice, region.data(), false); 517 518 { 519 InSequence in; 520 521 EXPECT_CALL(pciMock, pci_device_cfg_read_u8(Eq(&dev), NotNull(), 522 NuvotonDevice::config)) 523 .WillOnce(DoAll(SetArgPointee<1>(defaultVal), Return(0))); 524 EXPECT_CALL(pciMock, 525 pci_device_cfg_write_u8( 526 Eq(&dev), defaultVal | NuvotonDevice::bridgeEnabled, 527 NuvotonDevice::config)) 528 .WillOnce(Return(0)); 529 530 EXPECT_CALL(pciMock, pci_device_cfg_read_u8(Eq(&dev), NotNull(), 531 NuvotonDevice::config)) 532 .WillOnce(DoAll( 533 SetArgPointee<1>(defaultVal | NuvotonDevice::bridgeEnabled), 534 Return(0))); 535 EXPECT_CALL(pciMock, pci_device_cfg_write_u8(Eq(&dev), defaultVal, 536 NuvotonDevice::config)) 537 .WillOnce(Return(EFAULT)); 538 } 539 540 nuvotonDevice.getBridge(&pciMock); 541 } 542 543 /* Make sure the bridge gets enabled when needed */ 544 TEST(NuvotonBridgeTest, NotEnabledSuccess) 545 { 546 PciAccessMock pciMock; 547 struct pci_device dev; 548 std::vector<std::uint8_t> region(mockRegionSize); 549 550 expectSetup(pciMock, dev, &nuvotonDevice, region.data()); 551 nuvotonDevice.getBridge(&pciMock); 552 } 553 554 TEST(AspeedWriteTest, TooLarge) 555 { 556 PciAccessMock pciMock; 557 struct pci_device dev; 558 std::vector<std::uint8_t> region(mockRegionSize); 559 std::vector<std::uint8_t> data(0x10001); 560 561 expectSetup(pciMock, dev, &aspeedDevice, region.data()); 562 563 std::unique_ptr<PciBridgeIntf> bridge = aspeedDevice.getBridge(&pciMock); 564 EXPECT_THROW(bridge->write(stdplus::span<std::uint8_t>(data)), 565 ToolException); 566 } 567 568 TEST(AspeedWriteTest, Success) 569 { 570 PciAccessMock pciMock; 571 struct pci_device dev; 572 std::vector<std::uint8_t> region(mockRegionSize); 573 std::vector<std::uint8_t> data(0x10000); 574 575 std::generate(data.begin(), data.end(), std::rand); 576 577 expectSetup(pciMock, dev, &aspeedDevice, region.data()); 578 579 std::unique_ptr<PciBridgeIntf> bridge = aspeedDevice.getBridge(&pciMock); 580 bridge->write(stdplus::span<std::uint8_t>(data)); 581 582 EXPECT_THAT(stdplus::span<uint8_t>(®ion[0x10000], data.size()), 583 SpanEq(stdplus::span<uint8_t>(data))); 584 } 585 586 TEST(AspeedConfigureTest, Success) 587 { 588 PciAccessMock pciMock; 589 struct pci_device dev; 590 std::vector<std::uint8_t> region(mockRegionSize); 591 ipmi_flash::PciConfigResponse config{0x123bea51}; 592 593 expectSetup(pciMock, dev, &aspeedDevice, region.data()); 594 595 std::unique_ptr<PciBridgeIntf> bridge = aspeedDevice.getBridge(&pciMock); 596 bridge->configure(config); 597 598 auto configSpan = stdplus::raw::asSpan<uint8_t>(config); 599 EXPECT_THAT( 600 stdplus::span<uint8_t>(®ion[AspeedDevice::bridge], sizeof(config)), 601 SpanEq(configSpan)); 602 } 603 604 TEST(AspeedDataLengthTest, Success) 605 { 606 PciAccessMock pciMock; 607 struct pci_device dev; 608 std::vector<std::uint8_t> region(mockRegionSize); 609 610 expectSetup(pciMock, dev, &aspeedDevice, region.data()); 611 612 std::unique_ptr<PciBridgeIntf> bridge = aspeedDevice.getBridge(&pciMock); 613 EXPECT_EQ(bridge->getDataLength(), 0x10000); 614 } 615 616 /* Make sure config region is left alone if the bridge is already enabled */ 617 TEST(AspeedBridgeTest, AlreadyEnabledSuccess) 618 { 619 PciAccessMock pciMock; 620 struct pci_device dev; 621 std::vector<std::uint8_t> region(mockRegionSize); 622 623 constexpr std::uint8_t defaultVal = 0x42; 624 625 region[AspeedDevice::config] = defaultVal | AspeedDevice::bridgeEnabled; 626 627 expectSetup(pciMock, dev, &aspeedDevice, region.data()); 628 629 std::unique_ptr<PciBridgeIntf> bridge = aspeedDevice.getBridge(&pciMock); 630 631 { 632 std::vector<std::uint8_t> enabledRegion(mockRegionSize); 633 enabledRegion[AspeedDevice::config] = 634 defaultVal | AspeedDevice::bridgeEnabled; 635 EXPECT_THAT(region, ContainerEq(enabledRegion)); 636 } 637 638 bridge.reset(); 639 640 { 641 std::vector<std::uint8_t> disabledRegion(mockRegionSize); 642 disabledRegion[AspeedDevice::config] = defaultVal; 643 EXPECT_THAT(region, ContainerEq(disabledRegion)); 644 } 645 } 646 647 /* Make sure the bridge gets enabled when needed */ 648 TEST(AspeedBridgeTest, NotEnabledSuccess) 649 { 650 PciAccessMock pciMock; 651 struct pci_device dev; 652 std::vector<std::uint8_t> region(mockRegionSize); 653 654 constexpr std::uint8_t defaultVal = 0x42; 655 656 region[AspeedDevice::config] = defaultVal; 657 658 expectSetup(pciMock, dev, &aspeedDevice, region.data()); 659 660 std::unique_ptr<PciBridgeIntf> bridge = aspeedDevice.getBridge(&pciMock); 661 662 { 663 std::vector<std::uint8_t> enabledRegion(mockRegionSize); 664 enabledRegion[AspeedDevice::config] = 665 defaultVal | AspeedDevice::bridgeEnabled; 666 EXPECT_THAT(region, ContainerEq(enabledRegion)); 667 } 668 669 bridge.reset(); 670 671 { 672 std::vector<std::uint8_t> disabledRegion(mockRegionSize); 673 disabledRegion[AspeedDevice::config] = defaultVal; 674 EXPECT_THAT(region, ContainerEq(disabledRegion)); 675 } 676 } 677 678 } // namespace 679 } // namespace host_tool 680