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