Compare commits
11 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
bf7ed8f9f7 | |
![]() |
b2d0bf8c5f | |
![]() |
ddd4ba306e | |
![]() |
6f14ffe92b | |
![]() |
760282ee36 | |
![]() |
a2ea99857b | |
![]() |
a25ff31416 | |
![]() |
45beb44bdc | |
![]() |
21b508ac31 | |
![]() |
f8ba0ccf23 | |
![]() |
45c16a6c4e |
35
Kconfig
35
Kconfig
|
@ -1669,6 +1669,41 @@ config DEBUG_WATCHDOG_INFO
|
||||||
Enable watchdog time informational output to SYSLOG.
|
Enable watchdog time informational output to SYSLOG.
|
||||||
|
|
||||||
endif # DEBUG_WATCHDOG
|
endif # DEBUG_WATCHDOG
|
||||||
|
|
||||||
|
config DEBUG_PCIE
|
||||||
|
bool "PCI-E Debug Features"
|
||||||
|
default n
|
||||||
|
depends on PCIE
|
||||||
|
---help---
|
||||||
|
Enable PCIE driver debug features.
|
||||||
|
|
||||||
|
Support for this debug option is architecture-specific and may not
|
||||||
|
be available for some MCUs.
|
||||||
|
|
||||||
|
if DEBUG_PCIE
|
||||||
|
|
||||||
|
config DEBUG_PCIE_ERROR
|
||||||
|
bool "PCI-E Error Output"
|
||||||
|
default n
|
||||||
|
depends on DEBUG_ERROR
|
||||||
|
---help---
|
||||||
|
Enable PCI-E driver error output to SYSLOG.
|
||||||
|
|
||||||
|
config DEBUG_PCIE_WARN
|
||||||
|
bool "PCI-E Warnings Output"
|
||||||
|
default n
|
||||||
|
depends on DEBUG_WARN
|
||||||
|
---help---
|
||||||
|
Enable PCI-E driver warning output to SYSLOG.
|
||||||
|
|
||||||
|
config DEBUG_PCIE_INFO
|
||||||
|
bool "PCI-E Informational Output"
|
||||||
|
default n
|
||||||
|
depends on DEBUG_INFO
|
||||||
|
---help---
|
||||||
|
Enable PCI-E driver informational output to SYSLOG.
|
||||||
|
|
||||||
|
endif # DEBUG_PCIE
|
||||||
endif # DEBUG_FEATURES
|
endif # DEBUG_FEATURES
|
||||||
|
|
||||||
config ARCH_HAVE_STACKCHECK
|
config ARCH_HAVE_STACKCHECK
|
||||||
|
|
|
@ -2,3 +2,11 @@
|
||||||
# For a description of the syntax of this configuration file,
|
# For a description of the syntax of this configuration file,
|
||||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
config QEMU_PCIE
|
||||||
|
bool "Initialize and enumerate PCI-E Bus"
|
||||||
|
default n
|
||||||
|
select PCIE
|
||||||
|
|
||||||
|
---help---
|
||||||
|
Enables initialization and scaning of standard x86-64 pcie bus.
|
||||||
|
|
|
@ -66,6 +66,8 @@ extern "C"
|
||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
void qemu_pcie_init(void);
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,4 +26,8 @@ ifeq ($(CONFIG_LIB_BOARDCTL),y)
|
||||||
CSRCS += qemu_appinit.c
|
CSRCS += qemu_appinit.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_QEMU_PCIE),y)
|
||||||
|
CSRCS += qemu_pcie.c
|
||||||
|
endif
|
||||||
|
|
||||||
include $(TOPDIR)/boards/Board.mk
|
include $(TOPDIR)/boards/Board.mk
|
||||||
|
|
|
@ -68,6 +68,12 @@ void x86_64_boardinitialize(void)
|
||||||
uart_putreg(CONFIG_16550_UART1_BASE, UART_MCR_OFFSET, UART_MCR_OUT2);
|
uart_putreg(CONFIG_16550_UART1_BASE, UART_MCR_OFFSET, UART_MCR_OUT2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_QEMU_PCIE
|
||||||
|
/* Initialization of system */
|
||||||
|
|
||||||
|
qemu_pcie_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Configure on-board LEDs if LED support has been selected. */
|
/* Configure on-board LEDs if LED support has been selected. */
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_LEDS
|
#ifdef CONFIG_ARCH_LEDS
|
||||||
|
|
|
@ -0,0 +1,398 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* boards/x86_64/intel64/qemu-intel64/src/qemu_pcie.c
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* The MSI and MSI-X vector setup function are taken from Jailhouse inmate
|
||||||
|
* library
|
||||||
|
*
|
||||||
|
* Jailhouse, a Linux-based partitioning hypervisor
|
||||||
|
*
|
||||||
|
* Copyright (c) Siemens AG, 2014
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Jan Kiszka <jan.kiszka@siemens.com>
|
||||||
|
*
|
||||||
|
* This work is licensed under the terms of the GNU GPL, version 2. See
|
||||||
|
* the COPYING file in the top-level directory.
|
||||||
|
*
|
||||||
|
* Alternatively, you can use or redistribute this file under the following
|
||||||
|
* BSD license:
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <nuttx/pcie/pcie.h>
|
||||||
|
|
||||||
|
#include "qemu_pcie_readwrite.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int qemu_pci_cfg_write(FAR struct pcie_dev_s *dev, uintptr_t addr,
|
||||||
|
FAR const void *buffer, unsigned int size);
|
||||||
|
|
||||||
|
static int qemu_pci_cfg_read(FAR struct pcie_dev_s *dev, uintptr_t addr,
|
||||||
|
FAR void *buffer, unsigned int size);
|
||||||
|
|
||||||
|
static int qemu_pci_map_bar(FAR struct pcie_dev_s *dev, uint32_t addr,
|
||||||
|
unsigned long length);
|
||||||
|
|
||||||
|
static int qemu_pci_map_bar64(FAR struct pcie_dev_s *dev, uint64_t addr,
|
||||||
|
unsigned long length);
|
||||||
|
|
||||||
|
static int qemu_pci_msix_register(FAR struct pcie_dev_s *dev,
|
||||||
|
uint32_t vector, uint32_t index);
|
||||||
|
|
||||||
|
static int qemu_pci_msi_register(FAR struct pcie_dev_s *dev,
|
||||||
|
uint16_t vector);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct pcie_bus_ops_s qemu_pcie_bus_ops =
|
||||||
|
{
|
||||||
|
.pci_cfg_write = qemu_pci_cfg_write,
|
||||||
|
.pci_cfg_read = qemu_pci_cfg_read,
|
||||||
|
.pci_map_bar = qemu_pci_map_bar,
|
||||||
|
.pci_map_bar64 = qemu_pci_map_bar64,
|
||||||
|
.pci_msix_register = qemu_pci_msix_register,
|
||||||
|
.pci_msi_register = qemu_pci_msi_register,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pcie_bus_s qemu_pcie_bus =
|
||||||
|
{
|
||||||
|
.ops = &qemu_pcie_bus_ops,
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: qemu_pci_cfg_write
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Write 8, 16, 32, 64 bits data to PCI-E configuration space of device
|
||||||
|
* specified by dev
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* bdf - Device private data
|
||||||
|
* buffer - A pointer to the read-only buffer of data to be written
|
||||||
|
* size - The number of bytes to send from the buffer
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int qemu_pci_cfg_write(FAR struct pcie_dev_s *dev, uintptr_t addr,
|
||||||
|
FAR const void *buffer, unsigned int size)
|
||||||
|
{
|
||||||
|
if (!buffer)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
switch (size)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
return __qemu_pci_cfg_write(dev->bdf, addr, buffer, size);
|
||||||
|
case 8:
|
||||||
|
return __qemu_pci_cfg_write(dev->bdf, addr, buffer, size);
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: qemu_pci_cfg_read
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Read 8, 16, 32, 64 bits data from PCI-E configuration space of device
|
||||||
|
* specified by dev
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* buffer - A pointer to a buffer to receive the data from the device
|
||||||
|
* size - The requested number of bytes to be read
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int qemu_pci_cfg_read(FAR struct pcie_dev_s *dev, uintptr_t addr,
|
||||||
|
FAR void *buffer, unsigned int size)
|
||||||
|
{
|
||||||
|
if (!buffer)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
switch (size)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
return __qemu_pci_cfg_read(dev->bdf, addr, buffer, size);
|
||||||
|
case 8:
|
||||||
|
return __qemu_pci_cfg_read64(dev->bdf, addr, buffer, size);
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: qemu_pci_map_bar
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Map address in a 32 bits bar in the memory address space
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* bar - Bar number
|
||||||
|
* length - Map length, multiple of PAGE_SIZE
|
||||||
|
* ret - Bar Content
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int qemu_pci_map_bar(FAR struct pcie_dev_s *dev, uint32_t addr,
|
||||||
|
unsigned long length)
|
||||||
|
{
|
||||||
|
up_map_region((void *)((uintptr_t)addr), length,
|
||||||
|
X86_PAGE_WR | X86_PAGE_PRESENT | X86_PAGE_NOCACHE | X86_PAGE_GLOBAL);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: qemu_pci_map_bar64
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Map address in a 64 bits bar in the memory address space
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* bar - Bar number
|
||||||
|
* length - Map length, multiple of PAGE_SIZE
|
||||||
|
* ret - Bar Content
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int qemu_pci_map_bar64(FAR struct pcie_dev_s *dev, uint64_t addr,
|
||||||
|
unsigned long length)
|
||||||
|
{
|
||||||
|
up_map_region((void *)((uintptr_t)addr), length,
|
||||||
|
X86_PAGE_WR | X86_PAGE_PRESENT | X86_PAGE_NOCACHE | X86_PAGE_GLOBAL);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: qemu_pci_msix_register
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Map a device MSI-X vector to a platform IRQ vector
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device
|
||||||
|
* vector - IRQ number of the platform
|
||||||
|
* index - Device MSI-X vector number
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* <0: Mapping failed
|
||||||
|
* 0: Mapping succeed
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int qemu_pci_msix_register(FAR struct pcie_dev_s *dev,
|
||||||
|
uint32_t vector, uint32_t index)
|
||||||
|
{
|
||||||
|
unsigned int bar;
|
||||||
|
uint16_t message_control;
|
||||||
|
uint32_t table_bar_ind;
|
||||||
|
uint32_t table_addr_32;
|
||||||
|
uint64_t msix_table_addr = 0;
|
||||||
|
|
||||||
|
int cap = pci_find_cap(dev, PCI_CAP_MSIX);
|
||||||
|
if (cap < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
__qemu_pci_cfg_read(dev->bdf, cap + PCI_MSIX_MCR,
|
||||||
|
&message_control, PCI_MSIX_MCR_SIZE);
|
||||||
|
|
||||||
|
/* bounds check */
|
||||||
|
|
||||||
|
if (index > (message_control & PCI_MSIX_MCR_TBL_MASK))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
__qemu_pci_cfg_read(dev->bdf, cap + PCI_MSIX_TBL,
|
||||||
|
&table_bar_ind, PCI_MSIX_TBL_SIZE);
|
||||||
|
|
||||||
|
bar = (table_bar_ind & PCI_MSIX_BIR_MASK);
|
||||||
|
|
||||||
|
if (!pci_get_bar(dev, bar, &table_addr_32))
|
||||||
|
{
|
||||||
|
/* 32 bit bar */
|
||||||
|
|
||||||
|
msix_table_addr = table_addr_32;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pci_get_bar64(dev, bar, &msix_table_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
msix_table_addr &= ~0xf;
|
||||||
|
msix_table_addr += table_bar_ind & ~PCI_MSIX_BIR_MASK;
|
||||||
|
|
||||||
|
/* enable and mask */
|
||||||
|
|
||||||
|
message_control |= (PCI_MSIX_MCR_EN | PCI_MSIX_MCR_FMASK);
|
||||||
|
__qemu_pci_cfg_write(dev->bdf, cap + PCI_MSIX_MCR,
|
||||||
|
&message_control, PCI_MSIX_MCR_SIZE);
|
||||||
|
|
||||||
|
msix_table_addr += PCI_MSIX_TBL_ENTRY_SIZE * index;
|
||||||
|
mmio_write32((uint32_t *)(msix_table_addr + PCI_MSIX_TBL_LO_ADDR),
|
||||||
|
0xfee00000 | up_apic_cpu_id() << PCI_MSIX_APIC_ID_OFFSET);
|
||||||
|
mmio_write32((uint32_t *)(msix_table_addr + PCI_MSIX_TBL_HI_ADDR),
|
||||||
|
0);
|
||||||
|
mmio_write32((uint32_t *)(msix_table_addr + PCI_MSIX_TBL_MSG_DATA),
|
||||||
|
vector);
|
||||||
|
mmio_write32((uint32_t *)(msix_table_addr + PCI_MSIX_TBL_VEC_CTL),
|
||||||
|
0);
|
||||||
|
|
||||||
|
/* enable and unmask */
|
||||||
|
|
||||||
|
message_control &= ~PCI_MSIX_MCR_FMASK;
|
||||||
|
|
||||||
|
__qemu_pci_cfg_write(dev->bdf, cap + PCI_MSIX_MCR,
|
||||||
|
&message_control, PCI_MSIX_MCR_SIZE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: qemu_pci_msi_register
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Map device MSI vectors to a platform IRQ vector
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device
|
||||||
|
* vector - IRQ number of the platform
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* <0: Mapping failed
|
||||||
|
* 0: Mapping succeed
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int qemu_pci_msi_register(FAR struct pcie_dev_s *dev, uint16_t vector)
|
||||||
|
{
|
||||||
|
uint16_t ctl;
|
||||||
|
uint16_t data;
|
||||||
|
|
||||||
|
int cap = pci_find_cap(dev, PCI_CAP_MSI);
|
||||||
|
if (cap < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
uint32_t dest = 0xfee00000 | (up_apic_cpu_id() << PCI_MSI_APIC_ID_OFFSET);
|
||||||
|
__qemu_pci_cfg_write(dev->bdf, cap + PCI_MSI_MAR, &dest, PCI_MSI_MAR_SIZE);
|
||||||
|
|
||||||
|
__qemu_pci_cfg_read(dev->bdf, cap + PCI_MSI_MCR, &ctl, PCI_MSI_MCR_SIZE);
|
||||||
|
if ((ctl & PCI_MSI_MCR_64) == PCI_MSI_MCR_64)
|
||||||
|
{
|
||||||
|
uint32_t tmp = 0;
|
||||||
|
__qemu_pci_cfg_write(dev->bdf,
|
||||||
|
cap + PCI_MSI_MAR64_HI, &tmp,
|
||||||
|
PCI_MSI_MAR64_HI_SIZE);
|
||||||
|
data = cap + PCI_MSI_MDR64;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data = cap + PCI_MSI_MDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
__qemu_pci_cfg_write(dev->bdf, data, &vector, PCI_MSI_MDR_SIZE);
|
||||||
|
|
||||||
|
__qemu_pci_cfg_write(dev->bdf, cap + PCI_MSI_MCR, &vector,
|
||||||
|
PCI_MSI_MCR_SIZE);
|
||||||
|
|
||||||
|
uint16_t tmp = PCI_MSI_MCR_EN;
|
||||||
|
|
||||||
|
__qemu_pci_cfg_write(dev->bdf, cap + PCI_MSI_MCR, &tmp, PCI_MSI_MCR_SIZE);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: qemu_pcie_init
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize the PCI-E bus *
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void qemu_pcie_init(void)
|
||||||
|
{
|
||||||
|
pcie_initialize(&qemu_pcie_bus);
|
||||||
|
}
|
|
@ -0,0 +1,240 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* boards/x86_64/intel64/qemu-intel64/src/qemu_pcie_readwrite.h
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* The PCI-E Definitions and part of the access routines are taken from
|
||||||
|
* Jailhouse inmate library
|
||||||
|
*
|
||||||
|
* Jailhouse, a Linux-based partitioning hypervisor
|
||||||
|
*
|
||||||
|
* Copyright (c) Siemens AG, 2014
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Jan Kiszka <jan.kiszka@siemens.com>
|
||||||
|
*
|
||||||
|
* This work is licensed under the terms of the GNU GPL, version 2. See
|
||||||
|
* the COPYING file in the top-level directory.
|
||||||
|
*
|
||||||
|
* Alternatively, you can use or redistribute this file under the following
|
||||||
|
* BSD license:
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __INCLUDE_NUTTX_PCIE_PCIE_READWRITE_H
|
||||||
|
#define __INCLUDE_NUTTX_PCIE_PCIE_READWRITE_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <nuttx/pcie/pcie.h>
|
||||||
|
|
||||||
|
#include <nuttx/board.h>
|
||||||
|
#include <arch/board/board.h>
|
||||||
|
|
||||||
|
#include "up_arch.h"
|
||||||
|
#include "up_internal.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define PCI_REG_ADDR_PORT 0xcf8
|
||||||
|
#define PCI_REG_DATA_PORT 0xcfc
|
||||||
|
|
||||||
|
#define PCI_CONE (1 << 31)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: __qemu_pci_cfg_write
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Write 8, 16, 32 bits data to PCI-E configuration space of device
|
||||||
|
* specified by dev
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* bfd - Device private data
|
||||||
|
* buffer - A pointer to the read-only buffer of data to be written
|
||||||
|
* size - The number of bytes to send from the buffer
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline int __qemu_pci_cfg_write(uint16_t bfd, uintptr_t addr,
|
||||||
|
FAR const void *buffer,
|
||||||
|
unsigned int size)
|
||||||
|
{
|
||||||
|
if (!buffer)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
outl(PCI_CONE | ((uint32_t)bfd << 8) | (addr & 0xfc), PCI_REG_ADDR_PORT);
|
||||||
|
|
||||||
|
switch (size)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
outb(*(uint8_t *)(buffer), PCI_REG_DATA_PORT + (addr & 0x3));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
outw(*(uint16_t *)(buffer), PCI_REG_DATA_PORT + (addr & 0x3));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
outl(*(uint32_t *)(buffer), PCI_REG_DATA_PORT);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: __qemu_pci_cfg_write64
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Write 64 bits data to PCI-E configuration space of device
|
||||||
|
* specified by dev
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* bfd - Device private data
|
||||||
|
* buffer - A pointer to the read-only buffer of data to be written
|
||||||
|
* size - The number of bytes to send from the buffer
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline int __qemu_pci_cfg_write64(uint16_t bfd, uintptr_t addr,
|
||||||
|
FAR const void *buffer,
|
||||||
|
unsigned int size)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!buffer)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ret = __qemu_pci_cfg_write(bfd, addr + 4, buffer + 4, 4);
|
||||||
|
ret |= __qemu_pci_cfg_write(bfd, addr, buffer, 4);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: __qemu_pci_cfg_read
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Read 8, 16, 32 bits data from PCI-E configuration space of device
|
||||||
|
* specified by dev
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* buffer - A pointer to a buffer to receive the data from the device
|
||||||
|
* size - The requested number of bytes to be read
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline int __qemu_pci_cfg_read(uint16_t bfd, uintptr_t addr,
|
||||||
|
FAR void *buffer, unsigned int size)
|
||||||
|
{
|
||||||
|
if (!buffer)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
outl(PCI_CONE | ((uint32_t)bfd << 8) | (addr & 0xfc), PCI_REG_ADDR_PORT);
|
||||||
|
|
||||||
|
switch (size)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
*(uint8_t *)(buffer) = inb(PCI_REG_DATA_PORT + (addr & 0x3));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*(uint16_t *)(buffer) = inw(PCI_REG_DATA_PORT + (addr & 0x3));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
*(uint32_t *)(buffer) = inl(PCI_REG_DATA_PORT);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: __qemu_pci_cfg_read
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Read 64 bits data from PCI-E configuration space of device
|
||||||
|
* specified by dev
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* buffer - A pointer to a buffer to receive the data from the device
|
||||||
|
* size - The requested number of bytes to be read
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline int __qemu_pci_cfg_read64(uint16_t bfd,
|
||||||
|
uintptr_t addr,
|
||||||
|
FAR void *buffer,
|
||||||
|
unsigned int size)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!buffer)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ret = __qemu_pci_cfg_read(bfd, addr + 4, buffer + 4, 4);
|
||||||
|
ret |= __qemu_pci_cfg_read(bfd, addr, buffer, 4);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __INCLUDE_NUTTX_PCIE_PCIE_READWRITE_H */
|
|
@ -107,3 +107,5 @@ source drivers/1wire/Kconfig
|
||||||
source drivers/syslog/Kconfig
|
source drivers/syslog/Kconfig
|
||||||
source drivers/platform/Kconfig
|
source drivers/platform/Kconfig
|
||||||
source drivers/rf/Kconfig
|
source drivers/rf/Kconfig
|
||||||
|
source drivers/pcie/Kconfig
|
||||||
|
source drivers/virt/Kconfig
|
||||||
|
|
|
@ -73,6 +73,8 @@ include wireless/Make.defs
|
||||||
include contactless/Make.defs
|
include contactless/Make.defs
|
||||||
include 1wire/Make.defs
|
include 1wire/Make.defs
|
||||||
include rf/Make.defs
|
include rf/Make.defs
|
||||||
|
include pcie/Make.defs
|
||||||
|
include virt/Make.defs
|
||||||
|
|
||||||
ifeq ($(CONFIG_SPECIFIC_DRIVERS),y)
|
ifeq ($(CONFIG_SPECIFIC_DRIVERS),y)
|
||||||
include platform/Make.defs
|
include platform/Make.defs
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
#
|
||||||
|
# For a description of the syntax of this configuration file,
|
||||||
|
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||||
|
#
|
||||||
|
|
||||||
|
menuconfig PCIE
|
||||||
|
bool "Support for PCI-E Bus"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Enables support for the PCI-E bus.
|
||||||
|
Backend bust be provided by per-arch or per-board implementation..
|
||||||
|
|
||||||
|
if PCIE
|
||||||
|
config PCIE_MAX_BDF
|
||||||
|
hex "Maximum bdf to scan on PCI-E bus"
|
||||||
|
default 0x10000
|
||||||
|
---help---
|
||||||
|
The maximum bdf number to be scaned on PCI-E bus
|
||||||
|
|
||||||
|
endif
|
|
@ -0,0 +1,32 @@
|
||||||
|
############################################################################
|
||||||
|
# drivers/pcie/Make.defs
|
||||||
|
#
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
# contributor license agreements. See the NOTICE file distributed with
|
||||||
|
# this work for additional information regarding copyright ownership. The
|
||||||
|
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
# "License"); you may not use this file except in compliance with the
|
||||||
|
# License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
# Don't build anything if there is no CAN support
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_PCIE),y)
|
||||||
|
|
||||||
|
CSRCS += pcie_root.c
|
||||||
|
|
||||||
|
# Include PCIE device driver build support
|
||||||
|
|
||||||
|
DEPPATH += --dep-path pcie
|
||||||
|
VPATH += :pcie
|
||||||
|
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)pcie}
|
||||||
|
endif
|
|
@ -0,0 +1,446 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* nuttx/drivers/pcie/pcie_root.c
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/pcie/pcie.h>
|
||||||
|
#include <nuttx/virt/qemu_pci.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct pcie_dev_type_s *pci_device_types[] =
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_VIRT_QEMU_PCI_TEST
|
||||||
|
&pcie_type_qemu_pci_test,
|
||||||
|
#endif /* CONFIG_VIRT_QEMU_PCI_TEST */
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_enumerate
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Scan the PCI bus and enumerate the devices.
|
||||||
|
* Initialize any recognized devices, given in types.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* bus - PCI-E bus structure
|
||||||
|
* type - List of pointers to devices types recognized, NULL terminated
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_enumerate(FAR struct pcie_bus_s *bus,
|
||||||
|
FAR struct pcie_dev_type_s **types)
|
||||||
|
{
|
||||||
|
unsigned int bdf;
|
||||||
|
uint16_t vid;
|
||||||
|
uint16_t id;
|
||||||
|
uint16_t rev;
|
||||||
|
struct pcie_dev_s tmp_dev;
|
||||||
|
struct pcie_dev_type_s tmp_type =
|
||||||
|
{
|
||||||
|
.name = "Unknown",
|
||||||
|
.vendor = PCI_ID_ANY,
|
||||||
|
.device = PCI_ID_ANY,
|
||||||
|
.class_rev = PCI_ID_ANY,
|
||||||
|
.probe = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!bus)
|
||||||
|
return -EINVAL;
|
||||||
|
if (!types)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
for (bdf = 0; bdf < CONFIG_PCIE_MAX_BDF; bdf++)
|
||||||
|
{
|
||||||
|
tmp_dev.bus = bus;
|
||||||
|
tmp_dev.type = &tmp_type;
|
||||||
|
tmp_dev.bdf = bdf;
|
||||||
|
|
||||||
|
bus->ops->pci_cfg_read(&tmp_dev, PCI_CFG_VENDOR_ID, &vid, 2);
|
||||||
|
bus->ops->pci_cfg_read(&tmp_dev, PCI_CFG_DEVICE_ID, &id, 2);
|
||||||
|
bus->ops->pci_cfg_read(&tmp_dev, PCI_CFG_REVERSION, &rev, 2);
|
||||||
|
|
||||||
|
if (vid == PCI_ID_ANY)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pciinfo("[%02x:%02x.%x] Found %04x:%04x, class/reversion %08x\n",
|
||||||
|
bdf >> 8, (bdf >> 3) & 0x1f, bdf & 0x3,
|
||||||
|
vid, id, rev);
|
||||||
|
|
||||||
|
for (int i = 0; types[i] != NULL; i++)
|
||||||
|
{
|
||||||
|
if (types[i]->vendor == PCI_ID_ANY ||
|
||||||
|
types[i]->vendor == vid)
|
||||||
|
{
|
||||||
|
if (types[i]->device == PCI_ID_ANY ||
|
||||||
|
types[i]->device == id)
|
||||||
|
{
|
||||||
|
if (types[i]->class_rev == PCI_ID_ANY ||
|
||||||
|
types[i]->class_rev == rev)
|
||||||
|
{
|
||||||
|
if (types[i]->probe)
|
||||||
|
{
|
||||||
|
pciinfo("[%02x:%02x.%x] %s\n",
|
||||||
|
bdf >> 8, (bdf >> 3) & 0x1f, bdf & 0x3,
|
||||||
|
types[i]->name);
|
||||||
|
types[i]->probe(bus, types[i], bdf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pcierr("[%02x:%02x.%x] Error: Invalid \
|
||||||
|
device probe function\n",
|
||||||
|
bdf >> 8, (bdf >> 3) & 0x1f, bdf & 0x3);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pcie_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize the PCI-E bus and enumerate the devices with give devices
|
||||||
|
* type array
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* bus - An PCIE bus
|
||||||
|
* types - A array of PCIE device types
|
||||||
|
* num - Number of device types
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* OK if the driver was successfully register; A negated errno value is
|
||||||
|
* returned on any failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pcie_initialize(FAR struct pcie_bus_s *bus)
|
||||||
|
{
|
||||||
|
return pci_enumerate(bus, pci_device_types);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_enable_device
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Enable device with MMIO
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - device
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* -EINVAL: error
|
||||||
|
* OK: OK
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_enable_device(FAR struct pcie_dev_s *dev)
|
||||||
|
{
|
||||||
|
uint16_t old_cmd;
|
||||||
|
uint16_t cmd;
|
||||||
|
|
||||||
|
dev->bus->ops->pci_cfg_read(dev, PCI_CFG_COMMAND, &old_cmd, 2);
|
||||||
|
|
||||||
|
cmd = old_cmd | (PCI_CMD_MASTER | PCI_CMD_MEM);
|
||||||
|
|
||||||
|
dev->bus->ops->pci_cfg_write(dev, PCI_CFG_COMMAND, &cmd, 2);
|
||||||
|
|
||||||
|
pciinfo("%02x:%02x.%x, CMD: %x -> %x\n",
|
||||||
|
dev->bdf >> 8, (dev->bdf >> 3) & 0x1f, dev->bdf & 0x3,
|
||||||
|
old_cmd, cmd);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_find_cap
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Search through the PCI-e device capability list to find given capability.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device
|
||||||
|
* cap - Bitmask of capability
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* -1: Capability not supported
|
||||||
|
* other: the offset in PCI configuration space to the capability structure
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_find_cap(FAR struct pcie_dev_s *dev, uint16_t cap)
|
||||||
|
{
|
||||||
|
uint8_t pos = PCI_CFG_CAP_PTR - 1;
|
||||||
|
uint16_t status;
|
||||||
|
uint8_t rcap;
|
||||||
|
|
||||||
|
dev->bus->ops->pci_cfg_read(dev, PCI_CFG_STATUS, &status, 2);
|
||||||
|
|
||||||
|
if (!(status & PCI_STS_CAPS))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
dev->bus->ops->pci_cfg_read(dev, pos + 1, &pos, 1);
|
||||||
|
if (pos == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
dev->bus->ops->pci_cfg_read(dev, pos, &rcap, 1);
|
||||||
|
|
||||||
|
if (rcap == cap)
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_get_bar
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get a 32 bits bar
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* bar - Bar number
|
||||||
|
* ret - Bar Content
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_get_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
|
||||||
|
uint32_t *ret)
|
||||||
|
{
|
||||||
|
if (bar > 5)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4, ret, 4);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_get_bar64
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get a 64 bits bar
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* bar - Bar number
|
||||||
|
* ret - Bar Content
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_get_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
|
||||||
|
uint64_t *ret)
|
||||||
|
{
|
||||||
|
if (bar > 4 || ((bar % 2) != 0))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
uint32_t barmem1;
|
||||||
|
uint32_t barmem2;
|
||||||
|
|
||||||
|
dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4, &barmem1, 4);
|
||||||
|
dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4 + 4, &barmem2, 4);
|
||||||
|
|
||||||
|
*ret = ((uint64_t)barmem2 << 32) | barmem1;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_set_bar
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set a 32 bits bar
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* bar - Bar number
|
||||||
|
* val - Bar Content
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_set_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
|
||||||
|
uint32_t val)
|
||||||
|
{
|
||||||
|
if (bar > 5)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
dev->bus->ops->pci_cfg_write(dev, PCI_CFG_BAR + bar * 4, &val, 4);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_set_bar64
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set a 64 bits bar
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* bar - Bar number
|
||||||
|
* val - Bar Content
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_set_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
|
||||||
|
uint64_t val)
|
||||||
|
{
|
||||||
|
if (bar > 4 || ((bar % 2) != 0))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
uint32_t barmem1 = (uint32_t)val;
|
||||||
|
uint32_t barmem2 = (uint32_t)(val >> 32);
|
||||||
|
|
||||||
|
dev->bus->ops->pci_cfg_write(dev, PCI_CFG_BAR + bar * 4, &barmem1, 4);
|
||||||
|
dev->bus->ops->pci_cfg_write(dev, PCI_CFG_BAR + bar * 4 + 4, &barmem2, 4);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_map_bar
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Map address in a 32 bits bar in the flat memory address space
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* bar - Bar number
|
||||||
|
* length - Map length, multiple of PAGE_SIZE
|
||||||
|
* ret - Bar Content if not NULL
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_map_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
|
||||||
|
unsigned long length, uint32_t *ret)
|
||||||
|
{
|
||||||
|
if (bar > 5)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
uint32_t barmem;
|
||||||
|
|
||||||
|
dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4, &barmem, 4);
|
||||||
|
|
||||||
|
if (((bar % 2) == 0 &&
|
||||||
|
(barmem & PCI_BAR_64BIT) == PCI_BAR_64BIT) ||
|
||||||
|
(barmem & PCI_BAR_IO) == PCI_BAR_IO)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!dev->bus->ops->pci_map_bar)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
dev->bus->ops->pci_map_bar(dev, barmem, length);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
*ret = barmem;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_map_bar64
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Map address in a 64 bits bar in the flat memory address space
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* bar - Bar number
|
||||||
|
* length - Map length, multiple of PAGE_SIZE
|
||||||
|
* ret - Bar Content if not NULL
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_map_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
|
||||||
|
unsigned long length, uint64_t *ret)
|
||||||
|
{
|
||||||
|
if (bar > 4 || ((bar % 2) != 0))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
uint32_t barmem1;
|
||||||
|
uint32_t barmem2;
|
||||||
|
uint64_t barmem;
|
||||||
|
|
||||||
|
dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4, &barmem1, 4);
|
||||||
|
|
||||||
|
if ((barmem1 & PCI_BAR_64BIT) != PCI_BAR_64BIT ||
|
||||||
|
(barmem1 & PCI_BAR_IO) == PCI_BAR_IO)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4 + 4, &barmem2, 4);
|
||||||
|
|
||||||
|
barmem = ((uint64_t)barmem2 << 32) | barmem1;
|
||||||
|
|
||||||
|
if (!dev->bus->ops->pci_map_bar64)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
dev->bus->ops->pci_map_bar64(dev, barmem, length);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
*ret = barmem;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#
|
||||||
|
# For a description of the syntax of this configuration file,
|
||||||
|
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
menuconfig VIRT
|
||||||
|
bool "Virtualization"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Drivers for virtualized and emulated devices
|
||||||
|
|
||||||
|
if VIRT
|
||||||
|
|
||||||
|
config VIRT_QEMU_PCI_TEST
|
||||||
|
bool "Driver for QEMU PCI test device"
|
||||||
|
default n
|
||||||
|
select PCIE
|
||||||
|
---help---
|
||||||
|
Driver for QEMU PCI test device
|
||||||
|
|
||||||
|
endif # VIRT
|
|
@ -0,0 +1,37 @@
|
||||||
|
############################################################################
|
||||||
|
# drivers/pcie/Make.defs
|
||||||
|
#
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
# contributor license agreements. See the NOTICE file distributed with
|
||||||
|
# this work for additional information regarding copyright ownership. The
|
||||||
|
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
# "License"); you may not use this file except in compliance with the
|
||||||
|
# License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
# Don't build anything if there is no CAN support
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_VIRT_QEMU_PCI_TEST),y)
|
||||||
|
|
||||||
|
CSRCS += qemu_pci_test.c
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Include virt device driver build support
|
||||||
|
#
|
||||||
|
ifeq ($(CONFIG_VIRT),y)
|
||||||
|
|
||||||
|
DEPPATH += --dep-path virt
|
||||||
|
VPATH += :virt
|
||||||
|
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)virt}
|
||||||
|
|
||||||
|
endif
|
|
@ -0,0 +1,130 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* drivers/virt/qemu_pci_test.c
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
|
#include <nuttx/pcie/pcie.h>
|
||||||
|
#include <nuttx/virt/qemu_pci.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Private Types
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
struct pci_test_dev_hdr_s
|
||||||
|
{
|
||||||
|
volatile uint8_t test; /* write-only, starts a given test number */
|
||||||
|
volatile uint8_t width_type; /* read-only, type and width of access for a given test.
|
||||||
|
* 1,2,4 for byte,word or long write.
|
||||||
|
* any other value if test not supported on this BAR */
|
||||||
|
volatile uint8_t pad0[2];
|
||||||
|
volatile uint32_t offset; /* read-only, offset in this BAR for a given test */
|
||||||
|
volatile uint32_t data; /* read-only, data to use for a given test */
|
||||||
|
volatile uint32_t count; /* for debugging. number of writes detected. */
|
||||||
|
volatile uint8_t name[]; /* for debugging. 0-terminated ASCII string. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Name: qemu_pci_test_probe
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize device
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
int qemu_pci_test_probe(FAR struct pcie_bus_s *bus,
|
||||||
|
FAR struct pcie_dev_type_s *type, uint16_t bdf)
|
||||||
|
{
|
||||||
|
uint32_t bar[2];
|
||||||
|
struct pcie_dev_s dev =
|
||||||
|
{
|
||||||
|
.bus = bus,
|
||||||
|
.type = type,
|
||||||
|
.bdf = bdf,
|
||||||
|
};
|
||||||
|
|
||||||
|
pci_enable_device(&dev);
|
||||||
|
|
||||||
|
for (int ii = 0; ii < 2; ii++)
|
||||||
|
{
|
||||||
|
pci_get_bar(&dev, ii, bar + ii);
|
||||||
|
|
||||||
|
if ((bar[ii] & PCI_BAR_IO) != PCI_BAR_IO)
|
||||||
|
{
|
||||||
|
pciinfo("Mapping BAR%d: %x\n", ii, bar[ii]);
|
||||||
|
|
||||||
|
pci_map_bar(&dev, ii, 0x1000, NULL);
|
||||||
|
|
||||||
|
struct pci_test_dev_hdr_s *ptr =
|
||||||
|
(struct pci_test_dev_hdr_s *)(uintptr_t)bar[ii];
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
ptr->test = i;
|
||||||
|
|
||||||
|
if (ptr->width_type != 1 &&
|
||||||
|
ptr->width_type != 2 &&
|
||||||
|
ptr->width_type != 4)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pciinfo("Test[%d] Size:%d %s\n",
|
||||||
|
i, ptr->width_type,
|
||||||
|
ptr->name);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Public Data
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
struct pcie_dev_type_s pcie_type_qemu_pci_test =
|
||||||
|
{
|
||||||
|
.vendor = 0x1b36,
|
||||||
|
.device = 0x0005,
|
||||||
|
.class_rev = PCI_ID_ANY,
|
||||||
|
.name = "Qemu PCI test device",
|
||||||
|
.probe = qemu_pci_test_probe
|
||||||
|
};
|
|
@ -721,6 +721,24 @@
|
||||||
# define wdinfo _none
|
# define wdinfo _none
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_PCIE_ERROR
|
||||||
|
# define pcierr _err
|
||||||
|
#else
|
||||||
|
# define pcierr _none
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_PCIE_WARN
|
||||||
|
# define pciwarn _warn
|
||||||
|
#else
|
||||||
|
# define pciwarn _none
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_PCIE_INFO
|
||||||
|
# define pciinfo _info
|
||||||
|
#else
|
||||||
|
# define pciinfo _none
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Buffer dumping macros do not depend on varargs */
|
/* Buffer dumping macros do not depend on varargs */
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_ERROR
|
#ifdef CONFIG_DEBUG_ERROR
|
||||||
|
|
|
@ -0,0 +1,352 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* include/nuttx/pcie/pcie.h
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __INCLUDE_NUTTX_PCIE_PCIE_H
|
||||||
|
#define __INCLUDE_NUTTX_PCIE_PCIE_H
|
||||||
|
|
||||||
|
#ifdef CONFIG_PCIE
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <nuttx/fs/ioctl.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define PCI_CFG_VENDOR_ID 0x000
|
||||||
|
#define PCI_CFG_DEVICE_ID 0x002
|
||||||
|
#define PCI_CFG_COMMAND 0x004
|
||||||
|
# define PCI_CMD_IO (1 << 0)
|
||||||
|
# define PCI_CMD_MEM (1 << 1)
|
||||||
|
# define PCI_CMD_MASTER (1 << 2)
|
||||||
|
# define PCI_CMD_INTX_OFF (1 << 10)
|
||||||
|
#define PCI_CFG_STATUS 0x006
|
||||||
|
# define PCI_STS_INT (1 << 3)
|
||||||
|
# define PCI_STS_CAPS (1 << 4)
|
||||||
|
#define PCI_CFG_REVERSION 0x008
|
||||||
|
#define PCI_CFG_BAR 0x010
|
||||||
|
# define PCI_BAR_IO 0x1
|
||||||
|
# define PCI_BAR_1M 0x2
|
||||||
|
# define PCI_BAR_64BIT 0x4
|
||||||
|
#define PCI_CFG_CAP_PTR 0x034
|
||||||
|
|
||||||
|
#define PCI_ID_ANY 0xffff
|
||||||
|
#define PCI_DEV_CLASS_OTHER 0xff
|
||||||
|
|
||||||
|
#define PCI_CAP_PM 0x01
|
||||||
|
|
||||||
|
#define PCI_CAP_MSI 0x05
|
||||||
|
# define PCI_MSI_MCR 0x02
|
||||||
|
# define PCI_MSI_MCR_SIZE 2
|
||||||
|
# define PCI_MSI_MCR_EN (1 << 0)
|
||||||
|
# define PCI_MSI_MCR_64 (1 << 7)
|
||||||
|
# define PCI_MSI_MAR 0x04
|
||||||
|
# define PCI_MSI_MAR_SIZE 4
|
||||||
|
# define PCI_MSI_MDR 0x08
|
||||||
|
# define PCI_MSI_MDR_SIZE 2
|
||||||
|
# define PCI_MSI_MAR64_HI 0x08
|
||||||
|
# define PCI_MSI_MAR64_HI_SIZE 4
|
||||||
|
# define PCI_MSI_MDR64 0x0c
|
||||||
|
# define PCI_MSI_MDR64_SIZE 2
|
||||||
|
# define PCI_MSI_APIC_ID_OFFSET 0xc
|
||||||
|
|
||||||
|
#define PCI_CAP_MSIX 0x11
|
||||||
|
# define PCI_MSIX_MCR 0x02
|
||||||
|
# define PCI_MSIX_MCR_SIZE 2
|
||||||
|
# define PCI_MSIX_MCR_EN (1 << 15)
|
||||||
|
# define PCI_MSIX_MCR_FMASK 0x4000
|
||||||
|
# define PCI_MSIX_MCR_TBL_MASK 0x03ff
|
||||||
|
# define PCI_MSIX_TBL 0x04
|
||||||
|
# define PCI_MSIX_TBL_SIZE 4
|
||||||
|
# define PCI_MSIX_PBA 0x08
|
||||||
|
# define PCI_MSIX_PBA_SIZE 4
|
||||||
|
# define PCI_MSIX_BIR_MASK 0x07
|
||||||
|
# define PCI_MSIX_TBL_ENTRY_SIZE 0x10
|
||||||
|
# define PCI_MSIX_TBL_LO_ADDR 0x0
|
||||||
|
# define PCI_MSIX_TBL_HI_ADDR 0x4
|
||||||
|
# define PCI_MSIX_TBL_MSG_DATA 0x8
|
||||||
|
# define PCI_MSIX_TBL_VEC_CTL 0xc
|
||||||
|
# define PCI_MSIX_APIC_ID_OFFSET 0xc
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* The PCIE driver interface */
|
||||||
|
|
||||||
|
struct pcie_bus_s;
|
||||||
|
struct pcie_dev_type_s;
|
||||||
|
struct pcie_dev_s;
|
||||||
|
|
||||||
|
/* Bus related operations */
|
||||||
|
|
||||||
|
struct pcie_bus_ops_s
|
||||||
|
{
|
||||||
|
CODE int (*pcie_enumerate)(FAR struct pcie_bus_s *bus,
|
||||||
|
FAR struct pcie_dev_type_s **types);
|
||||||
|
|
||||||
|
CODE int (*pci_cfg_write)(FAR struct pcie_dev_s *dev, uintptr_t addr,
|
||||||
|
FAR const void *buffer, unsigned int size);
|
||||||
|
|
||||||
|
CODE int (*pci_cfg_read)(FAR struct pcie_dev_s *dev, uintptr_t addr,
|
||||||
|
FAR void *buffer, unsigned int size);
|
||||||
|
|
||||||
|
CODE int (*pci_map_bar)(FAR struct pcie_dev_s *dev, uint32_t addr,
|
||||||
|
unsigned long length);
|
||||||
|
|
||||||
|
CODE int (*pci_map_bar64)(FAR struct pcie_dev_s *dev, uint64_t addr,
|
||||||
|
unsigned long length);
|
||||||
|
|
||||||
|
CODE int (*pci_msi_register)(FAR struct pcie_dev_s *dev,
|
||||||
|
uint16_t vector);
|
||||||
|
|
||||||
|
CODE int (*pci_msix_register)(FAR struct pcie_dev_s *dev,
|
||||||
|
uint32_t vector, uint32_t index);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* PCIE bus private data. */
|
||||||
|
|
||||||
|
struct pcie_bus_s
|
||||||
|
{
|
||||||
|
FAR const struct pcie_bus_ops_s *ops; /* operations */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* PCIE device type, defines by vendor ID and device ID */
|
||||||
|
|
||||||
|
struct pcie_dev_type_s
|
||||||
|
{
|
||||||
|
uint16_t vendor; /* Device vendor ID */
|
||||||
|
uint16_t device; /* Device ID */
|
||||||
|
uint32_t class_rev; /* Device reversion */
|
||||||
|
const char *name; /* Human readable name */
|
||||||
|
|
||||||
|
/* Call back function when a device is probed */
|
||||||
|
|
||||||
|
CODE int (*probe)(FAR struct pcie_bus_s *bus,
|
||||||
|
FAR struct pcie_dev_type_s *type, uint16_t bdf);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* PCIE device private data. */
|
||||||
|
|
||||||
|
struct pcie_dev_s
|
||||||
|
{
|
||||||
|
FAR struct pcie_bus_s *bus;
|
||||||
|
FAR struct pcie_dev_type_s *type;
|
||||||
|
uint16_t bdf;
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#undef EXTERN
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#define EXTERN extern "C"
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#else
|
||||||
|
#define EXTERN extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pcie_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize the PCI-E bus and enumerate the devices with give devices
|
||||||
|
* type array
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* bus - An PCIE bus
|
||||||
|
* types - A array of PCIE device types
|
||||||
|
* num - Number of device types
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* OK if the driver was successfully register; A negated errno value is
|
||||||
|
* returned on any failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pcie_initialize(FAR struct pcie_bus_s *bus);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_enable_device
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Enable device with MMIO
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - device
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* -EINVAL: error
|
||||||
|
* OK: OK
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_enable_device(FAR struct pcie_dev_s *dev);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_find_cap
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Search through the PCI-e device capability list to find given capability.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device
|
||||||
|
* cap - Bitmask of capability
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* -1: Capability not supported
|
||||||
|
* other: the offset in PCI configuration space to the capability structure
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_find_cap(FAR struct pcie_dev_s *dev, uint16_t cap);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_map_bar
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Map address in a 32 bits bar in the flat memory address space
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* bar - Bar number
|
||||||
|
* length - Map length, multiple of PAGE_SIZE
|
||||||
|
* ret - Bar Contentif not NULL
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_map_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
|
||||||
|
unsigned long length, uint32_t *ret);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_map_bar64
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Map address in a 64 bits bar in the flat memory address space
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* bar - Bar number
|
||||||
|
* length - Map length, multiple of PAGE_SIZE
|
||||||
|
* ret - Bar Content if not NULL
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_map_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
|
||||||
|
unsigned long length, uint64_t *ret);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_get_bar
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get a 32 bits bar
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* bar - Bar number
|
||||||
|
* ret - Bar Content
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_get_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
|
||||||
|
uint32_t *ret);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_get_bar64
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get a 64 bits bar
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* bar - Bar number
|
||||||
|
* ret - Bar Content
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_get_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
|
||||||
|
uint64_t *ret);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_set_bar
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set a 32 bits bar
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* bar - Bar number
|
||||||
|
* val - Bar Content
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_set_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
|
||||||
|
uint32_t val);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pci_set_bar64
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set a 64 bits bar
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* dev - Device private data
|
||||||
|
* bar - Bar number
|
||||||
|
* val - Bar Content
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0: success, <0: A negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pci_set_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
|
||||||
|
uint64_t val);
|
||||||
|
|
||||||
|
#undef EXTERN
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif /* __INCLUDE_NUTTX_I2C_I2C_MASTER_H */
|
|
@ -0,0 +1,53 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* include/nuttx/serial/uart_mcs99xx.h
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __INCLUDE_NUTTX_VIRT_QEMU_PCI_TEST_H
|
||||||
|
#define __INCLUDE_NUTTX_VIRT_QEMU_PCI_TEST_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define EXTERN extern "C"
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#else
|
||||||
|
#define EXTERN extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_VIRT_QEMU_PCI_TEST
|
||||||
|
extern struct pcie_dev_type_s pcie_type_qemu_pci_test;
|
||||||
|
#endif /* CONFIG_VIRT_QEMU_PCI_TEST */
|
||||||
|
|
||||||
|
#undef EXTERN
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __INCLUDE_NUTTX_VIRT_QEMU_PCI_TEST_H */
|
Loading…
Reference in New Issue