blob: 2038141947ab7b7adbb7ac0cc898b3f1b6521c4a [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glass70778bc2015-03-05 12:25:26 -07002/*
3 * Copyright (c) 2014 Google, Inc
4 * Written by Simon Glass <sjg@chromium.org>
Simon Glass70778bc2015-03-05 12:25:26 -07005 */
6
7/*
8 * IO space access commands.
9 */
10
11#include <common.h>
12#include <command.h>
13#include <dm.h>
Simon Glass0f2af882020-05-10 11:40:05 -060014#include <log.h>
Simon Glass70778bc2015-03-05 12:25:26 -070015#include <asm/io.h>
16
17int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp,
18 struct udevice **devp, void **ptrp)
19{
20 struct udevice *dev;
21 int ret;
22
23 *ptrp = 0;
24 for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
25 dev;
26 uclass_next_device(&dev)) {
27 struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
28
29 if (!ops || !ops->map_physmem)
30 continue;
31 ret = (ops->map_physmem)(dev, paddr, lenp, ptrp);
32 if (ret)
33 continue;
34 *devp = dev;
35 return 0;
36 }
37
Thierry Reding82222602019-03-12 11:38:02 +010038 debug("%s: failed: addr=%pap\n", __func__, &paddr);
Simon Glass70778bc2015-03-05 12:25:26 -070039 return -ENOSYS;
40}
41
42int pci_unmap_physmem(const void *vaddr, unsigned long len,
43 struct udevice *dev)
44{
45 struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
46
47 if (!ops || !ops->unmap_physmem)
48 return -ENOSYS;
49 return (ops->unmap_physmem)(dev, vaddr, len);
50}
51
52static int pci_io_read(unsigned int addr, ulong *valuep, pci_size_t size)
53{
54 struct udevice *dev;
55 int ret;
56
57 *valuep = pci_get_ff(size);
58 for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
59 dev;
60 uclass_next_device(&dev)) {
61 struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
62
63 if (ops && ops->read_io) {
64 ret = (ops->read_io)(dev, addr, valuep, size);
65 if (!ret)
66 return 0;
67 }
68 }
69
70 debug("%s: failed: addr=%x\n", __func__, addr);
71 return -ENOSYS;
72}
73
74static int pci_io_write(unsigned int addr, ulong value, pci_size_t size)
75{
76 struct udevice *dev;
77 int ret;
78
79 for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
80 dev;
81 uclass_next_device(&dev)) {
82 struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
83
84 if (ops && ops->write_io) {
85 ret = (ops->write_io)(dev, addr, value, size);
86 if (!ret)
87 return 0;
88 }
89 }
90
91 debug("%s: failed: addr=%x, value=%lx\n", __func__, addr, value);
92 return -ENOSYS;
93}
94
Simon Glassca6f1212019-09-25 08:56:02 -060095int _inl(unsigned int addr)
Simon Glass70778bc2015-03-05 12:25:26 -070096{
97 unsigned long value;
98 int ret;
99
100 ret = pci_io_read(addr, &value, PCI_SIZE_32);
101
102 return ret ? 0 : value;
103}
104
Simon Glassca6f1212019-09-25 08:56:02 -0600105int _inw(unsigned int addr)
Simon Glass70778bc2015-03-05 12:25:26 -0700106{
107 unsigned long value;
108 int ret;
109
110 ret = pci_io_read(addr, &value, PCI_SIZE_16);
111
112 return ret ? 0 : value;
113}
114
Simon Glassca6f1212019-09-25 08:56:02 -0600115int _inb(unsigned int addr)
Simon Glass70778bc2015-03-05 12:25:26 -0700116{
117 unsigned long value;
118 int ret;
119
120 ret = pci_io_read(addr, &value, PCI_SIZE_8);
121
122 return ret ? 0 : value;
123}
124
Simon Glassca6f1212019-09-25 08:56:02 -0600125void _outl(unsigned int value, unsigned int addr)
Simon Glass70778bc2015-03-05 12:25:26 -0700126{
127 pci_io_write(addr, value, PCI_SIZE_32);
128}
129
Simon Glassca6f1212019-09-25 08:56:02 -0600130void _outw(unsigned int value, unsigned int addr)
Simon Glass70778bc2015-03-05 12:25:26 -0700131{
132 pci_io_write(addr, value, PCI_SIZE_16);
133}
134
Simon Glassca6f1212019-09-25 08:56:02 -0600135void _outb(unsigned int value, unsigned int addr)
Simon Glass70778bc2015-03-05 12:25:26 -0700136{
137 pci_io_write(addr, value, PCI_SIZE_8);
138}