* [PATCH v3, 1/5] powerpc: sysdev: fix compile error for fsl_85xx_l2ctlr
From: Wang Wenhu @ 2020-04-24 2:45 UTC (permalink / raw)
To: gregkh, arnd, linux-kernel, linuxppc-dev
Cc: robh, oss, kernel, paulus, Wang Wenhu
In-Reply-To: <20200424024554.30709-1-wenhu.wang@vivo.com>
Include "linux/of_address.h" to fix the compile error for
mpc85xx_l2ctlr_of_probe() when compiling fsl_85xx_cache_sram.c.
CC arch/powerpc/sysdev/fsl_85xx_l2ctlr.o
arch/powerpc/sysdev/fsl_85xx_l2ctlr.c: In function ‘mpc85xx_l2ctlr_of_probe’:
arch/powerpc/sysdev/fsl_85xx_l2ctlr.c:90:11: error: implicit declaration of function ‘of_iomap’; did you mean ‘pci_iomap’? [-Werror=implicit-function-declaration]
l2ctlr = of_iomap(dev->dev.of_node, 0);
^~~~~~~~
pci_iomap
arch/powerpc/sysdev/fsl_85xx_l2ctlr.c:90:9: error: assignment makes pointer from integer without a cast [-Werror=int-conversion]
l2ctlr = of_iomap(dev->dev.of_node, 0);
^
cc1: all warnings being treated as errors
scripts/Makefile.build:267: recipe for target 'arch/powerpc/sysdev/fsl_85xx_l2ctlr.o' failed
make[2]: *** [arch/powerpc/sysdev/fsl_85xx_l2ctlr.o] Error 1
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Christophe Leroy <christophe.leroy@c-s.fr>
Cc: Scott Wood <oss@buserror.net>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: linuxppc-dev@lists.ozlabs.org
Fixes: 6db92cc9d07d ("powerpc/85xx: add cache-sram support")
Reviewed-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Wang Wenhu <wenhu.wang@vivo.com>
---
No changes
---
arch/powerpc/sysdev/fsl_85xx_l2ctlr.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
index 2d0af0c517bb..7533572492f0 100644
--- a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
+++ b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_platform.h>
+#include <linux/of_address.h>
#include <asm/io.h>
#include "fsl_85xx_cache_ctlr.h"
--
2.17.1
^ permalink raw reply related
* [PATCH v3,0/5] misc: generic user level sram dynamic access support
From: Wang Wenhu @ 2020-04-24 2:45 UTC (permalink / raw)
To: gregkh, arnd, linux-kernel, linuxppc-dev
Cc: robh, oss, kernel, paulus, Wang Wenhu
This series add a new misc module that act as an interface for user level
applications to access SRAM memory dynamically. Freescale 85xx Cache-SRAM
is exact an example.
This is extremely helpful for the user level applications that require
high performance memory accesses, such as some embedded networking devices
that need to process data in user space.
The series also fix the compile errors and warning of the freescale 85xx
Cache-SRAM driver, and implement a module to register the SRAM device to
sram_dynamic module, which enables its access for users in user space.
Changes since v1: addressed comments from Arnd
* Changed the ioctl cmd definitions using _IO micros
* Export interfaces for HW-SRAM drivers to register apis to available list
* Modified allocation alignment to PAGE_SIZE
* Use phys_addr_t as type of SRAM resource size and offset
* Support compat_ioctl
* Misc device name:sram
* Use tristate for SRAM_UAPI
* Use postcore_initcall
Changes since v2: addressed comments from Arnd, greg and Scott
* Name the module with sram_dynamic in comparing with drivers/misc/sram.c
I tried to tie the sram_dynamic with the abstractions in sram.c as
Arnd suggested, and actually sram.c probes SRAM devices from devicetree
and manages them with different partitions and create memory pools which
are managed with genalloc functions.
Here sram_dynamic acts only as a interface to user space. A SRAM memory
pool is managed by the module that registers APIs to us, such as the
backend hardware driver of Freescale 85xx Cache-SRAM.
* Create one sram_device for each backend SRAM device(from Scott)
* Allow only one block of SRAM memory allocated to a file descriptor(from Scott)
* Add sysfs files for every allocated SRAM memory block
* More documentations(As Greg commented)
* Make uapi and non-uapi components apart(from Arnd and Greg)
* Add a new module to register freescale 85xx Cache-SRAM APIs to the
sram_dynamic module
Wang Wenhu (5):
powerpc: sysdev: fix compile error for fsl_85xx_l2ctlr
powerpc: sysdev: fix compile error for fsl_85xx_cache_sram
powerpc: sysdev: fix compile warning for fsl_85xx_cache_sram
misc: sram_dynamic for user level SRAM access
powerpc: sysdev: support userspace access of fsl 85xx sram
.../powerpc/include/asm/fsl_85xx_cache_sram.h | 4 +
arch/powerpc/platforms/85xx/Kconfig | 10 +
arch/powerpc/sysdev/Makefile | 1 +
arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h | 6 +
arch/powerpc/sysdev/fsl_85xx_cache_sram.c | 15 +-
arch/powerpc/sysdev/fsl_85xx_l2ctlr.c | 1 +
arch/powerpc/sysdev/fsl_85xx_sram_uapi.c | 39 ++
drivers/misc/Kconfig | 11 +
drivers/misc/Makefile | 1 +
drivers/misc/sram_dynamic.c | 580 ++++++++++++++++++
drivers/misc/sram_uapi.c | 351 +++++++++++
include/linux/sram_dynamic.h | 23 +
include/uapi/linux/sram.h | 11 +
13 files changed, 1052 insertions(+), 1 deletion(-)
create mode 100644 arch/powerpc/sysdev/fsl_85xx_sram_uapi.c
create mode 100644 drivers/misc/sram_dynamic.c
create mode 100644 drivers/misc/sram_uapi.c
create mode 100644 include/linux/sram_dynamic.h
create mode 100644 include/uapi/linux/sram.h
--
2.17.1
^ permalink raw reply
* [PATCH v3, 2/5] powerpc: sysdev: fix compile error for fsl_85xx_cache_sram
From: Wang Wenhu @ 2020-04-24 2:45 UTC (permalink / raw)
To: gregkh, arnd, linux-kernel, linuxppc-dev
Cc: robh, oss, kernel, paulus, Wang Wenhu
In-Reply-To: <20200424024554.30709-1-wenhu.wang@vivo.com>
Include linux/io.h into fsl_85xx_cache_sram.c to fix the
implicit-declaration compile error when building Cache-Sram.
arch/powerpc/sysdev/fsl_85xx_cache_sram.c: In function ‘instantiate_cache_sram’:
arch/powerpc/sysdev/fsl_85xx_cache_sram.c:97:26: error: implicit declaration of function ‘ioremap_coherent’; did you mean ‘bitmap_complement’? [-Werror=implicit-function-declaration]
cache_sram->base_virt = ioremap_coherent(cache_sram->base_phys,
^~~~~~~~~~~~~~~~
bitmap_complement
arch/powerpc/sysdev/fsl_85xx_cache_sram.c:97:24: error: assignment makes pointer from integer without a cast [-Werror=int-conversion]
cache_sram->base_virt = ioremap_coherent(cache_sram->base_phys,
^
arch/powerpc/sysdev/fsl_85xx_cache_sram.c:123:2: error: implicit declaration of function ‘iounmap’; did you mean ‘roundup’? [-Werror=implicit-function-declaration]
iounmap(cache_sram->base_virt);
^~~~~~~
roundup
cc1: all warnings being treated as errors
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Christophe Leroy <christophe.leroy@c-s.fr>
Cc: Scott Wood <oss@buserror.net>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: linuxppc-dev@lists.ozlabs.org
Fixes: 6db92cc9d07d ("powerpc/85xx: add cache-sram support")
Reviewed-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Wang Wenhu <wenhu.wang@vivo.com>
---
No changes
---
arch/powerpc/sysdev/fsl_85xx_cache_sram.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
index f6c665dac725..be3aef4229d7 100644
--- a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
+++ b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
@@ -17,6 +17,7 @@
#include <linux/of_platform.h>
#include <asm/pgtable.h>
#include <asm/fsl_85xx_cache_sram.h>
+#include <linux/io.h>
#include "fsl_85xx_cache_ctlr.h"
--
2.17.1
^ permalink raw reply related
* [PATCH v3, 3/5] powerpc: sysdev: fix compile warning for fsl_85xx_cache_sram
From: Wang Wenhu @ 2020-04-24 2:45 UTC (permalink / raw)
To: gregkh, arnd, linux-kernel, linuxppc-dev
Cc: robh, oss, kernel, paulus, Wang Wenhu
In-Reply-To: <20200424024554.30709-1-wenhu.wang@vivo.com>
Function instantiate_cache_sram should not be linked into the init
section for its caller mpc85xx_l2ctlr_of_probe is none-__init.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Christophe Leroy <christophe.leroy@c-s.fr>
Cc: Scott Wood <oss@buserror.net>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: linuxppc-dev@lists.ozlabs.org
Fixes: 6db92cc9d07d ("powerpc/85xx: add cache-sram support")
Reviewed-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Wang Wenhu <wenhu.wang@vivo.com>
---
No changes
---
arch/powerpc/sysdev/fsl_85xx_cache_sram.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
index be3aef4229d7..3de5ac8382c0 100644
--- a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
+++ b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
@@ -68,7 +68,7 @@ void mpc85xx_cache_sram_free(void *ptr)
}
EXPORT_SYMBOL(mpc85xx_cache_sram_free);
-int __init instantiate_cache_sram(struct platform_device *dev,
+int instantiate_cache_sram(struct platform_device *dev,
struct sram_parameters sram_params)
{
int ret = 0;
--
2.17.1
^ permalink raw reply related
* [PATCH v3,4/5] misc: sram_dynamic for user level SRAM access
From: Wang Wenhu @ 2020-04-24 2:45 UTC (permalink / raw)
To: gregkh, arnd, linux-kernel, linuxppc-dev
Cc: robh, oss, kernel, paulus, Wang Wenhu
In-Reply-To: <20200424024554.30709-1-wenhu.wang@vivo.com>
A generic User-Kernel interface module that allows a misc device created
when a backend SRAM hardware device driver registers its APIs to support
file operations of ioctl and mmap for user space applications to allocate
SRAM memory, mmap it to process address space and free it then after.
It is extremely helpful for the user space applications that require
high performance memory accesses, such as embedded networking devices
that would process data in user space, and PowerPC e500 is one case.
Signed-off-by: Wang Wenhu <wenhu.wang@vivo.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Christophe Leroy <christophe.leroy@c-s.fr>
Cc: Scott Wood <oss@buserror.net>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: linuxppc-dev@lists.ozlabs.org
---
Changes since v1: addressed comments from Arnd
* Changed the ioctl cmd definitions using _IO micros
* Export interfaces for HW-SRAM drivers to register apis to available list
* Modified allocation alignment to PAGE_SIZE
* Use phys_addr_t as type of SRAM resource size and offset
* Support compat_ioctl
* Misc device name:sram
* Use tristate for SRAM_UAPI
* Use postcore_initcall
Changes since v2: addressed comments from Arnd, greg and Scott
* Name the module with sram_dynamic in comparing with drivers/misc/sram.c
I tried to tie the sram_dynamic with the abstractions in sram.c as
Arnd suggested, and actually sram.c probes SRAM devices from devicetree
and manages them with different partitions and create memory pools which
are managed with genalloc functions.
Here sram_dynamic acts only as a interface to user space. A SRAM memory
pool is managed by the module that registers APIs to us, such as the
backend hardware driver of Freescale 85xx Cache-SRAM.
* Create one sram_device for each backend SRAM device(from Scott)
* Allow only one block of SRAM memory allocated to a file descriptor(from Scott)
* Add sysfs files for every allocated SRAM memory block
* More documentations(As Greg commented)
* Make uapi and non-uapi components apart(from Arnd and Greg)
Links:
v1: https://lore.kernel.org/lkml/20200418162157.50428-5-wenhu.wang@vivo.com/
v2: https://lore.kernel.org/lkml/20200420030538.101696-1-wenhu.wang@vivo.com/
UIO version:
v5: https://lore.kernel.org/lkml/20200417071616.44598-5-wenhu.wang@vivo.com/
---
drivers/misc/Kconfig | 11 +
drivers/misc/Makefile | 1 +
drivers/misc/sram_dynamic.c | 580 +++++++++++++++++++++++++++++++++++
drivers/misc/sram_uapi.c | 351 +++++++++++++++++++++
include/linux/sram_dynamic.h | 23 ++
include/uapi/linux/sram.h | 11 +
6 files changed, 977 insertions(+)
create mode 100644 drivers/misc/sram_dynamic.c
create mode 100644 drivers/misc/sram_uapi.c
create mode 100644 include/linux/sram_dynamic.h
create mode 100644 include/uapi/linux/sram.h
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 99e151475d8f..b7ad84e93855 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -465,6 +465,17 @@ config PVPANIC
a paravirtualized device provided by QEMU; it lets a virtual machine
(guest) communicate panic events to the host.
+config SRAM_DYNAMIC
+ tristate "Generic SRAM User Level Dynamic Access API support"
+ help
+ This driver allows you to create a misc device which could be used
+ as an interface to allocate SRAM memory from user level dynamically.
+
+ It is extremely helpful for some user space applications that require
+ high performance memory accesses.
+
+ If unsure, say N.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 9abf2923d831..c32085026d30 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
obj-$(CONFIG_SRAM) += sram.o
obj-$(CONFIG_SRAM_EXEC) += sram-exec.o
+obj-$(CONFIG_SRAM_DYNAMIC) += sram_dynamic.o
obj-y += mic/
obj-$(CONFIG_GENWQE) += genwqe/
obj-$(CONFIG_ECHO) += echo/
diff --git a/drivers/misc/sram_dynamic.c b/drivers/misc/sram_dynamic.c
new file mode 100644
index 000000000000..ea2d4d92cccf
--- /dev/null
+++ b/drivers/misc/sram_dynamic.c
@@ -0,0 +1,580 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Vivo Communication Technology Co. Ltd.
+ * Copyright (C) 2020 Wang Wenhu <wenhu.wang@vivo.com>
+ * All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/cdev.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <uapi/linux/sram.h>
+#include <linux/sram_dynamic.h>
+
+#define SRAM_MAX_DEVICES (1U << MINORBITS)
+
+/**
+ * struct sram_res - allocated SRAM memory resource description.
+ *
+ * @virt: virtual memory address of the SRAM memory resource
+ * @phys: physical memory address of the SRAM memory resource
+ * @size: size of the SRAM memory resource
+ * @sdev: sram_device the resource belongs to
+ * @map: sysfs directory of the resource
+ */
+struct sram_res {
+ void __iomem *virt;
+ phys_addr_t phys;
+ __be64 size;
+ struct sram_device *sdev;
+ struct sram_map *map;
+};
+
+/**
+ * struct sram_device - character device that act as an User-Kernel interface.
+ *
+ * A sram_device is created when specific lower level hardware SRAM driver
+ * calls sram_register_device(). The SRAM hardware device is set as the
+ * parent of sram_device. Then user can create a file descriptor when they
+ * open specific sram_device. With the file descriptor, user could request
+ * SRAM memory through ioctl syscall. Available ioctl numbers are defined
+ * in "include/uapi/linux/sram.h".
+ *
+ * @dev: character device to be added to system during SRAM registration
+ * @owner: owner module of the device
+ * @minor: minor id of the character device
+ * @sa: APIs registered by SRAM hardware driver
+ * @map_dir: sysfs directory containing all the maps related to the SRAM
+ */
+struct sram_device {
+ struct device dev;
+ struct module *owner;
+ int minor;
+ struct sram_api *sa;
+ struct kobject *map_dir;
+};
+
+/**
+ * sysfs map attribute fields.
+ *
+ * When a block of SRAM memory is allocated for user, specific map
+ * directory related to it would be created, the dir routine is:
+ *
+ * /sys/class/sram/$sram_device/maps/map:$phys
+ *
+ * Within the directory are the offset and size files whose meanings
+ * are very apparent.
+ *
+ * Multiple directories could be created if different file descriptors are
+ * created by openning the SRAM device. A map directory is removed by calling
+ * sram_del_map_attr() when the memory is released.
+ */
+
+struct sram_map {
+ struct kobject kobj;
+ struct sram_res *res;
+};
+
+#define to_map(map) container_of(map, struct sram_map, kobj)
+
+static ssize_t map_addr_show(struct sram_map *map, char *buf)
+{
+ return sprintf(buf, "%llx\n", (unsigned long long)map->res->phys);
+}
+
+static ssize_t map_size_show(struct sram_map *map, char *buf)
+{
+ return sprintf(buf, "%llx\n", map->res->size);
+}
+
+struct map_sysfs_entry {
+ struct attribute attr;
+ ssize_t (*show)(struct sram_map *map, char *buf);
+ ssize_t (*store)(struct sram_map *map, const char *buf, size_t size);
+};
+
+static struct map_sysfs_entry addr_attribute =
+ __ATTR(addr, 0444, map_addr_show, NULL);
+static struct map_sysfs_entry size_attribute =
+ __ATTR(size, 0444, map_size_show, NULL);
+
+static struct attribute *attrs[] = {
+ &addr_attribute.attr,
+ &size_attribute.attr,
+ NULL, /* need to NULL terminate the list of attributes */
+};
+
+/* callback for kobject_put */
+static void map_release(struct kobject *kobj)
+{
+ struct sram_map *map = to_map(kobj);
+
+ kfree(map);
+}
+
+static ssize_t map_type_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct sram_map *map = to_map(kobj);
+ struct map_sysfs_entry *entry;
+
+ entry = container_of(attr, struct map_sysfs_entry, attr);
+
+ if (!entry->show)
+ return -EIO;
+
+ return entry->show(map, buf);
+}
+
+static const struct sysfs_ops map_sysfs_ops = {
+ .show = map_type_show,
+};
+
+static struct kobj_type map_attr_type = {
+ .release = map_release,
+ .sysfs_ops = &map_sysfs_ops,
+ .default_attrs = attrs,
+};
+
+static DEFINE_MUTEX(minor_lock);
+static int sram_major;
+static struct cdev *sram_cdev;
+static DEFINE_IDR(sram_idr);
+
+
+/**
+ * SRAM character device file operations.
+ *
+ * A file descriptor is allowed to request one and only one block of
+ * SRAM memory. An entry of struct sram_res is used to describe the
+ * allocated SRAM memory resource. If the allocation succeeds, the
+ * virt element of the entry is set to the virtual address pointing
+ * to the SRAM memory. So we use virt as the mark of whether a file
+ * descriptor related to the device is attached to a block of SRAM
+ * memory. Whenever the related SRAM memory block is released, the
+ * virt element is set to NULL.
+ */
+
+static int sram_open(struct inode *inode, struct file *filp)
+{
+ struct sram_res *res;
+ struct sram_device *sdev;
+
+ mutex_lock(&minor_lock);
+ sdev = idr_find(&sram_idr, iminor(inode));
+ mutex_unlock(&minor_lock);
+ if (!sdev)
+ return -ENODEV;
+
+ get_device(&sdev->dev);
+
+ if (!try_module_get(sdev->owner)) {
+ put_device(&sdev->dev);
+ return -ENODEV;
+ }
+
+ res = kzalloc(sizeof(*res), GFP_KERNEL);
+ if (!res) {
+ module_put(sdev->owner);
+ put_device(&sdev->dev);
+ return -ENOMEM;
+ }
+
+ res->sdev = sdev;
+
+ filp->private_data = res;
+
+ return 0;
+}
+
+static int sram_add_map_attr(struct sram_res *res)
+{
+ struct sram_device *sdev = res->sdev;
+ struct sram_map *map;
+ __be64 phys;
+ int ret;
+
+ map = kzalloc(sizeof(*map), GFP_KERNEL);
+ if (!map)
+ return -ENOMEM;
+
+ kobject_init(&map->kobj, &map_attr_type);
+
+ phys = res->phys;
+ ret = kobject_add(&map->kobj, sdev->map_dir, "map:%08llx", phys);
+ if (ret)
+ goto err_put;
+
+ ret = kobject_uevent(&map->kobj, KOBJ_ADD);
+ if (ret)
+ goto err_put;
+
+ map->res = res;
+ res->map = map;
+
+ return 0;
+err_put:
+ kobject_put(&map->kobj);
+ return ret;
+}
+
+static void sram_del_map_attr(struct sram_res *res)
+{
+ struct sram_map *map = res->map;
+
+ kobject_put(&map->kobj);
+}
+
+static long sram_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ struct sram_res *res = filp->private_data;
+ struct sram_device *sdev = res->sdev;
+ long ret = -ENOTTY;
+ __be64 size;
+
+ /**
+ * Two ioctl cmds are supported. SRAM_UAPI_IOC_ALLOC allows
+ * users to request SRAM memory resource, and on the opposite
+ * side, SRAM_UAPI_IOC_FREE is used for SRAM resource free.
+ *
+ * One and only one block of SRAM memory resource is allowed
+ * to be allocated and attached to a file descriptor, so we
+ * take size as the single in parameter of SRAM_UAPI_IOC_ALLOC
+ * ioctl operation. No parameter needs to be copy in or out for
+ * SRAM_UAPI_IOC_FREE operation.
+ *
+ * It's user's choice to decide how the memory block would be
+ * managed and used in user-space, such as a user may request a
+ * large block of memory and then take it as a memory pool for
+ * further allocations of user threads.
+ */
+
+ switch (cmd) {
+ case SRAM_UAPI_IOC_ALLOC:
+ if (res->virt)
+ return -EEXIST;
+
+ if (get_user(size, (__be64 __user *)arg) == -EFAULT)
+ return -EFAULT;
+
+ /**
+ * Size limitation is handled by the driver who
+ * registered the sram APIs.
+ */
+ if (!size || !PAGE_ALIGNED(size))
+ return -EINVAL;
+
+ res->virt = sdev->sa->alloc(size, &res->phys, PAGE_SIZE);
+ if (!res->virt)
+ return -ENOSPC;
+
+ res->size = size;
+
+ ret = sram_add_map_attr(res);
+ if (ret) {
+ sdev->sa->free(res->virt);
+ memset(res, 0, sizeof(*res));
+ return ret;
+ }
+ break;
+
+ case SRAM_UAPI_IOC_FREE:
+ if (res->virt) {
+ sram_del_map_attr(res);
+ sdev->sa->free(res->virt);
+ ret = 0;
+ } else {
+ ret = -EFAULT;
+ }
+ break;
+ }
+
+ return ret;
+}
+
+static int sram_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct sram_res *res = filp->private_data;
+
+ if (!res->virt)
+ return -EFAULT;
+
+ if (vma->vm_end - vma->vm_start > res->size)
+ return -EINVAL;
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ return remap_pfn_range(vma, vma->vm_start,
+ res->phys >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+static int sram_release(struct inode *inodp, struct file *filp)
+{
+ struct sram_res *res = filp->private_data;
+ struct sram_device *sdev = res->sdev;
+
+ /**
+ * Should have been done with ioctl syscall, but we should still
+ * check and release the resource if res->virt is not NULL, in case
+ * that user did not do it apparently through ioctl syscall.
+ */
+ if (res->virt) {
+ sram_del_map_attr(res);
+ sdev->sa->free(res->virt);
+ }
+
+ kfree(res);
+
+ put_device(&sdev->dev);
+
+ module_put(sdev->owner);
+
+ return 0;
+}
+
+static const struct file_operations sram_fops = {
+ .owner = THIS_MODULE,
+ .open = sram_open,
+ .unlocked_ioctl = sram_ioctl,
+ .compat_ioctl = compat_ptr_ioctl,
+ .mmap = sram_mmap,
+ .release = sram_release,
+};
+
+static ssize_t name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%s\n", dev_name(dev));
+}
+static DEVICE_ATTR_RO(name);
+
+static struct attribute *sram_attrs[] = {
+ &dev_attr_name.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(sram);
+
+static bool sram_class_registered;
+
+static int sram_get_minor(struct sram_device *sdev)
+{
+ int ret = -ENOMEM;
+
+ mutex_lock(&minor_lock);
+ ret = idr_alloc(&sram_idr, sdev, 0, SRAM_MAX_DEVICES, GFP_KERNEL);
+ if (ret >= 0) {
+ sdev->minor = ret;
+ ret = 0;
+ }
+ mutex_unlock(&minor_lock);
+ return ret;
+}
+
+static void sram_free_minor(struct sram_device *sdev)
+{
+ mutex_lock(&minor_lock);
+ idr_remove(&sram_idr, sdev->minor);
+ mutex_unlock(&minor_lock);
+}
+
+/* SRAM class infrastructure */
+static struct class sram_class = {
+ .name = "sram",
+ .dev_groups = sram_groups,
+};
+
+static int sram_major_init(void)
+{
+ static const char *name = "sram";
+ struct cdev *cdev = NULL;
+ dev_t sram_dev = 0;
+ int ret;
+
+ ret = alloc_chrdev_region(&sram_dev, 0, SRAM_MAX_DEVICES, name);
+ if (ret)
+ return ret;
+
+ ret = -ENOMEM;
+ cdev = cdev_alloc();
+ if (!cdev)
+ goto out_unregister;
+
+ cdev->owner = THIS_MODULE;
+ cdev->ops = &sram_fops;
+ kobject_set_name(&cdev->kobj, "%s", name);
+
+ ret = cdev_add(cdev, sram_dev, SRAM_MAX_DEVICES);
+ if (ret)
+ goto out_put;
+
+ sram_major = MAJOR(sram_dev);
+ sram_cdev = cdev;
+ return 0;
+out_put:
+ kobject_put(&cdev->kobj);
+out_unregister:
+ unregister_chrdev_region(sram_dev, SRAM_MAX_DEVICES);
+ return ret;
+}
+
+static void sram_major_cleanup(void)
+{
+ unregister_chrdev_region(MKDEV(sram_major, 0), SRAM_MAX_DEVICES);
+ cdev_del(sram_cdev);
+}
+
+static int init_sram_class(void)
+{
+ int ret;
+
+ /* Allocate and add char device to the system. */
+ ret = sram_major_init();
+ if (ret)
+ goto exit;
+
+ ret = class_register(&sram_class);
+ if (ret) {
+ pr_err("class_register failed for sram\n");
+ goto err_class_register;
+ }
+
+ sram_class_registered = true;
+
+ return 0;
+
+err_class_register:
+ sram_major_cleanup();
+exit:
+ return ret;
+}
+
+static void release_sram_class(void)
+{
+ sram_class_registered = false;
+ class_unregister(&sram_class);
+ sram_major_cleanup();
+}
+
+static void sram_device_release(struct device *dev)
+{
+ struct sram_device *sdev = dev_get_drvdata(dev);
+
+ kfree(sdev);
+}
+
+/**
+ * sram_register_device() - register a new sram interface device
+ * @owner: module that creates the new device
+ * @parent: parent device
+ * @sa: sram device APIs for SRAM memory allocation and free
+ *
+ * Return: zero on success or a negative error code.
+ */
+int __sram_register_device(struct module *owner,
+ struct device *parent,
+ struct sram_api *sa)
+{
+ struct sram_device *sdev;
+ int ret = 0;
+
+ if (!sram_class_registered)
+ return -EPROBE_DEFER;
+
+ if (!parent || !sa || !sa->alloc || !sa->free)
+ return -EINVAL;
+
+ sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
+ if (!sdev)
+ return -ENOMEM;
+
+ sdev->owner = owner;
+ sdev->sa = sa;
+
+ ret = sram_get_minor(sdev);
+ if (ret) {
+ kfree(sdev);
+ return ret;
+ }
+
+ device_initialize(&sdev->dev);
+ sdev->dev.devt = MKDEV(sram_major, sdev->minor);
+ sdev->dev.class = &sram_class;
+ sdev->dev.parent = parent;
+ sdev->dev.release = sram_device_release;
+ dev_set_drvdata(&sdev->dev, sdev);
+
+ if (sa->name)
+ ret = dev_set_name(&sdev->dev, "%s", sa->name);
+ else
+ ret = dev_set_name(&sdev->dev, "sram%d", sdev->minor);
+ if (ret)
+ goto err_free;
+
+ ret = device_add(&sdev->dev);
+ if (ret)
+ goto err_free;
+
+ sdev->map_dir = kobject_create_and_add("maps", &sdev->dev.kobj);
+ if (!sdev->map_dir) {
+ ret = -ENOMEM;
+ goto err_device_del;
+ }
+
+ sa->sdev = sdev;
+
+ return 0;
+err_device_del:
+ device_del(&sdev->dev);
+err_free:
+ sram_free_minor(sdev);
+ put_device(&sdev->dev);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__sram_register_device);
+
+/**
+ * sram_unregister_device() - unregister a sram interface device
+ * @sa: sram device APIs for SRAM memory allocation and free
+ */
+void sram_unregister_device(struct sram_api *sa)
+{
+ struct sram_device *sdev;
+
+ if (!sa || !sa->sdev)
+ return;
+
+ sdev = sa->sdev;
+
+ kobject_put(sdev->map_dir);
+
+ sram_free_minor(sdev);
+
+ sdev->sa = NULL;
+
+ device_unregister(&sdev->dev);
+}
+EXPORT_SYMBOL_GPL(sram_unregister_device);
+
+static int __init sram_uapi_init(void)
+{
+ return init_sram_class();
+}
+postcore_initcall(sram_uapi_init);
+
+static void __exit sram_uapi_exit(void)
+{
+ release_sram_class();
+ idr_destroy(&sram_idr);
+}
+module_exit(sram_uapi_exit);
+
+MODULE_AUTHOR("Wang Wenhu <wenhu.wang@vivo.com>");
+MODULE_DESCRIPTION("SRAM Dynamic Access User API Support");
+MODULE_ALIAS("platform:sram_dynamic");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/sram_uapi.c b/drivers/misc/sram_uapi.c
new file mode 100644
index 000000000000..057bb243f2c8
--- /dev/null
+++ b/drivers/misc/sram_uapi.c
@@ -0,0 +1,351 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Vivo Communication Technology Co. Ltd.
+ * Copyright (C) 2020 Wang Wenhu <wenhu.wang@vivo.com>
+ * All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/sram_uapi.h>
+
+#define DRIVER_NAME "sram_uapi"
+
+struct res_info {
+ phys_addr_t offset;
+ phys_addr_t size;
+};
+
+struct sram_resource {
+ struct list_head list;
+ struct res_info info;
+ phys_addr_t phys;
+ void *virt;
+ struct vm_area_struct *vma;
+ struct sram_uapi *parent;
+};
+
+struct sram_uapi {
+ struct list_head res_list;
+ struct sram_api *sa;
+};
+
+static DEFINE_MUTEX(sram_api_list_lock);
+static LIST_HEAD(sram_api_list);
+
+long sram_api_register(struct sram_api *sa)
+{
+ struct sram_api *cur;
+
+ if (!sa || !sa->name || !sa->sram_alloc || !sa->sram_free)
+ return -EINVAL;
+
+ mutex_lock(&sram_api_list_lock);
+ list_for_each_entry(cur, &sram_api_list, list) {
+ if (cur->type == sa->type) {
+ pr_err("error sram %s type %d exists\n", sa->name,
+ sa->type);
+ mutex_unlock(&sram_api_list_lock);
+ return -EEXIST;
+ }
+ }
+
+ kref_init(&sa->kref);
+ list_add_tail(&sa->list, &sram_api_list);
+ pr_info("sram %s type %d registered\n", sa->name, sa->type);
+
+ mutex_unlock(&sram_api_list_lock);
+
+ return 0;
+};
+EXPORT_SYMBOL(sram_api_register);
+
+long sram_api_unregister(struct sram_api *sa)
+{
+ struct sram_api *cur, *tmp;
+ long ret = -ENODEV;
+
+ if (!sa || !sa->name || !sa->sram_alloc || !sa->sram_free)
+ return -EINVAL;
+
+ mutex_lock(&sram_api_list_lock);
+ list_for_each_entry_safe(cur, tmp, &sram_api_list, list) {
+ if (cur->type == sa->type && !strcmp(cur->name, sa->name)) {
+ if (kref_read(&cur->kref)) {
+ pr_err("error sram %s type %d is busy\n",
+ sa->name, sa->type);
+ ret = -EBUSY;
+ } else {
+ list_del(&cur->list);
+ pr_info("sram %s type %d unregistered\n",
+ sa->name, sa->type);
+ ret = 0;
+ }
+ break;
+ }
+ }
+ mutex_unlock(&sram_api_list_lock);
+
+ return ret;
+};
+EXPORT_SYMBOL(sram_api_unregister);
+
+static struct sram_api *get_sram_api_from_type(__u32 type)
+{
+ struct sram_api *cur;
+
+ mutex_lock(&sram_api_list_lock);
+ list_for_each_entry(cur, &sram_api_list, list) {
+ if (cur->type == type) {
+ kref_get(&cur->kref);
+ mutex_unlock(&sram_api_list_lock);
+ return cur;
+ }
+ }
+ mutex_unlock(&sram_api_list_lock);
+
+ return NULL;
+}
+
+static void sram_uapi_res_insert(struct sram_uapi *uapi,
+ struct sram_resource *res)
+{
+ struct sram_resource *cur, *tmp;
+ struct list_head *head = &uapi->res_list;
+
+ list_for_each_entry_safe(cur, tmp, head, list) {
+ if (&tmp->list != head &&
+ (cur->info.offset + cur->info.size + res->info.size <=
+ tmp->info.offset)) {
+ res->info.offset = cur->info.offset + cur->info.size;
+ res->parent = uapi;
+ list_add(&res->list, &cur->list);
+ return;
+ }
+ }
+
+ if (list_empty(head))
+ res->info.offset = 0;
+ else {
+ tmp = list_last_entry(head, struct sram_resource, list);
+ res->info.offset = tmp->info.offset + tmp->info.size;
+ }
+ list_add_tail(&res->list, head);
+}
+
+static struct sram_resource *sram_uapi_res_delete(struct sram_uapi *uapi,
+ struct res_info *info)
+{
+ struct sram_resource *res, *tmp;
+
+ list_for_each_entry_safe(res, tmp, &uapi->res_list, list) {
+ if (res->info.offset == info->offset) {
+ list_del(&res->list);
+ res->parent = NULL;
+ return res;
+ }
+ }
+
+ return NULL;
+}
+
+static struct sram_resource *sram_uapi_find_res(struct sram_uapi *uapi,
+ __u32 offset)
+{
+ struct sram_resource *res;
+
+ list_for_each_entry(res, &uapi->res_list, list) {
+ if (res->info.offset == offset)
+ return res;
+ }
+
+ return NULL;
+}
+
+static int sram_uapi_open(struct inode *inode, struct file *filp)
+{
+ struct sram_uapi *uapi;
+
+ uapi = kzalloc(sizeof(*uapi), GFP_KERNEL);
+ if (!uapi)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&uapi->res_list);
+ filp->private_data = uapi;
+
+ return 0;
+}
+
+static long sram_uapi_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ struct sram_uapi *uapi = filp->private_data;
+ struct sram_resource *res;
+ struct res_info info;
+ long ret = -ENOIOCTLCMD;
+ int size;
+ __u32 type;
+
+ if (!uapi)
+ return ret;
+
+ switch (cmd) {
+ case SRAM_UAPI_IOC_SET_SRAM_TYPE:
+ if (uapi->sa)
+ return -EEXIST;
+
+ get_user(type, (const __u32 __user *)arg);
+ uapi->sa = get_sram_api_from_type(type);
+ if (uapi->sa)
+ ret = 0;
+ else
+ ret = -ENODEV;
+
+ break;
+
+ case SRAM_UAPI_IOC_ALLOC:
+ if (!uapi->sa)
+ return -EINVAL;
+
+ res = kzalloc(sizeof(*res), GFP_KERNEL);
+ if (!res)
+ return -ENOMEM;
+
+ size = copy_from_user((void *)&res->info,
+ (const void __user *)arg,
+ sizeof(res->info));
+ if (!PAGE_ALIGNED(res->info.size) || !res->info.size)
+ return -EINVAL;
+
+ res->virt = (void *)uapi->sa->sram_alloc(res->info.size,
+ &res->phys,
+ PAGE_SIZE);
+ if (!res->virt) {
+ kfree(res);
+ return -ENOMEM;
+ }
+
+ sram_uapi_res_insert(uapi, res);
+ size = copy_to_user((void __user *)arg,
+ (const void *)&res->info,
+ sizeof(res->info));
+
+ ret = 0;
+ break;
+
+ case SRAM_UAPI_IOC_FREE:
+ if (!uapi->sa)
+ return -EINVAL;
+
+ size = copy_from_user((void *)&info, (const void __user *)arg,
+ sizeof(info));
+
+ res = sram_uapi_res_delete(uapi, &info);
+ if (!res) {
+ pr_err("error no sram resource found\n");
+ return -EINVAL;
+ }
+
+ uapi->sa->sram_free(res->virt);
+ kfree(res);
+
+ ret = 0;
+ break;
+
+ default:
+ pr_err("error no cmd not supported\n");
+ break;
+ }
+
+ return ret;
+}
+
+static int sram_uapi_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct sram_uapi *uapi = filp->private_data;
+ struct sram_resource *res;
+
+ res = sram_uapi_find_res(uapi, vma->vm_pgoff);
+ if (!res)
+ return -EINVAL;
+
+ if (vma->vm_end - vma->vm_start > res->info.size)
+ return -EINVAL;
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ return remap_pfn_range(vma, vma->vm_start,
+ res->phys >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+static void sram_uapi_res_release(struct sram_uapi *uapi)
+{
+ struct sram_resource *res, *tmp;
+
+ list_for_each_entry_safe(res, tmp, &uapi->res_list, list) {
+ list_del(&res->list);
+ uapi->sa->sram_free(res->virt);
+ kfree(res);
+ }
+}
+
+static int sram_uapi_release(struct inode *inodp, struct file *filp)
+{
+ struct sram_uapi *uapi = filp->private_data;
+
+ sram_uapi_res_release(uapi);
+ if (uapi->sa)
+ kref_put(&uapi->sa->kref, NULL);
+
+ kfree(uapi);
+
+ return 0;
+}
+
+static const struct file_operations sram_uapi_ops = {
+ .owner = THIS_MODULE,
+ .open = sram_uapi_open,
+ .unlocked_ioctl = sram_uapi_ioctl,
+ .compat_ioctl = compat_ptr_ioctl,
+ .mmap = sram_uapi_mmap,
+ .release = sram_uapi_release,
+};
+
+static struct miscdevice sram_uapi_miscdev = {
+ MISC_DYNAMIC_MINOR,
+ "sram",
+ &sram_uapi_ops,
+};
+
+static int __init sram_uapi_init(void)
+{
+ int ret;
+
+ INIT_LIST_HEAD(&sram_api_list);
+ mutex_init(&sram_api_list_lock);
+
+ ret = misc_register(&sram_uapi_miscdev);
+ if (ret)
+ pr_err("failed to register sram uapi misc device\n");
+
+ return ret;
+}
+postcore_initcall(sram_uapi_init);
+
+static void __exit sram_uapi_exit(void)
+{
+ misc_deregister(&sram_uapi_miscdev);
+}
+module_exit(sram_uapi_exit);
+
+MODULE_AUTHOR("Wang Wenhu <wenhu.wang@vivo.com>");
+MODULE_DESCRIPTION("SRAM User API Driver");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/sram_dynamic.h b/include/linux/sram_dynamic.h
new file mode 100644
index 000000000000..c77e9e7b1151
--- /dev/null
+++ b/include/linux/sram_dynamic.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __SRAM_DYNAMIC_H
+#define __SRAM_DYNAMIC_H
+
+struct sram_api {
+ const char *name;
+ struct sram_device *sdev;
+ void *(*alloc)(__u32 size, phys_addr_t *phys, __u32 align);
+ void (*free)(void *ptr);
+};
+
+extern int __must_check
+ __sram_register_device(struct module *owner,
+ struct device *parent,
+ struct sram_api *sa);
+
+/* Use a define to avoid include chaining to get THIS_MODULE */
+#define sram_register_device(parent, sa) \
+ __sram_register_device(THIS_MODULE, parent, sa)
+
+extern void sram_unregister_device(struct sram_api *sa);
+
+#endif /* __SRAM_DYNAMIC_H */
diff --git a/include/uapi/linux/sram.h b/include/uapi/linux/sram.h
new file mode 100644
index 000000000000..9b4a2615dbfe
--- /dev/null
+++ b/include/uapi/linux/sram.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __SRAM_H
+#define __SRAM_H
+
+/* Allocate memory resource from SRAM */
+#define SRAM_UAPI_IOC_ALLOC _IOWR('S', 0, __be64)
+
+/* Free allocated memory resource to SRAM */
+#define SRAM_UAPI_IOC_FREE _IO('S', 1)
+
+#endif /* __SRAM_H */
--
2.17.1
^ permalink raw reply related
* [PATCH v3, 5/5] powerpc: sysdev: support userspace access of fsl_85xx_sram
From: Wang Wenhu @ 2020-04-24 2:45 UTC (permalink / raw)
To: gregkh, arnd, linux-kernel, linuxppc-dev
Cc: robh, oss, kernel, paulus, Wang Wenhu
In-Reply-To: <20200424024554.30709-1-wenhu.wang@vivo.com>
New module which registers its memory allocation and free APIs to the
sram_dynamic module, which would create a device of struct sram_device
type to act as an interface for user level applications to access the
backend hardware device, fsl_85xx_cache_sram, which is drived by the
FSL_85XX_CACHE_SRAM module.
Signed-off-by: Wang Wenhu <wenhu.wang@vivo.com>
Cc: Christophe Leroy <christophe.leroy@c-s.fr>
Cc: Scott Wood <oss@buserror.net>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: linuxppc-dev@lists.ozlabs.org
---
.../powerpc/include/asm/fsl_85xx_cache_sram.h | 4 ++
arch/powerpc/platforms/85xx/Kconfig | 10 +++++
arch/powerpc/sysdev/Makefile | 1 +
arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h | 6 +++
arch/powerpc/sysdev/fsl_85xx_cache_sram.c | 12 ++++++
arch/powerpc/sysdev/fsl_85xx_sram_uapi.c | 39 +++++++++++++++++++
6 files changed, 72 insertions(+)
create mode 100644 arch/powerpc/sysdev/fsl_85xx_sram_uapi.c
diff --git a/arch/powerpc/include/asm/fsl_85xx_cache_sram.h b/arch/powerpc/include/asm/fsl_85xx_cache_sram.h
index 0235a0447baa..99cb7e202c38 100644
--- a/arch/powerpc/include/asm/fsl_85xx_cache_sram.h
+++ b/arch/powerpc/include/asm/fsl_85xx_cache_sram.h
@@ -26,6 +26,10 @@ struct mpc85xx_cache_sram {
unsigned int size;
rh_info_t *rh;
spinlock_t lock;
+
+#ifdef CONFIG_FSL_85XX_SRAM_UAPI
+ struct device *dev;
+#endif
};
extern void mpc85xx_cache_sram_free(void *ptr);
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index fa3d29dcb57e..3a6f6af973eb 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -16,6 +16,16 @@ if FSL_SOC_BOOKE
if PPC32
+config FSL_85XX_SRAM_UAPI
+ tristate "Freescale MPC85xx SRAM UAPI Support"
+ depends on FSL_SOC_BOOKE && SRAM_DYNAMIC
+ select FSL_85XX_CACHE_SRAM
+ help
+ This registers a device of struct sram_device type which would act as
+ an interface for user level applications to access the Freescale 85xx
+ Cache-SRAM memory dynamically, meaning allocate on demand dynamically
+ while they are running.
+
config FSL_85XX_CACHE_SRAM
bool
select PPC_LIB_RHEAP
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index cb5a5bd2cef5..e71f82f0d2c3 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_FSL_CORENET_RCPM) += fsl_rcpm.o
obj-$(CONFIG_FSL_LBC) += fsl_lbc.o
obj-$(CONFIG_FSL_GTM) += fsl_gtm.o
obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o
+obj-$(CONFIG_FSL_85XX_SRAM_UAPI) += fsl_85xx_sram_uapi.o
obj-$(CONFIG_FSL_RIO) += fsl_rio.o fsl_rmu.o
obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
obj-$(CONFIG_RTC_DRV_CMOS) += rtc_cmos_setup.o
diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h b/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
index ce370749add9..4930784d9852 100644
--- a/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
+++ b/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
@@ -10,6 +10,8 @@
#ifndef __FSL_85XX_CACHE_CTLR_H__
#define __FSL_85XX_CACHE_CTLR_H__
+#include <linux/platform_device.h>
+
#define L2CR_L2FI 0x40000000 /* L2 flash invalidate */
#define L2CR_L2IO 0x00200000 /* L2 instruction only */
#define L2CR_SRAM_ZERO 0x00000000 /* L2SRAM zero size */
@@ -81,6 +83,10 @@ struct sram_parameters {
phys_addr_t sram_offset;
};
+#ifdef CONFIG_FSL_85XX_SRAM_UAPI
+extern struct mpc85xx_cache_sram *mpc85xx_get_cache_sram(void);
+#endif
+
extern int instantiate_cache_sram(struct platform_device *dev,
struct sram_parameters sram_params);
extern void remove_cache_sram(struct platform_device *dev);
diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
index 3de5ac8382c0..0156ea63a3a2 100644
--- a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
+++ b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
@@ -23,6 +23,14 @@
struct mpc85xx_cache_sram *cache_sram;
+
+#ifdef CONFIG_FSL_85XX_SRAM_UAPI
+struct mpc85xx_cache_sram *mpc85xx_get_cache_sram(void)
+{
+ return cache_sram;
+}
+#endif
+
void *mpc85xx_cache_sram_alloc(unsigned int size,
phys_addr_t *phys, unsigned int align)
{
@@ -115,6 +123,10 @@ int instantiate_cache_sram(struct platform_device *dev,
rh_attach_region(cache_sram->rh, 0, cache_sram->size);
spin_lock_init(&cache_sram->lock);
+#ifdef CONFIG_FSL_85XX_SRAM_UAPI
+ cache_sram->dev = &dev->dev;
+#endif
+
dev_info(&dev->dev, "[base:0x%llx, size:0x%x] configured and loaded\n",
(unsigned long long)cache_sram->base_phys, cache_sram->size);
diff --git a/arch/powerpc/sysdev/fsl_85xx_sram_uapi.c b/arch/powerpc/sysdev/fsl_85xx_sram_uapi.c
new file mode 100644
index 000000000000..60190bf3c8e9
--- /dev/null
+++ b/arch/powerpc/sysdev/fsl_85xx_sram_uapi.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Vivo Communication Technology Co. Ltd.
+ * Copyright (C) 2020 Wang Wenhu <wenhu.wang@vivo.com>
+ * All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sram_dynamic.h>
+#include <asm/fsl_85xx_cache_sram.h>
+#include "fsl_85xx_cache_ctlr.h"
+
+static struct sram_api mpc85xx_sram_api = {
+ .name = "mpc85xx_sram",
+ .alloc = mpc85xx_cache_sram_alloc,
+ .free = mpc85xx_cache_sram_free,
+};
+
+static int __init mpc85xx_sram_uapi_init(void)
+{
+ struct mpc85xx_cache_sram *sram = mpc85xx_get_cache_sram();
+
+ if (!sram)
+ return -ENODEV;
+
+ return sram_register_device(sram->dev, &mpc85xx_sram_api);
+}
+subsys_initcall(mpc85xx_sram_uapi_init);
+
+static void __exit mpc85xx_sram_uapi_exit(void)
+{
+ sram_unregister_device(&mpc85xx_sram_api);
+}
+module_exit(mpc85xx_sram_uapi_exit);
+
+MODULE_AUTHOR("Wang Wenhu <wenhu.wang@vivo.com>");
+MODULE_DESCRIPTION("MPC85xx SRAM User-Space API Support");
+MODULE_LICENSE("GPL v2");
--
2.17.1
^ permalink raw reply related
* [Bug 199471] [Bisected][Regression] windfarm_pm* no longer gets automatically loaded when CONFIG_I2C_POWERMAC=y is set
From: bugzilla-daemon @ 2020-04-24 3:12 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-199471-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=199471
--- Comment #23 from Michael Ellerman (michael@ellerman.id.au) ---
The memory leak is a separate issue, see bug #206695.
Can anyone verify that bcf3588d8ed fixes the original issue?
--
You are receiving this mail because:
You are watching the assignee of the bug.
^ permalink raw reply
* Re: [PATCH] lib/mpi: Fix building for powerpc with clang
From: Michael Ellerman @ 2020-04-24 3:23 UTC (permalink / raw)
To: Nathan Chancellor, Herbert Xu
Cc: kbuild test robot, linux-kernel, clang-built-linux,
Paul Mackerras, linux-crypto, linuxppc-dev
In-Reply-To: <20200423163602.GA18872@ubuntu-s3-xlarge-x86>
Nathan Chancellor <natechancellor@gmail.com> writes:
> On Tue, Apr 14, 2020 at 11:57:31PM +1000, Herbert Xu wrote:
>> On Mon, Apr 13, 2020 at 12:50:42PM -0700, Nathan Chancellor wrote:
>> > 0day reports over and over on an powerpc randconfig with clang:
>> >
>> > lib/mpi/generic_mpih-mul1.c:37:13: error: invalid use of a cast in a
>> > inline asm context requiring an l-value: remove the cast or build with
>> > -fheinous-gnu-extensions
>> >
>> > Remove the superfluous casts, which have been done previously for x86
>> > and arm32 in commit dea632cadd12 ("lib/mpi: fix build with clang") and
>> > commit 7b7c1df2883d ("lib/mpi/longlong.h: fix building with 32-bit
>> > x86").
>> >
>> > Reported-by: kbuild test robot <lkp@intel.com>
>> > Link: https://github.com/ClangBuiltLinux/linux/issues/991
>> > Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
>>
>> Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
>> --
>> Email: Herbert Xu <herbert@gondor.apana.org.au>
>> Home Page: http://gondor.apana.org.au/~herbert/
>> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
>
> Might be better for you to take this instead. 0day just tripped over
> this again.
Sorry I missed the ack. Will pick it up today.
cheers
^ permalink raw reply
* Re: [PATCH v3 12/16] powerpc/watchpoint: Use builtin ALIGN*() macros
From: Ravi Bangoria @ 2020-04-24 3:24 UTC (permalink / raw)
To: Christophe Leroy
Cc: apopple, mikey, Ravi Bangoria, peterz, oleg, npiggin,
linux-kernel, paulus, jolsa, fweisbec, naveen.n.rao, linuxppc-dev,
mingo
In-Reply-To: <a2d7abe8-44e0-9780-6603-00f16300c2ca@c-s.fr>
Hi Christophe,
>> max_len = DAWR_MAX_LEN;
>> /* DAWR region can't cross 512 bytes boundary */
>> - if ((start_addr >> 9) != (end_addr >> 9))
>> + if ((start_addr >> 9) != ((end_addr - 1) >> 9))
>
> What about:
> if (ALIGN(start_addr, SZ_512M) != ALIGN(end - 1, SZ_512M))
ok.
>
>> return -EINVAL;
>> } else if (IS_ENABLED(CONFIG_PPC_8xx)) {
>> /* 8xx can setup a range without limitation */
>> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
>> index aab82ab80dfa..06679adac447 100644
>> --- a/arch/powerpc/kernel/process.c
>> +++ b/arch/powerpc/kernel/process.c
>> @@ -800,12 +800,12 @@ static inline int set_breakpoint_8xx(struct arch_hw_breakpoint *brk)
>> unsigned long lctrl1 = LCTRL1_CTE_GT | LCTRL1_CTF_LT | LCTRL1_CRWE_RW |
>> LCTRL1_CRWF_RW;
>> unsigned long lctrl2 = LCTRL2_LW0EN | LCTRL2_LW0LADC | LCTRL2_SLW0EN;
>> - unsigned long start_addr = brk->address & ~HW_BREAKPOINT_ALIGN;
>> - unsigned long end_addr = (brk->address + brk->len - 1) | HW_BREAKPOINT_ALIGN;
>> + unsigned long start_addr = ALIGN_DOWN(brk->address, HW_BREAKPOINT_SIZE);
>> + unsigned long end_addr = ALIGN(brk->address + brk->len, HW_BREAKPOINT_SIZE);
>> if (start_addr == 0)
>> lctrl2 |= LCTRL2_LW0LA_F;
>> - else if (end_addr == ~0U)
>> + else if (end_addr - 1 == ~0U)
>
> What about:
> else if (end_addr == 0)
That's better.
Thanks,
Ravi
^ permalink raw reply
* Re: [PATCH v3 13/16] powerpc/watchpoint: Prepare handler to handle more than one watcnhpoint
From: Ravi Bangoria @ 2020-04-24 3:32 UTC (permalink / raw)
To: Christophe Leroy
Cc: apopple, mikey, Ravi Bangoria, peterz, oleg, npiggin,
linux-kernel, paulus, jolsa, fweisbec, naveen.n.rao, linuxppc-dev,
mingo
In-Reply-To: <67349339-03df-091a-47f0-78c1b14c5981@c-s.fr>
Hi Christophe,
>> @@ -101,14 +129,20 @@ static bool is_ptrace_bp(struct perf_event *bp)
>> */
>> void arch_unregister_hw_breakpoint(struct perf_event *bp)
>> {
>> + int i;
>> +
>
> This declaration should be in the block using it.
>
>> /*
>> * If the breakpoint is unregistered between a hw_breakpoint_handler()
>> * and the single_step_dabr_instruction(), then cleanup the breakpoint
>> * restoration variables to prevent dangling pointers.
>> * FIXME, this should not be using bp->ctx at all! Sayeth peterz.
>> */
>> - if (bp->ctx && bp->ctx->task && bp->ctx->task != ((void *)-1L))
>> - bp->ctx->task->thread.last_hit_ubp = NULL;
>> + if (bp->ctx && bp->ctx->task && bp->ctx->task != ((void *)-1L)) {
>
> Add declaration of 'int i' here.
How will that help? Keeping declaration at the start of function is also
common practice and I don't see any recommendation to move them inside
conditional block.
Thanks,
Ravi
^ permalink raw reply
* [PATCH v3 1/3] powerpc/rtas: Export rtas_error_rc
From: Sam Bobroff @ 2020-04-24 4:58 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nathan Lynch, Oliver O'Halloran
In-Reply-To: <cover.1587704308.git.sbobroff@linux.ibm.com>
Export rtas_error_rc() so that it can be used by other users of
rtas_call() (which is already exported).
Signed-off-by: Sam Bobroff <sbobroff@linux.ibm.com>
---
v3 * New in this version.
arch/powerpc/include/asm/rtas.h | 1 +
arch/powerpc/kernel/rtas.c | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 3c1887351c71..7c9e4d3635cf 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -379,6 +379,7 @@ extern int rtas_set_rtc_time(struct rtc_time *rtc_time);
extern unsigned int rtas_busy_delay_time(int status);
extern unsigned int rtas_busy_delay(int status);
+extern int rtas_error_rc(int rtas_rc);
extern int early_init_dt_scan_rtas(unsigned long node,
const char *uname, int depth, void *data);
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index c5fa251b8950..238bf112d29a 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -518,7 +518,7 @@ unsigned int rtas_busy_delay(int status)
}
EXPORT_SYMBOL(rtas_busy_delay);
-static int rtas_error_rc(int rtas_rc)
+int rtas_error_rc(int rtas_rc)
{
int rc;
@@ -546,6 +546,7 @@ static int rtas_error_rc(int rtas_rc)
}
return rc;
}
+EXPORT_SYMBOL(rtas_error_rc);
int rtas_get_power_level(int powerdomain, int *level)
{
--
2.22.0.216.g00a2a96fc9
^ permalink raw reply related
* [PATCH v3 0/3] powerpc/eeh: Release EEH device state synchronously
From: Sam Bobroff @ 2020-04-24 4:58 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nathan Lynch, Oliver O'Halloran
Hi everyone,
Here are some fixes and cleanups that have come from other work but that I
think stand on their own.
Only one patch ("Release EEH device state synchronously", suggested by Oliver
O'Halloran) is a significant change: it moves the cleanup of some EEH device
data out of the (possibly asynchronous) device release handler and into the
(synchronously called) bus notifier. This is useful for future work as it makes
it easier to reason about the lifetimes of EEH structures.
Note that I've left a few WARN_ON_ONCEs in the code because I'm paranoid, but I
have not been able to hit them during testing.
Cheers,
Sam.
Notes for v3:
I've tweaked the fix for pseries_eeh_configure_bridge() to return the correct
error code (even though it's not used) by calling an already present RTAS
function, rtas_error_rc(). However, I had to make another change to export that
function and while it does seem like the right thing to do, but I'm concerned
it's a bit out of scope for such a small fix.
Notes for v2:
I've dropped both cleanup patches (3/4, 4/4) because that type of cleanup
(replacing a call to eeh_rmv_from_parent_pe() with one to eeh_remove_device())
is incorrect: if called during recovery, it will cause edev->pe to remain set
when it would have been cleared previously. This would lead to stale
information in the edev. I think there should be a way to simplify the code
around EEH_PE_KEEP but I'll look at that separately.
Patch set changelog follows:
Patch set v3:
Patch 1/3 (new in this version): powerpc/rtas: Export rtas_error_rc
Patch 2/3 (was 1/2): powerpc/eeh: fix pseries_eeh_configure_bridge()
Patch 3/3 (was 2/2): powerpc/eeh: Release EEH device state synchronously
Patch set v2:
Patch 1/2: powerpc/eeh: fix pseries_eeh_configure_bridge()
Patch 2/2: powerpc/eeh: Release EEH device state synchronously
- Added comment explaining why the add case can't be handled similarly to the remove case.
Dropped (was 3/4) powerpc/eeh: Remove workaround from eeh_add_device_late()
Dropped (was 4/4) powerpc/eeh: Clean up edev cleanup for VFs
Patch set v1:
Patch 1/4: powerpc/eeh: fix pseries_eeh_configure_bridge()
Patch 2/4: powerpc/eeh: Release EEH device state synchronously
Patch 3/4: powerpc/eeh: Remove workaround from eeh_add_device_late()
Patch 4/4: powerpc/eeh: Clean up edev cleanup for VFs
Sam Bobroff (3):
powerpc/rtas: Export rtas_error_rc
powerpc/eeh: fix pseries_eeh_configure_bridge()
powerpc/eeh: Release EEH device state synchronously
arch/powerpc/include/asm/rtas.h | 1 +
arch/powerpc/kernel/eeh.c | 31 ++++++++++++++++++++
arch/powerpc/kernel/pci-hotplug.c | 2 --
arch/powerpc/kernel/rtas.c | 3 +-
arch/powerpc/platforms/pseries/eeh_pseries.c | 4 ++-
5 files changed, 37 insertions(+), 4 deletions(-)
--
2.22.0.216.g00a2a96fc9
^ permalink raw reply
* [PATCH v3 2/3] powerpc/eeh: fix pseries_eeh_configure_bridge()
From: Sam Bobroff @ 2020-04-24 4:58 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nathan Lynch, Oliver O'Halloran
In-Reply-To: <cover.1587704308.git.sbobroff@linux.ibm.com>
If a device is hot unplgged during EEH recovery, it's possible for the
RTAS call to ibm,configure-pe in pseries_eeh_configure() to return
parameter error (-3), however negative return values are not checked
for and this leads to an infinite loop.
Fix this by correctly bailing out on negative values.
Signed-off-by: Sam Bobroff <sbobroff@linux.ibm.com>
---
arch/powerpc/platforms/pseries/eeh_pseries.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
index 893ba3f562c4..9ea1c06a78cd 100644
--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
@@ -607,6 +607,8 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
if (!ret)
return ret;
+ if (ret < 0)
+ break;
/*
* If RTAS returns a delay value that's above 100ms, cut it
@@ -627,7 +629,7 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
pr_warn("%s: Unable to configure bridge PHB#%x-PE#%x (%d)\n",
__func__, pe->phb->global_number, pe->addr, ret);
- return ret;
+ return rtas_error_rc(ret);
}
/**
--
2.22.0.216.g00a2a96fc9
^ permalink raw reply related
* [PATCH v3 3/3] powerpc/eeh: Release EEH device state synchronously
From: Sam Bobroff @ 2020-04-24 4:58 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nathan Lynch, Oliver O'Halloran
In-Reply-To: <cover.1587704308.git.sbobroff@linux.ibm.com>
EEH device state is currently removed (by eeh_remove_device()) during
the device release handler, which is invoked as the device's reference
count drops to zero. This may take some time, or forever, as other
threads may hold references.
However, the PCI device state is released synchronously by
pci_stop_and_remove_bus_device(). This mismatch causes problems, for
example the device may be re-discovered as a new device before the
release handler has been called, leaving the PCI and EEH state
mismatched.
So instead, call eeh_remove_device() from the bus device removal
handlers, which are called synchronously in the removal path.
Signed-off-by: Sam Bobroff <sbobroff@linux.ibm.com>
---
arch/powerpc/kernel/eeh.c | 31 +++++++++++++++++++++++++++++++
arch/powerpc/kernel/pci-hotplug.c | 2 --
2 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 17cb3e9b5697..64361311bc8e 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -1106,6 +1106,37 @@ static int eeh_init(void)
core_initcall_sync(eeh_init);
+static int eeh_device_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct device *dev = data;
+
+ switch (action) {
+ /*
+ * Note: It's not possible to perform EEH device addition (i.e.
+ * {pseries,pnv}_pcibios_bus_add_device()) here because it depends on
+ * the device's resources, which have not yet been set up.
+ */
+ case BUS_NOTIFY_DEL_DEVICE:
+ eeh_remove_device(to_pci_dev(dev));
+ break;
+ default:
+ break;
+ }
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block eeh_device_nb = {
+ .notifier_call = eeh_device_notifier,
+};
+
+static __init int eeh_set_bus_notifier(void)
+{
+ bus_register_notifier(&pci_bus_type, &eeh_device_nb);
+ return 0;
+}
+arch_initcall(eeh_set_bus_notifier);
+
/**
* eeh_add_device_early - Enable EEH for the indicated device node
* @pdn: PCI device node for which to set up EEH
diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c
index d6a67f814983..28e9aa274f64 100644
--- a/arch/powerpc/kernel/pci-hotplug.c
+++ b/arch/powerpc/kernel/pci-hotplug.c
@@ -57,8 +57,6 @@ void pcibios_release_device(struct pci_dev *dev)
struct pci_controller *phb = pci_bus_to_host(dev->bus);
struct pci_dn *pdn = pci_get_pdn(dev);
- eeh_remove_device(dev);
-
if (phb->controller_ops.release_device)
phb->controller_ops.release_device(dev);
--
2.22.0.216.g00a2a96fc9
^ permalink raw reply related
* Re: [PATCH v3,4/5] misc: sram_dynamic for user level SRAM access
From: Christophe Leroy @ 2020-04-24 5:17 UTC (permalink / raw)
To: Wang Wenhu, gregkh, arnd, linux-kernel, linuxppc-dev
Cc: robh, oss, kernel, paulus
In-Reply-To: <20200424024554.30709-5-wenhu.wang@vivo.com>
Le 24/04/2020 à 04:45, Wang Wenhu a écrit :
> A generic User-Kernel interface module that allows a misc device created
> when a backend SRAM hardware device driver registers its APIs to support
> file operations of ioctl and mmap for user space applications to allocate
> SRAM memory, mmap it to process address space and free it then after.
>
> It is extremely helpful for the user space applications that require
> high performance memory accesses, such as embedded networking devices
> that would process data in user space, and PowerPC e500 is one case.
>
> Signed-off-by: Wang Wenhu <wenhu.wang@vivo.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Christophe Leroy <christophe.leroy@c-s.fr>
> Cc: Scott Wood <oss@buserror.net>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: linuxppc-dev@lists.ozlabs.org
> ---
> Changes since v1: addressed comments from Arnd
> * Changed the ioctl cmd definitions using _IO micros
> * Export interfaces for HW-SRAM drivers to register apis to available list
> * Modified allocation alignment to PAGE_SIZE
> * Use phys_addr_t as type of SRAM resource size and offset
> * Support compat_ioctl
> * Misc device name:sram
> * Use tristate for SRAM_UAPI
> * Use postcore_initcall
>
> Changes since v2: addressed comments from Arnd, greg and Scott
> * Name the module with sram_dynamic in comparing with drivers/misc/sram.c
>
> I tried to tie the sram_dynamic with the abstractions in sram.c as
> Arnd suggested, and actually sram.c probes SRAM devices from devicetree
> and manages them with different partitions and create memory pools which
> are managed with genalloc functions.
>
> Here sram_dynamic acts only as a interface to user space. A SRAM memory
> pool is managed by the module that registers APIs to us, such as the
> backend hardware driver of Freescale 85xx Cache-SRAM.
>
> * Create one sram_device for each backend SRAM device(from Scott)
> * Allow only one block of SRAM memory allocated to a file descriptor(from Scott)
> * Add sysfs files for every allocated SRAM memory block
> * More documentations(As Greg commented)
> * Make uapi and non-uapi components apart(from Arnd and Greg)
>
> Links:
> v1: https://lore.kernel.org/lkml/20200418162157.50428-5-wenhu.wang@vivo.com/
> v2: https://lore.kernel.org/lkml/20200420030538.101696-1-wenhu.wang@vivo.com/
> UIO version:
> v5: https://lore.kernel.org/lkml/20200417071616.44598-5-wenhu.wang@vivo.com/
> ---
> drivers/misc/Kconfig | 11 +
> drivers/misc/Makefile | 1 +
> drivers/misc/sram_dynamic.c | 580 +++++++++++++++++++++++++++++++++++
> drivers/misc/sram_uapi.c | 351 +++++++++++++++++++++
> include/linux/sram_dynamic.h | 23 ++
> include/uapi/linux/sram.h | 11 +
> 6 files changed, 977 insertions(+)
> create mode 100644 drivers/misc/sram_dynamic.c
> create mode 100644 drivers/misc/sram_uapi.c
> create mode 100644 include/linux/sram_dynamic.h
> create mode 100644 include/uapi/linux/sram.h
>
> diff --git a/include/linux/sram_dynamic.h b/include/linux/sram_dynamic.h
> new file mode 100644
> index 000000000000..c77e9e7b1151
> --- /dev/null
> +++ b/include/linux/sram_dynamic.h
> @@ -0,0 +1,23 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __SRAM_DYNAMIC_H
> +#define __SRAM_DYNAMIC_H
> +
> +struct sram_api {
> + const char *name;
> + struct sram_device *sdev;
> + void *(*alloc)(__u32 size, phys_addr_t *phys, __u32 align);
> + void (*free)(void *ptr);
> +};
> +
> +extern int __must_check
> + __sram_register_device(struct module *owner,
> + struct device *parent,
> + struct sram_api *sa);
'extern' keyword is useless here, remove it (checkpatch --strict will
likely tell you the same)
> +
> +/* Use a define to avoid include chaining to get THIS_MODULE */
> +#define sram_register_device(parent, sa) \
> + __sram_register_device(THIS_MODULE, parent, sa)
> +
> +extern void sram_unregister_device(struct sram_api *sa);
Same, no 'extern' please.
> +
> +#endif /* __SRAM_DYNAMIC_H */
> diff --git a/include/uapi/linux/sram.h b/include/uapi/linux/sram.h
> new file mode 100644
> index 000000000000..9b4a2615dbfe
> --- /dev/null
> +++ b/include/uapi/linux/sram.h
> @@ -0,0 +1,11 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __SRAM_H
> +#define __SRAM_H
> +
> +/* Allocate memory resource from SRAM */
> +#define SRAM_UAPI_IOC_ALLOC _IOWR('S', 0, __be64)
> +
> +/* Free allocated memory resource to SRAM */
> +#define SRAM_UAPI_IOC_FREE _IO('S', 1)
> +
> +#endif /* __SRAM_H */
>
Christophe
^ permalink raw reply
* Re: [PATCH v3,5/5] powerpc: sysdev: support userspace access of fsl_85xx_sram
From: Christophe Leroy @ 2020-04-24 5:29 UTC (permalink / raw)
To: Wang Wenhu, gregkh, arnd, linux-kernel, linuxppc-dev
Cc: robh, oss, kernel, paulus
In-Reply-To: <20200424024554.30709-6-wenhu.wang@vivo.com>
Le 24/04/2020 à 04:45, Wang Wenhu a écrit :
> New module which registers its memory allocation and free APIs to the
> sram_dynamic module, which would create a device of struct sram_device
> type to act as an interface for user level applications to access the
> backend hardware device, fsl_85xx_cache_sram, which is drived by the
> FSL_85XX_CACHE_SRAM module.
>
> Signed-off-by: Wang Wenhu <wenhu.wang@vivo.com>
> Cc: Christophe Leroy <christophe.leroy@c-s.fr>
> Cc: Scott Wood <oss@buserror.net>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: linuxppc-dev@lists.ozlabs.org
> ---
> .../powerpc/include/asm/fsl_85xx_cache_sram.h | 4 ++
> arch/powerpc/platforms/85xx/Kconfig | 10 +++++
> arch/powerpc/sysdev/Makefile | 1 +
> arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h | 6 +++
> arch/powerpc/sysdev/fsl_85xx_cache_sram.c | 12 ++++++
> arch/powerpc/sysdev/fsl_85xx_sram_uapi.c | 39 +++++++++++++++++++
> 6 files changed, 72 insertions(+)
> create mode 100644 arch/powerpc/sysdev/fsl_85xx_sram_uapi.c
We shouldn't add more stuff in arch/powerpc/sysdev/
Either it is dedicated to 85xx, and it should go into
arch/powerpc/platform/85xx/ , or it is common to several
platforms/architectures and should be moved to drivers/soc/fsl/
>
> diff --git a/arch/powerpc/include/asm/fsl_85xx_cache_sram.h b/arch/powerpc/include/asm/fsl_85xx_cache_sram.h
> index 0235a0447baa..99cb7e202c38 100644
> --- a/arch/powerpc/include/asm/fsl_85xx_cache_sram.h
> +++ b/arch/powerpc/include/asm/fsl_85xx_cache_sram.h
> @@ -26,6 +26,10 @@ struct mpc85xx_cache_sram {
> unsigned int size;
> rh_info_t *rh;
> spinlock_t lock;
> +
> +#ifdef CONFIG_FSL_85XX_SRAM_UAPI
> + struct device *dev;
> +#endif
> };
>
> extern void mpc85xx_cache_sram_free(void *ptr);
> diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
> index fa3d29dcb57e..3a6f6af973eb 100644
> --- a/arch/powerpc/platforms/85xx/Kconfig
> +++ b/arch/powerpc/platforms/85xx/Kconfig
> @@ -16,6 +16,16 @@ if FSL_SOC_BOOKE
>
> if PPC32
>
> +config FSL_85XX_SRAM_UAPI
> + tristate "Freescale MPC85xx SRAM UAPI Support"
> + depends on FSL_SOC_BOOKE && SRAM_DYNAMIC
Is SRAM_DYNAMIC usefull on its own, without a driver like this one ? Is
that worth allowing tiny selection of both drivers ? Shouldn't one of
them imply the other one ?
> + select FSL_85XX_CACHE_SRAM
> + help
> + This registers a device of struct sram_device type which would act as
> + an interface for user level applications to access the Freescale 85xx
> + Cache-SRAM memory dynamically, meaning allocate on demand dynamically
> + while they are running.
> +
> config FSL_85XX_CACHE_SRAM
> bool
> select PPC_LIB_RHEAP
> diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
> index cb5a5bd2cef5..e71f82f0d2c3 100644
> --- a/arch/powerpc/sysdev/Makefile
> +++ b/arch/powerpc/sysdev/Makefile
> @@ -24,6 +24,7 @@ obj-$(CONFIG_FSL_CORENET_RCPM) += fsl_rcpm.o
> obj-$(CONFIG_FSL_LBC) += fsl_lbc.o
> obj-$(CONFIG_FSL_GTM) += fsl_gtm.o
> obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o
> +obj-$(CONFIG_FSL_85XX_SRAM_UAPI) += fsl_85xx_sram_uapi.o
> obj-$(CONFIG_FSL_RIO) += fsl_rio.o fsl_rmu.o
> obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
> obj-$(CONFIG_RTC_DRV_CMOS) += rtc_cmos_setup.o
> diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h b/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
> index ce370749add9..4930784d9852 100644
> --- a/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
> +++ b/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
> @@ -10,6 +10,8 @@
> #ifndef __FSL_85XX_CACHE_CTLR_H__
> #define __FSL_85XX_CACHE_CTLR_H__
>
> +#include <linux/platform_device.h>
> +
> #define L2CR_L2FI 0x40000000 /* L2 flash invalidate */
> #define L2CR_L2IO 0x00200000 /* L2 instruction only */
> #define L2CR_SRAM_ZERO 0x00000000 /* L2SRAM zero size */
> @@ -81,6 +83,10 @@ struct sram_parameters {
> phys_addr_t sram_offset;
> };
>
> +#ifdef CONFIG_FSL_85XX_SRAM_UAPI
> +extern struct mpc85xx_cache_sram *mpc85xx_get_cache_sram(void);
'extern' keywork is meaningless here, remove it.
> +#endif
> +
> extern int instantiate_cache_sram(struct platform_device *dev,
> struct sram_parameters sram_params);
> extern void remove_cache_sram(struct platform_device *dev);
> diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
> index 3de5ac8382c0..0156ea63a3a2 100644
> --- a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
> +++ b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
> @@ -23,6 +23,14 @@
>
> struct mpc85xx_cache_sram *cache_sram;
>
> +
> +#ifdef CONFIG_FSL_85XX_SRAM_UAPI
> +struct mpc85xx_cache_sram *mpc85xx_get_cache_sram(void)
> +{
> + return cache_sram;
> +}
> +#endif
This function is not worth the mess of an #ifdef in a .c file.
cache_sram is already globaly visible, so this function should go in
fsl_85xx_cache_ctlr.h as a 'static inline'
> +
> void *mpc85xx_cache_sram_alloc(unsigned int size,
> phys_addr_t *phys, unsigned int align)
> {
> @@ -115,6 +123,10 @@ int instantiate_cache_sram(struct platform_device *dev,
> rh_attach_region(cache_sram->rh, 0, cache_sram->size);
> spin_lock_init(&cache_sram->lock);
>
> +#ifdef CONFIG_FSL_85XX_SRAM_UAPI
> + cache_sram->dev = &dev->dev;
> +#endif
Can we avoid the #ifdef in .c file ? (see
https://www.kernel.org/doc/html/latest/process/coding-style.html#conditional-compilation)
> +
> dev_info(&dev->dev, "[base:0x%llx, size:0x%x] configured and loaded\n",
> (unsigned long long)cache_sram->base_phys, cache_sram->size);
>
> diff --git a/arch/powerpc/sysdev/fsl_85xx_sram_uapi.c b/arch/powerpc/sysdev/fsl_85xx_sram_uapi.c
> new file mode 100644
> index 000000000000..60190bf3c8e9
> --- /dev/null
> +++ b/arch/powerpc/sysdev/fsl_85xx_sram_uapi.c
> @@ -0,0 +1,39 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 Vivo Communication Technology Co. Ltd.
> + * Copyright (C) 2020 Wang Wenhu <wenhu.wang@vivo.com>
> + * All rights reserved.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/sram_dynamic.h>
> +#include <asm/fsl_85xx_cache_sram.h>
> +#include "fsl_85xx_cache_ctlr.h"
> +
> +static struct sram_api mpc85xx_sram_api = {
> + .name = "mpc85xx_sram",
> + .alloc = mpc85xx_cache_sram_alloc,
> + .free = mpc85xx_cache_sram_free,
> +};
> +
> +static int __init mpc85xx_sram_uapi_init(void)
> +{
> + struct mpc85xx_cache_sram *sram = mpc85xx_get_cache_sram();
> +
> + if (!sram)
> + return -ENODEV;
> +
> + return sram_register_device(sram->dev, &mpc85xx_sram_api);
> +}
> +subsys_initcall(mpc85xx_sram_uapi_init);
> +
> +static void __exit mpc85xx_sram_uapi_exit(void)
> +{
> + sram_unregister_device(&mpc85xx_sram_api);
> +}
> +module_exit(mpc85xx_sram_uapi_exit);
> +
> +MODULE_AUTHOR("Wang Wenhu <wenhu.wang@vivo.com>");
> +MODULE_DESCRIPTION("MPC85xx SRAM User-Space API Support");
> +MODULE_LICENSE("GPL v2");
>
Christophe
^ permalink raw reply
* Re: [PATCH v3 13/16] powerpc/watchpoint: Prepare handler to handle more than one watcnhpoint
From: Christophe Leroy @ 2020-04-24 5:48 UTC (permalink / raw)
To: Ravi Bangoria
Cc: apopple, mikey, peterz, oleg, npiggin, linux-kernel, paulus,
jolsa, fweisbec, naveen.n.rao, linuxppc-dev, mingo
In-Reply-To: <f571127c-89b0-a333-be71-18f411dc6586@linux.ibm.com>
Hi Ravi,
Le 24/04/2020 à 05:32, Ravi Bangoria a écrit :
> Hi Christophe,
>
>>> @@ -101,14 +129,20 @@ static bool is_ptrace_bp(struct perf_event *bp)
>>> */
>>> void arch_unregister_hw_breakpoint(struct perf_event *bp)
>>> {
>>> + int i;
>>> +
>>
>> This declaration should be in the block using it.
>>
>>> /*
>>> * If the breakpoint is unregistered between a
>>> hw_breakpoint_handler()
>>> * and the single_step_dabr_instruction(), then cleanup the
>>> breakpoint
>>> * restoration variables to prevent dangling pointers.
>>> * FIXME, this should not be using bp->ctx at all! Sayeth peterz.
>>> */
>>> - if (bp->ctx && bp->ctx->task && bp->ctx->task != ((void *)-1L))
>>> - bp->ctx->task->thread.last_hit_ubp = NULL;
>>> + if (bp->ctx && bp->ctx->task && bp->ctx->task != ((void *)-1L)) {
>>
>> Add declaration of 'int i' here.
>
> How will that help? Keeping declaration at the start of function is also
> common practice and I don't see any recommendation to move them inside
> conditional block.
Reducing the scope of local variables increases readability, you don't
have to scroll all up to the top of the function to see the declaration
of the variable.
common practice ? Are you sure ? Just have a look at fs/io_uring.c or
many other files in the kernel to see how uncommon your practice is.
Christophe
^ permalink raw reply
* Re: [PATCH v3,4/5] misc: sram_dynamic for user level SRAM access
From: 王文虎 @ 2020-04-24 6:47 UTC (permalink / raw)
To: Christophe Leroy
Cc: robh, arnd, gregkh, linux-kernel, oss, kernel, paulus,
linuxppc-dev
In-Reply-To: <6675dd9d-43be-6451-88a9-02d2c52c7d3a@c-s.fr>
>> diff --git a/include/linux/sram_dynamic.h b/include/linux/sram_dynamic.h
>> new file mode 100644
>> index 000000000000..c77e9e7b1151
>> --- /dev/null
>> +++ b/include/linux/sram_dynamic.h
>> @@ -0,0 +1,23 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +#ifndef __SRAM_DYNAMIC_H
>> +#define __SRAM_DYNAMIC_H
>> +
>> +struct sram_api {
>> + const char *name;
>> + struct sram_device *sdev;
>> + void *(*alloc)(__u32 size, phys_addr_t *phys, __u32 align);
>> + void (*free)(void *ptr);
>> +};
>> +
>> +extern int __must_check
>> + __sram_register_device(struct module *owner,
>> + struct device *parent,
>> + struct sram_api *sa);
>
>'extern' keyword is useless here, remove it (checkpatch --strict will
>likely tell you the same)
>
>> +
>> +/* Use a define to avoid include chaining to get THIS_MODULE */
>> +#define sram_register_device(parent, sa) \
>> + __sram_register_device(THIS_MODULE, parent, sa)
>> +
>> +extern void sram_unregister_device(struct sram_api *sa);
>
>Same, no 'extern' please.
>
Thanks, I will remove them in patch v4. And checkpatch with --strict will be prefered.
Wenhu
^ permalink raw reply
* [PATCH] ASoC: fsl_esai: Remove the tasklet
From: Shengjiu Wang @ 2020-04-24 6:54 UTC (permalink / raw)
To: timur, nicoleotsuka, Xiubo.Lee, festevam, broonie, lgirdwood,
perex, tiwai, alsa-devel, linuxppc-dev, linux-kernel
Remove tasklet for it may cause the reset operation
can't be handled immediately, then there will be
endless xrun interrupt.
Fixes: 7ccafa2b3879 ("ASoC: fsl_esai: recover the channel swap after xrun")
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
sound/soc/fsl/fsl_esai.c | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index c7a49d03463a..1ad0859da5e2 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -32,7 +32,6 @@
* @extalclk: esai clock source to derive HCK, SCK and FS
* @fsysclk: system clock source to derive HCK, SCK and FS
* @spbaclk: SPBA clock (optional, depending on SoC design)
- * @task: tasklet to handle the reset operation
* @lock: spin lock between hw_reset() and trigger()
* @fifo_depth: depth of tx/rx FIFO
* @slot_width: width of each DAI slot
@@ -56,7 +55,6 @@ struct fsl_esai {
struct clk *extalclk;
struct clk *fsysclk;
struct clk *spbaclk;
- struct tasklet_struct task;
spinlock_t lock; /* Protect hw_reset and trigger */
u32 fifo_depth;
u32 slot_width;
@@ -74,6 +72,8 @@ struct fsl_esai {
char name[32];
};
+static void fsl_esai_hw_reset(struct fsl_esai *esai_priv);
+
static irqreturn_t esai_isr(int irq, void *devid)
{
struct fsl_esai *esai_priv = (struct fsl_esai *)devid;
@@ -87,7 +87,7 @@ static irqreturn_t esai_isr(int irq, void *devid)
if ((saisr & (ESAI_SAISR_TUE | ESAI_SAISR_ROE)) &&
esai_priv->reset_at_xrun) {
dev_dbg(&pdev->dev, "reset module for xrun\n");
- tasklet_schedule(&esai_priv->task);
+ fsl_esai_hw_reset(esai_priv);
}
if (esr & ESAI_ESR_TINIT_MASK)
@@ -674,9 +674,8 @@ static void fsl_esai_trigger_stop(struct fsl_esai *esai_priv, bool tx)
ESAI_xFCR_xFR, 0);
}
-static void fsl_esai_hw_reset(unsigned long arg)
+static void fsl_esai_hw_reset(struct fsl_esai *esai_priv)
{
- struct fsl_esai *esai_priv = (struct fsl_esai *)arg;
bool tx = true, rx = false, enabled[2];
unsigned long lock_flags;
u32 tfcr, rfcr;
@@ -1034,9 +1033,6 @@ static int fsl_esai_probe(struct platform_device *pdev)
return ret;
}
- tasklet_init(&esai_priv->task, fsl_esai_hw_reset,
- (unsigned long)esai_priv);
-
pm_runtime_enable(&pdev->dev);
regcache_cache_only(esai_priv->regmap, true);
@@ -1050,10 +1046,7 @@ static int fsl_esai_probe(struct platform_device *pdev)
static int fsl_esai_remove(struct platform_device *pdev)
{
- struct fsl_esai *esai_priv = platform_get_drvdata(pdev);
-
pm_runtime_disable(&pdev->dev);
- tasklet_kill(&esai_priv->task);
return 0;
}
--
2.21.0
^ permalink raw reply related
* Re: [PATCH v3,5/5] powerpc: sysdev: support userspace access of fsl_85xx_sram
From: 王文虎 @ 2020-04-24 7:05 UTC (permalink / raw)
To: Christophe Leroy
Cc: robh, arnd, gregkh, linux-kernel, oss, kernel, paulus,
linuxppc-dev
In-Reply-To: <0dfd17ca-d11e-9cf3-177e-bce0b8eace5c@c-s.fr>
>Le 24/04/2020 à 04:45, Wang Wenhu a écrit :
>> New module which registers its memory allocation and free APIs to the
>> sram_dynamic module, which would create a device of struct sram_device
>> type to act as an interface for user level applications to access the
>> backend hardware device, fsl_85xx_cache_sram, which is drived by the
>> FSL_85XX_CACHE_SRAM module.
>>
>> Signed-off-by: Wang Wenhu <wenhu.wang@vivo.com>
>> Cc: Christophe Leroy <christophe.leroy@c-s.fr>
>> Cc: Scott Wood <oss@buserror.net>
>> Cc: Michael Ellerman <mpe@ellerman.id.au>
>> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>> Cc: Arnd Bergmann <arnd@arndb.de>
>> Cc: linuxppc-dev@lists.ozlabs.org
>> ---
>> .../powerpc/include/asm/fsl_85xx_cache_sram.h | 4 ++
>> arch/powerpc/platforms/85xx/Kconfig | 10 +++++
>> arch/powerpc/sysdev/Makefile | 1 +
>> arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h | 6 +++
>> arch/powerpc/sysdev/fsl_85xx_cache_sram.c | 12 ++++++
>> arch/powerpc/sysdev/fsl_85xx_sram_uapi.c | 39 +++++++++++++++++++
>> 6 files changed, 72 insertions(+)
>> create mode 100644 arch/powerpc/sysdev/fsl_85xx_sram_uapi.c
>
>We shouldn't add more stuff in arch/powerpc/sysdev/
>
>Either it is dedicated to 85xx, and it should go into
>arch/powerpc/platform/85xx/ , or it is common to several
>platforms/architectures and should be moved to drivers/soc/fsl/
>
Sure, actually I tried to find a better place, but did not recognize
the driver/soc. Thanks, and I will put fsl_85xx_sram_uapi there.
>>
>> diff --git a/arch/powerpc/include/asm/fsl_85xx_cache_sram.h b/arch/powerpc/include/asm/fsl_85xx_cache_sram.h
>> index 0235a0447baa..99cb7e202c38 100644
>> --- a/arch/powerpc/include/asm/fsl_85xx_cache_sram.h
>> +++ b/arch/powerpc/include/asm/fsl_85xx_cache_sram.h
>> @@ -26,6 +26,10 @@ struct mpc85xx_cache_sram {
>> unsigned int size;
>> rh_info_t *rh;
>> spinlock_t lock;
>> +
>> +#ifdef CONFIG_FSL_85XX_SRAM_UAPI
>> + struct device *dev;
>> +#endif
>> };
>>
>> extern void mpc85xx_cache_sram_free(void *ptr);
>> diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
>> index fa3d29dcb57e..3a6f6af973eb 100644
>> --- a/arch/powerpc/platforms/85xx/Kconfig
>> +++ b/arch/powerpc/platforms/85xx/Kconfig
>> @@ -16,6 +16,16 @@ if FSL_SOC_BOOKE
>>
>> if PPC32
>>
>> +config FSL_85XX_SRAM_UAPI
>> + tristate "Freescale MPC85xx SRAM UAPI Support"
>> + depends on FSL_SOC_BOOKE && SRAM_DYNAMIC
>
>Is SRAM_DYNAMIC usefull on its own, without a driver like this one ? Is
>that worth allowing tiny selection of both drivers ? Shouldn't one of
>them imply the other one ?
Truely the module like this is the top level selection, and SRAM_DYNAMIC
should be selected by any caller modules. As SRAM_DYNAMIC may be used by
other drivers(in the future, but currently only us here), I think make it
seleted by this is better? (show below)
diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig
index 4df32bc4c7a6..ceeebb22f6d3 100644
--- a/drivers/soc/fsl/Kconfig
+++ b/drivers/soc/fsl/Kconfig
@@ -50,4 +50,16 @@ config FSL_RCPM
tasks associated with power management, such as wakeup source control.
Note that currently this driver will not support PowerPC based
QorIQ processor.
+
+config FSL_85XX_SRAM_UAPI
+ tristate "Freescale MPC85xx SRAM UAPI Support"
+ depends on FSL_SOC_BOOKE && PPC32
+ select FSL_85XX_CACHE_SRAM
+ select SRAM_DYNAMIC
+ help
+ This registers a device of struct sram_device type which would act as
+ an interface for user level applications to access the Freescale 85xx
+ Cache-SRAM memory dynamically, meaning allocate on demand dynamically
+ while they are running.
+
endmenu
diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
index 906f1cd8af01..716e38f75735 100644
--- a/drivers/soc/fsl/Makefile
+++ b/drivers/soc/fsl/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_FSL_RCPM) += rcpm.o
obj-$(CONFIG_FSL_GUTS) += guts.o
obj-$(CONFIG_FSL_MC_DPIO) += dpio/
obj-$(CONFIG_DPAA2_CONSOLE) += dpaa2-console.o
+obj-$(CONFIG_FSL_85XX_SRAM_UAPI) += fsl_85xx_sram_uapi.o
>>
>> +#ifdef CONFIG_FSL_85XX_SRAM_UAPI
>> +extern struct mpc85xx_cache_sram *mpc85xx_get_cache_sram(void);
>
>'extern' keywork is meaningless here, remove it.
>
I will remove it in patch v4.
>> +#endif
>> +
>> extern int instantiate_cache_sram(struct platform_device *dev,
>> struct sram_parameters sram_params);
>> extern void remove_cache_sram(struct platform_device *dev);
>> diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
>> index 3de5ac8382c0..0156ea63a3a2 100644
>> --- a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
>> +++ b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
>> @@ -23,6 +23,14 @@
>>
>> struct mpc85xx_cache_sram *cache_sram;
>>
>> +
>> +#ifdef CONFIG_FSL_85XX_SRAM_UAPI
>> +struct mpc85xx_cache_sram *mpc85xx_get_cache_sram(void)
>> +{
>> + return cache_sram;
>> +}
>> +#endif
>
>This function is not worth the mess of an #ifdef in a .c file.
>cache_sram is already globaly visible, so this function should go in
>fsl_85xx_cache_ctlr.h as a 'static inline'
>
Yes, and I will change it like this, with an extern of cache_sram.
#define L2CR_SRAM_ZERO 0x00000000 /* L2SRAM zero size */
@@ -81,6 +83,15 @@ struct sram_parameters {
phys_addr_t sram_offset;
};
+#ifdef CONFIG_FSL_85XX_SRAM_UAPI
+extern struct mpc85xx_cache_sram *cache_sram;
+
+static inline struct mpc85xx_cache_sram *mpc85xx_get_cache_sram(void)
+{
+ return cache_sram;
+}
+#endif
+
extern int instantiate_cache_sram(struct platform_device *dev,
>> +
>> void *mpc85xx_cache_sram_alloc(unsigned int size,
>> phys_addr_t *phys, unsigned int align)
>> {
>> @@ -115,6 +123,10 @@ int instantiate_cache_sram(struct platform_device *dev,
>> rh_attach_region(cache_sram->rh, 0, cache_sram->size);
>> spin_lock_init(&cache_sram->lock);
>>
>> +#ifdef CONFIG_FSL_85XX_SRAM_UAPI
>> + cache_sram->dev = &dev->dev;
>> +#endif
>
> Can we avoid the #ifdef in .c file ? (see
>https://www.kernel.org/doc/html/latest/process/coding-style.html#conditional-compilation)
>
Definitely, and I will change it as below in patch v4:
+ if (IS_ENABLED(CONFIG_FSL_85XX_SRAM_UAPI))
+ cache_sram->dev = &dev->dev;
+
dev_info(&dev->dev, "[base:0x%llx, size:0x%x] configured and loaded\n",
Thanks, for your suggestions, as these are minor modifications,
I will send a new patch series v4 soon.
Regards,
Wenhu
^ permalink raw reply related
* [RFC PATCH v2 0/7] consolidate PowerPC instruction encoding macros
From: Balamuruhan S @ 2020-04-24 7:08 UTC (permalink / raw)
To: mpe
Cc: ravi.bangoria, jniethe5, Balamuruhan S, paulus, sandipan,
naveen.n.rao, linuxppc-dev
ppc-opcode.h have base instruction encoding wrapped with stringify_in_c()
for raw encoding to have compatibility. But there are redundant macros for
base instruction encodings in bpf, instruction emulation test infrastructure
and powerpc selftests.
Currently PPC_INST_* macros are used for encoding instruction opcode and PPC_*
for raw instuction encoding, this rfc patchset introduces PPC_RAW_* macros for
base instruction encoding and reuse it from elsewhere. With this change we can
avoid redundant macro definitions in multiple files and start adding new
instructions in ppc-opcode.h in future.
Changes in v2:
-------------
Fix review comments/suggestions from Naveen and Michael Ellerman,
* Rename PPC_ENCODE_* to PPC_RAW_* for base instruction encoding macros.
* Split the patches that does mass renaming and make them simpler that just
adds new macros.
* Keep the patch to update all the existing names later (patch 6).
* Lot of PPC_INST_* macros are used only in ppc-opcode.h for PPC_* macros,
fold PPC_INST_* encoding into PPC_RAW_* to avoid using them accidentally.
* Fixed clipped macros that was due to a typo/copy-paste
* Consolidated all the instruction encoding macros from bpf_jit.h to
ppc-opcode.h
* squashed patch that removes the duplicate macro PPC_MR() in bpf_jit.h
* merge few changes in bpf_jit files from patch 2 into patch 3
* few fixes in powerpc selftest stringloops Makefile
* build tested for ppc64le_defconfig, ppc64e_defconfig and pmac32_defconfig
* Rebased on next branch of linuxppc tree
Testing:
-------
* Tested it by compiling vmlinux and comparing objdump of it with and without
the patchset and observed that it remains same,
# diff vmlinux_objdump vmlinux_rfc_objdump
2c2
< vmlinux: file format elf64-powerpcle
---
> vmlinux_rfc: file format elf64-powerpcle
* Tested building it with this changes for Fedora30 config, booted VM
with powerpc next and powerpc next + patchset to run powerpc selftest and
ftrace selftest. There were couple of failures that were common and
patchset did not introduce any new failures.
ftrace selftest:
---------------
# # of passed: 96
# # of failed: 1
# # of unresolved: 7
# # of untested: 0
# # of unsupported: 1
# # of xfailed: 1
# # of undefined(test bug): 0
not ok 1 selftests: ftrace: ftracetest # exit=1
powerpc selftest:
----------------
not ok 7 selftests: powerpc/dscr: dscr_sysfs_thread_test # exit=1
not ok 20 selftests: powerpc/pmu/ebb: lost_exception_test # TIMEOUT
not ok 2 selftests: powerpc/security: spectre_v2 # exit=1
Thanks to Naveen, Sandipan and Michael on overall suggestions/improvements.
I would request for review and suggestions to make it better.
v1: https://lists.ozlabs.org/pipermail/linuxppc-dev/2020-March/206494.html
Balamuruhan S (7):
powerpc/ppc-opcode: introduce PPC_RAW_* macros for base instruction
encoding
powerpc/ppc-opcode: move ppc instruction encoding from
test_emulate_step
powerpc/bpf_jit: reuse instruction macros from ppc-opcode.h
powerpc/ppc-opcode: consolidate powerpc instructions from bpf_jit.h
powerpc/ppc-opcode: reuse raw instruction macros to stringify
powerpc/ppc-opcode: fold PPC_INST_* macros into PPC_RAW_* macros
powerpc/selftest: reuse ppc-opcode macros to avoid redundancy
arch/powerpc/include/asm/ppc-opcode.h | 706 +++++++++++-------
arch/powerpc/lib/test_emulate_step.c | 155 ++--
arch/powerpc/net/bpf_jit.h | 184 +----
arch/powerpc/net/bpf_jit32.h | 34 +-
arch/powerpc/net/bpf_jit64.h | 16 +-
arch/powerpc/net/bpf_jit_comp.c | 134 ++--
arch/powerpc/net/bpf_jit_comp64.c | 298 ++++----
.../selftests/powerpc/stringloops/Makefile | 34 +-
.../powerpc/stringloops/asm/asm-const.h | 1 +
.../powerpc/stringloops/asm/ppc-opcode.h | 36 +-
10 files changed, 762 insertions(+), 836 deletions(-)
create mode 120000 tools/testing/selftests/powerpc/stringloops/asm/asm-const.h
mode change 100644 => 120000 tools/testing/selftests/powerpc/stringloops/asm/ppc-opcode.h
base-commit: 45591da765885f7320a111d290b3a28a23eed359
--
2.24.1
^ permalink raw reply
* [RFC PATCH v2 2/7] powerpc/ppc-opcode: move ppc instruction encoding from test_emulate_step
From: Balamuruhan S @ 2020-04-24 7:08 UTC (permalink / raw)
To: mpe
Cc: ravi.bangoria, jniethe5, Balamuruhan S, paulus, sandipan,
naveen.n.rao, linuxppc-dev
In-Reply-To: <20200424070853.443969-1-bala24@linux.ibm.com>
Few ppc instructions are encoded in test_emulate_step.c, consolidate
them and use it from ppc-opcode.h
Signed-off-by: Balamuruhan S <bala24@linux.ibm.com>
---
arch/powerpc/include/asm/ppc-opcode.h | 35 ++++++
arch/powerpc/lib/test_emulate_step.c | 155 ++++++++++----------------
2 files changed, 91 insertions(+), 99 deletions(-)
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index c5ec2ea283f1..2ae0afc5c2bb 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -76,6 +76,9 @@
#define __REGA0_R30 30
#define __REGA0_R31 31
+#define IMM_L(i) ((uintptr_t)(i) & 0xffff)
+#define IMM_DS(i) ((uintptr_t)(i) & 0xfffc)
+
/* opcode and xopcode for instructions */
#define OP_TRAP 3
#define OP_TRAP_64 2
@@ -602,6 +605,38 @@
___PPC_RT(vrt) | \
___PPC_RA(vra) | \
___PPC_RB(vrb) | __PPC_RC21)
+#define PPC_RAW_LD(r, base, i) (PPC_INST_LD | ___PPC_RT(r) | \
+ ___PPC_RA(base) | IMM_DS(i))
+#define PPC_RAW_LWZ(r, base, i) (PPC_INST_LWZ | ___PPC_RT(r) | \
+ ___PPC_RA(base) | IMM_L(i))
+#define PPC_RAW_LWZX(t, a, b) (PPC_INST_LWZX | ___PPC_RT(t) | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_STD(r, base, i) (PPC_INST_STD | ___PPC_RS(r) | \
+ ___PPC_RA(base) | IMM_DS(i))
+#define PPC_RAW_STDCX(s, a, b) (PPC_INST_STDCX | ___PPC_RS(s) | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_LFSX(t, a, b) (PPC_INST_LFSX | ___PPC_RT(t) | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_STFSX(s, a, b) (PPC_INST_STFSX | ___PPC_RS(s) | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_LFDX(t, a, b) (PPC_INST_LFDX | ___PPC_RT(t) | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_STFDX(s, a, b) (PPC_INST_STFDX | ___PPC_RS(s) | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_LVX(t, a, b) (PPC_INST_LVX | ___PPC_RT(t) | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_STVX(s, a, b) (PPC_INST_STVX | ___PPC_RS(s) | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_ADD(t, a, b) (PPC_INST_ADD | ___PPC_RT(t) | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_ADD_DOT(t, a, b) (PPC_INST_ADD | ___PPC_RT(t) | \
+ ___PPC_RA(a) | ___PPC_RB(b) | \
+ 0x1)
+#define PPC_RAW_ADDC(t, a, b) (PPC_INST_ADDC | ___PPC_RT(t) | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_ADDC_DOT(t, a, b) (PPC_INST_ADDC | ___PPC_RT(t) | \
+ ___PPC_RA(a) | ___PPC_RB(b) | \
+ 0x1)
/* Deal with instructions that older assemblers aren't aware of */
#define PPC_CP_ABORT stringify_in_c(.long PPC_INST_CP_ABORT)
diff --git a/arch/powerpc/lib/test_emulate_step.c b/arch/powerpc/lib/test_emulate_step.c
index 53df4146dd32..7a703bec3061 100644
--- a/arch/powerpc/lib/test_emulate_step.c
+++ b/arch/powerpc/lib/test_emulate_step.c
@@ -12,49 +12,6 @@
#include <asm/ppc-opcode.h>
#include <asm/code-patching.h>
-#define IMM_L(i) ((uintptr_t)(i) & 0xffff)
-#define IMM_DS(i) ((uintptr_t)(i) & 0xfffc)
-
-/*
- * Defined with TEST_ prefix so it does not conflict with other
- * definitions.
- */
-#define TEST_LD(r, base, i) (PPC_INST_LD | ___PPC_RT(r) | \
- ___PPC_RA(base) | IMM_DS(i))
-#define TEST_LWZ(r, base, i) (PPC_INST_LWZ | ___PPC_RT(r) | \
- ___PPC_RA(base) | IMM_L(i))
-#define TEST_LWZX(t, a, b) (PPC_INST_LWZX | ___PPC_RT(t) | \
- ___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_STD(r, base, i) (PPC_INST_STD | ___PPC_RS(r) | \
- ___PPC_RA(base) | IMM_DS(i))
-#define TEST_LDARX(t, a, b, eh) (PPC_INST_LDARX | ___PPC_RT(t) | \
- ___PPC_RA(a) | ___PPC_RB(b) | \
- __PPC_EH(eh))
-#define TEST_STDCX(s, a, b) (PPC_INST_STDCX | ___PPC_RS(s) | \
- ___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_LFSX(t, a, b) (PPC_INST_LFSX | ___PPC_RT(t) | \
- ___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_STFSX(s, a, b) (PPC_INST_STFSX | ___PPC_RS(s) | \
- ___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_LFDX(t, a, b) (PPC_INST_LFDX | ___PPC_RT(t) | \
- ___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_STFDX(s, a, b) (PPC_INST_STFDX | ___PPC_RS(s) | \
- ___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_LVX(t, a, b) (PPC_INST_LVX | ___PPC_RT(t) | \
- ___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_STVX(s, a, b) (PPC_INST_STVX | ___PPC_RS(s) | \
- ___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_LXVD2X(s, a, b) (PPC_INST_LXVD2X | VSX_XX1((s), R##a, R##b))
-#define TEST_STXVD2X(s, a, b) (PPC_INST_STXVD2X | VSX_XX1((s), R##a, R##b))
-#define TEST_ADD(t, a, b) (PPC_INST_ADD | ___PPC_RT(t) | \
- ___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_ADD_DOT(t, a, b) (PPC_INST_ADD | ___PPC_RT(t) | \
- ___PPC_RA(a) | ___PPC_RB(b) | 0x1)
-#define TEST_ADDC(t, a, b) (PPC_INST_ADDC | ___PPC_RT(t) | \
- ___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_ADDC_DOT(t, a, b) (PPC_INST_ADDC | ___PPC_RT(t) | \
- ___PPC_RA(a) | ___PPC_RB(b) | 0x1)
-
#define MAX_SUBTESTS 16
#define IGNORE_GPR(n) (0x1UL << (n))
@@ -104,7 +61,7 @@ static void __init test_ld(void)
regs.gpr[3] = (unsigned long) &a;
/* ld r5, 0(r3) */
- stepped = emulate_step(®s, TEST_LD(5, 3, 0));
+ stepped = emulate_step(®s, PPC_RAW_LD(5, 3, 0));
if (stepped == 1 && regs.gpr[5] == a)
show_result("ld", "PASS");
@@ -122,7 +79,7 @@ static void __init test_lwz(void)
regs.gpr[3] = (unsigned long) &a;
/* lwz r5, 0(r3) */
- stepped = emulate_step(®s, TEST_LWZ(5, 3, 0));
+ stepped = emulate_step(®s, PPC_RAW_LWZ(5, 3, 0));
if (stepped == 1 && regs.gpr[5] == a)
show_result("lwz", "PASS");
@@ -142,7 +99,7 @@ static void __init test_lwzx(void)
regs.gpr[5] = 0x8765;
/* lwzx r5, r3, r4 */
- stepped = emulate_step(®s, TEST_LWZX(5, 3, 4));
+ stepped = emulate_step(®s, PPC_RAW_LWZX(5, 3, 4));
if (stepped == 1 && regs.gpr[5] == a[2])
show_result("lwzx", "PASS");
else
@@ -160,7 +117,7 @@ static void __init test_std(void)
regs.gpr[5] = 0x5678;
/* std r5, 0(r3) */
- stepped = emulate_step(®s, TEST_STD(5, 3, 0));
+ stepped = emulate_step(®s, PPC_RAW_STD(5, 3, 0));
if (stepped == 1 && regs.gpr[5] == a)
show_result("std", "PASS");
else
@@ -185,7 +142,7 @@ static void __init test_ldarx_stdcx(void)
regs.gpr[5] = 0x5678;
/* ldarx r5, r3, r4, 0 */
- stepped = emulate_step(®s, TEST_LDARX(5, 3, 4, 0));
+ stepped = emulate_step(®s, PPC_RAW_LDARX(5, 3, 4, 0));
/*
* Don't touch 'a' here. Touching 'a' can do Load/store
@@ -203,7 +160,7 @@ static void __init test_ldarx_stdcx(void)
regs.gpr[5] = 0x9ABC;
/* stdcx. r5, r3, r4 */
- stepped = emulate_step(®s, TEST_STDCX(5, 3, 4));
+ stepped = emulate_step(®s, PPC_RAW_STDCX(5, 3, 4));
/*
* Two possible scenarios that indicates successful emulation
@@ -243,7 +200,7 @@ static void __init test_lfsx_stfsx(void)
regs.gpr[4] = 0;
/* lfsx frt10, r3, r4 */
- stepped = emulate_step(®s, TEST_LFSX(10, 3, 4));
+ stepped = emulate_step(®s, PPC_RAW_LFSX(10, 3, 4));
if (stepped == 1)
show_result("lfsx", "PASS");
@@ -256,7 +213,7 @@ static void __init test_lfsx_stfsx(void)
c.a = 678.91;
/* stfsx frs10, r3, r4 */
- stepped = emulate_step(®s, TEST_STFSX(10, 3, 4));
+ stepped = emulate_step(®s, PPC_RAW_STFSX(10, 3, 4));
if (stepped == 1 && c.b == cached_b)
show_result("stfsx", "PASS");
@@ -286,7 +243,7 @@ static void __init test_lfdx_stfdx(void)
regs.gpr[4] = 0;
/* lfdx frt10, r3, r4 */
- stepped = emulate_step(®s, TEST_LFDX(10, 3, 4));
+ stepped = emulate_step(®s, PPC_RAW_LFDX(10, 3, 4));
if (stepped == 1)
show_result("lfdx", "PASS");
@@ -299,7 +256,7 @@ static void __init test_lfdx_stfdx(void)
c.a = 987654.32;
/* stfdx frs10, r3, r4 */
- stepped = emulate_step(®s, TEST_STFDX(10, 3, 4));
+ stepped = emulate_step(®s, PPC_RAW_STFDX(10, 3, 4));
if (stepped == 1 && c.b == cached_b)
show_result("stfdx", "PASS");
@@ -345,7 +302,7 @@ static void __init test_lvx_stvx(void)
regs.gpr[4] = 0;
/* lvx vrt10, r3, r4 */
- stepped = emulate_step(®s, TEST_LVX(10, 3, 4));
+ stepped = emulate_step(®s, PPC_RAW_LVX(10, 3, 4));
if (stepped == 1)
show_result("lvx", "PASS");
@@ -361,7 +318,7 @@ static void __init test_lvx_stvx(void)
c.b[3] = 498532;
/* stvx vrs10, r3, r4 */
- stepped = emulate_step(®s, TEST_STVX(10, 3, 4));
+ stepped = emulate_step(®s, PPC_RAW_STVX(10, 3, 4));
if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
@@ -402,7 +359,7 @@ static void __init test_lxvd2x_stxvd2x(void)
regs.gpr[4] = 0;
/* lxvd2x vsr39, r3, r4 */
- stepped = emulate_step(®s, TEST_LXVD2X(39, 3, 4));
+ stepped = emulate_step(®s, PPC_RAW_LXVD2X(39, R3, R4));
if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
show_result("lxvd2x", "PASS");
@@ -422,7 +379,7 @@ static void __init test_lxvd2x_stxvd2x(void)
c.b[3] = 4;
/* stxvd2x vsr39, r3, r4 */
- stepped = emulate_step(®s, TEST_STXVD2X(39, 3, 4));
+ stepped = emulate_step(®s, PPC_RAW_STXVD2X(39, R3, R4));
if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
cached_b[2] == c.b[2] && cached_b[3] == c.b[3] &&
@@ -484,7 +441,7 @@ static struct compute_test compute_tests[] = {
.subtests = {
{
.descr = "RA = LONG_MIN, RB = LONG_MIN",
- .instr = TEST_ADD(20, 21, 22),
+ .instr = PPC_RAW_ADD(20, 21, 22),
.regs = {
.gpr[21] = LONG_MIN,
.gpr[22] = LONG_MIN,
@@ -492,7 +449,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = LONG_MIN, RB = LONG_MAX",
- .instr = TEST_ADD(20, 21, 22),
+ .instr = PPC_RAW_ADD(20, 21, 22),
.regs = {
.gpr[21] = LONG_MIN,
.gpr[22] = LONG_MAX,
@@ -500,7 +457,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = LONG_MAX, RB = LONG_MAX",
- .instr = TEST_ADD(20, 21, 22),
+ .instr = PPC_RAW_ADD(20, 21, 22),
.regs = {
.gpr[21] = LONG_MAX,
.gpr[22] = LONG_MAX,
@@ -508,7 +465,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
- .instr = TEST_ADD(20, 21, 22),
+ .instr = PPC_RAW_ADD(20, 21, 22),
.regs = {
.gpr[21] = ULONG_MAX,
.gpr[22] = ULONG_MAX,
@@ -516,7 +473,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = ULONG_MAX, RB = 0x1",
- .instr = TEST_ADD(20, 21, 22),
+ .instr = PPC_RAW_ADD(20, 21, 22),
.regs = {
.gpr[21] = ULONG_MAX,
.gpr[22] = 0x1,
@@ -524,7 +481,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = INT_MIN, RB = INT_MIN",
- .instr = TEST_ADD(20, 21, 22),
+ .instr = PPC_RAW_ADD(20, 21, 22),
.regs = {
.gpr[21] = INT_MIN,
.gpr[22] = INT_MIN,
@@ -532,7 +489,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = INT_MIN, RB = INT_MAX",
- .instr = TEST_ADD(20, 21, 22),
+ .instr = PPC_RAW_ADD(20, 21, 22),
.regs = {
.gpr[21] = INT_MIN,
.gpr[22] = INT_MAX,
@@ -540,7 +497,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = INT_MAX, RB = INT_MAX",
- .instr = TEST_ADD(20, 21, 22),
+ .instr = PPC_RAW_ADD(20, 21, 22),
.regs = {
.gpr[21] = INT_MAX,
.gpr[22] = INT_MAX,
@@ -548,7 +505,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = UINT_MAX, RB = UINT_MAX",
- .instr = TEST_ADD(20, 21, 22),
+ .instr = PPC_RAW_ADD(20, 21, 22),
.regs = {
.gpr[21] = UINT_MAX,
.gpr[22] = UINT_MAX,
@@ -556,7 +513,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = UINT_MAX, RB = 0x1",
- .instr = TEST_ADD(20, 21, 22),
+ .instr = PPC_RAW_ADD(20, 21, 22),
.regs = {
.gpr[21] = UINT_MAX,
.gpr[22] = 0x1,
@@ -570,7 +527,7 @@ static struct compute_test compute_tests[] = {
{
.descr = "RA = LONG_MIN, RB = LONG_MIN",
.flags = IGNORE_CCR,
- .instr = TEST_ADD_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADD_DOT(20, 21, 22),
.regs = {
.gpr[21] = LONG_MIN,
.gpr[22] = LONG_MIN,
@@ -578,7 +535,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = LONG_MIN, RB = LONG_MAX",
- .instr = TEST_ADD_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADD_DOT(20, 21, 22),
.regs = {
.gpr[21] = LONG_MIN,
.gpr[22] = LONG_MAX,
@@ -587,7 +544,7 @@ static struct compute_test compute_tests[] = {
{
.descr = "RA = LONG_MAX, RB = LONG_MAX",
.flags = IGNORE_CCR,
- .instr = TEST_ADD_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADD_DOT(20, 21, 22),
.regs = {
.gpr[21] = LONG_MAX,
.gpr[22] = LONG_MAX,
@@ -595,7 +552,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
- .instr = TEST_ADD_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADD_DOT(20, 21, 22),
.regs = {
.gpr[21] = ULONG_MAX,
.gpr[22] = ULONG_MAX,
@@ -603,7 +560,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = ULONG_MAX, RB = 0x1",
- .instr = TEST_ADD_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADD_DOT(20, 21, 22),
.regs = {
.gpr[21] = ULONG_MAX,
.gpr[22] = 0x1,
@@ -611,7 +568,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = INT_MIN, RB = INT_MIN",
- .instr = TEST_ADD_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADD_DOT(20, 21, 22),
.regs = {
.gpr[21] = INT_MIN,
.gpr[22] = INT_MIN,
@@ -619,7 +576,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = INT_MIN, RB = INT_MAX",
- .instr = TEST_ADD_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADD_DOT(20, 21, 22),
.regs = {
.gpr[21] = INT_MIN,
.gpr[22] = INT_MAX,
@@ -627,7 +584,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = INT_MAX, RB = INT_MAX",
- .instr = TEST_ADD_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADD_DOT(20, 21, 22),
.regs = {
.gpr[21] = INT_MAX,
.gpr[22] = INT_MAX,
@@ -635,7 +592,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = UINT_MAX, RB = UINT_MAX",
- .instr = TEST_ADD_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADD_DOT(20, 21, 22),
.regs = {
.gpr[21] = UINT_MAX,
.gpr[22] = UINT_MAX,
@@ -643,7 +600,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = UINT_MAX, RB = 0x1",
- .instr = TEST_ADD_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADD_DOT(20, 21, 22),
.regs = {
.gpr[21] = UINT_MAX,
.gpr[22] = 0x1,
@@ -656,7 +613,7 @@ static struct compute_test compute_tests[] = {
.subtests = {
{
.descr = "RA = LONG_MIN, RB = LONG_MIN",
- .instr = TEST_ADDC(20, 21, 22),
+ .instr = PPC_RAW_ADDC(20, 21, 22),
.regs = {
.gpr[21] = LONG_MIN,
.gpr[22] = LONG_MIN,
@@ -664,7 +621,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = LONG_MIN, RB = LONG_MAX",
- .instr = TEST_ADDC(20, 21, 22),
+ .instr = PPC_RAW_ADDC(20, 21, 22),
.regs = {
.gpr[21] = LONG_MIN,
.gpr[22] = LONG_MAX,
@@ -672,7 +629,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = LONG_MAX, RB = LONG_MAX",
- .instr = TEST_ADDC(20, 21, 22),
+ .instr = PPC_RAW_ADDC(20, 21, 22),
.regs = {
.gpr[21] = LONG_MAX,
.gpr[22] = LONG_MAX,
@@ -680,7 +637,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
- .instr = TEST_ADDC(20, 21, 22),
+ .instr = PPC_RAW_ADDC(20, 21, 22),
.regs = {
.gpr[21] = ULONG_MAX,
.gpr[22] = ULONG_MAX,
@@ -688,7 +645,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = ULONG_MAX, RB = 0x1",
- .instr = TEST_ADDC(20, 21, 22),
+ .instr = PPC_RAW_ADDC(20, 21, 22),
.regs = {
.gpr[21] = ULONG_MAX,
.gpr[22] = 0x1,
@@ -696,7 +653,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = INT_MIN, RB = INT_MIN",
- .instr = TEST_ADDC(20, 21, 22),
+ .instr = PPC_RAW_ADDC(20, 21, 22),
.regs = {
.gpr[21] = INT_MIN,
.gpr[22] = INT_MIN,
@@ -704,7 +661,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = INT_MIN, RB = INT_MAX",
- .instr = TEST_ADDC(20, 21, 22),
+ .instr = PPC_RAW_ADDC(20, 21, 22),
.regs = {
.gpr[21] = INT_MIN,
.gpr[22] = INT_MAX,
@@ -712,7 +669,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = INT_MAX, RB = INT_MAX",
- .instr = TEST_ADDC(20, 21, 22),
+ .instr = PPC_RAW_ADDC(20, 21, 22),
.regs = {
.gpr[21] = INT_MAX,
.gpr[22] = INT_MAX,
@@ -720,7 +677,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = UINT_MAX, RB = UINT_MAX",
- .instr = TEST_ADDC(20, 21, 22),
+ .instr = PPC_RAW_ADDC(20, 21, 22),
.regs = {
.gpr[21] = UINT_MAX,
.gpr[22] = UINT_MAX,
@@ -728,7 +685,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = UINT_MAX, RB = 0x1",
- .instr = TEST_ADDC(20, 21, 22),
+ .instr = PPC_RAW_ADDC(20, 21, 22),
.regs = {
.gpr[21] = UINT_MAX,
.gpr[22] = 0x1,
@@ -736,7 +693,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
- .instr = TEST_ADDC(20, 21, 22),
+ .instr = PPC_RAW_ADDC(20, 21, 22),
.regs = {
.gpr[21] = LONG_MIN | (uint)INT_MIN,
.gpr[22] = LONG_MIN | (uint)INT_MIN,
@@ -750,7 +707,7 @@ static struct compute_test compute_tests[] = {
{
.descr = "RA = LONG_MIN, RB = LONG_MIN",
.flags = IGNORE_CCR,
- .instr = TEST_ADDC_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADDC_DOT(20, 21, 22),
.regs = {
.gpr[21] = LONG_MIN,
.gpr[22] = LONG_MIN,
@@ -758,7 +715,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = LONG_MIN, RB = LONG_MAX",
- .instr = TEST_ADDC_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADDC_DOT(20, 21, 22),
.regs = {
.gpr[21] = LONG_MIN,
.gpr[22] = LONG_MAX,
@@ -767,7 +724,7 @@ static struct compute_test compute_tests[] = {
{
.descr = "RA = LONG_MAX, RB = LONG_MAX",
.flags = IGNORE_CCR,
- .instr = TEST_ADDC_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADDC_DOT(20, 21, 22),
.regs = {
.gpr[21] = LONG_MAX,
.gpr[22] = LONG_MAX,
@@ -775,7 +732,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
- .instr = TEST_ADDC_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADDC_DOT(20, 21, 22),
.regs = {
.gpr[21] = ULONG_MAX,
.gpr[22] = ULONG_MAX,
@@ -783,7 +740,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = ULONG_MAX, RB = 0x1",
- .instr = TEST_ADDC_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADDC_DOT(20, 21, 22),
.regs = {
.gpr[21] = ULONG_MAX,
.gpr[22] = 0x1,
@@ -791,7 +748,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = INT_MIN, RB = INT_MIN",
- .instr = TEST_ADDC_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADDC_DOT(20, 21, 22),
.regs = {
.gpr[21] = INT_MIN,
.gpr[22] = INT_MIN,
@@ -799,7 +756,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = INT_MIN, RB = INT_MAX",
- .instr = TEST_ADDC_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADDC_DOT(20, 21, 22),
.regs = {
.gpr[21] = INT_MIN,
.gpr[22] = INT_MAX,
@@ -807,7 +764,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = INT_MAX, RB = INT_MAX",
- .instr = TEST_ADDC_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADDC_DOT(20, 21, 22),
.regs = {
.gpr[21] = INT_MAX,
.gpr[22] = INT_MAX,
@@ -815,7 +772,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = UINT_MAX, RB = UINT_MAX",
- .instr = TEST_ADDC_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADDC_DOT(20, 21, 22),
.regs = {
.gpr[21] = UINT_MAX,
.gpr[22] = UINT_MAX,
@@ -823,7 +780,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = UINT_MAX, RB = 0x1",
- .instr = TEST_ADDC_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADDC_DOT(20, 21, 22),
.regs = {
.gpr[21] = UINT_MAX,
.gpr[22] = 0x1,
@@ -831,7 +788,7 @@ static struct compute_test compute_tests[] = {
},
{
.descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
- .instr = TEST_ADDC_DOT(20, 21, 22),
+ .instr = PPC_RAW_ADDC_DOT(20, 21, 22),
.regs = {
.gpr[21] = LONG_MIN | (uint)INT_MIN,
.gpr[22] = LONG_MIN | (uint)INT_MIN,
--
2.24.1
^ permalink raw reply related
* [RFC PATCH v2 1/7] powerpc/ppc-opcode: introduce PPC_RAW_* macros for base instruction encoding
From: Balamuruhan S @ 2020-04-24 7:08 UTC (permalink / raw)
To: mpe
Cc: ravi.bangoria, jniethe5, Balamuruhan S, paulus, sandipan,
naveen.n.rao, linuxppc-dev
In-Reply-To: <20200424070853.443969-1-bala24@linux.ibm.com>
Introduce PPC_RAW_* macros to have all the bare encoding of ppc
instructions. Move `VSX_XX*()` and `TMRN()` macros up to reuse it.
Signed-off-by: Balamuruhan S <bala24@linux.ibm.com>
---
arch/powerpc/include/asm/ppc-opcode.h | 183 ++++++++++++++++++++++++--
1 file changed, 175 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index c1df75edde44..c5ec2ea283f1 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -428,6 +428,181 @@
#define __PPC_EH(eh) 0
#endif
+/* Base instruction encoding */
+#define PPC_RAW_CP_ABORT (PPC_INST_CP_ABORT)
+#define PPC_RAW_COPY(a, b) (PPC_INST_COPY | ___PPC_RA(a) | \
+ ___PPC_RB(b))
+#define PPC_RAW_DARN(t, l) (PPC_INST_DARN | ___PPC_RT(t) | \
+ (((l) & 0x3) << 16))
+#define PPC_RAW_DCBAL(a, b) (PPC_INST_DCBAL | __PPC_RA(a) | \
+ __PPC_RB(b))
+#define PPC_RAW_DCBZL(a, b) (PPC_INST_DCBZL | __PPC_RA(a) | \
+ __PPC_RB(b))
+#define PPC_RAW_LQARX(t, a, b, eh) (PPC_INST_LQARX | ___PPC_RT(t) | \
+ ___PPC_RA(a) | \
+ ___PPC_RB(b) | __PPC_EH(eh))
+#define PPC_RAW_LDARX(t, a, b, eh) (PPC_INST_LDARX | ___PPC_RT(t) | \
+ ___PPC_RA(a) | \
+ ___PPC_RB(b) | __PPC_EH(eh))
+#define PPC_RAW_LWARX(t, a, b, eh) (PPC_INST_LWARX | \
+ ___PPC_RT(t) | ___PPC_RA(a) | \
+ ___PPC_RB(b) | __PPC_EH(eh))
+#define PPC_RAW_STQCX(t, a, b) (PPC_INST_STQCX | \
+ ___PPC_RT(t) | ___PPC_RA(a) | \
+ ___PPC_RB(b))
+#define PPC_RAW_MADDHD(t, a, b, c) (PPC_INST_MADDHD | \
+ ___PPC_RT(t) | ___PPC_RA(a) | \
+ ___PPC_RB(b) | ___PPC_RC(c))
+#define PPC_RAW_MADDHDU(t, a, b, c) (PPC_INST_MADDHDU | \
+ ___PPC_RT(t) | ___PPC_RA(a) | \
+ ___PPC_RB(b) | ___PPC_RC(c))
+#define PPC_RAW_MADDLD(t, a, b, c) (PPC_INST_MADDLD | \
+ ___PPC_RT(t) | ___PPC_RA(a) | \
+ ___PPC_RB(b) | ___PPC_RC(c))
+#define PPC_RAW_MSGSND(b) (PPC_INST_MSGSND | ___PPC_RB(b))
+#define PPC_RAW_MSGSYNC (PPC_INST_MSGSYNC)
+#define PPC_RAW_MSGCLR(b) (PPC_INST_MSGCLR | ___PPC_RB(b))
+#define PPC_RAW_MSGSNDP(b) (PPC_INST_MSGSNDP | ___PPC_RB(b))
+#define PPC_RAW_MSGCLRP(b) (PPC_INST_MSGCLRP | ___PPC_RB(b))
+#define PPC_RAW_PASTE(a, b) (PPC_INST_PASTE | ___PPC_RA(a) | \
+ ___PPC_RB(b))
+#define PPC_RAW_POPCNTB(a, s) (PPC_INST_POPCNTB | __PPC_RA(a) | \
+ __PPC_RS(s))
+#define PPC_RAW_POPCNTD(a, s) (PPC_INST_POPCNTD | __PPC_RA(a) | \
+ __PPC_RS(s))
+#define PPC_RAW_POPCNTW(a, s) (PPC_INST_POPCNTW | __PPC_RA(a) | \
+ __PPC_RS(s))
+#define PPC_RAW_RFCI (PPC_INST_RFCI)
+#define PPC_RAW_RFDI (PPC_INST_RFDI)
+#define PPC_RAW_RFMCI (PPC_INST_RFMCI)
+#define PPC_RAW_TLBILX(t, a, b) (PPC_INST_TLBILX | \
+ __PPC_T_TLB(t) | \
+ __PPC_RA0(a) | \
+ __PPC_RB(b))
+#define PPC_RAW_WAIT(w) (PPC_INST_WAIT | __PPC_WC(w))
+#define PPC_RAW_TLBIE(lp, a) (PPC_INST_TLBIE | ___PPC_RB(a) | \
+ ___PPC_RS(lp))
+#define PPC_RAW_TLBIE_5(rb, rs, ric, prs, r) \
+ (PPC_INST_TLBIE | \
+ ___PPC_RB(rb) | \
+ ___PPC_RS(rs) | \
+ ___PPC_RIC(ric) | \
+ ___PPC_PRS(prs) | \
+ ___PPC_R(r))
+#define PPC_RAW_TLBIEL(rb, rs, ric, prs, r) \
+ (PPC_INST_TLBIEL | \
+ ___PPC_RB(rb) | \
+ ___PPC_RS(rs) | \
+ ___PPC_RIC(ric) | \
+ ___PPC_PRS(prs) | \
+ ___PPC_R(r))
+#define PPC_RAW_TLBSRX_DOT(a, b) (PPC_INST_TLBSRX_DOT | \
+ __PPC_RA0(a) | __PPC_RB(b))
+#define PPC_RAW_TLBIVAX(a, b) (PPC_INST_TLBIVAX | \
+ __PPC_RA0(a) | __PPC_RB(b))
+#define PPC_RAW_ERATWE(s, a, w) (PPC_INST_ERATWE | \
+ __PPC_RS(s) | __PPC_RA(a) | \
+ __PPC_WS(w))
+#define PPC_RAW_ERATRE(s, a, w) (PPC_INST_ERATRE | \
+ __PPC_RS(s) | __PPC_RA(a) | \
+ __PPC_WS(w))
+#define PPC_RAW_ERATILX(t, a, b) (PPC_INST_ERATILX | \
+ __PPC_T_TLB(t) | \
+ __PPC_RA0(a) | \
+ __PPC_RB(b))
+#define PPC_RAW_ERATIVAX(s, a, b) (PPC_INST_ERATIVAX | \
+ __PPC_RS(s) | __PPC_RA0(a) | \
+ __PPC_RB(b))
+#define PPC_RAW_ERATSX(t, a, w) (PPC_INST_ERATSX | \
+ __PPC_RS(t) | __PPC_RA0(a) | \
+ __PPC_RB(b))
+#define PPC_RAW_ERATSX_DOT(t, a, w) (PPC_INST_ERATSX_DOT | \
+ __PPC_RS(t) | __PPC_RA0(a) | \
+ __PPC_RB(b))
+#define PPC_RAW_SLBFEE_DOT(t, b) (PPC_INST_SLBFEE | \
+ __PPC_RT(t) | __PPC_RB(b))
+#define __PPC_RAW_SLBFEE_DOT(t, b) (PPC_INST_SLBFEE | \
+ ___PPC_RT(t) | ___PPC_RB(b))
+#define PPC_RAW_ICBT(c, a, b) (PPC_INST_ICBT | \
+ __PPC_CT(c) | __PPC_RA0(a) | \
+ __PPC_RB(b))
+#define PPC_RAW_LBZCIX(t, a, b) (PPC_INST_LBZCIX | \
+ __PPC_RT(t) | __PPC_RA(a) | \
+ __PPC_RB(b))
+#define PPC_RAW_STBCIX(s, a, b) (PPC_INST_STBCIX | \
+ __PPC_RS(s) | __PPC_RA(a) | \
+ __PPC_RB(b))
+/*
+ * Define what the VSX XX1 form instructions will look like, then add
+ * the 128 bit load store instructions based on that.
+ */
+#define VSX_XX1(s, a, b) (__PPC_XS(s) | __PPC_RA(a) | \
+ __PPC_RB(b))
+#define VSX_XX3(t, a, b) (__PPC_XT(t) | __PPC_XA(a) | \
+ __PPC_XB(b))
+#define PPC_RAW_STXVD2X(s, a, b) (PPC_INST_STXVD2X | \
+ VSX_XX1((s), a, b))
+#define PPC_RAW_LXVD2X(s, a, b) (PPC_INST_LXVD2X | \
+ VSX_XX1((s), a, b))
+#define PPC_RAW_MFVRD(a, t) (PPC_INST_MFVSRD | \
+ VSX_XX1((t) + 32, a, R0))
+#define PPC_RAW_MTVRD(t, a) (PPC_INST_MTVSRD | \
+ VSX_XX1((t) + 32, a, R0))
+#define PPC_RAW_VPMSUMW(t, a, b) (PPC_INST_VPMSUMW | \
+ VSX_XX3((t), a, b))
+#define PPC_RAW_VPMSUMD(t, a, b) (PPC_INST_VPMSUMD | \
+ VSX_XX3((t), a, b))
+#define PPC_RAW_XXLOR(t, a, b) (PPC_INST_XXLOR | \
+ VSX_XX3((t), a, b))
+#define PPC_RAW_XXSWAPD(t, a) (PPC_INST_XXSWAPD | \
+ VSX_XX3((t), a, a))
+#define PPC_RAW_XVCPSGNDP(t, a, b) ((PPC_INST_XVCPSGNDP | \
+ VSX_XX3((t), (a), (b))))
+#define PPC_RAW_VPERMXOR(vrt, vra, vrb, vrc) \
+ ((PPC_INST_VPERMXOR | \
+ ___PPC_RT(vrt) | \
+ ___PPC_RA(vra) | \
+ ___PPC_RB(vrb) | \
+ (((vrc) & 0x1f) << 6)))
+#define PPC_RAW_NAP (PPC_INST_NAP)
+#define PPC_RAW_SLEEP (PPC_INST_SLEEP)
+#define PPC_RAW_WINKLE (PPC_INST_WINKLE)
+#define PPC_RAW_STOP (PPC_INST_STOP)
+#define PPC_RAW_CLRBHRB (PPC_INST_CLRBHRB)
+#define PPC_RAW_MFBHRBE(r, n) (PPC_INST_BHRBE | \
+ __PPC_RT(r) | \
+ (((n) & 0x3ff) << 11))
+#define PPC_RAW_TRECHKPT (PPC_INST_TRECHKPT)
+#define PPC_RAW_TRECLAIM(r) (PPC_INST_TRECLAIM \
+ | __PPC_RA(r))
+#define PPC_RAW_TABORT(r) (PPC_INST_TABORT \
+ | __PPC_RA(r))
+#define TMRN(x) ((((x) & 0x1f) << 16) | (((x) & 0x3e0) << 6))
+#define PPC_RAW_MTTMR(tmr, r) (PPC_INST_MTTMR | \
+ TMRN(tmr) | ___PPC_RS(r))
+#define PPC_RAW_MFTMR(tmr, r) (PPC_INST_MFTMR | \
+ TMRN(tmr) | ___PPC_RT(r))
+#define PPC_RAW_ICSWX(s, a, b) (PPC_INST_ICSWX | \
+ ___PPC_RS(s) | \
+ ___PPC_RA(a) | \
+ ___PPC_RB(b))
+#define PPC_RAW_ICSWEPX(s, a, b) (PPC_INST_ICSWEPX | \
+ ___PPC_RS(s) | \
+ ___PPC_RA(a) | \
+ ___PPC_RB(b))
+#define PPC_RAW_SLBIA(IH) (PPC_INST_SLBIA | \
+ (((IH) & 0x7) << 21))
+#define PPC_RAW_VCMPEQUD_RC(vrt, vra, vrb) \
+ (PPC_INST_VCMPEQUD | \
+ ___PPC_RT(vrt) | \
+ ___PPC_RA(vra) | \
+ ___PPC_RB(vrb) | __PPC_RC21)
+#define PPC_RAW_VCMPEQUB_RC(vrt, vra, vrb) \
+ (PPC_INST_VCMPEQUB | \
+ ___PPC_RT(vrt) | \
+ ___PPC_RA(vra) | \
+ ___PPC_RB(vrb) | __PPC_RC21)
+
/* Deal with instructions that older assemblers aren't aware of */
#define PPC_CP_ABORT stringify_in_c(.long PPC_INST_CP_ABORT)
#define PPC_COPY(a, b) stringify_in_c(.long PPC_INST_COPY | \
@@ -528,13 +703,6 @@
__PPC_RT(t) | __PPC_RA(a) | __PPC_RB(b))
#define STBCIX(s,a,b) stringify_in_c(.long PPC_INST_STBCIX | \
__PPC_RS(s) | __PPC_RA(a) | __PPC_RB(b))
-
-/*
- * Define what the VSX XX1 form instructions will look like, then add
- * the 128 bit load store instructions based on that.
- */
-#define VSX_XX1(s, a, b) (__PPC_XS(s) | __PPC_RA(a) | __PPC_RB(b))
-#define VSX_XX3(t, a, b) (__PPC_XT(t) | __PPC_XA(a) | __PPC_XB(b))
#define STXVD2X(s, a, b) stringify_in_c(.long PPC_INST_STXVD2X | \
VSX_XX1((s), a, b))
#define LXVD2X(s, a, b) stringify_in_c(.long PPC_INST_LXVD2X | \
@@ -579,7 +747,6 @@
| __PPC_RA(r))
/* book3e thread control instructions */
-#define TMRN(x) ((((x) & 0x1f) << 16) | (((x) & 0x3e0) << 6))
#define MTTMR(tmr, r) stringify_in_c(.long PPC_INST_MTTMR | \
TMRN(tmr) | ___PPC_RS(r))
#define MFTMR(tmr, r) stringify_in_c(.long PPC_INST_MFTMR | \
--
2.24.1
^ permalink raw reply related
* [RFC PATCH v2 3/7] powerpc/bpf_jit: reuse instruction macros from ppc-opcode.h
From: Balamuruhan S @ 2020-04-24 7:08 UTC (permalink / raw)
To: mpe
Cc: ravi.bangoria, jniethe5, Balamuruhan S, paulus, sandipan,
naveen.n.rao, linuxppc-dev
In-Reply-To: <20200424070853.443969-1-bala24@linux.ibm.com>
remove duplicate macro definitions from bpf_jit.h and reuse the macros from
ppc-opcode.h
Signed-off-by: Balamuruhan S <bala24@linux.ibm.com>
---
arch/powerpc/net/bpf_jit.h | 18 +-----------------
arch/powerpc/net/bpf_jit32.h | 10 +++++-----
arch/powerpc/net/bpf_jit64.h | 4 ++--
arch/powerpc/net/bpf_jit_comp.c | 2 +-
arch/powerpc/net/bpf_jit_comp64.c | 20 ++++++++++----------
5 files changed, 19 insertions(+), 35 deletions(-)
diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index 55d4377ccfae..535d1de4dfee 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -11,6 +11,7 @@
#ifndef __ASSEMBLY__
#include <asm/types.h>
+#include <asm/ppc-opcode.h>
#ifdef PPC64_ELF_ABI_v1
#define FUNCTION_DESCR_SIZE 24
@@ -26,7 +27,6 @@
#define IMM_H(i) ((uintptr_t)(i)>>16)
#define IMM_HA(i) (((uintptr_t)(i)>>16) + \
(((uintptr_t)(i) & 0x8000) >> 15))
-#define IMM_L(i) ((uintptr_t)(i) & 0xffff)
#define PLANT_INSTR(d, idx, instr) \
do { if (d) { (d)[idx] = instr; } idx++; } while (0)
@@ -45,8 +45,6 @@
#define PPC_ADDIS(d, a, i) EMIT(PPC_INST_ADDIS | \
___PPC_RT(d) | ___PPC_RA(a) | IMM_L(i))
#define PPC_LIS(r, i) PPC_ADDIS(r, 0, i)
-#define PPC_STD(r, base, i) EMIT(PPC_INST_STD | ___PPC_RS(r) | \
- ___PPC_RA(base) | ((i) & 0xfffc))
#define PPC_STDX(r, base, b) EMIT(PPC_INST_STDX | ___PPC_RS(r) | \
___PPC_RA(base) | ___PPC_RB(b))
#define PPC_STDU(r, base, i) EMIT(PPC_INST_STDU | ___PPC_RS(r) | \
@@ -62,12 +60,8 @@
#define PPC_LBZ(r, base, i) EMIT(PPC_INST_LBZ | ___PPC_RT(r) | \
___PPC_RA(base) | IMM_L(i))
-#define PPC_LD(r, base, i) EMIT(PPC_INST_LD | ___PPC_RT(r) | \
- ___PPC_RA(base) | ((i) & 0xfffc))
#define PPC_LDX(r, base, b) EMIT(PPC_INST_LDX | ___PPC_RT(r) | \
___PPC_RA(base) | ___PPC_RB(b))
-#define PPC_LWZ(r, base, i) EMIT(PPC_INST_LWZ | ___PPC_RT(r) | \
- ___PPC_RA(base) | IMM_L(i))
#define PPC_LHZ(r, base, i) EMIT(PPC_INST_LHZ | ___PPC_RT(r) | \
___PPC_RA(base) | IMM_L(i))
#define PPC_LHBRX(r, base, b) EMIT(PPC_INST_LHBRX | ___PPC_RT(r) | \
@@ -75,16 +69,8 @@
#define PPC_LDBRX(r, base, b) EMIT(PPC_INST_LDBRX | ___PPC_RT(r) | \
___PPC_RA(base) | ___PPC_RB(b))
-#define PPC_BPF_LDARX(t, a, b, eh) EMIT(PPC_INST_LDARX | ___PPC_RT(t) | \
- ___PPC_RA(a) | ___PPC_RB(b) | \
- __PPC_EH(eh))
-#define PPC_BPF_LWARX(t, a, b, eh) EMIT(PPC_INST_LWARX | ___PPC_RT(t) | \
- ___PPC_RA(a) | ___PPC_RB(b) | \
- __PPC_EH(eh))
#define PPC_BPF_STWCX(s, a, b) EMIT(PPC_INST_STWCX | ___PPC_RS(s) | \
___PPC_RA(a) | ___PPC_RB(b))
-#define PPC_BPF_STDCX(s, a, b) EMIT(PPC_INST_STDCX | ___PPC_RS(s) | \
- ___PPC_RA(a) | ___PPC_RB(b))
#define PPC_CMPWI(a, i) EMIT(PPC_INST_CMPWI | ___PPC_RA(a) | IMM_L(i))
#define PPC_CMPDI(a, i) EMIT(PPC_INST_CMPDI | ___PPC_RA(a) | IMM_L(i))
#define PPC_CMPW(a, b) EMIT(PPC_INST_CMPW | ___PPC_RA(a) | \
@@ -100,8 +86,6 @@
#define PPC_SUB(d, a, b) EMIT(PPC_INST_SUB | ___PPC_RT(d) | \
___PPC_RB(a) | ___PPC_RA(b))
-#define PPC_ADD(d, a, b) EMIT(PPC_INST_ADD | ___PPC_RT(d) | \
- ___PPC_RA(a) | ___PPC_RB(b))
#define PPC_MULD(d, a, b) EMIT(PPC_INST_MULLD | ___PPC_RT(d) | \
___PPC_RA(a) | ___PPC_RB(b))
#define PPC_MULW(d, a, b) EMIT(PPC_INST_MULLW | ___PPC_RT(d) | \
diff --git a/arch/powerpc/net/bpf_jit32.h b/arch/powerpc/net/bpf_jit32.h
index 4ec2a9f14f84..753c244a7cf9 100644
--- a/arch/powerpc/net/bpf_jit32.h
+++ b/arch/powerpc/net/bpf_jit32.h
@@ -76,13 +76,13 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
else { PPC_ADDIS(r, base, IMM_HA(i)); \
PPC_LBZ(r, r, IMM_L(i)); } } while(0)
-#define PPC_LD_OFFS(r, base, i) do { if ((i) < 32768) PPC_LD(r, base, i); \
+#define PPC_LD_OFFS(r, base, i) do { if ((i) < 32768) EMIT(PPC_RAW_LD(r, base, i)); \
else { PPC_ADDIS(r, base, IMM_HA(i)); \
- PPC_LD(r, r, IMM_L(i)); } } while(0)
+ EMIT(PPC_RAW_LD(r, r, IMM_L(i))); } } while(0)
-#define PPC_LWZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LWZ(r, base, i); \
+#define PPC_LWZ_OFFS(r, base, i) do { if ((i) < 32768) EMIT(PPC_RAW_LWZ(r, base, i)); \
else { PPC_ADDIS(r, base, IMM_HA(i)); \
- PPC_LWZ(r, r, IMM_L(i)); } } while(0)
+ EMIT(PPC_RAW_LWZ(r, r, IMM_L(i))); } } while(0)
#define PPC_LHZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LHZ(r, base, i); \
else { PPC_ADDIS(r, base, IMM_HA(i)); \
@@ -118,7 +118,7 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
#define PPC_NTOHS_OFFS(r, base, i) PPC_LHZ_OFFS(r, base, i)
#endif
-#define PPC_BPF_LL(r, base, i) do { PPC_LWZ(r, base, i); } while(0)
+#define PPC_BPF_LL(r, base, i) do { EMIT(PPC_RAW_LWZ(r, base, i)); } while(0)
#define PPC_BPF_STL(r, base, i) do { PPC_STW(r, base, i); } while(0)
#define PPC_BPF_STLU(r, base, i) do { PPC_STWU(r, base, i); } while(0)
diff --git a/arch/powerpc/net/bpf_jit64.h b/arch/powerpc/net/bpf_jit64.h
index cf3a7e337f02..c144a3777158 100644
--- a/arch/powerpc/net/bpf_jit64.h
+++ b/arch/powerpc/net/bpf_jit64.h
@@ -73,14 +73,14 @@ static const int b2p[] = {
PPC_LI(b2p[TMP_REG_2], (i)); \
PPC_LDX(r, base, b2p[TMP_REG_2]); \
} else \
- PPC_LD(r, base, i); \
+ EMIT(PPC_RAW_LD(r, base, i)); \
} while(0)
#define PPC_BPF_STL(r, base, i) do { \
if ((i) % 4) { \
PPC_LI(b2p[TMP_REG_2], (i)); \
PPC_STDX(r, base, b2p[TMP_REG_2]); \
} else \
- PPC_STD(r, base, i); \
+ EMIT(PPC_RAW_STD(r, base, i)); \
} while(0)
#define PPC_BPF_STLU(r, base, i) do { PPC_STDU(r, base, i); } while(0)
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 0acc9d5fb19e..abcf56c00be5 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -134,7 +134,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
/*** ALU ops ***/
case BPF_ALU | BPF_ADD | BPF_X: /* A += X; */
ctx->seen |= SEEN_XREG;
- PPC_ADD(r_A, r_A, r_X);
+ EMIT(PPC_RAW_ADD(r_A, r_A, r_X));
break;
case BPF_ALU | BPF_ADD | BPF_K: /* A += K; */
if (!K)
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
index be3517ef0574..f721fbe6ca4d 100644
--- a/arch/powerpc/net/bpf_jit_comp64.c
+++ b/arch/powerpc/net/bpf_jit_comp64.c
@@ -239,7 +239,7 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
* if (index >= array->map.max_entries)
* goto out;
*/
- PPC_LWZ(b2p[TMP_REG_1], b2p_bpf_array, offsetof(struct bpf_array, map.max_entries));
+ EMIT(PPC_RAW_LWZ(b2p[TMP_REG_1], b2p_bpf_array, offsetof(struct bpf_array, map.max_entries)));
PPC_RLWINM(b2p_index, b2p_index, 0, 0, 31);
PPC_CMPLW(b2p_index, b2p[TMP_REG_1]);
PPC_BCC(COND_GE, out);
@@ -260,7 +260,7 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
/* prog = array->ptrs[index]; */
PPC_MULI(b2p[TMP_REG_1], b2p_index, 8);
- PPC_ADD(b2p[TMP_REG_1], b2p[TMP_REG_1], b2p_bpf_array);
+ EMIT(PPC_RAW_ADD(b2p[TMP_REG_1], b2p[TMP_REG_1], b2p_bpf_array));
PPC_BPF_LL(b2p[TMP_REG_1], b2p[TMP_REG_1], offsetof(struct bpf_array, ptrs));
/*
@@ -340,7 +340,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
*/
case BPF_ALU | BPF_ADD | BPF_X: /* (u32) dst += (u32) src */
case BPF_ALU64 | BPF_ADD | BPF_X: /* dst += src */
- PPC_ADD(dst_reg, dst_reg, src_reg);
+ EMIT(PPC_RAW_ADD(dst_reg, dst_reg, src_reg));
goto bpf_alu32_trunc;
case BPF_ALU | BPF_SUB | BPF_X: /* (u32) dst -= (u32) src */
case BPF_ALU64 | BPF_SUB | BPF_X: /* dst -= src */
@@ -357,7 +357,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
PPC_ADDI(dst_reg, dst_reg, IMM_L(imm));
else {
PPC_LI32(b2p[TMP_REG_1], imm);
- PPC_ADD(dst_reg, dst_reg, b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_ADD(dst_reg, dst_reg, b2p[TMP_REG_1]));
}
}
goto bpf_alu32_trunc;
@@ -689,9 +689,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
PPC_ADDI(b2p[TMP_REG_1], dst_reg, off);
tmp_idx = ctx->idx * 4;
/* load value from memory into TMP_REG_2 */
- PPC_BPF_LWARX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1], 0);
+ EMIT(PPC_RAW_LWARX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1], 0));
/* add value from src_reg into this */
- PPC_ADD(b2p[TMP_REG_2], b2p[TMP_REG_2], src_reg);
+ EMIT(PPC_RAW_ADD(b2p[TMP_REG_2], b2p[TMP_REG_2], src_reg));
/* store result back */
PPC_BPF_STWCX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1]);
/* we're done if this succeeded */
@@ -701,9 +701,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
case BPF_STX | BPF_XADD | BPF_DW:
PPC_ADDI(b2p[TMP_REG_1], dst_reg, off);
tmp_idx = ctx->idx * 4;
- PPC_BPF_LDARX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1], 0);
- PPC_ADD(b2p[TMP_REG_2], b2p[TMP_REG_2], src_reg);
- PPC_BPF_STDCX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_LDARX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1], 0));
+ EMIT(PPC_RAW_ADD(b2p[TMP_REG_2], b2p[TMP_REG_2], src_reg));
+ EMIT(PPC_RAW_STDCX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1]));
PPC_BCC_SHORT(COND_NE, tmp_idx);
break;
@@ -724,7 +724,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
break;
/* dst = *(u32 *)(ul) (src + off) */
case BPF_LDX | BPF_MEM | BPF_W:
- PPC_LWZ(dst_reg, src_reg, off);
+ EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break;
--
2.24.1
^ permalink raw reply related
* [RFC PATCH v2 4/7] powerpc/ppc-opcode: consolidate powerpc instructions from bpf_jit.h
From: Balamuruhan S @ 2020-04-24 7:08 UTC (permalink / raw)
To: mpe
Cc: ravi.bangoria, jniethe5, Balamuruhan S, paulus, sandipan,
naveen.n.rao, linuxppc-dev
In-Reply-To: <20200424070853.443969-1-bala24@linux.ibm.com>
move macro definitions of powerpc instructions from bpf_jit.h to ppc-opcode.h
and adopt the users of the macros accordingly. `PPC_MR()` is defined twice in
bpf_jit.h, remove the duplicate one.
Signed-off-by: Balamuruhan S <bala24@linux.ibm.com>
---
arch/powerpc/include/asm/ppc-opcode.h | 139 +++++++++++++
arch/powerpc/net/bpf_jit.h | 166 ++-------------
arch/powerpc/net/bpf_jit32.h | 24 +--
arch/powerpc/net/bpf_jit64.h | 12 +-
arch/powerpc/net/bpf_jit_comp.c | 132 ++++++------
arch/powerpc/net/bpf_jit_comp64.c | 278 +++++++++++++-------------
6 files changed, 378 insertions(+), 373 deletions(-)
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index 2ae0afc5c2bb..6b9a891884be 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -79,6 +79,16 @@
#define IMM_L(i) ((uintptr_t)(i) & 0xffff)
#define IMM_DS(i) ((uintptr_t)(i) & 0xfffc)
+/*
+ * 16-bit immediate helper macros: HA() is for use with sign-extending instrs
+ * (e.g. LD, ADDI). If the bottom 16 bits is "-ve", add another bit into the
+ * top half to negate the effect (i.e. 0xffff + 1 = 0x(1)0000).
+ */
+#define IMM_H(i) ((uintptr_t)(i)>>16)
+#define IMM_HA(i) (((uintptr_t)(i)>>16) + \
+ (((uintptr_t)(i) & 0x8000) >> 15))
+
+
/* opcode and xopcode for instructions */
#define OP_TRAP 3
#define OP_TRAP_64 2
@@ -637,6 +647,135 @@
#define PPC_RAW_ADDC_DOT(t, a, b) (PPC_INST_ADDC | ___PPC_RT(t) | \
___PPC_RA(a) | ___PPC_RB(b) | \
0x1)
+#define PPC_RAW_NOP() (PPC_INST_NOP)
+#define PPC_RAW_BLR() (PPC_INST_BLR)
+#define PPC_RAW_BLRL() (PPC_INST_BLRL)
+#define PPC_RAW_MTLR(r) (PPC_INST_MTLR | ___PPC_RT(r))
+#define PPC_RAW_BCTR() (PPC_INST_BCTR)
+#define PPC_RAW_MTCTR(r) (PPC_INST_MTCTR | ___PPC_RT(r))
+#define PPC_RAW_ADDI(d, a, i) (PPC_INST_ADDI | ___PPC_RT(d) | \
+ ___PPC_RA(a) | IMM_L(i))
+#define PPC_RAW_LI(r, i) PPC_RAW_ADDI(r, 0, i)
+#define PPC_RAW_ADDIS(d, a, i) (PPC_INST_ADDIS | \
+ ___PPC_RT(d) | ___PPC_RA(a) | \
+ IMM_L(i))
+#define PPC_RAW_LIS(r, i) PPC_RAW_ADDIS(r, 0, i)
+#define PPC_RAW_STDX(r, base, b) (PPC_INST_STDX | ___PPC_RS(r) | \
+ ___PPC_RA(base) | ___PPC_RB(b))
+#define PPC_RAW_STDU(r, base, i) (PPC_INST_STDU | ___PPC_RS(r) | \
+ ___PPC_RA(base) | \
+ ((i) & 0xfffc))
+#define PPC_RAW_STW(r, base, i) (PPC_INST_STW | ___PPC_RS(r) | \
+ ___PPC_RA(base) | IMM_L(i))
+#define PPC_RAW_STWU(r, base, i) (PPC_INST_STWU | ___PPC_RS(r) | \
+ ___PPC_RA(base) | IMM_L(i))
+#define PPC_RAW_STH(r, base, i) (PPC_INST_STH | ___PPC_RS(r) | \
+ ___PPC_RA(base) | IMM_L(i))
+#define PPC_RAW_STB(r, base, i) (PPC_INST_STB | ___PPC_RS(r) | \
+ ___PPC_RA(base) | IMM_L(i))
+#define PPC_RAW_LBZ(r, base, i) (PPC_INST_LBZ | ___PPC_RT(r) | \
+ ___PPC_RA(base) | IMM_L(i))
+#define PPC_RAW_LDX(r, base, b) (PPC_INST_LDX | ___PPC_RT(r) | \
+ ___PPC_RA(base) | ___PPC_RB(b))
+#define PPC_RAW_LHZ(r, base, i) (PPC_INST_LHZ | ___PPC_RT(r) | \
+ ___PPC_RA(base) | IMM_L(i))
+#define PPC_RAW_LHBRX(r, base, b) (PPC_INST_LHBRX | ___PPC_RT(r) | \
+ ___PPC_RA(base) | ___PPC_RB(b))
+#define PPC_RAW_LDBRX(r, base, b) (PPC_INST_LDBRX | ___PPC_RT(r) | \
+ ___PPC_RA(base) | ___PPC_RB(b))
+#define PPC_RAW_STWCX(s, a, b) (PPC_INST_STWCX | ___PPC_RS(s) | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_CMPWI(a, i) (PPC_INST_CMPWI | ___PPC_RA(a) | IMM_L(i))
+#define PPC_RAW_CMPDI(a, i) (PPC_INST_CMPDI | ___PPC_RA(a) | IMM_L(i))
+#define PPC_RAW_CMPW(a, b) (PPC_INST_CMPW | ___PPC_RA(a) | \
+ ___PPC_RB(b))
+#define PPC_RAW_CMPD(a, b) (PPC_INST_CMPD | ___PPC_RA(a) | \
+ ___PPC_RB(b))
+#define PPC_RAW_CMPLWI(a, i) (PPC_INST_CMPLWI | ___PPC_RA(a) | IMM_L(i))
+#define PPC_RAW_CMPLDI(a, i) (PPC_INST_CMPLDI | ___PPC_RA(a) | IMM_L(i))
+#define PPC_RAW_CMPLW(a, b) (PPC_INST_CMPLW | ___PPC_RA(a) | \
+ ___PPC_RB(b))
+#define PPC_RAW_CMPLD(a, b) (PPC_INST_CMPLD | ___PPC_RA(a) | \
+ ___PPC_RB(b))
+#define PPC_RAW_SUB(d, a, b) (PPC_INST_SUB | ___PPC_RT(d) | \
+ ___PPC_RB(a) | ___PPC_RA(b))
+#define PPC_RAW_MULD(d, a, b) (PPC_INST_MULLD | ___PPC_RT(d) | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_MULW(d, a, b) (PPC_INST_MULLW | ___PPC_RT(d) | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_MULHWU(d, a, b) (PPC_INST_MULHWU | ___PPC_RT(d) | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_MULI(d, a, i) (PPC_INST_MULLI | ___PPC_RT(d) | \
+ ___PPC_RA(a) | IMM_L(i))
+#define PPC_RAW_DIVWU(d, a, b) (PPC_INST_DIVWU | ___PPC_RT(d) | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_DIVDU(d, a, b) (PPC_INST_DIVDU | ___PPC_RT(d) | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_RAW_AND(d, a, b) (PPC_INST_AND | ___PPC_RA(d) | \
+ ___PPC_RS(a) | ___PPC_RB(b))
+#define PPC_RAW_ANDI(d, a, i) (PPC_INST_ANDI | ___PPC_RA(d) | \
+ ___PPC_RS(a) | IMM_L(i))
+#define PPC_RAW_AND_DOT(d, a, b) (PPC_INST_ANDDOT | ___PPC_RA(d) | \
+ ___PPC_RS(a) | ___PPC_RB(b))
+#define PPC_RAW_OR(d, a, b) (PPC_INST_OR | ___PPC_RA(d) | \
+ ___PPC_RS(a) | ___PPC_RB(b))
+#define PPC_RAW_MR(d, a) PPC_RAW_OR(d, a, a)
+#define PPC_RAW_ORI(d, a, i) (PPC_INST_ORI | ___PPC_RA(d) | \
+ ___PPC_RS(a) | IMM_L(i))
+#define PPC_RAW_ORIS(d, a, i) (PPC_INST_ORIS | ___PPC_RA(d) | \
+ ___PPC_RS(a) | IMM_L(i))
+#define PPC_RAW_XOR(d, a, b) (PPC_INST_XOR | ___PPC_RA(d) | \
+ ___PPC_RS(a) | ___PPC_RB(b))
+#define PPC_RAW_XORI(d, a, i) (PPC_INST_XORI | ___PPC_RA(d) | \
+ ___PPC_RS(a) | IMM_L(i))
+#define PPC_RAW_XORIS(d, a, i) (PPC_INST_XORIS | ___PPC_RA(d) | \
+ ___PPC_RS(a) | IMM_L(i))
+#define PPC_RAW_EXTSW(d, a) (PPC_INST_EXTSW | ___PPC_RA(d) | \
+ ___PPC_RS(a))
+#define PPC_RAW_SLW(d, a, s) (PPC_INST_SLW | ___PPC_RA(d) | \
+ ___PPC_RS(a) | ___PPC_RB(s))
+#define PPC_RAW_SLD(d, a, s) (PPC_INST_SLD | ___PPC_RA(d) | \
+ ___PPC_RS(a) | ___PPC_RB(s))
+#define PPC_RAW_SRW(d, a, s) (PPC_INST_SRW | ___PPC_RA(d) | \
+ ___PPC_RS(a) | ___PPC_RB(s))
+#define PPC_RAW_SRAW(d, a, s) (PPC_INST_SRAW | ___PPC_RA(d) | \
+ ___PPC_RS(a) | ___PPC_RB(s))
+#define PPC_RAW_SRAWI(d, a, i) (PPC_INST_SRAWI | ___PPC_RA(d) | \
+ ___PPC_RS(a) | __PPC_SH(i))
+#define PPC_RAW_SRD(d, a, s) (PPC_INST_SRD | ___PPC_RA(d) | \
+ ___PPC_RS(a) | ___PPC_RB(s))
+#define PPC_RAW_SRAD(d, a, s) (PPC_INST_SRAD | ___PPC_RA(d) | \
+ ___PPC_RS(a) | ___PPC_RB(s))
+#define PPC_RAW_SRADI(d, a, i) (PPC_INST_SRADI | ___PPC_RA(d) | \
+ ___PPC_RS(a) | __PPC_SH64(i))
+#define PPC_RAW_RLWINM(d, a, i, mb, me) (PPC_INST_RLWINM | ___PPC_RA(d) | \
+ ___PPC_RS(a) | __PPC_SH(i) | \
+ __PPC_MB(mb) | __PPC_ME(me))
+#define PPC_RAW_RLWINM_DOT(d, a, i, mb, me) \
+ (PPC_INST_RLWINM_DOT | ___PPC_RA(d) | \
+ ___PPC_RS(a) | __PPC_SH(i) | \
+ __PPC_MB(mb) | __PPC_ME(me))
+#define PPC_RAW_RLWIMI(d, a, i, mb, me) (PPC_INST_RLWIMI | ___PPC_RA(d) | \
+ ___PPC_RS(a) | __PPC_SH(i) | \
+ __PPC_MB(mb) | __PPC_ME(me))
+#define PPC_RAW_RLDICL(d, a, i, mb) (PPC_INST_RLDICL | ___PPC_RA(d) | \
+ ___PPC_RS(a) | __PPC_SH64(i) | \
+ __PPC_MB64(mb))
+#define PPC_RAW_RLDICR(d, a, i, me) (PPC_INST_RLDICR | ___PPC_RA(d) | \
+ ___PPC_RS(a) | __PPC_SH64(i) | \
+ __PPC_ME64(me))
+
+/* slwi = rlwinm Rx, Ry, n, 0, 31-n */
+#define PPC_RAW_SLWI(d, a, i) PPC_RAW_RLWINM(d, a, i, 0, 31-(i))
+/* srwi = rlwinm Rx, Ry, 32-n, n, 31 */
+#define PPC_RAW_SRWI(d, a, i) PPC_RAW_RLWINM(d, a, 32-(i), i, 31)
+/* sldi = rldicr Rx, Ry, n, 63-n */
+#define PPC_RAW_SLDI(d, a, i) PPC_RAW_RLDICR(d, a, i, 63-(i))
+/* sldi = rldicl Rx, Ry, 64-n, n */
+#define PPC_RAW_SRDI(d, a, i) PPC_RAW_RLDICL(d, a, 64-(i), i)
+
+#define PPC_RAW_NEG(d, a) (PPC_INST_NEG | ___PPC_RT(d) | \
+ ___PPC_RA(a))
/* Deal with instructions that older assemblers aren't aware of */
#define PPC_CP_ABORT stringify_in_c(.long PPC_INST_CP_ABORT)
diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index 535d1de4dfee..d0a67a1bbaf1 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -19,150 +19,10 @@
#define FUNCTION_DESCR_SIZE 0
#endif
-/*
- * 16-bit immediate helper macros: HA() is for use with sign-extending instrs
- * (e.g. LD, ADDI). If the bottom 16 bits is "-ve", add another bit into the
- * top half to negate the effect (i.e. 0xffff + 1 = 0x(1)0000).
- */
-#define IMM_H(i) ((uintptr_t)(i)>>16)
-#define IMM_HA(i) (((uintptr_t)(i)>>16) + \
- (((uintptr_t)(i) & 0x8000) >> 15))
-
#define PLANT_INSTR(d, idx, instr) \
do { if (d) { (d)[idx] = instr; } idx++; } while (0)
#define EMIT(instr) PLANT_INSTR(image, ctx->idx, instr)
-#define PPC_NOP() EMIT(PPC_INST_NOP)
-#define PPC_BLR() EMIT(PPC_INST_BLR)
-#define PPC_BLRL() EMIT(PPC_INST_BLRL)
-#define PPC_MTLR(r) EMIT(PPC_INST_MTLR | ___PPC_RT(r))
-#define PPC_BCTR() EMIT(PPC_INST_BCTR)
-#define PPC_MTCTR(r) EMIT(PPC_INST_MTCTR | ___PPC_RT(r))
-#define PPC_ADDI(d, a, i) EMIT(PPC_INST_ADDI | ___PPC_RT(d) | \
- ___PPC_RA(a) | IMM_L(i))
-#define PPC_MR(d, a) PPC_OR(d, a, a)
-#define PPC_LI(r, i) PPC_ADDI(r, 0, i)
-#define PPC_ADDIS(d, a, i) EMIT(PPC_INST_ADDIS | \
- ___PPC_RT(d) | ___PPC_RA(a) | IMM_L(i))
-#define PPC_LIS(r, i) PPC_ADDIS(r, 0, i)
-#define PPC_STDX(r, base, b) EMIT(PPC_INST_STDX | ___PPC_RS(r) | \
- ___PPC_RA(base) | ___PPC_RB(b))
-#define PPC_STDU(r, base, i) EMIT(PPC_INST_STDU | ___PPC_RS(r) | \
- ___PPC_RA(base) | ((i) & 0xfffc))
-#define PPC_STW(r, base, i) EMIT(PPC_INST_STW | ___PPC_RS(r) | \
- ___PPC_RA(base) | IMM_L(i))
-#define PPC_STWU(r, base, i) EMIT(PPC_INST_STWU | ___PPC_RS(r) | \
- ___PPC_RA(base) | IMM_L(i))
-#define PPC_STH(r, base, i) EMIT(PPC_INST_STH | ___PPC_RS(r) | \
- ___PPC_RA(base) | IMM_L(i))
-#define PPC_STB(r, base, i) EMIT(PPC_INST_STB | ___PPC_RS(r) | \
- ___PPC_RA(base) | IMM_L(i))
-
-#define PPC_LBZ(r, base, i) EMIT(PPC_INST_LBZ | ___PPC_RT(r) | \
- ___PPC_RA(base) | IMM_L(i))
-#define PPC_LDX(r, base, b) EMIT(PPC_INST_LDX | ___PPC_RT(r) | \
- ___PPC_RA(base) | ___PPC_RB(b))
-#define PPC_LHZ(r, base, i) EMIT(PPC_INST_LHZ | ___PPC_RT(r) | \
- ___PPC_RA(base) | IMM_L(i))
-#define PPC_LHBRX(r, base, b) EMIT(PPC_INST_LHBRX | ___PPC_RT(r) | \
- ___PPC_RA(base) | ___PPC_RB(b))
-#define PPC_LDBRX(r, base, b) EMIT(PPC_INST_LDBRX | ___PPC_RT(r) | \
- ___PPC_RA(base) | ___PPC_RB(b))
-
-#define PPC_BPF_STWCX(s, a, b) EMIT(PPC_INST_STWCX | ___PPC_RS(s) | \
- ___PPC_RA(a) | ___PPC_RB(b))
-#define PPC_CMPWI(a, i) EMIT(PPC_INST_CMPWI | ___PPC_RA(a) | IMM_L(i))
-#define PPC_CMPDI(a, i) EMIT(PPC_INST_CMPDI | ___PPC_RA(a) | IMM_L(i))
-#define PPC_CMPW(a, b) EMIT(PPC_INST_CMPW | ___PPC_RA(a) | \
- ___PPC_RB(b))
-#define PPC_CMPD(a, b) EMIT(PPC_INST_CMPD | ___PPC_RA(a) | \
- ___PPC_RB(b))
-#define PPC_CMPLWI(a, i) EMIT(PPC_INST_CMPLWI | ___PPC_RA(a) | IMM_L(i))
-#define PPC_CMPLDI(a, i) EMIT(PPC_INST_CMPLDI | ___PPC_RA(a) | IMM_L(i))
-#define PPC_CMPLW(a, b) EMIT(PPC_INST_CMPLW | ___PPC_RA(a) | \
- ___PPC_RB(b))
-#define PPC_CMPLD(a, b) EMIT(PPC_INST_CMPLD | ___PPC_RA(a) | \
- ___PPC_RB(b))
-
-#define PPC_SUB(d, a, b) EMIT(PPC_INST_SUB | ___PPC_RT(d) | \
- ___PPC_RB(a) | ___PPC_RA(b))
-#define PPC_MULD(d, a, b) EMIT(PPC_INST_MULLD | ___PPC_RT(d) | \
- ___PPC_RA(a) | ___PPC_RB(b))
-#define PPC_MULW(d, a, b) EMIT(PPC_INST_MULLW | ___PPC_RT(d) | \
- ___PPC_RA(a) | ___PPC_RB(b))
-#define PPC_MULHWU(d, a, b) EMIT(PPC_INST_MULHWU | ___PPC_RT(d) | \
- ___PPC_RA(a) | ___PPC_RB(b))
-#define PPC_MULI(d, a, i) EMIT(PPC_INST_MULLI | ___PPC_RT(d) | \
- ___PPC_RA(a) | IMM_L(i))
-#define PPC_DIVWU(d, a, b) EMIT(PPC_INST_DIVWU | ___PPC_RT(d) | \
- ___PPC_RA(a) | ___PPC_RB(b))
-#define PPC_DIVDU(d, a, b) EMIT(PPC_INST_DIVDU | ___PPC_RT(d) | \
- ___PPC_RA(a) | ___PPC_RB(b))
-#define PPC_AND(d, a, b) EMIT(PPC_INST_AND | ___PPC_RA(d) | \
- ___PPC_RS(a) | ___PPC_RB(b))
-#define PPC_ANDI(d, a, i) EMIT(PPC_INST_ANDI | ___PPC_RA(d) | \
- ___PPC_RS(a) | IMM_L(i))
-#define PPC_AND_DOT(d, a, b) EMIT(PPC_INST_ANDDOT | ___PPC_RA(d) | \
- ___PPC_RS(a) | ___PPC_RB(b))
-#define PPC_OR(d, a, b) EMIT(PPC_INST_OR | ___PPC_RA(d) | \
- ___PPC_RS(a) | ___PPC_RB(b))
-#define PPC_MR(d, a) PPC_OR(d, a, a)
-#define PPC_ORI(d, a, i) EMIT(PPC_INST_ORI | ___PPC_RA(d) | \
- ___PPC_RS(a) | IMM_L(i))
-#define PPC_ORIS(d, a, i) EMIT(PPC_INST_ORIS | ___PPC_RA(d) | \
- ___PPC_RS(a) | IMM_L(i))
-#define PPC_XOR(d, a, b) EMIT(PPC_INST_XOR | ___PPC_RA(d) | \
- ___PPC_RS(a) | ___PPC_RB(b))
-#define PPC_XORI(d, a, i) EMIT(PPC_INST_XORI | ___PPC_RA(d) | \
- ___PPC_RS(a) | IMM_L(i))
-#define PPC_XORIS(d, a, i) EMIT(PPC_INST_XORIS | ___PPC_RA(d) | \
- ___PPC_RS(a) | IMM_L(i))
-#define PPC_EXTSW(d, a) EMIT(PPC_INST_EXTSW | ___PPC_RA(d) | \
- ___PPC_RS(a))
-#define PPC_SLW(d, a, s) EMIT(PPC_INST_SLW | ___PPC_RA(d) | \
- ___PPC_RS(a) | ___PPC_RB(s))
-#define PPC_SLD(d, a, s) EMIT(PPC_INST_SLD | ___PPC_RA(d) | \
- ___PPC_RS(a) | ___PPC_RB(s))
-#define PPC_SRW(d, a, s) EMIT(PPC_INST_SRW | ___PPC_RA(d) | \
- ___PPC_RS(a) | ___PPC_RB(s))
-#define PPC_SRAW(d, a, s) EMIT(PPC_INST_SRAW | ___PPC_RA(d) | \
- ___PPC_RS(a) | ___PPC_RB(s))
-#define PPC_SRAWI(d, a, i) EMIT(PPC_INST_SRAWI | ___PPC_RA(d) | \
- ___PPC_RS(a) | __PPC_SH(i))
-#define PPC_SRD(d, a, s) EMIT(PPC_INST_SRD | ___PPC_RA(d) | \
- ___PPC_RS(a) | ___PPC_RB(s))
-#define PPC_SRAD(d, a, s) EMIT(PPC_INST_SRAD | ___PPC_RA(d) | \
- ___PPC_RS(a) | ___PPC_RB(s))
-#define PPC_SRADI(d, a, i) EMIT(PPC_INST_SRADI | ___PPC_RA(d) | \
- ___PPC_RS(a) | __PPC_SH64(i))
-#define PPC_RLWINM(d, a, i, mb, me) EMIT(PPC_INST_RLWINM | ___PPC_RA(d) | \
- ___PPC_RS(a) | __PPC_SH(i) | \
- __PPC_MB(mb) | __PPC_ME(me))
-#define PPC_RLWINM_DOT(d, a, i, mb, me) EMIT(PPC_INST_RLWINM_DOT | \
- ___PPC_RA(d) | ___PPC_RS(a) | \
- __PPC_SH(i) | __PPC_MB(mb) | \
- __PPC_ME(me))
-#define PPC_RLWIMI(d, a, i, mb, me) EMIT(PPC_INST_RLWIMI | ___PPC_RA(d) | \
- ___PPC_RS(a) | __PPC_SH(i) | \
- __PPC_MB(mb) | __PPC_ME(me))
-#define PPC_RLDICL(d, a, i, mb) EMIT(PPC_INST_RLDICL | ___PPC_RA(d) | \
- ___PPC_RS(a) | __PPC_SH64(i) | \
- __PPC_MB64(mb))
-#define PPC_RLDICR(d, a, i, me) EMIT(PPC_INST_RLDICR | ___PPC_RA(d) | \
- ___PPC_RS(a) | __PPC_SH64(i) | \
- __PPC_ME64(me))
-
-/* slwi = rlwinm Rx, Ry, n, 0, 31-n */
-#define PPC_SLWI(d, a, i) PPC_RLWINM(d, a, i, 0, 31-(i))
-/* srwi = rlwinm Rx, Ry, 32-n, n, 31 */
-#define PPC_SRWI(d, a, i) PPC_RLWINM(d, a, 32-(i), i, 31)
-/* sldi = rldicr Rx, Ry, n, 63-n */
-#define PPC_SLDI(d, a, i) PPC_RLDICR(d, a, i, 63-(i))
-/* sldi = rldicl Rx, Ry, 64-n, n */
-#define PPC_SRDI(d, a, i) PPC_RLDICL(d, a, 64-(i), i)
-
-#define PPC_NEG(d, a) EMIT(PPC_INST_NEG | ___PPC_RT(d) | ___PPC_RA(a))
-
/* Long jump; (unconditional 'branch') */
#define PPC_JMP(dest) EMIT(PPC_INST_BRANCH | \
(((dest) - (ctx->idx * 4)) & 0x03fffffc))
@@ -175,11 +35,11 @@
#define PPC_LI32(d, i) do { \
if ((int)(uintptr_t)(i) >= -32768 && \
(int)(uintptr_t)(i) < 32768) \
- PPC_LI(d, i); \
+ EMIT(PPC_RAW_LI(d, i)); \
else { \
- PPC_LIS(d, IMM_H(i)); \
+ EMIT(PPC_RAW_LIS(d, IMM_H(i))); \
if (IMM_L(i)) \
- PPC_ORI(d, d, IMM_L(i)); \
+ EMIT(PPC_RAW_ORI(d, d, IMM_L(i))); \
} } while(0)
#define PPC_LI64(d, i) do { \
@@ -188,19 +48,21 @@
PPC_LI32(d, i); \
else { \
if (!((uintptr_t)(i) & 0xffff800000000000ULL)) \
- PPC_LI(d, ((uintptr_t)(i) >> 32) & 0xffff); \
+ EMIT(PPC_RAW_LI(d, ((uintptr_t)(i) >> 32) & \
+ 0xffff)); \
else { \
- PPC_LIS(d, ((uintptr_t)(i) >> 48)); \
+ EMIT(PPC_RAW_LIS(d, ((uintptr_t)(i) >> 48))); \
if ((uintptr_t)(i) & 0x0000ffff00000000ULL) \
- PPC_ORI(d, d, \
- ((uintptr_t)(i) >> 32) & 0xffff); \
+ EMIT(PPC_RAW_ORI(d, d, \
+ ((uintptr_t)(i) >> 32) & 0xffff)); \
} \
- PPC_SLDI(d, d, 32); \
+ EMIT(PPC_RAW_SLDI(d, d, 32)); \
if ((uintptr_t)(i) & 0x00000000ffff0000ULL) \
- PPC_ORIS(d, d, \
- ((uintptr_t)(i) >> 16) & 0xffff); \
+ EMIT(PPC_RAW_ORIS(d, d, \
+ ((uintptr_t)(i) >> 16) & 0xffff)); \
if ((uintptr_t)(i) & 0x000000000000ffffULL) \
- PPC_ORI(d, d, (uintptr_t)(i) & 0xffff); \
+ EMIT(PPC_RAW_ORI(d, d, (uintptr_t)(i) & \
+ 0xffff)); \
} } while (0)
#ifdef CONFIG_PPC64
@@ -224,7 +86,7 @@ static inline bool is_nearbranch(int offset)
#define PPC_BCC(cond, dest) do { \
if (is_nearbranch((dest) - (ctx->idx * 4))) { \
PPC_BCC_SHORT(cond, dest); \
- PPC_NOP(); \
+ EMIT(PPC_RAW_NOP()); \
} else { \
/* Flip the 'T or F' bit to invert comparison */ \
PPC_BCC_SHORT(cond ^ COND_CMP_TRUE, (ctx->idx+2)*4); \
diff --git a/arch/powerpc/net/bpf_jit32.h b/arch/powerpc/net/bpf_jit32.h
index 753c244a7cf9..448dfd4d98e1 100644
--- a/arch/powerpc/net/bpf_jit32.h
+++ b/arch/powerpc/net/bpf_jit32.h
@@ -72,21 +72,21 @@ DECLARE_LOAD_FUNC(sk_load_half);
DECLARE_LOAD_FUNC(sk_load_byte);
DECLARE_LOAD_FUNC(sk_load_byte_msh);
-#define PPC_LBZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LBZ(r, base, i); \
- else { PPC_ADDIS(r, base, IMM_HA(i)); \
- PPC_LBZ(r, r, IMM_L(i)); } } while(0)
+#define PPC_LBZ_OFFS(r, base, i) do { if ((i) < 32768) EMIT(PPC_RAW_LBZ(r, base, i)); \
+ else { EMIT(PPC_RAW_ADDIS(r, base, IMM_HA(i))); \
+ EMIT(PPC_RAW_LBZ(r, r, IMM_L(i))); } } while(0)
#define PPC_LD_OFFS(r, base, i) do { if ((i) < 32768) EMIT(PPC_RAW_LD(r, base, i)); \
- else { PPC_ADDIS(r, base, IMM_HA(i)); \
+ else { EMIT(PPC_RAW_ADDIS(r, base, IMM_HA(i))); \
EMIT(PPC_RAW_LD(r, r, IMM_L(i))); } } while(0)
#define PPC_LWZ_OFFS(r, base, i) do { if ((i) < 32768) EMIT(PPC_RAW_LWZ(r, base, i)); \
- else { PPC_ADDIS(r, base, IMM_HA(i)); \
+ else { EMIT(PPC_RAW_ADDIS(r, base, IMM_HA(i))); \
EMIT(PPC_RAW_LWZ(r, r, IMM_L(i))); } } while(0)
-#define PPC_LHZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LHZ(r, base, i); \
- else { PPC_ADDIS(r, base, IMM_HA(i)); \
- PPC_LHZ(r, r, IMM_L(i)); } } while(0)
+#define PPC_LHZ_OFFS(r, base, i) do { if ((i) < 32768) EMIT(PPC_RAW_LHZ(r, base, i)); \
+ else { EMIT(PPC_RAW_ADDIS(r, base, IMM_HA(i))); \
+ EMIT(PPC_RAW_LHZ(r, r, IMM_L(i))); } } while(0)
#ifdef CONFIG_PPC64
#define PPC_LL_OFFS(r, base, i) do { PPC_LD_OFFS(r, base, i); } while(0)
@@ -107,11 +107,11 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
} while(0)
#endif
#else
-#define PPC_BPF_LOAD_CPU(r) do { PPC_LI(r, 0); } while(0)
+#define PPC_BPF_LOAD_CPU(r) do { EMIT(PPC_RAW_LI(r, 0)); } while(0)
#endif
#define PPC_LHBRX_OFFS(r, base, i) \
- do { PPC_LI32(r, i); PPC_LHBRX(r, r, base); } while(0)
+ do { PPC_LI32(r, i); EMIT(PPC_RAW_LHBRX(r, r, base)); } while(0)
#ifdef __LITTLE_ENDIAN__
#define PPC_NTOHS_OFFS(r, base, i) PPC_LHBRX_OFFS(r, base, i)
#else
@@ -119,8 +119,8 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
#endif
#define PPC_BPF_LL(r, base, i) do { EMIT(PPC_RAW_LWZ(r, base, i)); } while(0)
-#define PPC_BPF_STL(r, base, i) do { PPC_STW(r, base, i); } while(0)
-#define PPC_BPF_STLU(r, base, i) do { PPC_STWU(r, base, i); } while(0)
+#define PPC_BPF_STL(r, base, i) do { EMIT(PPC_RAW_STW(r, base, i)); } while(0)
+#define PPC_BPF_STLU(r, base, i) do { EMIT(PPC_RAW_STWU(r, base, i)); } while(0)
#define SEEN_DATAREF 0x10000 /* might call external helpers */
#define SEEN_XREG 0x20000 /* X reg is used */
diff --git a/arch/powerpc/net/bpf_jit64.h b/arch/powerpc/net/bpf_jit64.h
index c144a3777158..2e33c6673ff9 100644
--- a/arch/powerpc/net/bpf_jit64.h
+++ b/arch/powerpc/net/bpf_jit64.h
@@ -70,19 +70,21 @@ static const int b2p[] = {
*/
#define PPC_BPF_LL(r, base, i) do { \
if ((i) % 4) { \
- PPC_LI(b2p[TMP_REG_2], (i)); \
- PPC_LDX(r, base, b2p[TMP_REG_2]); \
+ EMIT(PPC_RAW_LI(b2p[TMP_REG_2], (i)));\
+ EMIT(PPC_RAW_LDX(r, base, \
+ b2p[TMP_REG_2])); \
} else \
EMIT(PPC_RAW_LD(r, base, i)); \
} while(0)
#define PPC_BPF_STL(r, base, i) do { \
if ((i) % 4) { \
- PPC_LI(b2p[TMP_REG_2], (i)); \
- PPC_STDX(r, base, b2p[TMP_REG_2]); \
+ EMIT(PPC_RAW_LI(b2p[TMP_REG_2], (i)));\
+ EMIT(PPC_RAW_STDX(r, base, \
+ b2p[TMP_REG_2])); \
} else \
EMIT(PPC_RAW_STD(r, base, i)); \
} while(0)
-#define PPC_BPF_STLU(r, base, i) do { PPC_STDU(r, base, i); } while(0)
+#define PPC_BPF_STLU(r, base, i) do { EMIT(PPC_RAW_STDU(r, base, i)); } while(0)
#define SEEN_FUNC 0x1000 /* might call external helpers */
#define SEEN_STACK 0x2000 /* uses BPF stack */
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index abcf56c00be5..16d09b36fe06 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -61,7 +61,7 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image,
PPC_LWZ_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff,
data_len));
PPC_LWZ_OFFS(r_HL, r_skb, offsetof(struct sk_buff, len));
- PPC_SUB(r_HL, r_HL, r_scratch1);
+ EMIT(PPC_RAW_SUB(r_HL, r_HL, r_scratch1));
PPC_LL_OFFS(r_D, r_skb, offsetof(struct sk_buff, data));
}
@@ -70,12 +70,12 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image,
* TODO: Could also detect whether first instr. sets X and
* avoid this (as below, with A).
*/
- PPC_LI(r_X, 0);
+ EMIT(PPC_RAW_LI(r_X, 0));
}
/* make sure we dont leak kernel information to user */
if (bpf_needs_clear_a(&filter[0]))
- PPC_LI(r_A, 0);
+ EMIT(PPC_RAW_LI(r_A, 0));
}
static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
@@ -83,10 +83,10 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
int i;
if (ctx->seen & (SEEN_MEM | SEEN_DATAREF)) {
- PPC_ADDI(1, 1, BPF_PPC_STACKFRAME);
+ EMIT(PPC_RAW_ADDI(1, 1, BPF_PPC_STACKFRAME));
if (ctx->seen & SEEN_DATAREF) {
PPC_BPF_LL(0, 1, PPC_LR_STKOFF);
- PPC_MTLR(0);
+ EMIT(PPC_RAW_MTLR(0));
PPC_BPF_LL(r_D, 1, -(REG_SZ*(32-r_D)));
PPC_BPF_LL(r_HL, 1, -(REG_SZ*(32-r_HL)));
}
@@ -100,7 +100,7 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
}
/* The RETs have left a return value in R3. */
- PPC_BLR();
+ EMIT(PPC_RAW_BLR());
}
#define CHOOSE_LOAD_FUNC(K, func) \
@@ -139,119 +139,119 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
case BPF_ALU | BPF_ADD | BPF_K: /* A += K; */
if (!K)
break;
- PPC_ADDI(r_A, r_A, IMM_L(K));
+ EMIT(PPC_RAW_ADDI(r_A, r_A, IMM_L(K)));
if (K >= 32768)
- PPC_ADDIS(r_A, r_A, IMM_HA(K));
+ EMIT(PPC_RAW_ADDIS(r_A, r_A, IMM_HA(K)));
break;
case BPF_ALU | BPF_SUB | BPF_X: /* A -= X; */
ctx->seen |= SEEN_XREG;
- PPC_SUB(r_A, r_A, r_X);
+ EMIT(PPC_RAW_SUB(r_A, r_A, r_X));
break;
case BPF_ALU | BPF_SUB | BPF_K: /* A -= K */
if (!K)
break;
- PPC_ADDI(r_A, r_A, IMM_L(-K));
+ EMIT(PPC_RAW_ADDI(r_A, r_A, IMM_L(-K)));
if (K >= 32768)
- PPC_ADDIS(r_A, r_A, IMM_HA(-K));
+ EMIT(PPC_RAW_ADDIS(r_A, r_A, IMM_HA(-K)));
break;
case BPF_ALU | BPF_MUL | BPF_X: /* A *= X; */
ctx->seen |= SEEN_XREG;
- PPC_MULW(r_A, r_A, r_X);
+ EMIT(PPC_RAW_MULW(r_A, r_A, r_X));
break;
case BPF_ALU | BPF_MUL | BPF_K: /* A *= K */
if (K < 32768)
- PPC_MULI(r_A, r_A, K);
+ EMIT(PPC_RAW_MULI(r_A, r_A, K));
else {
PPC_LI32(r_scratch1, K);
- PPC_MULW(r_A, r_A, r_scratch1);
+ EMIT(PPC_RAW_MULW(r_A, r_A, r_scratch1));
}
break;
case BPF_ALU | BPF_MOD | BPF_X: /* A %= X; */
case BPF_ALU | BPF_DIV | BPF_X: /* A /= X; */
ctx->seen |= SEEN_XREG;
- PPC_CMPWI(r_X, 0);
+ EMIT(PPC_RAW_CMPWI(r_X, 0));
if (ctx->pc_ret0 != -1) {
PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
} else {
PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12);
- PPC_LI(r_ret, 0);
+ EMIT(PPC_RAW_LI(r_ret, 0));
PPC_JMP(exit_addr);
}
if (code == (BPF_ALU | BPF_MOD | BPF_X)) {
- PPC_DIVWU(r_scratch1, r_A, r_X);
- PPC_MULW(r_scratch1, r_X, r_scratch1);
- PPC_SUB(r_A, r_A, r_scratch1);
+ EMIT(PPC_RAW_DIVWU(r_scratch1, r_A, r_X));
+ EMIT(PPC_RAW_MULW(r_scratch1, r_X, r_scratch1));
+ EMIT(PPC_RAW_SUB(r_A, r_A, r_scratch1));
} else {
- PPC_DIVWU(r_A, r_A, r_X);
+ EMIT(PPC_RAW_DIVWU(r_A, r_A, r_X));
}
break;
case BPF_ALU | BPF_MOD | BPF_K: /* A %= K; */
PPC_LI32(r_scratch2, K);
- PPC_DIVWU(r_scratch1, r_A, r_scratch2);
- PPC_MULW(r_scratch1, r_scratch2, r_scratch1);
- PPC_SUB(r_A, r_A, r_scratch1);
+ EMIT(PPC_RAW_DIVWU(r_scratch1, r_A, r_scratch2));
+ EMIT(PPC_RAW_MULW(r_scratch1, r_scratch2, r_scratch1));
+ EMIT(PPC_RAW_SUB(r_A, r_A, r_scratch1));
break;
case BPF_ALU | BPF_DIV | BPF_K: /* A /= K */
if (K == 1)
break;
PPC_LI32(r_scratch1, K);
- PPC_DIVWU(r_A, r_A, r_scratch1);
+ EMIT(PPC_RAW_DIVWU(r_A, r_A, r_scratch1));
break;
case BPF_ALU | BPF_AND | BPF_X:
ctx->seen |= SEEN_XREG;
- PPC_AND(r_A, r_A, r_X);
+ EMIT(PPC_RAW_AND(r_A, r_A, r_X));
break;
case BPF_ALU | BPF_AND | BPF_K:
if (!IMM_H(K))
- PPC_ANDI(r_A, r_A, K);
+ EMIT(PPC_RAW_ANDI(r_A, r_A, K));
else {
PPC_LI32(r_scratch1, K);
- PPC_AND(r_A, r_A, r_scratch1);
+ EMIT(PPC_RAW_AND(r_A, r_A, r_scratch1));
}
break;
case BPF_ALU | BPF_OR | BPF_X:
ctx->seen |= SEEN_XREG;
- PPC_OR(r_A, r_A, r_X);
+ EMIT(PPC_RAW_OR(r_A, r_A, r_X));
break;
case BPF_ALU | BPF_OR | BPF_K:
if (IMM_L(K))
- PPC_ORI(r_A, r_A, IMM_L(K));
+ EMIT(PPC_RAW_ORI(r_A, r_A, IMM_L(K)));
if (K >= 65536)
- PPC_ORIS(r_A, r_A, IMM_H(K));
+ EMIT(PPC_RAW_ORIS(r_A, r_A, IMM_H(K)));
break;
case BPF_ANC | SKF_AD_ALU_XOR_X:
case BPF_ALU | BPF_XOR | BPF_X: /* A ^= X */
ctx->seen |= SEEN_XREG;
- PPC_XOR(r_A, r_A, r_X);
+ EMIT(PPC_RAW_XOR(r_A, r_A, r_X));
break;
case BPF_ALU | BPF_XOR | BPF_K: /* A ^= K */
if (IMM_L(K))
- PPC_XORI(r_A, r_A, IMM_L(K));
+ EMIT(PPC_RAW_XORI(r_A, r_A, IMM_L(K)));
if (K >= 65536)
- PPC_XORIS(r_A, r_A, IMM_H(K));
+ EMIT(PPC_RAW_XORIS(r_A, r_A, IMM_H(K)));
break;
case BPF_ALU | BPF_LSH | BPF_X: /* A <<= X; */
ctx->seen |= SEEN_XREG;
- PPC_SLW(r_A, r_A, r_X);
+ EMIT(PPC_RAW_SLW(r_A, r_A, r_X));
break;
case BPF_ALU | BPF_LSH | BPF_K:
if (K == 0)
break;
else
- PPC_SLWI(r_A, r_A, K);
+ EMIT(PPC_RAW_SLWI(r_A, r_A, K));
break;
case BPF_ALU | BPF_RSH | BPF_X: /* A >>= X; */
ctx->seen |= SEEN_XREG;
- PPC_SRW(r_A, r_A, r_X);
+ EMIT(PPC_RAW_SRW(r_A, r_A, r_X));
break;
case BPF_ALU | BPF_RSH | BPF_K: /* A >>= K; */
if (K == 0)
break;
else
- PPC_SRWI(r_A, r_A, K);
+ EMIT(PPC_RAW_SRWI(r_A, r_A, K));
break;
case BPF_ALU | BPF_NEG:
- PPC_NEG(r_A, r_A);
+ EMIT(PPC_RAW_NEG(r_A, r_A));
break;
case BPF_RET | BPF_K:
PPC_LI32(r_ret, K);
@@ -277,24 +277,24 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
if (ctx->seen)
PPC_JMP(exit_addr);
else
- PPC_BLR();
+ EMIT(PPC_RAW_BLR());
}
break;
case BPF_RET | BPF_A:
- PPC_MR(r_ret, r_A);
+ EMIT(PPC_RAW_MR(r_ret, r_A));
if (i != flen - 1) {
if (ctx->seen)
PPC_JMP(exit_addr);
else
- PPC_BLR();
+ EMIT(PPC_RAW_BLR());
}
break;
case BPF_MISC | BPF_TAX: /* X = A */
- PPC_MR(r_X, r_A);
+ EMIT(PPC_RAW_MR(r_X, r_A));
break;
case BPF_MISC | BPF_TXA: /* A = X */
ctx->seen |= SEEN_XREG;
- PPC_MR(r_A, r_X);
+ EMIT(PPC_RAW_MR(r_A, r_X));
break;
/*** Constant loads/M[] access ***/
@@ -305,19 +305,19 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
PPC_LI32(r_X, K);
break;
case BPF_LD | BPF_MEM: /* A = mem[K] */
- PPC_MR(r_A, r_M + (K & 0xf));
+ EMIT(PPC_RAW_MR(r_A, r_M + (K & 0xf)));
ctx->seen |= SEEN_MEM | (1<<(K & 0xf));
break;
case BPF_LDX | BPF_MEM: /* X = mem[K] */
- PPC_MR(r_X, r_M + (K & 0xf));
+ EMIT(PPC_RAW_MR(r_X, r_M + (K & 0xf)));
ctx->seen |= SEEN_MEM | (1<<(K & 0xf));
break;
case BPF_ST: /* mem[K] = A */
- PPC_MR(r_M + (K & 0xf), r_A);
+ EMIT(PPC_RAW_MR(r_M + (K & 0xf), r_A));
ctx->seen |= SEEN_MEM | (1<<(K & 0xf));
break;
case BPF_STX: /* mem[K] = X */
- PPC_MR(r_M + (K & 0xf), r_X);
+ EMIT(PPC_RAW_MR(r_M + (K & 0xf), r_X));
ctx->seen |= SEEN_XREG | SEEN_MEM | (1<<(K & 0xf));
break;
case BPF_LD | BPF_W | BPF_LEN: /* A = skb->len; */
@@ -346,13 +346,13 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
type) != 2);
PPC_LL_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff,
dev));
- PPC_CMPDI(r_scratch1, 0);
+ EMIT(PPC_RAW_CMPDI(r_scratch1, 0));
if (ctx->pc_ret0 != -1) {
PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
} else {
/* Exit, returning 0; first pass hits here. */
PPC_BCC_SHORT(COND_NE, ctx->idx * 4 + 12);
- PPC_LI(r_ret, 0);
+ EMIT(PPC_RAW_LI(r_ret, 0));
PPC_JMP(exit_addr);
}
if (code == (BPF_ANC | SKF_AD_IFINDEX)) {
@@ -383,9 +383,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT:
PPC_LBZ_OFFS(r_A, r_skb, PKT_VLAN_PRESENT_OFFSET());
if (PKT_VLAN_PRESENT_BIT)
- PPC_SRWI(r_A, r_A, PKT_VLAN_PRESENT_BIT);
+ EMIT(PPC_RAW_SRWI(r_A, r_A, PKT_VLAN_PRESENT_BIT));
if (PKT_VLAN_PRESENT_BIT < 7)
- PPC_ANDI(r_A, r_A, 1);
+ EMIT(PPC_RAW_ANDI(r_A, r_A, 1));
break;
case BPF_ANC | SKF_AD_QUEUE:
BUILD_BUG_ON(sizeof_field(struct sk_buff,
@@ -395,8 +395,8 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
break;
case BPF_ANC | SKF_AD_PKTTYPE:
PPC_LBZ_OFFS(r_A, r_skb, PKT_TYPE_OFFSET());
- PPC_ANDI(r_A, r_A, PKT_TYPE_MAX);
- PPC_SRWI(r_A, r_A, 5);
+ EMIT(PPC_RAW_ANDI(r_A, r_A, PKT_TYPE_MAX));
+ EMIT(PPC_RAW_SRWI(r_A, r_A, 5));
break;
case BPF_ANC | SKF_AD_CPU:
PPC_BPF_LOAD_CPU(r_A);
@@ -414,9 +414,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
/* Load from [K]. */
ctx->seen |= SEEN_DATAREF;
PPC_FUNC_ADDR(r_scratch1, func);
- PPC_MTLR(r_scratch1);
+ EMIT(PPC_RAW_MTLR(r_scratch1));
PPC_LI32(r_addr, K);
- PPC_BLRL();
+ EMIT(PPC_RAW_BLRL());
/*
* Helper returns 'lt' condition on error, and an
* appropriate return value in r3
@@ -440,11 +440,11 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
*/
ctx->seen |= SEEN_DATAREF | SEEN_XREG;
PPC_FUNC_ADDR(r_scratch1, func);
- PPC_MTLR(r_scratch1);
- PPC_ADDI(r_addr, r_X, IMM_L(K));
+ EMIT(PPC_RAW_MTLR(r_scratch1));
+ EMIT(PPC_RAW_ADDI(r_addr, r_X, IMM_L(K)));
if (K >= 32768)
- PPC_ADDIS(r_addr, r_addr, IMM_HA(K));
- PPC_BLRL();
+ EMIT(PPC_RAW_ADDIS(r_addr, r_addr, IMM_HA(K)));
+ EMIT(PPC_RAW_BLRL());
/* If error, cr0.LT set */
PPC_BCC(COND_LT, exit_addr);
break;
@@ -489,30 +489,30 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
case BPF_JMP | BPF_JGE | BPF_X:
case BPF_JMP | BPF_JEQ | BPF_X:
ctx->seen |= SEEN_XREG;
- PPC_CMPLW(r_A, r_X);
+ EMIT(PPC_RAW_CMPLW(r_A, r_X));
break;
case BPF_JMP | BPF_JSET | BPF_X:
ctx->seen |= SEEN_XREG;
- PPC_AND_DOT(r_scratch1, r_A, r_X);
+ EMIT(PPC_RAW_AND_DOT(r_scratch1, r_A, r_X));
break;
case BPF_JMP | BPF_JEQ | BPF_K:
case BPF_JMP | BPF_JGT | BPF_K:
case BPF_JMP | BPF_JGE | BPF_K:
if (K < 32768)
- PPC_CMPLWI(r_A, K);
+ EMIT(PPC_RAW_CMPLWI(r_A, K));
else {
PPC_LI32(r_scratch1, K);
- PPC_CMPLW(r_A, r_scratch1);
+ EMIT(PPC_RAW_CMPLW(r_A, r_scratch1));
}
break;
case BPF_JMP | BPF_JSET | BPF_K:
if (K < 32768)
/* PPC_ANDI is /only/ dot-form */
- PPC_ANDI(r_scratch1, r_A, K);
+ EMIT(PPC_RAW_ANDI(r_scratch1, r_A, K));
else {
PPC_LI32(r_scratch1, K);
- PPC_AND_DOT(r_scratch1, r_A,
- r_scratch1);
+ EMIT(PPC_RAW_AND_DOT(r_scratch1, r_A,
+ r_scratch1));
}
break;
}
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
index f721fbe6ca4d..022103c6a201 100644
--- a/arch/powerpc/net/bpf_jit_comp64.c
+++ b/arch/powerpc/net/bpf_jit_comp64.c
@@ -95,12 +95,12 @@ static void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx)
* invoked through a tail call.
*/
if (ctx->seen & SEEN_TAILCALL) {
- PPC_LI(b2p[TMP_REG_1], 0);
+ EMIT(PPC_RAW_LI(b2p[TMP_REG_1], 0));
/* this goes in the redzone */
PPC_BPF_STL(b2p[TMP_REG_1], 1, -(BPF_PPC_STACK_SAVE + 8));
} else {
- PPC_NOP();
- PPC_NOP();
+ EMIT(PPC_RAW_NOP());
+ EMIT(PPC_RAW_NOP());
}
#define BPF_TAILCALL_PROLOGUE_SIZE 8
@@ -129,8 +129,8 @@ static void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx)
/* Setup frame pointer to point to the bpf stack area */
if (bpf_is_seen_register(ctx, BPF_REG_FP))
- PPC_ADDI(b2p[BPF_REG_FP], 1,
- STACK_FRAME_MIN_SIZE + ctx->stack_size);
+ EMIT(PPC_RAW_ADDI(b2p[BPF_REG_FP], 1,
+ STACK_FRAME_MIN_SIZE + ctx->stack_size));
}
static void bpf_jit_emit_common_epilogue(u32 *image, struct codegen_context *ctx)
@@ -144,10 +144,10 @@ static void bpf_jit_emit_common_epilogue(u32 *image, struct codegen_context *ctx
/* Tear down our stack frame */
if (bpf_has_stack_frame(ctx)) {
- PPC_ADDI(1, 1, BPF_PPC_STACKFRAME + ctx->stack_size);
+ EMIT(PPC_RAW_ADDI(1, 1, BPF_PPC_STACKFRAME + ctx->stack_size));
if (ctx->seen & SEEN_FUNC) {
PPC_BPF_LL(0, 1, PPC_LR_STKOFF);
- PPC_MTLR(0);
+ EMIT(PPC_RAW_MTLR(0));
}
}
}
@@ -157,9 +157,9 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
bpf_jit_emit_common_epilogue(image, ctx);
/* Move result to r3 */
- PPC_MR(3, b2p[BPF_REG_0]);
+ EMIT(PPC_RAW_MR(3, b2p[BPF_REG_0]));
- PPC_BLR();
+ EMIT(PPC_RAW_BLR());
}
static void bpf_jit_emit_func_call_hlp(u32 *image, struct codegen_context *ctx,
@@ -171,7 +171,7 @@ static void bpf_jit_emit_func_call_hlp(u32 *image, struct codegen_context *ctx,
/* Load actual entry point from function descriptor */
PPC_BPF_LL(b2p[TMP_REG_1], b2p[TMP_REG_2], 0);
/* ... and move it to LR */
- PPC_MTLR(b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_MTLR(b2p[TMP_REG_1]));
/*
* Load TOC from function descriptor at offset 8.
* We can clobber r2 since we get called through a
@@ -182,9 +182,9 @@ static void bpf_jit_emit_func_call_hlp(u32 *image, struct codegen_context *ctx,
#else
/* We can clobber r12 */
PPC_FUNC_ADDR(12, func);
- PPC_MTLR(12);
+ EMIT(PPC_RAW_MTLR(12));
#endif
- PPC_BLRL();
+ EMIT(PPC_RAW_BLRL());
}
static void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx,
@@ -206,7 +206,7 @@ static void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx,
* that PPC_LI64() can emit.
*/
for (i = ctx->idx - ctx_idx; i < 5; i++)
- PPC_NOP();
+ EMIT(PPC_RAW_NOP());
#ifdef PPC64_ELF_ABI_v1
/*
@@ -220,8 +220,8 @@ static void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx,
PPC_BPF_LL(12, 12, 0);
#endif
- PPC_MTLR(12);
- PPC_BLRL();
+ EMIT(PPC_RAW_MTLR(12));
+ EMIT(PPC_RAW_BLRL());
}
static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
@@ -240,8 +240,8 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
* goto out;
*/
EMIT(PPC_RAW_LWZ(b2p[TMP_REG_1], b2p_bpf_array, offsetof(struct bpf_array, map.max_entries)));
- PPC_RLWINM(b2p_index, b2p_index, 0, 0, 31);
- PPC_CMPLW(b2p_index, b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_RLWINM(b2p_index, b2p_index, 0, 0, 31));
+ EMIT(PPC_RAW_CMPLW(b2p_index, b2p[TMP_REG_1]));
PPC_BCC(COND_GE, out);
/*
@@ -249,17 +249,17 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
* goto out;
*/
PPC_BPF_LL(b2p[TMP_REG_1], 1, bpf_jit_stack_tailcallcnt(ctx));
- PPC_CMPLWI(b2p[TMP_REG_1], MAX_TAIL_CALL_CNT);
+ EMIT(PPC_RAW_CMPLWI(b2p[TMP_REG_1], MAX_TAIL_CALL_CNT));
PPC_BCC(COND_GT, out);
/*
* tail_call_cnt++;
*/
- PPC_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1], 1);
+ EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1], 1));
PPC_BPF_STL(b2p[TMP_REG_1], 1, bpf_jit_stack_tailcallcnt(ctx));
/* prog = array->ptrs[index]; */
- PPC_MULI(b2p[TMP_REG_1], b2p_index, 8);
+ EMIT(PPC_RAW_MULI(b2p[TMP_REG_1], b2p_index, 8));
EMIT(PPC_RAW_ADD(b2p[TMP_REG_1], b2p[TMP_REG_1], b2p_bpf_array));
PPC_BPF_LL(b2p[TMP_REG_1], b2p[TMP_REG_1], offsetof(struct bpf_array, ptrs));
@@ -267,24 +267,24 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
* if (prog == NULL)
* goto out;
*/
- PPC_CMPLDI(b2p[TMP_REG_1], 0);
+ EMIT(PPC_RAW_CMPLDI(b2p[TMP_REG_1], 0));
PPC_BCC(COND_EQ, out);
/* goto *(prog->bpf_func + prologue_size); */
PPC_BPF_LL(b2p[TMP_REG_1], b2p[TMP_REG_1], offsetof(struct bpf_prog, bpf_func));
#ifdef PPC64_ELF_ABI_v1
/* skip past the function descriptor */
- PPC_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1],
- FUNCTION_DESCR_SIZE + BPF_TAILCALL_PROLOGUE_SIZE);
+ EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1],
+ FUNCTION_DESCR_SIZE + BPF_TAILCALL_PROLOGUE_SIZE));
#else
- PPC_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1], BPF_TAILCALL_PROLOGUE_SIZE);
+ EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1], BPF_TAILCALL_PROLOGUE_SIZE));
#endif
- PPC_MTCTR(b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_MTCTR(b2p[TMP_REG_1]));
/* tear down stack, restore NVRs, ... */
bpf_jit_emit_common_epilogue(image, ctx);
- PPC_BCTR();
+ EMIT(PPC_RAW_BCTR());
/* out: */
}
@@ -344,7 +344,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
goto bpf_alu32_trunc;
case BPF_ALU | BPF_SUB | BPF_X: /* (u32) dst -= (u32) src */
case BPF_ALU64 | BPF_SUB | BPF_X: /* dst -= src */
- PPC_SUB(dst_reg, dst_reg, src_reg);
+ EMIT(PPC_RAW_SUB(dst_reg, dst_reg, src_reg));
goto bpf_alu32_trunc;
case BPF_ALU | BPF_ADD | BPF_K: /* (u32) dst += (u32) imm */
case BPF_ALU | BPF_SUB | BPF_K: /* (u32) dst -= (u32) imm */
@@ -354,7 +354,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
imm = -imm;
if (imm) {
if (imm >= -32768 && imm < 32768)
- PPC_ADDI(dst_reg, dst_reg, IMM_L(imm));
+ EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(imm)));
else {
PPC_LI32(b2p[TMP_REG_1], imm);
EMIT(PPC_RAW_ADD(dst_reg, dst_reg, b2p[TMP_REG_1]));
@@ -364,43 +364,43 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
case BPF_ALU | BPF_MUL | BPF_X: /* (u32) dst *= (u32) src */
case BPF_ALU64 | BPF_MUL | BPF_X: /* dst *= src */
if (BPF_CLASS(code) == BPF_ALU)
- PPC_MULW(dst_reg, dst_reg, src_reg);
+ EMIT(PPC_RAW_MULW(dst_reg, dst_reg, src_reg));
else
- PPC_MULD(dst_reg, dst_reg, src_reg);
+ EMIT(PPC_RAW_MULD(dst_reg, dst_reg, src_reg));
goto bpf_alu32_trunc;
case BPF_ALU | BPF_MUL | BPF_K: /* (u32) dst *= (u32) imm */
case BPF_ALU64 | BPF_MUL | BPF_K: /* dst *= imm */
if (imm >= -32768 && imm < 32768)
- PPC_MULI(dst_reg, dst_reg, IMM_L(imm));
+ EMIT(PPC_RAW_MULI(dst_reg, dst_reg, IMM_L(imm)));
else {
PPC_LI32(b2p[TMP_REG_1], imm);
if (BPF_CLASS(code) == BPF_ALU)
- PPC_MULW(dst_reg, dst_reg,
- b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_MULW(dst_reg, dst_reg,
+ b2p[TMP_REG_1]));
else
- PPC_MULD(dst_reg, dst_reg,
- b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_MULD(dst_reg, dst_reg,
+ b2p[TMP_REG_1]));
}
goto bpf_alu32_trunc;
case BPF_ALU | BPF_DIV | BPF_X: /* (u32) dst /= (u32) src */
case BPF_ALU | BPF_MOD | BPF_X: /* (u32) dst %= (u32) src */
if (BPF_OP(code) == BPF_MOD) {
- PPC_DIVWU(b2p[TMP_REG_1], dst_reg, src_reg);
- PPC_MULW(b2p[TMP_REG_1], src_reg,
- b2p[TMP_REG_1]);
- PPC_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_DIVWU(b2p[TMP_REG_1], dst_reg, src_reg));
+ EMIT(PPC_RAW_MULW(b2p[TMP_REG_1], src_reg,
+ b2p[TMP_REG_1]));
+ EMIT(PPC_RAW_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]));
} else
- PPC_DIVWU(dst_reg, dst_reg, src_reg);
+ EMIT(PPC_RAW_DIVWU(dst_reg, dst_reg, src_reg));
goto bpf_alu32_trunc;
case BPF_ALU64 | BPF_DIV | BPF_X: /* dst /= src */
case BPF_ALU64 | BPF_MOD | BPF_X: /* dst %= src */
if (BPF_OP(code) == BPF_MOD) {
- PPC_DIVDU(b2p[TMP_REG_1], dst_reg, src_reg);
- PPC_MULD(b2p[TMP_REG_1], src_reg,
- b2p[TMP_REG_1]);
- PPC_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_DIVDU(b2p[TMP_REG_1], dst_reg, src_reg));
+ EMIT(PPC_RAW_MULD(b2p[TMP_REG_1], src_reg,
+ b2p[TMP_REG_1]));
+ EMIT(PPC_RAW_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]));
} else
- PPC_DIVDU(dst_reg, dst_reg, src_reg);
+ EMIT(PPC_RAW_DIVDU(dst_reg, dst_reg, src_reg));
break;
case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */
case BPF_ALU | BPF_DIV | BPF_K: /* (u32) dst /= (u32) imm */
@@ -415,35 +415,37 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
switch (BPF_CLASS(code)) {
case BPF_ALU:
if (BPF_OP(code) == BPF_MOD) {
- PPC_DIVWU(b2p[TMP_REG_2], dst_reg,
- b2p[TMP_REG_1]);
- PPC_MULW(b2p[TMP_REG_1],
+ EMIT(PPC_RAW_DIVWU(b2p[TMP_REG_2],
+ dst_reg,
+ b2p[TMP_REG_1]));
+ EMIT(PPC_RAW_MULW(b2p[TMP_REG_1],
b2p[TMP_REG_1],
- b2p[TMP_REG_2]);
- PPC_SUB(dst_reg, dst_reg,
- b2p[TMP_REG_1]);
+ b2p[TMP_REG_2]));
+ EMIT(PPC_RAW_SUB(dst_reg, dst_reg,
+ b2p[TMP_REG_1]));
} else
- PPC_DIVWU(dst_reg, dst_reg,
- b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_DIVWU(dst_reg, dst_reg,
+ b2p[TMP_REG_1]));
break;
case BPF_ALU64:
if (BPF_OP(code) == BPF_MOD) {
- PPC_DIVDU(b2p[TMP_REG_2], dst_reg,
- b2p[TMP_REG_1]);
- PPC_MULD(b2p[TMP_REG_1],
+ EMIT(PPC_RAW_DIVDU(b2p[TMP_REG_2],
+ dst_reg,
+ b2p[TMP_REG_1]));
+ EMIT(PPC_RAW_MULD(b2p[TMP_REG_1],
b2p[TMP_REG_1],
- b2p[TMP_REG_2]);
- PPC_SUB(dst_reg, dst_reg,
- b2p[TMP_REG_1]);
+ b2p[TMP_REG_2]));
+ EMIT(PPC_RAW_SUB(dst_reg, dst_reg,
+ b2p[TMP_REG_1]));
} else
- PPC_DIVDU(dst_reg, dst_reg,
- b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_DIVDU(dst_reg, dst_reg,
+ b2p[TMP_REG_1]));
break;
}
goto bpf_alu32_trunc;
case BPF_ALU | BPF_NEG: /* (u32) dst = -dst */
case BPF_ALU64 | BPF_NEG: /* dst = -dst */
- PPC_NEG(dst_reg, dst_reg);
+ EMIT(PPC_RAW_NEG(dst_reg, dst_reg));
goto bpf_alu32_trunc;
/*
@@ -451,101 +453,101 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
*/
case BPF_ALU | BPF_AND | BPF_X: /* (u32) dst = dst & src */
case BPF_ALU64 | BPF_AND | BPF_X: /* dst = dst & src */
- PPC_AND(dst_reg, dst_reg, src_reg);
+ EMIT(PPC_RAW_AND(dst_reg, dst_reg, src_reg));
goto bpf_alu32_trunc;
case BPF_ALU | BPF_AND | BPF_K: /* (u32) dst = dst & imm */
case BPF_ALU64 | BPF_AND | BPF_K: /* dst = dst & imm */
if (!IMM_H(imm))
- PPC_ANDI(dst_reg, dst_reg, IMM_L(imm));
+ EMIT(PPC_RAW_ANDI(dst_reg, dst_reg, IMM_L(imm)));
else {
/* Sign-extended */
PPC_LI32(b2p[TMP_REG_1], imm);
- PPC_AND(dst_reg, dst_reg, b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_AND(dst_reg, dst_reg, b2p[TMP_REG_1]));
}
goto bpf_alu32_trunc;
case BPF_ALU | BPF_OR | BPF_X: /* dst = (u32) dst | (u32) src */
case BPF_ALU64 | BPF_OR | BPF_X: /* dst = dst | src */
- PPC_OR(dst_reg, dst_reg, src_reg);
+ EMIT(PPC_RAW_OR(dst_reg, dst_reg, src_reg));
goto bpf_alu32_trunc;
case BPF_ALU | BPF_OR | BPF_K:/* dst = (u32) dst | (u32) imm */
case BPF_ALU64 | BPF_OR | BPF_K:/* dst = dst | imm */
if (imm < 0 && BPF_CLASS(code) == BPF_ALU64) {
/* Sign-extended */
PPC_LI32(b2p[TMP_REG_1], imm);
- PPC_OR(dst_reg, dst_reg, b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_OR(dst_reg, dst_reg, b2p[TMP_REG_1]));
} else {
if (IMM_L(imm))
- PPC_ORI(dst_reg, dst_reg, IMM_L(imm));
+ EMIT(PPC_RAW_ORI(dst_reg, dst_reg, IMM_L(imm)));
if (IMM_H(imm))
- PPC_ORIS(dst_reg, dst_reg, IMM_H(imm));
+ EMIT(PPC_RAW_ORIS(dst_reg, dst_reg, IMM_H(imm)));
}
goto bpf_alu32_trunc;
case BPF_ALU | BPF_XOR | BPF_X: /* (u32) dst ^= src */
case BPF_ALU64 | BPF_XOR | BPF_X: /* dst ^= src */
- PPC_XOR(dst_reg, dst_reg, src_reg);
+ EMIT(PPC_RAW_XOR(dst_reg, dst_reg, src_reg));
goto bpf_alu32_trunc;
case BPF_ALU | BPF_XOR | BPF_K: /* (u32) dst ^= (u32) imm */
case BPF_ALU64 | BPF_XOR | BPF_K: /* dst ^= imm */
if (imm < 0 && BPF_CLASS(code) == BPF_ALU64) {
/* Sign-extended */
PPC_LI32(b2p[TMP_REG_1], imm);
- PPC_XOR(dst_reg, dst_reg, b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_XOR(dst_reg, dst_reg, b2p[TMP_REG_1]));
} else {
if (IMM_L(imm))
- PPC_XORI(dst_reg, dst_reg, IMM_L(imm));
+ EMIT(PPC_RAW_XORI(dst_reg, dst_reg, IMM_L(imm)));
if (IMM_H(imm))
- PPC_XORIS(dst_reg, dst_reg, IMM_H(imm));
+ EMIT(PPC_RAW_XORIS(dst_reg, dst_reg, IMM_H(imm)));
}
goto bpf_alu32_trunc;
case BPF_ALU | BPF_LSH | BPF_X: /* (u32) dst <<= (u32) src */
/* slw clears top 32 bits */
- PPC_SLW(dst_reg, dst_reg, src_reg);
+ EMIT(PPC_RAW_SLW(dst_reg, dst_reg, src_reg));
/* skip zero extension move, but set address map. */
if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break;
case BPF_ALU64 | BPF_LSH | BPF_X: /* dst <<= src; */
- PPC_SLD(dst_reg, dst_reg, src_reg);
+ EMIT(PPC_RAW_SLD(dst_reg, dst_reg, src_reg));
break;
case BPF_ALU | BPF_LSH | BPF_K: /* (u32) dst <<== (u32) imm */
/* with imm 0, we still need to clear top 32 bits */
- PPC_SLWI(dst_reg, dst_reg, imm);
+ EMIT(PPC_RAW_SLWI(dst_reg, dst_reg, imm));
if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break;
case BPF_ALU64 | BPF_LSH | BPF_K: /* dst <<== imm */
if (imm != 0)
- PPC_SLDI(dst_reg, dst_reg, imm);
+ EMIT(PPC_RAW_SLDI(dst_reg, dst_reg, imm));
break;
case BPF_ALU | BPF_RSH | BPF_X: /* (u32) dst >>= (u32) src */
- PPC_SRW(dst_reg, dst_reg, src_reg);
+ EMIT(PPC_RAW_SRW(dst_reg, dst_reg, src_reg));
if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break;
case BPF_ALU64 | BPF_RSH | BPF_X: /* dst >>= src */
- PPC_SRD(dst_reg, dst_reg, src_reg);
+ EMIT(PPC_RAW_SRD(dst_reg, dst_reg, src_reg));
break;
case BPF_ALU | BPF_RSH | BPF_K: /* (u32) dst >>= (u32) imm */
- PPC_SRWI(dst_reg, dst_reg, imm);
+ EMIT(PPC_RAW_SRWI(dst_reg, dst_reg, imm));
if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break;
case BPF_ALU64 | BPF_RSH | BPF_K: /* dst >>= imm */
if (imm != 0)
- PPC_SRDI(dst_reg, dst_reg, imm);
+ EMIT(PPC_RAW_SRDI(dst_reg, dst_reg, imm));
break;
case BPF_ALU | BPF_ARSH | BPF_X: /* (s32) dst >>= src */
- PPC_SRAW(dst_reg, dst_reg, src_reg);
+ EMIT(PPC_RAW_SRAW(dst_reg, dst_reg, src_reg));
goto bpf_alu32_trunc;
case BPF_ALU64 | BPF_ARSH | BPF_X: /* (s64) dst >>= src */
- PPC_SRAD(dst_reg, dst_reg, src_reg);
+ EMIT(PPC_RAW_SRAD(dst_reg, dst_reg, src_reg));
break;
case BPF_ALU | BPF_ARSH | BPF_K: /* (s32) dst >>= imm */
- PPC_SRAWI(dst_reg, dst_reg, imm);
+ EMIT(PPC_RAW_SRAWI(dst_reg, dst_reg, imm));
goto bpf_alu32_trunc;
case BPF_ALU64 | BPF_ARSH | BPF_K: /* (s64) dst >>= imm */
if (imm != 0)
- PPC_SRADI(dst_reg, dst_reg, imm);
+ EMIT(PPC_RAW_SRADI(dst_reg, dst_reg, imm));
break;
/*
@@ -555,10 +557,10 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */
if (imm == 1) {
/* special mov32 for zext */
- PPC_RLWINM(dst_reg, dst_reg, 0, 0, 31);
+ EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 0, 0, 31));
break;
}
- PPC_MR(dst_reg, src_reg);
+ EMIT(PPC_RAW_MR(dst_reg, src_reg));
goto bpf_alu32_trunc;
case BPF_ALU | BPF_MOV | BPF_K: /* (u32) dst = imm */
case BPF_ALU64 | BPF_MOV | BPF_K: /* dst = (s64) imm */
@@ -572,7 +574,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
bpf_alu32_trunc:
/* Truncate to 32-bits */
if (BPF_CLASS(code) == BPF_ALU && !fp->aux->verifier_zext)
- PPC_RLWINM(dst_reg, dst_reg, 0, 0, 31);
+ EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 0, 0, 31));
break;
/*
@@ -590,11 +592,11 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
switch (imm) {
case 16:
/* Rotate 8 bits left & mask with 0x0000ff00 */
- PPC_RLWINM(b2p[TMP_REG_1], dst_reg, 8, 16, 23);
+ EMIT(PPC_RAW_RLWINM(b2p[TMP_REG_1], dst_reg, 8, 16, 23));
/* Rotate 8 bits right & insert LSB to reg */
- PPC_RLWIMI(b2p[TMP_REG_1], dst_reg, 24, 24, 31);
+ EMIT(PPC_RAW_RLWIMI(b2p[TMP_REG_1], dst_reg, 24, 24, 31));
/* Move result back to dst_reg */
- PPC_MR(dst_reg, b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_MR(dst_reg, b2p[TMP_REG_1]));
break;
case 32:
/*
@@ -602,12 +604,12 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
* 2 bytes are already in their final position
* -- byte 2 and 4 (of bytes 1, 2, 3 and 4)
*/
- PPC_RLWINM(b2p[TMP_REG_1], dst_reg, 8, 0, 31);
+ EMIT(PPC_RAW_RLWINM(b2p[TMP_REG_1], dst_reg, 8, 0, 31));
/* Rotate 24 bits and insert byte 1 */
- PPC_RLWIMI(b2p[TMP_REG_1], dst_reg, 24, 0, 7);
+ EMIT(PPC_RAW_RLWIMI(b2p[TMP_REG_1], dst_reg, 24, 0, 7));
/* Rotate 24 bits and insert byte 3 */
- PPC_RLWIMI(b2p[TMP_REG_1], dst_reg, 24, 16, 23);
- PPC_MR(dst_reg, b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_RLWIMI(b2p[TMP_REG_1], dst_reg, 24, 16, 23));
+ EMIT(PPC_RAW_MR(dst_reg, b2p[TMP_REG_1]));
break;
case 64:
/*
@@ -619,8 +621,8 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
* same across all passes
*/
PPC_BPF_STL(dst_reg, 1, bpf_jit_stack_local(ctx));
- PPC_ADDI(b2p[TMP_REG_1], 1, bpf_jit_stack_local(ctx));
- PPC_LDBRX(dst_reg, 0, b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], 1, bpf_jit_stack_local(ctx)));
+ EMIT(PPC_RAW_LDBRX(dst_reg, 0, b2p[TMP_REG_1]));
break;
}
break;
@@ -629,14 +631,14 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
switch (imm) {
case 16:
/* zero-extend 16 bits into 64 bits */
- PPC_RLDICL(dst_reg, dst_reg, 0, 48);
+ EMIT(PPC_RAW_RLDICL(dst_reg, dst_reg, 0, 48));
if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break;
case 32:
if (!fp->aux->verifier_zext)
/* zero-extend 32 bits into 64 bits */
- PPC_RLDICL(dst_reg, dst_reg, 0, 32);
+ EMIT(PPC_RAW_RLDICL(dst_reg, dst_reg, 0, 32));
break;
case 64:
/* nop */
@@ -650,18 +652,18 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
case BPF_STX | BPF_MEM | BPF_B: /* *(u8 *)(dst + off) = src */
case BPF_ST | BPF_MEM | BPF_B: /* *(u8 *)(dst + off) = imm */
if (BPF_CLASS(code) == BPF_ST) {
- PPC_LI(b2p[TMP_REG_1], imm);
+ EMIT(PPC_RAW_LI(b2p[TMP_REG_1], imm));
src_reg = b2p[TMP_REG_1];
}
- PPC_STB(src_reg, dst_reg, off);
+ EMIT(PPC_RAW_STB(src_reg, dst_reg, off));
break;
case BPF_STX | BPF_MEM | BPF_H: /* (u16 *)(dst + off) = src */
case BPF_ST | BPF_MEM | BPF_H: /* (u16 *)(dst + off) = imm */
if (BPF_CLASS(code) == BPF_ST) {
- PPC_LI(b2p[TMP_REG_1], imm);
+ EMIT(PPC_RAW_LI(b2p[TMP_REG_1], imm));
src_reg = b2p[TMP_REG_1];
}
- PPC_STH(src_reg, dst_reg, off);
+ EMIT(PPC_RAW_STH(src_reg, dst_reg, off));
break;
case BPF_STX | BPF_MEM | BPF_W: /* *(u32 *)(dst + off) = src */
case BPF_ST | BPF_MEM | BPF_W: /* *(u32 *)(dst + off) = imm */
@@ -669,7 +671,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
PPC_LI32(b2p[TMP_REG_1], imm);
src_reg = b2p[TMP_REG_1];
}
- PPC_STW(src_reg, dst_reg, off);
+ EMIT(PPC_RAW_STW(src_reg, dst_reg, off));
break;
case BPF_STX | BPF_MEM | BPF_DW: /* (u64 *)(dst + off) = src */
case BPF_ST | BPF_MEM | BPF_DW: /* *(u64 *)(dst + off) = imm */
@@ -686,20 +688,20 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
/* *(u32 *)(dst + off) += src */
case BPF_STX | BPF_XADD | BPF_W:
/* Get EA into TMP_REG_1 */
- PPC_ADDI(b2p[TMP_REG_1], dst_reg, off);
+ EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], dst_reg, off));
tmp_idx = ctx->idx * 4;
/* load value from memory into TMP_REG_2 */
EMIT(PPC_RAW_LWARX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1], 0));
/* add value from src_reg into this */
EMIT(PPC_RAW_ADD(b2p[TMP_REG_2], b2p[TMP_REG_2], src_reg));
/* store result back */
- PPC_BPF_STWCX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_STWCX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1]));
/* we're done if this succeeded */
PPC_BCC_SHORT(COND_NE, tmp_idx);
break;
/* *(u64 *)(dst + off) += src */
case BPF_STX | BPF_XADD | BPF_DW:
- PPC_ADDI(b2p[TMP_REG_1], dst_reg, off);
+ EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], dst_reg, off));
tmp_idx = ctx->idx * 4;
EMIT(PPC_RAW_LDARX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1], 0));
EMIT(PPC_RAW_ADD(b2p[TMP_REG_2], b2p[TMP_REG_2], src_reg));
@@ -712,13 +714,13 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
*/
/* dst = *(u8 *)(ul) (src + off) */
case BPF_LDX | BPF_MEM | BPF_B:
- PPC_LBZ(dst_reg, src_reg, off);
+ EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break;
/* dst = *(u16 *)(ul) (src + off) */
case BPF_LDX | BPF_MEM | BPF_H:
- PPC_LHZ(dst_reg, src_reg, off);
+ EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off));
if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break;
@@ -775,7 +777,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
else
bpf_jit_emit_func_call_rel(image, ctx, func_addr);
/* move return value from r3 to BPF_REG_0 */
- PPC_MR(b2p[BPF_REG_0], 3);
+ EMIT(PPC_RAW_MR(b2p[BPF_REG_0], 3));
break;
/*
@@ -860,9 +862,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
case BPF_JMP32 | BPF_JNE | BPF_X:
/* unsigned comparison */
if (BPF_CLASS(code) == BPF_JMP32)
- PPC_CMPLW(dst_reg, src_reg);
+ EMIT(PPC_RAW_CMPLW(dst_reg, src_reg));
else
- PPC_CMPLD(dst_reg, src_reg);
+ EMIT(PPC_RAW_CMPLD(dst_reg, src_reg));
break;
case BPF_JMP | BPF_JSGT | BPF_X:
case BPF_JMP | BPF_JSLT | BPF_X:
@@ -874,21 +876,21 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
case BPF_JMP32 | BPF_JSLE | BPF_X:
/* signed comparison */
if (BPF_CLASS(code) == BPF_JMP32)
- PPC_CMPW(dst_reg, src_reg);
+ EMIT(PPC_RAW_CMPW(dst_reg, src_reg));
else
- PPC_CMPD(dst_reg, src_reg);
+ EMIT(PPC_RAW_CMPD(dst_reg, src_reg));
break;
case BPF_JMP | BPF_JSET | BPF_X:
case BPF_JMP32 | BPF_JSET | BPF_X:
if (BPF_CLASS(code) == BPF_JMP) {
- PPC_AND_DOT(b2p[TMP_REG_1], dst_reg,
- src_reg);
+ EMIT(PPC_RAW_AND_DOT(b2p[TMP_REG_1], dst_reg,
+ src_reg));
} else {
int tmp_reg = b2p[TMP_REG_1];
- PPC_AND(tmp_reg, dst_reg, src_reg);
- PPC_RLWINM_DOT(tmp_reg, tmp_reg, 0, 0,
- 31);
+ EMIT(PPC_RAW_AND(tmp_reg, dst_reg, src_reg));
+ EMIT(PPC_RAW_RLWINM_DOT(tmp_reg, tmp_reg, 0, 0,
+ 31));
}
break;
case BPF_JMP | BPF_JNE | BPF_K:
@@ -912,19 +914,19 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
*/
if (imm >= 0 && imm < 32768) {
if (is_jmp32)
- PPC_CMPLWI(dst_reg, imm);
+ EMIT(PPC_RAW_CMPLWI(dst_reg, imm));
else
- PPC_CMPLDI(dst_reg, imm);
+ EMIT(PPC_RAW_CMPLDI(dst_reg, imm));
} else {
/* sign-extending load */
PPC_LI32(b2p[TMP_REG_1], imm);
/* ... but unsigned comparison */
if (is_jmp32)
- PPC_CMPLW(dst_reg,
- b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_CMPLW(dst_reg,
+ b2p[TMP_REG_1]));
else
- PPC_CMPLD(dst_reg,
- b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_CMPLD(dst_reg,
+ b2p[TMP_REG_1]));
}
break;
}
@@ -945,17 +947,17 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
*/
if (imm >= -32768 && imm < 32768) {
if (is_jmp32)
- PPC_CMPWI(dst_reg, imm);
+ EMIT(PPC_RAW_CMPWI(dst_reg, imm));
else
- PPC_CMPDI(dst_reg, imm);
+ EMIT(PPC_RAW_CMPDI(dst_reg, imm));
} else {
PPC_LI32(b2p[TMP_REG_1], imm);
if (is_jmp32)
- PPC_CMPW(dst_reg,
- b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_CMPW(dst_reg,
+ b2p[TMP_REG_1]));
else
- PPC_CMPD(dst_reg,
- b2p[TMP_REG_1]);
+ EMIT(PPC_RAW_CMPD(dst_reg,
+ b2p[TMP_REG_1]));
}
break;
}
@@ -964,19 +966,19 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
/* andi does not sign-extend the immediate */
if (imm >= 0 && imm < 32768)
/* PPC_ANDI is _only/always_ dot-form */
- PPC_ANDI(b2p[TMP_REG_1], dst_reg, imm);
+ EMIT(PPC_RAW_ANDI(b2p[TMP_REG_1], dst_reg, imm));
else {
int tmp_reg = b2p[TMP_REG_1];
PPC_LI32(tmp_reg, imm);
if (BPF_CLASS(code) == BPF_JMP) {
- PPC_AND_DOT(tmp_reg, dst_reg,
- tmp_reg);
+ EMIT(PPC_RAW_AND_DOT(tmp_reg, dst_reg,
+ tmp_reg));
} else {
- PPC_AND(tmp_reg, dst_reg,
- tmp_reg);
- PPC_RLWINM_DOT(tmp_reg, tmp_reg,
- 0, 0, 31);
+ EMIT(PPC_RAW_AND(tmp_reg, dst_reg,
+ tmp_reg));
+ EMIT(PPC_RAW_RLWINM_DOT(tmp_reg, tmp_reg,
+ 0, 0, 31));
}
}
break;
--
2.24.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox