U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(10):__xchg
2008-04-14 14:47
344 查看
在u-boot-1.1.6-2008R1/include/asm/system.h中有这样一个函数:
static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
int size)
{
unsigned long tmp = 0;
unsigned long flags = 0;
local_irq_save(flags);
switch (size) {
case 1:
__asm__ __volatile__
("%0 = b%2 (z);/n/t"
"b%2 = %1;/n/t"
: "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
break;
case 2:
__asm__ __volatile__
("%0 = w%2 (z);/n/t"
"w%2 = %1;/n/t"
: "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
break;
case 4:
__asm__ __volatile__
("%0 = %2;/n/t"
"%2 = %1;/n/t"
: "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
break;
}
local_irq_restore(flags);
return tmp;
}
这个函数使用了内嵌汇编,移植时有几个问题:
1、%0=b%2(z),类似这样的语句,在VDSP下一解释就变成了
r0 = bp0(r0和p0的使用可能与实际值不同)
当然是明显的语法错误,所以应该修改为
%0 = b[%2] (z)
2、”m”,在VDSP中不支持”m”,由于此处需要使用P指针,所以相应地改为”a”或者”p”。
3、(*__xg(ptr)),直接用(ptr)就OK了。
这样,经过修改后的函数就成了:
static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
int size)
{
unsigned long tmp = 0;
unsigned long flags = 0;
local_irq_save(flags);
switch (size) {
case 1:
__asm__ __volatile__
("%0 = b[%2] (z);/n/t"
"b[%2] = %1;/n/t"
: "=&d" (tmp) : "d" (x), "a" (ptr) : "memory");
break;
case 2:
__asm__ __volatile__
("%0 = w[%2] (z);/n/t"
"w[%2] = %1;/n/t"
: "=&d" (tmp) : "d" (x), "a" (ptr) : "memory");
break;
case 4:
__asm__ __volatile__
("%0 = %2;/n/t"
"%2 = %1;/n/t"
: "=&d" (tmp) : "d" (x), "a" (ptr) : "memory");
break;
}
local_irq_restore(flags);
return tmp;
}
不过经过这样修改之后,VDSP会给出一个警告:
[Warning ea5506] "C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/acc0ab0f1fc000/acc0ab0f1fc001.s":124 Memory load instruction use may trigger hardware anomaly 05-00-0227. See appropriate Blackfin anomaly lists for more information.
查了一下anomaly 05-00-0227,是这样解释的
Enables workaround for anomaly 05-00-0257: “An interrupt or exception during short hardware loops may cause the instruction fetch unit to malfunction.” When enabled, the compiler saves and restores LC0 and LC1 in interrupt handlers.
The compiler defines the macro __WORKAROUND_SHORT_LOOP_EXCEPTIONS_257 at the compile, assembly, and link build stages when this workaround is enabled.
暂时还不太明白这其中的意思,不过比较了一下gcc生成的代码和VDSP生成的代码,两者是一样的,所以暂时搁置一下这个问题。
相关文章推荐
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(5):ENDPROC
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(6):使用u-boot的crt代码
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(12):第二阶段的程序入口
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(18):const
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(9):bool的问题
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(7):改造u-boot.lds.s
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(13):使用L1
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录:#if
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(8):链接错误_bss_start
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(19):分号惹祸
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(2): .macro
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(14):使用VDSP库
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(16):*cplb_add
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(3): 汇编空语句
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(15):DECLARE_GLOBAL_DATA_PTR
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(20):INPUT_SECTION_ALIGN
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(4):提示信息
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(11):bsz
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(17): Entry.h
- U-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录(21):收工