1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #pragma once
6
7 #include <ddk/protocol/pci.h>
8 #include <ddk/mmio-buffer.h>
9
10 __BEGIN_CDECLS;
11
pci_map_bar_buffer(const pci_protocol_t * pci,uint32_t bar_id,uint32_t cache_policy,mmio_buffer_t * buffer)12 static inline zx_status_t pci_map_bar_buffer(const pci_protocol_t* pci, uint32_t bar_id,
13 uint32_t cache_policy, mmio_buffer_t* buffer) {
14
15 zx_pci_bar_t bar;
16
17 zx_status_t status = pci->ops->get_bar(pci->ctx, bar_id, &bar);
18 if (status != ZX_OK) {
19 return status;
20 }
21 // TODO(cja): PIO may be mappable on non-x86 architectures
22 if (bar.type == ZX_PCI_BAR_TYPE_PIO || bar.handle == ZX_HANDLE_INVALID) {
23 return ZX_ERR_WRONG_TYPE;
24 }
25 return mmio_buffer_init(buffer, 0, bar.size, bar.handle, cache_policy);
26 }
27
pci_config_read8(const pci_protocol_t * pci,uint16_t offset,uint8_t * value)28 static inline zx_status_t pci_config_read8(const pci_protocol_t* pci,
29 uint16_t offset, uint8_t* value) {
30 uint32_t value_;
31 zx_status_t st = pci->ops->config_read(pci->ctx, offset, sizeof(uint8_t), &value_);
32 *value = value_ & UINT8_MAX;
33 return st;
34 }
35
pci_config_read16(const pci_protocol_t * pci,uint16_t offset,uint16_t * value)36 static inline zx_status_t pci_config_read16(const pci_protocol_t* pci,
37 uint16_t offset, uint16_t* value) {
38 uint32_t value_;
39 zx_status_t st = pci->ops->config_read(pci->ctx, offset, sizeof(uint16_t), &value_);
40 *value = value_ & UINT16_MAX;
41 return st;
42 }
43
pci_config_read32(const pci_protocol_t * pci,uint16_t offset,uint32_t * value)44 static inline zx_status_t pci_config_read32(const pci_protocol_t* pci,
45 uint16_t offset, uint32_t* value) {
46 return pci->ops->config_read(pci->ctx, offset, sizeof(uint32_t), value);
47 }
48
pci_config_write8(const pci_protocol_t * pci,uint16_t offset,uint8_t value)49 static inline zx_status_t pci_config_write8(const pci_protocol_t* pci,
50 uint16_t offset, uint8_t value) {
51 return pci->ops->config_write(pci->ctx, offset, sizeof(uint8_t), value);
52 }
53
pci_config_write16(const pci_protocol_t * pci,uint16_t offset,uint16_t value)54 static inline zx_status_t pci_config_write16(const pci_protocol_t* pci,
55 uint16_t offset, uint16_t value) {
56 return pci->ops->config_write(pci->ctx, offset, sizeof(uint16_t), value);
57 }
58
pci_config_write32(const pci_protocol_t * pci,uint16_t offset,uint32_t value)59 static inline zx_status_t pci_config_write32(const pci_protocol_t* pci,
60 uint16_t offset, uint32_t value) {
61 return pci->ops->config_write(pci->ctx, offset, sizeof(uint32_t), value);
62 }
63
pci_get_first_capability(const pci_protocol_t * pci,uint8_t type)64 static inline uint8_t pci_get_first_capability(const pci_protocol_t* pci, uint8_t type) {
65 // the next_capability method will always look at the second byte next
66 // pointer to fetch the next capability. By offsetting the CapPtr field
67 // by -1 we can pretend we're working with a normal capability entry
68 return pci_get_next_capability(pci, PCI_CFG_CAPABILITIES_PTR - 1u, type);
69 }
70
71 __END_CDECLS;
72