Compare commits

...

157 Commits

Author SHA1 Message Date
Christian Helmuth
abc9a2f232 depot: update recipe hashes 2021-10-14 13:46:25 +02:00
Norman Feske
0a35e02961 sculpt: documentation update
Issue #4281
2021-10-14 13:22:18 +02:00
Christian Helmuth
98ffa60577 Increase cap quota for system-shell terminal 2021-10-14 11:48:23 +02:00
Josef Söntgen
9980718c92 libyuv: build unoptimized on ARMv8 2021-10-14 11:46:42 +02:00
Josef Söntgen
2e0d9c8521 libdrm: short-cut tiling in iris back end
Apparently the iris driver does not make use of tiling by the kernel, so
we shortcut the 'SET_TILING' call to keep iris happy with this quickfix.

However, tiling information may get lost, if the iris driver ever calls
'MMAP_GTT' and no fence is configured for the buffer. A follow-up commit
should address this shortcoming in the future.

Issue #4284
2021-10-14 11:40:39 +02:00
Norman Feske
31567c8e46 sculpt: curate default index / installation
- CPU-architecture annotations
- Change order of top-level menu, moving Mesa driver to the end
- Add black_hole, recall_fs, file_fault
- Add usb_webcam, test-capture
- Add audio driver and mixer
- Add vbox6, keeping vbox5-nova-sculpt as fallback
- Remove recall_fs launcher, which is obsolete with the recall_fs pkg
- Replace system_clock by system_clock-pc pkg

Issue #4281
2021-10-14 11:02:18 +02:00
Norman Feske
006e807103 sculpt: version 21.10 2021-10-14 11:02:18 +02:00
Norman Feske
4dac2fd008 sculpt: increase RAM of leitzentrale nitpicker
This follow-up commit to "sculpt: avoid flickering of leitzentrale"
allows nitpicker to double-buffer pixels during resize operation on a
screen size of 1920x1200.
2021-10-14 11:02:17 +02:00
Norman Feske
68e8d1fd21 cached_fs_rom: remove diagnostic message
The message "defer transfer..." spams the log on Sculpt OS.

Issue #4281
2021-10-14 11:02:17 +02:00
Norman Feske
6a89f8b19e wm: fix key_cnt consistency glitch
This patch presents all press and release events to the pointer state,
fixing the problem that _key_cnt was decreased but never increased.
However, the inconsistency had no observable effects in practice.

Issue #4176
2021-10-14 11:02:17 +02:00
Norman Feske
ee463b21ae nitpicker: fix interplay of hover with dragging
This patch extends the notion of having only one uniquely hovered client
in the presence of held keys.

If motion occurs once a key is pressed (e.g., while dragging), the
receiver of the key sequence observes the motion events. In this case,
we have to submit an artificial leave event to the originally hovered
client so that no more than one client observes itself as being hovered
at the same time. Once the key sequence is finished, the hovering is
updated again, eventually presenting a motion event to the originally
hovered client and a leave event to the receiver of the key sequence.

Issue #4176
2021-10-14 11:02:17 +02:00
Norman Feske
1088035f8e wm: defer pointer report update
This patch ensures that the pointer report is updated not before all
input events are handled. The change does not solve any observed
practical issue but the potential problem was spotted while reviewing
the code.

Issue #4176
2021-10-14 11:02:17 +02:00
Christian Helmuth
b2ff2a2950 vbox6: configure OSS plugin only once (as /dev/dsp) 2021-10-14 11:02:16 +02:00
Stefan Kalkowski
c976a1d7e0 dde_linux: iterate over device names not types
To clearly identify the correct device use the unique device's name
not the type. Otherwise a driver cannot drive several devices of the
same type.

Fix #4297
2021-10-14 11:02:15 +02:00
Stefan Kalkowski
98400a68c9 os: extend ARM Platform::Device constructor
Enable construction by explicitely naming a specific device,
if more than one device of the same type exist.

Ref #4297
2021-10-14 11:02:15 +02:00
Josef Söntgen
8679f32d0b dde_linux: backport update event ring for usb_host
This commit contains a backport of commit [1] that deals with updating
the event ring dequeue pointer more often to prevent unnecessary
'Event Ring Full' errors.

  [1] 'usb: host: xhci: update event ring dequeue pointer on purpose'
      (dc0ffbea5729a3abafa577ebfce87f18b79e294b)

Fixes #4296.
2021-10-14 11:02:15 +02:00
Stefan Kalkowski
1d1379430a genode_c_api: safeguard session-policy parsing
Fix #4294
2021-10-14 11:02:15 +02:00
Stefan Kalkowski
b7a379546e genode_c_api: delay USB service announcement
Ref #4294
2021-10-14 11:02:14 +02:00
Stefan Kalkowski
873eb687b0 genode_c_api: reduce USB session ram requirements
Ref #4294
2021-10-14 11:02:14 +02:00
Stefan Kalkowski
1508fdc276 usb_block_drv: handle USB state at startup
Fix #4293
2021-10-14 11:02:14 +02:00
Sebastian Sumpf
c79cdc7b39 gpu/intel: use managed dataspace for aperture mappings
Use 'Region_map_client' for aperture mappings through the GGTT instead
of 'Io_mem_connections'.

issue #4284
2021-10-14 11:02:14 +02:00
Norman Feske
440debfc39 depot_query: filter index by CPU architecture
This patch changes the depot_query tool to filter the returned index
data depending on the 'arch' as specified for the query. This way, one
index file can support multiple CPU architectures while allowing
individual entries to be architecture-specific.

Fixes #4295
2021-10-14 11:02:14 +02:00
Norman Feske
28a71f4a73 cpu_balancer.run: adjust caps for sel4/x86_64 2021-10-14 11:02:14 +02:00
Christian Helmuth
4fd2c9c618 libuvc: exclude .git directory from src archive 2021-10-14 11:02:13 +02:00
Norman Feske
96997ead62 sculpt: fix warning during prepare step
This patch adds the missing definition of 'prio_levels' in the prepare
sub init, fixing the warning:

  [init -> runtime -> prepare] Warning: vfs: invalid priority, upgrading from -2 to 0

Issue #4281
2021-10-14 11:02:13 +02:00
Norman Feske
a12168e1bb pkg/mesa_gears: display frames per second 2021-10-14 11:02:13 +02:00
Sebastian Sumpf
d1461f6a72 vbox6: machine power-down support
Use 'StateChange' event to check for machine's 'PowerOff' state, close
Gui connections and submit exit signal to EP which in turns calls exit.

Fixes #4291
2021-10-14 11:02:13 +02:00
Christian Helmuth
c7abc9f983 vbox6: add pkg with webcam capture support
Issue #4281
Issue #4287
2021-10-14 11:02:13 +02:00
Christian Helmuth
d078f7db76 qemu-usb: adapt to webcam capture on/off changes
Issue #4287
2021-10-14 11:02:13 +02:00
Norman Feske
6f1d3862cd base: introduce Env::try_session
The new 'Env::try_session' method mirrors the existing 'Env::session'
without implicitly handling exceptions of the types 'Out_of_ram',
'Out_of_caps', 'Insufficient_ram_quota', and 'Insufficient_cap_quota'.
It enables runtime environments like init to reflect those exceptions to
their children instead of paying the costs of implicit session-quota
upgrades out of the own pocket.

By changing the 'Parent_service' to use 'try_session', this patch fixes
a resource-exhaustion problem of init in Sculpt OS that occurred when
the GPU multiplexer created a large batch of IO_MEM sessions, with each
session requiring a second attempt with the session quota upgraded by
4 KiB.

Issue #3767
2021-10-14 11:02:12 +02:00
Christian Prochaska
d5d7915b4d audio_in: fix compile errors when strict warnings are enabled
Fixes #4290
2021-10-14 11:02:11 +02:00
Christian Prochaska
b337ee2f2b vfs_oss: fix output fragment limit calculations
Fixes #4289
2021-10-14 11:02:11 +02:00
Johannes Schlatow
ef8a43c546 base-hw: cache maintenance
touch each page before flushing to ensure that it's present in the page table

genodelabs/genode#4279
2021-10-14 11:02:10 +02:00
Sebastian Sumpf
350353885e vbox6: add shared folder support
builds virtualbox6-sharedfolders.lib.so from unmodified VirtualBox6
sources.

fixes #4288
2021-10-14 11:02:10 +02:00
Norman Feske
eb80d6ce66 usb_webcam: on/off dependent on capture client
This commit removes the report service from the usb_webcam pkg, which
was used to enable or disable the webcam driver. The on/off state is
instead controlled by the presence of a capture client. That is, once a
capture client appears, the webcam driver is started. Vice versa, once
no capture client exists, the webcam driver is removed automatically.

Internally, the detection of presence of a capture client is based on
nitpicker's 'displays' report, which is consumed as input of the
rom_filter, which in turn generates the configuration of a dynamic sub
init.

Fixes #4287
2021-10-14 11:02:10 +02:00
Norman Feske
bc5a7eb495 rom_filter: support default input values
Fixes #4286
2021-10-14 11:02:10 +02:00
Stefan Kalkowski
cb67d07e61 lx_emul: be compliant to original softirq impl.
Ref #4268
2021-10-14 11:02:10 +02:00
Christian Helmuth
96ebed6c31 vbox6: use configuration from machine.vbox6
There are some subtle incompatibilities in VirtualBox 6 with settings we
used in version 5. Therefore, the vbox6 package uses machine.vbox6 as
configuration file. An example configuration is provided by the
raw/vbox6 package.

Issue #4281
2021-10-14 11:02:10 +02:00
Josef Söntgen
6093f8ad81 gpu/intel: deal with insufficient amount of CAPS
'Out_of_ram' was so far the only exception a client had to deal with
during buffer managment. Allocating memory, however, does not only
consume RAM quota but CAP quota as well.

This commit tries to mitigate that shortcoming by reflecting the
'Out_of_caps' state back to the client. Furthermore it allows for
resource accounting on certain client allocations, e.g. buffers.

Fixes #4284.
2021-10-14 11:02:09 +02:00
Josef Söntgen
f6d845e630 gpu: reflect CAP shortage during buffer management
Allocating and mapping buffers not only consumes RAM quota, it consumes
CAP quota as well. Extended the Gpu session to allow for dealing with
that on the client side.

On a side note, the amount of initial CAP quota needed to establish
a connection is increased to cover the current costs of the Intel
GPU multiplexer.

Issue #4284.
2021-10-14 11:02:09 +02:00
Josef Söntgen
27e55dab3e platform_drv: check quota before allocating buffer
The platform driver uses a 'Constrained_ram_allocator' to allocate
meta-data on behave of a client. It uses the PD session as
'Ram_allocator' back end that in return is implemented via the
'Expanding_pd_session_client'.

Whenever the PD client itselft comes into resource shortage it will
ask its parent unconditionally. However, depending on the integration,
such a request may be left unanswered.

This commit introduces a check to prevent that situation from
occurring. In case the platform driver notices the resource shortage
it will reflect that back to the client.

Issue #4284.
2021-10-14 11:02:09 +02:00
Norman Feske
05b451c563 pkg/mesa_gpu: use cached_fs_rom
By using the cached_fs_rom instead of fs_rom, each client obtains the
same (read-only) copy of the shared library, avoiding a RAM resource
request when running mulitple GPU applications at the same time.
With this patch, Sculpt is able to host at least 3 Mesa applications.

Issue #4263
Issue #4281
2021-10-14 11:02:09 +02:00
Sebastian Sumpf
2604c3cca6 vbox6: add mouse pointer shape support
Implement 'MousePointerShapeChanged' event, retrieve parameters from
COM pointer, and update shape report.

fixes #4283
2021-10-14 11:02:09 +02:00
Norman Feske
8ebc185caf depot: merge rtc_drv into system_clock runtime pkg
This new version of the system_clock pkg does no longer depend on the
presence of an external 'Rtc' service as previously provided by the
Sculpt base system. Instead, it hosts the rtc_drv inside the subsystem.
Because rtc_drv is board-dependent, the system_clock pkg is named
system_clock-pc now.

Issue #4281
2021-10-14 11:02:08 +02:00
Norman Feske
6e32102cc6 depot: add recall_fs runtime pkg
Issue #4281
2021-10-14 11:02:08 +02:00
Norman Feske
42541fcc92 sculpt: limit depot selection
This patch reduces the items of the default depot-selection menu to
users that actively maintain a Sculpt index.

Issue #4281
2021-10-14 11:02:08 +02:00
Norman Feske
7cae324726 sculpt: remove RTC driver from base system
The RTC driver is not needed by the base system and can thereby be
handled as a user-installable component.

Issue #4281
2021-10-13 14:50:46 +02:00
Sebastian Sumpf
1072a91592 qemu-usb: disable remote wake up in config descriptors
Some guests don't handle remote wake up correctly causing devices to
stop functioning. Therefore, we disable the remote wake up bit (5) in
`bmAttributes` of the device configuration descriptor.

Thanks to Peter for the initial fix.

Fixes #4278
2021-10-13 14:50:46 +02:00
Christian Helmuth
07bb3fc1ec Initial update of init-state ROM in init_loop test
ROM clients have to request an initial update of dynamic ROMs explicitly
and should not depend on artificial signals from the ROM session on
signal-handler registration.

Issue #4274
2021-10-13 14:50:46 +02:00
Johannes Schlatow
93583cce3b sequence: immediately stop child on exit
The sequence app should immediately stop the child when it called
parent().exit(). Otherwise, the child will continue execution which
causes a race condition: The child's ld.lib.so will eventually destruct
an Attached_rom_dataspace for the config rom. If sequence destructed the
corresponding service first, we will get an Ipc_error.

genodelabs/genode#4267
2021-10-13 14:50:46 +02:00
Josef Söntgen
e6bd9fd7da libc: implement SNDCTL_DSP_GETFMTS ioctl
This I/O control is used to query the audio format, e.g. AFMT_S16_LE
in our case.

Fixes #4276.
2021-10-13 14:50:46 +02:00
Martin Stein
870c5c7a81 file_vault: GUI control for encrypted virtual FS's
Warning!

The current version of the file vault is not thought for productive use but
for mere demonstrational purpose! Please refrain from storing sensitive data
with it!

The File Vault component implements a graphical frontend for setting up and
controlling encrypted virtual file systems using the Consistent Block Encrypter
(CBE) for encryption and snapshot management. For more details see
'repos/gems/src/app/file_vault/README'.

Fixes #4032
2021-10-13 14:50:46 +02:00
Martin Stein
3e375e4315 cbe tools: log less by default
Previously unconditional calls to Genode::log in cbe init and the cbe trust
anchor VFS plugin were made dependent on a verbosity flag that is set to
"false" by default.

Ref #4032
2021-10-13 14:50:46 +02:00
Martin Stein
8dfa586462 vfs/cbe_trust_anchor: fix bug in key decrypt
The plugin used the ciphertext instead of the plaintext buffer for key
decryption which led to bogus ciphertext keys.

Ref #4032
2021-10-13 14:50:46 +02:00
Martin Stein
a661aa79de vfs/cbe_trust_anchor: AES-key-wrap private key
Instead of simply encrypting the private key with AES-256 when storing it to
the 'encrypted_private_key' file, wrap it using the AES-key-wrap algorithm
described in RFC 3394 "Advanced Encryption Standard (AES) Key Wrap Algorithm".
This is more secure and enables us to directly check whether the passphrase
entered by the user was correct or not.

Ref #4032
2021-10-13 14:50:46 +02:00
Martin Stein
94701eec09 vfs/cbe_trust_anchor: rename secured_superblock
As the file formerly named 'secured_superblock' actually contains the hash of
the superblock that was secured, it was renamed 'superblock_hash'.

Ref #4032
2021-10-13 14:50:46 +02:00
Martin Stein
a28ca44101 vfs/cbe_trust_anchor: rename keyfile
As the file formerly named 'keyfile' actually contains the encrypted private
key of the Trust Anchor, it was renamed 'encrypted_private_key'.

Ref #4032
2021-10-13 14:50:46 +02:00
Martin Stein
641a738e3d vfs/cbe_trust_anchor: encrypt symmetric keys
By now, the symmetric keys were only XOR'ed with the private key as placeholder
for a real encryption. Now they are encrypted using AES256 with the TA's
private key as key

Ref #4032.
2021-10-13 14:50:46 +02:00
Martin Stein
f41dec67e1 vfs/cbe_trust_anchor: use secure private key
A private key of 256 bits is generated pseudo-randomly using the jitterentropy
VFS plugin on initialization. The private key is stored in the key file
encrypted via AES256 using the SHA256 hash of the users passphrase. When
unlocking the CBE device, the encrypted private key is read from the key file
and decrypted with the hash of the users passphrase.

Ref #4032
2021-10-13 14:50:46 +02:00
Martin Stein
75a55b62a3 vfs/cbe_trust_anchor: use hash of passphrase
Instead of using the user passphrase directly, use its SHA256 hash calculated
using libcrypto. The passphrase hash is still stored in the key file to be
used as base for the very primitive way of generating the private key.

Ref #4032
2021-10-13 14:50:46 +02:00
Martin Stein
989b7f39e1 vfs/cbe_trust_anchor: use secure symmetric keys
Use the jitterentropy vfs plugin for the generation of new symmetric block
encryption keys in the cbe trust anchor vfs plugin.

Ref #4032
2021-10-13 14:50:46 +02:00
Martin Stein
a2d2b874ec vfs/cbe_trust_anchor: sync keyfile-handle close
Closing the keyfile handle after a write operation wasn't synchronised to the
actual end of the write operation.

Issuing a write operation at the back end returns successfull as soon as the
back end has acknowledged that it will execute the operation. However, the
actual writing of the data might still be in progress at this point. But the
plugin used to close the file handle and declare the operation finished at this
point which led to warnings about acks on unknown file handles and leaking
resources. Now, the plugin issues a sync operation directly after the write
operation and waits for the sync to complete. This ensures that the plugin
doesn't declare the operation finished too early.

