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
11 #include <rthw.h>
12 #include <rtthread.h>
13
14 #define DBG_TAG "pci.ecam"
15 #define DBG_LVL DBG_INFO
16 #include <rtdbg.h>
17
18 #include "ecam.h"
19
pci_ecam_create(struct rt_pci_host_bridge * host_bridge,const struct pci_ecam_ops * ops)20 struct pci_ecam_config_window *pci_ecam_create(struct rt_pci_host_bridge *host_bridge,
21 const struct pci_ecam_ops *ops)
22 {
23 struct pci_ecam_config_window *conf_win = rt_calloc(1, sizeof(*conf_win));
24
25 if (!conf_win)
26 {
27 return RT_NULL;
28 }
29
30 conf_win->bus_range = host_bridge->bus_range;
31 conf_win->bus_shift = ops->bus_shift;
32 conf_win->ops = ops;
33
34 host_bridge->ops = (const struct rt_pci_ops *)&ops->pci_ops;
35
36 return conf_win;
37 }
38
pci_ecam_map(struct rt_pci_bus * bus,rt_uint32_t devfn,int where)39 void *pci_ecam_map(struct rt_pci_bus *bus, rt_uint32_t devfn, int where)
40 {
41 struct pci_ecam_config_window *conf_win = bus->sysdata;
42 const struct pci_ecam_ops *eops = conf_win->ops;
43 void *win = conf_win->win, *map;
44 rt_uint32_t busn = bus->number, bus_shift = eops->bus_shift, devfn_shift = bus_shift - 8;
45
46 busn -= conf_win->bus_range[0];
47
48 if (bus_shift)
49 {
50 rt_uint32_t bus_offset = (busn & PCIE_ECAM_BUS_MASK) << bus_shift;
51 rt_uint32_t devfn_offset = (devfn & PCIE_ECAM_DEVFN_MASK) << devfn_shift;
52
53 where &= PCIE_ECAM_REG_MASK;
54 map = win + (bus_offset | devfn_offset | where);
55 }
56 else
57 {
58 map = win + PCIE_ECAM_OFFSET(busn, devfn, where);
59 }
60
61 return map;
62 }
63
64 const struct pci_ecam_ops pci_generic_ecam_ops =
65 {
66 .pci_ops =
67 {
68 .map = pci_ecam_map,
69 .read = rt_pci_bus_read_config_uxx,
70 .write = rt_pci_bus_write_config_uxx,
71 }
72 };
73