blob: 9f72e78ddb41bd3a14b0df3f82176a1c1f921bc1 [file] [log] [blame]
Benjamin Faire5aafa52020-06-05 21:04:24 -07001/*
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
Tim Lee2d57d522023-09-18 11:47:53 +080017#include "config.h"
18
Patrick Ventureb5bf0fc2019-05-03 14:33:49 -070019#pragma once
20
Benjamin Faire5aafa52020-06-05 21:04:24 -070021#include "data.hpp"
Benjamin Fairc04c2c52020-06-05 09:14:44 -070022#include "internal/sys.hpp"
Benjamin Faire5aafa52020-06-05 21:04:24 -070023#include "pciaccess.hpp"
Patrick Ventureb5bf0fc2019-05-03 14:33:49 -070024
Benjamin Fairc04c2c52020-06-05 09:14:44 -070025#include <linux/pci_regs.h>
26
Patrick Williams28c00d62022-04-27 08:37:13 -050027#include <span>
Patrick Ventureb5bf0fc2019-05-03 14:33:49 -070028
Benjamin Faire5aafa52020-06-05 21:04:24 -070029// Some versions of the linux/pci_regs.h header don't define this
Benjamin Fairc04c2c52020-06-05 09:14:44 -070030#ifndef PCI_STD_NUM_BARS
31#define PCI_STD_NUM_BARS 6
32#endif // !PCI_STD_NUM_BARS
33
Patrick Ventureb5bf0fc2019-05-03 14:33:49 -070034namespace host_tool
35{
36
Benjamin Faire5aafa52020-06-05 21:04:24 -070037class PciBridgeIntf
Patrick Ventureb5bf0fc2019-05-03 14:33:49 -070038{
39 public:
Benjamin Faire5aafa52020-06-05 21:04:24 -070040 virtual ~PciBridgeIntf() = default;
Patrick Ventureb5bf0fc2019-05-03 14:33:49 -070041
Patrick Williams28c00d62022-04-27 08:37:13 -050042 virtual void write(const std::span<const std::uint8_t> data) = 0;
Benjamin Faire5aafa52020-06-05 21:04:24 -070043 virtual void configure(const ipmi_flash::PciConfigResponse& config) = 0;
44
45 virtual std::size_t getDataLength() = 0;
Patrick Ventureb5bf0fc2019-05-03 14:33:49 -070046};
47
Benjamin Faire5aafa52020-06-05 21:04:24 -070048class PciAccessBridge : public PciBridgeIntf
Patrick Ventureb5bf0fc2019-05-03 14:33:49 -070049{
50 public:
Benjamin Faire5aafa52020-06-05 21:04:24 -070051 virtual ~PciAccessBridge();
52
Patrick Williams28c00d62022-04-27 08:37:13 -050053 virtual void write(const std::span<const std::uint8_t> data) override;
Patrick Williams42a44c22024-08-16 15:21:32 -040054 virtual void configure(const ipmi_flash::PciConfigResponse&) override {};
Benjamin Faire5aafa52020-06-05 21:04:24 -070055
56 std::size_t getDataLength() override
Patrick Ventureb5bf0fc2019-05-03 14:33:49 -070057 {
Benjamin Faire5aafa52020-06-05 21:04:24 -070058 return dataLength;
Patrick Ventureb5bf0fc2019-05-03 14:33:49 -070059 }
60
Benjamin Faire5aafa52020-06-05 21:04:24 -070061 protected:
62 /**
63 * Finds the PCI device matching @a match and saves a reference to it in @a
64 * dev. Also maps the memory region described in BAR number @a bar to
65 * address @a addr,
66 */
67 PciAccessBridge(const struct pci_id_match* match, int bar,
68 std::size_t dataOffset, std::size_t dataLength,
69 const PciAccess* pci);
Patrick Ventureb5bf0fc2019-05-03 14:33:49 -070070
Benjamin Faire5aafa52020-06-05 21:04:24 -070071 struct pci_device* dev = nullptr;
72 std::uint8_t* addr = nullptr;
73 std::size_t size = 0;
Benjamin Fairc04c2c52020-06-05 09:14:44 -070074
Patrick Ventureb5bf0fc2019-05-03 14:33:49 -070075 private:
Benjamin Faire5aafa52020-06-05 21:04:24 -070076 std::size_t dataOffset;
77 std::size_t dataLength;
78
79 protected:
80 const PciAccess* pci;
81};
82
83class NuvotonPciBridge : public PciAccessBridge
84{
85 public:
Willy Tu49dd8ce2020-11-03 19:32:34 -080086 explicit NuvotonPciBridge(const PciAccess* pciAccess,
Willy Tu8a9de242020-10-30 11:00:21 -070087 bool skipBridgeDisable = false) :
Willy Tu49dd8ce2020-11-03 19:32:34 -080088 PciAccessBridge(&match, bar, dataOffset, dataLength, pciAccess),
Willy Tu8a9de242020-10-30 11:00:21 -070089 skipBridgeDisable(skipBridgeDisable)
Benjamin Fairc1a30c02020-06-09 11:46:34 -070090 {
91 enableBridge();
92 }
Benjamin Faire5aafa52020-06-05 21:04:24 -070093
94 ~NuvotonPciBridge()
Benjamin Fairc1a30c02020-06-09 11:46:34 -070095 {
Willy Tu8a9de242020-10-30 11:00:21 -070096 if (!skipBridgeDisable)
97 disableBridge();
Benjamin Fairc1a30c02020-06-09 11:46:34 -070098 }
Benjamin Faire5aafa52020-06-05 21:04:24 -070099
100 private:
101 static constexpr std::uint32_t vid = 0x1050;
Tim Lee2d57d522023-09-18 11:47:53 +0800102 static constexpr std::uint32_t did = NUVOTON_PCI_DID;
Benjamin Faire5aafa52020-06-05 21:04:24 -0700103 static constexpr int bar = 0;
104 static constexpr struct pci_id_match match
Benjamin Fairc04c2c52020-06-05 09:14:44 -0700105 {
Willy Tub487eb42021-09-16 21:44:43 -0700106 vid, did, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0
Benjamin Faire5aafa52020-06-05 21:04:24 -0700107 };
108
109 static constexpr pciaddr_t bridge = 0x04;
110 static constexpr std::uint8_t bridgeEnabled = 0x02;
111
112 static constexpr std::size_t dataOffset = 0x0;
113 static constexpr std::size_t dataLength = 0x4000;
Benjamin Fairc1a30c02020-06-09 11:46:34 -0700114
115 void enableBridge();
116 void disableBridge();
Willy Tu8a9de242020-10-30 11:00:21 -0700117
118 bool skipBridgeDisable;
Benjamin Faire5aafa52020-06-05 21:04:24 -0700119};
120
121class AspeedPciBridge : public PciAccessBridge
122{
123 public:
Willy Tu49dd8ce2020-11-03 19:32:34 -0800124 explicit AspeedPciBridge(const PciAccess* pciAccess,
Willy Tu8a9de242020-10-30 11:00:21 -0700125 bool skipBridgeDisable = false) :
Willy Tu49dd8ce2020-11-03 19:32:34 -0800126 PciAccessBridge(&match, bar, dataOffset, dataLength, pciAccess),
Willy Tu8a9de242020-10-30 11:00:21 -0700127 skipBridgeDisable(skipBridgeDisable)
Benjamin Faire5aafa52020-06-05 21:04:24 -0700128 {
129 enableBridge();
Benjamin Fairc04c2c52020-06-05 09:14:44 -0700130 }
131
Benjamin Faire5aafa52020-06-05 21:04:24 -0700132 ~AspeedPciBridge()
Benjamin Fairc04c2c52020-06-05 09:14:44 -0700133 {
Willy Tu8a9de242020-10-30 11:00:21 -0700134 if (!skipBridgeDisable)
135 disableBridge();
Benjamin Fairc04c2c52020-06-05 09:14:44 -0700136 }
Benjamin Faire5aafa52020-06-05 21:04:24 -0700137
138 void configure(const ipmi_flash::PciConfigResponse& configResp) override;
139
140 private:
141 static constexpr std::uint32_t vid = 0x1a03;
142 static constexpr std::uint32_t did = 0x2000;
143 static constexpr int bar = 1;
144 static constexpr struct pci_id_match match
145 {
Willy Tub487eb42021-09-16 21:44:43 -0700146 vid, did, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0
Benjamin Faire5aafa52020-06-05 21:04:24 -0700147 };
148
149 static constexpr std::size_t config = 0x0f000;
150 static constexpr std::size_t bridge = 0x0f004;
151 static constexpr std::uint32_t bridgeEnabled = 0x1;
152
153 static constexpr std::size_t dataOffset = 0x10000;
154 static constexpr std::size_t dataLength = 0x10000;
155
156 void enableBridge();
157 void disableBridge();
Willy Tu8a9de242020-10-30 11:00:21 -0700158
159 bool skipBridgeDisable;
Patrick Ventureb5bf0fc2019-05-03 14:33:49 -0700160};
161
162} // namespace host_tool