gpt4 book ai didi

c - 为什么这个函数在 Linux 驱动中不能是静态的

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:47:14 24 4
gpt4 key购买 nike

我有一些汇编代码封装在我的驱动程序代码的静态函数中。我的代码就像

static int _ARMVAtoPA(void *pvAddr)
{
__asm__ __volatile__(
/* ; INTERRUPTS_OFF" */
" mrs r2, CPSR;\n" /* r2 saves current status */
"CPSID iaf;\n" /* Disable interrupts */

/*In order to handle PAGE OUT scenario, we need do the same operation
twice. In the first time, if PAGE OUT happens for the input address,
translation abort will happen and OS will do PAGE IN operation
Then the second time will succeed.
*/

"mcr p15, 0, r0, c7, c8, 0;\n "
/* ; get VA = <Rn> and run nonsecure translation
; with nonsecure privileged read permission.
; if the selected translation table has privileged
; read permission, the PA is loaded in the PA
; Register, otherwise abort information is loaded
; in the PA Register.
*/

/* read in <Rd> the PA value */
"mrc p15, 0, r1, c7, c4, 0;\n"
/* get VA = <Rn> and run nonsecure translation */
" mcr p15, 0, r0, c7, c8, 0;\n"

/* ; with nonsecure privileged read permission.
; if the selected translation table has privileged
; read permission, the PA is loaded in the PA
; Register, otherwise abort information is loaded
; in the PA Register.
*/
"mrc p15, 0, r0, c7, c4, 0;\n" /* read in <Rd> the PA value */

/* restore INTERRUPTS_ON/OFF status*/
"msr cpsr, r2;\n" /* re-enable interrupts */

"tst r0, #0x1;\n"
"ldr r2, =0xffffffff;\n"

/* if error happens,return INVALID_PHYSICAL_ADDRESS */
"movne r0, r2;\n"
"biceq r0, r0, #0xff;\n"
"biceq r0, r0, #0xf00;" /* if ok, clear the flag bits */
);
}

static unsigned long CpuUmAddrToCpuPAddr(void *pvCpuUmAddr)
{
int phyAdrs;
int mask = 0xFFF; /* low 12bit */
int offset = (int)pvCpuUmAddr & mask;
int phyAdrsReg = _ARMVAtoPA((void *)pvCpuUmAddr);

if (INVALID_PHYSICAL_ADDRESS != phyAdrsReg)
phyAdrs = (phyAdrsReg & (~mask)) + offset;
else
phyAdrs = INVALID_PHYSICAL_ADDRESS;

return phyAdrs;
}

如你所见,我尝试将虚拟地址从用户空间转换为物理地址。我正在从另一个项目移植此代码,除了我将 _ARMVAtoPA 函数修改为静态函数。

当我使用 static int _ARMVAtoPA(void *pvAddr) 时:

  • 这个转换函数(里面有一堆汇编代码)总是返回fffffff,肯定是错误情况。

当我使用 int _ARMVAtoPA(void *pvAddr) 时:

  • 这个转换函数可以正常工作。

谁能给我解释一下,为什么当我使用静态和非静态函数时结果会有所不同。

谢谢

最佳答案

ASM 代码没有定义哪个寄存器保存函数参数 pvAddr 以及哪个寄存器保存返回值。它只是假设编译器遵循 mips ABI。

但如果函数是内联的(static 可能是内联的),寄存器分配可能会改变,因此 asm 代码可能完全错误。

为了解决这个问题,您应该使用 gcc 扩展来为函数参数和返回值分配寄存器。并且还声明它将使用哪些寄存器而不进行恢复,因此编译器可以在调用后恢复寄存器,以防函数被内联。

关于c - 为什么这个函数在 Linux 驱动中不能是静态的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34807474/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com