xref: /openbmc/u-boot/arch/sandbox/lib/pci_io.c (revision cbd2fba1)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2014 Google, Inc
4  * Written by Simon Glass <sjg@chromium.org>
5  */
6 
7 /*
8  * IO space access commands.
9  */
10 
11 #include <common.h>
12 #include <command.h>
13 #include <dm.h>
14 #include <asm/io.h>
15 
16 int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp,
17 		    struct udevice **devp, void **ptrp)
18 {
19 	struct udevice *dev;
20 	int ret;
21 
22 	*ptrp = 0;
23 	for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
24 	     dev;
25 	     uclass_next_device(&dev)) {
26 		struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
27 
28 		if (!ops || !ops->map_physmem)
29 			continue;
30 		ret = (ops->map_physmem)(dev, paddr, lenp, ptrp);
31 		if (ret)
32 			continue;
33 		*devp = dev;
34 		return 0;
35 	}
36 
37 	debug("%s: failed: addr=%x\n", __func__, paddr);
38 	return -ENOSYS;
39 }
40 
41 int pci_unmap_physmem(const void *vaddr, unsigned long len,
42 		      struct udevice *dev)
43 {
44 	struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
45 
46 	if (!ops || !ops->unmap_physmem)
47 		return -ENOSYS;
48 	return (ops->unmap_physmem)(dev, vaddr, len);
49 }
50 
51 static int pci_io_read(unsigned int addr, ulong *valuep, pci_size_t size)
52 {
53 	struct udevice *dev;
54 	int ret;
55 
56 	*valuep = pci_get_ff(size);
57 	for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
58 	     dev;
59 	     uclass_next_device(&dev)) {
60 		struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
61 
62 		if (ops && ops->read_io) {
63 			ret = (ops->read_io)(dev, addr, valuep, size);
64 			if (!ret)
65 				return 0;
66 		}
67 	}
68 
69 	debug("%s: failed: addr=%x\n", __func__, addr);
70 	return -ENOSYS;
71 }
72 
73 static int pci_io_write(unsigned int addr, ulong value, pci_size_t size)
74 {
75 	struct udevice *dev;
76 	int ret;
77 
78 	for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
79 	     dev;
80 	     uclass_next_device(&dev)) {
81 		struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
82 
83 		if (ops && ops->write_io) {
84 			ret = (ops->write_io)(dev, addr, value, size);
85 			if (!ret)
86 				return 0;
87 		}
88 	}
89 
90 	debug("%s: failed: addr=%x, value=%lx\n", __func__, addr, value);
91 	return -ENOSYS;
92 }
93 
94 int inl(unsigned int addr)
95 {
96 	unsigned long value;
97 	int ret;
98 
99 	ret = pci_io_read(addr, &value, PCI_SIZE_32);
100 
101 	return ret ? 0 : value;
102 }
103 
104 int inw(unsigned int addr)
105 {
106 	unsigned long value;
107 	int ret;
108 
109 	ret = pci_io_read(addr, &value, PCI_SIZE_16);
110 
111 	return ret ? 0 : value;
112 }
113 
114 int inb(unsigned int addr)
115 {
116 	unsigned long value;
117 	int ret;
118 
119 	ret = pci_io_read(addr, &value, PCI_SIZE_8);
120 
121 	return ret ? 0 : value;
122 }
123 
124 void outl(unsigned int value, unsigned int addr)
125 {
126 	pci_io_write(addr, value, PCI_SIZE_32);
127 }
128 
129 void outw(unsigned int value, unsigned int addr)
130 {
131 	pci_io_write(addr, value, PCI_SIZE_16);
132 }
133 
134 void outb(unsigned int value, unsigned int addr)
135 {
136 	pci_io_write(addr, value, PCI_SIZE_8);
137 }
138