Lines Matching +full:address +full:- +full:aligned

1 // SPDX-License-Identifier: GPL-2.0-only
3 * imr.c -- Intel Isolated Memory Region driver
6 * Copyright(c) 2015 Bryan O'Donoghue <pure.logic@nexus-software.ie>
10 * When a device behind a masked port performs an access - snooped or
22 * See quark-x1000-datasheet.pdf for register definitions.
23 * http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/quark-x1000-datasheet.pdf
28 #include <asm-generic/sections.h>
50 * See quark-x1000-datasheet.pdf sections 12.7.4.5 and 12.7.4.6 for
56 * 23:2 1 KiB aligned lo address
61 * 23:2 1 KiB aligned hi address
79 * imr_is_enabled - true if an IMR is enabled false otherwise.
81 * Determines if an IMR is enabled based on address range and read/write
82 * mask. An IMR set with an address range set to zero and a read/write
84 * other state - for example set to zero but without read/write access
94 return !(imr->rmask == IMR_READ_ACCESS_ALL && in imr_is_enabled()
95 imr->wmask == IMR_WRITE_ACCESS_ALL && in imr_is_enabled()
96 imr_to_phys(imr->addr_lo) == 0 && in imr_is_enabled()
97 imr_to_phys(imr->addr_hi) == 0); in imr_is_enabled()
101 * imr_read - read an IMR at a given index.
107 * @imr: IMR structure representing address and access masks.
112 u32 reg = imr_id * IMR_NUM_REGS + idev->reg_base; in imr_read()
115 ret = iosf_mbi_read(QRK_MBI_UNIT_MM, MBI_REG_READ, reg++, &imr->addr_lo); in imr_read()
119 ret = iosf_mbi_read(QRK_MBI_UNIT_MM, MBI_REG_READ, reg++, &imr->addr_hi); in imr_read()
123 ret = iosf_mbi_read(QRK_MBI_UNIT_MM, MBI_REG_READ, reg++, &imr->rmask); in imr_read()
127 return iosf_mbi_read(QRK_MBI_UNIT_MM, MBI_REG_READ, reg++, &imr->wmask); in imr_read()
131 * imr_write - write an IMR at a given index.
134 * Note lock bits need to be written independently of address bits.
138 * @imr: IMR structure representing address and access masks.
144 u32 reg = imr_id * IMR_NUM_REGS + idev->reg_base; in imr_write()
149 ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE, reg++, imr->addr_lo); in imr_write()
153 ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE, reg++, imr->addr_hi); in imr_write()
157 ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE, reg++, imr->rmask); in imr_write()
161 ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE, reg++, imr->wmask); in imr_write()
174 WARN(ret, "IOSF-MBI write fail range 0x%08x-0x%08x unreliable\n", in imr_write()
175 imr_to_phys(imr->addr_lo), imr_to_phys(imr->addr_hi) + IMR_MASK); in imr_write()
181 * imr_dbgfs_state_show - print state of IMR registers.
192 struct imr_device *idev = s->private; in imr_dbgfs_state_show()
195 int ret = -ENODEV; in imr_dbgfs_state_show()
197 mutex_lock(&idev->lock); in imr_dbgfs_state_show()
199 for (i = 0; i < idev->max_imr; i++) { in imr_dbgfs_state_show()
213 size = end - base + 1; in imr_dbgfs_state_show()
226 mutex_unlock(&idev->lock); in imr_dbgfs_state_show()
232 * imr_debugfs_register - register debugfs hooks.
243 * imr_check_params - check passed address range IMR alignment and non-zero size
245 * @base: base address of intended IMR.
247 * @return: zero on valid range -EINVAL on unaligned base/size.
254 return -EINVAL; in imr_check_params()
257 return -EINVAL; in imr_check_params()
263 * imr_raw_size - account for the IMR_ALIGN bytes that addr_hi appends.
274 return size - IMR_ALIGN; in imr_raw_size()
278 * imr_address_overlap - detects an address overlap.
280 * @addr: address to check against an existing IMR.
286 return addr >= imr_to_phys(imr->addr_lo) && addr <= imr_to_phys(imr->addr_hi); in imr_address_overlap()
290 * imr_add_range - add an Isolated Memory Region.
292 * @base: physical base address of region aligned to 1KiB.
293 * @size: physical size of region in bytes must be aligned to 1KiB.
309 if (WARN_ONCE(idev->init == false, "driver not initialized")) in imr_add_range()
310 return -ENODEV; in imr_add_range()
329 return -ENOTSUPP; in imr_add_range()
331 mutex_lock(&idev->lock); in imr_add_range()
339 reg = -1; in imr_add_range()
340 for (i = 0; i < idev->max_imr; i++) { in imr_add_range()
346 ret = -EINVAL; in imr_add_range()
358 if (reg == -1) { in imr_add_range()
359 ret = -ENOMEM; in imr_add_range()
363 pr_debug("add %d phys %pa-%pa size %zx mask 0x%08x wmask 0x%08x\n", in imr_add_range()
386 mutex_unlock(&idev->lock); in imr_add_range()
392 * __imr_remove_range - delete an Isolated Memory Region.
395 * by address range specified by base and size respectively. If you specify an
398 * imr_remove_range(-1, base, size); delete IMR from base to base+size.
401 * @base: physical base address of region aligned to 1 KiB.
402 * @size: physical size of region in bytes aligned to 1 KiB.
403 * @return: -EINVAL on invalid range or out or range id
404 * -ENODEV if reg is valid but no IMR exists or is locked
417 if (WARN_ONCE(idev->init == false, "driver not initialized")) in __imr_remove_range()
418 return -ENODEV; in __imr_remove_range()
421 * Validate address range if deleting by address, else we are in __imr_remove_range()
424 if (reg == -1) { in __imr_remove_range()
434 mutex_lock(&idev->lock); in __imr_remove_range()
443 ret = -ENODEV; in __imr_remove_range()
448 /* Search for match based on address range. */ in __imr_remove_range()
449 for (i = 0; i < idev->max_imr; i++) { in __imr_remove_range()
467 ret = -ENODEV; in __imr_remove_range()
471 pr_debug("remove %d phys %pa-%pa size %zx\n", reg, &base, &end, raw_size); in __imr_remove_range()
482 mutex_unlock(&idev->lock); in __imr_remove_range()
487 * imr_remove_range - delete an Isolated Memory Region by address
489 * This function allows you to delete an IMR by an address range specified
493 * @base: physical base address of region aligned to 1 KiB.
494 * @size: physical size of region in bytes aligned to 1 KiB.
495 * @return: -EINVAL on invalid range or out or range id
496 * -ENODEV if reg is valid but no IMR exists or is locked
501 return __imr_remove_range(-1, base, size); in imr_remove_range()
506 * imr_clear - delete an Isolated Memory Region by index
508 * This function allows you to delete an IMR by an address range specified
510 * address map.
514 * @return: -EINVAL on invalid range or out or range id
515 * -ENODEV if reg is valid but no IMR exists or is locked
524 * imr_fixup_memmap - Tear down IMRs used during bootup.
530 * As a result if you're running a root filesystem from SD - you'll need
531 * the boot-time IMRs torn down or you'll find seemingly random resets when
540 size_t size = virt_to_phys(&__end_rodata) - base; in imr_fixup_memmap()
546 for (i = 0; i < idev->max_imr; i++) in imr_fixup_memmap()
550 end = (unsigned long)__end_rodata - 1; in imr_fixup_memmap()
557 * We don't round up @size since it is already PAGE_SIZE aligned. in imr_fixup_memmap()
562 pr_err("unable to setup IMR for kernel: %zu KiB (%lx - %lx)\n", in imr_fixup_memmap()
565 pr_info("protecting kernel .text - .rodata: %zu KiB (%lx - %lx)\n", in imr_fixup_memmap()
577 * imr_init - entry point for IMR driver.
579 * return: -ENODEV for no IMR support 0 if good to go.
586 return -ENODEV; in imr_init()
588 idev->max_imr = QUARK_X1000_IMR_MAX; in imr_init()
589 idev->reg_base = QUARK_X1000_IMR_REGBASE; in imr_init()
590 idev->init = true; in imr_init()
592 mutex_init(&idev->lock); in imr_init()