ChrisOS Research ProjectOperating systems · language systems · graphics · machine emulation
DOCUMENTATION ARCHIVEMAIN BRANCH
ChrisOS/Referência de fonte: SYS/DRV/VIRTIOGPU.CC

Referência de fonte: SYS/DRV/VIRTIOGPU.CC

Registro determinístico da fonte. O conteúdo completo do arquivo é reproduzido abaixo; esta página não substitui a interpretação arquitetural dos capítulos autorais.

Identidade do arquivo

Campo Valor
Path SYS/DRV/VIRTIOGPU.CC
Lines 289
Bytes 5073
SHA-256 6c12573e82c7e812b857ee04e0a0c8dc30516ac139cf370e5be8736c6c9b3740
ChrisOS revision da3df29cb397932c43d32373871fb9380e688ade

Dependências sintáticas detectadas

Linha Include
— Nenhum include de preprocessor detectado.

Símbolos detectados

Linha Símbolo
24 find_gpu
43 enable_dev
50 take_caps
97 dev_status
101 features_ok
115 setup_queue
167 clear_cmd
178 kick
205 cmd4
209 send_create
219 send_attach
230 send_scanout
239 gpu_init
276 main

Fonte completa

O bloco seguinte é o arquivo textual integral na revisão indicada. Não há elisão, abreviação ou paráfrase.

int g_bus;
int g_slot;
int g_cwin;
int g_coff;
int g_nwin;
int g_noff;
int g_mult;
int g_q;
int g_cmd;
int g_fb;
int g_qlo;
int g_qhi;
int g_clo;
int g_chi;
int g_flo;
int g_fhi;
int g_idx;
int g_qnote;
int g_w;
int g_h;
int g_pages;
int g_bytes;

int find_gpu() {
  int id;
  int dev;
  g_bus = 0;
  g_slot = 0;
  while (g_slot < 32) {
    id = drv_pci(g_bus, g_slot, 0, 0);
    if ((id & 65535) == 0x1AF4) {
      dev = id >> 16;
      dev = dev & 65535;
      if (dev == 0x1050) {
        return 1;
      }
    }
    g_slot = g_slot + 1;
  }
  return 0;
}

int enable_dev() {
  int cmd;
  cmd = drv_pci(g_bus, g_slot, 0, 4);
  cmd = cmd | 6;
  return pci_write(g_bus, g_slot, 0, 4, cmd);
}

int take_caps() {
  int off;
  int cap;
  int vndr;
  int next;
  int typ;
  int bar;
  int cfg;
  int win;
  off = drv_pci(g_bus, g_slot, 0, 0x34);
  off = off & 255;
  g_cwin = 0 - 1;
  g_nwin = 0 - 1;
  g_mult = 0;
  while (off > 0) {
    cap = drv_pci(g_bus, g_slot, 0, off);
    vndr = cap & 255;
    next = cap >> 8;
    next = next & 255;
    typ = cap >> 24;
    typ = typ & 255;
    if (vndr == 9) {
      bar = drv_pci(g_bus, g_slot, 0, off + 4);
      bar = bar & 255;
      cfg = drv_pci(g_bus, g_slot, 0, off + 8);
      win = bar_map(g_bus, g_slot, 0, bar);
      if (typ == 1) {
        g_cwin = win;
        g_coff = cfg;
      }
      if (typ == 2) {
        g_nwin = win;
        g_noff = cfg;
        g_mult = drv_pci(g_bus, g_slot, 0, off + 16);
      }
    }
    off = next;
  }
  if (g_cwin < 0) {
    return 0;
  }
  if (g_nwin < 0) {
    return 0;
  }
  return 1;
}

int dev_status(int v) {
  return mmio_w8(g_cwin, g_coff + 20, v);
}

int features_ok() {
  int st;
  mmio_w32(g_cwin, g_coff, 1);
  mmio_w32(g_cwin, g_coff + 8, 1);
  mmio_w32(g_cwin, g_coff + 12, 1);
  dev_status(11);
  st = mmio_r8(g_cwin, g_coff + 20);
  st = st & 8;
  if (st == 0) {
    return 0;
  }
  return 1;
}

