| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 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 |  | 
| Patrick Venture | b5bf0fc | 2019-05-03 14:33:49 -0700 | [diff] [blame] | 17 | #pragma once | 
 | 18 |  | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 19 | #include "data.hpp" | 
| Benjamin Fair | c04c2c5 | 2020-06-05 09:14:44 -0700 | [diff] [blame] | 20 | #include "internal/sys.hpp" | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 21 | #include "pciaccess.hpp" | 
| Patrick Venture | b5bf0fc | 2019-05-03 14:33:49 -0700 | [diff] [blame] | 22 |  | 
| Benjamin Fair | c04c2c5 | 2020-06-05 09:14:44 -0700 | [diff] [blame] | 23 | #include <linux/pci_regs.h> | 
 | 24 |  | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 25 | #include <stdplus/types.hpp> | 
| Patrick Venture | b5bf0fc | 2019-05-03 14:33:49 -0700 | [diff] [blame] | 26 |  | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 27 | // Some versions of the linux/pci_regs.h header don't define this | 
| Benjamin Fair | c04c2c5 | 2020-06-05 09:14:44 -0700 | [diff] [blame] | 28 | #ifndef PCI_STD_NUM_BARS | 
 | 29 | #define PCI_STD_NUM_BARS 6 | 
 | 30 | #endif // !PCI_STD_NUM_BARS | 
 | 31 |  | 
