c1kのモジュールにはmini PICeコネクタでWIFIカードが接続されているので、PCIeのサポートを考えて見ます。
まずメモリからですが、
#define AHB_PCIe0CMD_BASE 0x11400000
#define AHB_PCIe1CMD_BASE 0x11410000
#define AHB_PCIe0_BASE 0x40000000
#define AHB_PCIe1_BASE 0x50000000
#define APB_PCIe0_BASE 0x10010000
#define APB_PCIe1_BASE 0x10030000
#define APB_PCIePHY_BASE 0x10060000
の定義があります。
AHB_PCIe0CMD_BASEはコンフィグレジスタアクセス用のアドレスで、AHB_PCIe0_BASEはPCIeのデバイスのマップ用のアドレス空間です。
HOST-PCIブリッジの提供するコンフィグレジスタのアクセスはチップ毎に仕様が違います。
このSOCではAHB_PCIe0CMD_BASEに直接コンフィグレジスタがマップされるわけではなくて、ここのレジスタを操作する事でコンフィグレジスタが読み書きできます。
APB_PCIe0_BASEはHOST-PICブリッジの本体のアドレスで、APB_PCIePHY_BASEはPHYの設定用のアドレスです。
PHY以外はポート毎になっています。
割り込みは、
#define IRQ_PCIe0_EXT 14
#define IRQ_PCIe0_INT 15
#define IRQ_PCIe1_EXT 16
#define IRQ_PCIe1_INT 17
IRQ_PCIe0_INTはHOST-PCIブリッジの本体の割り込みで、IRQ_PCIe0_EXTがデバイスの割り込みです。
コードを見ていてきがついたのですが、SynopsysのIPのようです。
このコントローラーはHOSTにもDEVICEにもなれるようです。
PCIのBARの設定
PCIやPCIeではOSがコンフィグレジスタのBAR(Base Address Register)を設定する事で、そのアドレスをドライバーがマップしてデバイスにアクセスできます。
デバイスが32ビットの時はBAR0で、64ビットの時はBAR0,BAR1でアドレスを指定します。
BARはメモリアドレス以外にx86由来のIOアドレスも指定できますが、ホストが対応していないとそのデバイスは利用できません。IOだけという事はあまりなくてメモリとIOの二つのアクセスを用意しているケースが多いです。BARは計6本あり、複数のアドレスブロックを指定する事もできます。
デバイスのメモリサイズはさまざまでたとえば4Kバイトと8Kバイトのデバイスが2枚あったとします。
OSはデバイスごとのメモリサイズは以下のような方法で知ることが出来ます。
BAR0に0xffffffffを書き込み、読み出しをすると、4Kバイトのデバイスは0xfffff004が読み出され、8Kのデバイスは0xffffe004が読み出されます。
これはメモリサイズを越えた部分のビットはリード/ライト可能で、メモリサイズのビット部分はリードオンリーとなるためです。下位4ビットは属性ビットです。
OSはこのサイズを元にPICのデバイスマップ用のアドレスに適宜配置してBARを設定します。
デバイスドライバはデバイスのメモリサイズは知っているので、BARからそのサイズをマップします。
BARには物理アドレスが設定されているので、マップする時にはその物理アドレスを仮想アドレスでアクセスできるようにします。