CPC700 有一个 “特性”,该特性本应使某些内存访问使用 64 位宽度。这是一个问题,因为我们板上的一些测试和设置寄存器可能会被意外设置,因为我们试图读取低 16 位的内容。为了解决这种情况,我们将内存控制器设置为 64 位宽间隔。如果您尝试以其他方式(8 位或 16 位访问)访问这些区域,CPC700 会直接丢弃它们。我们必须能够读/写这些区域,因为重要的 “离散量”(由 Altera 设备控制)映射在那里。
为了访问这些区域,我们需要一个执行 64 位写入的函数。据我所知,在 PowerPC 上执行 64 位写入有两种方法:使用缓存行和使用浮点寄存器。浮点寄存器是一个 64 位大小的寄存器,因此当我们写入它时,整个 64 位都会被写入。问题是您不能在内核中执行浮点运算。由于内核在上下文切换期间不保存浮点寄存器,因此它不允许 FP,如果在内核中执行 FP 操作,则会抛出异常。
在尝试使用缓存行之后,我们决定采用 FP 方式,并添加了以下函数
void out64(__u32 addr, long long *pVal) { __u32 flags, tmp_msr; save_flags(flags); cli(); tmp_msr = __get_MSR(); tmp_msr |= MSR_FP; tmp_msr &= ~(MSR_FE0 | MSR_FE1); __put_MSR(tmp_msr); sysOut64(addr, pVal); __put_MSR(flags & ~(MSR_EE)); restore_flags(flags); } |
_GLOBAL(sysOut64) stwu r1, -DEPTH(r1) mflr r0 stw r31, FP_LOC(r1) stw r0, LR_LOC(r1) mr r31, r1 stfd fr0, FPR_SAVE(r31) /* save floating point reg contents */ lfd fr0,0(r4) stfd fr0,0(r3) eieio lfd fr0, FPR_SAVE(r31) /* restore floating point value */ lwz r4, 0(r1) /* now restore the stack frame */ lwz r0, 4(r4) mtlr r0 lwz r31, -4(r4) mr r1, r4 blr |