| Patrick Venture | b5bf0fc | 2019-05-03 14:33:49 -0700 | [diff] [blame] | 32 | namespace host_tool | 
 | 33 | { | 
 | 34 |  | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 35 | class PciBridgeIntf | 
| Patrick Venture | b5bf0fc | 2019-05-03 14:33:49 -0700 | [diff] [blame] | 36 | { | 
 | 37 |   public: | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 38 |     virtual ~PciBridgeIntf() = default; | 
| Patrick Venture | b5bf0fc | 2019-05-03 14:33:49 -0700 | [diff] [blame] | 39 |  | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 40 |     virtual void write(const stdplus::span<const std::uint8_t> data) = 0; | 
 | 41 |     virtual void configure(const ipmi_flash::PciConfigResponse& config) = 0; | 
 | 42 |  | 
 | 43 |     virtual std::size_t getDataLength() = 0; | 
| Patrick Venture | b5bf0fc | 2019-05-03 14:33:49 -0700 | [diff] [blame] | 44 | }; | 
 | 45 |  | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 46 | class PciAccessBridge : public PciBridgeIntf | 
| Patrick Venture | b5bf0fc | 2019-05-03 14:33:49 -0700 | [diff] [blame] | 47 | { | 
 | 48 |   public: | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 49 |     virtual ~PciAccessBridge(); | 
 | 50 |  | 
 | 51 |     virtual void write(const stdplus::span<const std::uint8_t> data) override; | 
| Willy Tu | b487eb4 | 2021-09-16 21:44:43 -0700 | [diff] [blame] | 52 |     virtual void configure(const ipmi_flash::PciConfigResponse&) override{}; | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 53 |  | 
 | 54 |     std::size_t getDataLength() override | 
| Patrick Venture | b5bf0fc | 2019-05-03 14:33:49 -0700 | [diff] [blame] | 55 |     { | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 56 |         return dataLength; | 
| Patrick Venture | b5bf0fc | 2019-05-03 14:33:49 -0700 | [diff] [blame] | 57 |     } | 
 | 58 |  | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 59 |   protected: | 
 | 60 |     /** | 
 | 61 |      * Finds the PCI device matching @a match and saves a reference to it in @a | 
 | 62 |      * dev. Also maps the memory region described in BAR number @a bar to | 
 | 63 |      * address @a addr, | 
 | 64 |      */ | 
 | 65 |     PciAccessBridge(const struct pci_id_match* match, int bar, | 
 | 66 |                     std::size_t dataOffset, std::size_t dataLength, | 
 | 67 |                     const PciAccess* pci); | 
| Patrick Venture | b5bf0fc | 2019-05-03 14:33:49 -0700 | [diff] [blame] | 68 |  | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 69 |     struct pci_device* dev = nullptr; | 
 | 70 |     std::uint8_t* addr = nullptr; | 
 | 71 |     std::size_t size = 0; | 
| Benjamin Fair | c04c2c5 | 2020-06-05 09:14:44 -0700 | [diff] [blame] | 72 |  | 
| Patrick Venture | b5bf0fc | 2019-05-03 14:33:49 -0700 | [diff] [blame] | 73 |   private: | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 74 |     std::size_t dataOffset; | 
 | 75 |     std::size_t dataLength; | 
 | 76 |  | 
 | 77 |   protected: | 
 | 78 |     const PciAccess* pci; | 
 | 79 | }; | 
 | 80 |  | 
 | 81 | class NuvotonPciBridge : public PciAccessBridge | 
 | 82 | { | 
 | 83 |   public: | 
| Willy Tu | 49dd8ce | 2020-11-03 19:32:34 -0800 | [diff] [blame] | 84 |     explicit NuvotonPciBridge(const PciAccess* pciAccess, | 
| Willy Tu | 8a9de24 | 2020-10-30 11:00:21 -0700 | [diff] [blame] | 85 |                               bool skipBridgeDisable = false) : | 
| Willy Tu | 49dd8ce | 2020-11-03 19:32:34 -0800 | [diff] [blame] | 86 |         PciAccessBridge(&match, bar, dataOffset, dataLength, pciAccess), | 
| Willy Tu | 8a9de24 | 2020-10-30 11:00:21 -0700 | [diff] [blame] | 87 |         skipBridgeDisable(skipBridgeDisable) | 
| Benjamin Fair | c1a30c0 | 2020-06-09 11:46:34 -0700 | [diff] [blame] | 88 |     { | 
 | 89 |         enableBridge(); | 
 | 90 |     } | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 91 |  | 
 | 92 |     ~NuvotonPciBridge() | 
| Benjamin Fair | c1a30c0 | 2020-06-09 11:46:34 -0700 | [diff] [blame] | 93 |     { | 
| Willy Tu | 8a9de24 | 2020-10-30 11:00:21 -0700 | [diff] [blame] | 94 |         if (!skipBridgeDisable) | 
 | 95 |             disableBridge(); | 
| Benjamin Fair | c1a30c0 | 2020-06-09 11:46:34 -0700 | [diff] [blame] | 96 |     } | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 97 |  | 
 | 98 |   private: | 
 | 99 |     static constexpr std::uint32_t vid = 0x1050; | 
 | 100 |     static constexpr std::uint32_t did = 0x0750; | 
 | 101 |     static constexpr int bar = 0; | 
 | 102 |     static constexpr struct pci_id_match match | 
| Benjamin Fair | c04c2c5 | 2020-06-05 09:14:44 -0700 | [diff] [blame] | 103 |     { | 
| Willy Tu | b487eb4 | 2021-09-16 21:44:43 -0700 | [diff] [blame] | 104 |         vid, did, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0 | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 105 |     }; | 
 | 106 |  | 
 | 107 |     static constexpr pciaddr_t bridge = 0x04; | 
 | 108 |     static constexpr std::uint8_t bridgeEnabled = 0x02; | 
 | 109 |  | 
 | 110 |     static constexpr std::size_t dataOffset = 0x0; | 
 | 111 |     static constexpr std::size_t dataLength = 0x4000; | 
| Benjamin Fair | c1a30c0 | 2020-06-09 11:46:34 -0700 | [diff] [blame] | 112 |  | 
 | 113 |     void enableBridge(); | 
 | 114 |     void disableBridge(); | 
| Willy Tu | 8a9de24 | 2020-10-30 11:00:21 -0700 | [diff] [blame] | 115 |  | 
 | 116 |     bool skipBridgeDisable; | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 117 | }; | 
 | 118 |  | 
 | 119 | class AspeedPciBridge : public PciAccessBridge | 
 | 120 | { | 
 | 121 |   public: | 
| Willy Tu | 49dd8ce | 2020-11-03 19:32:34 -0800 | [diff] [blame] | 122 |     explicit AspeedPciBridge(const PciAccess* pciAccess, | 
| Willy Tu | 8a9de24 | 2020-10-30 11:00:21 -0700 | [diff] [blame] | 123 |                              bool skipBridgeDisable = false) : | 
| Willy Tu | 49dd8ce | 2020-11-03 19:32:34 -0800 | [diff] [blame] | 124 |         PciAccessBridge(&match, bar, dataOffset, dataLength, pciAccess), | 
| Willy Tu | 8a9de24 | 2020-10-30 11:00:21 -0700 | [diff] [blame] | 125 |         skipBridgeDisable(skipBridgeDisable) | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 126 |     { | 
 | 127 |         enableBridge(); | 
| Benjamin Fair | c04c2c5 | 2020-06-05 09:14:44 -0700 | [diff] [blame] | 128 |     } | 
 | 129 |  | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 130 |     ~AspeedPciBridge() | 
| Benjamin Fair | c04c2c5 | 2020-06-05 09:14:44 -0700 | [diff] [blame] | 131 |     { | 
| Willy Tu | 8a9de24 | 2020-10-30 11:00:21 -0700 | [diff] [blame] | 132 |         if (!skipBridgeDisable) | 
 | 133 |             disableBridge(); | 
| Benjamin Fair | c04c2c5 | 2020-06-05 09:14:44 -0700 | [diff] [blame] | 134 |     } | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 135 |  | 
 | 136 |     void configure(const ipmi_flash::PciConfigResponse& configResp) override; | 
 | 137 |  | 
 | 138 |   private: | 
 | 139 |     static constexpr std::uint32_t vid = 0x1a03; | 
 | 140 |     static constexpr std::uint32_t did = 0x2000; | 
 | 141 |     static constexpr int bar = 1; | 
 | 142 |     static constexpr struct pci_id_match match | 
 | 143 |     { | 
| Willy Tu | b487eb4 | 2021-09-16 21:44:43 -0700 | [diff] [blame] | 144 |         vid, did, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0 | 
| Benjamin Fair | e5aafa5 | 2020-06-05 21:04:24 -0700 | [diff] [blame] | 145 |     }; | 
 | 146 |  | 
 | 147 |     static constexpr std::size_t config = 0x0f000; | 
 | 148 |     static constexpr std::size_t bridge = 0x0f004; | 
 | 149 |     static constexpr std::uint32_t bridgeEnabled = 0x1; | 
 | 150 |  | 
 | 151 |     static constexpr std::size_t dataOffset = 0x10000; | 
 | 152 |     static constexpr std::size_t dataLength = 0x10000; | 
 | 153 |  | 
 | 154 |     void enableBridge(); | 
 | 155 |     void disableBridge(); | 
| Willy Tu | 8a9de24 | 2020-10-30 11:00:21 -0700 | [diff] [blame] | 156 |  | 
 | 157 |     bool skipBridgeDisable; | 
| Patrick Venture | b5bf0fc | 2019-05-03 14:33:49 -0700 | [diff] [blame] | 158 | }; | 
 | 159 |  | 
 | 160 | } // namespace host_tool |