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