5.E1000代码说明

一、E1000初始化

1.main

void main() {
  ...
	#ifdef LAB_NET
    pci_init();
    sockinit();
	#endif    
...
}

2.pci_init

void pci_init() {
  // e1000的寄存器映射到此地址.
  // vm.c maps this range.
  uint64 e1000_regs = 0x40000000L;

  // qemu -machine virt puts PCIe config space here.
  // vm.c maps this range.
  uint32  *ecam = (uint32 *) 0x30000000L;
  
  // look at each possible PCI device on bus 0.
  for(int dev = 0; dev < 32; dev++){
    int bus = 0;
    int func = 0;
    int offset = 0;
    uint32 off = (bus << 16) | (dev << 11) | (func << 8) | (offset);
    volatile uint32 *base = ecam + off;
    uint32 id = base[0];
    
    // 100e:8086 is an e1000
    if(id == 0x100e8086){
      // command and status register.
      // bit 0 : I/O access enable
      // bit 1 : memory access enable
      // bit 2 : enable mastering
      base[1] = 7;
      __sync_synchronize();

      for(int i = 0; i < 6; i++){
        uint32 old = base[4+i];

        // writing all 1's to the BAR causes it to be
        // replaced with its size.
        base[4+i] = 0xffffffff;
        __sync_synchronize();

        base[4+i] = old;
      }

      // tell the e1000 to reveal its registers at
      // physical address 0x40000000.
      base[4+0] = e1000_regs;

      e1000_init((uint32*)e1000_regs);
    }
  }
}

根据memlayout.h所述,xv6的内存布局由hw/riscv/virt.c决定,查看相关代码

https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c,有如下定义

static const MemMapEntry virt_memmap[] = {
...
    [VIRT_PCIE_ECAM] =    { 0x30000000,    0x10000000 },
    [VIRT_PCIE_MMIO] =    { 0x40000000,    0x40000000 },
    [VIRT_DRAM] =         { 0x80000000,           0x0 },
};

0x300000000x40000000的地址分别是PCIE_ECAM和PCIE_MMIO

PCIE_ECAM

ECAM(PCI Express Configuration Access Mechanism)是访问PCIE配置空间一种机制,将 PCI E 设备的配置寄存器映射到内存,使得软件可以像访问普通内存一样访问这些寄存器。

PCIE_MMIO

MMIO(Memory-Mapped I/O),映射 PCIE 设备 I/O 地址空间中的寄存器到内存。可通过读写内存地址来访问这些设备寄存器,实现对设备的控制和数据交换。

PCIE配置空间

https://en.wikipedia.org/wiki/PCI_configuration_space

不明确的

就是设备的控制寄存器,通过对这些寄存器可对pcie设备进行控制

每个控制寄存器大小为32位

注:这里的控制寄存器是设备的,不是主板上的

E1000 PCIe的相关配置在第4章 PCI Local Bus Interface

代码解释

base指向控制寄存器

  1. base[0]中存储Vendor ID和Device ID,根据E1000 手册(95页),82540EM的两个值分别是8086和100e

    image-20240319184517514
posted @ 2024-04-21 00:14  INnoVation-V2  阅读(3)  评论(0编辑  收藏  举报