raiden00pl commented on code in PR #11583: URL: https://github.com/apache/nuttx/pull/11583#discussion_r1466392220
########## drivers/pci/pci.c: ########## @@ -0,0 +1,832 @@ +/**************************************************************************** + * drivers/pci/pci.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/pci/pci.h> +#include <nuttx/virt/qemu_pci.h> + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* For now hard code jailhouse as a flag. In the future we can determine this + * by looking at the CPUID base for "Jailhouse\0\0\0" + */ + +#define JAILHOUSE_ENABLED 1 + +#define PCI_BDF(bus, slot, func) (((uint32_t)bus << 8) | \ + ((uint32_t)slot << 3) | \ + func) + +/**************************************************************************** + * Private Functions Definitions + ****************************************************************************/ + +static void pci_probe_device(FAR struct pci_bus_s *root_bus, + uint8_t bus_idx, uint8_t slot_idx, uint8_t func, + FAR const struct pci_dev_type_s **types); + +static uint8_t pci_check_pci_bridge(FAR struct pci_bus_s *root_bus, + uint8_t bus_idx, uint8_t slot_idx, + uint8_t dev_func); + +static void pci_scan_device(FAR struct pci_bus_s *root_bus, + uint8_t bus_idx, uint8_t slot_idx, + FAR const struct pci_dev_type_s **types); + +static void pci_scan_bus(FAR struct pci_bus_s *root_bus, + uint8_t bus_idx, + FAR const struct pci_dev_type_s **types); + +static void pci_set_cmd_bit(FAR struct pci_dev_s *dev, uint16_t bitmask); + +static void pci_clear_cmd_bit(FAR struct pci_dev_s *dev, uint16_t bitmask); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct pci_dev_type_s *pci_device_types[] = +{ +#ifdef CONFIG_VIRT_QEMU_PCI_TEST + &g_pci_type_qemu_pci_test, +#endif +#ifdef CONFIG_VIRT_QEMU_EDU + &g_pci_type_qemu_edu, +#endif + NULL, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pci_probe + * + * Description: + * Checks if the specified device is supported and if so calls probe on it + * + * Input Parameters: + * root_bus - The root bus device that lets us address the whole tree + * bus - Bus ID + * slot - Device Slot + * func - Device Function + * types - List of pointers to devices types recognized, NULL terminated + * + ****************************************************************************/ + +static void pci_probe_device(FAR struct pci_bus_s *root_bus, + uint8_t bus_idx, uint8_t slot_idx, uint8_t func, + FAR const struct pci_dev_type_s **types) +{ + struct pci_dev_s tmp_dev; + uint32_t class_rev; + uint16_t vid; + uint16_t id; + int i; + + tmp_dev.bus = root_bus; + tmp_dev.bdf = PCI_BDF(bus_idx, slot_idx, func); + + vid = root_bus->ops->pci_cfg_read(&tmp_dev, PCI_CONFIG_VENDOR, 2); + id = root_bus->ops->pci_cfg_read(&tmp_dev, PCI_CONFIG_DEVICE, 2); + + /* This is reading rev prog_if subclass and class */ + + class_rev = root_bus->ops->pci_cfg_read(&tmp_dev, PCI_CONFIG_REV_ID, 4); + + pci_dev_dump(&tmp_dev); + + for (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 == class_rev) + { + pciinfo("Found: %s\n", types[i]->name); + if (types[i]->probe) + { + pciinfo("[%02x:%02x.%x] Probing\n", + bus_idx, slot_idx, func); + types[i]->probe(root_bus, types[i], tmp_dev.bdf); + } + else + { + pcierr("[%02x:%02x.%x] Error: Invalid \ + device probe function\n", + bus_idx, slot_idx, func); + } + + break; + } + } + } + } +} + +/**************************************************************************** + * Name: pci_check_pci_bridge + * + * Description: + * Checks if the specified device is PCI bridge and return the sub-bridge + * idx if found. Otherwise return 0. + * + * Input Parameters: + * root_bus - The root bus device that lets us address the whole tree + * bus - Bus ID + * slot - Device Slot + * func - Device Function + * + ****************************************************************************/ + +static uint8_t pci_check_pci_bridge(FAR struct pci_bus_s *root_bus, + uint8_t bus_idx, uint8_t slot_idx, + uint8_t dev_func) +{ + struct pci_dev_s tmp_dev; + uint8_t base_class; + uint8_t sub_class; + uint8_t secondary_bus; + + tmp_dev.bus = root_bus; + tmp_dev.bdf = PCI_BDF(bus_idx, slot_idx, dev_func); + + /* Check if this is a PCI-PCI bridge device */ + + base_class = root_bus->ops->pci_cfg_read(&tmp_dev, PCI_CONFIG_CLASS, 1); + sub_class = root_bus->ops->pci_cfg_read(&tmp_dev, PCI_CONFIG_SUBCLASS, 1); + + if ((base_class == PCI_CLASS_BASE_BRG_DEV) && \ + (sub_class == PCI_CLASS_SUB_PCI_BRG)) + { + /* This is a bridge device we need to determin the bus idx and + * enumerate it just like we do the root. + */ + + pciinfo("[%02x:%02x.%x] Found Bridge\n", + bus_idx, slot_idx, dev_func); + + secondary_bus = root_bus->ops->pci_cfg_read( + &tmp_dev, PCI_CONFIG_SEC_BUS, 1); + + return secondary_bus; + } + + return 0; +} + +/**************************************************************************** + * Name: pci_scan_device + * + * Description: + * Checks if the specified device is a bus and iterates over it or + * if it is a real device initializes it if recognized. + * + * Input Parameters: + * root_bus - The root bus device that lets us address the whole tree + * bus - Bus ID + * slot - Device Slot + * types - List of pointers to devices types recognized, NULL terminated + * + ****************************************************************************/ + +static void pci_scan_device(FAR struct pci_bus_s *root_bus, + uint8_t bus_idx, uint8_t slot_idx, + FAR const struct pci_dev_type_s **types) +{ + struct pci_dev_s tmp_dev; + uint8_t multi_function; + uint8_t dev_func = 0; + uint16_t vid; + uint8_t sec_bus; + + tmp_dev.bus = root_bus; + tmp_dev.bdf = PCI_BDF(bus_idx, slot_idx, dev_func); + vid = root_bus->ops->pci_cfg_read(&tmp_dev, PCI_CONFIG_VENDOR, 2); + if (vid == 0xffff) + { + return; + } + + /* Check if this is a PCI-PCI bridge device */ + + sec_bus = pci_check_pci_bridge(root_bus, bus_idx, slot_idx, dev_func); Review Comment: you are right: ``` pci_check_pci_bridge: [00:06.0] Found Bridge pci_check_pci_bridge: [00:06.0] Found Bridge pci_check_pci_bridge: [00:07.0] Found Bridge pci_check_pci_bridge: [00:07.0] Found Bridge ``` fixed now: ``` pci_check_pci_bridge: [00:06.0] Found Bridge pci_check_pci_bridge: [00:07.0] Found Bridge ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org