Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9612c2bc authored by Vikram Mulukutla's avatar Vikram Mulukutla
Browse files

qcom: peripheral-loader: Account for arm64 alignment requirements



ARM64 mandates that 8 byte accesses to/from device memory shall
only be allowed with 64 bit aligned addresses. The current Linux
ARM64 memset implementation does not account for alignment, and
memset_io is inefficient (it does a byte copy).

Until a more generic solution is implemented, account for this
alignement restriction by always passing in 64 bit aligned
address and size parameters to memset().

Change-Id: I2a3647486cc8a86531c79d1af53ba42957dd231b
Signed-off-by: default avatarVikram Mulukutla <markivx@codeaurora.org>
parent bc9a8f61
Loading
Loading
Loading
Loading
+20 −4
Original line number Original line Diff line number Diff line
@@ -575,20 +575,36 @@ static int pil_load_seg(struct pil_desc *desc, struct pil_seg *seg)
	paddr = seg->paddr + seg->filesz;
	paddr = seg->paddr + seg->filesz;
	count = seg->sz - seg->filesz;
	count = seg->sz - seg->filesz;
	while (count > 0) {
	while (count > 0) {
		int size;
		int size, orig_size;
		u8 __iomem *buf;
		u8 __iomem *buf;
		u8 bytes_before;
		u8 bytes_after;


		size = min_t(size_t, IOMAP_SIZE, count);
		orig_size = size = min_t(size_t, IOMAP_SIZE, count);
		buf = ioremap(paddr, size);
		buf = ioremap(paddr, size);
		if (!buf) {
		if (!buf) {
			pil_err(desc, "Failed to map memory\n");
			pil_err(desc, "Failed to map memory\n");
			return -ENOMEM;
			return -ENOMEM;
		}
		}

		if ((unsigned long)buf & 0x7) {
			bytes_before = 8 - ((unsigned long)buf & 0x7);
			memset_io(buf, 0, bytes_before);
			size -= bytes_before;
			buf += bytes_before;
		}

		if (size & 0x7) {
			bytes_after = size & 0x7;
			memset_io(buf + size - bytes_after, 0, bytes_after);
			size -= bytes_after;
		}

		memset(buf, 0, size);
		memset(buf, 0, size);
		iounmap(buf);
		iounmap(buf);


		count -= size;
		count -= orig_size;
		paddr += size;
		paddr += orig_size;
	}
	}


	if (desc->ops->verify_blob) {
	if (desc->ops->verify_blob) {