3local
L4 = require
"L4";
5local l =
L4.Loader.new({mem =
L4.Env.user_factory});
11 Utility function to merge several lua tables
13 \param ... one or more tables
15 \note Later tables are given more priority when merging
17 \return a
new combined table
19function table_override(...)
21 for _, tab in ipairs({...})
do
22 for k, v in pairs(tab)
do
30 Creates a
new scheduler proxy at moe.
32 \param prio Base priority of the threads running in the scheduler proxy
33 \param cpu_mask First of a list of CPU masks
for the first 64 CPUs to use
for
35 \param ... more CPU masks
37 \return created scheduler
40 return
L4.Env.user_factory:create(
L4.Proto.Scheduler, prio + 10, prio,
45 Start IO service with the given options
47 \param[in,out] busses table of vBus names as keys. Uses io config
48 `<name>.vbus` to fill vBus `<name>`.
49 \param cmdline io command line parameters
50 \param opts Option table for loader.start function, e.g. scheduler
51 or ext_caps. Entries from ext_caps have precedence over
52 default caps created by this function.
54 After this function returns the created vBusses are located in the table
58 if opts == nil then opts = {} end
60 if opts.caps ~= nil then
61 print(
"Warning: use opts.ext_caps to pass custom/additional capabilities.")
64 if opts.scheduler == nil then
65 print(
"IO started with base priority. Risk of priority related deadlocks! "
66 ..
"Provide an opts.scheduler entry.")
70 sigma0 =
L4.cast(
L4.Proto.
Factory,
L4.Env.sigma0):create(
L4.Proto.Sigma0);
73 dma_mgr =
L4.Env.dma_mgr;
78 for k, v in pairs(busses)
do
79 if caps[k] ~= nil then
80 print(
"Warning: overwriting caps." .. k ..
" with vbus of same name.")
82 local c = l:new_channel();
85 files = files ..
" rom/" .. k ..
".vbus";
88 opts.caps = table_override(caps, opts.caps or {}, opts.ext_caps or {})
89 opts.log = opts.log or {
"io",
"red" }
91 return l:start(opts,
"rom/io " .. cmdline .. files)
95 Create scheduler proxy and add it into the `opts` table under
98 \param[in,out] opts option table
99 \param prio thread priority (or `nil`)
100 \param cpus cpu mask (or `nil`)
101 \param ... more CPU masks
103 There are four possibilities
for values of prio and cpus:
105 \li No prio and no cpus: No scheduler proxy created.
106 \li A prio, but no cpus: Create a scheduler proxy with only a priority limit.
107 \li No Prio, but cpus: Create a scheduler proxy with
default prio and cpus
109 \li A prio and cpus: Create a scheduler proxy with given limits.
112 if cpus == nil and prio == nil then
117 -- Default to zero to use the
L4Re Default_thread_prio
121 local sched =
new_sched(prio, cpus, ...);
122 opts[
"scheduler"] = sched;
126 Start virtio network application.
128 \deprecated This function exists for backwards compatiblity reasons and calls
131 \param[in,out] ports table with port names as keys
132 \param prio priority for started thread
133 \param cpus cpu mask for started thread
134 \param switch_type Selects application to start. Either `switch` or `p2p`
135 \param ext_caps Extra capabilities to pass to the started application
137 The switch_type `switch` can take additional arguments to create a port at the
138 switch. To pass these arguments for a specific port, pass a table as value for
139 a key in the ports table.
145 switch_type = switch_type,
153 Start virtio network application.
155 \param options A table of parameters
157 The following keys are supported in the `options` table:
159 | table key | value |
160 | ------------ | ---------------------------------------------------------------- |
161 | `ports` | table with port names as keys |
162 | `scheduler` | scheduler (e.g. created with
new_sched) |
163 | `switch_type`| selects application to start. Either `
switch` or `p2p` |
164 | `ext_caps` | Extra capabilities to pass to the started application |
165 | `svr_cap` | cap slot to be used
for the server
interface |
166 | `port_limit` | the maximum number of dynamic ports the switch shall support |
168 The switch_type `switch` can take additional arguments to create a port at the
169 switch. To pass these arguments for a specific port, pass a table as value for
170 a key in the ports table.
172 \note The `svr_cap` capability requires server rights, use
":svr()".
175 local ports = options.ports;
176 local scheduler = options.scheduler;
177 local switch_type = options.switch_type;
178 local ext_caps = options.ext_caps;
179 local svr_cap = options.svr_cap;
180 local port_limit = options.port_limit;
182 if svr_cap and port_limit == nil then
183 print(
"Warning: start_virtio_switch_tbl(): 'svr_cap' defined, but no "..
184 "'port_limit' set. The svr_cap will not support dynamic port "..
188 if port_limit and svr_cap == nil then
189 error(
"start_virtio_switch_tbl(): 'port_limit' set, but no 'svr_cap'. "..
190 "This is not supported")
196 switch = svr_cap:svr()
198 switch = l:new_channel()
202 log = {
"switch",
"Blue" },
203 caps = table_override({ svr =
switch:svr() }, ext_caps or {});
207 opts[
"scheduler"] = scheduler;
210 if switch_type ==
"switch" then
211 local port_count = 0;
212 for k, v in pairs(ports)
do
213 port_count = port_count + 1;
216 port_count = port_count + port_limit
219 svr = l:start(opts,
"rom/l4vio_switch -v -p " .. port_count );
221 for k, extra_opts in pairs(ports)
do
222 if type(extra_opts) ~=
"table" then
226 ports[k] =
L4.cast(
L4.Proto.
Factory,
switch):create(
230 table.unpack(extra_opts)
234 svr = l:start(opts,
"rom/l4vio_net_p2p");
236 for k, v in pairs(ports)
do
237 ports[k] =
L4.cast(
L4.Proto.
Factory,
switch):create(0,
"ds-max=4");
247 \param options A table of parameters
249 The following keys are supported in the `options` table:
251 | table key | value |
252 | ----------- | ---------------------------------------------------------------- |
253 | `bootargs` | command line
for guest kernel |
254 | `cpus` | cpu mask |
255 | `ext_args` | additional arguments to pass to UVMM |
256 | `fdt` | file name of the device tree |
257 | `
id` | an integer identifying the VM |
258 | `jdb` | jdb capability |
259 | `kernel` | file name of the guest kernel binary |
260 | `mem` | RAM size in MiB \e or dataspace cap
for guest memory. |
261 | `mem_align` | alignment
for the guest memory in bits. Ignored
if mem is a cap. |
262 | `mon` | monitor application file name |
263 | `net` | a virtio cap, e.g.
for network |
264 | `prio` | thread priority |
265 | `ram_base` | start of guest memory |
266 | `rd` | file name of the ramdisk |
267 | `scheduler` | a scheduler cap. If used, prio and cpus are ignored. |
268 | `vbus` | the vBus to attach to the VM |
271 local nr = options.id;
273 local vbus = options.vbus;
274 local vnet = options.net;
275 local prio = options.prio;
276 local cpus = options.cpus;
277 local scheduler = options.scheduler;
278 local nonidentmem = options.nonidentmem;
281 if L4.Info.arch() ==
"arm" then
283 elseif
L4.Info.arch() ==
"arm64" then
286 align = options.mem_align or align;
290 if type(options.fdt) ~=
"table" then
291 options.fdt = { options.fdt }
293 for _,v in ipairs(options.fdt) do
294 cmdline[
#cmdline+1] = "-d" .. v;
298 if options.bootargs then
299 cmdline[#cmdline+1] =
"-c" .. options.bootargs;
303 cmdline[#cmdline+1] =
"-r" .. options.rd;
306 if options.kernel then
307 cmdline[#cmdline+1] =
"-k" .. options.kernel;
310 if options.ram_base then
311 cmdline[#cmdline+1] =
"-b" .. options.ram_base;
314 if L4.Info.arch() ==
"arm" or
L4.Info.arch() ==
"arm64" then
315 if not options.nonidentmem then
316 cmdline[#cmdline+1] =
"-i";
320 local keyb_shortcut = nil;
322 keyb_shortcut =
"key=" .. nr;
326 if type(options.mem) ==
"userdata" then
327 -- User gave us a cap. Using
this as dataspace
for guest RAM.
329 elseif type(options.mem) ==
"number" then
330 -- User gave us a number. Using
this as size
for a
new Dataspace.
331 size_mb = options.mem
332 elseif type(options.mem) ==
"string" then
333 print(
"start_vm: mem parameter '" .. options.mem ..
"' is of type string, "
334 ..
"please use integer.");
335 size_mb = tonumber(options.mem)
337 -- User did not give us any valid value.
342 local mem_flags =
L4.Mem_alloc_flags.Continuous
343 |
L4.Mem_alloc_flags.Pinned
344 |
L4.Mem_alloc_flags.Super_pages;
346 vm_ram =
L4.Env.user_factory:create(
L4.Proto.Dataspace,
347 size_mb * 1024 * 1024,
348 mem_flags, align):m(
"rw");
358 caps[
"jdb"] =
L4.Env.jdb
361 if options.ext_args then
362 for _,v in ipairs(options.ext_args) do
363 cmdline[
#cmdline+1] = v
368 log = options.log or l.log_fab:create(
L4.Proto.Log,
"vm" .. nr,
"w",
370 caps = table_override(caps, options.ext_caps or {});
374 opts[
"scheduler"] = scheduler;
379 if type(options.mon) ==
'string' then
380 -- assume
'mon' is the name of a server binary which implements the uvmm
382 mon = l:new_channel()
385 scheduler = opts.scheduler;
386 log = l.log_fab:create(
L4.Proto.Log,
"mon" .. nr),
387 caps = { mon = mon:svr() }
388 },
"rom/" .. options.mon)
390 opts.caps[
"mon"] = mon
391 elseif options.mon ~=
false then
392 opts.caps[
"mon"] = l.log_fab:create(
L4.Proto.Log,
"mon" .. nr,
"g");
395 return l:startv(opts,
"rom/uvmm", table.unpack(cmdline));
C++ Factory interface, see Factory for the C interface.
L4 low-level kernel interface.
start_virtio_switch_tbl( options)
new_sched( prio, cpu_mask, ...)
start_virtio_switch( ports, prio, cpus, switch_type, ext_caps)
set_sched( opts, prio, cpus, ...)
start_io( busses, cmdline, opts)