Amiga Buddha 与 Catweasel IDE 控制器寄存器映射全解析:从 Zorro-II 硬件规格到 Linux PATA 驱动实现
【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux
本篇技术指南以 Linux 内核 Documentation/arch/m68k/buddha-driver.rst 为骨架,完整讲解 Amiga Buddha(及 Catweasel Zorro-II 版)IDE 控制器的寄存器映射、Autoconfiguration 流程、速度寄存器时序表与 IRQ 机制,并结合内核源码 drivers/ata/pata_buddha.c 展示这套 1997 年的硬件规格如何在现代 libata 框架下落地。读完你将掌握该控制器的底层寻址规则、ATAPI 命令访问时序选择依据,以及内核中对应驱动的注册与端口初始化方式。
一、背景:Buddha 与 Catweasel 在 m68k 体系中的位置
Buddha 是个体计算机公司(Individual Computers,厂商号 0x1212)为 Amiga 推出的 Zorro-II 扩展板卡,提供 IDE 接口用于挂接硬盘与 CD-ROM;Catweasel Zorro-II 版本则是其衍生板卡,额外提供第三个 IDE 端口。Linux 内核的 Amiga Buddha 与 Catweasel IDE 驱动由 Geert Uytterhoeven 编写,其寄存器规格说明出自 Jens Schönfeld(1997 年 2 月 19 日撰写,同年 5 月 27 日更新),即本仓库 buddha-driver.rst 所保存的原始文档。
在内核侧,该控制器的现代实现是 libata 驱动 drivers/ata/pata_buddha.c,其文件头注释明确标注了演进关系:
- 当前版本基于 1997/2001 年的
buddha.c(作者 Geert Uytterhoeven 等人); - 2018 年由三星电子重构为基于 libata 的
pata_buddha驱动,同时支持 Buddha、Catweasel 与 X-Surf 三类板卡(DRV_NAME "pata_buddha",DRV_VERSION "0.1.1")。
Zorro 厂商与产品 ID 定义在 include/uapi/linux/zorro_ids.h:
#define ZORRO_MANUF_INDIVIDUAL_COMPUTERS 0x1212 #define ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x00, 0) #define ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x17, 0) #define ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x2A, 0)注意其中 Catweasel 的产品号 0x2A 正是十进制 42,与规格文档中"product number: 0(42 for Catweasel Z-II)"的记载完全吻合。
二、Autoconfiguration:板卡如何被 Zorro-II 总线识别
Buddha 的 Autoconfiguration 完全按照 Commodore 官方手册实现,没有使用任何取巧手段(例如从地址方程中省略某些地址线)。文档给出的配置信息如下:
| 属性 | 值 |
|---|---|
| Vendor number | 4626($1212) |
| Product number | 0(Catweasel Z-II 为 42) |
| Serial number | 0 |
| Rom-vector | $1000 |
板卡类型声明为:Z-II 板、容量 64K、不放入 freemem 列表、Rom-Vector 有效、同一卡上无第二个 Autoconfig 板、无空间偏好、支持 "Shutup_forever"。
在 Linux 中,驱动通过 Zorro 设备 ID 表与板卡绑定,见 drivers/ata/pata_buddha.c:
static const struct zorro_device_id pata_buddha_zorro_tbl[] = { { .id = ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA, .driver_data = BOARD_BUDDHA }, { .id = ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL, .driver_data = BOARD_CATWEASEL }, { } }; MODULE_DEVICE_TABLE(zorro, pata_buddha_zorro_tbl);驱动以zorro_driver形式通过 zorro_register_driver() 注册,probe回调在 Zorro 总线枚举出匹配板卡时被调用。X-Surf 因与 zorro8390 网络驱动竞争 modalias,采用late_initcall手动绑定(见 pata_buddha_late_init),Buddha 与 Catweasel 则走常规自动绑定路径。
三、基地址设置:$4a 先行、$48 殿后的两步握手
基地址设置必须分两步完成,与 Amiga Kickstart 的做法一致:
- 将 8 位地址的低半个字节写入 $4a;
- 再将完整字节写入 $48。
写入 $4a 的次数无关紧要,只要 $48 未被触碰即可;一旦 $48 被写入,整块板卡就从 $e8 消失,并映射到刚写入的新地址。文档特别强调:必须确保先写 $4a 再写 $48,否则找到板卡的概率只有 1:16。
值得注意的是,即使板卡映射到 $e8,其本地内存映射(local memory-map)依然生效,这是后续所有寄存器访问的基础。
四、本地内存映射表:从 Autoconfig 空间到 IDE-Select 窗口
板卡的本地内存映射是驱动访问所有功能的核心依据,完整映射如下:
| 地址范围 | 功能说明 |
|---|---|
| $0-$7e | Autoconfig 空间,见 Z-II 文档 |
| $80-$7fd | 保留 |
| $7fe | 速度选择寄存器(Speed-select Register,可读可写,详见下文) |
| $800-$8ff | IDE-Select 0(Port 0,寄存器组 0) |
| $900-$9ff | IDE-Select 1(Port 0,寄存器组 1) |
| $a00-$aff | IDE-Select 2(Port 1,寄存器组 0) |
| $b00-$bff | IDE-Select 3(Port 1,寄存器组 1) |
| $c00-$cff | IDE-Select 4(Port 2,寄存器组 0,Catweasel 独有) |
| $d00-$dff | IDE-Select 5(Port 3,寄存器组 1,Catweasel 独有) |
| $e00-$eff | 本地扩展口;Catweasel Z-II 上 Catweasel 寄存器也映射于此。切勿触碰,请使用 multidisk.device |
| $f00 | 只读、字节访问:Bit 7 反映 IDE Port 0 的 IRQ 线电平 |
| $f01-$f3f | $f00 的镜像 |
| $f40 | 只读、字节访问:Bit 7 反映 IDE Port 1 的 IRQ 线电平 |
| $f41-$f7f | $f40 的镜像 |
| $f80 | 只读、字节访问:Bit 7 反映 IDE Port 2 的 IRQ 线电平(Catweasel 独有) |
| $f81-$fbf | $f80 的镜像 |
| $fc0 | 只写:写入任意值即允许 IDE 端口的 IRQ 传递到 Zorro 总线(详见下文) |
| $fc1-$fff | $fc0 的镜像 |
| $1000-$ffff | Buddha-Rom,位于 ROM 芯片偏移 $1000 处;ROM 芯片的 $0-$fff 不可读。ROM 为字节宽,映射到偶数地址 |
与 pata_buddha 驱动的映射对应关系
这份内存映射在现代驱动中以宏常量形式复现,见 drivers/ata/pata_buddha.c:
#define BUDDHA_BASE1 0x800 #define BUDDHA_BASE2 0xa00 #define BUDDHA_BASE3 0xc00 #define BUDDHA_CONTROL 0x11a #define BUDDHA_IRQ 0xf00 #define BUDDHA_IRQ_MR 0xfc0 /* master interrupt enable */BUDDHA_BASE1/BASE2/BASE3分别对应 IDE-Select 0/2/4 窗口起始地址;BUDDHA_IRQ对应 IRQ 状态寄存器基址 $f00;BUDDHA_IRQ_MR对应 IRQ 总使能寄存器 $fc0。驱动在 probe 时按板卡类型决定端口数量(pata_buddha_probe):
unsigned int nr_ports = (type == BOARD_CATWEASEL) ? 3 : 2;即 Buddha 与 X-Surf 各 2 个端口,Catweasel 3 个端口——与文档"IDE-Select 4/5 为 Catweasel 独有"的描述一致。同时驱动申请内存区域时使用board + BUDDHA_BASE1起 0x800 字节(drivers/ata/pata_buddha.c),对应 64K 板卡空间中 $800 起的 IDE 窗口。
五、中断机制:INT2 轮询与 $fc0 总使能
IDE 端口产生 INT2 中断。驱动可通过读取三个(Buddha 仅两个)状态寄存器 $f00、$f40、$f80 来获知各 IDE 端口的 IRQ 线电平,从而在同一 INT2 下区分是哪个端口、哪个驱动需要服务,便于并行处理多个 I/O 请求。此外,Buddha 与 Catweasel 扩展板还能产生 INT6,并为此准备了独立的 I/O 模块与系统操作员 I/O 模块内存映射。
$fc0 是一个特殊的只写寄存器:写入任意值即允许 IDE 端口的 IRQ 传递到 Zorro 总线。这一机制是为了兼容那些有缺陷或固件存在 bug、启动时会把 IRQ 线拉高的硬盘——若中断始终直通总线,计算机可能无法正常启动。该标志一旦使能便无法再关闭,且软件无法读回其电平状态。
驱动中的中断实现
在 drivers/ata/pata_buddha.c 中,中断路径被完整实现:
- IRQ 使能(pata_buddha_probe):对 Buddha/Catweasel 执行
z_writeb(0, buddha_board + BUDDHA_IRQ_MR),向 $fc0 写入任意值(此处为 0)打开总使能; - IRQ 状态读取(pata_buddha_irq_check):从
ap->private_data指向的端口 IRQ 寄存器读取一个字节,检查ch & 0x80即 Bit 7,与文档"Bit 7 反映 IRQ 线电平"完全对应; - 端口 IRQ 寄存器寻址(pata_buddha_probe):
irqport = buddha_board + BUDDHA_IRQ + i * 0x40,即端口 0/1/2 分别落在 $f00、$f40、$f80,正是文档中的三个状态寄存器地址; - 中断线挂接(pata_buddha_probe):通过
ata_host_activate(host, IRQ_AMIGA_PORTS, ata_sff_interrupt, IRQF_SHARED, &pata_buddha_sht)使用 Amiga 的IRQ_AMIGA_PORTS(对应 INT2)并声明共享中断,与"IDE 端口发出 INT2"的硬件事实一致。
六、速度选择寄存器与访问时序表
速度选择寄存器位于 $7fe,为字节宽寄存器,仅使用高三位(Bit 7 至 Bit 5)。Bit 4 必须恒为 1,以保证与未来 Buddha 版本的兼容性;低四位按定义也应置 1。写寄存器时,表中数值需左移 5 位并与 $1f 做或运算(即置位低 5 位)。
所有时序的共同特征是:Select 与 IOR/IOW 同时上升。IOR/IOW 相对 Zorro 总线时钟约有 30ns 的传播延迟,因此表中的数值并非 71 的整数倍。一个时钟周期为 71ns(PAL 系统 14.18MHz 下精确值为 70.5ns)。
| 值 | Select 时序 | IOR/IOW 时序 |
|---|---|---|
| 0(复位后默认) | 497ns(7 个时钟周期) | 172ns 后(2 个时钟周期) |
| 1 | 639ns(9 个时钟周期) | 243ns 后(3 个时钟周期) |
| 2 | 781ns(11 个时钟周期) | 314ns 后(4 个时钟周期) |
| 3 | 355ns(5 个时钟周期) | 101ns 后(1 个时钟周期) |
| 4 | 355ns(5 个时钟周期) | 172ns 后(2 个时钟周期) |
| 5 | 355ns(5 个时钟周期) | 243ns 后(3 个时钟周期) |
| 6 | 1065ns(15 个时钟周期) | 314ns 后(4 个时钟周期) |
| 7 | 355ns(5 个时钟周期) | 101ns 后(1 个时钟周期) |
默认值 0 的时序与不带加速卡的 Amiga 1200 IDE 端口完全相同(497ns Select、IOR/IOW 172ns 后有效)。
关于时序的两点补充说明:
- 所有 355ns 的快速 Select 访问是否会被延长,取决于系统所用的加速卡:某些总线接口会额外插入两个时钟周期,使整个访问变为 497ns。这既不影响控制器可靠性也不影响性能,因为该情况并不频繁。
- 所有时序均为理论计算值,并经实测确认(作者可据此数出时钟周期)。若系统使用 28.37516MHz 之外的其他振荡器(如 NTSC 频率 28.63636MHz),每个时钟周期会略短于 70ns(差异可忽略)。文档也提醒:虽然超频系统能带来小幅性能提升,但需要 multisync 显示器或显卡,且内置软驱会"发疯",因此不建议用这种方式给 Amiga 调优。
七、A6=1 镜像访问:命令访问的固定慢速通道
IDE 端口由地址线 A2 至 A4 驱动,与 Amiga 1200/4000 的 IDE 端口一致,因此已有驱动可以轻松移植到 Buddha。由于每个字都被镜像一次,一次move.l会从 IDE 端口的同一地址轮询出两个字;虽然无法使用movem,但也没必要——这种技术只能加速 68000 系统,68020 + fastmem 的系统用move.l反而更快。
关键特性:若使用 A6=1 的 IDE 端口镜像寄存器(例如端口 0 寄存器组 0 的 $840),Buddha 将忽略速度寄存器中选定的速度,固定以 780ns 进行一次访问。文档建议这些寄存器用于对硬盘/CD-ROM 的命令访问,因为命令访问为字节宽,按 ATA-X3T9 手册必须放慢执行。对应地,以 A6=1 访问 IDE 寄存器(如 $84x)时,时序恒为模式 0 的 8 位兼容模式:781ns Select、IOR/IOW 在 4 个时钟周期(314ns)后有效,无论速度寄存器选择了什么。
八、Buddha 与 Catweasel 的软件兼容性设计
为了让软件能同时兼容 Buddha 与 Catweasel Z-II,Buddha 在行为上完全模拟一台"第三个 IDE 端口未接设备"的 Catweasel Z-II:
- IRQ 寄存器 $f80 在 Buddha 上始终显示"无 IRQ";
- 对第三个 IDE 端口的访问在 Buddha 上会进入"数据 Nirwana"(即无实际效果)。
在驱动侧,这一设计通过pata_buddha_zorro_tbl将两类板卡映射到不同枚举值(BOARD_BUDDHA/BOARD_CATWEASEL),统一使用同一套pata_buddha_ops,仅端口数量不同(见 drivers/ata/pata_buddha.c),从而最大化代码复用。
九、端口寄存器布局与数据搬运:地址线 A2-A4 的代价
由于 IDE 端口由地址线 A2-A4 驱动(每 4 字节一个寄存器槽位),驱动在 pata_buddha_probe 中按base + 2 + n * 4的步进摆放 libata 的 I/O 地址:
ap->ioaddr.data_addr = base; ap->ioaddr.error_addr = base + 2 + 1 * 4; ap->ioaddr.feature_addr = base + 2 + 1 * 4; ap->ioaddr.nsect_addr = base + 2 + 2 * 4; ap->ioaddr.lbal_addr = base + 2 + 3 * 4; ap->ioaddr.lbam_addr = base + 2 + 4 * 4; ap->ioaddr.lbah_addr = base + 2 + 5 * 4; ap->ioaddr.device_addr = base + 2 + 6 * 4; ap->ioaddr.status_addr = base + 2 + 7 * 4; ap->ioaddr.command_addr = base + 2 + 7 * 4;数据区(data_addr)在base,控制/备用状态区在base + BUDDHA_CONTROL(0x11a)。由于硬件不支持 DMA,驱动仅声明ap->pio_mask = ATA_PIO4,并设置ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY标志(drivers/ata/pata_buddha.c)。
数据搬运采用自定义的 pata_buddha_data_xfer:以字为单位用raw_insw/raw_outsw传输(对应文档中"一次 move.l 轮询两个字"的 16 位数据通路),并单独处理可能剩余的 1 字节尾部。模式设置则使用 pata_buddha_set_mode,将所有设备统一配置为XFER_PIO_0——与文档中"速度寄存器决定硬件访问时序"的分工不同,驱动侧不再做运行时传输模式切换。
十、内核配置:如何启用 Buddha/Catweasel 支持
驱动对应内核配置项在 drivers/ata/Kconfig:
config PATA_BUDDHA tristate "Buddha/Catweasel/X-Surf PATA support" depends on ZORRO help This option enables support for the IDE interfaces on the Buddha, Catweasel and X-Surf expansion boards on the Zorro expansion bus. It supports up to two interfaces on the Buddha, three on the Catweasel and two on the X-Surf. If unsure, say N.要点:
- 依赖
ZORRO,仅在启用 Zorro 总线(m68k Amiga 平台)时可编译; - 可编译为模块(tristate);
- 支持数量:Buddha 2 个接口、Catweasel 3 个、X-Surf 2 个。
在 Amiga 平台的默认配置 arch/m68k/configs/amiga_defconfig 中,该驱动被静态启用:
CONFIG_PATA_GAYLE=y CONFIG_PATA_BUDDHA=yCONFIG_PATA_GAYLE是 Amiga 1200/4000 板载 IDE 的驱动,与 Buddha 同属 m68k/Amiga IDE 生态,两者并列出现说明 Amiga 默认配置即覆盖了板载与扩展板两条 IDE 路径。
结语
从 1997 年的硬件规格文档到 2018 年重构的 libata 驱动,Buddha/Catweasel 的寄存器映射始终保持一致:$800/$a00/$c00 的 IDE-Select 窗口、$f00/$f40/$f80 的 IRQ 状态位、$fc0 的一次性中断总使能,以及 $7fe 速度寄存器中"高三位 + 低五位掩码"的编码方式,都被 pata_buddha.c 逐一复现。理解这份寄存器映射,不仅有助于阅读 Amiga 时代的第三方驱动代码,也能为在现代 Linux 上调试 Zorro 总线 ATA 设备提供最底层的参考依据。
【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考