Ref #4032
2021-10-13 14:50:45 +02:00
Martin Stein
42490208c2 vfs/cbe_trust_anchor: fix unlocking
The unlocking operation in the trust anchor was broken wich caused bad keys in
the CBE. This rewrites the whole operation to work as desired. Note that this
doesn't make it more safe! The private key is still almost the same as the
passphrase and stored plaintext.

Ref #4032
2021-10-13 14:50:45 +02:00
Martin Stein
95639a7492 vfs/cbe_trust_anchor: close handles correctly
The plugin used to close file handles via the 'vfs_env.root_dir.close'.
However, this lead to resource leaks and apparently isn't the right way to
do it. Other VFS plugins do it by calling 'close' directly on the handle and
doing it in the trust anchor plugin also, fixes the leaks.

Ref #4032
2021-10-13 14:50:45 +02:00
Martin Stein
df7de17435 vfs/cbe_trust_anchor: sync hashfile-handle close
Closing the hashfile handle after a write operation wasn't synchronised to the
actual end of the write operation.

Issuing a write operation at the back end returns successfull as soon as the
back end has acknowledged that it will execute the operation. However, the
actual writing of the data might still be in progress at this point. But the
plugin used to close the file handle and declare the operation finished at this
point which led to warnings about acks on unknown file handles and leaking
resources. Now, the plugin issues a sync operation directly after the write
operation and waits for the sync to complete. This ensures that the plugin
doesn't declare the operation finished too early.

Ref #4032
2021-10-13 14:50:45 +02:00
Martin Stein
1b4a80ffae vfs/cbe: control/deinitialize file
There were no means for issuing a Deinitialize request at the CBE using the
CBE VFS plugin. The new control/deinitialize file fixes this. When writing
"true" to the file, a Deinitialize request is submitted at the CBE. When
reading the file, the state of the operation is returned as a string of the
format "[current_state] last-result: [last_result]" where [current_state] can
be "idle" or "in-progress" and [last_result] can be "none", "success", or
"failed".

Ref #4032
2021-10-13 14:50:45 +02:00
Martin Stein
88e6991083 vfs/cbe: fix ID argument on discard_snap
When discarding a snapshot, the CBE VFS plugin didn't communicate the ID of
the snapshot to the CBE. Instead it set the ID argument to 0. Therefore the
operation never had any effect.

Ref #4032
2021-10-13 14:50:45 +02:00
Martin Stein
9b953e79ba vfs/cbe: support watching the snapshots fs
The snapshots file system couldn't be watched. But it's of interest to watch
for appearing and disappearing snapshots.

Ref #4032
2021-10-13 14:50:45 +02:00
Martin Stein
4c1eae97cf vfs/cbe: fix result of SnapshotsFS.num_dirent("/")
The snapshots file system used to return the number of snapshots on
'num_dirent' when called for the root directory although it was expected to
return 1. This confused the tooling ontop of the VFS.

Ref #4032
2021-10-13 14:50:45 +02:00
Martin Stein
f051bfa90d vfs/cbe: support watching "rekey" file
The control/rekey file couldn't be watched although it was meant to be used
to watch the current state of the rekey operation.

Ref #4032
2021-10-13 14:50:45 +02:00
Martin Stein
4ed45dd303 vfs/cbe: support watching "extend" file
The control/extend file couldn't be watched although it was meant to be used
to watch the current state of the extend operation.

Ref #4032
2021-10-13 14:50:45 +02:00
Martin Stein
2d0ac161cb vfs/cbe: mark extend/rekey fs readable
Despite being readable, the files control/extend and control/rekey proclaimed
that they were not when asked. This caused the fs_query tool to not report the
content of the files although it could have.

Ref #4032
2021-10-13 14:50:45 +02:00
Martin Stein
34245376ba vfs/cbe: fix size of extend/rekey fs
Stat calls on the control/extend and control/rekey files returned a bogus file
size that led to an error in the VFS File_content tool. The tool complained
that the size of the file determined while reading the content differs from the
one reported by the stat operation. Now, the stat call will always determine
the actual size of what would be read.  However, it isn't guaranteed that this
size doesn't change in the time after the stat operation and before the read
operation.

Ref #4032
2021-10-13 14:50:45 +02:00
Martin Stein
bd79f93657 cbe/types: invalid generation, generation string
Ref #4032
2021-10-13 14:50:45 +02:00
Martin Stein
731df4b037 recipes/src/cbe: build also cbe_init_trust_anchor
Ref #4032
2021-10-13 14:50:45 +02:00
Martin Stein
d3cc5c9cd2 gems/recipes: api/cbe
Ref #4032
2021-10-13 14:50:45 +02:00
Martin Stein
ff656401b3 gems: update cbe port
This update fixes a bug when discarding snapshots.

Ref #4032
2021-10-13 14:50:45 +02:00
Christian Helmuth
46ee872b50 vbox6: shared clipboard service
The service is loaded dynamically VBoxSharedClipboard.so at runtime. The
VFS configuration mounts the shared object at /VBoxSharedClipboard.so as
the file is checked by contrib code before loading. An init
configuration in pkg/vbox6/runtime illustrates this and how to re-label
the VBoxSharedClipboard.so ROM to its real name
virtualbox6-sharedclipboard.lib.so.
2021-10-13 14:50:45 +02:00
Christian Helmuth
5aee693f70 vbox6: limit wait for ack to 15 ms in AHCI model
During Windows 10 boot with sequential block requests, the AHCI request
worker finished earlier than the EMT thread signals hEvtProcess and
begins waiting for hEvtProcessAck indefinitely. The timeouts helps to
survive this short phase.

A better solution would use conditional variables, which are not
provided in VirtualBox's runtime.
2021-10-13 14:50:45 +02:00
Josef Söntgen
f21cf3f8b1 mesa: name driver library appropriately
Rename the 'egl_drv' library and the various back ends to 'mesa_gpu_drv'
and 'mesa_gpu-<backend>'.

Fixes #4275.
2021-10-13 14:50:37 +02:00
Norman Feske
32c283d26f os: introduce C API for generating Genode events
This patch introduces a C API to be used by input drivers to generate
Genode events. The initial version is limited to multitouch events only.

Fixes #4273
2021-10-13 14:46:54 +02:00
Stefan Kalkowski
f4cb5cc299 dde_linux: preserve Io_signal_handler for IRQs
Do not construct/destruct signal handlers for interrupts dynamically,
but only the Irq session to prevent a deadlock.

Fix #4272
2021-10-13 14:46:54 +02:00
Stefan Kalkowski
6ae55d490b lx_emul: restrict allocations to minimal alignment
* Use the architecture-dependent minimal alignment for all allocations,
  e.g. on ARM it is necessary to have cacheline aligned allocations for DMA
* Remove the allocation functions without alignment from generic API
* Fix a warning

Fix #4268
2021-10-13 14:46:54 +02:00
Stefan Kalkowski
2ac8620f44 lx_emul: invalidate cache for DMA-read only
After a DMA transaction do only invalidate cachelines from the
corresponding DMA buffers if data got transfered from device to
CPU, and not vice versa. Otherwise it might result in data corruption.

Ref #4268
2021-10-13 14:46:54 +02:00
Stefan Kalkowski
d8c344f6b9 lx_emul: do not block kworkers unconditionally
Ref #4268
2021-10-13 14:46:54 +02:00
Stefan Kalkowski
f8cf0442ed lx_emul: implement lookup of dma-addr to virt-addr
* Use the new Lx_kit::Map as lookup structure for virt-to-dma and vice versa,
  instead of a list-based registry

Ref #4268
2021-10-13 14:46:54 +02:00
Stefan Kalkowski
9bc7ecb605 lx_emul: provide alignment for DMA allocations
Ref #4268
2021-10-13 14:46:54 +02:00
Christian Helmuth
4c4ce2f899 report_rom: versioning and explicit notification
The former implementation did not internally track ROM changes notified
vs. delivered to the client. We adapt the versioning implementation
implemented in dynamic_rom_session.h and enable explicit notification of
the current version.

The feature is used by the clipboard to notify permitted readers of the
clipboard ROM service on focus change via the newly created private
Rom::Module::_notify_permitted_readers() function.

Fixes #4274
2021-10-13 14:46:54 +02:00
Stefan Kalkowski
4803937dd2 os: introduce C-API to provide USB service
Fix #4270
2021-10-13 14:46:54 +02:00
Stefan Kalkowski
6789b86871 base-hw: optimize cache maintainance for ARMv8
* Remove the data-synchronization barrier from the inner-loop
* Instead add a system-wide barrier at the end of the operation

Fix #4269
2021-10-13 14:46:54 +02:00
Martin Stein
9542bcf88c base-hw: reduce includes in board.h
The includes for the address-space-ID allocator and the translation table are
usually specific to the CPU in use. Therefore these includes can be moved from
their current location in the board header to the CPU headers. This reduces the
number of decisions a board maintainer has to make if the CPU model he's aiming
for is already available.

This can probably also be applied for other includes in the board headers but I
intentionally leave it for a future commit as I don't have the time to do it
all now.

Ref #4217
2021-10-13 14:46:54 +02:00
Martin Stein
ad059362d2 base-hw: reduce hardware-specific include paths
For base-hw Core, we used to add quite some hardware-specific include paths
to 'INC_DIR'. Generic code used to include, for instance, '<cpu.h>' and
'<translation_table.h>' using these implicit path resolutions. This commit
removes hardware-specific include paths except for

1) the '<board.h>' include paths (e.g., 'src/core/board/pbxa9'),
2) most architecture-specific include paths (e.g., 'src/core/spec/arm_v7'),
3) include paths that reflect usage of virtualization or ARM Trustzone
   (e.g., 'src/core/spec/arm/virtualization').

The first category is kept because, in contrast to the former "spec"-mechanism,
the board variable used for this type of resolution is not deprecated and the
board headers are meant to be the front end of hardware-specific headers
towards generic code which is why they must be available generically via
'<board.h>'.

The second category is kept because it was suggested by other maintainers that
simple arch-dependent headers (like for the declaration of a CPU state) should
not imply the inclusion of the whole '<board.h>' and because the architecture
is given also without the former "spec"-mechanism through the type of the build
directory. I think this is questionable but am fine with it.

The third category is kept because the whole way of saying whether
virtualization resp. ARM Trustzone is used is done in an out-dated manner and
changing it now would blow up this commit a lot and exceed the time that I'm
willing to spend. This category should be subject to a future issue.

Ref #4217
2021-10-13 14:46:53 +02:00
Martin Stein
49b09702b8 base-hw: don't include board.h from hardw. headers
The 'src/core/board/<board>/board.h' header is thought as front end of
hardware-specific headers of a given board towards the generic base-hw Core
code. Therefore it leads to problems (circular includes) if the board.h header
is included from within another hardware-specific header.

If hardware-specific headers access declarations from namespace Board in a
definition, the definition should be moved to a compilation unit that may
include board.h. If hardware-specific headers access declarations from board.h
in a declaration, they should either use the primary declaration from the
original header or, if the declaration must be selected according to the board,
another board-specific header should be introduced to reflect this abstraction.

This is applied by this commit for the current state of base-hw.

Ref #4217
2021-10-13 14:46:53 +02:00
Martin Stein
5d74509b2d base-hw: get rid of static perf counter object
It is not necessary to have a class, an object, and a generic header for the
perfomance counter. The kernel merely enables the counter using cpu registers
('msr' instructions, no MMIO) on arm_v6 and arm_v7 only. Therefore this commit
makes the header arm-specific and replaces class and global static object with
a function for enabling the counter.

Fixes #4217
2021-10-13 14:46:53 +02:00
Martin Stein
b817e1977c base-hw: serial output as Main member
Let the kernel's serial-output driver be a member of the one Kernel::Main
object instead of having it as global static variable.

Ref #4217
2021-10-13 14:46:53 +02:00
Martin Stein
910788313e base-hw: get rid of static variable in Kernel::Pd
Ref #4217
2021-10-13 14:46:53 +02:00
Martin Stein
02f00a999c base-hw: global IRQ controller as Main member
Let the kernel's driver for the global IRQ controller be a member of the one
Kernel::Main object instead of having it as static variables in the drivers for
the local IRQ controllers. Note that this commit spares out renaming 'Pic' to
'Local_interrupt_controller' which would be more sensible now with the new
'Global_interrupt_controller' class. Furthermore, on ARM boards the commit
doesn't move 'Distributer' stuff to the new global IRQ controller class as they
don't have real data members (only MMIO) and can be instanciated for each CPU
anew. However, the right way would be to instanciate them only once in Main as
well.

Ref #4217
2021-10-13 14:46:53 +02:00
Martin Stein
441d137482 base-hw: Address-Space-ID allocator as Main member
Let the kernel's Address-Space-ID allocator be a member of the one
Kernel::Main object instead of having it as global static variable.

Ref #4217
2021-10-13 14:46:53 +02:00
Martin Stein
0c61b25bcf base-hw: no unmanaged_singleton in kernel thread
The unmanaged-singleton approach was used in this context only because of the
alignment requirement of the Core main-UTCB. This, however can also be achieved
with the new 'Aligned' utility, allowing the UTCB to be a member of the Core
main-thread object.

Ref #4217
2021-10-13 14:46:53 +02:00
Martin Stein
b6641eaa25 base-hw: Core PD as Main member
Let the Core protection-domain object be a member of the one Kernel::Main
object instead of having it as global static variable.

Ref #4217
2021-10-13 14:46:53 +02:00
Martin Stein
d6e347163d base-hw: unnecessary unmanaged-singleton includes
Remove some deprecated include directives for the unmanaged-singleton header.

Ref #4217
2021-10-13 14:46:53 +02:00
Martin Stein
5dd8ee5840 base-hw: global IRQ pool as Main member
Let the global kernel IRQ-pool be a member of the one Kernel::Main object
instead of having it as global static variable.

Ref #4217
2021-10-13 14:46:53 +02:00
Martin Stein
c49db16762 base-hw: don't use boot_info() outside main.cc
It's sufficient to access the boot info only on kernel initialization time.
Therfore, it can remain completely hidden to the rest of the kernel inside
kernel/main.cc in the initialization function.

Ref #4217
2021-10-13 14:46:53 +02:00
Martin Stein
b247def09a base-hw: Core main-thread as Main member
Let the Core main-thread object be a member of the one Kernel::Main object
instead of having it as global static variable.

Ref #4217
2021-10-13 14:46:53 +02:00
Martin Stein
2b89cd66cb base-hw: kernel CPU-pool as Main member
Let the kernel CPU-pool be a member of the one Kernel::Main object instead of
having it as global static variable.

Ref #4217
2021-10-13 14:46:53 +02:00
Martin Stein
be3d5232c8 base-hw: kernel-data lock as Main member
Let the global kernel-data lock be a member of the one Kernel::Main object
instead of having it as global static variable.

Ref #4217
2021-10-13 14:46:53 +02:00
Martin Stein
82cf31ac27 base-hw: introduce Kernel::Main class
This commit introduces the Kernel::Main class that replaces the former way of
initializing the kernel (former 'kernel_init' function) and calling the C++
kernel entry handler (former 'kernel' function). These two are now
'Main::initialize_and_handle_kernel_entry' and 'Main::handle_kernel_entry'.
Also reading the execution time of the idle threads was already moved to
'Main'. The one static Main instance is meant to successivly replace all the
global static objects of the base-hw kernel with data members of the Main
instance making the data model of the kernel much more comprehensible. The
instance and most of its interface are hidden in kernel/main.cc. There are only
rare cases where parts of the Main interface must be accessible from the
outside. This should be done in the most specific way possible (see main.h)
and, if possible, without handing out references to Main data members or the
Main instance itself.

Ref #4217
2021-10-13 14:46:52 +02:00
Martin Stein
9de43a48b6 base-hw: conform pc board header
Normally, the board header can be found for each supported board under
'src/core/board/<BOARD>/board.h'. This was not the case for the board 'pc'
that was located under 'src/core/spec/x86_64/board.h'. The commit fixes this.

Ref #4217
2021-10-13 14:46:52 +02:00
Martin Stein
a9563bfd4c base-hw: rename Core_thread Core_main_thread
The class name Core_thread in Kernel for the object of the first thread of
core is too generic as there can be an arbitrary number of threads in core
besides this one. Furthermore, creating a core thread has its own syscall
'new_core_thread' that isn't related in any way to Core_thread. Therefore
this commit introduces the more specific name Core_main_thread as replacement
for Core_thread.

Ref #4217
2021-10-13 14:46:52 +02:00
Martin Stein
693a2b5421 base-hw: get rid of cpu_pool() in platform.cc
The function was only still used for reading the execution time of idle threads
of CPUs. Certainly, it is technically fine and more performant to read these
values directly from the kernel objects without doing a syscall. However,
calling cpu_pool() for it provides read and write access to a lot more than
only the execution time values. The interface via which Core directly reads
state of the kernel should be as narrow and specific as possible.
Perspectively, we want to get rid of the cpu_pool() accessor anyway. Therefore
this commit introduces Kernel::read_idle_thread_execution_time(cpu_idx) as
replacement. The function is implemented in kernel code and called by Core in
platform.cc.

Ref #4217
2021-10-13 14:46:52 +02:00
Martin Stein
277adcacb0 base-hw: make Trace_source in Platform() a class
Apparently, there is no need for exposing the data members of Trace_source, so,
we sould better make them private before someone gets the impression that they
are meant to be accessed directly.

Ref #4217
2021-10-13 14:46:52 +02:00
Martin Stein
aa6a7db50a base-hw: communicate kernel irqs via boot info
Core used to read the kernel-reserved IRQs from the timer objects in the
kernel's CPU objects and the PIC class (inter-processor IRQ). Besides not
being "good style" to access a kernel object in Core, this becomes a problem
when trying to prevent CPU pool from being accessed via global functions.

As a solution, this commit extends the boot info to also carry an array of all
kernel-reserved IRQs.

Ref #4217
2021-10-13 14:46:52 +02:00
Martin Stein
8b69bc96f9 base-hw: separate variants of Kernel_object(...)
For the constructor of Kernel_object<T> there are two variants. One for the
case that it is called from Core where the kernel object (type T) must be
created via a syscall and one when it is called from within the kernel and the
kernel object can be created directly. Selecting one of these variants was done
using a bool argument to the constructor. However, this implies that the
constructor of Kernel_object<T> and that of T have the same signature in the
variadic arguments, even in the syscall case, although technically it would
then not be necessary.

