既然我们了解了显示屏的工作原理,现在让我们来看看这款主机的内部结构。 如果你拿到主板,你会看到三个大芯片,其中一个是 CPU CTR。 这是一个大型系统级芯片(SoC),它承载了整个系统(存储和RAM除外)。
CPU CTR 沿袭了任天堂之前便携式主机的设计方法。 也就是说,将所有工程设计都压缩到一个单一的区块中。 这样做可以减少假冒产品的生产,保护敏感组件并改善散热。
在实际的CPU方面,任天堂再次与他们的老朋友ARM合作,生产他们的下一代核心。 ARM传统的授权模式(基于提供可综合设计)允许任天堂根据自己的需求塑造CPU,包括将其集成到大型不透明的SoC中。 最终,ARM为他们提供了一个相对陈旧但经过大幅升级的产品。 他们的选择是ARM11,它是ARM9(在Nintendo DS中出现)的继任者。 更具体地说,是MPCore变体,这是ARM的首个同质多核解决方案。
任天堂利用ARM的设计,打造了一个包含两个ARM11核心的ARM11 MPCore集群。 三年后,随着"New"3DS 的到来,SoC被扩展为包含四个ARM11核心。 这些影响将在适当的时候解释。 因此,在此之前,让我们先分析一下新的CPU核心为这款主机带来了什么。
一个标志性产业
ARM11 系列处理器于 2002 年问世。 当时,手机运行 Java ME 应用程序,并以拥有_真实旋律_的铃声而自豪。 在接下来的几年里,ARM11 取代了流行的ARM9、昙花一现的ARM10和英特尔的XScale,成为移动CPU领域的主力军。 XScale是StrongARM的延续,英特尔后来将其出售,以专注于"低功耗"x86 CPU——如果他们知道移动市场会飞速发展就好了!

