【问题标题】:What is the purpose of invalidating D-cache when D-cache is off?当 D-cache 关闭时,使 D-cache 无效的目的是什么?
【发布时间】:2020-11-29 01:12:10
【问题描述】:

在 Linux 内核源代码 arch/arm64/kernel/head.S 中,引导要求状态是引导加载程序必须在 D-cache 关闭的情况下进入:

/*
 * Kernel startup entry point.
 * ---------------------------
 *
 * The requirements are:
 *   MMU = off, D-cache = off, I-cache = on or off,
 *   x0 = physical address to the FDT blob.
 ...
 */

然后,在preserve_boot_args() 函数中,在将参数加载到boot_args 数组后调用使D-cache 的一个区域无效

SYM_CODE_START_LOCAL(preserve_boot_args)
    mov x21, x0             // x21=FDT

    adr_l   x0, boot_args           // record the contents of
    stp x21, x1, [x0]           // x0 .. x3 at kernel entry
    stp x2, x3, [x0, #16]

    dmb sy              // needed before dc ivac with
                        // MMU off

    mov x1, #0x20           // 4 x 8 bytes
    b   __inval_dcache_area     // tail call
SYM_CODE_END(preserve_boot_args)

如果D-cache关闭,为什么D-cache行需要失效?

【问题讨论】:

  • 当缓存关闭时,它们仍然响应命中(即,如果它们没有失效并且软件写入缓存中已经存在的行,则该行在缓存中被修改并且永远不会写入内存)。有一个 ARM 文档说明了这一点。我的假设是:引导加载程序可能已禁用但未使缓存无效,并且由于boot_args 缓冲区的地址是任意的,因此固件/引导加载程序缓存的可能性很小。如果boot_args 最终位于先前访问的内存区域中,则会发生这种情况。因此无效。
  • 它是否有可能被失效以便在某个时候可以打开?
  • @MargaretBloom 那么你的意思是如果稍后打开缓存,修改后的缓存行会写入内存?我不知道这个“D-cache is off”是什么意思。从这个链接(developer.arm.com/documentation/ddi0344/b/level-2-memory-system/…)听起来 D-cache 关闭意味着数据直接进出内存。
  • @ChanKim 当 D-cache 关闭时,不会在缓存中获取新行但不会刷新缓存,它仍然保留其数据。只要没有命中缓存,数据就会绕过缓存。如果稍后打开缓存,它包含的行将根据替换策略写入内存。如果您缓存了一个位置并禁用了缓存,则该位置将继续从缓存中提供(反之,以前未缓存的位置将绕过它)。
  • @MargaretBloom“如果它们没有失效并且软件写入缓存中已经存在的行,则该行在缓存中被修改并且永远不会写入内存。有一个 ARM 文档说明了这一点”。你能指点那个医生吗?如果您所说的(“从未写入内存”)属实,则意味着任何写入内存都必须伴随着缓存闪存。否则有些数据可能永远不会到达内存。

标签: assembly caching linux-kernel arm64 cpu-cache


【解决方案1】:

为什么 D-cache 行需要失效,如果 D-cache 是 关了吗?

这些寄存器stp x21, x1, [x0] \ stp x2, x3, [x0, #16]boot_args地址开始写入内存。缓存已关闭,因此数据将直接写入内存。

D-Cache 不受此类写入的影响。所以 D-Cache 要么包含它在关闭之前保存的数据,要么包含一些垃圾(如果芯片通电)。

通过使boot_args + 0x20 区域无效,您可以保证如果启用了 D-cache,稍后会从内存中读取写入的数据。

考虑场景:

  • 写入区域未失效
  • 稍后启用缓存
  • D-Caches 的行包含来自 [boot_args .. boot_args + 0x20] 内存区域的数据
  • [boot_args ..boot_args + 0x20] 内存区域被读回寄存器

所以在这种情况下,缓存会命中,缓存中的“垃圾”会进入寄存器,而不是从内存中获取的“正确”数据。

【讨论】:

    猜你喜欢
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 2013-07-16
    相关资源
    最近更新 更多