This becomes a problem as soon as kernel objects created by Core shall receive
additional arguments from the kernel, for instance a reference to the global
CPU pool, and therefore stands in the way when wanting to get rid of global
statics in the kernel. Therefore, this commit introduces two constructors that
are selected through enum arguments:

! Kernel_object(Called_from_kernel, ...);
! Kernel_object(Called_from_core, ...);

Ref #4217
2021-10-13 14:46:52 +02:00
Martin Stein
6e4ef43bf0 base-hw: always use 'unsigned' for priorities
At some points in the code, 'signed' was used instead of the more appropriate
'unsigned' type.

Ref #4217
2021-10-13 14:46:52 +02:00
Martin Stein
b922dc5c10 base-hw: fix self-include in kernel/types.h
That this header apparently used to include itself didn't cause any problems
so far but still remained bad style.

Ref #4217
2021-10-13 14:46:52 +02:00
Josef Söntgen
cacb83b163 gpu: introduce mapping attributes
The various mapping methods are modelled after the requirements of
the Intel GPUs or rather the Mesa driver back end.

With upcoming support for other driver back ends, we need to
sequeeze their requirements in as well. For now hijack 'map_buffer'
to provide for specifying the kind of attributes the client needs.

For now all buffers mapped in the GGTT for Intel GPUs are treated
as RW.

Issue #4265.
2021-10-13 14:46:52 +02:00
Josef Söntgen
90e151e2c4 gpu: add 'complete' RPC call
This call allows for checking if the given execution buffer has been
completed and complements the completion signal. Initially the GPU
multiplexer always sent such a signal when the currently scheduled
execution buffer has been completed. During enablement of the 'iris'
driver it became necessary to properly check of sequence number.

In case of the Intel GPU multiplexer the sequence numbers are
continous, which prompted the greater-than-or-equal check in the
DRM back end. By hidding this implementation detail behind the
interface, GPU drivers are free to deal with sequence numbers any
way they like and allows for polling in the client, where the
completion signal is now more of a progress signal.

Issue #4265.
2021-10-13 14:46:52 +02:00
Josef Söntgen
e37792ce94 gpu: introduce information dataspace
The current info implementation (as RPC) is limited in a few ways:

  * The amount of data that may be transferred is constrained by the
    underlying base platform
  * Most information never changes during run time but is copied
    nonetheless
  * The information differs depending on the used GPU device and
    in its current implementation only contains Intel GPU specific
    details

With this commit the 'info' RPC call is replaced with the
'info_dataspace' call that transfers the capability for the dataspace
containing the information only. This is complemented by a client
local 'attached_info' call that allows for getting typed access to
the information. The layout of the information is moved to its own
and GPU-specific header file, e.g., 'gpu/info_intel.h'

Issue #4265.
2021-10-13 14:46:52 +02:00
Josef Söntgen
cfb170c719 gpu: move exec sequence number to Gpu namespace
Moving the type definition removes the aritifial linkage to the Gpu
information structure.

Issue #4265.
2021-10-13 14:46:52 +02:00
Josef Söntgen
3b40790e02 gpu: use Buffer_id to identify buffers
Rather than using the dataspace capability directly, let the client
choose its own local identifier that is linked to the underlying
capability.

Fixes #4265.
2021-10-13 14:46:52 +02:00
Stefan Kalkowski
9a80c3a618 depot: suppress error when copying empty package
Instead of failing, ignore empty packages when copying over
depot packages to a run-script environment.

Fix #4271
2021-10-13 14:46:52 +02:00
Josef Söntgen
ba430dfeac libdrm/iris: destroy Buffer_handle object
When the client frees the buffer, destroy the corresponding
Buffer_handle as well.

Fixes #4266.
2021-10-13 14:46:52 +02:00
Piotr Tworek
b157256a2b uplink client: Add missing space in warning message.
Right now the warning about failure to forward packet from driver to
uplink RX connection reads:

  "exception while trying to forward packet from driverto Uplink
   connection TX"

Add missing space between "driver" and "to".

Issue #4264
2021-10-13 14:46:52 +02:00
Piotr Tworek
60980045ea virtio_nic: Increase default TX & RX virtqueue sizes.
32KB is a rather small value. The driver can cope with it now, but
it does not perform as well as it should. This visible especially
in scenarions like nic_router_flood where we still often hit
synchronous wait path. Bump the size to 256kB.

Issue #4264
2021-10-13 14:46:51 +02:00
Piotr Tworek
880cd3a490 virtio_nic: Fix packet transmission handling.
The problem can be seen when running nic_router_flood scenarion on arm
qemu_virt boards. With the amount of data this scenario tries to send
the driver quickly complains it has failed to push data into TX VirtIO
queue. After this warning message is printed nothing really happens and
after a while the test scenario fails.

The fact that we can't write all available data to the device is not
unexpected. VirtIO queue size is slected at initialization time and we
don't change it during driver lifetime. It can be tweaked via driver
config, but this does not change the fact that we'll always be able to
produce more data packets than we have free space in the VirtIO queue.

IMO the expected behavior of the driver in such case should be to:
1. Notify the device there is data to process.
2. Wait for the device to process at least part of it.
3. Retry sending queued packets.

One could expect returning Transmit_result::RETRY from _drv_transmit_pkt
would produce such result. Unfortunately it seems that Uplink_client_base
treats RETRY return value as indication of link being down. It'll retry
sending the packet only after the device notifies it the link is once
again up. This is the reason why nothing happens when running
nic_router_flood on top of virtio_nic driver. The link never goes down
in this case so once we fill the TX VirtIO queue and tell the base class
to retry the send, we'll be stuck waiting for link up change event
which will never arrive.

To fix this problem, when sending a packet to the device fails, do a
synchrnonus TX VirtIO queue flush (tell device there is data to process
and wait until its done with it).

With this fix in place nic_router_flood test scenario passes on both arm
qemu_virt boards.

Issue #4264
2021-10-13 14:46:51 +02:00
Piotr Tworek
b7f66626c2 virtio: Make avail and used ring pointers volatile
The contents of those descriptor rings can be modified by the device.
Mark them as volatile so the compiler does not make any assumptions
about them.

