forked from xinyu391/zircon
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplatform-bus.h
More file actions
148 lines (114 loc) · 5.29 KB
/
platform-bus.h
File metadata and controls
148 lines (114 loc) · 5.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <ddk/device.h>
#include <ddktl/device.h>
#include <ddktl/protocol/clk.h>
#include <ddktl/protocol/gpio-impl.h>
#include <ddktl/protocol/i2c-impl.h>
#include <ddktl/protocol/iommu.h>
#include <ddktl/protocol/platform-bus.h>
#include <fbl/array.h>
#include <fbl/intrusive_wavl_tree.h>
#include <fbl/mutex.h>
#include <fbl/unique_ptr.h>
#include <fbl/vector.h>
#include <lib/sync/completion.h>
#include <lib/zx/handle.h>
#include <lib/zx/vmo.h>
#include <stdint.h>
#include <threads.h>
#include <zircon/types.h>
#include "platform-device.h"
#include "platform-protocol-device.h"
#include "platform-i2c.h"
#include "proxy-protocol.h"
namespace platform_bus {
class PlatformBus;
using PlatformBusType = ddk::Device<PlatformBus, ddk::GetProtocolable>;
// This is the main class for the platform bus driver.
class PlatformBus : public PlatformBusType, public ddk::PlatformBusProtocol<PlatformBus>,
public ddk::IommuProtocol<PlatformBus> {
public:
static zx_status_t Create(zx_device_t* parent, const char* name, zx::vmo zbi);
zx_status_t Proxy(platform_proxy_args_t* args);
// Device protocol implementation.
zx_status_t DdkGetProtocol(uint32_t proto_id, void* out);
void DdkRelease();
// Platform bus protocol implementation.
zx_status_t DeviceAdd(const pbus_dev_t* dev);
zx_status_t ProtocolDeviceAdd(uint32_t proto_id, const pbus_dev_t* dev);
zx_status_t RegisterProtocol(uint32_t proto_id, void* protocol, platform_proxy_cb_t proxy_cb,
void* proxy_cb_cookie);
const char* GetBoardName();
zx_status_t SetBoardInfo(const pbus_board_info_t* info);
// IOMMU protocol implementation.
zx_status_t IommuGetBti(uint32_t iommu_index, uint32_t bti_id, zx_handle_t* out_handle);
// Returns the resource handle to be used for creating MMIO regions and IRQs.
// Currently this just returns the root resource, but we may change this to a more
// limited resource in the future.
zx_handle_t GetResource() const { return get_root_resource(); }
// Used by PlatformDevice to queue I2C transactions on an I2C bus.
zx_status_t I2cTransact(uint32_t txid, rpc_i2c_req_t* req, const pbus_i2c_channel_t* channel,
zx_handle_t channel_handle);
// Helper for PlatformDevice.
zx_status_t GetBoardInfo(pdev_board_info_t* out_info);
zx_status_t GetZbiMetadata(uint32_t type, uint32_t extra, const void** out_metadata,
uint32_t* out_size);
// Protocol accessors for PlatformDevice.
inline ddk::ClkProtocolProxy* clk() const { return clk_.get(); }
inline ddk::GpioImplProtocolProxy* gpio() const { return gpio_.get(); }
inline ddk::I2cImplProtocolProxy* i2c() const { return i2c_.get(); }
private:
// This class is a wrapper for a platform_proxy_cb_t added via pbus_register_protocol().
// It also is the element type for the proto_proxys_ WAVL tree.
class ProtoProxy : public fbl::WAVLTreeContainable<fbl::unique_ptr<ProtoProxy>> {
public:
ProtoProxy(uint32_t proto_id, ddk::AnyProtocol* protocol, platform_proxy_cb_t proxy_cb,
void* proxy_cb_cookie)
: proto_id_(proto_id), protocol_(*protocol), proxy_cb_(proxy_cb),
proxy_cb_cookie_(proxy_cb_cookie) {}
inline uint32_t GetKey() const { return proto_id_; }
inline void GetProtocol(void* out) const { memcpy(out, &protocol_, sizeof(protocol_)); }
inline void Proxy(platform_proxy_args_t* args) {
proxy_cb_(args, proxy_cb_cookie_);
}
private:
const uint32_t proto_id_;
ddk::AnyProtocol protocol_;
const platform_proxy_cb_t proxy_cb_;
void* proxy_cb_cookie_;
};
explicit PlatformBus(zx_device_t* parent);
DISALLOW_COPY_ASSIGN_AND_MOVE(PlatformBus);
zx_status_t Init(zx::vmo zbi);
// Reads the platform ID and driver metadata records from the boot image.
zx_status_t ReadZbi(zx::vmo zbi);
zx_status_t I2cInit(i2c_impl_protocol_t* i2c);
pdev_board_info_t board_info_;
// Protocols that are optionally provided by the board driver.
fbl::unique_ptr<ddk::ClkProtocolProxy> clk_;
fbl::unique_ptr<ddk::GpioImplProtocolProxy> gpio_;
fbl::unique_ptr<ddk::IommuProtocolProxy> iommu_;
fbl::unique_ptr<ddk::I2cImplProtocolProxy> i2c_;
// Completion used by WaitProtocol().
sync_completion_t proto_completion_ __TA_GUARDED(proto_completion_mutex_);
// Protects proto_completion_.
fbl::Mutex proto_completion_mutex_;
// Metadata extracted from ZBI.
fbl::Array<uint8_t> metadata_;
// List of I2C buses.
fbl::Vector<fbl::unique_ptr<PlatformI2cBus>> i2c_buses_;
// Dummy IOMMU.
zx::handle iommu_handle_;
fbl::WAVLTree<uint32_t, fbl::unique_ptr<ProtoProxy>> proto_proxys_
__TA_GUARDED(proto_proxys_mutex_);
// Protects proto_proxys_.
fbl::Mutex proto_proxys_mutex_;
};
} // namespace platform_bus
__BEGIN_CDECLS
zx_status_t platform_bus_create(void* ctx, zx_device_t* parent, const char* name,
const char* args, zx_handle_t rpc_channel);
__END_CDECLS