comcat 2007-5-11 11:04
貌似 lw 可以访问非对齐的地址
测试程序如下:
1 #include <stdio.h>
2
3 unsigned short data[] = {
4 0x1, 0x2, 0x3, 0x4,
5 0x55aa, 0x66bb, 0x77cc, 0x0000,
6 };
7
8 inline void unaligned_access(unsigned short * const row)
9 {
10 asm volatile
11 (
12 ".set mips3\n\t"
13 ".set noreorder\n\t"
14
15 "xor $10, $10\n\t"
16 "xor $11, $11\n\t"
17
18 //"lwr $10, 1(%1)\n\t" /* %1 word aligned, %1+1 word unaligned */
19 //"lwl $11, 4(%1)\n\t"
20
21 "lw $10, 1(%1)\n\t" /* %1 word aligned, %1+1 word unaligned */
22
23 //"or $10, $11\n\t"
24 "sw $10, %0\n\t"
25
26 ".set reorder\n\t"
27 ".set mips0\n\t"
28 : "=m"(*(row))
29 : "r"(row+4)
30 : "$11", "$10", "memory"
31 );
32 }
33
34 int main()
35 {
36 printf("---------------------------------------------------------\n");
37 printf(" Testing Godson2 unaligned access Instruction \n");
38 printf("---------------------------------------------------------\n\n");
39
40 unaligned_access(data);
41
42 printf("result is: 0x%04x %04x %04x %04x\n", data[3], data[2], data[1], data[0]);
43
44 }
gdb 跟踪结果data 放在0x440b90处,则21行 lw 访问的地址为 0x440b99,低2位为01,字不对齐。反汇编、跟踪都表明确实执行的是 lw 。
以上程序执行结果,与打开18,19,23 行,注释21行的结果相同。
都为:(32位系统,那位兄弟测一下64位系统的情况)
---------------------------------------------------------
Testing Godson2 unaligned access Instruction
---------------------------------------------------------
result is: 0x0004 0003 cc66 bb55
是否 lw 实现时对非对齐的访问进行了处理?转化成龙芯内部指令?
[[i] 本帖最后由 comcat 于 2007-5-11 01:19 PM 编辑 [/i]]
water 2007-5-11 11:54
那是否触发异常处理了呢 也许在那里使用了lwr/lwl swr/swl
comcat 2007-5-11 11:59
这个应该不会,ld 访问一个非对齐地址的话,内核直接输出“非法指令”的信息。
water 2007-5-11 12:02
这可不一定哦 我看到c mips run上面 甚至可以模拟cpu没有的指令
如果异常处理程序判断出异常是由ld之类的指令引发的 则可以特别处理的
[[i] 本帖最后由 water 于 2007-5-11 12:03 PM 编辑 [/i]]
comcat 2007-5-11 13:13
真让你说中了,内核里确实有一个异常处理函数负责处理 lw 访问非对齐地址引起的异常。
可惜 ld 的没有,难怪ld 与 lw 访问非对齐地址时行为不一样。
而且在用户空间提供了接口可以关闭之,如在上面的测试程序中 39 行处插入 sysmips(MIPS_FIXADE, 0);
头文件包含 sys/sysmips.h 编译执行则会提示常见的 bus error
谢谢:handshake
[[i] 本帖最后由 comcat 于 2007-5-11 01:15 PM 编辑 [/i]]
water 2007-5-11 17:19
呵呵 comcat干脆把ld也加上吧 代码应该和lw的差不多
water 2007-5-12 08:50
那内核中的lw可能是开发人员测试用的 大概发现效率不高就放弃继续改ld了
comcat 2007-5-15 18:20
早上看了下,内核里已经有了处理ld的代码(位于arch/mips/kernel/unaligned.c),只是代码的作者比较谨慎,在32位的内核模式下没有打开。
将该文件中原 #ifdef CONFIG_64BIT 换成 #if (defined (CONFIG_64BIT) || defined (CONFIG_CPU_GODSON2) ) 后重新编译之,lwu 访问非对齐地址可以了(原来抛出 "Illegal instruction" ),ld/sd 访问非对齐地址亦正常 而非原来的"Illegal instruction"。
[[i] 本帖最后由 comcat 于 2007-5-15 06:53 PM 编辑 [/i]]
comcat 2007-5-15 18:59
原代码注释为:
/* A 32-bit kernel might be running on a 64-bit processor. But
* if we're on a 32-bit processor and an i-cache incoherency
* or race makes us see a 64-bit instruction here the sdl/sdr
* would blow up, so for now we don't handle unaligned 64-bit
* instructions on 32-bit kernels.
*/
这个在2e平台上并不存在,因而可以直接引入解决lwu/ld/sd 访问非对齐地址抛出"Illegal instruction"的问题。
给个patch 吧,见附件。
foxsen 2007-5-15 19:06
回复 #9 comcat 的帖子
谢谢,我得去看看ralf有没有收入龙梦的patch了
lyxmoo 2007-5-16 18:00
有的定义为 CONFIG_CPU_GODSON2
有的定义为
CONFIG_CPU_LOONGSON2
还是需要整理规定如何定义这些 define 名。
悄悄的匿了。