一部诺基亚5230(2009年)、一部红色3DS(2011年)和一部树莓派Model B(2012年),它们都搭载了ARM11。
最终,ARM11因其为2006-2009年一代智能手机提供动力而闻名。 这一代手机融合了键盘、翻盖和全触屏设计。 如果你曾拥有诺基亚N95、5230或第一代iPhone,那么你就使用过ARM11处理器。 许多高端相机、GPS或类似外设也采用了这种处理器。 有趣的是,RIM和三星等其他制造商一直沿用英特尔XScale直到2009年。 另外值得一提的是,ARM11也是第一代树莓派的CPU选择。
到了任天堂采用ARM11的时候,其创造者ARM公司已经推出了Cortex-A系列来接替它。 这完全在意料之中,因为任天堂的模式更注重成本效益,而非前卫的CPU。 从另一个角度来看,节省CPU成本可以让他们将预算集中在主机其他方面,你很快就会明白。
新方言......
伴随着闪亮的新CPU,一套新的指令集——ARMv6——也应运而生。
从程序员的角度来看,ARMv6指令集架构(ISA)通过一套新的向量指令和多核支持进行创新。 新的向量指令集由SIMD指令组成,这些指令可以一次性操作四组8位值或两组16位值(使用现有的32位寄存器)。 然而,这些指令只能操作整数(不能操作浮点数)。 此外,新的多核指令包含"存储"和"加载"操作码,并特别注意了同步(这在多个CPU使用相同的内存位置时至关重要) 。
总而言之,这对于一个新的芯片系列来说可能看起来并不那么繁荣,但请记住,ARM的CPU会说多种"语言"。 对于基于ARM11的内核,你将获得:
- 主要的32位ISA,称为ARMv6。
- 一个名为Thumb的压缩替代方案。 它的指令以16位字的形式存在。 如果你想了解更多,我在Game Boy Advance和Nintendo DS的文章中都有介绍,因为它在那些主机中占有重要地位。
- Jazelle,一个Java字节码解释器,尽管大部分已被遗忘且未使用。 我在Wii的文章中提到过一些。
- 捆绑在内核中的任何扩展。 例如,MPCore包含一个矢量浮点协处理器(VFP),带有额外的指令来控制该协处理器。 我稍后会详细介绍。
为了减少混淆,ARM倾向于将所有这些都用一个单一的命名法进行打包。 例如,对于ARM11 MPCore操作码,ARM将此变体称为ARMv6k指令集。
......以及碎片化的分发
尽管如此,扩展和替代指令集的采用最终使得针对通用ARM硬件的开发者面临非常复杂的情况,你只需看看为Linux发行版设计的无数ARM移植版本就知道了。
Debian作为最流行的发行版之一,试图通过并行开发两个移植版本来解决这些差异:
armel:为了广泛兼容性(ARMv4T及更高版本)。armhf:通过VFP扩展进行加速,但仅兼容ARMv7及更高版本。
然而,随着Raspberry Pi(由ARMv6驱动并由VFP加速)的到来,两者都被认为不可接受。 因此,开发了一个名为"Raspbian"的非官方移植版本,为ARMv6 CPU提供了一个VFP加速版本 。 即便如此,这种趋势仍在继续:几年后,随着ARMv8和AArch64的到来,Debian又衍生出了另一个移植版本arm64,针对新的64位ISA进行了优化。
我不记得在x86上见过这种迷宫(尽管x86 SIMD扩展的采用至少可以说并不一致),但至少现在情况变得更有序了。 AArch64统一了许多扩展并放弃了替代模式(再见了,Thumb和Jazelle)。
核心功能
...... ......这只是一个快速的题外话,让我们回到分析3DS CPU的内容!
对于这项研究,我们可以将ARM11 MPCore分为两个区域:
- 构成集群的MP11核心。
- 高级可扩展接口(AXI)总线,这是一项连接核心并与外部世界接口的新发明。
现在我们先从核心开始,然后再检查AXI总线。
原始的MPCore
随初代3DS首次亮相的首个ARM11 MPCore变体包含两个核心。 每个核心都称为MP11,运行频率为268 MHz 。
除了实现ARMv6k指令集外,MP11还具有8级流水线 ,并辅以两级分支预测:"动态"(基于先前的执行)和"静态"(仅基于当前指令)。 总体而言,我感觉这些新增特性是新设计理念的一部分,它最终将使标志性的条件执行机制过时,不过我们直到下一代才会真正察觉到这一点。
此外,自ARM946E-S CPU以来,ARM一直配备一个名为CP15的系统控制协处理器。 这次,它提供了内存管理(MMU功能)以及输出MPCore集群信息的寄存器内存。
现在,不再有紧密耦合内存(TCM)。 然而,它有16 KB的指令缓存和16 KB的数据缓存,这种模式的改变类似于同代其他系统。 如果你好奇,这个L1缓存是4路组相联的。
最后,每个核心都包含一个名为向量浮点协处理器(Vector Floating-point Coprocessor)的协处理器,也称为"VFP",在ARM11中则称为"VFP11"。 它加速浮点数的算术运算,包括32位单精度(即 float)和64位双精度(即 double)两种类型 。 不过它并非一个大型协处理器,因为它的寄存器文件由三十二个32位寄存器组成,因此双精度数会占用两个寄存器。 无论如何,这个处理器实现了VFPv2指令集并遵循IEEE 754标准。 考虑到前几代的困难,后者是一个受欢迎的决定。
"新"MPCore
随着2014年新3DS的发布,引入了一个新的SoC(CPU LGR),随之而来的是一次豪华的CPU升级。
最明显的变化是,现在我们有四个MP11核心,而不是两个。 然而,这带来的影响并非简单就能阐明,但我们会在适当的时候看到它们。
第二个变化是,CPU集成了2MB的L2缓存,由四个核心共享。 这种类型的缓存是16路关联的,它预示着四个核心可以同时访问它。 如果你想了解更多,我在Xbox 360的文章中介绍过关联缓存。
接下来,所有核心现在都运行在804 MHz(是原始速度的三倍,这无疑会引起一些人的注意)。
AXI总线

