summary refs log tree commit diff stats
path: root/lib/genode/alloc.nim
blob: a21a3ad7bd01d101c277bd087cd20086e3755dc2 (plain) (blame)
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#
#
#            Nim's Runtime Library
#        (c) Copyright 2017 Emery Hemingway
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

# Low level dataspace allocator for Genode.
# For interacting with dataspaces outside of the
# standard library see the Genode Nimble package.

when not defined(genode):
  {.error: "Genode only module".}

when not declared(GenodeEnv):
  include genode/env

type DataspaceCapability {.
  importcpp: "Genode::Dataspace_capability", pure.} = object

type
  Map = object
    attachment: pointer
    size: int
    ds: DataspaceCapability

  SlabMeta = object
    next: ptr MapSlab
    ds: DataspaceCapability

  MapSlab = object
    meta: SlabMeta
    maps: array[1,Map]

const SlabBackendSize = 4096

proc ramAvail(env: GenodeEnv): int {.
  importcpp: "#->pd().avail_ram().value".}
  ## Return number of bytes available for allocation.

proc capsAvail(env: GenodeEnv): int {.
  importcpp: "#->pd().avail_caps().value".}
  ## Return the number of available capabilities.
  ## Each dataspace allocation consumes a capability.

proc allocDataspace(env: GenodeEnv; size: int): DataspaceCapability {.
  importcpp: "#->pd().alloc(@)".}
  ## Allocate a dataspace and its capability.

proc attachDataspace(env: GenodeEnv; ds: DataspaceCapability): pointer {.
  importcpp: "#->rm().attach(@)".}
  ## Attach a dataspace into the component address-space.

proc detachAddress(env: GenodeEnv; p: pointer) {.
  importcpp: "#->rm().detach(@)".}
  ## Detach a dataspace from the component address-space.

proc freeDataspace(env: GenodeEnv; ds: DataspaceCapability) {.
  importcpp: "#->pd().free(@)".}
  ## Free a dataspace.

proc newMapSlab(): ptr MapSlab =
  let
    ds = runtimeEnv.allocDataspace SlabBackendSize
    p = runtimeEnv.attachDataspace ds
  result = cast[ptr MapSlab](p)
  result.meta.ds = ds

iterator items(s: ptr MapSlab): ptr Map =
  let mapCount = (SlabBackendSize - sizeof(SlabMeta)) div sizeof(Map)
  for i in 0 ..< mapCount:
    yield s.maps[i].addr

var slabs: ptr MapSlab

proc osAllocPages(size: int): pointer =
  if slabs.isNil:
    slabs = newMapSlab()
  var
    slab = slabs
    map: ptr Map
  let mapCount = (SlabBackendSize - sizeof(SlabMeta)) div sizeof(Map)
  block findFreeMap:
    while true:
      # lookup first free spot in slabs
      for m in slab.items:
        if m.attachment.isNil:
          map = m
          break findFreeMap
      if slab.meta.next.isNil:
        slab.meta.next = newMapSlab()
          # tack a new slab on the tail
      slab = slab.meta.next
        # move to next slab in linked list
  map.ds = runtimeEnv.allocDataspace size
  map.size = size
  map.attachment = runtimeEnv.attachDataspace map.ds
  result = map.attachment

proc osTryAllocPages(size: int): pointer =
  if runtimeEnv.ramAvail() >= size and runtimeEnv.capsAvail() > 4:
    result = osAllocPages size

proc osDeallocPages(p: pointer; size: int) =
  var slab = slabs
  while not slab.isNil:
    # lookup first free spot in slabs
    for m in slab.items:
      if m.attachment == p:
        if m.size != size:
          echo "cannot partially detach dataspace"
          quit -1
        runtimeEnv.detachAddress m.attachment
        runtimeEnv.freeDataspace m.ds
        m[] = Map()
        return
    slab = slab.meta.next
pre>
67573caf ^
69f04c3f ^
4be9a93b ^
3e849f11 ^
5f98a10c ^
75aa3a98 ^
0487a30e ^
75aa3a98 ^




0487a30e ^
4be9a93b ^
69f04c3f ^

717ab659 ^
5f98a10c ^

3e849f11 ^





5f98a10c ^
3e849f11 ^
88be3dbc ^
717ab659 ^
bc643692 ^
717ab659 ^

5497090a ^
717ab659 ^

5497090a ^
717ab659 ^








795f5244 ^
166e3c0d ^



717ab659 ^

67573caf ^
717ab659 ^


88be3dbc ^
717ab659 ^
bc643692 ^
717ab659 ^

bc643692 ^
5497090a ^
717ab659 ^






795f5244 ^
166e3c0d ^
717ab659 ^
166e3c0d ^
795f5244 ^
e4630643 ^

5f98a10c ^
795f5244 ^
e4630643 ^

166e3c0d ^



67573caf ^

0487a30e ^
67573caf ^
ac0e9db5 ^
827898fc ^
67573caf ^
717ab659 ^

ac0e9db5 ^
0487a30e ^

827898fc ^
717ab659 ^



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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172