int setup_queue() {
  int ulo;
  g_w = disp_w();
  g_h = disp_h();
  if (g_w > 1920) {
    g_w = 1920;
  }
  if (g_h > 1080) {
    g_h = 1080;
  }
  if (g_w < 1) {
    g_w = 320;
  }
  if (g_h < 1) {
    g_h = 200;
  }
  g_bytes = g_w * g_h * 4;
  g_pages = (g_bytes + 4095) / 4096;
  g_q = dma_alloc(1);
  g_cmd = dma_alloc(1);
  g_fb = dma_alloc(g_pages);
  if (g_q < 0) {
    return 0;
  }
  if (g_cmd < 0) {
    return 0;
  }
  if (g_fb < 0) {
    return 0;
  }
  g_qlo = dma_lo(g_q);
  g_qhi = dma_hi(g_q);
  g_clo = dma_lo(g_cmd);
  g_chi = dma_hi(g_cmd);
  g_flo = dma_lo(g_fb);
  g_fhi = dma_hi(g_fb);
  mmio_w16(g_cwin, g_coff + 22, 0);
  mmio_w16(g_cwin, g_coff + 24, 4);
  mmio_w32(g_cwin, g_coff + 32, g_qlo);
  mmio_w32(g_cwin, g_coff + 36, g_qhi);
  mmio_w32(g_cwin, g_coff + 40, g_qlo + 64);
  mmio_w32(g_cwin, g_coff + 44, g_qhi);
  ulo = g_qlo + 2048;
  mmio_w32(g_cwin, g_coff + 48, ulo);
  mmio_w32(g_cwin, g_coff + 52, g_qhi);
  mmio_w16(g_cwin, g_coff + 28, 1);
  g_qnote = mmio_r16(g_cwin, g_coff + 30);
  g_noff = g_noff + g_qnote * g_mult;
  dev_status(15);
  return 1;
}

int clear_cmd() {
  int i;
  i = 0;
  while (i < 16) {
    dma_w32(g_cmd, i * 4, 0);
    dma_w32(g_cmd, 256 + i * 4, 0);
    i = i + 1;
  }
  return 0;
}

int kick(int len) {
  int spins;
  int used;
  dma_w32(g_q, 0, g_clo);
  dma_w32(g_q, 4, g_chi);
  dma_w32(g_q, 8, len);
  dma_w32(g_q, 12, 65537);
  dma_w32(g_q, 16, g_clo + 256);
  dma_w32(g_q, 20, g_chi);
  dma_w32(g_q, 24, 64);
  dma_w32(g_q, 28, 2);
  g_idx = g_idx + 1;
  dma_w32(g_q, 64, g_idx * 65536);
  mmio_w16(g_nwin, g_noff, 0);
  spins = 0;
  while (spins < 100000) {
    used = dma_r32(g_q, 2048);
    used = used >> 16;
    used = used & 65535;
    if (used == g_idx) {
      return dma_r32(g_cmd, 256);
    }
    spins = spins + 1;
  }
  return 0;
}

int cmd4(int at, int v) {
  return dma_w32(g_cmd, at, v);
}

int send_create() {
  clear_cmd();
  cmd4(0, 0x0101);
  cmd4(24, 1);
  cmd4(28, 1);
  cmd4(32, g_w);
  cmd4(36, g_h);
  return kick(40);
}

int send_attach() {
  clear_cmd();
  cmd4(0, 0x0106);
  cmd4(24, 1);
  cmd4(28, 1);
  cmd4(32, g_flo);
  cmd4(36, g_fhi);
  cmd4(40, g_bytes);
  return kick(48);
}

int send_scanout() {
  clear_cmd();
  cmd4(0, 0x0103);
  cmd4(32, g_w);
  cmd4(36, g_h);
  cmd4(44, 1);
  return kick(48);
}

int gpu_init() {
  int resp;
  g_idx = 0;
  if (find_gpu() == 0) {
    return 0;
  }
  enable_dev();
  if (take_caps() == 0) {
    return 0;
  }
  dev_status(0);
  dev_status(1);
  dev_status(3);
  if (features_ok() == 0) {
    return 0;
  }
  if (setup_queue() == 0) {
    return 0;
  }
  resp = send_create();
  if (resp != 0x1100) {
    return 0;
  }
  resp = send_attach();
  if (resp != 0x1100) {
    return 0;
  }
  resp = send_scanout();
  if (resp != 0x1100) {
    return 0;
  }
  if (gpu_arm(g_q, g_cmd, g_fb, g_w, g_h, g_nwin, g_noff) != 0) {
    return 0;
  }
  return 1;
}

void main() {
  viewport(220, 40);
  if (gpu_ready() == 1) {
    text(4, 12, "gpu scanout", 0x00E0FFE0);
  } else if (gpu_init() == 1) {
    text(4, 12, "virtio-gpu", 0x00E0FFE0);
  } else {
    text(4, 12, "no gpu", 0x00FF8080);
  }
  while (1) {
    wait(100);
  }
}

Papel deste registro

O atlas garante rastreabilidade arquivo-a-arquivo. Responsabilidade, invariantes, ownership, concorrência, segurança, desempenho e interação entre subsistemas pertencem aos capítulos autorais e devem citar este arquivo quando aplicável.

Registro do documento ID: source-6c12573e82c7e812 Reviewed source: da3df29cb397 Class: generated-source-reference