kernel-brax3-ubuntu-touch/drivers/misc/mediatek/mkp/mkp_module.c
erascape f319b992b1 kernel-5.15: Initial import brax3 UT kernel
* halium configs enabled

Signed-off-by: erascape <erascape@proton.me>
2025-09-23 15:17:10 +00:00

115 lines
3.7 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2002 Richard Henderson
* Copyright (C) 2001 Rusty Russell, 2002, 2010 Rusty Russell IBM.
* Copyright (C) 2021 MediaTek Inc.
*/
#include <linux/of.h>
#include "mkp_module.h"
#include "mkp_api.h"
#define DRV_NUM_MAX 128
static const char *drv_skip_list[DRV_NUM_MAX] __ro_after_init;
static int drv_skip_num __ro_after_init;
/* mkp_drv_skip="ko_1", "ko_2", "ko_3", ..., "ko_128"; */
void __init update_drv_skip_by_dts(struct device_node *node)
{
if (!node)
return;
drv_skip_num = of_property_read_string_array(node, "mkp_drv_skip",
drv_skip_list, DRV_NUM_MAX);
if (drv_skip_num < 0 && drv_skip_num >= DRV_NUM_MAX) {
pr_info("%s: no valid mkp_drv_skip(%d)\n", __func__, drv_skip_num);
drv_skip_num = 0;
}
}
bool drv_skip(char *module_name)
{
int i = 0;
for (i = 0; i < drv_skip_num; i++) {
if (strcmp(module_name, drv_skip_list[i]) == 0)
return true;
}
return false;
}
static void frob_text(const struct module_layout *layout,
enum helper_ops ops, uint32_t policy)
{
int ret;
BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1));
ret = mkp_set_mapping_xxx_helper((unsigned long)layout->base, layout->text_size>>PAGE_SHIFT,
policy, ops);
}
static void frob_rodata(const struct module_layout *layout,
enum helper_ops ops, uint32_t policy)
{
int ret;
BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1));
BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1));
ret = mkp_set_mapping_xxx_helper((unsigned long)layout->base+layout->text_size,
(layout->ro_size-layout->text_size)>>PAGE_SHIFT, policy, ops);
}
static void frob_ro_after_init(const struct module_layout *layout,
enum helper_ops ops, uint32_t policy)
{
int ret;
BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1));
BUG_ON((unsigned long)layout->ro_after_init_size & (PAGE_SIZE-1));
ret = mkp_set_mapping_xxx_helper((unsigned long)layout->base+layout->ro_size,
(layout->ro_after_init_size-layout->ro_size)>>PAGE_SHIFT, policy, ops);
}
static void frob_writable_data(const struct module_layout *layout,
enum helper_ops ops, uint32_t policy)
{
int ret;
BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
BUG_ON((unsigned long)layout->ro_after_init_size & (PAGE_SIZE-1));
BUG_ON((unsigned long)layout->size & (PAGE_SIZE-1));
ret = mkp_set_mapping_xxx_helper((unsigned long)layout->base+layout->ro_after_init_size,
(layout->size-layout->ro_after_init_size)>>PAGE_SHIFT, policy, ops);
}
void module_enable_x(const struct module *mod, uint32_t policy)
{
frob_text(&mod->core_layout, HELPER_MAPPING_X, policy);
if (policy == MKP_POLICY_DRV)
frob_text(&mod->init_layout, HELPER_MAPPING_X, policy);
}
void module_enable_ro(const struct module *mod, bool after_init, uint32_t policy)
{
/* DO NOT CHANGE THE FOLLOWING ORDER */
frob_text(&mod->core_layout, HELPER_MAPPING_RO, policy);
frob_rodata(&mod->core_layout, HELPER_MAPPING_RO, policy);
if (policy == MKP_POLICY_DRV) {
frob_text(&mod->init_layout, HELPER_MAPPING_RO, policy);
frob_rodata(&mod->init_layout, HELPER_MAPPING_RO, policy);
}
if (after_init)
frob_ro_after_init(&mod->core_layout, HELPER_MAPPING_RO, policy);
}
void module_enable_nx(const struct module *mod, uint32_t policy)
{
frob_rodata(&mod->core_layout, HELPER_MAPPING_NX, policy);
/* DO NOT REMOVE THE FOLLOWING STEP */
frob_ro_after_init(&mod->core_layout, HELPER_MAPPING_NX, policy);
frob_writable_data(&mod->core_layout, HELPER_MAPPING_NX, policy);
if (policy == MKP_POLICY_DRV) {
frob_rodata(&mod->init_layout, HELPER_MAPPING_NX, policy);
frob_writable_data(&mod->init_layout, HELPER_MAPPING_NX, policy);
}
}