ecam.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-10-24 GuEe-GUI first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #define DBG_TAG "pci.ecam"
  13. #define DBG_LVL DBG_INFO
  14. #include <rtdbg.h>
  15. #include "ecam.h"
  16. struct pci_ecam_config_window *pci_ecam_create(struct rt_pci_host_bridge *host_bridge,
  17. const struct pci_ecam_ops *ops)
  18. {
  19. struct pci_ecam_config_window *conf_win = rt_calloc(1, sizeof(*conf_win));
  20. if (!conf_win)
  21. {
  22. return RT_NULL;
  23. }
  24. conf_win->bus_range = host_bridge->bus_range;
  25. conf_win->bus_shift = ops->bus_shift;
  26. conf_win->ops = ops;
  27. host_bridge->ops = (const struct rt_pci_ops *)&ops->pci_ops;
  28. return conf_win;
  29. }
  30. void *pci_ecam_map(struct rt_pci_bus *bus, rt_uint32_t devfn, int where)
  31. {
  32. struct pci_ecam_config_window *conf_win = bus->sysdata;
  33. const struct pci_ecam_ops *eops = conf_win->ops;
  34. void *win = conf_win->win, *map;
  35. rt_uint32_t busn = bus->number, bus_shift = eops->bus_shift, devfn_shift = bus_shift - 8;
  36. busn -= conf_win->bus_range[0];
  37. if (bus_shift)
  38. {
  39. rt_uint32_t bus_offset = (busn & PCIE_ECAM_BUS_MASK) << bus_shift;
  40. rt_uint32_t devfn_offset = (devfn & PCIE_ECAM_DEVFN_MASK) << devfn_shift;
  41. where &= PCIE_ECAM_REG_MASK;
  42. map = win + (bus_offset | devfn_offset | where);
  43. }
  44. else
  45. {
  46. map = win + PCIE_ECAM_OFFSET(busn, devfn, where);
  47. }
  48. return map;
  49. }
  50. const struct pci_ecam_ops pci_generic_ecam_ops =
  51. {
  52. .pci_ops =
  53. {
  54. .map = pci_ecam_map,
  55. .read = rt_pci_bus_read_config_uxx,
  56. .write = rt_pci_bus_write_config_uxx,
  57. }
  58. };