xref: /openbmc/u-boot/arch/sandbox/lib/pci_io.c (revision ad5b5801)
1 /*
2  * Copyright (c) 2014 Google, Inc
3  * Written by Simon Glass <sjg@chromium.org>
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7 
8 /*
9  * IO space access commands.
10  */
11 
12 #include <common.h>
13 #include <command.h>
14 #include <dm.h>
15 #include <asm/io.h>
16 
17 int 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 
38 	debug("%s: failed: addr=%x\n", __func__, paddr);
39 	return -ENOSYS;
40 }
41 
42 int 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 
52 static 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 
74 static 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 
95 int inl(unsigned int addr)
96 {
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 
105 int inw(unsigned int addr)
106 {
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 
115 int inb(unsigned int addr)
116 {
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 
125 void outl(unsigned int value, unsigned int addr)
126 {
127 	pci_io_write(addr, value, PCI_SIZE_32);
128 }
129 
130 void outw(unsigned int value, unsigned int addr)
131 {
132 	pci_io_write(addr, value, PCI_SIZE_16);
133 }
134 
135 void outb(unsigned int value, unsigned int addr)
136 {
137 	pci_io_write(addr, value, PCI_SIZE_8);
138 }
139