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