任天堂3DS AXI实现互连不同类型组件的示例。 在这里,CPU和DMA充当主设备,而RAM节点是从设备。 然而,角色可以根据需要改变。
无论是两个还是四个MP11核心,所有这些都通过ARM自豪地开发的一种流行总线——高级可扩展接口(AXI)进行连接。 该协议是AMBA3模型的一部分,它是我们在Wii和Wii U(两者都搭载ARM9 CPU)中见过的原始AMBA修订版的继任者。 通过这种方式,ARM将AXI模型作为系统级芯片(SoC)的关键构建块。
一般来说,AXI模型提供了一套用于连接具有不同带宽要求的组件的协议。 它们可以自由选择任何特定的拓扑结构,例如PlayStation 3的令牌环模型或Xbox 360的网格解决方案。 现在,在Nintendo 3DS中,我们发现了总线和星形设计的结合。
遵循AMBA互连节点的方法,将存在主从层次结构来表示哪个实体负责。 主组件(通常是CPU核心)将是向从设备(即内存和I/O块)发送命令的实体。
此外,AXI网络可以通过一个专用模块(称为AXI互连)作为总线矩阵进行仲裁。 这就是我们在MPCore中发现的,它依赖于独立的64位总线。 通过这种方式,网络解决了高带宽组件的拥塞问题(这是PlayStation 2等主机曾经面临的问题)。 此外,多个主设备可以使用单独的通道与从节点通信,以避免等待其他主设备完成。 如果这还不够,传统的增强功能,如突发事务,也得到了实现,MP11核心就利用了这一点。
在3DS的案例中,AXI互连容纳在一个更大的模块中,称为窥探控制单元(SCU),它还负责自动维护MP11核心之间的一级缓存一致性。
还有其他CPU吗?
到目前为止,我一直将MPCore视为该系统中唯一的CPU,原因是在这项分析中混合使用不同的CPU可能会使其变成一篇难以理解的文章。 也就是说,直到现在。
事实是,任天堂对这款主机有额外的要求。 他们想要一个完善的安全系统,同时也希望能够即时将主机变成Nintendo DSi或GBA。 因此,为了所有这些,他们最终捆绑了三个不同的CPU包——其中一个就是前面提到的ARM11。 另外两个则被很好地隐藏起来,游戏完全不知道它们的存在。 事实上,像Citra这样的3DS模拟器根本不关心它们。

