aboutsummaryrefslogtreecommitdiff
path: root/pk/device.c
blob: 73cd71d68e801dc112233fee1678c54793845374 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include "pk.h"
#include <string.h>
#include <stdlib.h>

static uint64_t tohost_sync(unsigned dev, unsigned cmd, uint64_t payload)
{
  uint64_t tohost = (uint64_t)dev << 56 | (uint64_t)cmd << 48 | payload;
  uint64_t fromhost;
  __sync_synchronize();
  while (swap_csr(tohost, tohost) != 0);
  while ((fromhost = swap_csr(fromhost, 0)) == 0);
  __sync_synchronize();
  return fromhost;
}

void enumerate_devices()
{
  char buf[64] __attribute__((aligned(64)));

  for (int dev = 0; dev < 256; dev++)
  {
    tohost_sync(dev, 0xFF, (uintptr_t)buf << 8 | 0xFF);
    if (buf[0])
    {
      printk("device %d: %s\n", dev, buf);

      for (int cmd = 0; cmd < 255; cmd++)
      {
        tohost_sync(dev, 0xFF, (uintptr_t)buf << 8 | cmd);
        if (buf[0])
          printk("  command %d: %s\n", cmd, buf);
      }
    }
  }
}

void disk_test()
{
  struct disk_req {
    uint64_t addr;
    uint64_t offset;
    uint64_t size;
    uint64_t tag;
  };

  // find disk
  const char* disk_str = "disk size=";
  char buf[64] __attribute__((aligned(64)));

  for (int dev = 0; dev < 256; dev++)
  {
    tohost_sync(dev, 0xFF, (uintptr_t)buf << 8 | 0xFF);
    if (strncmp(buf, disk_str, strlen(disk_str)) == 0)
    {
      long size = atol(buf + strlen(disk_str));
      printk("found disk device %d, size %ld\n", dev, size);

      long sec_size = 512;
      char buf[sec_size] __attribute__((aligned(64)));

      // read block 3
      struct disk_req req = { (uintptr_t)buf, 3*sec_size, sec_size, 0 };
      tohost_sync(dev, 0, (uintptr_t)&req);
      // copy block 3 to block 5
      req.offset = 5*sec_size;
      tohost_sync(dev, 1, (uintptr_t)&req);

      printk("copied block 3 to block 5\n");
    }
  }
}

void rfb_test()
{
  char buf[64] __attribute__((aligned(64)));

  int bpp = 16;
  int width = 32;
  int height = 32;
  uint16_t fb[width * height] __attribute__((aligned(64)));

  for (int dev = 0; dev < 256; dev++)
  { 
    tohost_sync(dev, 0xFF, (uintptr_t)buf << 8 | 0xFF);
    if (strcmp(buf, "rfb") == 0)
    {

      tohost_sync(dev, 0, width | height << 16 | (uint64_t)bpp << 32);
      tohost_sync(dev, 1, (uintptr_t)fb);

      for (int pixel = 0; ; )
        for (int i = 0, value = 0; i < width * height; i++, pixel++)
          fb[i] = pixel;
    }
  }
}