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