任天堂3DS与其前身(任天堂DS Lite)并列,后者已成为一个普遍的参照物。
但我们确实关心! 因此,以下是该系统所包含的完整CPU列表:
- 我们刚刚看到的ARM11 MPCore。
- 一个来自任天堂DS时代的ARM946E-S。 它被视为一个秘密协处理器,仅由操作系统管理。 此外,每当执行DS或DSi游戏时,它就成为主处理器。
- 借助于其捆绑的CP15协处理器,系统内置了内存保护单元(MPU)。 这将保护CPU免受随意执行内存中任何位置代码的侵害。
- 一个来自Game Boy Advance时代的ARM7TDMI。 它是一个相对被忽视的CPU,除非正在玩DS或DSi游戏,在这种情况下它充当协处理器。 然而,在运行Game Boy Advance游戏这种特殊情况下,主执行权将由该CPU负责。
不幸的是,或者出于显而易见的原因,这三个CPU从未同时可用。 相反,主机有三种运行模式:
- 原生3DS模式:ARM11 MPCore执行3DS游戏,而ARM946E-S处理I/O和安全。 另一方面,ARM7处于关闭状态。
- 任天堂DSi模式:ARM946E-S和ARM7TDMI以多处理器配置运行,以执行任天堂DS或DSi游戏。 就像其前身一样,ARM7TDMI对I/O有更大的访问权限。 同时,ARM11 MPCore将在后台工作,以模拟缺失和重新定位的DS硬件(实时时钟、电源管理、手柄、GBA/DS PPU显示等)。
- Game Boy Advance模式:ARM7TDMI是唯一执行指令的CPU(99%的情况下,指令来自GBA游戏)。 ARM11 MPCore和ARM9,两者仍在"原生3DS模式"的能力范围内,将在后台运行。
如果你仔细思考,任天堂3DS最终总共包含了四个处理器(两个MP11核心 + 一个ARM9 + 一个ARM7),而在新3DS中更是达到了惊人的六个。 这复杂程度真是令人咋舌? 这真是太复杂了,不是吗?幸运的是,这个系统没有遭受世嘉土星那样的复杂性困扰,这要归功于任天堂和ARM的工程设计。 毕竟,3DS开发者只需要处理MPCore。
由于ARM9和ARM7主要用于I/O、安全和向下兼容性(这些都不需要开发者关注),我将在本文的后续章节中讨论它们。 但如果你想了解更多关于ARM7和ARM9的设计,我分别在之前的文章(Game Boy Advance和Nintendo DS)中写过。
多核通信
我想现在的问题是,CPU和核心如何相互通信? 嗯,最简单的方法是共享RAM......但你也可以尝试更高效的方法,这取决于尝试通信的核心:
- 在ARM11核心间通信中,一个核心可以通过写入其
软件中断寄存器向另一个核心发送中断 。 - 在ARM11<->ARM9或ARM9<->ARM7通信中,采用了与Nintendo DS相同的FIFO模型。 此外,ARM11<->ARM9 FIFO也称为"PXI"。
可用内存
拥有三个不同的CPU也意味着内存布局不会简单,特别是如果你关心安全的话。
长话短说,我们有以下内存块:
- 从开发者的角度来看,系统提供128 MB的FCRAM。 新3DS将其增加到256 MB。 其余部分对游戏来说是冗余的。
- 主要出于安全原因,ARM11还配备了一个512 KB的快速SRAM块。 ARM9也获得了一个1 MB的SRAM块(在新3DS中为1.5 MB)。
- 继承了任天堂DS的模型,ARM9也包含紧密耦合内存(TCM)。 具体来说,有32 KB用于指令,16 KB用于数据。
发现了一种新型内存
任天堂3DS包含其前身通用内存的32倍,这固然令人高兴,但"FCRAM"又是什么呢? 它与其他标准有什么不同吗?
嗯,快速周期DRAM(FCRAM)是又一项RAM发明,这次由富士通和东芝于2002年开发。 作为DRAM技术(即SDRAM、EDO DRAM、RDRAM等)的替代品,FCRAM在非连续读取方面表现出色,其延迟低于DRAM 。 这样做是为了复制更昂贵的SRAM所提供的性能。
FCRAM通过提供内存阵列的改进设计,直接与DDR DRAM竞争。 它没有在其上增加更多电路,而是将阵列分成更小的子块,然后使用3级流水线进行访问 。 通过这样做,在随机位置的读写变得更快。 这些改变在设计时仍然考虑了向下兼容性。 因此,FCRAM与DDR DRAM控制器兼容(因此,其全称是"DDR FCRAM")。
更快的内存传输
MPCore和AMBA总线的发明者碰巧也提供了一个名为CoreLink的DMA控制器品牌,而任天堂是其忠实客户。 因此,3DS在其SoC中捆绑了多个CoreLink DMA-330块也就不足为奇了 。
这些DMA特别连接到AXI总线并充当主设备。 每个DMA都可以在通过AMBA协议(无论是AXI还是较慢的APB)互连的两个从设备之间传输数据 。
任天堂在ARM9旁边安装了一个CoreLink DMA,这被称为XDMA,它提供多达四个通道(因此,最多可进行四次并发传输)。 在ARM11块旁边还有另一个DMA,这次被称为CDMA,它提供多达八个通道。 随着新3DS的到来,在ARM11块(现在是四核集群)旁边又安装了一个CoreLink DMA-330。
编程
综上所述,如何为这种非正统的CPU配置系统编程呢? 公平地说,非常规系统对视频游戏开发者来说并不陌生。 但在这种情况下,3DS程序员只能访问ARM11 MPCore。 此外,一旦你阅读到"操作系统"部分,你就会知道这个集群的能力会受到进一步限制。
无论主机版本如何,程序员都将其算法基于多线程模型:程序使用线程将指令序列分组,然后由操作系统根据需要将这些线程调度到物理核心。 这个标准曾经是Xbox 360软件的新奇之处,它提供了一层抽象,使开发者无需编写仅兼容固定数量和类型CPU核心的软件。
处理"新"硬件
由于新3DS与原始规格有很大不同,任天堂设置了一个薄薄的兼容层,以使旧3DS游戏无需手动干预即可在新硬件上运行。
本质上,当在新3DS主机上启动游戏时,游戏的代码会指定它是否专门针对新模型。 如果是,操作系统将激活所有新特性(更快的时钟速度、额外的RAM和L2缓存的使用),供该游戏享受。 如果不是,操作系统将保持其独占硬件处于非激活状态,直到用户退出游戏,这样游戏就可以安全地假设它正在旧硬件上运行,并且不会出现问题。
为了继续支持旧3DS,游戏可以用两个代码库打包(一个用于"新"型号,另一个用于"旧"型号)。 由游戏工作室决定是同时支持旧3DS和新3DS,还是只支持新3DS。
你可能想知道新3DS所包含的其余独占硬件(即额外的ARM11核心和DMA)会发生什么。 嗯,要正确理解其原理,我会在你阅读到"操作系统"部分时解释这一点,但我恐怕你不会喜欢这个答案!




