/* * Read a value from configuration space */ static int octeon_read_config(struct pci_bus *bus, unsigned int devfn, int reg, int size, u32 *val) { union octeon_pci_address pci_addr; pci_addr.u64 = 0; pci_addr.s.upper = 2; pci_addr.s.io = 1; pci_addr.s.did = 3; pci_addr.s.subdid = 1; pci_addr.s.endian_swap = 1; pci_addr.s.bus = bus->number; pci_addr.s.dev = devfn >> 3; pci_addr.s.func = devfn & 0x7; pci_addr.s.reg = reg; #if PCI_CONFIG_SPACE_DELAY udelay(PCI_CONFIG_SPACE_DELAY); #endif switch (size) { case 4: *val = le32_to_cpu(cvmx_read64_uint32(pci_addr.u64)); return PCIBIOS_SUCCESSFUL; case 2: *val = le16_to_cpu(cvmx_read64_uint16(pci_addr.u64)); return PCIBIOS_SUCCESSFUL; case 1: *val = cvmx_read64_uint8(pci_addr.u64); return PCIBIOS_SUCCESSFUL; } return PCIBIOS_FUNC_NOT_SUPPORTED; }
static uint32_t octopci_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, int bytes) { struct octopci_softc *sc; uint64_t addr; uint32_t data; sc = device_get_softc(dev); addr = octopci_cs_addr(bus, slot, func, reg); switch (bytes) { case 4: data = le32toh(cvmx_read64_uint32(addr)); return (data); case 2: data = le16toh(cvmx_read64_uint16(addr)); return (data); case 1: data = cvmx_read64_uint8(addr); return (data); default: return ((uint32_t)-1); } }
void ehci_writel(volatile u32 *addr32, u32 val) { u64 addr64 = 0x80016F0000000000ull + (ulong)addr32; u32 val2 = 0; cvmx_write64_uint32(addr64, val); val2 = cvmx_read64_uint32(addr64); debug("%s: wrote 0x%08x to address %p (0x%llx), read back 0x%08x\n", __func__, val, addr32, addr64, val2); }
/** * Read 32bits from a Device's config space * * @pcie_port: PCIe port the device is on * @bus: Sub bus * @dev: Device ID * @fn: Device sub function * @reg: Register to access * * Returns Result of the read */ static uint32_t cvmx_pcie_config_read32(int pcie_port, int bus, int dev, int fn, int reg) { uint64_t address = __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg); if (address) return le32_to_cpu(cvmx_read64_uint32(address)); else return 0xffffffff; }
u32 ehci_readl(volatile u32 *addr32) { u64 addr64 = 0x80016F0000000000ull + (ulong)addr32; u32 val; val = cvmx_read64_uint32(addr64); debug("%s: read 0x%08x from address %p (0x%llx)\n", __func__, val, addr32, addr64); return val; }
int do_read64l(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { uint64_t addr; uint32_t val; if ((argc != 2)) { printf("Usage:\n%s\n", cmdtp->usage); return 1; } addr = simple_strtoull(argv[1], NULL, 16); addr += base_address64; printf("attempting to read from addr: 0x%llx\n", addr); val = cvmx_read64_uint32(addr); printf("0x%llx: 0x%x\n", addr, val); return (0); }
int print_buffer64(uint64_t addr, uint64_t data, uint width, uint count, int swap, uint linelen) { /* linebuf as a union causes proper alignment */ union linebuf { uint64_t ud[MAX_LINE_LENGTH_BYTES/sizeof(uint64_t) + 1]; uint32_t ui[MAX_LINE_LENGTH_BYTES/sizeof(uint32_t) + 1]; uint16_t us[MAX_LINE_LENGTH_BYTES/sizeof(uint16_t) + 1]; uint8_t uc[MAX_LINE_LENGTH_BYTES/sizeof(uint8_t) + 1]; } lb; int i; if (linelen*width > MAX_LINE_LENGTH_BYTES) linelen = MAX_LINE_LENGTH_BYTES / width; if (linelen < 1) linelen = DEFAULT_LINE_LENGTH_BYTES / width; while (count) { printf("%016llx:", addr); /* check for overflow condition */ if (count < linelen) linelen = count; /* Copy from memory into linebuf and print hex values */ for (i = 0; i < linelen; i++) { uint64_t x; if (width == 8) { x = lb.ud[i] = cvmx_read_csr(data); if (swap) x = swab64(x); } else if (width == 4) { x = lb.ui[i] = cvmx_read64_uint32(data); if (swap) x = swab32(x); } else if (width == 2) { x = lb.us[i] = cvmx_read64_uint16(data); if (swap) x = swab16(x); } else { x = lb.uc[i] = cvmx_read64_int8(data); } printf(" %0*llx", width * 2, x); data += width; } /* Print data in ASCII characters */ for (i = 0; i < linelen * width; i++) { if (!isprint(lb.uc[i]) || lb.uc[i] >= 0x80) lb.uc[i] = '.'; } lb.uc[i] = '\0'; printf(" %s\n", lb.uc); /* update references */ addr += linelen * width; count -= linelen; if (ctrlc()) return -1; } return 0; }
int do_mem_loop64(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint64_t addr, length, i, dummy; int size; if (argc < 3) return CMD_RET_USAGE; /* Check for a size spefication. * Defaults to long if no or incorrect specification. */ if ((size = cmd_get_data_size(argv[0], 8)) < 0) return 1; /* Address is always specified. */ addr = simple_strtoull(argv[1], NULL, 16); /* Length is the number of objects, not number of bytes. */ length = simple_strtoull(argv[2], NULL, 16); /* We want to optimize the loops to run as fast as possible. * If we have only one object, just run infinite loops. */ if (length == 1) { if (size == 8) { for (;;) i = cvmx_read_csr(addr); } else if (size == 4) { for (;;) i = cvmx_read64_uint32(addr); } if (size == 2) { for (;;) i = cvmx_read64_uint16(addr); } for (;;) i = cvmx_read64_uint8(addr); } if (size == 8) { for (;;) { dummy = addr; i = length; while (i-- > 0) cvmx_write_csr(dummy, cvmx_read_csr(dummy) + 1); } } else if (size == 4) { for (;;) { dummy = addr; i = length; while (i-- > 0) cvmx_write64_uint32(dummy, cvmx_read64_uint32(dummy) + 1); } } if (size == 2) { for (;;) { dummy = addr; i = length; while (i-- > 0) cvmx_write64_uint16(dummy, cvmx_read64_uint16(dummy) + 1); } } for (;;) { dummy = addr; i = length; while (i-- > 0) cvmx_write64_uint8(dummy, cvmx_read64_uint8(dummy) + 1); } return -1; }
int do_mem_cp64 ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint64_t addr, dest, count; int size; if (argc != 4) return CMD_RET_USAGE; /* Check for size specification. */ if ((size = cmd_get_data_size(argv[0], 8)) < 0) return 1; addr = simple_strtoull(argv[1], NULL, 16); addr |= base_address64; dest = simple_strtoull(argv[2], NULL, 16); dest |= base_address64; count = simple_strtoull(argv[3], NULL, 16); if (count == 0) { puts ("Zero length ???\n"); return 1; } #ifndef CONFIG_SYS_NO_FLASH /* check if we are copying to Flash */ if ( (dest < 0xc0000000 && addr2info(dest) != NULL) #ifdef CONFIG_HAS_DATAFLASH && (!addr_dataflash(dest)) #endif ) { int rc; if (addr + count >= 0x100000000ull) { puts("Source address too high to copy to flash\n"); return 1; } puts ("Copy to Flash... "); rc = flash_write ((char *)((uint32_t)addr), (uint32_t)dest, count * size); if (rc != 0) { flash_perror (rc); return (1); } puts ("done\n"); return 0; } #endif #ifdef CONFIG_HAS_DATAFLASH /* Check if we are copying from RAM or Flash to DataFlash */ if ((dest < 0xc0000000) && addr_dataflash((uint32_t)dest) && !addr_dataflash((uint32_t)addr)) { int rc; if (addr + count >= 0x100000000ull) { puts("Source address is too high to copy to flash\n"); return 1; } puts ("Copy to DataFlash... "); rc = write_dataflash (dest, addr, count*size); if (rc != 1) { dataflash_perror (rc); return (1); } puts ("done\n"); return 0; } /* Check if we are copying from DataFlash to RAM */ if ((addr < 0xc0000000) && addr_dataflash((uint32_t)addr) && (dest + count < 0x100000000ull) && !addr_dataflash((uint32_t)dest) #ifndef CONFIG_SYS_NO_FLASH && (addr2info((uint32_t)dest) == NULL) #endif ) { int rc; rc = read_dataflash((uint32_t)addr, count * size, (char *)((uint32_t)dest)); if (rc != 1) { dataflash_perror (rc); return (1); } return 0; } if ((addr | dest) < 0x10000000ull && addr_dataflash(addr) && addr_dataflash(dest)) { puts ("Unsupported combination of source/destination.\n\r"); return 1; } #endif while (count-- > 0) { if (size == 8) cvmx_write_csr(dest, cvmx_read_csr(addr)); else if (size == 4) cvmx_write64_uint32(dest, cvmx_read64_uint32(addr)); else if (size == 2) cvmx_write64_uint16(dest, cvmx_read64_uint16(addr)); else cvmx_write64_uint8(dest, cvmx_read64_uint8(addr)); addr += size; dest += size; /* reset watchdog from time to time */ if ((count % (64 << 10)) == 0) WATCHDOG_RESET(); } return 0; }
int do_mem_cmp64 (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint64_t addr1, addr2, count, ngood; int size; int rcode = 0; const char *type; if (argc != 4) return CMD_RET_USAGE; /* Check for size specification. */ if ((size = cmd_get_data_size(argv[0], 8)) < 0) return 1; type = size == 8 ? "dword" : size == 4 ? "word" : size == 2 ? "halfword" : "byte"; addr1 = simple_strtoull(argv[1], NULL, 16); addr1 |= base_address64; addr2 = simple_strtoull(argv[2], NULL, 16); addr2 |= base_address64; count = simple_strtoull(argv[3], NULL, 16); #ifdef CONFIG_HAS_DATAFLASH if (addr_dataflash(addr1) | addr_dataflash(addr2)) { puts ("Comparison with DataFlash space not supported.\n\r"); return 0; } #endif for (ngood = 0; ngood < count; ++ngood) { uint64_t word1, word2; if (size == 8) { word1 = cvmx_read_csr(addr1); word2 = cvmx_read_csr(addr2); } else if (size == 4) { word1 = cvmx_read64_uint32(addr1); word2 = cvmx_read64_uint32(addr2); } else if (size == 2) { word1 = cvmx_read64_uint16(addr1); word2 = cvmx_read64_uint16(addr2); } else { word1 = cvmx_read64_uint8(addr1); word2 = cvmx_read64_uint8(addr2); } if (word1 != word2) { printf("%s at 0x%016llx (%#0*llx) != %s at 0x%16llx (%#0*llx)\n", type, addr1, size, word1, type, addr2, size, word2); rcode = 1; break; } addr1 += size; addr2 += size; /* reset watchdog from time to time */ if ((ngood % (64 << 10)) == 0) WATCHDOG_RESET(); } printf("Total of %llu %s(s) were the same\n", ngood, type); return rcode; }
/** * @INTERNAL * Read a USB 32bit CSR. It performs the necessary address swizzle for 32bit * CSRs. * * @param usb USB device state populated by * cvmx_usbd_initialize(). * @param address 64bit address to read * * @return Result of the read */ static inline uint32_t __cvmx_usbd_read_csr32(cvmx_usbd_state_t *usb, uint64_t address) { uint32_t result = cvmx_read64_uint32(address ^ 4); return result; }