Issue #4264
2021-10-13 14:46:51 +02:00
Christian Helmuth
c0a7696c71 tool/dts/extract: convert regex strings to latin1
The former encoding was UTF-8, which works quite well if LC_CTYPE is
ensured to be an UTF-8 codeset (e.g., en_US.UTF-8 or C.UTF-8 . But, if
LC_CTYPE is set to C or latin1 for example, the Tcl regex library enters
an infinite loop because of unexpected characters used as markers
n the strings (e.g., SECTION SIGN U+00A7).

Therefore, the extract tool was converted to latin1 with the following
commands and now works for LC_CTYPE C and UTF-8 codesets.

   iconv -f utf-8 -t latin1 tool/dts/extract > /tmp/e
   cp /tmp/e tool/dts/extract
2021-10-13 14:46:51 +02:00
Alexander Boettcher
d85a448c52 gpu/intel: provide supported devices as config
Adjust drivers_managed and sculpt accordingly.

Issue #4260
2021-10-13 14:46:51 +02:00
Sebastian Sumpf
d67899be95 gpu/intel: enable 32 bit CPU support
* use Gpu::addr_t (64 Bit) where necessary instead of Genode::addr_t.

issue #4260
2021-10-13 14:46:51 +02:00
Alexander Boettcher
6112c0df6d mesa: rename gpu-* pkg to mesa_gpu-*
for easier linking by user with the Mesa client ROM requests, which will be
mesa_gpu-drv.lib.so. Adjust mesa-gears demo accordingly.

Issue #4263
2021-10-13 14:46:51 +02:00
Alexander Boettcher
367385aed7 gpu/intel: add more supported Intel GPUs
- Lenovo T470p, T490, T490s

Issue #4260
2021-10-13 14:46:51 +02:00
Alexander Boettcher
0f72356570 gpu/intel: use read out gttm size
and don't assume 8M, which leads to Region_conflicts if size is >8M (X201).

Issue #4260
2021-10-13 14:46:51 +02:00
Christian Helmuth
727fa86088 autopilot: support additional repo directories
-a <repo-dir> appends repo-dir to REPOSITORIES in build.conf
2021-10-13 14:46:51 +02:00
Christian Helmuth
32394c0733 hello: fix resource config / add to autopilot list 2021-10-13 14:46:51 +02:00
Alexander Boettcher
5aa3c56e5c mesa: add gears package
Issue #4263
2021-10-13 14:46:51 +02:00
Alexander Boettcher
0c2edce8ac sculpt: add Gpu service support
Fixes #4263
2021-10-13 14:46:51 +02:00
Alexander Boettcher
2d2ef2a763 mesa: add gpu-iris package providing IRIS driver
Issue #4263
2021-10-13 14:46:51 +02:00
Alexander Boettcher
b6beff673a mesa: add gpu-cpu package providing SWRAST driver
Issue #4263
2021-10-13 14:46:51 +02:00
Sebastian Sumpf
07881f90a9 mesa/libdrm: remove signal EP
This is a left over from Mesa-11 and we exchanged it with a
'wait_and_dispatch_one_io_signal' for synchronous signal waits.

issue #4260
2021-10-13 14:46:50 +02:00
Sebastian Sumpf
3daa94ff2e gpu/intel: Add support for Gen9+
This commit contains features and buf fixes:

* Catch errors during resource allocation

* Because Mesa tries to allocate fence (hardware) registers for each
  batch buffer execution, do not allocate new fences for buffer objects
  that are already fenced

* Add support for global hardware status page. Each context additionally
  has a per-process hardware status page, which we used to set the
  global hardware status page during Vgpu switch. This was obviously
  wrong. There is only one global hardware status page (set once during
  initialization) and a distinct per-process page for contexts.

* Write the sequence number of the currently executing batch buffer to
  dword 52 of the per-process hardware status page. We use the pipe line
  command with QW_WRITE (quad word write), GLOBAL_GTT_IVB disabled
  (address space is per-process address space), and STORE_DATA_INDEX
  enabled (write goes to offset of hardware status page). This command
  used to write to the scratch page. But Linux now uses the first
  reserved word of the per-process hardware status page.

* Add Gen9+ WaEnableGapsTsvCreditFix workaround. This sets the "GAPS TSV
  Credit fix Enable" bit of the Arbiter control register (GARBCNTLREG)
  as described by the documentation this bit should be set by the BIOS
  but is not on most Gen9/9.5 platforms. Not setting this bit leads to
  random GPU hangs.

* Increase the context size from 20 to 22 pages for Gen9. On Gen8 the
  hardware context is 20 pages (1 hardware status page + 19 ring context
  register pages). On Gen9 the size of the ring context registers has
  increased by two pages to 21 pages or 81.3125 KBytes as the IGD
  documentation states.

* The logical ring size in the ring buffer control of the execlist
  context has to be programmed with number of pages - 1. So 0 is 1 page.
  We programmed the actual number of pages before, leading to ring
  buffer execution of NOOPs if page behind our ring buffer was empty or
  GPU hangs if there was data on the page.

issue #4260
2021-10-13 14:46:50 +02:00
Sebastian Sumpf
59b23bc7e1 libdrm: Iris - execute batch buffer synchronous
* Wait for for completion before return from 'execbuffer2'. This makes
  buffer execution synchronous.

* Because the Iris driver manages the virtual address space of the GPU
  and creates one GEM context for each batch buffer we have to map/unmap
  all buffer objects before and after batch buffer execution.

issue #4260
2021-10-13 14:46:50 +02:00
Norman Feske
b7bb6869b4 drivers_interactive-pc: remove platform service
The platform driver should better stay internal to the drivers subsystem
to reinforce the consistency with other drivers_interactive packages.
2021-10-13 14:45:24 +02:00
Norman Feske
e6cdaafb20 tool/ports: use current time as modification time
Fixes #4262
2021-10-13 14:02:16 +02:00
Norman Feske
d072c408ab dde_linux: call init_page_count for each page
The lx_emul_virt_to_pages implementation initialized the page ref
counter only for the first page, leaving the remaining elements in
uninitialized state. This, in turn, rendered the Linux page_pool (as
used by the emac network driver) ineffective, ultimately leading the a
memory leak. The fix changes the call of 'init_page_count' to take the
loop variable as argument.

Issue #4225
2021-10-13 14:02:16 +02:00
Johannes Schlatow
4dacac3dbb depot_autopilot: fix test-trace
Increased number of trace subjects since the test sporadically fails on
some platforms.

Also added a sanity check to print an error message in case we run into
the same issue again.

Fixes genodelabs/genode#4261
2021-10-13 14:02:16 +02:00
Norman Feske
914a41a8bd dde_linux: adjustments for Linux 5.14.1
Issue #4259
2021-10-13 14:01:03 +02:00
Tomasz Gajewski
e6c915ae06 libssh port: immediate mode for ssh poll
This patch adds a switch to internal poll function in libssh that
allows to force this function to immediately return without actually
polling for data and in consequence processing this data. This switch
is used to avoid calling callback functions when flushing output
streams which caused locks due to recursive access to internal
ssh_terminal sessions registry.

Issue #4258
2021-10-13 14:01:02 +02:00
Tomasz Gajewski
6ef6f16cb3 libssh port: backported sftp_server_free
sftp_server_free function was added in 0.9 version of libssh and is
required to avoid memory leaks when clients are disconnecting.

Issue #4258
2021-10-13 14:01:02 +02:00
Tomasz Gajewski
f327a40bbb libssh port: required modifications for sftp
This patch allows to replace sftp packet read and write with
completely asynchronous versions needed to properly hook in existing
ssh_terminal implementation.

Issue #4258
2021-10-13 14:01:02 +02:00
Tomasz Gajewski
e34d1550a4 ssh_terminal: added missing include
Issue #4258
2021-10-13 14:01:02 +02:00
Christian Helmuth
77a5cf7fd4 vbox6: enable audio via OSS plugin 2021-10-13 14:01:02 +02:00
Christian Helmuth
2ba5e4a5b1 libc/oss: check argp per ioctl
... as some ioctls do not require a valid pointer.
2021-10-13 14:01:02 +02:00
Christian Helmuth
5c82045170 vbox6: enable mouse wheel reporting 2021-10-13 14:01:02 +02:00
Christian Helmuth
4a87fcc4cf vbox6: fix TPR handling 2021-10-13 14:01:02 +02:00
Christian Helmuth
e5b828ae8f Switch to genodelabs depot in depot_download test 2021-10-13 14:01:02 +02:00
Martin Stein
f1b72d0281 cxx: define delete operator with alignm. arg
Using 'alignas' in declarations might cause GCC to request for an
implementation of 'operator delete(void*, unsigned long, std::align_val_t)'
although it might actually never be called. This commit adds a dummy
implementation to 'cxx/new_delete.cc' that does nothing more than printing an
error to the log that a proper implementation is missing. This approach is
coherent with our treatment of other global delete operators.

Ref #4217
2021-10-13 14:01:02 +02:00
Martin Stein
ebd140cacb reconstructible: respect alignment of payload
If one has an object X that has a minimum alignment requirement specified
through 'alignas' this requirement is normally inherited by objects that have
object X as member, and by those that have objects as member that have X as
member, and so on... . However, this chain used to get silently interrupted
(dropping the minimum alignment requirement to 8 again) at objects that are
managed with Genode::Reconstructible or Genode::Constructible. In order to fix
this, the commit ensures that Genode::Reconstructible (and therefore also
Genode::Constructible) has at least the minimum alignment requirement (using
'alignas') as the object it manages.

Ref #4217
2021-10-13 13:59:57 +02:00
817 changed files with 16002 additions and 2929 deletions

View File

@@ -1 +1 @@
2021-08-28 eec6b1e516691434c54196615af980b54428eb7e
2021-10-13 05c76f8a5e76e0cc76fd7336c7cf63836ecec35d

View File

@@ -1 +1 @@
2021-08-28 29757bf5413bf396d085bafbc700268e2d1156c4
2021-10-13 0e3f2b9302333cb9bcabfb933a0ab142f41d070c

View File

@@ -1 +1 @@
2021-08-28 60c1ff4c8efe8caa105ff16fdd7fd09ef1ef6991
2021-10-13 af7ceb5c77e20a66ed9f394526766b31a205d89d

View File

@@ -1 +1 @@
2021-08-28 038ab57adceb64cf49000518343c3e14b8481851
2021-10-13 62af5bc4ad5747f1552f1c03882f756ec7f1d63c

View File

@@ -1 +1 @@
2021-08-28 ba949187f071c5af50467ab054d8841788e48548
2021-10-13 6bd8c055af6f1031539124d93164d0ae24f956c8

View File

@@ -1 +1 @@
2021-08-28 52379c07bda990554cf5e18e81d3c3de449b9197
2021-10-13 dabb150f6be49ee72d2d5db160e8885ac7faddd0

View File

@@ -15,7 +15,6 @@
#define _KERNEL__TYPES_H_
/* base-hw includes */
#include <kernel/types.h>
#include <kernel/interface_support.h>
namespace Kernel {

View File

@@ -51,10 +51,9 @@ SRC_CC += pager.cc
SRC_CC += _main.cc
SRC_CC += kernel/cpu.cc
SRC_CC += kernel/cpu_scheduler.cc
SRC_CC += kernel/init.cc
SRC_CC += kernel/ipc_node.cc
SRC_CC += kernel/irq.cc
SRC_CC += kernel/kernel.cc
SRC_CC += kernel/main.cc
SRC_CC += kernel/object.cc
SRC_CC += kernel/signal_receiver.cc
SRC_CC += kernel/thread.cc

View File

@@ -4,9 +4,6 @@
# \date 2014-12-15
#
# add include paths
REP_INC_DIR += src/core/spec/zynq
# add C++ sources
SRC_CC += platform_services.cc

View File

@@ -1,5 +1,10 @@
REP_INC_DIR += src/core/spec/arm_v8
#
# \brief Build config for Genodes core process
# \author Stefan Kalkowski
# \date 2019-05-21
#
# add libraries
LIBS += syscall-hw
# add C++ sources

View File

@@ -4,9 +4,6 @@
# \date 2014-09-02
#
# add include paths
REP_INC_DIR += src/core/spec/cortex_a15
# add C++ sources
SRC_CC += spec/cortex_a15/cpu.cc
SRC_CC += kernel/cpu_mp.cc

View File

@@ -4,9 +4,6 @@
# \date 2014-09-02
#
# add include paths
REP_INC_DIR += src/core/spec/cortex_a8
# add C++ sources
SRC_CC += kernel/cpu_up.cc
SRC_CC += kernel/lock.cc

View File

@@ -4,11 +4,9 @@
# \date 2014-09-02
#
# add include paths
REP_INC_DIR += src/core/spec/cortex_a9
# add C++ sources
SRC_CC += spec/cortex_a9/board.cc
SRC_CC += spec/cortex_a9/cpu.cc
SRC_CC += spec/arm/cortex_a9_private_timer.cc
SRC_CC += spec/arm/gicv2.cc
SRC_CC += spec/arm/kernel/lock.cc

View File

@@ -6,6 +6,7 @@
#
# add include paths
REP_INC_DIR += src/core/board/pc
REP_INC_DIR += src/core/spec/x86_64
LIBS += syscall-hw

View File

@@ -1 +1 @@
2021-06-24 5626884aba14848b98e9aad4d00714fa5ea7c84a
2021-10-13 e4a9e369a9c321759fdc73d5e2b2b9ac1e2d7795

View File

@@ -1 +1 @@
2021-08-28 7bb57a2e769700abf6fd2057d9e003abfa98299b
2021-10-13 11943f5bc31d6ebd43c67e008cf12cc7e2ca2934

View File

@@ -1 +1 @@
2021-08-28 76c6eeb920f7d892be4ed670b8ee88f1ddb6706d
2021-10-13 69215f704c6797b15bcacfc11a2709d5b65019e9

View File

@@ -1 +1 @@
2021-08-28 2ff3b759c6df9a5c461e9c259909e9804ad17ed7
2021-10-13 78f942508805ec6afc8d75550d5b67f38664b5f6

View File

@@ -1 +1 @@
2021-08-28 a78c91c4f6fbcdad8e5cb77c4995c306f6e7f383
2021-10-13 85df38295bad953fc194078cc22d31f1acfa4c08

View File

@@ -1 +1 @@
2021-08-28 f1a2ea4fa36605cc76483a40040c7e0bd1921695
2021-10-13 e23737af156d1967b1d59c690b62f5538856a85c

View File

@@ -1 +1 @@
2021-08-28 c0c4cabd03be175d380f036de30106881eeb6651
2021-10-13 cf4e82d22cc8f343aa16f5b996e4cf3cc9608d69

View File

@@ -1 +1 @@
2021-08-28 a8c4f0782c8653dc18e5ecd20bb3eb11a8d2984b
2021-10-13 ec5754c900404b3d4e1594fa5e36630afb58df0e

View File

@@ -1 +1 @@
2021-08-28 67253c6a4c652664896221c8b79fb82fff01dc57
2021-10-13 910b8cd795a9326fc0b3fcd9afef8d35abd60c8b

View File

@@ -1 +1 @@
2021-08-28 d0b3d729f5a549c885dab4dd7b4bc930daa5f6dc
2021-10-13 67dab318aac08eb348e660cfe11c711a9aea1198

View File

@@ -1 +1 @@
2021-08-28 c850168cfba0ff5bbfb1048c2a58552dd36dfb0f
2021-10-13 e43c142340fd7f0fcae846c5203c308fe50a979e

View File

@@ -1 +1 @@
2021-08-28 e4de82cc87762b272d28d6d632c967a575197e11
2021-10-13 ae6959ca0ea79c0b8611c7e4a56e5cdb634cfaf1

View File

@@ -1 +1 @@
2021-08-28 0e5bcaca15c5738839c7bae0bcdc1cbace99018b
2021-10-13 0aed7db811134981a69cf1f4bb5cef3ba7e9a7c2

View File

@@ -1 +1 @@
2021-08-28 2e6f58ac4d73642b0241f211c0738ad2b47b5f6a
2021-10-13 3233ce8f7b5f3246ace4fbdf810b1632cb147a1a

View File

@@ -15,10 +15,14 @@
#ifndef _CORE__SPEC__IMX53_QSB__BOARD_H_
#define _CORE__SPEC__IMX53_QSB__BOARD_H_
/* base-hw internal includes */
#include <hw/spec/arm/imx_tzic.h>
#include <hw/spec/arm/imx53_qsb_board.h>
/* base-hw Core includes */
#include <spec/arm/imx_epit.h>
#include <spec/arm/trustzone_board.h>
#include <spec/cortex_a8/cpu.h>
namespace Board { using namespace Hw::Imx53_qsb_board; }

View File

@@ -14,15 +14,21 @@
#ifndef _CORE__SPEC__IMX6Q_SABRELITE__BOARD_H_
#define _CORE__SPEC__IMX6Q_SABRELITE__BOARD_H_
/* base-hw internal includes */
#include <hw/spec/arm/gicv2.h>
#include <hw/spec/arm/imx6q_sabrelite_board.h>
/* base-hw Core includes */
#include <spec/arm/cortex_a9_private_timer.h>
#include <spec/cortex_a9/cpu.h>
namespace Board {
using namespace Hw::Imx6q_sabrelite_board;
using Pic = Hw::Gicv2;
class Global_interrupt_controller { };
class Pic : public Hw::Gicv2 { public: Pic(Global_interrupt_controller &) { } };
using L2_cache = Hw::Pl310;
L2_cache & l2_cache();

View File

@@ -14,11 +14,15 @@
#ifndef _CORE__SPEC__IMX7D_SABRE__BOARD_H_
#define _CORE__SPEC__IMX7D_SABRE__BOARD_H_
/* base-hw internal includes */
#include <hw/spec/arm/imx7d_sabre_board.h>
/* base-hw Core includes */
#include <spec/arm/virtualization/gicv2.h>
#include <spec/arm/generic_timer.h>
#include <spec/arm/cpu/vm_state_virtualization.h>
#include <spec/arm/virtualization/board.h>
#include <spec/cortex_a15/cpu.h>
namespace Board {

View File

@@ -14,10 +14,18 @@
#ifndef _CORE__SPEC__IMX8Q_EVK__BOARD_H_
#define _CORE__SPEC__IMX8Q_EVK__BOARD_H_
/* base-hw internal includes */
#include <hw/spec/arm_64/imx8q_evk_board.h>
/* base-hw Core includes */
#include <spec/arm/generic_timer.h>
#include <spec/arm/virtualization/gicv3.h>
#include <spec/arm_v8/cpu.h>
/* base-hw includes */
#include <spec/arm_64/cpu/vm_state_virtualization.h>
/* base-hw Core includes */
#include <spec/arm/virtualization/board.h>
namespace Board {

View File

@@ -14,15 +14,21 @@
#ifndef _CORE__SPEC__NIT6_SOLOX__BOARD_H_
#define _CORE__SPEC__NIT6_SOLOX__BOARD_H_
/* base-hw internal includes */
#include <hw/spec/arm/gicv2.h>
#include <hw/spec/arm/nit6_solox_board.h>
/* base-hw Core includes */
#include <spec/arm/cortex_a9_private_timer.h>
#include <spec/cortex_a9/cpu.h>
namespace Board {
using namespace Hw::Nit6_solox_board;
using Pic = Hw::Gicv2;
class Global_interrupt_controller { };
class Pic : public Hw::Gicv2 { public: Pic(Global_interrupt_controller &) { } };
using L2_cache = Hw::Pl310;
L2_cache & l2_cache();

View File

@@ -14,15 +14,20 @@
#ifndef _CORE__SPEC__PBXA9__BOARD_H_
#define _CORE__SPEC__PBXA9__BOARD_H_
/* base-hw internal includes */
#include <hw/spec/arm/gicv2.h>
#include <hw/spec/arm/pbxa9_board.h>
/* base-hw Core includes */
#include <spec/arm/cortex_a9_private_timer.h>
#include <spec/cortex_a9/cpu.h>
namespace Board {
using namespace Hw::Pbxa9_board;
using Pic = Hw::Gicv2;
class Global_interrupt_controller { };
class Pic : public Hw::Gicv2 { public: Pic(Global_interrupt_controller &) { } };
L2_cache & l2_cache();
}

View File

@@ -11,17 +11,23 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _CORE__SPEC__X86_64__BOARD_H_
#define _CORE__SPEC__X86_64__BOARD_H_
#ifndef _BOARD_H_
#define _BOARD_H_
/* base-hw internal includes */
#include <hw/spec/x86_64/pc_board.h>
/* base-hw Core includes */
#include <spec/x86_64/pic.h>
#include <spec/x86_64/pit.h>
#include <spec/x86_64/cpu.h>
namespace Board {
using namespace Hw::Pc_board;
class Pic : public Local_interrupt_controller { };
enum {
VECTOR_REMAP_BASE = 48,
TIMER_VECTOR_KERNEL = 32,
@@ -30,4 +36,4 @@ namespace Board {
};
}
#endif /* _CORE__SPEC__X86_64__BOARD_H_ */
#endif /* _BOARD_H_ */

View File

@@ -14,13 +14,14 @@
#ifndef _CORE__SPEC__RISCV_QEMU__BOARD_H_
#define _CORE__SPEC__RISCV_QEMU__BOARD_H_
/* base-hw internal includes */
#include <hw/spec/riscv/qemu_board.h>
/* base-hw Core includes */
#include <spec/riscv/pic.h>
#include <spec/riscv/cpu.h>
#include <spec/riscv/timer.h>
namespace Board { using namespace Hw::Riscv_board; }
#include <spec/riscv/timer.h>
#endif /* _CORE__SPEC__RISCV_QEMU__BOARD_H_ */

View File

@@ -15,9 +15,13 @@
#ifndef _CORE__SPEC__RPI__BOARD_H_
#define _CORE__SPEC__RPI__BOARD_H_
/* base-hw internal includes */
#include <hw/spec/arm/rpi_board.h>
/* base-hw Core includes */
#include <spec/arm/bcm2835_pic.h>
#include <spec/arm/bcm2835_system_timer.h>
#include <spec/arm_v6/cpu.h>
namespace Board { using namespace Hw::Rpi_board; };

View File

@@ -14,9 +14,13 @@
#ifndef _CORE__SPEC__RPI3__BOARD_H_
#define _CORE__SPEC__RPI3__BOARD_H_
/* base-hw internal includes */
#include <hw/spec/arm_64/rpi3_board.h>
/* base-hw Core includes */
#include <spec/arm/bcm2837_pic.h>
#include <spec/arm/generic_timer.h>
#include <spec/arm_v8/cpu.h>
namespace Board {

View File

@@ -15,10 +15,14 @@
#ifndef _CORE__SPEC__USB_ARMORY__BOARD_H_
#define _CORE__SPEC__USB_ARMORY__BOARD_H_
/* base-hw internal includes */
#include <hw/spec/arm/imx_tzic.h>
#include <hw/spec/arm/usb_armory_board.h>
/* base-hw Core includes */
#include <spec/arm/imx_epit.h>
#include <spec/arm/trustzone_board.h>
#include <spec/cortex_a8/cpu.h>
namespace Board { using namespace Hw::Usb_armory_board; }

View File

@@ -14,11 +14,19 @@
#ifndef _SRC__CORE__SPEC__VIRT__QEMU_H_
#define _SRC__CORE__SPEC__VIRT__QEMU_H_
/* base-hw internal includes */
#include <hw/spec/arm/virt_qemu_board.h>
/* base-hw Core includes */
#include <spec/arm/virtualization/gicv2.h>
#include <spec/arm/generic_timer.h>
/* base-hw includes */
#include <spec/arm/cpu/vm_state_virtualization.h>
/* base-hw Core includes */
#include <spec/arm/virtualization/board.h>
#include <spec/cortex_a15/cpu.h>
namespace Kernel { class Cpu; }

View File

@@ -14,13 +14,20 @@
#ifndef _SRC__CORE__SPEC__VIRT_QEMU_64_H_
#define _SRC__CORE__SPEC__VIRT_QEMU_64_H_
/* base-hw internal includes */
#include <hw/spec/arm/virt_qemu_board.h>
/* base-hw Core includes */
#include <spec/arm/generic_timer.h>
#include <spec/arm/virtualization/gicv3.h>
/* base-hw includes */
#include <spec/arm_64/cpu/vm_state_virtualization.h>
#include <translation_table.h>
/* base-hw Core includes */
#include <kernel/configuration.h>
#include <kernel/irq.h>
#include <spec/arm_v8/cpu.h>
namespace Board {
@@ -51,13 +58,21 @@ namespace Kernel {
struct Board::Vcpu_context
{
struct Vm_irq : Kernel::Irq
class Vm_irq : public Kernel::Irq
{
Vm_irq(unsigned const irq, Kernel::Cpu &);
virtual ~Vm_irq() {};
private:
virtual void handle(Kernel::Cpu &, Kernel::Vm & vm, unsigned irq);
void occurred() override;
Kernel::Cpu &_cpu;
public:
Vm_irq(unsigned const irq, Kernel::Cpu &cpu);
virtual ~Vm_irq() {};
virtual void handle(Kernel::Vm &vm, unsigned irq);
void occurred() override;
};
@@ -65,7 +80,7 @@ struct Board::Vcpu_context
{
Pic_maintainance_irq(Kernel::Cpu &);
void handle(Kernel::Cpu &, Kernel::Vm &, unsigned) override { }
void handle(Kernel::Vm &, unsigned) override { }
};

View File

@@ -15,17 +15,23 @@
#ifndef _CORE__SPEC__WAND_QUAD__BOARD_H_
#define _CORE__SPEC__WAND_QUAD__BOARD_H_
/* base-hw internal includes */
#include <hw/spec/arm/gicv2.h>
#include <hw/spec/arm/wand_quad_board.h>
/* base-hw Core includes */
#include <spec/arm/cortex_a9_private_timer.h>
#include <spec/cortex_a9/cpu.h>
namespace Board {
using namespace Hw::Wand_quad_board;
using L2_cache = Hw::Pl310;
using Pic = Hw::Gicv2;
class Global_interrupt_controller { };
class Pic : public Hw::Gicv2 { public: Pic(Global_interrupt_controller &) { } };
L2_cache & l2_cache();
enum {

View File

@@ -16,15 +16,20 @@
#ifndef _CORE__SPEC__ZYNQ_QEMU__BOARD_H_
#define _CORE__SPEC__ZYNQ_QEMU__BOARD_H_
/* base-hw internal includes */
#include <hw/spec/arm/gicv2.h>
#include <hw/spec/arm/zynq_qemu_board.h>
/* base-hw Core includes */
#include <spec/arm/cortex_a9_private_timer.h>
#include <spec/cortex_a9/cpu.h>
namespace Board {
using namespace Hw::Zynq_qemu_board;
using Pic = Hw::Gicv2;
class Global_interrupt_controller { };
class Pic : public Hw::Gicv2 { public: Pic(Global_interrupt_controller &) { } };
L2_cache & l2_cache();
}

View File

@@ -14,7 +14,6 @@
/* core includes */
#include <kernel/cpu.h>
#include <kernel/kernel.h>
#include <kernel/thread.h>
#include <kernel/irq.h>
#include <kernel/pd.h>
@@ -22,15 +21,9 @@
#include <hw/assert.h>
#include <hw/boot_info.h>
/* base-internal includes */
#include <base/internal/unmanaged_singleton.h>
using namespace Kernel;
Kernel::Cpu_pool &Kernel::cpu_pool() { return *unmanaged_singleton<Cpu_pool>(); }
/*************
** Cpu_job **
*************/
@@ -52,22 +45,22 @@ void Cpu_job::_yield()
}
void Cpu_job::_interrupt(unsigned const /* cpu_id */)
void Cpu_job::_interrupt(Irq::Pool &user_irq_pool, unsigned const /* cpu_id */)
{
/* determine handling for specific interrupt */
/* let the IRQ controller take a pending IRQ for handling, if any */
unsigned irq_id;
if (_cpu->pic().take_request(irq_id))
/* is the interrupt a cpu-local one */
if (!_cpu->interrupt(irq_id)) {
/* let the CPU of this job handle the IRQ if it is a CPU-local one */
if (!_cpu->handle_if_cpu_local_interrupt(irq_id)) {
/* it needs to be a user interrupt */
User_irq * irq = User_irq::object(irq_id);
/* it isn't a CPU-local IRQ, so, it must be a user IRQ */
User_irq * irq = User_irq::object(user_irq_pool, irq_id);
if (irq) irq->occurred();
else Genode::raw("Unknown interrupt ", irq_id);
}
/* end interrupt request at controller */
/* let the IRQ controller finish the currently taken IRQ */
_cpu->pic().finish_request();
}
@@ -110,14 +103,18 @@ Cpu_job::~Cpu_job()
extern "C" void idle_thread_main(void);
Cpu::Idle_thread::Idle_thread(Cpu &cpu)
Cpu::Idle_thread::Idle_thread(Board::Address_space_id_allocator &addr_space_id_alloc,
Irq::Pool &user_irq_pool,
Cpu_pool &cpu_pool,
Cpu &cpu,
Pd &core_pd)
:
Thread("idle")
Thread { addr_space_id_alloc, user_irq_pool, cpu_pool, core_pd, "idle" }
{
regs->ip = (addr_t)&idle_thread_main;
affinity(cpu);
Thread::_pd = &core_pd();
Thread::_pd = &core_pd;
}
@@ -134,7 +131,7 @@ void Cpu::schedule(Job * const job)
}
bool Cpu::interrupt(unsigned const irq_id)
bool Cpu::handle_if_cpu_local_interrupt(unsigned const irq_id)
{
Irq * const irq = object(irq_id);
@@ -177,12 +174,21 @@ addr_t Cpu::stack_start()
}
Cpu::Cpu(unsigned const id, Inter_processor_work_list & global_work_list)
Cpu::Cpu(unsigned const id,
Board::Address_space_id_allocator &addr_space_id_alloc,
Irq::Pool &user_irq_pool,
Cpu_pool &cpu_pool,
Pd &core_pd,
Board::Global_interrupt_controller &global_irq_ctrl)
:
_id(id), _timer(*this),
_scheduler(_idle, _quota(), _fill()), _idle(*this),
_ipi_irq(*this),
_global_work_list(global_work_list)
_id { id },
_pic { global_irq_ctrl },
_timer { *this },
_scheduler { _idle, _quota(), _fill() },
_idle { addr_space_id_alloc, user_irq_pool, cpu_pool, *this,
core_pd },
_ipi_irq { *this },
_global_work_list { cpu_pool.work_list() }
{
_arch_init();
}
@@ -192,17 +198,22 @@ Cpu::Cpu(unsigned const id, Inter_processor_work_list & global_work_list)
** Cpu_pool **
**************/
bool Cpu_pool::initialize()
void
Cpu_pool::
initialize_executing_cpu(Board::Address_space_id_allocator &addr_space_id_alloc,
Irq::Pool &user_irq_pool,
Pd &core_pd,
Board::Global_interrupt_controller &global_irq_ctrl)
{
unsigned id = Cpu::executing_id();
_cpus[id].construct(id, _global_work_list);
return --_initialized == 0;
_cpus[id].construct(
id, addr_space_id_alloc, user_irq_pool, *this, core_pd, global_irq_ctrl);
}
Cpu & Cpu_pool::cpu(unsigned const id)
{
assert(id < _count && _cpus[id].constructed());
assert(id < _nr_of_cpus && _cpus[id].constructed());
return *_cpus[id];
}
@@ -210,7 +221,7 @@ Cpu & Cpu_pool::cpu(unsigned const id)
using Boot_info = Hw::Boot_info<Board::Boot_info>;
Cpu_pool::Cpu_pool()
Cpu_pool::Cpu_pool(unsigned nr_of_cpus)
:
_count(reinterpret_cast<Boot_info*>(Hw::Mm::boot_info().base)->cpus)
_nr_of_cpus(nr_of_cpus)
{ }

View File

@@ -35,11 +35,6 @@ namespace Kernel {
* Provides a CPU object for every available CPU
*/
class Cpu_pool;
/**
* Return singleton of CPU pool
*/
Cpu_pool &cpu_pool();
}
@@ -107,12 +102,16 @@ class Kernel::Cpu : public Genode::Cpu, private Irq::Pool, private Timeout
/**
* Construct idle context for CPU 'cpu'
*/
Idle_thread(Cpu &cpu);
Idle_thread(Board::Address_space_id_allocator &addr_space_id_alloc,
Irq::Pool &user_irq_pool,
Cpu_pool &cpu_pool,
Cpu &cpu,
Pd &core_pd);
};
unsigned const _id;
Board::Pic _pic {};
Board::Pic _pic;
Timer _timer;
Cpu_scheduler _scheduler;
Idle_thread _idle;
@@ -132,8 +131,12 @@ class Kernel::Cpu : public Genode::Cpu, private Irq::Pool, private Timeout
/**
* Construct object for CPU 'id'
*/
Cpu(unsigned const id,
Inter_processor_work_list & global_work_list);
Cpu(unsigned const id,
Board::Address_space_id_allocator &addr_space_id_alloc,
Irq::Pool &user_irq_pool,
Cpu_pool &cpu_pool,
Pd &core_pd,
Board::Global_interrupt_controller &global_irq_ctrl);
static inline unsigned primary_id() { return 0; }
@@ -148,7 +151,7 @@ class Kernel::Cpu : public Genode::Cpu, private Irq::Pool, private Timeout
* \param irq_id id of the interrupt that occured
* \returns true if the interrupt belongs to this CPU, otherwise false
*/
bool interrupt(unsigned const irq_id);
bool handle_if_cpu_local_interrupt(unsigned const irq_id);
/**
* Schedule 'job' at this CPU
@@ -197,15 +200,18 @@ class Kernel::Cpu_pool
private:
Inter_processor_work_list _global_work_list {};
unsigned _count;
unsigned _initialized { _count };
unsigned _nr_of_cpus;
Genode::Constructible<Cpu> _cpus[NR_OF_CPUS];
public:
Cpu_pool();
Cpu_pool(unsigned nr_of_cpus);
bool initialize();
void
initialize_executing_cpu(Board::Address_space_id_allocator &addr_space_id_alloc,
Irq::Pool &user_irq_pool,
Pd &core_pd,
Board::Global_interrupt_controller &global_irq_ctrl);
/**
* Return object of CPU 'id'
@@ -225,11 +231,13 @@ class Kernel::Cpu_pool
template <typename FUNC>
void for_each_cpu(FUNC const &func)
{
for (unsigned i = 0; i < _count; i++) func(cpu(i));
for (unsigned i = 0; i < _nr_of_cpus; i++) func(cpu(i));
}
Inter_processor_work_list & work_list() {
return _global_work_list; }
unsigned nr_of_cpus() { return _nr_of_cpus; }
};
#endif /* _CORE__KERNEL__CPU_H_ */

View File

@@ -51,7 +51,7 @@ class Kernel::Cpu_job : private Cpu_share
/**
* Handle interrupt exception that occured during execution on CPU 'id'
*/
void _interrupt(unsigned const id);
void _interrupt(Irq::Pool &user_irq_pool, unsigned const id);
/**
* Activate our own CPU-share

View File

@@ -50,7 +50,7 @@ void Cpu::trigger_ip_interrupt()
Cpu::Ipi::Ipi(Cpu & cpu)
:
Irq(Board::Pic::IPI, cpu), cpu(cpu)
Irq(Board::Pic::IPI, cpu, cpu.pic()), cpu(cpu)
{
cpu.pic().unmask(Board::Pic::IPI, cpu.id());
}

View File

@@ -34,7 +34,7 @@ void Cpu_scheduler::_reset_claims(unsigned const p)
void Cpu_scheduler::_next_round()
{
_residual = _quota;
_for_each_prio([&] (unsigned const p) { _reset_claims(p); });
_for_each_prio([&] (Cpu_priority const p, bool &) { _reset_claims(p); });
}
@@ -90,21 +90,23 @@ void Cpu_scheduler::_head_filled(unsigned const r)
bool Cpu_scheduler::_claim_for_head()
{
for (signed p = Prio::MAX; p > Prio::MIN - 1; p--) {
bool result { false };
_for_each_prio([&] (Cpu_priority const p, bool &cancel_for_each_prio) {
Double_list_item<Cpu_share> *const item { _rcl[p].head() };
if (!item)
continue;
return;
Cpu_share &share { item->payload() };
if (!share._claim)
continue;
return;
_set_head(share, share._claim, 1);
return 1;
}
return 0;
result = true;
cancel_for_each_prio = true;
});
return result;
}

View File

@@ -47,27 +47,28 @@ class Kernel::Cpu_priority
public:
enum {
MIN = 0,
MAX = cpu_priorities - 1,
};
static constexpr unsigned min() { return 0; }
static constexpr unsigned max() { return cpu_priorities - 1; }
/**
* Construct priority with value 'v'
*/
Cpu_priority(signed const v) : _value(Genode::min(v, MAX)) { }
Cpu_priority(unsigned const v)
:
_value { Genode::min(v, max()) }
{ }
/*
* Standard operators
*/
Cpu_priority &operator =(signed const v)
Cpu_priority &operator =(unsigned const v)
{
_value = Genode::min(v, MAX);
_value = Genode::min(v, max());
return *this;
}
operator signed() const { return _value; }
operator unsigned() const { return _value; }
};
@@ -79,7 +80,7 @@ class Kernel::Cpu_share
Double_list_item<Cpu_share> _fill_item { *this };
Double_list_item<Cpu_share> _claim_item { *this };
signed const _prio;
Cpu_priority const _prio;
unsigned _quota;
unsigned _claim;
unsigned _fill { 0 };
@@ -93,7 +94,7 @@ class Kernel::Cpu_share
* \param p claimed priority
* \param q claimed quota
*/
Cpu_share(signed const p, unsigned const q)
Cpu_share(Cpu_priority const p, unsigned const q)
: _prio(p), _quota(q), _claim(q) { }
/*
@@ -111,8 +112,8 @@ class Kernel::Cpu_scheduler
typedef Cpu_share Share;
typedef Cpu_priority Prio;
Double_list<Cpu_share> _rcl[Prio::MAX + 1]; /* ready claims */
Double_list<Cpu_share> _ucl[Prio::MAX + 1]; /* unready claims */
Double_list<Cpu_share> _rcl[Prio::max() + 1]; /* ready claims */
Double_list<Cpu_share> _ucl[Prio::max() + 1]; /* unready claims */
Double_list<Cpu_share> _fills { }; /* ready fills */
Share &_idle;
Share *_head = nullptr;
@@ -125,8 +126,15 @@ class Kernel::Cpu_scheduler
bool _need_to_schedule { true };
time_t _last_time { 0 };
template <typename F> void _for_each_prio(F f) {
for (signed p = Prio::MAX; p > Prio::MIN - 1; p--) { f(p); } }
template <typename F> void _for_each_prio(F f)
{
bool cancel_for_each_prio { false };
for (unsigned p = Prio::max(); p != Prio::min() - 1; p--) {
f(p, cancel_for_each_prio);
if (cancel_for_each_prio)
return;
}
}
static void _reset(Cpu_share &share);

View File

@@ -19,4 +19,7 @@ void Kernel::Cpu::Ipi::occurred() { }
void Kernel::Cpu::trigger_ip_interrupt() { }
Kernel::Cpu::Ipi::Ipi(Kernel::Cpu & cpu) : Irq(~0U, cpu), cpu(cpu) { }
Kernel::Cpu::Ipi::Ipi(Kernel::Cpu & cpu)
:
Irq(~0U, cpu, cpu.pic()), cpu(cpu)
{ }

View File

@@ -1,85 +0,0 @@
/*
* \brief Common kernel initialization
* \author Martin Stein
* \author Stefan Kalkowski
* \date 2015-12-20
*/
/*
* Copyright (C) 2015-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* core includes */
#include <kernel/pd.h>
#include <kernel/cpu.h>
#include <kernel/kernel.h>
#include <kernel/lock.h>
#include <platform_pd.h>
#include <board.h>
#include <platform_thread.h>
/* base includes */
#include <base/internal/unmanaged_singleton.h>
using namespace Kernel;
static_assert(sizeof(Genode::sizet_arithm_t) >= 2 * sizeof(size_t),
"Bad result type for size_t arithmetics.");
Pd &Kernel::core_pd() {
return unmanaged_singleton<Genode::Core_platform_pd>()->kernel_pd(); }
extern "C" void kernel_init();
/**
* Setup kernel environment
*/
extern "C" void kernel_init()
{
static volatile bool lock_ready = false;
static volatile bool pool_ready = false;
static volatile bool kernel_ready = false;
/**
* It is essential to guard the initialization of the data_lock object
* in the SMP case, because otherwise the __cxa_guard_aquire of the cxx
* library contention path might get called, which ends up in
* calling a Semaphore, which will call Kernel::stop_thread() or
* Kernel::yield() system-calls in this code
*/
while (Cpu::executing_id() != Cpu::primary_id() && !lock_ready) { ; }
{
Lock::Guard guard(data_lock());
lock_ready = true;
/* initialize current cpu */
pool_ready = cpu_pool().initialize();
};
/* wait until all cpus have initialized their corresponding cpu object */
while (!pool_ready) { ; }
/* the boot-cpu initializes the rest of the kernel */
if (Cpu::executing_id() == Cpu::primary_id()) {
Lock::Guard guard(data_lock());
Genode::log("");
Genode::log("kernel initialized");
Core_thread::singleton();
kernel_ready = true;
} else {
/* secondary cpus spin until the kernel is initialized */
while (!kernel_ready) {;}
}
kernel();
}

View File

@@ -20,7 +20,6 @@
/* core includes */
#include <kernel/ipc_node.h>
#include <kernel/kernel.h>
#include <kernel/thread.h>
using namespace Kernel;

View File

@@ -12,37 +12,32 @@
*/
/* core includes */
#include <kernel/kernel.h>
#include <kernel/cpu.h>
#include <kernel/irq.h>
void Kernel::Irq::disable() const
{
cpu_pool().executing_cpu().pic().mask(_irq_nr);
_pic.mask(_irq_nr);
}
void Kernel::Irq::enable() const
{
cpu_pool().executing_cpu().pic().unmask(_irq_nr, Cpu::executing_id());
_pic.unmask(_irq_nr, Cpu::executing_id());
}
Kernel::Irq::Pool &Kernel::User_irq::_pool()
{
static Irq::Pool p;
return p;
}
Kernel::User_irq::User_irq(unsigned const irq,
Genode::Irq_session::Trigger trigger,
Genode::Irq_session::Polarity polarity,
Signal_context & context)
Kernel::User_irq::User_irq(unsigned const irq,
Genode::Irq_session::Trigger trigger,
Genode::Irq_session::Polarity polarity,
Signal_context &context,
Board::Pic &pic,
Irq::Pool &user_irq_pool)
:
Irq(irq, _pool()), _context(context)
Irq { irq, user_irq_pool, pic },
_context { context }
{
disable();
cpu_pool().executing_cpu().pic().irq_mode(_irq_nr, trigger, polarity);
_pic.irq_mode(_irq_nr, trigger, polarity);
}

View File

@@ -19,12 +19,15 @@
#include <irq_session/irq_session.h>
#include <util/avl_tree.h>
/* base-internal includes */
#include <base/internal/unmanaged_singleton.h>
/* core includes */
#include <kernel/signal_receiver.h>
namespace Board {
class Pic;
}
namespace Kernel {
/**
@@ -67,8 +70,9 @@ class Kernel::Irq : Genode::Avl_node<Irq>
protected:
unsigned _irq_nr; /* kernel name of the interrupt */
Pool &_pool;
unsigned _irq_nr; /* kernel name of the interrupt */
Pool &_irq_pool;
Board::Pic &_pic;
public:
@@ -78,14 +82,18 @@ class Kernel::Irq : Genode::Avl_node<Irq>
* \param irq interrupt number
* \param pool pool this interrupt shall belong to
*/
Irq(unsigned const irq, Pool &pool)
Irq(unsigned const irq,
Pool &irq_pool,
Board::Pic &pic)
:
_irq_nr(irq), _pool(pool)
_irq_nr { irq },
_irq_pool { irq_pool },
_pic { pic }
{
_pool.insert(this);
_irq_pool.insert(this);
}
virtual ~Irq() { _pool.remove(this); }
virtual ~Irq() { _irq_pool.remove(this); }
/**
* Handle occurence of the interrupt
@@ -131,20 +139,17 @@ class Kernel::User_irq : public Kernel::Irq
Kernel::Object _kernel_object { *this };
Signal_context &_context;
/**
* Get map that provides all user interrupts by their kernel names
*/
static Irq::Pool &_pool();
public:
/**
* Construct object that signals interrupt 'irq' via signal 'context'
*/
User_irq(unsigned const irq,
Genode::Irq_session::Trigger trigger,
Genode::Irq_session::Polarity polarity,
Signal_context & context);
User_irq(unsigned const irq,
Genode::Irq_session::Trigger trigger,
Genode::Irq_session::Polarity polarity,
Signal_context &context,
Board::Pic &pic,
Irq::Pool &user_irq_pool);
/**
* Destructor
@@ -165,8 +170,8 @@ class Kernel::User_irq : public Kernel::Irq
/**
* Handle occurence of interrupt 'irq'
*/
static User_irq * object(unsigned const irq) {
return dynamic_cast<User_irq*>(_pool().object(irq)); }
static User_irq * object(Irq::Pool &user_irq_pool, unsigned const irq) {
return dynamic_cast<User_irq*>(user_irq_pool.object(irq)); }
/**
* Syscall to create user irq object

View File

@@ -1,35 +0,0 @@
/*
* \brief Kernel entrypoint
* \author Martin Stein
* \author Stefan Kalkowski
* \date 2011-10-20
*/
/*
* Copyright (C) 2011-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* core includes */
#include <kernel/cpu.h>
#include <kernel/lock.h>
#include <kernel/kernel.h>
extern "C" void kernel()
{
using namespace Kernel;
Cpu &cpu = cpu_pool().cpu(Cpu::executing_id());
Cpu_job * new_job;
{
Lock::Guard guard(data_lock());
new_job = &cpu.schedule();
}
new_job->proceed(cpu);
}

View File

@@ -1,31 +0,0 @@
/*
* \brief Singlethreaded minimalistic kernel
* \author Martin Stein
* \author Stefan Kalkowski
* \date 2013-09-30
*/
/*
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _CORE__KERNEL__KERNEL_H_
#define _CORE__KERNEL__KERNEL_H_
/**
* Main routine of every kernel pass
*/
extern "C" void kernel();
namespace Kernel {
class Pd;
Pd &core_pd();
}
#endif /* _CORE__KERNEL__KERNEL_H_ */

View File

@@ -11,19 +11,13 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#include <base/lock_guard.h>
/* Genode includes */
#include <cpu/atomic.h>
#include <cpu/memory_barrier.h>
/* base-hw Core includes */
#include <kernel/cpu.h>
#include <kernel/lock.h>
#include <kernel/kernel.h>
Kernel::Lock & Kernel::data_lock()
{
static Kernel::Lock lock;
return lock;
}
void Kernel::Lock::lock()

View File

@@ -15,12 +15,10 @@
#ifndef _CORE__SPEC__SMP__KERNEL__LOCK_H_
#define _CORE__SPEC__SMP__KERNEL__LOCK_H_
namespace Kernel {
/* Genode includes */
#include <base/lock_guard.h>
class Lock;
Lock & data_lock();
}
namespace Kernel { class Lock; }
class Kernel::Lock

View File

@@ -0,0 +1,239 @@
/*
* \brief Main object of the kernel
* \author Martin Stein
* \author Stefan Kalkowski
* \date 2021-07-09
*/
/*
* Copyright (C) 2021 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* base includes */
#include <util/reconstructible.h>
/* base Core includes */
#include <map_local.h>
/* base-hw Core includes */
#include <kernel/cpu.h>
#include <kernel/lock.h>
#include <kernel/main.h>
#include <platform_pd.h>
#include <platform_thread.h>
/* base-hw-internal includes */
#include <hw/boot_info.h>
namespace Kernel {
class Main;
}
class Kernel::Main
{
private:
friend void main_handle_kernel_entry();
friend void main_initialize_and_handle_kernel_entry();
friend time_t main_read_idle_thread_execution_time(unsigned cpu_idx);
friend void main_print_char(char c);
enum { SERIAL_BAUD_RATE = 115200 };
static Main *_instance;
Lock _data_lock { };
Cpu_pool _cpu_pool;
Irq::Pool _user_irq_pool { };
Board::Address_space_id_allocator _addr_space_id_alloc { };
Genode::Core_platform_pd _core_platform_pd { _addr_space_id_alloc };
Genode::Constructible<Core_main_thread> _core_main_thread { };
Board::Global_interrupt_controller _global_irq_ctrl { };
Board::Serial _serial { Genode::Platform::mmio_to_virt(Board::UART_BASE),
Board::UART_CLOCK,
SERIAL_BAUD_RATE };
void _handle_kernel_entry();
Main(unsigned nr_of_cpus);
public:
static Genode::Platform_pd &core_platform_pd();
};
Kernel::Main *Kernel::Main::_instance;
Kernel::Main::Main(unsigned nr_of_cpus)
:
_cpu_pool { nr_of_cpus }
{ }
void Kernel::Main::_handle_kernel_entry()
{
Cpu &cpu = _cpu_pool.cpu(Cpu::executing_id());
Cpu_job * new_job;
{
Lock::Guard guard(_data_lock);
new_job = &cpu.schedule();
}
new_job->proceed(cpu);
}
void Kernel::main_handle_kernel_entry()
{
Main::_instance->_handle_kernel_entry();
}
void Kernel::main_initialize_and_handle_kernel_entry()
{
static_assert(sizeof(Genode::sizet_arithm_t) >= 2 * sizeof(size_t),
"Bad result type for size_t arithmetics.");
using Boot_info = Hw::Boot_info<Board::Boot_info>;
static volatile bool instance_initialized { false };
static volatile unsigned nr_of_initialized_cpus { 0 };
static volatile bool kernel_initialized { false };
Boot_info &boot_info {
*reinterpret_cast<Boot_info*>(Hw::Mm::boot_info().base) };
unsigned const nr_of_cpus { boot_info.cpus };
bool const primary_cpu { Cpu::executing_id() == Cpu::primary_id() };
if (primary_cpu) {
/**
* Let the primary CPU create a Main object and initialize the static
* reference to it.
*/
static Main instance { nr_of_cpus };
Main::_instance = &instance;
} else {
/**
* Let secondary CPUs block until the primary CPU has managed to set
* up the Main instance.
*/
while (!instance_initialized) { }
}
{
/**
* Let each CPU initialize its corresponding CPU object in the
* CPU pool.
*/
Lock::Guard guard(Main::_instance->_data_lock);
instance_initialized = true;
Main::_instance->_cpu_pool.initialize_executing_cpu(
Main::_instance->_addr_space_id_alloc,
Main::_instance->_user_irq_pool,
Main::_instance->_core_platform_pd.kernel_pd(),
Main::_instance->_global_irq_ctrl);
nr_of_initialized_cpus++;
};
/**
* Let all CPUs block until each CPU object in the CPU pool has been
* initialized by the corresponding CPU.
*/
while (nr_of_initialized_cpus < nr_of_cpus) { }
if (primary_cpu) {
/**
* Let the primary CPU initialize the core main thread and finish
* initialization of the boot info.
*/
Lock::Guard guard(Main::_instance->_data_lock);
Main::_instance->_cpu_pool.for_each_cpu([&] (Kernel::Cpu &cpu) {
boot_info.kernel_irqs.add(cpu.timer().interrupt_id());
});
boot_info.kernel_irqs.add((unsigned)Board::Pic::IPI);
Main::_instance->_core_main_thread.construct(
Main::_instance->_addr_space_id_alloc,
Main::_instance->_user_irq_pool,
Main::_instance->_cpu_pool,
Main::_instance->_core_platform_pd.kernel_pd());
boot_info.core_main_thread_utcb =
(addr_t)Main::_instance->_core_main_thread->utcb();
Genode::log("");
Genode::log("kernel initialized");
kernel_initialized = true;
} else {
/**
* Let secondary CPUs block until the primary CPU has initialized the
* core main thread and finished initialization of the boot info.
*/
while (!kernel_initialized) {;}
}
Main::_instance->_handle_kernel_entry();
}
Genode::Platform_pd &Kernel::Main::core_platform_pd()
{
return _instance->_core_platform_pd;
}
void Kernel::main_print_char(char c)
{
Main::_instance->_serial.put_char(c);
}
Kernel::time_t Kernel::main_read_idle_thread_execution_time(unsigned cpu_idx)
{
return Main::_instance->_cpu_pool.cpu(cpu_idx).idle_thread().execution_time();
}
Genode::Platform_pd &
Genode::Platform_thread::_kernel_main_get_core_platform_pd()
{
return Kernel::Main::core_platform_pd();
}
bool Genode::map_local(addr_t from_phys, addr_t to_virt, size_t num_pages,
Page_flags flags)
{
return
Kernel::Main::core_platform_pd().insert_translation(
to_virt, from_phys, num_pages * get_page_size(), flags);
}
bool Genode::unmap_local(addr_t virt_addr, size_t num_pages)
{
Kernel::Main::core_platform_pd().flush(
virt_addr, num_pages * get_page_size());
return true;
}

View File

@@ -0,0 +1,33 @@
/*
* \brief Main object of the kernel
* \author Martin Stein
* \date 2021-07-09
*/
/*
* Copyright (C) 2021 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _KERNEL__MAIN_H_
#define _KERNEL__MAIN_H_
/* base-hw Core includes */
#include <kernel/types.h>
namespace Kernel {
void main_print_char(char const c);
void main_handle_kernel_entry();
void main_initialize_and_handle_kernel_entry();
time_t main_read_idle_thread_execution_time(unsigned cpu_idx);
void main_print_char(char c);
}
#endif /* _KERNEL__MAIN_H_ */

View File

@@ -1,6 +1,5 @@
#include <kernel/object.h>
#include <kernel/pd.h>
#include <kernel/kernel.h>
#include <util/construct_at.h>

View File

@@ -23,7 +23,6 @@
/* core includes */
#include <kernel/core_interface.h>
#include <kernel/interface.h>
#include <kernel/kernel.h>
namespace Kernel {
@@ -228,9 +227,24 @@ class Kernel::Core_object_identity : public Object_identity,
{
public:
Core_object_identity(T & object)
: Object_identity(object.kernel_object()),
Object_identity_reference(this, core_pd()) { }
/**
* Constructor used for objects other than the Core PD
*/
Core_object_identity(Pd &core_pd,
T &object)
:
Object_identity(object.kernel_object()),
Object_identity_reference(this, core_pd)
{ }
/**
* Constructor used for Core PD object
*/
Core_object_identity(T &core_pd)
:
Object_identity(core_pd.kernel_object()),
Object_identity_reference(this, core_pd)
{ }
capid_t core_capid() { return capid(); }
@@ -248,9 +262,26 @@ class Kernel::Core_object : public T, Kernel::Core_object_identity<T>
{
public:
/**
* Constructor used for objects other than the Core PD
*/
template <typename... ARGS>
Core_object(Pd &core_pd,
ARGS &&... args)
:
T(args...),
Core_object_identity<T>(core_pd, *static_cast<T*>(this))
{ }
/**
* Constructor used for Core PD object
*/
template <typename... ARGS>
Core_object(ARGS &&... args)
: T(args...), Core_object_identity<T>(*static_cast<T*>(this)) { }
:
T(args...),
Core_object_identity<T>(*static_cast<T*>(this))
{ }
using Kernel::Core_object_identity<T>::core_capid;
using Kernel::Core_object_identity<T>::capid;

View File

@@ -15,13 +15,13 @@
#ifndef _CORE__KERNEL__PD_H_
#define _CORE__KERNEL__PD_H_
/* core includes */
/* base-hw Core includes */
#include <hw/assert.h>
#include <cpu.h>
#include <kernel/core_interface.h>
#include <object.h>
#include <translation_table.h>
#include <board.h>
/* base includes */
#include <util/reconstructible.h>
namespace Genode { class Platform_pd; }
@@ -53,7 +53,6 @@ class Kernel::Pd
Genode::Platform_pd &_platform_pd;
Capid_allocator _capid_alloc { };
Object_identity_reference_tree _cap_tree { };
bool _core_pd { false };
public:
@@ -65,19 +64,16 @@ class Kernel::Pd
* \param table translation table of the PD
* \param platform_pd core object of the PD
*/
Pd(Hw::Page_table &table,
Genode::Platform_pd &platform_pd)
Pd(Hw::Page_table &table,
Genode::Platform_pd &platform_pd,
Board::Address_space_id_allocator &addr_space_id_alloc)
:
_table(table), _platform_pd(platform_pd), mmu_regs((addr_t)&table)
_table(table),
_platform_pd(platform_pd),
mmu_regs((addr_t)&table, addr_space_id_alloc)
{
capid_t invalid = _capid_alloc.alloc();
assert(invalid == cap_id_invalid());
static bool first_pd = true;
if (first_pd) {
_core_pd = true;
first_pd = false;
}
}
~Pd()
@@ -113,15 +109,6 @@ class Kernel::Pd
Hw::Page_table &translation_table() { return _table; }
Capid_allocator &capid_alloc() { return _capid_alloc; }
Object_identity_reference_tree &cap_tree() { return _cap_tree; }
bool core_pd() const { return _core_pd; }
};
template<>
inline Kernel::Core_object_identity<Kernel::Pd>::Core_object_identity(Kernel::Pd & pd)
:
Object_identity(pd.kernel_object()),
Object_identity_reference(this, pd.core_pd() ? pd : core_pd())
{ }
#endif /* _CORE__KERNEL__PD_H_ */

View File

@@ -17,14 +17,11 @@
#include <cpu_session/cpu_session.h>
/* base-internal includes */
#include <base/internal/unmanaged_singleton.h>
#include <base/internal/native_utcb.h>
#include <base/internal/crt0.h>
/* core includes */
#include <hw/assert.h>
#include <kernel/cpu.h>
#include <kernel/kernel.h>
#include <kernel/thread.h>
#include <kernel/irq.h>
#include <kernel/log.h>
@@ -98,7 +95,7 @@ void Thread::ipc_copy_msg(Thread &sender)
Reference *dst_oir = oir->find(pd());
/* if it is not found, and the target is not core, create a reference */
if (!dst_oir && (&pd() != &core_pd())) {
if (!dst_oir && (&pd() != &_core_pd)) {
dst_oir = oir->factory(_obj_id_ref_ptr[i], pd());
if (dst_oir) _obj_id_ref_ptr[i] = nullptr;
}
@@ -111,13 +108,22 @@ void Thread::ipc_copy_msg(Thread &sender)
}
Thread::Tlb_invalidation::Tlb_invalidation(Thread & caller, Pd & pd,
addr_t addr, size_t size,
unsigned cnt)
Thread::
Tlb_invalidation::Tlb_invalidation(Inter_processor_work_list &global_work_list,
Thread &caller,
Pd &pd,
addr_t addr,
size_t size,
unsigned cnt)
:
caller(caller), pd(pd), addr(addr), size(size), cnt(cnt)
global_work_list { global_work_list },
caller { caller },
pd { pd },
addr { addr },
size { size },
cnt { cnt }
{
cpu_pool().work_list().insert(&_le);
global_work_list.insert(&_le);
caller._become_inactive(AWAITS_RESTART);
}
@@ -131,10 +137,11 @@ Thread::Destroy::Destroy(Thread & caller, Genode::Kernel_object<Thread> & to_del
}
void Thread::Destroy::execute()
void
Thread::Destroy::execute()
{
thread_to_destroy->_cpu->work_list().remove(&_le);
thread_to_destroy.destruct();
cpu_pool().executing_cpu().work_list().remove(&_le);
caller._restart();
}
@@ -280,7 +287,7 @@ void Thread::_call_thread_quota()
void Thread::_call_start_thread()
{
/* lookup CPU */
Cpu & cpu = cpu_pool().cpu(user_arg_2());
Cpu & cpu = _cpu_pool.cpu(user_arg_2());
user_arg_0(0);
Thread &thread = *(Thread*)user_arg_1();
@@ -648,7 +655,9 @@ void Thread::_call_new_irq()
Genode::Irq_session::Polarity polarity =
(Genode::Irq_session::Polarity) (user_arg_3() & 0b11);
_call_new<User_irq>((unsigned)user_arg_2(), trigger, polarity, *c);
_call_new<User_irq>(
(unsigned)user_arg_2(), trigger, polarity, *c,
_cpu_pool.executing_cpu().pic(), _user_irq_pool);
}
@@ -671,7 +680,7 @@ void Thread::_call_new_obj()
using Thread_identity = Genode::Constructible<Core_object_identity<Thread>>;
Thread_identity & coi = *(Thread_identity*)user_arg_1();
coi.construct(*thread);
coi.construct(_core_pd, *thread);
user_arg_0(coi->core_capid());
}
@@ -709,12 +718,15 @@ void Kernel::Thread::_call_invalidate_tlb()
size_t size = (size_t) user_arg_3();
unsigned cnt = 0;
cpu_pool().for_each_cpu([&] (Cpu & cpu) {
_cpu_pool.for_each_cpu([&] (Cpu & cpu) {
/* if a cpu needs to update increase the counter */
if (pd->invalidate_tlb(cpu, addr, size)) cnt++; });
/* insert the work item in the list if there are outstanding cpus */
if (cnt) _tlb_invalidation.construct(*this, *pd, addr, size, cnt);
if (cnt) {
_tlb_invalidation.construct(
_cpu_pool.work_list(), *this, *pd, addr, size, cnt);
}
}
@@ -759,12 +771,14 @@ void Thread::_call()
/* switch over kernel calls that are restricted to core */
switch (call_id) {
case call_id_new_thread():
_call_new<Thread>((unsigned) user_arg_2(),
_call_new<Thread>(_addr_space_id_alloc, _user_irq_pool, _cpu_pool,
_core_pd, (unsigned) user_arg_2(),
(unsigned) _core_to_kernel_quota(user_arg_3()),
(char const *) user_arg_4());
return;
case call_id_new_core_thread():
_call_new<Thread>((char const *) user_arg_2());
_call_new<Thread>(_addr_space_id_alloc, _user_irq_pool, _cpu_pool,
_core_pd, (char const *) user_arg_2());
return;
case call_id_thread_quota(): _call_thread_quota(); return;
case call_id_delete_thread(): _call_delete_thread(); return;
@@ -774,7 +788,8 @@ void Thread::_call()
case call_id_invalidate_tlb(): _call_invalidate_tlb(); return;
case call_id_new_pd():
_call_new<Pd>(*(Hw::Page_table *) user_arg_2(),
*(Genode::Platform_pd *) user_arg_3());
*(Genode::Platform_pd *) user_arg_3(),
_addr_space_id_alloc);
return;
case call_id_delete_pd(): _call_delete<Pd>(); return;
case call_id_new_signal_receiver(): _call_new<Signal_receiver>(); return;
@@ -821,12 +836,26 @@ void Thread::_mmu_exception()
}
Thread::Thread(unsigned const priority, unsigned const quota,
char const * const label, bool core)
Thread::Thread(Board::Address_space_id_allocator &addr_space_id_alloc,
Irq::Pool &user_irq_pool,
Cpu_pool &cpu_pool,
Pd &core_pd,
unsigned const priority,
unsigned const quota,
char const *const label,
bool core)
:
Kernel::Object { *this },
Cpu_job(priority, quota), _ipc_node(*this), _state(AWAITS_START),
_label(label), _core(core), regs(core)
Kernel::Object { *this },
Cpu_job { priority, quota },
_addr_space_id_alloc { addr_space_id_alloc },
_user_irq_pool { user_irq_pool },
_cpu_pool { cpu_pool },
_core_pd { core_pd },
_ipc_node { *this },
_state { AWAITS_START },
_label { label },
_core { core },
regs { core }
{ }
@@ -844,41 +873,35 @@ void Thread::print(Genode::Output &out) const
Genode::uint8_t __initial_stack_base[DEFAULT_STACK_SIZE];
/*****************
** Core_thread **
*****************/
/**********************
** Core_main_thread **
**********************/
Core_thread::Core_thread()
Core_main_thread::
Core_main_thread(Board::Address_space_id_allocator &addr_space_id_alloc,
Irq::Pool &user_irq_pool,
Cpu_pool &cpu_pool,
Pd &core_pd)
:
Core_object<Thread>("core")
Core_object<Thread>(
core_pd, addr_space_id_alloc, user_irq_pool, cpu_pool, core_pd, "core")
{
using namespace Genode;
static Native_utcb * const utcb =
unmanaged_singleton<Native_utcb, get_page_size()>();
static addr_t const utcb_phys = Platform::core_phys_addr((addr_t)utcb);
/* map UTCB */
Genode::map_local(utcb_phys, (addr_t)utcb_main_thread(),
Genode::map_local(Platform::core_phys_addr((addr_t)&_utcb_instance),
(addr_t)utcb_main_thread(),
sizeof(Native_utcb) / get_page_size());
utcb->cap_add(core_capid());
utcb->cap_add(cap_id_invalid());
utcb->cap_add(cap_id_invalid());
_utcb_instance.cap_add(core_capid());
_utcb_instance.cap_add(cap_id_invalid());
_utcb_instance.cap_add(cap_id_invalid());
/* start thread with stack pointer at the top of stack */
regs->sp = (addr_t)&__initial_stack_base[0] + DEFAULT_STACK_SIZE;
regs->ip = (addr_t)&_core_start;
affinity(cpu_pool().primary_cpu());
_utcb = utcb;
Thread::_pd = &core_pd();
affinity(_cpu_pool.primary_cpu());
_utcb = &_utcb_instance;
Thread::_pd = &core_pd;
_become_active();
}
Thread & Core_thread::singleton()
{
static Core_thread ct;
return ct;
}

View File

@@ -19,8 +19,7 @@
#include <base/signal.h>
#include <util/reconstructible.h>
/* core includes */
#include <cpu.h>
/* base-hw Core includes */
#include <kernel/cpu_context.h>
#include <kernel/inter_processor_work.h>
#include <kernel/signal_receiver.h>
@@ -29,13 +28,15 @@
#include <kernel/interface.h>
#include <assertion.h>
/* base-local includes */
/* base internal includes */
#include <base/internal/native_utcb.h>
namespace Kernel {
class Cpu_pool;
struct Thread_fault;
class Thread;
class Core_thread;
class Core_main_thread;
}
@@ -69,14 +70,19 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout
*/
struct Tlb_invalidation : Inter_processor_work
{
Thread & caller; /* the caller gets blocked until all finished */
Pd & pd; /* the corresponding pd */
addr_t addr;
size_t size;
unsigned cnt; /* count of cpus left */
Inter_processor_work_list &global_work_list;
Thread &caller; /* the caller gets blocked until all finished */
Pd &pd; /* the corresponding pd */
addr_t addr;
size_t size;
unsigned cnt; /* count of cpus left */
Tlb_invalidation(Thread & caller, Pd & pd, addr_t addr, size_t size,
unsigned cnt);
Tlb_invalidation(Inter_processor_work_list &global_work_list,
Thread &caller,
Pd &pd,
addr_t addr,
size_t size,
unsigned cnt);
/************************************
** Inter_processor_work interface **
@@ -124,22 +130,26 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout
enum { MAX_RCV_CAPS = Genode::Msgbuf_base::MAX_CAPS_PER_MSG };
void *_obj_id_ref_ptr[MAX_RCV_CAPS] { nullptr };
Ipc_node _ipc_node;
capid_t _ipc_capid { cap_id_invalid() };
size_t _ipc_rcv_caps { 0 };
Genode::Native_utcb *_utcb { nullptr };
Pd *_pd { nullptr };
Signal_context *_pager { nullptr };
Thread_fault _fault { };
State _state;
Signal_handler _signal_handler { *this };
Signal_context_killer _signal_context_killer { *this };
char const *const _label;
capid_t _timeout_sigid { 0 };
bool _paused { false };
bool _cancel_next_await_signal { false };
bool const _core { false };
Board::Address_space_id_allocator &_addr_space_id_alloc;
Irq::Pool &_user_irq_pool;
Cpu_pool &_cpu_pool;
Pd &_core_pd;
void *_obj_id_ref_ptr[MAX_RCV_CAPS] { nullptr };
Ipc_node _ipc_node;
capid_t _ipc_capid { cap_id_invalid() };
size_t _ipc_rcv_caps { 0 };
Genode::Native_utcb *_utcb { nullptr };
Pd *_pd { nullptr };
Signal_context *_pager { nullptr };
Thread_fault _fault { };
State _state;
Signal_handler _signal_handler { *this };
Signal_context_killer _signal_context_killer { *this };
char const *const _label;
capid_t _timeout_sigid { 0 };
bool _paused { false };
bool _cancel_next_await_signal { false };
bool const _core { false };
Genode::Constructible<Tlb_invalidation> _tlb_invalidation {};
Genode::Constructible<Destroy> _destroy {};
@@ -255,7 +265,7 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout
{
Genode::Kernel_object<T> & kobj =
*(Genode::Kernel_object<T>*)user_arg_1();
kobj.construct(args...);
kobj.construct(_core_pd, args...);
user_arg_0(kobj->core_capid());
}
@@ -284,16 +294,29 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout
* \param label debugging label
* \param core whether it is a core thread or not
*/
Thread(unsigned const priority, unsigned const quota,
char const * const label, bool core = false);
Thread(Board::Address_space_id_allocator &addr_space_id_alloc,
Irq::Pool &user_irq_pool,
Cpu_pool &cpu_pool,
Pd &core_pd,
unsigned const priority,
unsigned const quota,
char const *const label,
bool core = false);
/**
* Constructor for core/kernel thread
*
* \param label debugging label
*/
Thread(char const * const label)
: Thread(Cpu_priority::MIN, 0, label, true) { }
Thread(Board::Address_space_id_allocator &addr_space_id_alloc,
Irq::Pool &user_irq_pool,
Cpu_pool &cpu_pool,
Pd &core_pd,
char const *const label)
:
Thread(addr_space_id_alloc, user_irq_pool, cpu_pool, core_pd,
Cpu_priority::min(), 0, label, true)
{ }
~Thread();
@@ -422,11 +445,18 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout
/**
* The first core thread in the system bootstrapped by the Kernel
*/
struct Kernel::Core_thread : Core_object<Kernel::Thread>
class Kernel::Core_main_thread : public Core_object<Kernel::Thread>
{
Core_thread();
private:
static Thread & singleton();
Native_utcb _utcb_instance alignas(Hw::get_page_size()) { };
public:
Core_main_thread(Board::Address_space_id_allocator &addr_space_id_alloc,
Irq::Pool &user_irq_pool,
Cpu_pool &cpu_pool,
Pd &core_pd);
};
#endif /* _CORE__KERNEL__THREAD_H_ */

View File

@@ -25,7 +25,8 @@ void Timer::Irq::occurred() { _cpu.scheduler().timeout(); }
Timer::Irq::Irq(unsigned id, Cpu &cpu)
:
Kernel::Irq(id, cpu.irq_pool()), _cpu(cpu)
Kernel::Irq { id, cpu.irq_pool(), cpu.pic() },
_cpu { cpu }
{ }

View File

@@ -18,7 +18,6 @@ namespace Genode { class Vm_state; }
/* core includes */
#include <kernel/cpu_context.h>
#include <kernel/kernel.h>
#include <kernel/pd.h>
#include <kernel/signal_receiver.h>
@@ -55,6 +54,7 @@ class Kernel::Vm : private Kernel::Object, public Cpu_job
enum Scheduler_state { ACTIVE, INACTIVE };
Irq::Pool & _user_irq_pool;
Object _kernel_object { *this };
State & _state;
Signal_context & _context;
@@ -71,10 +71,11 @@ class Kernel::Vm : private Kernel::Object, public Cpu_job
* \param state initial CPU state
* \param context signal for VM exceptions other than interrupts
*/
Vm(unsigned cpu,
State & state,
Signal_context & context,
Identity & id);
Vm(Irq::Pool & user_irq_pool,
Cpu & cpu,
Genode::Vm_state & state,
Kernel::Signal_context & context,
Identity & id);
/**
* Inject an interrupt to this VM

View File

@@ -14,6 +14,7 @@
/* core includes */
#include <kernel/thread.h>
#include <kernel/vm.h>
#include <kernel/cpu.h>
void Kernel::Thread::_call_new_vm()
{
@@ -24,7 +25,8 @@ void Kernel::Thread::_call_new_vm()
return;
}
_call_new<Vm>((unsigned)user_arg_2(), *(Board::Vm_state*)user_arg_3(),
_call_new<Vm>(_user_irq_pool, _cpu_pool.cpu((unsigned)user_arg_2()),
*(Board::Vm_state*)user_arg_3(),
*context, *(Vm::Identity*)user_arg_4());
}

View File

@@ -12,29 +12,20 @@
* under the terms of the GNU Affero General Public License version 3.
*/
/* base-internal includes */
#include <base/internal/unmanaged_singleton.h>
#include <board.h>
#include <platform.h>
/* base-hw Core includes */
#include <kernel/main.h>
#include <kernel/log.h>
void Kernel::log(char const c)
{
using namespace Board;
enum {
ASCII_LINE_FEED = 10,
ASCII_CARRIAGE_RETURN = 13,
BAUD_RATE = 115200
};
static Serial serial { Genode::Platform::mmio_to_virt(UART_BASE),
UART_CLOCK, BAUD_RATE };
if (c == ASCII_LINE_FEED)
serial.put_char(ASCII_CARRIAGE_RETURN);
main_print_char(ASCII_CARRIAGE_RETURN);
serial.put_char(c);
main_print_char(c);
}

View File

@@ -44,19 +44,29 @@ class Genode::Kernel_object : public Genode::Constructible<Kernel::Core_object<T
public:
enum Called_from_core { CALLED_FROM_CORE };
enum Called_from_kernel { CALLED_FROM_KERNEL };
Kernel_object() {}
/**
* Creates a kernel object either via a syscall or directly
* Creates a kernel object via a syscall
*/
template <typename... ARGS>
Kernel_object(bool syscall, ARGS &&... args)
Kernel_object(Called_from_core, ARGS &&... args)
:
_cap(Capability_space::import(syscall ? T::syscall_create(*this, args...)
: Kernel::cap_id_invalid()))
_cap(Capability_space::import(T::syscall_create(*this, args...)))
{ }
/**
* Creates a kernel object directly
*/
template <typename... ARGS>
Kernel_object(Called_from_kernel, ARGS &&... args)
:
_cap(Capability_space::import(Kernel::cap_id_invalid()))
{
if (!syscall)
Genode::Constructible<Kernel::Core_object<T>>::construct(args...);
Genode::Constructible<Kernel::Core_object<T>>::construct(args...);
}
~Kernel_object()

View File

@@ -110,7 +110,8 @@ Pager_entrypoint::Pager_entrypoint(Rpc_cap_factory &)
:
Thread(Weight::DEFAULT_WEIGHT, "pager_ep", PAGER_EP_STACK_SIZE,
Type::NORMAL),
_kobj(true)
_kobj(_kobj.CALLED_FROM_CORE)
{
start();
}

View File

@@ -21,9 +21,6 @@
#include <base/signal.h>
#include <pager/capability.h>
/* base-internal includes */
#include <base/internal/unmanaged_singleton.h>
/* core-local includes */
#include <kernel/signal_receiver.h>
#include <hw/mapping.h>

View File

@@ -13,24 +13,27 @@
*/
/* core includes */
/* base Core includes */
#include <boot_modules.h>
#include <core_log.h>
#include <hw/memory_region.h>
/* base-hw Core includes */
#include <map_local.h>
#include <platform.h>
#include <platform_pd.h>
#include <kernel/main.h>
/* base-hw internal includes */
#include <hw/page_flags.h>
#include <hw/util.h>
#include <kernel/kernel.h>
#include <translation_table.h>
#include <kernel/cpu.h>
#include <hw/memory_region.h>
/* base-internal includes */
/* base internal includes */
#include <base/internal/crt0.h>
#include <base/internal/stack_area.h>
#include <base/internal/unmanaged_singleton.h>
/* Genode includes */
/* base includes */
#include <base/log.h>
#include <trace/source_registry.h>
@@ -63,6 +66,11 @@ Hw::Page_table::Allocator & Platform::core_page_table_allocator()
}
addr_t Platform::core_main_thread_phys_utcb()
{
return core_phys_addr(_boot_info().core_main_thread_utcb);
}
void Platform::_init_io_mem_alloc()
{
/* add entire adress space minus the RAM memory regions */
@@ -177,14 +185,12 @@ Platform::Platform()
/* make all non-kernel interrupts available to the interrupt allocator */
for (unsigned i = 0; i < Board::Pic::NR_OF_IRQ; i++) {
bool kernel_resource = false;
Kernel::cpu_pool().for_each_cpu([&] (Kernel::Cpu & cpu) {
if (i == cpu.timer().interrupt_id()) {
_boot_info().kernel_irqs.for_each([&] (unsigned /*idx*/,
unsigned kernel_irq) {
if (i == kernel_irq) {
kernel_resource = true;
}
});
if (i == Board::Pic::IPI) {
kernel_resource = true;
}
if (kernel_resource) {
continue;
}
@@ -218,39 +224,47 @@ Platform::Platform()
init_core_log(Core_log_range { core_local_addr, log_size } );
}
struct Trace_source : public Trace::Source::Info_accessor,
private Trace::Control,
private Trace::Source
class Idle_thread_trace_source : public Trace::Source::Info_accessor,
private Trace::Control,
private Trace::Source
{
Kernel::Thread &thread;
Affinity::Location const affinity;
private:
/**
* Trace::Source::Info_accessor interface
*/
Info trace_source_info() const override
{
Trace::Execution_time execution_time { thread.execution_time(), 0 };
return { Session_label("kernel"), thread.label(), execution_time,
affinity };
}
Affinity::Location const _affinity;
Trace_source(Trace::Source_registry &registry,
Kernel::Thread &thread, Affinity::Location affinity)
:
Trace::Control(),
Trace::Source(*this, *this),
thread(thread), affinity(affinity)
{
registry.insert(this);
}
public:
/**
* Trace::Source::Info_accessor interface
*/
Info trace_source_info() const override
{
Trace::Execution_time execution_time {
Kernel::main_read_idle_thread_execution_time(
_affinity.xpos()), 0 };
return { Session_label("kernel"), "idle",
execution_time, _affinity };
}
Idle_thread_trace_source(Trace::Source_registry &registry,
Affinity::Location affinity)
:
Trace::Control { },
Trace::Source { *this, *this },
_affinity { affinity }
{
registry.insert(this);
}
};
/* create trace sources for idle threads */
Kernel::cpu_pool().for_each_cpu([&] (Kernel::Cpu & cpu) {
new (core_mem_alloc()) Trace_source(Trace::sources(), cpu.idle_thread(),
Affinity::Location(cpu.id(), 0));
});
for (unsigned cpu_idx = 0; cpu_idx < _boot_info().cpus; cpu_idx++) {
new (core_mem_alloc())
Idle_thread_trace_source(
Trace::sources(), Affinity::Location(cpu_idx, 0));
}
log(_rom_fs);
}
@@ -260,23 +274,6 @@ Platform::Platform()
** Support for core memory management **
****************************************/
bool Genode::map_local(addr_t from_phys, addr_t to_virt, size_t num_pages,
Page_flags flags)
{
Platform_pd &pd = Kernel::core_pd().platform_pd();
return pd.insert_translation(to_virt, from_phys,
num_pages * get_page_size(), flags);
}
bool Genode::unmap_local(addr_t virt_addr, size_t num_pages)
{
Platform_pd &pd = Kernel::core_pd().platform_pd();
pd.flush(virt_addr, num_pages * get_page_size());
return true;
}
bool Mapped_mem_allocator::_map_local(addr_t virt_addr, addr_t phys_addr,
unsigned size) {
return ::map_local(phys_addr, virt_addr, size / get_page_size()); }

View File

@@ -15,24 +15,25 @@
#ifndef _CORE__PLATFORM_H_
#define _CORE__PLATFORM_H_
/* Genode includes */
/* base includes */
#include <base/synced_allocator.h>
#include <base/allocator_avl.h>
#include <irq_session/irq_session.h>
#include <util/xml_generator.h>
/* base-hw includes */
/* base-hw internal includes */
#include <hw/boot_info.h>
#include <hw/memory_region.h>
/* base-hw includes */
#include <kernel/configuration.h>
#include <kernel/core_interface.h>
#include <kernel/pd.h>
/* core includes */
/* base-hw Core includes */
#include <platform_generic.h>
#include <core_region_map.h>
#include <core_mem_alloc.h>
#include <translation_table.h>
#include <assertion.h>
#include <board.h>
@@ -143,6 +144,8 @@ class Genode::Platform : public Genode::Platform_generic
* by core's local capability space.
*/
size_t max_caps() const override { return Kernel::Pd::max_cap_ids; }
static addr_t core_main_thread_phys_utcb();
};
#endif /* _CORE__PLATFORM_H_ */

View File

@@ -89,14 +89,18 @@ void Hw::Address_space::flush(addr_t virt, size_t size, Core_local_addr)
}
Hw::Address_space::Address_space(Page_table & tt,
Page_table::Allocator & tt_alloc,
Platform_pd & pd)
Hw::Address_space::
Address_space(Page_table &tt,
Page_table::Allocator &tt_alloc,
Platform_pd &pd,
Board::Address_space_id_allocator &addr_space_id_alloc)
:
_tt(tt),
_tt_phys(Platform::core_page_table()),
_tt_alloc(tt_alloc),
_kobj(false, *(Page_table*)translation_table_phys(), pd)
_kobj(_kobj.CALLED_FROM_KERNEL,
*(Page_table*)translation_table_phys(),
pd, addr_space_id_alloc)
{ }
@@ -107,7 +111,9 @@ Hw::Address_space::Address_space(Platform_pd & pd)
_tt_array(new (_cma()) Array([] (void * virt) {
return (addr_t)_cma().phys_addr(virt);})),
_tt_alloc(_tt_array->alloc()),
_kobj(true, *(Page_table*)translation_table_phys(), pd)
_kobj(_kobj.CALLED_FROM_CORE,
*(Page_table*)translation_table_phys(),
pd)
{ }
@@ -156,10 +162,12 @@ void Platform_pd::assign_parent(Native_capability parent)
}
Platform_pd::Platform_pd(Page_table & tt,
Page_table::Allocator & alloc)
Platform_pd::
Platform_pd(Page_table &tt,
Page_table::Allocator &alloc,
Board::Address_space_id_allocator &addr_space_id_alloc)
:
Hw::Address_space(tt, alloc, *this), _label("core")
Hw::Address_space(tt, alloc, *this, addr_space_id_alloc), _label("core")
{ }
@@ -185,8 +193,9 @@ Platform_pd::~Platform_pd()
** Core_platform_pd implementation **
*************************************/
Core_platform_pd::Core_platform_pd()
Core_platform_pd::
Core_platform_pd(Board::Address_space_id_allocator &addr_space_id_alloc)
:
Platform_pd(*(Hw::Page_table*)Hw::Mm::core_page_tables().base,
Platform::core_page_table_allocator())
Platform::core_page_table_allocator(), addr_space_id_alloc)
{ }

View File

@@ -15,16 +15,17 @@
#ifndef _CORE__PLATFORM_PD_H_
#define _CORE__PLATFORM_PD_H_
/* Core includes */
#include <translation_table.h>
/* base-hw Core includes */
#include <platform.h>
#include <address_space.h>
#include <hw/page_table_allocator.h>
#include <object.h>
#include <kernel/configuration.h>
#include <kernel/object.h>
#include <kernel/pd.h>
/* base-hw internal includes */
#include <hw/page_table_allocator.h>
namespace Hw {
using namespace Kernel;
@@ -88,20 +89,21 @@ class Hw::Address_space : public Genode::Address_space
Kernel_object<Kernel::Pd> _kobj;
/**
* Core-specific constructor
* Constructor used for the Core PD object
*
* \param tt reference to translation table
* \param tt_alloc reference to translation table allocator
* \param pd reference to platform pd object
*/
Address_space(Hw::Page_table & tt,
Hw::Page_table::Allocator & tt_alloc,
Platform_pd & pd);
Address_space(Hw::Page_table &tt,
Hw::Page_table::Allocator &tt_alloc,
Platform_pd &pd,
Board::Address_space_id_allocator &addr_space_id_alloc);
public:
/**
* Constructor
* Constructor used for objects other than the Core PD
*
* \param pd reference to platform pd object
*/
@@ -182,18 +184,19 @@ class Genode::Platform_pd : public Hw::Address_space,
protected:
/**
* Constructor for core pd
* Constructor used for the Core PD object
*
* \param tt translation table address
* \param tt_alloc translation table allocator
*/
Platform_pd(Hw::Page_table & tt,
Hw::Page_table::Allocator & tt_alloc);
Platform_pd(Hw::Page_table &tt,
Hw::Page_table::Allocator &tt_alloc,
Board::Address_space_id_allocator &addr_space_id_alloc);
public:
/**
* Constructor for non-core pd
* Constructor used for objects other than the Core PD
*
* \param label name of protection domain
*/
@@ -229,7 +232,7 @@ class Genode::Platform_pd : public Hw::Address_space,
struct Genode::Core_platform_pd : Genode::Platform_pd
{
Core_platform_pd();
Core_platform_pd(Board::Address_space_id_allocator &addr_space_id_alloc);
};
#endif /* _CORE__PLATFORM_PD_H_ */

View File

@@ -25,7 +25,7 @@
/* kernel includes */
#include <kernel/pd.h>
#include <kernel/kernel.h>
#include <kernel/main.h>
using namespace Genode;
@@ -62,13 +62,13 @@ void Platform_thread::quota(size_t const quota)
Platform_thread::Platform_thread(Label const &label, Native_utcb &utcb)
:
_label(label),
_pd(&Kernel::core_pd().platform_pd()),
_pd(&_kernel_main_get_core_platform_pd()),
_pager(nullptr),
_utcb_core_addr(&utcb),
_utcb_pd_addr(&utcb),
_main_thread(false),
_location(Affinity::Location()),
_kobj(true, _label.string())
_kobj(_kobj.CALLED_FROM_CORE, _label.string())
{
/* create UTCB for a core thread */
void *utcb_phys;
@@ -95,7 +95,7 @@ Platform_thread::Platform_thread(size_t const quota,
_quota(quota),
_main_thread(false),
_location(location),
_kobj(true, _priority, _quota, _label.string())
_kobj(_kobj.CALLED_FROM_CORE, _priority, _quota, _label.string())
{
try {
_utcb = core_env().pd_session()->alloc(sizeof(Native_utcb), CACHED);

View File

@@ -89,10 +89,12 @@ class Genode::Platform_thread : Noncopyable
unsigned _scale_priority(unsigned virt_prio)
{
return Cpu_session::scale_priority(Kernel::Cpu_priority::MAX,
return Cpu_session::scale_priority(Kernel::Cpu_priority::max(),
virt_prio);
}
Platform_pd &_kernel_main_get_core_platform_pd();
public:
/**

View File

@@ -12,13 +12,10 @@
* under the terms of the GNU Affero General Public License version 3.
*/
/* core includes */
/* base-hw Core includes */
#include <pager.h>
#include <platform_pd.h>
#include <platform_thread.h>
#include <translation_table.h>
/* base-internal includes */
using namespace Genode;

View File

@@ -56,7 +56,7 @@ struct Genode::Signal_source_component : private Kernel_object<Kernel::Signal_re
Signal_source_component()
:
Kernel_object<Kernel::Signal_receiver>(true),
Kernel_object<Kernel::Signal_receiver>(CALLED_FROM_CORE),
Signal_source_pool::Entry(Kernel_object<Kernel::Signal_receiver>::cap())
{ }
@@ -70,7 +70,10 @@ struct Genode::Signal_source_component : private Kernel_object<Kernel::Signal_re
Genode::Signal_context_component::Signal_context_component(Signal_source_component &s,
addr_t const imprint)
:
Kernel_object<Kernel::Signal_context>(true, s.signal_receiver(), imprint),
Kernel_object<Kernel::Signal_context>(CALLED_FROM_CORE,
s.signal_receiver(),
imprint),
Signal_context_pool::Entry(Kernel_object<Kernel::Signal_context>::_cap)
{ }

View File

@@ -0,0 +1,25 @@
/*
* \brief Allocator for hardware-specific address-space identifiers
* \author Martin Stein
* \date 2021-07-21
*/
/*
* Copyright (C) 2021 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _ARM__ADDRESS_SPACE_ID_ALLOCATOR_H_
#define _ARM__ADDRESS_SPACE_ID_ALLOCATOR_H_
/* base includes */
#include <util/bit_allocator.h>
namespace Board {
class Address_space_id_allocator : public Genode::Bit_allocator<256> { };
}
#endif /* _ARM__ADDRESS_SPACE_ID_ALLOCATOR_H_ */

View File

@@ -37,9 +37,11 @@ bool Board::Pic::Usb_dwc_otg::_need_trigger_sof(uint32_t host_frame,
}
Board::Pic::Usb_dwc_otg::Usb_dwc_otg()
Board::Pic::
Usb_dwc_otg::Usb_dwc_otg(Global_interrupt_controller &global_irq_ctrl)
:
Mmio(Platform::mmio_to_virt(Board::USB_DWC_OTG_BASE))
Mmio { Platform::mmio_to_virt(Board::USB_DWC_OTG_BASE) },
_global_irq_ctrl { global_irq_ctrl }
{
write<Guid::Num>(0);
write<Guid::Num_valid>(false);
@@ -52,10 +54,8 @@ bool Board::Pic::Usb_dwc_otg::handle_sof()
if (!_is_sof())
return false;
static int cnt = 0;
if (++cnt == 8*20) {
cnt = 0;
if (_global_irq_ctrl.increment_and_return_sof_cnt() == 8*20) {
_global_irq_ctrl.reset_sof_cnt();
return false;
}
@@ -72,9 +72,10 @@ bool Board::Pic::Usb_dwc_otg::handle_sof()
}
Board::Pic::Pic()
Board::Pic::Pic(Global_interrupt_controller &global_irq_ctrl)
:
Mmio(Platform::mmio_to_virt(Board::IRQ_CONTROLLER_BASE))
Mmio { Platform::mmio_to_virt(Board::IRQ_CONTROLLER_BASE) },
_usb { global_irq_ctrl }
{
mask();
}

View File

@@ -17,7 +17,25 @@
/* Genode includes */
#include <util/mmio.h>
namespace Board { class Pic; }
namespace Board {
class Global_interrupt_controller;
class Pic;
}
class Board::Global_interrupt_controller
{
private:
int _sof_cnt { 0 };
public:
int increment_and_return_sof_cnt() { return ++_sof_cnt; }
void reset_sof_cnt() { _sof_cnt = 0; }
};
class Board::Pic : Genode::Mmio
@@ -80,6 +98,8 @@ class Board::Pic : Genode::Mmio
struct Num : Bitfield<0, 14> { };
};
Global_interrupt_controller &_global_irq_ctrl;
bool _is_sof() const
{
return read<Core_irq_status::Sof>();
@@ -90,12 +110,12 @@ class Board::Pic : Genode::Mmio
public:
Usb_dwc_otg();
Usb_dwc_otg(Global_interrupt_controller &global_irq_ctrl);
bool handle_sof();
};
Usb_dwc_otg _usb { };
Usb_dwc_otg _usb;
/**
* Return true if specified interrupt is pending
@@ -108,7 +128,7 @@ class Board::Pic : Genode::Mmio
public:
Pic();
Pic(Global_interrupt_controller &global_irq_ctrl);
bool take_request(unsigned &irq);
void finish_request() { }

View File

@@ -11,12 +11,12 @@
* under the terms of the GNU Affero General Public License version 3.
*/
/* base-hw Core includes */
#include <board.h>
#include <cpu.h>
#include <platform.h>
Board::Pic::Pic()
Board::Pic::Pic(Global_interrupt_controller &)
:
Genode::Mmio(Genode::Platform::mmio_to_virt(Board::LOCAL_IRQ_CONTROLLER_BASE))
{ }

View File

@@ -16,7 +16,11 @@
#include <util/mmio.h>
namespace Board { class Pic; }
namespace Board {
class Global_interrupt_controller { };
class Pic;
}
class Board::Pic : Genode::Mmio
@@ -54,7 +58,7 @@ class Board::Pic : Genode::Mmio
public:
Pic();
Pic(Global_interrupt_controller &);
bool take_request(unsigned &irq);
void finish_request() { }

View File

@@ -11,10 +11,10 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#include <util/bit_allocator.h>
/* base includes */
#include <cpu/memory_barrier.h>
#include <base/internal/unmanaged_singleton.h>
/* base-hw Core includes */
#include <kernel/cpu.h>
#include <kernel/thread.h>
#include <spec/arm/cpu_support.h>
@@ -36,21 +36,21 @@ Arm_cpu::Context::Context(bool privileged)
}
using Asid_allocator = Bit_allocator<256>;
static Asid_allocator &alloc() {
return *unmanaged_singleton<Asid_allocator>(); }
Arm_cpu::Mmu_context::Mmu_context(addr_t table)
: cidr((uint8_t)alloc().alloc()), ttbr0(Ttbr::init(table)) { }
Arm_cpu::Mmu_context::
Mmu_context(addr_t table,
Board::Address_space_id_allocator &addr_space_id_alloc)
:
_addr_space_id_alloc(addr_space_id_alloc),
cidr((uint8_t)_addr_space_id_alloc.alloc()),
ttbr0(Ttbr::init(table))
{ }
Genode::Arm_cpu::Mmu_context::~Mmu_context()
{
/* flush TLB by ASID */
Cpu::Tlbiasid::write(id());
alloc().free(id());
_addr_space_id_alloc.free(id());
}

View File

@@ -15,17 +15,19 @@
#ifndef _CORE__SPEC__ARM__CPU_SUPPORT_H_
#define _CORE__SPEC__ARM__CPU_SUPPORT_H_
/* Genode includes */
/* base includes */
#include <util/register.h>
#include <cpu/cpu_state.h>
/* base internal includes */
#include <base/internal/align_at.h>
/* base-hw internal includes */
#include <hw/spec/arm/cpu.h>
/* local includes */
/* base-hw Core includes */
#include <spec/arm/address_space_id_allocator.h>
#include <kernel/interface_support.h>
#include <kernel/kernel.h>
#include <board.h>
#include <util.h>
namespace Kernel { struct Thread_fault; }
@@ -53,15 +55,23 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu
/**
* This class comprises ARM specific protection domain attributes
*/
struct Mmu_context
class Mmu_context
{
Cidr::access_t cidr;
Ttbr0::access_t ttbr0;
private:
Mmu_context(addr_t page_table_base);
~Mmu_context();
Board::Address_space_id_allocator &_addr_space_id_alloc;
uint8_t id() { return cidr; }
public:
Cidr::access_t cidr;
Ttbr0::access_t ttbr0;
Mmu_context(addr_t page_table_base,
Board::Address_space_id_allocator &addr_space_id_alloc);
~Mmu_context();
uint8_t id() { return cidr; }
};
/**

View File

@@ -31,7 +31,7 @@
add sp, r1, r0
/* jump into init C code */
b kernel_init
b _ZN6Kernel39main_initialize_and_handle_kernel_entryEv
_kernel_stack: .long kernel_stack
_kernel_stack_size: .long kernel_stack_size

View File

@@ -134,7 +134,7 @@
bx lr
_kernel_entry:
.long kernel
.long _ZN6Kernel24main_handle_kernel_entryEv
_fpu_save:
.long vfp_save_fpu_context

View File

@@ -19,8 +19,7 @@
void Kernel::Cpu::_arch_init()
{
/* enable performance counter */
perf_counter()->enable();
enable_performance_counter();
/* enable timer interrupt */
_pic.unmask(_timer.interrupt_id(), id());

View File

@@ -11,20 +11,13 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#include <base/lock_guard.h>
/* Genode includes */
#include <cpu/atomic.h>
#include <cpu/memory_barrier.h>
/* base-hw Core includes */
#include <kernel/cpu.h>
#include <kernel/lock.h>
#include <kernel/kernel.h>
Kernel::Lock & Kernel::data_lock()
{
static Kernel::Lock lock;
return lock;
}
void Kernel::Lock::lock()

View File

@@ -11,8 +11,8 @@
* under the terms of the GNU Affero General Public License version 3.
*/
/* base-hw Core includes */
#include <kernel/cpu.h>
#include <kernel/kernel.h>
void Kernel::panic(Genode::Cpu_state * state) {

View File

@@ -16,21 +16,7 @@
namespace Kernel {
/**
* Performance counter
*/
class Perf_counter
{
public:
/**
* Enable counting
*/
void enable();
};
extern Perf_counter * perf_counter();
void enable_performance_counter();
}
#endif /* _CORE__KERNEL__PERF_COUNTER_H_ */

View File

@@ -12,11 +12,12 @@
* under the terms of the GNU Affero General Public License version 3.
*/
/* base includes */
#include <cpu/memory_barrier.h>
/* base-hw Core includes */
#include <platform_pd.h>
#include <kernel/cpu.h>
#include <kernel/kernel.h>
#include <kernel/pd.h>
#include <kernel/thread.h>
@@ -37,7 +38,7 @@ void Thread::exception(Cpu & cpu)
return;
case Cpu::Context::INTERRUPT_REQUEST:
case Cpu::Context::FAST_INTERRUPT_REQUEST:
_interrupt(cpu.id());
_interrupt(_user_irq_pool, cpu.id());
return;
case Cpu::Context::UNDEFINED_INSTRUCTION:
Genode::raw(*this, ": undefined instruction at ip=",

View File

@@ -11,7 +11,7 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#include <cpu.h>
/* base-hw Core includes */
#include <platform_pd.h>
#include <kernel/pd.h>
#include <kernel/thread.h>

View File

@@ -27,7 +27,8 @@ namespace Board {
struct Vm_page_table {};
struct Vm_page_table_array {};
struct Pic : Hw::Pic { struct Virtual_context {}; };
class Global_interrupt_controller { };
struct Pic : Hw::Pic { struct Virtual_context {}; Pic(Global_interrupt_controller &) { } };
struct Vcpu_context { Vcpu_context(Kernel::Cpu &) {} };
}

View File

@@ -14,10 +14,13 @@
#ifndef _CORE__SPEC__ARM__VIRTUALIZATION__BOARD_H_
#define _CORE__SPEC__ARM__VIRTUALIZATION__BOARD_H_
#include <translation_table.h>
/* base-hw Core includes */
#include <kernel/configuration.h>
#include <kernel/irq.h>
/* base-hw internal includes */
#include <hw/spec/arm/lpae.h>
namespace Board {
using Vm_page_table = Hw::Level_1_stage_2_translation_table;
@@ -38,13 +41,21 @@ namespace Kernel {
struct Board::Vcpu_context
{
struct Vm_irq : Kernel::Irq
class Vm_irq : public Kernel::Irq
{
Vm_irq(unsigned const irq, Kernel::Cpu &);
virtual ~Vm_irq() {};
private:
virtual void handle(Kernel::Cpu &, Kernel::Vm & vm, unsigned irq);
void occurred() override;
Kernel::Cpu &_cpu;
public:
Vm_irq(unsigned const irq, Kernel::Cpu &cpu);
virtual ~Vm_irq() { };
virtual void handle(Kernel::Vm &vm, unsigned irq);
void occurred() override;
};
@@ -52,7 +63,7 @@ struct Board::Vcpu_context
{
Pic_maintainance_irq(Kernel::Cpu &);
void handle(Kernel::Cpu &, Kernel::Vm &, unsigned) override { }
void handle(Kernel::Vm &, unsigned) override { }
};

View File

@@ -16,7 +16,11 @@
#include <hw/spec/arm/gicv2.h>
namespace Board { struct Pic; };
namespace Board {
class Global_interrupt_controller { };
class Pic;
};
class Board::Pic : public Hw::Gicv2
@@ -50,6 +54,8 @@ class Board::Pic : public Hw::Gicv2
bool ack_virtual_irq(Virtual_context & c);
void insert_virtual_irq(Virtual_context & c, unsigned irq);
Pic(Global_interrupt_controller &) { }
};
#endif /* _CORE__SPEC__ARM__VIRTUALIZATION__GICV2_H_ */

View File

@@ -16,7 +16,11 @@
#include <hw/spec/arm/gicv3.h>
namespace Board { class Pic; };
namespace Board {
class Global_interrupt_controller { };
class Pic;
};
class Board::Pic : public Hw::Pic
@@ -51,6 +55,8 @@ class Board::Pic : public Hw::Pic
c.lr = irq | 1ULL << 41 | 1ULL << 60 | 1ULL << 62;
}
Pic(Global_interrupt_controller &) { }
};
#endif /* _CORE__SPEC__ARM__VIRTUALIZATION__GICV3_H_ */

View File

@@ -14,6 +14,9 @@
/* Genode includes */
#include <util/construct_at.h>
/* base internal includes */
#include <base/internal/unmanaged_singleton.h>
/* core includes */
#include <kernel/core_interface.h>
#include <vm_session_component.h>

Some files were not shown because too many files have changed in this diff Show More