硬汉嵌入式论坛

 找回密码
 立即注册
查看: 734|回复: 1
收起左侧

[技术讨论] gd32vf103 PMP内存保护疑问

[复制链接]

69

主题

175

回帖

382

积分

高级会员

积分
382
发表于 2024-7-1 10:12:40 | 显示全部楼层 |阅读模式
使用nuclei IDE建立的pmp的例程代码,测试不开启执行权限“R/W/X”,并没有产生异常进入中断,debug时发现配置PMP后再回读配置,配置的值并不是写进去的值,这是什么原因呢?有小伙伴用过这个例程PMP吗?
[C] 纯文本查看 复制代码
// See LICENSE for license details.
#include <stdio.h>
#include <string.h>
#include "nuclei_sdk_soc.h"

/* different trigger condition */
#define INSTRUCTION_FETCH_EXCEPTION    0
#define LOAD_EXCEPTION                 1
#define STORE_EXCEPTION                2
#define RUN_WITH_NO_PMP_CHECK          3

/* Just choose one from above defines to test PMP */
#define TRIGGER_PMP_VIOLATION_MODE     INSTRUCTION_FETCH_EXCEPTION

volatile uint8_t protected_data[0x2000] __attribute__((aligned(0x2000))) =    \
{0xaa, 0x1, 0x02, 0x03, 0x04, 0x05, 0x06, 0xaa};

#ifndef __ICCRISCV__
#define __PMP_PROTECT   __attribute__((section (".text"), aligned(0x2000)))
#else
/* IAR CC currently don't support align function in section,
 * so we provide a workaround using a customized iar_evalsoc_ilm.icf in this demo
 * we define a block called PMPFUNC alignment set to 0x2000 */
#define __PMP_PROTECT   __attribute__((section (".text.pmpfunc")))
#endif

static void __PMP_PROTECT protected_execute(void)
{
    printf("----protected_execute succeed!----\r\n");

    printf("Attempting to read protected_data[0]\r\n");
    printf("protected_data[0]: 0x%0X succeed\r\n", protected_data[0]);

    printf("Attempting to write protected_data[0]\r\n");
    protected_data[0] = 0xFF;

    printf("Won't run here if violates L R\\W\\X permission check!\r\n");
}

static void pmp_violation_fault_handler(unsigned long mcause, unsigned long sp)
{
    EXC_Frame_Type *exc_frame = (EXC_Frame_Type *)sp;

    switch (mcause & MCAUSE_CAUSE) {
        case InsAccFault_EXCn:
            printf("Instruction access fault occurs, cause: 0x%lx, epc: 0x%lx\r\n", exc_frame->cause, exc_frame->epc);
            break;
        case LdFault_EXCn:
            printf("Load access fault occurs, cause: 0x%lx, epc: 0x%lx\r\n", exc_frame->cause, exc_frame->epc);
            break;
        case StAccessFault_EXCn:
            printf("Store/AMO access fault occurs, cause: 0x%lx, epc: 0x%lx\r\n", exc_frame->cause, exc_frame->epc);
            break;
        default: break;
    }
    while(1);
}

typedef void(*__funcpt)(void);

int main(void)
{
    /* Configuration of execution region*/
    pmp_config pmp_config_x = {
        /*
         * Locked PMP entries remain locked until the hart is reset,
         * the L bit also indicates whether the R/W/X permissions are enforced on M-mode accesses
         */
        .protection = PMP_L | PMP_R | PMP_W | PMP_X,
        /* Initial protected excutable address range is 2^12 = 4K bytes*/
        .order = 12,
        /* initial base address is 0, change it to your memory assignment */
        .base_addr = 0,
    };

    /* configuration of read/write region*/
    pmp_config pmp_config_rw = {
        /*
         * Locked PMP entries remain locked until the hart is reset,
         * the L bit also indicates whether the R/W/X permissions are enforced on M-mode accesses
         */
        .protection = PMP_L | PMP_R | PMP_W | PMP_X,
        /* initial protected readable/writable address range is 2^12 = 4K bytes */
        .order = 12,
        /* initial base address is 0, change it to your memory assignment */
        .base_addr = 0,
    };

    pmp_config_x.base_addr = (unsigned long)protected_execute;
    pmp_config_rw.base_addr = (unsigned long)protected_data;

#if (INSTRUCTION_FETCH_EXCEPTION == TRIGGER_PMP_VIOLATION_MODE)
    /* Remove X permission of protected_execute region */
    pmp_config_x.protection = PMP_L | PMP_R | PMP_W;

    pmp_config_rw.protection = PMP_L | PMP_R | PMP_W;
#elif (LOAD_EXCEPTION == TRIGGER_PMP_VIOLATION_MODE)
    /* Retrive X permission of protected_execute region */
    pmp_config_x.protection = PMP_L | PMP_R | PMP_W | PMP_X;

    /* Remove R permission of protected_data region */
    pmp_config_rw.protection = PMP_L | PMP_W;
#elif (STORE_EXCEPTION == TRIGGER_PMP_VIOLATION_MODE)
    /* Retrive X permission of protected_execute region */
    pmp_config_x.protection = PMP_L | PMP_R | PMP_W | PMP_X;

    /* Remove W permission of protected_data region */
    pmp_config_rw.protection = PMP_L | PMP_R ;
#elif (RUN_WITH_NO_PMP_CHECK == TRIGGER_PMP_VIOLATION_MODE)
    /* Unset Locking bit, any M-mode access matching the PMP entry will succeed */
    pmp_config_x.protection = PMP_R | PMP_W | PMP_X;

    pmp_config_rw.protection = PMP_R | PMP_W ;
#endif

    printf("------PMP demo with trigger condition %d------\r\n", TRIGGER_PMP_VIOLATION_MODE);

    __set_PMPENTRYx(0, &pmp_config_x);
    /* Verify the configuration takes effect */
    memset(&pmp_config_x, 0, sizeof(pmp_config));
    __get_PMPENTRYx(0, &pmp_config_x);
    printf("Get pmp entry: index %d, prot_out: 0x%x, addr_out: 0x%lx, order_out: %lu\r\n", \
        0, pmp_config_x.protection, pmp_config_x.base_addr, pmp_config_x.order);

    __set_PMPENTRYx(1, &pmp_config_rw);
    /* Verify the configuration takes effect */
    memset(&pmp_config_rw, 0, sizeof(pmp_config));
    __get_PMPENTRYx(1, &pmp_config_rw);
    printf("Get pmp entry: index %d, prot_out: 0x%x, addr_out: 0x%lx, order_out: %lu\r\n", \
        1, pmp_config_rw.protection, pmp_config_rw.base_addr, pmp_config_rw.order);

    /* register corresponding exception */
    Exception_Register_EXC(InsAccFault_EXCn, (unsigned long)pmp_violation_fault_handler);
    Exception_Register_EXC(LdFault_EXCn, (unsigned long)pmp_violation_fault_handler);
    Exception_Register_EXC(StAccessFault_EXCn, (unsigned long)pmp_violation_fault_handler);

    /* In case compiler use inline optimization of protected_execute */
    __funcpt fncptr = ((__funcpt)protected_execute);
    printf("Attempting to fetch instruction from protected address\n");
    fncptr();

    while(1);
    return 0;
}





回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117555
QQ
发表于 2024-7-1 11:32:02 | 显示全部楼层
帮顶。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-14 10:28 , Processed in 0.036032 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表