initial config_read routing

Change-Id: I5d9877e0e05a37e2e719f732e2ff5abc0332af1d
Esse commit está contido em:
Christopher Anderson
2017-08-17 16:59:13 -07:00
commit dcf80c83c7
3 arquivos alterados com 80 adições e 0 exclusões
+54
Ver Arquivo
@@ -330,6 +330,50 @@ mx_status_t sys_pci_get_nth_device(mx_handle_t hrsrc,
return MX_OK;
}
mx_status_t sys_pci_config_read(mx_handle_t handle, uint16_t offset, size_t width,
user_ptr<uint32_t> out_val) {
mxtl::RefPtr<PciDeviceDispatcher> pci_device;
mxtl::RefPtr<Dispatcher> dispatcher;
if (handle == MX_HANDLE_INVALID) {
return MX_ERR_BAD_HANDLE;
}
if (out_val.get() == nullptr) {
return MX_ERR_INVALID_ARGS;
}
// The only valid reads in the device dependent config region following the header.
// For header information callers are expected to use the get_device_info() protocol
// method.
if (offset < PCIE_STANDARD_CONFIG_HDR_SIZE) {
return MX_ERR_OUT_OF_RANGE;
}
// Get the PciDeviceDispatcher from the handle passed in via the pci protocol
auto up = ProcessDispatcher::GetCurrent();
mx_status_t status = up->GetDispatcherWithRights(handle, MX_RIGHT_READ | MX_RIGHT_WRITE,
&pci_device);
if (status != MX_OK) {
return status;
}
// Based on the width passed in we can use the type safety of the PciConfig layer
// to ensure we're getting correctly sized data back and return errors in the PIO
// cases.
auto config = pci_device->device()->config();
switch(width) {
case 8u: return out_val.copy_to_user(static_cast<uint32_t>(config->Read(PciReg8(offset))));
case 16u: return out_val.copy_to_user(static_cast<uint32_t>(config->Read(PciReg16(offset))));
case 32u: return out_val.copy_to_user(config->Read(PciReg32(offset)));
default: return MX_ERR_INVALID_ARGS;
}
// If we reached this point then the width was invalid.
return MX_ERR_INVALID_ARGS;
}
/* This is a transitional method to bootstrap legacy PIO access before
* PCI moves to userspace.
*/
@@ -713,6 +757,16 @@ mx_status_t sys_pci_add_subtract_io_range(mx_handle_t handle, bool mmio, uint64_
return MX_ERR_NOT_SUPPORTED;
}
mx_status_t sys_pci_config_read(mx_handle_t handle, uint16_t offset, size_t width,
user_ptr<uint32_t> out_val) {
return MX_ERR_NOT_SUPPORTED;
}
mx_status_t sys_pci_cfg_pio_rw(mx_handle_t handle, uint8_t bus, uint8_t dev, uint8_t func,
uint8_t offset, user_ptr<uint32_t> val, size_t width, bool write) {
return MX_ERR_NOT_SUPPORTED;
}
mx_status_t sys_pci_get_nth_device(mx_handle_t, uint32_t, user_ptr<mx_pcie_device_info_t>,
user_ptr<mx_handle_t>) {
return MX_ERR_NOT_SUPPORTED;
+22
Ver Arquivo
@@ -51,6 +51,28 @@ static mx_status_t do_resource_bookkeeping(mx_pci_resource_t* res) {
return status;
}
// These reads are proxied directly over to the device's PciConfig object so the validity of the
// widths and offsets will be validated on that end and then trickle back to this level of the
// protocol.
static mx_status_t pci_config_read(void* ctx, uint16_t offset, size_t width, uint32_t* out_val) {
kpci_device_t* device = ctx;
return mx_pci_config_read(device->handle, offset, width, out_val);
}
static mx_status_t pci_config_read8(void* ctx, uint16_t offset, uint8_t* out_val) {
return pci_config_read(ctx, offset, 8u, (uint32_t*)out_val);
}
static mx_status_t pci_config_read16(void* ctx, uint16_t offset, uint16_t* out_val) {
return pci_config_read(ctx, offset, 16u, (uint32_t*)out_val);
}
static mx_status_t pci_config_read32(void* ctx, uint16_t offset, uint32_t* out_val) {
return pci_config_read(ctx, offset, 32u, out_val);
}
static mx_status_t pci_get_resource(void* ctx, uint32_t res_id, mx_pci_resource_t* out_res) {
mx_status_t status = MX_OK;
+4
Ver Arquivo
@@ -566,6 +566,10 @@ syscall pci_reset_device
(handle: mx_handle_t)
returns (mx_status_t);
syscall pci_config_read
(handle: mx_handle_t, offset: uint16_t, width: size_t, out_val: uint32_t[1] OUT)
returns (mx_status_t);
syscall pci_cfg_pio_rw
(handle: mx_handle_t, bus: uint8_t, dev: uint8_t, func: uint8_t, offset: uint8_t,
val: uint32_t[1] OUT, width: size_t, write: bool)