laura(mips)操作cp2

来源:互联网 发布:电脑硬盘分区软件 编辑:程序博客网 时间:2024/06/06 10:55

添加系统调用来操作laura的cp2寄存器,但是自测发现要不就是根本不能使用,勉强能使用也是计数不准,今天仔细看了代码,找到了原因。

    larua平台的performance相关寄存器在cp2。要读写cp2的相关寄存器首先要使能cp0 status寄存器的CU2(bit[30])。但是默认是不使能CU2。
    Linux系统分内核态和用户态,CU0(bit[28])用来区别用户态和内核态。系统陷入内核态时会保存cp0 status寄存器的值并使能CU0,返回用户态时恢复cp0 status寄存器的值并disable CU0。所以使用系统调用使能CU2也不会成功(返回用户态时会自动恢复原来的值)。另外创建进程时会自动disable CU2。

    现修改代码,使得:(本修改基于linux-2.6.27.28内核)
1. 系统启动之后默认使能CU2
修改linux-2.6.27.28/arch/mips/kernel/traps.c,把per_cpu_trap_init中Line1419

unsigned int status_set = ST0_CU0;

改为:

unsigned int status_set = ST0_CU0 | ST0_CU2;

本来linux-2.6.27.28/arch/mips/kernel/head.S中也需要修改

即会调用的setup_c0_status中的Line99由

 or t0, ST0_CU0|/set|0x1f|/clr

改为:

 or t0, ST0_CU2|ST0_CU0|/set|0x1f|/clr

但测试发现由于traps.c的设置在后面,所以head.S不修改也没关系。
2. 创建进程不会disable CU2
修改linux-2.6.27.28/arch/mips/kernel/process.c,把copy_thread函数中Line148/149由

 p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1);
 childregs->cp0_status &= ~(ST0_CU2|ST0_CU1);
改为:

 p->thread.cp0_status = read_c0_status() & ~(ST0_CU1);
 childregs->cp0_status &= ~(ST0_CU1);

这样就可以使用laura的cp2。

 

 

mips判断是kernel mode还是user mode的说明:

在stackframe.h里,这个SAVE_SOME宏里,根据cu0的值来判断是kernel mode(为1)还是user mode(为0),对两者采取不同的保存方式:
  .macro SAVE_SOME
  .set push
  .set noat
  .set reorder
  mfc0 k0, CP0_STATUS
  sll k0, 3  /* extract cu0 bit */
  .set noreorder
  bltz k0, 8f
   move k1, sp
  .set reorder
  /* Called from user mode, new stack. */
  get_saved_sp

原创粉丝点击