diff --git a/VERSION b/VERSION index a01c758c18..54de1e741d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -22.05 +22.08 diff --git a/doc/news.txt b/doc/news.txt index c1f29a5e9b..46f5b2cd18 100644 --- a/doc/news.txt +++ b/doc/news.txt @@ -4,6 +4,67 @@ =========== +Sculpt OS release 22.10 | 2022-10-13 +#################################### + +| Sculpt OS 22.10 is a maintenance release of our Genode-based +| general-purpose OS. It imposes a new rigid regime to the management of +| low-level devices, improves USB hotplug support, and comes with numerous +| performance optimizations. + +The just released version 22.10 of the Sculpt operating system bears the fruit +of our year-long effort to apply the rigidity of Genode's architecture to the +management of PCI configuration and device interrupts. This sweeping change +left no single device driver unturned. If we did our job right, you should not +notice any visible difference from the previous Sculpt version. + +However, you should definitely _feel_ a difference when using the new version. +We put several performance optimizations in place - from accelerated system +startup, over increased network thoughput, to improved user-interface +responsiveness. Moreover, we put much emphasis on stressing Sculpt's USB +hotplug support, which includes the dynamic assignment and revocation of +USB devices to and from virtual machines. + +With respect to available software, Sculpt users can enjoy an updated +Chromium engine - via the Falkon or Morph web browsers - and an updated +audio driver based on OpenBSD 7.1. + +Sculpt OS 22.10 is available as ready-to-use system image at the +[https://genode.org/download/sculpt - Sculpt download page] along with +updated [https://genode.org/documentation/articles/sculpt-22-10 - documentation]. + + +Genode OS Framework release 22.08 | 2022-08-31 +############################################## + +| The overarching theme of Genode 22.08 is the emerging phone variant of +| Sculpt OS, touching topics as diverse as USB ECM, Mali-400 GPU, SD-card +| access, telephony, mobile-data connectivity, the Morph web browser, and a +| custom user interface. Among the further highlights are new tracing tools, +| improved network performance USB smart-card support, and VirtIO drivers for +| RISC-V. + +The vision of a Genode-based smart phone is certainly our most ambitious +undertaking since we created Sculpt OS for the PC. Over the past two years, we +relentlessly pursued this vision while targeting the PinePhone hardware. +The scope of work reaches from custom firmware for the system-control +processor, over kernel development, a staggering variety of device drivers, to +the user-interface and application level. With Genode 22.08, those efforts +culminate in a first complete system - a phone variant of Sculpt OS. The +[https://genode.org/documentation/release-notes/22.08 - release documentation] +tells the story behind this line of work in great detail. + +Beside phone-related topics, the new release features new tooling for +gathering and analyzing system traces that allow for holistic performance +studies covering the interplay between components. One particular success +story of the new trace recorder is a profoundly improved network performance. +Further highlights are the support for USB smart cards via PKCS#11, VirtIO +drivers for RISC-V, and the update of Qt5 to version 5.15.2. + +For the complete picture, please enjoy the official +[https:/documentation/release-notes/22.08 - release documentation of version 22.08...] + + Genode OS Framework release 22.05 | 2022-05-31 ############################################## diff --git a/doc/release_notes/22-08.txt b/doc/release_notes/22-08.txt new file mode 100644 index 0000000000..6b501b28f2 --- /dev/null +++ b/doc/release_notes/22-08.txt @@ -0,0 +1,866 @@ + + + =============================================== + Release notes for the Genode OS Framework 22.08 + =============================================== + + Genode Labs + + + +The overarching topic of version 22.08 is the emerging phone version of the +Genode-based Sculpt OS, targeting the PinePhone. The immense breadth and depth +of this line of work presented in Section [Genode coming to the phone] +touches topics as diverse as telephony, mobile-data connectivity, a custom +user interface, a mobile web browser, the GPU, SD-card access, USB, and audio +control. + +With the growing sophistication of Genode-based systems, performance +optimizations come more and more into focus. Aided by the new tools introduced +in Section [Enhanced tooling for system tracing], we were able to profoundly +improve the network performance of Genode's user-level network routing +component. Speaking of optimizations, the current release reduces the CPU +overhead of our Linux device-driver environment +(Section [Linux-device-driver environment (DDE Linux)]) and +improves the responsiveness of GUIs based on Genode's menu-view component +(Section [Menu-view performance]). + +Further topics of the new version reach from our forthcoming platform-driver +consolidation across PC and ARM-based devices, over the use of USB smart +cards, to new VirtIO drivers on RISC-V. + + +Genode coming to the phone +########################## + +Our [https://genode.org/about/road-map - road map] for this year states the +goal of reaching a useful base line of functionality of Genode on the +PinePhone. This entails the principle ability to use the device as a phone - +receiving and issuing voice calls - and a mobile internet browser. Once +reached, this base line of functionality will allow us to routinely use Genode +on the device ("eating our own dog food"), experience pain points, guide +optimization efforts towards user-visible areas that matter, and faithfully +evaluate non-functional aspects like battery lifetime with real-world work +loads under realistic conditions. + +For the Genode-based phone, we pursue the combination of a minimally-complex +trustworthy base system with a generally untrusted Web browser as application +runtime. The feature set of the base system corresponds to the bare-bones +[https://genode.org/download/sculpt - Sculpt OS] extended with appliance-like +feature-phone functionality. Thanks to Sculpt's rigid component-based +structure and the overall low complexity, it promises high reliability and +security. The application runtime is hosted on top of the base system without +tainting the assurance of the base system. In contrast to the appliance-like +and rather static feature set of the base system, the application runtime +anticipates a great variety of modern-day application scenarios, universally +expected commodity user-interface paradigms, and fast-paced software updates. +E.g., we aspire the use of WebRTC-based video conferencing via Jitsi as one +reference scenario. + +Since we succeeded in bringing the Chromium web engine - the base technology +of most modern web browsers - to life as a +[https://genodians.org/nfeske/2022-01-27-browser-odyssey - native Genode component], +users of Sculpt OS are able to use a fully featured web browser without +relying on virtualization. With the use case of the browser on a mobile phone +in sight, we already ensured that the browser would work on 64-bit ARM +hardware. However, whereas we could showcase the technical feasibility of +Chromium on Genode, the practical usability eventually depends on a suitable +mobile user experience, which was largely disregarded by the desktop-oriented +Falkon browser that we enabled on Genode. + + +Assessment +---------- + +Fortunately, we discovered the Morph web browser while experimenting with +[https://xnux.eu/p-boot-demo/ - various Linux distributions] on the PinePhone. +Among the various alternatives to Android, the Ubuntu Touch UI - alongside +Sailfish OS - stood out for its refined user experience, subjectively. +The unobtrusive Morph browser as used by default on Ubuntu Touch left a +particularly good impression on us. To our delight, we found that this +browser relies on Qt5 and the Chromium web engine as its foundation, both of +which we already had enabled on Genode. Out of this observation grew the idea +of reusing the Morph browser as application runtime on our Genode-based phone. +But we had to consider several risks. + +First, would the heaviness of Chromium overwhelm the rather resource-constrained +PinePhone hardware when executed on Genode? In contrast to Linux, Genode's +POSIX environment is less sophisticated and - most importantly - does not +provide the over-provisioning of memory resources. The latter could be a show +stopper. + +Second, the build mechanics of the browser deviate from the beaten track we +covered so far, specifically the use of QMake. The Morph browser +unconditionally depends on CMake as build tool. Even though we gathered +[https://genodians.org/nfeske/2019-11-25-goa - early experiences], with using +CMake for building Genode executables, we did not attempt using CMake for +complex Qt5 applications targeting Genode so far. + +Finally, we discovered a so-called Ubuntu-Touch-UI toolkit as an +additional dependency over Qt5. It presumably extends Qt5's QML with +custom user-interface widgets for mobile user interfaces. In contrast +to the multi-platform Qt5 framework, Ubuntu Touch generally targets +Linux only, which raised a number of concerns with respect to hidden +assumptions on the underlying platform. For example, the expectation +of a certain service manager, the direct use of the Linux kernel interface, +or accidentally complex library dependencies. + + +Methodology +=========== + +As practiced during our work with bringing the Chromium-based Falkon web +browser to Genode, we took several intermediate steps to mitigate technical +risks as far as possible. + +Pruning dependencies +-------------------- + +The first step was building the Morph browser from source for its regular +designated target platform, namely Linux. This step allowed us to validate the +functionality of the browser built from source as opposed to merely testing a +binary package. During this process, we learned about the mandatory dependence +on CMake as build tool. We also identified the following library dependencies +as sources of uncertainty. + +*Ubuntu-UI toolkit* is a collection of QML widgets for smartphone apps. +It is built via QMake and comes with its own set of dependencies. +We were specifically concerned by QtSystemInfo, QtOrganizer, D-Bus, and +gettext. Genode has no meaningful equivalent to any of these dependencies. +The *Ubuntu Themes* dependency comprises graphical assets, used on Ubuntu +Touch. *Ubuntu-UI extras* extends Qt's feature set by functionality like the +'TabsBar' QML-Widget introduces additional transitive dependencies +such as the [https://www.cups.org/ - CUPS printing system] or +the [https://exiv2.org/ - Exiv2] image metadata library. + +Further dependencies worth noting are QNetworkInterface, QtConcurrent, QtDBus, +QtSystemInfo, unity-action-api, and D-Bus. Those libraries do not exist in +Genode and may even raise conceptual problems. For example, the D-Bus +inter-component mechanism on Linux is not in line with Genode's +capability-based inter-component communication. + +With the first manually built executable of Morph created on Linux, we could +repeatedly remove dependencies piece by piece and validate the functioning of +the browser after each step. We ultimately reached a point where most of the +library dependencies could be cut off while the core functionality of the +browser - the ability to view web pages - stayed intact. The resulting +minimized version of the Morph browser thereby served as starting point for +the subsequent porting work to Genode. + +Re-targeting to Genode +---------------------- + +To stay as close as possible to the original browser, we decided to reuse the +browser's build system by tweaking the CMake build tool such that the project +could be cross compiled for Genode, similar to the approach we successfully +employed for QMake in the past. At first, we targeted Genode/Linux on x86, +which is still close to the browser's natural environment. Once the first +version of the browser came to life, we immediately cross-validated the result +on the 64-bit ARM architecture as this is our primary target. Subsequently, we +moved away from Linux by moving the browser over to NOVA (on Sculpt) on PC +hardware as well as our custom base-hw microkernel in order to target the +actual PinePhone. + +[image touch_ui] + Ubuntu-Touch UI gallery demo running on Genode + +The methodology mirrored in large parts the approach we took for the original +porting of the Chromium web engine, but it was a much smoother experience +given that all road blocks we encountered during our Chromium work are solved +problems by now. Image [touch_ui] shows the browser's underlying +user-interface tool kit in action, running directly on Genode. Image [morph] +shows the Morph browser hosted in Genode's window system. + +[image morph] + Morph browser running on Genode + + +Unexpected caveats +================== + +However, the smooth ride of re-targeting the browser to Genode ended once +we discovered the extremely poor interactive performance of the browser +running on Genode. This is in contrast to our prior experience with the +Chromium-based Falkon browser which achieved comparable performance to Linux. + +The performance degradation originated from the Ubuntu-UI toolkit, which +has a hard dependency on OpenGL despite being built atop the Qt5 framework. +In several instances, the Ubuntu-UI toolkit accesses the OpenGL context +directly, which is handled by a software fallback implementation in the +Mesa library. We found the removal of those offending accesses infeasible +because this change would cause several widgets appearing incomplete. +To attain the visual completeness of the user interface, we also had to +enhance the Genode-specific back end of Qt (QPA). However, even though +we achieved correctly looking results, the performance of Mesa3D without +GPU acceleration made the user interface practically unusable, even on +powerful PC hardware, not speaking of the resource-constrained PinePhone. +We came to the conclusion that the Morph browser's hard dependency +on hardware-accelerated graphics cannot be worked around. This realization, +in turn, spawned the line of work reported in +Section [Hardware-accelerated graphics]. + +As another - but arguably much less dramatic - caveat, we found the touch user +interface behaving strangely in some situations when running on Genode. The +reason turned out to be a disparity of Genode's notion of touch-release events +from the expectations of Qt. Whereas Genode's input-event interface does not +report a positional value of a touch-release event, Qt expects a positional +value that corresponds to the original touch event. Fortunately, once this +disparity had been identified, we could easily emulate the expected behavior +locally in Genode's QPA plugin. + + +Hardware-accelerated graphics +============================= + +As mentioned above, we were taken by surprise by the hard dependency of the +Morph browser on GPU-accelerated graphics. Even though we have explored the +principle use of a GPU on an ARM-based platform before, our prior line of work +was targeting the Vivante GPU of the NXP i.MX8 SoC, which is different from +the Mali-400 GPU as present in the PinePhone's A64 SoC. Originally, we did not +plan to deal with the PinePhone's GPU at the current stage. But the +requirement of the Morph browser abruptly changed our priorities. + +As a rapid experiment, we took the challenge to port the Lima driver for the +Mali-400 GPU from Linux to Genode and combine it with the matching user-level +driver code of the Mesa library. Even though this experiment was pursued on +short notice and risky, it was at least a tangible straw. To our delight, +however, the first functional rapid prototype came to life after merely two +weeks of work, which is almost an order of magnitude faster than our past +efforts. The reason of this success is many-fold. First, our recently +established methodology and tooling for porting Linux device drivers - as +described in our comprehensive +[https://genode.org/documentation/genode-platforms-22-05.pdf - Porting Guide] - +streamlines the formerly labor-intensive grunt work. Second, we greatly +benefited from our practical experience with GPUs accumulated over the past +few years. And third, even though the Mali-400 is different from the Vivante +GPU, the integration into the Linux GPU stack follows very similar patterns, +unlike Intel GPUs. So we found our existing knowledge largely applicable. + +[image glmark2] + GLMark2 reference application using the GPU + +Following the initial rapid prototype, we successively refined this work to +the point where the GPU driver became usable for the Morph browser on the +PinePhone. Thanks to the added driver, the interactive performance got boosted +to an acceptable level. + + +Mobile data connectivity +======================== + +It goes without saying that a web browser requires network connectivity, +which is a topic we had left unaddressed on the PinePhone until now. +However, given our +[https://genode.org/documentation/release-notes/22.05#Telephony - recent line] +of modem-related work in the context of telephony, we foresaw a low-complexity +solution to attain mobile data connectivity. + +Today's LTE modems offer +[https://genodians.org/ssumpf/2020-12-04-mbim - QMI or MBIM] protocol support +in order to configure and handle mobile data connections. Both protocols are +in binary format and require a separate USB device (called Wireless Mobile +Communication Device). For Genode, this would mean to add support for this +device to USB while additionally the QMI or MBIM library would have to be +ported and adjusted to Genode. For the +[https://www.quectel.com/product/lte-eg25-g - Quectel EG25 modem] +in the PinePhone, we found a much simpler solution to handle mobile data +connections. The modem can be configured to emulate a USB Ethernet device +([https://en.wikipedia.org/wiki/Ethernet_over_USB - ECM device]). +In this operational mode, the modem will automatically connect to the carrier +and register itself as USB Ethernet device at the PinePhone's USB host +controller. Genode can thereby access the device through the USB networking +and CDC Ethernet drivers. The modem also offers a DHCP server and will hand +out a local IP address upon a DHCP request to Genode. Internally the modem +will use [https://en.wikipedia.org/wiki/Network_address_translation - NAT] in +order to translate IP requests from Genode to the address received from the +carrier. + +As a prerequisite to conduct this solution, we had to enable a USB +host-controller driver for the PinePhone. Of course, we took advantage of our +modern DDE Linux porting approach for this work, which allowed to attain a +functional USB driver in merely two weeks. This driver must be combined with +our existing USB Ethernet driver (usb_net) that we swiftly extended to support +ECM based devices. + +With this driver infrastructure in place, the USB network device of the modem +appears as uplink to Genode's NIC router. The NIC router, in turn, +successfully obtains a local IP address that is network-translated by the +modem. At the carrier side, IP network connectivity can be established by +issuing AT-protocol commands over UART. So the first prototype of the +low-level network connectivity worked as anticipated. With this practical way +of keeping the complexity of binary configuration protocols out of the loop, +we can maintain the low-complexity implementation of telephony and SIM +configuration via the UART control channel while regarding IP connectivity - +and the unavoidable complexity of USB - as an entirely complementary feature. + + +Phone flavor of Sculpt OS +========================= + +Seeing the various puzzle pieces of the Morph browser scenario - GPU +acceleration, data connectivity, the browser itself - coming together, it was +time for the integration of those pieces into an overall system. The natural +basis of such a Genode-based system is +[https://genode.org/download/sculpt - Sculpt OS], +which complements Genode with universally expected operating-system features +such as interactive system configuration as well as the installation and +deployment of software packages. + +Sculpt OS was originally designed for PC-based use cases. Its administrative +user interface is largely mouse and keyboard driven, and network connectivity +is usually attained by a wired or wireless LAN connection. Although we +presented a first version of +[https://fosdem.org/2022/schedule/event/nfeske/ - Sculpt OS on the PinePhone] +earlier this year, the call for a touch-oriented user interface is more than +obvious. Hence, we went forward with creating a phone-specific variant +of Sculpt. Similar to the original Sculpt OS, the system consists of two +largely isolated domains, the administrative domain called Leitzentrale and +the domain of user-installed components called desktop. The user can switch +between both domains at any time using a secure attention key or gesture. +On the phone, the Leitzentrale domain plays the role of a feature-phone +appliance that provides the most fundamental device functionality such +as the interaction with the SIM card, power control, telephony, network +configuration, storage management, and software installation. We approached +the concept of the user interface from a clean slate striving for simplicity. + +[image sim_pin] + Emerging mobile-phone flavor of Sculpt OS + +As the first use case, we addressed telephony, displaying incoming calls, +presenting the options for accepting/rejecting calls, and initiating calls +using a dial pad. By modelling these scenarios, we could validate the +user-interface concept of the evolving phone version of Sculpt's Leitzentrale. + + +User interaction with the SIM card +================================== + +The administrative user interface mentioned above must be matched by the +underlying middleware that talks to the modem. Remember that our +[https://genode.org/documentation/release-notes/22.05#Telephony - original] +telephony scenario relied on the manual use of the modem's AT commands. +We ultimately have to control the modem's control channel by software using an +AT protocol stack. To bridge this gap with the lowest complexity possible, we +created a simple AT protocol implementation that is specifically designed for +Genode's state-driven component model. +The modem driver - hosting the AT protocol driver - accepts a configuration +that expresses the desired state (as opposed to desired actions). For example, +a configuration may look as simple as follows. + +! +! +! + +The AT protocol implementation takes this configuration and the current modem +state as the basis for determining a sequence of modem commands needed to +attain the desired state. For example, if the modem is not powered, the driver +steps through the powering sequence. Or in case the SIM PIN is required, the +driver supplies the corresponding command to supply the configured PIN. + +To allow interactive usage, the driver supports dynamic reconfiguration. +E.g., to cancel the outbound call of the example above, the configuration +would be updated with the '' node removed. Given this approach, an +interactive user interface comes down to generating such simple +configurations. + +Vice versa, the driver exports the modem's state as a state report, which is +updated whenever the modem state changes. E.g., an incoming call is reflected +to the consumer of this state report with all information relevant for an +interactive user interface. For example, the state report entails the power +state, PIN state, and call states (incoming, outbound, alerting, rejected). +This design nicely hides the peculiarities of the AT protocol from Genode's +component interfaces. + +At the current stage, with less than 1000 lines of code, the AT protocol +implementation suffices for basic telephony needs, supporting the interaction +with the SIM card, managing call states, initiating calls, and driving the +modem power up and down. It also takes care of establishing the modem +configuration needed for USB ECM networking. + + +Current state +============= + +The current version of the phone variant of Sculpt OS is able to control the +power state of the modem, interact with the SIM card (PIN entry), initiate +phone calls via a dial pad, pick up inbound calls, establish mobile-data +network connectivity, and deploy a preconfigured application scenario. +The interactive switching between the base system and the application runtime +can be triggered at any time by touching the left border of the touch screen. + +[image sculpt_pinephone] + The runtime graph of the base system (left) reveals the relationships of the + Morph browser with other components (right). + +This flavor of Sculpt OS evolves in the +[https://github.com/nfeske/genode-allwinner - genode-allwinner] repository, +specifically within the _sculpt/_ and _src/app/phone_manager/_ directories. +The latter asserts the role of Sculpt's _gems/src/app/sculpt_manager_. +We invite seasoned developers - especially those who are following the +[https://genodians.org/nfeske/index - Pine-fun article series] - to experiment +with the new phone variant. It can be built via the following command: + +! built/arm_v8a$ make run/sculpt KERNEL=hw BOARD=pinephone SCULPT=phone + +For a broader audience, we plan to provide a ready-to-use SD-card image for +the PinePhone in tandem with the next release of Sculpt OS. + + +Enhanced tooling for system tracing +################################### + +Since release 13.08, Genode features a +[https://genode.org/documentation/release-notes/13.08#Light-weight_event_tracing - light-weight event-tracing facility] +that comes in form of core's TRACE service. Up to now, it has merely been used +for capturing textual trace messages. The two prominent monitor components are +the +[https://genode.org/documentation/release-notes/18.02#New_trace-logging_component - trace_logger] +and the +[https://genode.org/documentation/release-notes/19.08#Tracing - VFS plugin] + +The trace recorder is a new monitor component that is designed for binary trace +formats. Currently, it supports the Common Trace Format (CTF) and pcapng. +CTF is a compact and scalable format for storing event traces. It is supported +by [https://www.eclipse.org/tracecompass/ - TraceCompass], an Eclipse-based +tool for trace analysis and visualization. Pcapng is a packet-capture format +used by Wireshark. + +In order to support capturing network packets, we added a 'trace_eth_packet()' +method to Genode's trace-policy API and equipped the NIC router with a +'trace_packets' option to control packet capturing on domain level. For manual +instrumentation of components, we also added a 'checkpoint()' method to the +trace-policy API. + +For more details, please refer to the following Genodians article. + +:Identifying network-throughput bottlenecks with trace recording: + + [https://genodians.org/jschlatow/2022-08-29-trace-recorder] + + +Base framework and OS-level infrastructure +########################################## + +Networking optimizations +======================== + +With the new trace recorder at hand, we took an effort in optimizing Genode's +network throughput. First, we implemented a benchmark component called +"nic_perf" that sends and/or receives an infinite stream of UDP packets in +order to stimulate the involved networking components in separation. As a +consequence of its central role, we particularly focused on the NIC router as +a starting point. + +As a base line, we took two 'nic_perf' components: one as a sender and the other +as a receiver. By taking any copying or packet inspection out of the loop, we +could verify that the packet-stream interface holds up to our expectations with +respect to attainable throughput. However, as soon as we put a NIC router in +between, the throughput dropped to approx. 10% of our base line. On older +ThinkPads, this meant sub-gigabit throughput and on a Cortex-A9 @ 666MHz we +barely jumped over the 100Mbit mark. + +Since we were not able to explain the substantial decrease in packet throughput, +we investigated with the help of the trace recorder and 'GENODE_LOG_TSC'. +As it turned out, the NIC router spent most of its time with exception handling +during routing-rule lookup, which is done for every packet. Since there are +multiple types of rules, a lookup takes place for every rule type. If no rule +was found for particular type, an exception was thrown and caught, which +turned out to be incredibly expensive. We therefore eliminated exceptions from +common-case code paths, more precisely from rule lookup, from ARP-cache +lookup, and from packet allocation. The result impressed us with a tripled +throughput. + +Another bottleneck that we identified were frequent 'trigger_once' and +'elapsed_ms' RPCs. Given that the NIC router only maintains very +coarse-grained timeouts, such frequent RPCs to the timer seemed finical. +Sparing the details, we were able to significantly reduce the number of +these RPCs by relaxing the precision of the NIC router's time keeping. + +Along the way, we identified a few more, minor, tweaks: + +* We increased the default value of 'max_packets_per_signal' from 32 to 150. + This value determines the maximum number of packets that are consumed from an + interface at once. +* We eliminated eager packet-stream signalling from the NIC router to improve + batch processing of packets. With this change, packet-stream signals are only + emitted once the NIC router processed all available or + 'max_packets_per_signal' packets. +* We implemented incremental checksum update for UDP/TCP according to RFC1071. +* We discovered and fixed a few corner cases in the packet-stream interface + with respect to the signalling. +* We fixed allocation errors in the 'ipxe_nic_drv' that popped up during high + TX load. + +In the end, we attained a ~5x speed up (exact values depending on the hardware) +for the NIC router. + + +Event-filter improvements for touch devices +=========================================== + +The phone variant of Sculpt OS calls for a way to trigger certain low-level +buttons or keys using the touch screen. In particular, the switch between the +administrative user interface and the runtime system must be possible at any +time. On the [https://genode.org/download/sculpt - PC version], this switch +is triggered by pressing F12, which is remapped to KEY_DASHBOARD. Even though +a physical button could be used on the phone in principle, there are three +arguments in favor of a virtual key. First, there are only three physical +buttons available (volume +/- and power) on the PinePhone. Remapping one of +those buttons to KEY_DASHBOARD deprives the button of its original purpose. +Second, the force needed for pressing a physical button may impede the +ergonomics of the device depending on how often the switch is needed. And +third, the physical buttons require a driver. When enabling a new device, this +barrier can be nicely sidestepped by a virtual key. + +Given this rationale, we extended Genode's event-filter component with a new +'' filter type. Once added to the filter chain, it triggers an +artificial key tap (a press event followed by a release event) whenever the +user touches a preconfigured area on the touch screen. The filter node can +host any number of '' sub nodes. Each sub node must define a rectangular +area - using the attributes 'xpos', 'ypos', 'width', and 'height' - and the +name of the tapped key as 'key' attribute. + +! +! +! ... +! + +The example above repurposes the 25 left-most pixels of the touch screen as +dashboard key. When touched, a pair of press and release events is fired at +once. + + +Menu-view performance +===================== + +The administrative user interface of Sculpt OS is based on Genode's custom +menu-view component, which renders and updates graphical dialogs based on +high-level XML descriptions. Up to now, the component operated on Genode's +GUI-session interface with alpha-channel support. However, the alpha channel +noticeably impedes the software-rendering performance on lower-end devices +like the PinePhone. In the latter case, we'd prefer to trade the nice-looking +alpha blending for a better UI responsiveness. + +We have now enhanced the menu-view component with two new optional +configuration attributes 'opaque' and 'background'. Setting 'opaque' to "yes" +suppresses the use of the alpha channel at the GUI session. This improves the +drawing performance by 20% on the PinePhone. The 'background' attribute can be +specified to define the reset color of the GUI buffer. It alleviates the need +to create a frame widget for the top level, significantly reducing the costs +for drawing the background pixels. + +Finally, we found that the use of GCC's optimization level -O3 instead of the +default level -O2 increases the drawing performance on the PinePhone by 30%. +Combined, those optimizations result in an acceptable user experience of +Sculpt's administrative user interface on the PinePhone. + + +Device drivers +############## + +USB networking via Ethernet control model (ECM) +=============================================== + +To implement mobile data connectivity on the PinePhone +(Section [Mobile data connectivity]), we added USB host-controller support +(EHCI) for the Allwinner A64 SoC to Genode by porting the corresponding +host-controller driver from Linux using our DDE approach. Since our existing +USB-over-Ethernet +[https://github.com/genodelabs/genode/tree/master/repos/dde_linux/src/drivers/usb_net - driver] +on Genode lacked support for the Ethernet Control Model, which is provided by +the modem, we added support for ECM as well. + + +GPU and Mesa driver for Mali-400 +================================ + +As mentioned in Section [Genode coming to the phone], we enabled the principle +ability to use the Mali-400 GPU of the PinePhone under Genode. This support +entails two parts. The first part is the low-level driver code called Lima +that normally resides in the Linux kernel. This component provides a GPU +session interface. We transplanted the driver code to a dedicated Genode +component, which is hosted at the +[https://github.com/genodelabs/genode-allwinner - genode-allwinner] repository. +The second part is the user-level Mesa3D driver stack - hosted at the libports +repository - that is linked local to the application and uses the GPU session +to access the GPU. + +The combination of both parts was successfully tested on the PinePhone and +the Pine-A64-LTS V1.2 board. Given that the primary motivation for this +line of work was our ambition to run the Morph web browser, we disregarded the +multiplexing of the GPU for now. The GPU driver currently supports only one +client at a time. + + +SD-card driver for the PinePhone +================================ + +In anticipation of running Sculpt OS on the PinePhone, we ported the Linux +SD/MMC-card driver to Genode. The driver - hosted at the +[https://github.com/genodelabs/genode-allwinner - genode-allwinner] repository - +was successfully tested with the PinePhone and Pine-A64LTS V1.2 board. For the +moment, only SD cards (no eMMC) are supported. +The provided _a64_sd_card_drv.run_ script illustrates the integration and use +of the driver. + + +Linux-device-driver environment (DDE Linux) +=========================================== + +Tickless idle operation +----------------------- + +The DDE-Linux emulation library and thereby all ported drivers now support +the NO_HZ_IDLE Linux kernel configuration option, which disables periodic +timer ticks when ported drivers are idle. With this option, energy and up to +3% CPU time per driver can be preserved, which becomes significant especially +if multiple ported drivers are in use in sophisticated scenarios like Sculpt +OS. + +Consistent use of SMP configuration +----------------------------------- + +All kernel threads in the Linux device driver ports are currently mapped to one +and the same native Genode thread, using cooperative scheduling within the +emulation environment. Intuitively, it does not make much sense to address +multi-processing support provided by the original Linux kernel code. +Nonetheless, the drivers that we ported are normally used in the context of +SMP-aware Linux kernel configurations only. To not leave the well tested and +beaten track, we decided to switch on SMP support in all kernel configurations +we use as porting base. + +This especially applies to the Linux drivers within the _repos/pc_ +sub-directory, and the WireGuard port. Other driver ports already used SMP +support in their configuration. + +As a side effect, we removed the insufficient emulation of so called "softirqs" +formerly used by the non-SMP driver ports, and replaced them with the original +implementation. + + +Forthcoming platform-driver modernization +========================================= + +During the past year, we switched from board-specific platform driver APIs +step-by-step to one generic interface. But PC-related drivers still depend on +the legacy x86-specific platform driver and API, especially to the PCI-related +part of it. + +To finalize the unification and modernization of the platform driver and its +API, there were still some pieces missing, which we added with the current +release. + +While trying to switch PC-related Linux device driver ports to the new API, we +recognized that some drivers depend on additional information of the PCI +configuration space that were not exported so far. Namely, the fields for +sub-vendor, sub-product, and revision IDs were needed. Moreover, some ported +drivers use hard-coded indices of PCI base-address registers (BAR) to refer to +I/O resources of the device. + +Therefore, we extended the pci_decode tool to export this additional +information, and to annotate I/O port ranges and memory attributes with the +corresponding BAR index. The generic platform driver parses this additional +information from a given devices ROM, and exports it to the corresponding +clients accordingly. The correlation between I/O resources and BAR indices is +only unveiled to clients where the platform driver's policy states that +physical information has to be provided, like in this example: + +! +! +! +! +! ... +! + +UHCI-specific platform extensions +--------------------------------- + +Some device-specific registers are only present within the PCI configuration +space. For instance UHCI controllers in the PC architecture provide a special +legacy support register only accessible via the PCI configuration space. This +register is used to hand over the USB hardware from the BIOS to the operating +system. + +We did not want to pollute the platform API with a lot of device specific +tweaks nor provide unlimited access to the PCI configuration space to a +driver. Therefore, we implement the hand-over of the UHCI PCI device in the +platform driver if available. Moreover, we handle the Intel-specific resume +register whenever a session to the corresponding UHCI controller is opened. + +Intel GPU information from Host Bridge +-------------------------------------- + +Some information needed by Intel GPU and framebuffer drivers is derived from +the Intel Graphics and Controller HUB (GMCH) respectively its control +register. It is used to calculate the GPU's Global Translation Table (GTT), +and the stolen memory sizes. Again we do not want to give access to the whole +configuration space of this sensitive device to either the GPU or the +framebuffer driver. Instead, the platform driver now detects Intel PCI graphic +cards, and exports the information found within the GMCH control register to +the corresponding client as part of the platform session's devices ROM. + +Transition of PC drivers +------------------------ + +Although there is everything in place now to switch the remaining PC-drivers +to the generic platform driver and its API, we decided to do this step after +the current release. This way, we have time to stress-test the drivers during +our daily use of Genode, the remaining transitional work is planned for the +upcoming Sculpt OS release instead. + + +Libraries and applications +########################## + +Qt5 and Morph browser +===================== + +As mentioned in Section [Genode coming to the phone], we had to improve +Genode's Qt support to get the Morph browser to work. This work includes +added support for building Qt projects with CMake, the addition of missing Qt +modules like QtGraphicalEffects, and improving the OpenGL support of the QPA +plugin. The latter was needed for the Ubuntu UI Toolkit to display its widgets +correctly. Note that this change implies that QtQuick applications now use +OpenGL by default instead of the QtQuick software rendering fallback back end. +This can improve the experience when an accelerated GPU driver is available +but can also slow down a QtQuick application if only the Mesa software driver +('softpipe') is available on the target platform. In that case, it is possible +to enforce the use of the software QtQuick renderer by setting the following +environment variable in the configuration of the application: + +! + +When we tried to use the free public Jitsi server at [https://meet.jit.si] with +our ported web browsers, we noticed that our QtWebEngine Chromium version was +too old and caused issues like a non-working join button and failed WebRTC +connections. For this reason, we updated our Qt port to the latest version with +QtWebEngine support on FreeBSD, which at this time is version 5.15.2. + +To use this new version, it is necessary to update the Qt5 host tools with the +'tool/tool_chain_qt5' script. + +We also updated the Falkon web browser to the latest version 3.2.0. + +Up-to-date Sculpt packages of both the Falkon and Morph browsers for x86_64 are +available in the 'cproc' depot. + + +USB smart cards via PKCS#11 +=========================== + +With this release, Genode gains support for accessing USB smart-card devices +via PKCS#11. This is achieved through a port of the OpenSC PKCS#11 tool that is +now available as package for the Sculpt OS. A quick look into the features and +integration of the tool is possible using the new _pkcs11_tool_ run script +hosted in the [https://github.com/genodelabs/genode-world - genode-world] +repository. For a more detailed guide to the tool, you may read the +corresponding Genodians article. + +:USB smart cards via PKCS#11: + + [https://genodians.org/m-stein/2022-08-18-pkcs11-tool-1] + + +Sculpt OS improvements +====================== + +In addition to the major developments described in +Section [Genode coming to the phone], Sculpt OS has received several minor +refinements. + +When integrating a +[https://genode.org/documentation/release-notes/22.02#Framework_for_special-purpose_Sculpt-based_operating_systems - Sculpt-based appliance] +with a predefined deploy configuration, the _sculpt.run_ script automatically +adds the required software packages as tar archive to the boot image. However, +for complex scenarios, it is sometimes desirable to keep the boot image small +and fetch the packages at runtime over the network. To support such use cases, +we added the new run-script argument 'DEPOT' with the possible values 'tar' +(default) and 'omit'. If the latter is specified, the deployed software +packages are excluded from the boot image and the run script merely prints the +versions of the required packages. This information can conveniently be used +as input for publishing the packages. + +We added two new packages 'part_block' and 'ext2_fs' that simplify the access +of multiple block devices and partitions in manually curated deploy +configurations. The part_block package can be used in Sculpt's +_/config/deploy_ as follows. + +! +! +! +! +! +! +! +! +! +! + +It can be combined with the 'ext2_fs' package to access the files stored on a +particular partition. + +! +! +! +! +! +! +! +! +! +! + + +Platforms +######### + +Qemu virtual platform +===================== + +Because more and more architectures on Genode now support VirtIO drivers on +Qemu (ARMv7, ARMv8, and RISC-V), the generic board name "virt_qemu" did not +suffice for keeping a clean distinction between the separate architecture +requirements. Therefore, we decided to make the board name architecture +specific. The following board names are now supported on base-hw: +"virt_qemu_arm_v7a", "virt_qemu_arm_v8a", and "virt_qemu_riscv". +The "virt_qemu" board name was removed. + + +RISC-V +====== + +As suggested above Genode's RISC-V support got extended by VirtIO drivers. +This includes a block driver, a networking driver, keyboard and mouse handling +as well as basic framebuffer support. This way, it has become possible to test +interactive and networking scenarios on Genode's RISC-V version using Qemu. + +This work was contributed by Piotr Tworek. Thanks a lot! + + +Allwinner A64 +============= + +In the +[https://genode.org/documentation/release-notes/22.05#Custom_system-control_processor__SCP__firmware - previous release], +we introduced our custom firmware for the PinePhone's system-control processor +(SCP). We have now generalized the firmware to cover also the Pine-A64-LTS +board. By establishing our custom SCP firmware as a base line for all A64-based +boards, we can make our A64 platform driver depend on the SCP for accessing the +PMIC (power management chip) instead of driving the RSB and PMIC by itself. + + +Build system and tools +###################### + +In this release, we improve support for booting Genode/Sculpt on UEFI +platforms in several aspects. First, the Bender tool gains a more robust +UEFI-boot detection mechanism while retrieving serial-device parameters. Also, +the GRUB boot loader was updated to version 2.06 and now keeps lower RAM +untouched from internal memory allocations, which prevents nasty surprises on +booting some UEFI devices. And last, our [https://ipxe.org/ - iPXE-based] boot +option received support for UEFI images when using the following run-tool +configuration. + +! RUN_OPT += --include image/uefi +! RUN_OPT += --include load/ipxe + diff --git a/repos/base-fiasco/recipes/src/base-fiasco/content.mk b/repos/base-fiasco/recipes/src/base-fiasco/content.mk index 1c494bd998..cc4c522144 100644 --- a/repos/base-fiasco/recipes/src/base-fiasco/content.mk +++ b/repos/base-fiasco/recipes/src/base-fiasco/content.mk @@ -21,6 +21,5 @@ content: for spec in x86_32; do \ mv lib/mk/spec/$$spec/ld-fiasco.mk lib/mk/spec/$$spec/ld.mk; \ done; - sed -i "s/ld-fiasco/ld/" src/lib/ld/fiasco/target.mk sed -i "s/fiasco_timer_drv/timer/" src/timer/fiasco/target.mk diff --git a/repos/base-fiasco/recipes/src/base-fiasco/hash b/repos/base-fiasco/recipes/src/base-fiasco/hash index e295e18337..f9dac8e5fc 100644 --- a/repos/base-fiasco/recipes/src/base-fiasco/hash +++ b/repos/base-fiasco/recipes/src/base-fiasco/hash @@ -1 +1 @@ -2022-05-24 1790ce242c001ed77aab9695f69923a44d1dc1d1 +2022-10-11 1f0607de6493bad0e47b24e66d84474652e8b6be diff --git a/repos/base-fiasco/src/lib/ld/fiasco/target.mk b/repos/base-fiasco/src/lib/ld/fiasco/target.mk deleted file mode 100644 index 060986f382..0000000000 --- a/repos/base-fiasco/src/lib/ld/fiasco/target.mk +++ /dev/null @@ -1,2 +0,0 @@ -TARGET = ld-fiasco -LIBS = ld-fiasco diff --git a/repos/base-foc/recipes/src/base-foc-imx6q_sabrelite/hash b/repos/base-foc/recipes/src/base-foc-imx6q_sabrelite/hash index 4746445245..265fd08d89 100644 --- a/repos/base-foc/recipes/src/base-foc-imx6q_sabrelite/hash +++ b/repos/base-foc/recipes/src/base-foc-imx6q_sabrelite/hash @@ -1 +1 @@ -2022-05-24 f7900083623a2009d35234c47d2475dea8f6cf53 +2022-10-11 d258920f8664460c78eeea25fafb89eaa5e7adf5 diff --git a/repos/base-foc/recipes/src/base-foc-imx7d_sabre/hash b/repos/base-foc/recipes/src/base-foc-imx7d_sabre/hash index f276f3e23e..b26ae8d41e 100644 --- a/repos/base-foc/recipes/src/base-foc-imx7d_sabre/hash +++ b/repos/base-foc/recipes/src/base-foc-imx7d_sabre/hash @@ -1 +1 @@ -2022-05-24 f7d228f6419c2fc9b1b0faf4ba8d88862ba61e81 +2022-10-11 1c94d29566bccccced246eeaf90702348e2b1a7f diff --git a/repos/base-foc/recipes/src/base-foc-pbxa9/hash b/repos/base-foc/recipes/src/base-foc-pbxa9/hash index 9db655430c..51ecc915eb 100644 --- a/repos/base-foc/recipes/src/base-foc-pbxa9/hash +++ b/repos/base-foc/recipes/src/base-foc-pbxa9/hash @@ -1 +1 @@ -2022-05-24 391b798b7c1d1b44ff65d855980eb41a8f4a87c1 +2022-10-11 2668fd23d5cbd45b8f632073fc7c155f96ecb848 diff --git a/repos/base-foc/recipes/src/base-foc-pc/hash b/repos/base-foc/recipes/src/base-foc-pc/hash index 0ae034bc12..56c9910ab6 100644 --- a/repos/base-foc/recipes/src/base-foc-pc/hash +++ b/repos/base-foc/recipes/src/base-foc-pc/hash @@ -1 +1 @@ -2022-05-24 79eab679e71dd70803b0e1647a23e2ba86c76f50 +2022-10-11 8da054ff9e4c37895816fd30857b3c42d9e75eb0 diff --git a/repos/base-foc/recipes/src/base-foc-rpi3/hash b/repos/base-foc/recipes/src/base-foc-rpi3/hash index 4b5f6173ab..e63b5c8e6a 100644 --- a/repos/base-foc/recipes/src/base-foc-rpi3/hash +++ b/repos/base-foc/recipes/src/base-foc-rpi3/hash @@ -1 +1 @@ -2022-05-24 7a16aeb081d1392c36d83f526936f17cc9560442 +2022-10-11 f41df6b57d2c4b090a84427e02950df84fb385ad diff --git a/repos/base-foc/recipes/src/base-foc_content.inc b/repos/base-foc/recipes/src/base-foc_content.inc index b4b26e44df..7d97f7d1e8 100644 --- a/repos/base-foc/recipes/src/base-foc_content.inc +++ b/repos/base-foc/recipes/src/base-foc_content.inc @@ -39,5 +39,4 @@ content: for spec in x86_32 x86_64 arm arm_64; do \ mv lib/mk/spec/$$spec/ld-foc.mk lib/mk/spec/$$spec/ld.mk; \ done; - sed -i "s/ld-foc/ld/" src/lib/ld/foc/target.mk sed -i "s/foc_timer_drv/timer/" src/timer/foc/target.mk diff --git a/repos/base-foc/src/lib/ld/foc/target.mk b/repos/base-foc/src/lib/ld/foc/target.mk deleted file mode 100644 index ef4453cc43..0000000000 --- a/repos/base-foc/src/lib/ld/foc/target.mk +++ /dev/null @@ -1,2 +0,0 @@ -TARGET = ld-foc -LIBS = ld-foc diff --git a/repos/base-hw/board/virt_qemu/arch b/repos/base-hw/board/virt_qemu_arm_v7a/arch similarity index 50% rename from repos/base-hw/board/virt_qemu/arch rename to repos/base-hw/board/virt_qemu_arm_v7a/arch index cd8d498319..16c61114d8 100644 --- a/repos/base-hw/board/virt_qemu/arch +++ b/repos/base-hw/board/virt_qemu_arm_v7a/arch @@ -1,2 +1 @@ arm_v7a -arm_v8a diff --git a/repos/base-hw/board/virt_qemu/image_link_address b/repos/base-hw/board/virt_qemu_arm_v7a/image_link_address similarity index 100% rename from repos/base-hw/board/virt_qemu/image_link_address rename to repos/base-hw/board/virt_qemu_arm_v7a/image_link_address diff --git a/repos/base-hw/board/virt_qemu_arm_v8a/arch b/repos/base-hw/board/virt_qemu_arm_v8a/arch new file mode 100644 index 0000000000..ae398b9a2e --- /dev/null +++ b/repos/base-hw/board/virt_qemu_arm_v8a/arch @@ -0,0 +1 @@ +arm_v8a diff --git a/repos/base-hw/board/virt_qemu_arm_v8a/image_link_address b/repos/base-hw/board/virt_qemu_arm_v8a/image_link_address new file mode 100644 index 0000000000..f8742e5363 --- /dev/null +++ b/repos/base-hw/board/virt_qemu_arm_v8a/image_link_address @@ -0,0 +1 @@ +0x40000000 diff --git a/repos/base-hw/lib/mk/spec/arm_v7/bootstrap-hw-virt_qemu.mk b/repos/base-hw/lib/mk/spec/arm_v7/bootstrap-hw-virt_qemu_arm_v7a.mk similarity index 76% rename from repos/base-hw/lib/mk/spec/arm_v7/bootstrap-hw-virt_qemu.mk rename to repos/base-hw/lib/mk/spec/arm_v7/bootstrap-hw-virt_qemu_arm_v7a.mk index d4351334e5..b26a3dc66e 100644 --- a/repos/base-hw/lib/mk/spec/arm_v7/bootstrap-hw-virt_qemu.mk +++ b/repos/base-hw/lib/mk/spec/arm_v7/bootstrap-hw-virt_qemu_arm_v7a.mk @@ -1,6 +1,6 @@ -REP_INC_DIR += src/bootstrap/board/virt_qemu +REP_INC_DIR += src/bootstrap/board/virt_qemu_arm_v7a -SRC_CC += bootstrap/board/virt_qemu/platform.cc +SRC_CC += bootstrap/board/virt_qemu_arm_v7a/platform.cc SRC_CC += bootstrap/spec/arm/arm_v7_cpu.cc SRC_CC += bootstrap/spec/arm/cortex_a15_cpu.cc SRC_CC += bootstrap/spec/arm/gicv2.cc diff --git a/repos/base-hw/lib/mk/spec/arm_v7/core-hw-virt_qemu.mk b/repos/base-hw/lib/mk/spec/arm_v7/core-hw-virt_qemu_arm_v7a.mk similarity index 93% rename from repos/base-hw/lib/mk/spec/arm_v7/core-hw-virt_qemu.mk rename to repos/base-hw/lib/mk/spec/arm_v7/core-hw-virt_qemu_arm_v7a.mk index 477b70eb93..e6830f1877 100644 --- a/repos/base-hw/lib/mk/spec/arm_v7/core-hw-virt_qemu.mk +++ b/repos/base-hw/lib/mk/spec/arm_v7/core-hw-virt_qemu_arm_v7a.mk @@ -1,4 +1,4 @@ -REP_INC_DIR += src/core/board/virt_qemu +REP_INC_DIR += src/core/board/virt_qemu_arm_v7a REP_INC_DIR += src/core/spec/arm/virtualization # add C++ sources diff --git a/repos/base-hw/lib/mk/spec/arm_v8/bootstrap-hw-virt_qemu.mk b/repos/base-hw/lib/mk/spec/arm_v8/bootstrap-hw-virt_qemu_arm_v8a.mk similarity index 77% rename from repos/base-hw/lib/mk/spec/arm_v8/bootstrap-hw-virt_qemu.mk rename to repos/base-hw/lib/mk/spec/arm_v8/bootstrap-hw-virt_qemu_arm_v8a.mk index c6d06d592f..65ac7ac5cb 100644 --- a/repos/base-hw/lib/mk/spec/arm_v8/bootstrap-hw-virt_qemu.mk +++ b/repos/base-hw/lib/mk/spec/arm_v8/bootstrap-hw-virt_qemu_arm_v8a.mk @@ -1,8 +1,8 @@ -REP_INC_DIR += src/bootstrap/board/virt_qemu_64 +REP_INC_DIR += src/bootstrap/board/virt_qemu_arm_v8a SRC_CC += bootstrap/spec/arm/gicv3.cc SRC_CC += bootstrap/spec/arm_64/cortex_a53_mmu.cc -SRC_CC += bootstrap/board/virt_qemu_64/platform.cc +SRC_CC += bootstrap/board/virt_qemu_arm_v8a/platform.cc SRC_CC += lib/base/arm_64/kernel/interface.cc SRC_CC += spec/64bit/memory_map.cc SRC_S += bootstrap/spec/arm_64/crt0.s diff --git a/repos/base-hw/lib/mk/spec/arm_v8/core-hw-virt_qemu.mk b/repos/base-hw/lib/mk/spec/arm_v8/core-hw-virt_qemu_arm_v8a.mk similarity index 92% rename from repos/base-hw/lib/mk/spec/arm_v8/core-hw-virt_qemu.mk rename to repos/base-hw/lib/mk/spec/arm_v8/core-hw-virt_qemu_arm_v8a.mk index 27e337f0fe..41825db29d 100644 --- a/repos/base-hw/lib/mk/spec/arm_v8/core-hw-virt_qemu.mk +++ b/repos/base-hw/lib/mk/spec/arm_v8/core-hw-virt_qemu_arm_v8a.mk @@ -1,4 +1,4 @@ -REP_INC_DIR += src/core/board/virt_qemu_64 +REP_INC_DIR += src/core/board/virt_qemu_arm_v8a REP_INC_DIR += src/core/spec/arm/virtualization # add C++ sources diff --git a/repos/base-hw/lib/mk/timeout-hw.mk b/repos/base-hw/lib/mk/timeout-hw.mk index aad9ffa127..eabca0ad00 100644 --- a/repos/base-hw/lib/mk/timeout-hw.mk +++ b/repos/base-hw/lib/mk/timeout-hw.mk @@ -4,6 +4,6 @@ SRC_CC += timer_connection_time.cc SRC_CC += hw/timer_connection_timestamp.cc SRC_CC += duration.cc -INC_DIR += $(BASE_DIR)/src/include +REP_INC_DIR += src/include -vpath % $(BASE_DIR)/src/lib/timeout +vpath % $(call select_from_repositories,src/lib/timeout) diff --git a/repos/base-hw/recipes/src/base-hw-imx53_qsb/hash b/repos/base-hw/recipes/src/base-hw-imx53_qsb/hash index b22493af83..8dbc470141 100644 --- a/repos/base-hw/recipes/src/base-hw-imx53_qsb/hash +++ b/repos/base-hw/recipes/src/base-hw-imx53_qsb/hash @@ -1 +1 @@ -2022-05-24 ab1cb582165e76bda4abf27870f44ad7d1ae5b6d +2022-10-11 50db06fe21eca6c46c9b4bf7fcbc81538ac74f32 diff --git a/repos/base-hw/recipes/src/base-hw-imx53_qsb_tz/content.mk b/repos/base-hw/recipes/src/base-hw-imx53_qsb_tz/content.mk index cf571d6154..829317888c 100644 --- a/repos/base-hw/recipes/src/base-hw-imx53_qsb_tz/content.mk +++ b/repos/base-hw/recipes/src/base-hw-imx53_qsb_tz/content.mk @@ -1,4 +1,6 @@ CONTENT += src/core/board/imx53_qsb \ - src/bootstrap/board/imx53_qsb + src/bootstrap/board/imx53_qsb \ + lib/mk/spec/arm_v7/core-hw-imx53_qsb.inc \ + lib/mk/spec/arm_v7/bootstrap-hw-imx53_qsb.inc include $(GENODE_DIR)/repos/base-hw/recipes/src/base-hw_content.inc diff --git a/repos/base-hw/recipes/src/base-hw-imx53_qsb_tz/hash b/repos/base-hw/recipes/src/base-hw-imx53_qsb_tz/hash index 31bad89aab..6d37391b56 100644 --- a/repos/base-hw/recipes/src/base-hw-imx53_qsb_tz/hash +++ b/repos/base-hw/recipes/src/base-hw-imx53_qsb_tz/hash @@ -1 +1 @@ -2022-05-24 0fff6ce83b962b3fd54cf6eda0a157cb0cb0c9d5 +2022-10-11 1377d3a2b7afaa265cc5ae6bbd515679be527c40 diff --git a/repos/base-hw/recipes/src/base-hw-imx6q_sabrelite/hash b/repos/base-hw/recipes/src/base-hw-imx6q_sabrelite/hash index 5259a2354f..00b6238861 100644 --- a/repos/base-hw/recipes/src/base-hw-imx6q_sabrelite/hash +++ b/repos/base-hw/recipes/src/base-hw-imx6q_sabrelite/hash @@ -1 +1 @@ -2022-05-24 8c17512664a648eaed876c815ea678770eda3280 +2022-10-11 c32cf899ce00bd69aff5bbd4f7b6b611d2bfa47d diff --git a/repos/base-hw/recipes/src/base-hw-imx7d_sabre/hash b/repos/base-hw/recipes/src/base-hw-imx7d_sabre/hash index 31826aea8e..0df81b7f31 100644 --- a/repos/base-hw/recipes/src/base-hw-imx7d_sabre/hash +++ b/repos/base-hw/recipes/src/base-hw-imx7d_sabre/hash @@ -1 +1 @@ -2022-05-24 edc396d9bc9a2ebf73590e70c1363020226909be +2022-10-11 39ff297bc573b8e8bf4f2e6e233bf0b1b21f13af diff --git a/repos/base-hw/recipes/src/base-hw-nit6_solox/hash b/repos/base-hw/recipes/src/base-hw-nit6_solox/hash index a2e240820d..59a5a7a695 100644 --- a/repos/base-hw/recipes/src/base-hw-nit6_solox/hash +++ b/repos/base-hw/recipes/src/base-hw-nit6_solox/hash @@ -1 +1 @@ -2022-05-24 da90478c4c0b8993041bc59488eedb124e680e78 +2022-10-11 f5456c3ed55b53ccaefee603fdb8d9b1e3ca84ab diff --git a/repos/base-hw/recipes/src/base-hw-pbxa9/hash b/repos/base-hw/recipes/src/base-hw-pbxa9/hash index 8842770459..9f9b562e4e 100644 --- a/repos/base-hw/recipes/src/base-hw-pbxa9/hash +++ b/repos/base-hw/recipes/src/base-hw-pbxa9/hash @@ -1 +1 @@ -2022-05-24 1b34e317209c48bfc88af6118db32be261ce3e0c +2022-10-11 de2f50d9164952dbbf6ce76d29abad5d96da8512 diff --git a/repos/base-hw/recipes/src/base-hw-pc/hash b/repos/base-hw/recipes/src/base-hw-pc/hash index 93f152f935..7518974942 100644 --- a/repos/base-hw/recipes/src/base-hw-pc/hash +++ b/repos/base-hw/recipes/src/base-hw-pc/hash @@ -1 +1 @@ -2022-05-24 46e9f88209bbc95228d3882cc0831770315402e4 +2022-10-11 5d72eb4e34f582c06c086345b225cee91ce539cc diff --git a/repos/base-hw/recipes/src/base-hw-virt_qemu/content.mk b/repos/base-hw/recipes/src/base-hw-virt_qemu/content.mk deleted file mode 100644 index 2d331b60be..0000000000 --- a/repos/base-hw/recipes/src/base-hw-virt_qemu/content.mk +++ /dev/null @@ -1,4 +0,0 @@ -CONTENT += src/core/board/virt_qemu_64 \ - src/bootstrap/board/virt_qemu_64 - -include $(GENODE_DIR)/repos/base-hw/recipes/src/base-hw_content.inc diff --git a/repos/base-hw/recipes/src/base-hw-virt_qemu/hash b/repos/base-hw/recipes/src/base-hw-virt_qemu/hash deleted file mode 100644 index 7bb55aaf3c..0000000000 --- a/repos/base-hw/recipes/src/base-hw-virt_qemu/hash +++ /dev/null @@ -1 +0,0 @@ -2022-05-24 bb6c39c093a24d2ec4ff1d00e397529c51e95fa7 diff --git a/repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v7a/content.mk b/repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v7a/content.mk new file mode 100644 index 0000000000..38ce9bebad --- /dev/null +++ b/repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v7a/content.mk @@ -0,0 +1,4 @@ +CONTENT += src/core/board/virt_qemu_arm_v7a \ + src/bootstrap/board/virt_qemu_arm_v7a + +include $(GENODE_DIR)/repos/base-hw/recipes/src/base-hw_content.inc diff --git a/repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v7a/hash b/repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v7a/hash new file mode 100644 index 0000000000..0eecd093ea --- /dev/null +++ b/repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v7a/hash @@ -0,0 +1 @@ +2022-10-11 70e53c98ef4b3215440efb2ea09e07ff7cd97c4f diff --git a/repos/base-hw/recipes/src/base-hw-virt_qemu/used_apis b/repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v7a/used_apis similarity index 100% rename from repos/base-hw/recipes/src/base-hw-virt_qemu/used_apis rename to repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v7a/used_apis diff --git a/repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v8a/content.mk b/repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v8a/content.mk new file mode 100644 index 0000000000..7b0ace030f --- /dev/null +++ b/repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v8a/content.mk @@ -0,0 +1,4 @@ +CONTENT += src/core/board/virt_qemu_arm_v8a \ + src/bootstrap/board/virt_qemu_arm_v8a + +include $(GENODE_DIR)/repos/base-hw/recipes/src/base-hw_content.inc diff --git a/repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v8a/hash b/repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v8a/hash new file mode 100644 index 0000000000..ec4320f9e9 --- /dev/null +++ b/repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v8a/hash @@ -0,0 +1 @@ +2022-10-11 c146d70c9bde3f928110c868a54b8c800beffd79 diff --git a/repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v8a/used_apis b/repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v8a/used_apis new file mode 100644 index 0000000000..ed9b772565 --- /dev/null +++ b/repos/base-hw/recipes/src/base-hw-virt_qemu_arm_v8a/used_apis @@ -0,0 +1,2 @@ +base-hw +base diff --git a/repos/base-hw/recipes/src/base-hw_content.inc b/repos/base-hw/recipes/src/base-hw_content.inc index f26b8981e6..ee1b9ae2f8 100644 --- a/repos/base-hw/recipes/src/base-hw_content.inc +++ b/repos/base-hw/recipes/src/base-hw_content.inc @@ -115,6 +115,12 @@ SRC_LIB_BASE += $(notdir $(wildcard $(BASE_HW_DIR)/src/lib/base/*.cc)) \ $(notdir $(wildcard $(BASE_DIR)/src/lib/base/*.cc)) \ ${call selected_content,SRC_LIB_BASE_SPECS} +SRC_LIB_TIMEOUT += duration.cc \ + hw/timer_connection_timestamp.cc \ + timeout.cc \ + timer_connection.cc \ + timer_connection_time.cc + SRC_LIB_STARTUP += init_main_thread.cc _main.cc \ $(addprefix spec/,${call selected_content,SRC_LIB_STARTUP_SPECS}) @@ -125,15 +131,24 @@ SRC_CORE += $(notdir $(wildcard $(BASE_HW_DIR)/src/core/*.cc)) \ $(addprefix board/,$(BOARD)) \ version.inc target.inc include hw kernel -LIB_MK := base-hw-common.mk base-hw.mk bootstrap-hw.inc core-hw.inc \ - timeout-hw.mk cxx.mk base.inc base-common.inc startup.inc \ - $(addprefix spec/,${call selected_content,LIB_MK_SPECS}) +# names of the lib/mk/ files to consider for inclusion in the src archive +LIB_MK_FILES := base-common.inc base-hw-common.mk \ + base.inc base-hw.mk \ + bootstrap-hw.inc bootstrap-hw-$(BOARD).inc bootstrap-hw-$(BOARD).mk \ + core-hw.inc core-hw-$(BOARD).inc core-hw-$(BOARD).mk \ + startup.inc startup-hw.mk \ + timeout-hw.mk cxx.mk ld-hw.mk syscall-hw.mk + +LIB_MK_DIRS := lib/mk $(addprefix lib/mk/spec/,${call selected_content,LIB_MK_SPECS}) + +CONTENT += $(foreach D,$(LIB_MK_DIRS),$(addprefix $D/,$(LIB_MK_FILES))) CONTENT += $(addprefix src/timer/,$(SRC_TIMER)) \ $(addprefix src/include/hw/,$(SRC_INCLUDE_HW)) \ $(addprefix src/bootstrap/,$(SRC_BOOTSTRAP)) \ $(addprefix lib/mk/,$(LIB_MK)) \ $(addprefix src/lib/base/,$(SRC_LIB_BASE)) \ + $(addprefix src/lib/timeout/,$(SRC_LIB_TIMEOUT)) \ $(addprefix src/lib/startup/,$(SRC_LIB_STARTUP)) \ $(addprefix src/core/,$(SRC_CORE)) \ src/lib/hw src/lib/ld src/lib/cxx \ @@ -180,7 +195,6 @@ generalize_target_names: $(CONTENT) # apply kernel-agnostic convention of naming the timer and ld.lib.so for subdir in ${call selected_content,LD_MK_DIRS}; do \ mv $$subdir/ld-hw.mk $$subdir/ld.mk; done - sed -i "s/ld-hw/ld/" src/lib/ld/hw/target.mk sed -i "s/hw_timer_drv/timer/" src/timer/hw/target.mk # supplement BOARD definition that normally comes form the build dir sed -i "s/\?= unknown/:= $(BOARD)/" src/core/hw/target.mk @@ -189,5 +203,4 @@ generalize_target_names: $(CONTENT) sed -i "1aREQUIRES := $(ARCH)" src/core/hw/target.mk sed -i "1aREQUIRES := $(ARCH)" src/bootstrap/hw/target.mk sed -i "/REQUIRES/s/hw/hw $(ARCH)/" src/timer/hw/target.mk - sed -i "1aREQUIRES := $(ARCH)" src/lib/ld/hw/target.mk diff --git a/repos/base-hw/src/bootstrap/board/virt_qemu/board.h b/repos/base-hw/src/bootstrap/board/virt_qemu_arm_v7a/board.h similarity index 100% rename from repos/base-hw/src/bootstrap/board/virt_qemu/board.h rename to repos/base-hw/src/bootstrap/board/virt_qemu_arm_v7a/board.h diff --git a/repos/base-hw/src/bootstrap/board/virt_qemu/platform.cc b/repos/base-hw/src/bootstrap/board/virt_qemu_arm_v7a/platform.cc similarity index 100% rename from repos/base-hw/src/bootstrap/board/virt_qemu/platform.cc rename to repos/base-hw/src/bootstrap/board/virt_qemu_arm_v7a/platform.cc diff --git a/repos/base-hw/src/bootstrap/board/virt_qemu_64/board.h b/repos/base-hw/src/bootstrap/board/virt_qemu_arm_v8a/board.h similarity index 100% rename from repos/base-hw/src/bootstrap/board/virt_qemu_64/board.h rename to repos/base-hw/src/bootstrap/board/virt_qemu_arm_v8a/board.h diff --git a/repos/base-hw/src/bootstrap/board/virt_qemu_64/platform.cc b/repos/base-hw/src/bootstrap/board/virt_qemu_arm_v8a/platform.cc similarity index 100% rename from repos/base-hw/src/bootstrap/board/virt_qemu_64/platform.cc rename to repos/base-hw/src/bootstrap/board/virt_qemu_arm_v8a/platform.cc diff --git a/repos/base-hw/src/core/board/virt_qemu/board.h b/repos/base-hw/src/core/board/virt_qemu_arm_v7a/board.h similarity index 100% rename from repos/base-hw/src/core/board/virt_qemu/board.h rename to repos/base-hw/src/core/board/virt_qemu_arm_v7a/board.h diff --git a/repos/base-hw/src/core/board/virt_qemu_64/board.h b/repos/base-hw/src/core/board/virt_qemu_arm_v8a/board.h similarity index 100% rename from repos/base-hw/src/core/board/virt_qemu_64/board.h rename to repos/base-hw/src/core/board/virt_qemu_arm_v8a/board.h diff --git a/repos/base-hw/src/core/kernel/cpu.cc b/repos/base-hw/src/core/kernel/cpu.cc index 7840d39acb..cd7e57b5b9 100644 --- a/repos/base-hw/src/core/kernel/cpu.cc +++ b/repos/base-hw/src/core/kernel/cpu.cc @@ -109,7 +109,8 @@ Cpu::Idle_thread::Idle_thread(Board::Address_space_id_allocator &addr_space_id_a Cpu &cpu, Pd &core_pd) : - Thread { addr_space_id_alloc, user_irq_pool, cpu_pool, core_pd, "idle" } + Thread { addr_space_id_alloc, user_irq_pool, cpu_pool, core_pd, + Cpu_priority::min(), 0, "idle", Thread::IDLE } { regs->ip = (addr_t)&idle_thread_main; @@ -120,14 +121,9 @@ Cpu::Idle_thread::Idle_thread(Board::Address_space_id_allocator &addr_space_id_a void Cpu::schedule(Job * const job) { - if (_id == executing_id()) - _scheduler.ready(job->share()); - else { - _scheduler.ready_check(job->share()); - - if (_scheduler.need_to_schedule()) - trigger_ip_interrupt(); - } + _scheduler.ready(job->share()); + if (_id != executing_id() && _scheduler.need_to_schedule()) + trigger_ip_interrupt(); } diff --git a/repos/base-hw/src/core/kernel/cpu_scheduler.cc b/repos/base-hw/src/core/kernel/cpu_scheduler.cc index a9ac614e5d..b56d771656 100644 --- a/repos/base-hw/src/core/kernel/cpu_scheduler.cc +++ b/repos/base-hw/src/core/kernel/cpu_scheduler.cc @@ -191,45 +191,17 @@ void Cpu_scheduler::update(time_t time) } -void Cpu_scheduler::ready_check(Share &s1) -{ - assert(_head); - - ready(s1); - - if (_need_to_schedule) - return; - - Share * s2 = _head; - if (!s1._claim) { - _need_to_schedule = s2 == &_idle; - } else if (!_head_claims) { - _need_to_schedule = true; - } else if (s1._prio != s2->_prio) { - _need_to_schedule = s1._prio > s2->_prio; - } else { - for ( - ; s2 && s2 != &s1; - s2 = - Double_list::next(&s2->_claim_item) != nullptr ? - &Double_list::next(&s2->_claim_item)->payload() : - nullptr) ; - - _need_to_schedule = !s2; - } -} - - void Cpu_scheduler::ready(Share &s) { assert(!s._ready && &s != &_idle); - _need_to_schedule = true; - s._ready = 1; s._fill = _fill; _fills.insert_tail(&s._fill_item); + if (_head == &_idle) + _need_to_schedule = true; + if (!s._quota) return; @@ -239,6 +211,28 @@ void Cpu_scheduler::ready(Share &s) _rcl[s._prio].insert_head(&s._claim_item); else _rcl[s._prio].insert_tail(&s._claim_item); + + /* + * Check whether we need to re-schedule + */ + if (_need_to_schedule) + return; + + /* current head has no quota left */ + if (!_head_claims) { + _need_to_schedule = true; + return; + } + + /* if current head has different priority */ + if (s._prio != _head->_prio) { + _need_to_schedule = s._prio > _head->_prio; + return; + } + + /* if current head has same priority, the ready share gets active */ + if (s._claim) + _need_to_schedule = true; } @@ -246,7 +240,8 @@ void Cpu_scheduler::unready(Share &s) { assert(s._ready && &s != &_idle); - _need_to_schedule = true; + if (&s == _head) + _need_to_schedule = true; s._ready = 0; _fills.remove(&s._fill_item); @@ -270,21 +265,15 @@ void Cpu_scheduler::remove(Share &s) { assert(&s != &_idle); - _need_to_schedule = true; + if (s._ready) unready(s); if (&s == _head) _head = nullptr; - if (s._ready) - _fills.remove(&s._fill_item); - if (!s._quota) return; - if (s._ready) - _rcl[s._prio].remove(&s._claim_item); - else - _ucl[s._prio].remove(&s._claim_item); + _ucl[s._prio].remove(&s._claim_item); } @@ -292,8 +281,6 @@ void Cpu_scheduler::insert(Share &s) { assert(!s._ready); - _need_to_schedule = true; - if (!s._quota) return; diff --git a/repos/base-hw/src/core/kernel/cpu_scheduler.h b/repos/base-hw/src/core/kernel/cpu_scheduler.h index ad8624a257..70e921f44c 100644 --- a/repos/base-hw/src/core/kernel/cpu_scheduler.h +++ b/repos/base-hw/src/core/kernel/cpu_scheduler.h @@ -180,15 +180,10 @@ class Kernel::Cpu_scheduler void timeout() { _need_to_schedule = true; } /** - * Update head according to the consumed time + * Update head according to the current (absolute) time */ void update(time_t time); - /** - * Set 's1' ready and return wether this outdates current head - */ - void ready_check(Share &s1); - /** * Set share 's' ready */ diff --git a/repos/base-hw/src/core/kernel/thread.cc b/repos/base-hw/src/core/kernel/thread.cc index 0d2e9227e7..a5f3b37593 100644 --- a/repos/base-hw/src/core/kernel/thread.cc +++ b/repos/base-hw/src/core/kernel/thread.cc @@ -329,6 +329,23 @@ void Thread::_call_start_thread() /* join protection domain */ thread._pd = (Pd *) user_arg_3(); thread._ipc_init(*(Native_utcb *)user_arg_4(), *this); + + /* + * Sanity check core threads! + * + * Currently, the model assumes that there is only one core + * entrypoint, which serves requests, and which can destroy + * threads and pds. If this changes, we have to inform all + * cpus about pd destructions to remove their page-tables + * from the hardware in case that a core-thread running with + * that same pd is currently active. Therefore, warn if the + * semantic changes, and additional core threads are started + * across cpu cores. + */ + if (thread._pd == &_core_pd && cpu.id() != _cpu_pool.primary_cpu().id()) + Genode::raw("Error: do not start core threads" + " on CPU cores different than boot cpu"); + thread._become_active(); } @@ -369,7 +386,7 @@ void Thread::_call_restart_thread() Thread &thread = *thread_ptr; - if (!_core && (&pd() != &thread.pd())) { + if (_type == USER && (&pd() != &thread.pd())) { raw(*this, ": failed to lookup thread ", (unsigned)user_arg_1(), " to restart it"); _die(); @@ -447,6 +464,18 @@ void Thread::_call_delete_thread() } +void Thread::_call_delete_pd() +{ + Genode::Kernel_object & pd = + *(Genode::Kernel_object*)user_arg_1(); + + if (_cpu->active(pd->mmu_regs)) + _cpu->switch_to(_core_pd.mmu_regs); + + _call_delete(); +} + + void Thread::_call_await_request_msg() { if (_ipc_node.can_await_request()) { @@ -793,7 +822,7 @@ void Thread::_call() case call_id_pause_vm(): _call_pause_vm(); return; default: /* check wether this is a core thread */ - if (!_core) { + if (_type != CORE) { Genode::raw(*this, ": not entitled to do kernel call"); _die(); return; @@ -805,7 +834,7 @@ void Thread::_call() _call_new(_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()); + (char const *) user_arg_4(), USER); return; case call_id_new_core_thread(): _call_new(_addr_space_id_alloc, _user_irq_pool, _cpu_pool, @@ -822,7 +851,7 @@ void Thread::_call() *(Genode::Platform_pd *) user_arg_3(), _addr_space_id_alloc); return; - case call_id_delete_pd(): _call_delete(); return; + case call_id_delete_pd(): _call_delete_pd(); return; case call_id_new_signal_receiver(): _call_new(); return; case call_id_new_signal_context(): _call_new(*(Signal_receiver*) user_arg_2(), user_arg_3()); @@ -857,7 +886,7 @@ void Thread::_mmu_exception() return; } - if (_core) + if (_type != USER) Genode::raw(*this, " raised a fault, which should never happen ", _fault); @@ -874,7 +903,7 @@ Thread::Thread(Board::Address_space_id_allocator &addr_space_id_alloc, unsigned const priority, unsigned const quota, char const *const label, - bool core) + Type type) : Kernel::Object { *this }, Cpu_job { priority, quota }, @@ -885,8 +914,8 @@ Thread::Thread(Board::Address_space_id_allocator &addr_space_id_alloc, _ipc_node { *this }, _state { AWAITS_START }, _label { label }, - _core { core }, - regs { core } + _type { type }, + regs { type != USER } { } diff --git a/repos/base-hw/src/core/kernel/thread.h b/repos/base-hw/src/core/kernel/thread.h index f7516a6ba9..93e45c3303 100644 --- a/repos/base-hw/src/core/kernel/thread.h +++ b/repos/base-hw/src/core/kernel/thread.h @@ -57,6 +57,10 @@ struct Kernel::Thread_fault */ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout { + public: + + enum Type { USER, CORE, IDLE }; + private: /* @@ -149,7 +153,7 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout capid_t _timeout_sigid { 0 }; bool _paused { false }; bool _cancel_next_await_signal { false }; - bool const _core { false }; + Type const _type; Genode::Constructible _tlb_invalidation {}; Genode::Constructible _destroy {}; @@ -230,6 +234,7 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout void _call_restart_thread(); void _call_yield_thread(); void _call_delete_thread(); + void _call_delete_pd(); void _call_await_request_msg(); void _call_send_request_msg(); void _call_send_reply_msg(); @@ -301,7 +306,7 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout unsigned const priority, unsigned const quota, char const *const label, - bool core = false); + Type const type); /** * Constructor for core/kernel thread @@ -315,7 +320,7 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout char const *const label) : Thread(addr_space_id_alloc, user_irq_pool, cpu_pool, core_pd, - Cpu_priority::min(), 0, label, true) + Cpu_priority::min(), 0, label, CORE) { } ~Thread(); @@ -432,6 +437,7 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout char const * label() const { return _label; } Thread_fault fault() const { return _fault; } Genode::Native_utcb *utcb() { return _utcb; } + Type type() const { return _type; } Pd &pd() const { diff --git a/repos/base-hw/src/core/kernel/vm.h b/repos/base-hw/src/core/kernel/vm.h index bc7301e577..06a069a743 100644 --- a/repos/base-hw/src/core/kernel/vm.h +++ b/repos/base-hw/src/core/kernel/vm.h @@ -77,6 +77,8 @@ class Kernel::Vm : private Kernel::Object, public Cpu_job Kernel::Signal_context & context, Identity & id); + ~Vm(); + /** * Inject an interrupt to this VM * diff --git a/repos/base-hw/src/core/spec/arm/cortex_a9_private_timer.cc b/repos/base-hw/src/core/spec/arm/cortex_a9_private_timer.cc index 5ad0ced3f4..d2bf7dc4b4 100644 --- a/repos/base-hw/src/core/spec/arm/cortex_a9_private_timer.cc +++ b/repos/base-hw/src/core/spec/arm/cortex_a9_private_timer.cc @@ -22,13 +22,17 @@ using namespace Genode; using namespace Kernel; -using Device = Board::Timer; + +using Device = Board::Timer; +using counter_t = Board::Timer::Counter::access_t; enum { TICS_PER_MS = Board::CORTEX_A9_PRIVATE_TIMER_CLK / - Board::CORTEX_A9_PRIVATE_TIMER_DIV / 1000 + Board::CORTEX_A9_PRIVATE_TIMER_DIV / 1000, + + MAX_COUNTER_VAL = ~(counter_t)0 }; @@ -79,12 +83,33 @@ time_t Timer::us_to_ticks(time_t const us) const { time_t Timer::_duration() const { - Device::Counter::access_t last = _last_timeout_duration; - Device::Counter::access_t cnt = _device.read(); - Device::Counter::access_t ret = (_device.read()) - ? _max_value() - cnt + last : last - cnt; - return ret; + counter_t const start_counter_val { (counter_t)_last_timeout_duration }; + counter_t const curr_counter_val { _device.read() }; + + /* + * Calculate result depending on whether the counter already wrapped or + * not. See the comment in the implementation of '_max_value' for an + * explanation why this comparison is done instead of checking the IRQ + * status and why it is sufficient. + */ + if (curr_counter_val > start_counter_val) + return start_counter_val + (MAX_COUNTER_VAL - curr_counter_val); + + return start_counter_val - curr_counter_val; } -time_t Timer::_max_value() const { return 0xfffffffe; } +time_t Timer::_max_value() const +{ + /* + * We propagate a max timeout value far lower than the one required + * by the hardware. This is because on some platforms (Qemu 4.2.1 PBXA9), + * the IRQ status register is not reliable. Sometimes, it indicates an IRQ + * too early, i.e., shortly before the counter wraps. Therefore we have to + * accomplish wrap detection via counter comparison only. Therefore, we + * have to make sure that we always read out the counter before it hits + * the max timout value again. And, therefore, the max timeout value has + * to be far away from the first value the counter has after wrapping. + */ + return MAX_COUNTER_VAL >> 1; +} diff --git a/repos/base-hw/src/core/spec/arm/cpu.cc b/repos/base-hw/src/core/spec/arm/cpu.cc index f0a7fa4ea8..7c8c722e31 100644 --- a/repos/base-hw/src/core/spec/arm/cpu.cc +++ b/repos/base-hw/src/core/spec/arm/cpu.cc @@ -87,24 +87,25 @@ void Arm_cpu::mmu_fault_status(Fsr::access_t fsr, Thread_fault & fault) } -void Arm_cpu::switch_to(Arm_cpu::Context&, Arm_cpu::Mmu_context & o) +bool Arm_cpu::active(Arm_cpu::Mmu_context & ctx) { - if (o.cidr == 0) return; + return (Cidr::read() == ctx.cidr); +} - Cidr::access_t cidr = Cidr::read(); - if (cidr != o.cidr) { - /** - * First switch to global mappings only to prevent - * that wrong branch predicts result due to ASID - * and Page-Table not being in sync (see ARM RM B 3.10.4) - */ - Cidr::write(0); - Cpu::synchronization_barrier(); - Ttbr0::write(o.ttbr0); - Cpu::synchronization_barrier(); - Cidr::write(o.cidr); - Cpu::synchronization_barrier(); - } + +void Arm_cpu::switch_to(Arm_cpu::Mmu_context & ctx) +{ + /** + * First switch to global mappings only to prevent + * that wrong branch predicts result due to ASID + * and Page-Table not being in sync (see ARM RM B 3.10.4) + */ + Cidr::write(0); + Cpu::synchronization_barrier(); + Ttbr0::write(ctx.ttbr0); + Cpu::synchronization_barrier(); + Cidr::write(ctx.cidr); + Cpu::synchronization_barrier(); } diff --git a/repos/base-hw/src/core/spec/arm/cpu_support.h b/repos/base-hw/src/core/spec/arm/cpu_support.h index bba89ce42a..33d63848be 100644 --- a/repos/base-hw/src/core/spec/arm/cpu_support.h +++ b/repos/base-hw/src/core/spec/arm/cpu_support.h @@ -104,7 +104,8 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu else Tlbiall::write(0); } - void switch_to(Context&, Mmu_context & o); + bool active(Mmu_context &); + void switch_to(Mmu_context &); static void mmu_fault(Context & c, Kernel::Thread_fault & fault); static void mmu_fault_status(Fsr::access_t fsr, diff --git a/repos/base-hw/src/core/spec/arm/kernel/thread.cc b/repos/base-hw/src/core/spec/arm/kernel/thread.cc index efc67e510a..838a730c79 100644 --- a/repos/base-hw/src/core/spec/arm/kernel/thread.cc +++ b/repos/base-hw/src/core/spec/arm/kernel/thread.cc @@ -67,7 +67,8 @@ void Kernel::Thread::Tlb_invalidation::execute() { }; void Thread::proceed(Cpu & cpu) { - cpu.switch_to(*regs, pd().mmu_regs); + if (!cpu.active(pd().mmu_regs) && type() != CORE) + cpu.switch_to(pd().mmu_regs); regs->cpu_exception = cpu.stack_start(); kernel_to_user_context_switch((static_cast(&*regs)), diff --git a/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc b/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc index 968786b6d2..e6cc8f2d00 100644 --- a/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc +++ b/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc @@ -38,6 +38,9 @@ Vm::Vm(Irq::Pool & user_irq_pool, } +Vm::~Vm() {} + + void Vm::exception(Cpu & cpu) { switch(_state.cpu_exception) { diff --git a/repos/base-hw/src/core/spec/arm_v7/virtualization/exception_vector.s b/repos/base-hw/src/core/spec/arm_v7/virtualization/exception_vector.s index 837483f817..e2808a1670 100644 --- a/repos/base-hw/src/core/spec/arm_v7/virtualization/exception_vector.s +++ b/repos/base-hw/src/core/spec/arm_v7/virtualization/exception_vector.s @@ -15,7 +15,7 @@ push { r0 } mrc p15, 4, r0, c1, c1, 0 /* read HCR register */ tst r0, #1 /* check VM bit */ - beq _host_to_vm + beq _from_host mov r0, #\exception_type b _vm_to_host .endm /* _vm_exit */ @@ -47,10 +47,27 @@ _vt_dab_entry: _vm_exit 5 _vt_irq_entry: _vm_exit 6 _vt_trp_entry: _vm_exit 8 -_host_to_vm: +_from_host: + pop { r0 } + cmp r0, #0 + beq _to_vm + cmp r0, #1 + beq _invalidate_tlb + eret + + +_invalidate_tlb: + push { r3, r4 } + mrrc p15, 6, r3, r4, c2 /* save VTTBR */ + mcrr p15, 6, r1, r2, c2 /* write VTTBR */ + mcr p15, 0, r0, c8, c3, 0 /* TLBIALLIS */ + mcrr p15, 6, r3, r4, c2 /* restore VTTBR */ + eret + +_to_vm: push { r1 } - ldr r0, [sp, #1*4] - add r0, r0, #13*4 + push { r2 } + add r0, r1, #13*4 ldmia r0!, { r1-r5 } msr sp_usr, r1 mov lr, r2 @@ -115,6 +132,7 @@ _host_to_vm: ldmia r0, {r0-r12} /* load vm's r0-r12 */ eret + _vm_to_host: push { r0 } /* push cpu excep. */ ldr r0, [sp, #3*4] /* load vm state ptr */ @@ -218,6 +236,7 @@ _vm_to_host: /* host kernel must jump to this point to switch to a vm */ -.global hypervisor_enter_vm -hypervisor_enter_vm: +.global hypervisor_call +hypervisor_call: hvc #0 + bx lr diff --git a/repos/base-hw/src/core/spec/arm_v7/virtualization/hypervisor.h b/repos/base-hw/src/core/spec/arm_v7/virtualization/hypervisor.h new file mode 100644 index 0000000000..d9935902d6 --- /dev/null +++ b/repos/base-hw/src/core/spec/arm_v7/virtualization/hypervisor.h @@ -0,0 +1,55 @@ +/* + * \brief Interface between kernel and hypervisor + * \author Stefan Kalkowski + * \date 2022-06-13 + */ + +/* + * Copyright (C) 2022 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 _SPEC__ARM_V7__VIRTUALIZATION_HYPERVISOR_H_ +#define _SPEC__ARM_V7__VIRTUALIZATION_HYPERVISOR_H_ + +#include +#include + +namespace Hypervisor { + + struct Host_context; + + enum Call_number { + WORLD_SWITCH = 0, + TLB_INVALIDATE = 1, + }; + + using Call_arg = Genode::umword_t; + using Call_ret = Genode::umword_t; + + extern "C" + Call_ret hypervisor_call(Call_arg call_id, + Call_arg arg0, + Call_arg arg1); + + + inline void invalidate_tlb(Genode::uint64_t vttbr) + { + hypervisor_call(TLB_INVALIDATE, + (vttbr & 0xffffffff), + ((vttbr >> 32U) & 0xffffffff)); + } + + + inline void switch_world(Genode::Vm_state & vm_state, + Host_context & host_state) + { + hypervisor_call(WORLD_SWITCH, + (Call_arg)&vm_state, + (Call_arg)&host_state); + } +} + +#endif /* _SPEC__ARM_V7__VIRTUALIZATION_HYPERVISOR_H_ */ diff --git a/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc b/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc index d73b76a22e..416110121e 100644 --- a/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc +++ b/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc @@ -19,6 +19,7 @@ #include #include #include +#include namespace Kernel { @@ -41,7 +42,7 @@ namespace Kernel { using namespace Kernel; -struct Host_context +struct Hypervisor::Host_context { Cpu::Ttbr_64bit::access_t vttbr; Cpu::Hcr::access_t hcr; @@ -61,15 +62,13 @@ struct Host_context } vt_host_context; -extern "C" void hypervisor_enter_vm(Genode::Vm_state&, Host_context&); - - -static Host_context & host_context(Cpu & cpu) +static Hypervisor::Host_context & host_context(Cpu & cpu) { - static Genode::Constructible host_context[NR_OF_CPUS]; + static Genode::Constructible + host_context[NR_OF_CPUS]; if (!host_context[cpu.id()].constructed()) { host_context[cpu.id()].construct(); - Host_context & c = *host_context[cpu.id()]; + Hypervisor::Host_context & c = *host_context[cpu.id()]; c.sp = cpu.stack_start(); c.ttbr0 = Cpu::Ttbr0_64bit::read(); c.ttbr1 = Cpu::Ttbr1_64bit::read(); @@ -152,6 +151,15 @@ Kernel::Vm::Vm(Irq::Pool & user_irq_pool, } +Kernel::Vm::~Vm() +{ + Cpu::Ttbr_64bit::access_t vttbr = + Cpu::Ttbr_64bit::Ba::masked((Cpu::Ttbr_64bit::access_t)_id.table); + Cpu::Ttbr_64bit::Asid::set(vttbr, _id.id); + Hypervisor::invalidate_tlb(vttbr); +} + + void Kernel::Vm::exception(Cpu & cpu) { switch(_state.cpu_exception) { @@ -190,7 +198,7 @@ void Kernel::Vm::proceed(Cpu & cpu) _state.esr_el2 = Cpu::Hstr::init(); _state.hpfar_el2 = Cpu::Hcr::init(); - hypervisor_enter_vm(_state, host_context(cpu)); + Hypervisor::switch_world(_state, host_context(cpu)); } diff --git a/repos/base-hw/src/core/spec/arm_v8/cpu.cc b/repos/base-hw/src/core/spec/arm_v8/cpu.cc index a06e142f1b..617b7fd70b 100644 --- a/repos/base-hw/src/core/spec/arm_v8/cpu.cc +++ b/repos/base-hw/src/core/spec/arm_v8/cpu.cc @@ -26,12 +26,15 @@ Genode::Cpu::Context::Context(bool privileged) } -void Genode::Cpu::switch_to(Context&, Mmu_context & mmu_context) +bool Genode::Cpu::active(Mmu_context & mmu_context) { - if (mmu_context.id() == 0) return; + return (mmu_context.id() == Ttbr::Asid::get(Ttbr0_el1::read())); +} - if (mmu_context.id() != Ttbr::Asid::get(Ttbr0_el1::read())) - Ttbr0_el1::write(mmu_context.ttbr); + +void Genode::Cpu::switch_to(Mmu_context & mmu_context) +{ + Ttbr0_el1::write(mmu_context.ttbr); } diff --git a/repos/base-hw/src/core/spec/arm_v8/cpu.h b/repos/base-hw/src/core/spec/arm_v8/cpu.h index a9ca159ea3..b9ff4dbde6 100644 --- a/repos/base-hw/src/core/spec/arm_v8/cpu.h +++ b/repos/base-hw/src/core/spec/arm_v8/cpu.h @@ -99,7 +99,8 @@ struct Genode::Cpu : Hw::Arm_64_cpu return Ttbr::Asid::get(ttbr) & 0xffff; } }; - void switch_to(Context&, Mmu_context &); + bool active(Mmu_context &); + void switch_to(Mmu_context &); static void mmu_fault(Context &, Kernel::Thread_fault &); diff --git a/repos/base-hw/src/core/spec/arm_v8/kernel/thread.cc b/repos/base-hw/src/core/spec/arm_v8/kernel/thread.cc index e3bb8df148..17e431043c 100644 --- a/repos/base-hw/src/core/spec/arm_v8/kernel/thread.cc +++ b/repos/base-hw/src/core/spec/arm_v8/kernel/thread.cc @@ -55,6 +55,16 @@ void Thread::exception(Cpu & cpu) " ISS=", Cpu::Esr::Iss::get(esr), " ip=", (void*)regs->ip); }; + + /* + * If the machine exception is caused by a non-privileged + * component, mark it dead, and continue execution. + */ + if (regs->exception_type == Cpu::SYNC_LEVEL_EL0) { + Genode::raw("Will freeze thread ", *this); + _become_inactive(DEAD); + return; + } break; } default: @@ -75,10 +85,14 @@ void Thread::exception(Cpu & cpu) void Kernel::Thread::Tlb_invalidation::execute() { }; -bool Kernel::Pd::invalidate_tlb(Cpu &, addr_t addr, size_t size) +bool Kernel::Pd::invalidate_tlb(Cpu & cpu, addr_t addr, size_t size) { using namespace Genode; + /* only apply to the active cpu */ + if (cpu.id() != Cpu::executing_id()) + return false; + /** * The kernel part of the address space is mapped as global * therefore we have to invalidate it differently @@ -108,7 +122,9 @@ bool Kernel::Pd::invalidate_tlb(Cpu &, addr_t addr, size_t size) void Thread::proceed(Cpu & cpu) { - cpu.switch_to(*regs, pd().mmu_regs); + if (!cpu.active(pd().mmu_regs) && type() != CORE) + cpu.switch_to(pd().mmu_regs); + kernel_to_user_context_switch((static_cast(&*regs)), (void*)cpu.stack_start()); } diff --git a/repos/base-hw/src/core/spec/arm_v8/virtualization/exception_vector.s b/repos/base-hw/src/core/spec/arm_v8/virtualization/exception_vector.s index 8011bfeead..a159d81c34 100644 --- a/repos/base-hw/src/core/spec/arm_v8/virtualization/exception_vector.s +++ b/repos/base-hw/src/core/spec/arm_v8/virtualization/exception_vector.s @@ -22,24 +22,34 @@ .global hypervisor_exception_vector hypervisor_exception_vector: .rept 16 - add sp, sp, #-16 /* push x0, x1 to stack */ - stp x0, x1, [sp] - mrs x1, hcr_el2 /* read HCR register */ - tst x1, #1 /* check VM bit */ - beq _host_to_vm /* if VM bit is not set, switch to VM */ - ldr x0, [sp, #32] /* otherwise, load vm_state pointer */ - adr x1, . /* hold exception vector offset in x1 */ - and x1, x1, #0xf80 - b _vm_to_host + add sp, sp, #-16 /* push x29, x30 to stack */ + stp x29, x30, [sp] + mrs x30, hcr_el2 /* read HCR register */ + tst x30, #1 /* check VM bit */ + beq _from_host /* if VM bit is not set, its a host call */ + ldr x29, [sp, #32] /* otherwise, load vm_state pointer */ + adr x30, . /* hold exception vector offset in x30 */ + and x30, x30, #0xf80 + b _from_vm .balign 128 .endr -_host_to_vm: +_from_host: + ldp x29, x30, [sp], #2*8 /* pop x29, x30 from stack */ + cmp x0, #0 + beq _to_vm + cmp x0, #1 + beq _invalidate_tlb + eret - add sp, sp, #-16 /* push arg2 (vm pic state) to stack */ - str x2, [sp] +_to_vm: + add sp, sp, #-16 /* push arg1/2 (vm/host state to stack */ + stp x1, x2, [sp] + add sp, sp, #-16 /* push arg3 (vm pic state) to stack */ + str x3, [sp] - msr vttbr_el2, x3 /* stage2 table pointer was arg3 */ + msr vttbr_el2, x4 /* stage2 table pointer was arg4 */ + mov x0, x1 add x0, x0, #31*8 /* skip x0...x30, loaded later */ @@ -179,27 +189,38 @@ _host_to_vm: eret -_vm_to_host: + +_invalidate_tlb: + msr vttbr_el2, x1 + tlbi vmalle1is + msr vttbr_el2, xzr + eret + + +_from_vm: /********************* ** Save vm context ** *********************/ /** general-purpose register **/ - add x0, x0, #2*8 /* skip x0 and x1 for now */ - stp x2, x3, [x0], #2*8 - stp x4, x5, [x0], #2*8 - stp x6, x7, [x0], #2*8 - stp x8, x9, [x0], #2*8 - stp x10, x11, [x0], #2*8 - stp x12, x13, [x0], #2*8 - stp x14, x15, [x0], #2*8 - stp x16, x17, [x0], #2*8 - stp x18, x19, [x0], #2*8 - stp x20, x21, [x0], #2*8 - stp x22, x23, [x0], #2*8 - stp x24, x25, [x0], #2*8 - stp x26, x27, [x0], #2*8 + stp x0, x1, [x29], #2*8 + stp x2, x3, [x29], #2*8 + stp x4, x5, [x29], #2*8 + stp x6, x7, [x29], #2*8 + stp x8, x9, [x29], #2*8 + stp x10, x11, [x29], #2*8 + stp x12, x13, [x29], #2*8 + stp x14, x15, [x29], #2*8 + stp x16, x17, [x29], #2*8 + stp x18, x19, [x29], #2*8 + stp x20, x21, [x29], #2*8 + stp x22, x23, [x29], #2*8 + stp x24, x25, [x29], #2*8 + stp x26, x27, [x29], #2*8 + mov x0, x29 + mov x1, x30 + ldp x29, x30, [sp], #2*8 /* pop x29, x30 from stack */ stp x28, x29, [x0], #2*8 str x30, [x0], #1*8 @@ -284,11 +305,8 @@ _vm_to_host: mov x0, #0b111 msr cnthctl_el2, x0 - - ldp x0, x1, [sp], #2*8 /* pop x0, x1 from stack */ - ldr x29, [sp], #2*8 /* pop vm pic state from stack */ - ldp x2, x30, [sp], #2*8 /* pop vm, and host state from stack */ - stp x0, x1, [x2] /* save x0, x1 to vm state */ + ldr x29, [sp], #2*8 /* pop vm pic state from stack */ + ldp x2, x30, [sp], #2*8 /* pop vm, and host state from stack */ /********************** @@ -364,6 +382,7 @@ _vm_to_host: eret /* host kernel must jump to this point to switch to a vm */ -.global hypervisor_enter_vm -hypervisor_enter_vm: +.global hypervisor_call +hypervisor_call: hvc #0 + ret diff --git a/repos/base-hw/src/core/spec/arm_v8/virtualization/hypervisor.h b/repos/base-hw/src/core/spec/arm_v8/virtualization/hypervisor.h new file mode 100644 index 0000000000..b58193fb22 --- /dev/null +++ b/repos/base-hw/src/core/spec/arm_v8/virtualization/hypervisor.h @@ -0,0 +1,52 @@ +/* + * \brief Interface between kernel and hypervisor + * \author Stefan Kalkowski + * \date 2022-06-13 + */ + +/* + * Copyright (C) 2022 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 _SPEC__ARM_V8__VIRTUALIZATION_HYPERVISOR_H_ +#define _SPEC__ARM_V8__VIRTUALIZATION_HYPERVISOR_H_ + +#include + +namespace Hypervisor { + + enum Call_number { + WORLD_SWITCH = 0, + TLB_INVALIDATE = 1, + }; + + using Call_arg = Genode::umword_t; + using Call_ret = Genode::umword_t; + + extern "C" + Call_ret hypervisor_call(Call_arg call_id, + Call_arg arg0, + Call_arg arg1, + Call_arg arg2, + Call_arg arg3); + + + inline void invalidate_tlb(Call_arg ttbr) + { + hypervisor_call(TLB_INVALIDATE, ttbr, 0, 0, 0); + } + + + inline void switch_world(Call_arg guest_state, + Call_arg host_state, + Call_arg pic_state, + Call_arg ttbr) + { + hypervisor_call(WORLD_SWITCH, guest_state, host_state, pic_state, ttbr); + } +} + +#endif /* _SPEC__ARM_V8__VIRTUALIZATION_HYPERVISOR_H_ */ diff --git a/repos/base-hw/src/core/spec/arm_v8/virtualization/kernel/vm.cc b/repos/base-hw/src/core/spec/arm_v8/virtualization/kernel/vm.cc index 6db8317560..30b6962865 100644 --- a/repos/base-hw/src/core/spec/arm_v8/virtualization/kernel/vm.cc +++ b/repos/base-hw/src/core/spec/arm_v8/virtualization/kernel/vm.cc @@ -23,14 +23,12 @@ #include #include +#include + using Genode::addr_t; using Kernel::Cpu; using Kernel::Vm; -extern void * kernel_stack; -extern "C" void hypervisor_enter_vm(addr_t vm, addr_t host, - addr_t pic, addr_t guest_table); - static Genode::Vm_state & host_context(Cpu & cpu) { @@ -154,6 +152,15 @@ Vm::Vm(Irq::Pool & user_irq_pool, } +Vm::~Vm() +{ + Cpu::Vttbr_el2::access_t vttbr_el2 = + Cpu::Vttbr_el2::Ba::masked((Cpu::Vttbr_el2::access_t)_id.table); + Cpu::Vttbr_el2::Asid::set(vttbr_el2, _id.id); + Hypervisor::invalidate_tlb(vttbr_el2); +} + + void Vm::exception(Cpu & cpu) { switch (_state.exception_type) { @@ -197,7 +204,7 @@ void Vm::proceed(Cpu & cpu) addr_t pic = Hw::Mm::el2_addr(&_vcpu_context.pic); addr_t host = Hw::Mm::el2_addr(&host_context(cpu)); - hypervisor_enter_vm(guest, host, pic, vttbr_el2); + Hypervisor::switch_world(guest, host, pic, vttbr_el2); } diff --git a/repos/base-hw/src/core/spec/cortex_a15/cpu.h b/repos/base-hw/src/core/spec/cortex_a15/cpu.h index 3a1ad078cf..ca1a447ec2 100644 --- a/repos/base-hw/src/core/spec/cortex_a15/cpu.h +++ b/repos/base-hw/src/core/spec/cortex_a15/cpu.h @@ -115,11 +115,14 @@ class Genode::Cpu : public Arm_v7_cpu */ static unsigned executing_id() { return Mpidr::Aff_0::get(Mpidr::read()); } - - void switch_to(Context &, Mmu_context & mmu_context) + bool active(Mmu_context & mmu_context) { - if (mmu_context.id() && (Ttbr0_64bit::read() != mmu_context.ttbr0)) - Ttbr0_64bit::write(mmu_context.ttbr0); + return (Ttbr0_64bit::read() == mmu_context.ttbr0); + } + + void switch_to(Mmu_context & mmu_context) + { + Ttbr0_64bit::write(mmu_context.ttbr0); } }; diff --git a/repos/base-hw/src/core/spec/riscv/cpu.cc b/repos/base-hw/src/core/spec/riscv/cpu.cc index e182afe444..e2e77f2aa5 100644 --- a/repos/base-hw/src/core/spec/riscv/cpu.cc +++ b/repos/base-hw/src/core/spec/riscv/cpu.cc @@ -53,22 +53,16 @@ Mmu_context::~Mmu_context() } +bool Genode::Cpu::active(Mmu_context & context) +{ + return Satp::read() == context.satp; +} + + void Genode::Cpu::switch_to(Mmu_context & context) { - /* - * The sstatus register defines to which privilege level - * the machin returns when doing an exception return - */ - bool user = Satp::Asid::get(context.satp); - Sstatus::access_t v = Sstatus::read(); - Sstatus::Spp::set(v, user ? 0 : 1); - Sstatus::write(v); - - /* change the translation table when necessary */ - if (user) { - Satp::write(context.satp); - sfence(); - } + Satp::write(context.satp); + sfence(); } diff --git a/repos/base-hw/src/core/spec/riscv/cpu.h b/repos/base-hw/src/core/spec/riscv/cpu.h index 86820b3504..d719abcb1c 100644 --- a/repos/base-hw/src/core/spec/riscv/cpu.h +++ b/repos/base-hw/src/core/spec/riscv/cpu.h @@ -97,6 +97,7 @@ class Genode::Cpu : public Hw::Riscv_cpu static void invalidate_tlb_by_pid(unsigned const /* pid */) { sfence(); } + bool active(Mmu_context & context); void switch_to(Mmu_context & context); static void mmu_fault(Context & c, Kernel::Thread_fault & f); diff --git a/repos/base-hw/src/core/spec/riscv/kernel/thread.cc b/repos/base-hw/src/core/spec/riscv/kernel/thread.cc index 15f568af26..10814fde15 100644 --- a/repos/base-hw/src/core/spec/riscv/kernel/thread.cc +++ b/repos/base-hw/src/core/spec/riscv/kernel/thread.cc @@ -100,7 +100,16 @@ void Kernel::Thread::_call_cache_invalidate_data_region() { } void Kernel::Thread::proceed(Cpu & cpu) { - cpu.switch_to(_pd->mmu_regs); + /* + * The sstatus register defines to which privilege level + * the machine returns when doing an exception return + */ + Cpu::Sstatus::access_t v = Cpu::Sstatus::read(); + Cpu::Sstatus::Spp::set(v, (type() == USER) ? 0 : 1); + Cpu::Sstatus::write(v); + + if (!cpu.active(pd().mmu_regs) && type() != CORE) + cpu.switch_to(_pd->mmu_regs); asm volatile("csrw sscratch, %1 \n" "mv x31, %0 \n" diff --git a/repos/base-hw/src/core/spec/x86_64/cpu.cc b/repos/base-hw/src/core/spec/x86_64/cpu.cc index 5ef6bc2cff..689e4f9e3d 100644 --- a/repos/base-hw/src/core/spec/x86_64/cpu.cc +++ b/repos/base-hw/src/core/spec/x86_64/cpu.cc @@ -111,11 +111,20 @@ extern void const * const kernel_stack; extern Genode::size_t const kernel_stack_size; -void Genode::Cpu::switch_to(Context & context, Mmu_context &mmu_context) +bool Genode::Cpu::active(Mmu_context &mmu_context) { - if ((context.cs != 0x8) && (mmu_context.cr3 != Cr3::read())) - Cr3::write(mmu_context.cr3); + return (mmu_context.cr3 == Cr3::read()); +} + +void Genode::Cpu::switch_to(Mmu_context &mmu_context) +{ + Cr3::write(mmu_context.cr3); +} + + +void Genode::Cpu::switch_to(Context & context) +{ tss.ist[0] = (addr_t)&context + sizeof(Genode::Cpu_state); addr_t const stack_base = reinterpret_cast(&kernel_stack); diff --git a/repos/base-hw/src/core/spec/x86_64/cpu.h b/repos/base-hw/src/core/spec/x86_64/cpu.h index 35073dcc93..781fa38373 100644 --- a/repos/base-hw/src/core/spec/x86_64/cpu.h +++ b/repos/base-hw/src/core/spec/x86_64/cpu.h @@ -126,7 +126,10 @@ class Genode::Cpu : public Hw::X86_64_cpu * * \param context next CPU context */ - void switch_to(Context & context, Mmu_context &mmu_context); + void switch_to(Context & context); + + bool active(Mmu_context &mmu_context); + void switch_to(Mmu_context &mmu_context); static void mmu_fault(Context & regs, Kernel::Thread_fault & fault); diff --git a/repos/base-hw/src/core/spec/x86_64/kernel/thread.cc b/repos/base-hw/src/core/spec/x86_64/kernel/thread.cc index 9df97877b1..df3332a4de 100644 --- a/repos/base-hw/src/core/spec/x86_64/kernel/thread.cc +++ b/repos/base-hw/src/core/spec/x86_64/kernel/thread.cc @@ -43,7 +43,10 @@ void Kernel::Thread::_call_cache_invalidate_data_region() { } void Kernel::Thread::proceed(Cpu & cpu) { - cpu.switch_to(*regs, pd().mmu_regs); + if (!cpu.active(pd().mmu_regs) && type() != CORE) + cpu.switch_to(pd().mmu_regs); + + cpu.switch_to(*regs); asm volatile("fxrstor (%1) \n" "mov %0, %%rsp \n" diff --git a/repos/base-hw/src/lib/ld/hw/target.mk b/repos/base-hw/src/lib/ld/hw/target.mk deleted file mode 100644 index da9b4cb18f..0000000000 --- a/repos/base-hw/src/lib/ld/hw/target.mk +++ /dev/null @@ -1,2 +0,0 @@ -TARGET = ld-hw -LIBS = ld-hw diff --git a/repos/base-hw/src/test/cpu_scheduler/test.cc b/repos/base-hw/src/test/cpu_scheduler/test.cc index 470a8ba44f..f26e2924ce 100644 --- a/repos/base-hw/src/test/cpu_scheduler/test.cc +++ b/repos/base-hw/src/test/cpu_scheduler/test.cc @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2014-2017 Genode Labs GmbH + * Copyright (C) 2014-2022 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. @@ -18,125 +18,110 @@ /* core includes */ #include -/* - * Utilities - */ +using namespace Genode; +using namespace Kernel; -using Genode::size_t; -using Genode::addr_t; -using Genode::construct_at; -using Kernel::Cpu_share; -using Kernel::Cpu_scheduler; - - -struct Data +struct Main { - Cpu_share idle; - Cpu_scheduler scheduler; - char shares[9][sizeof(Cpu_share)]; + enum { MAX_SHARES = 10 }; - Data() : idle(0, 0), scheduler(idle, 1000, 100) { } + Constructible shares[MAX_SHARES] {}; + Cpu_scheduler scheduler; + time_t current_time { 0 }; + + Cpu_share & _idle() + { + if (!shares[0].constructed()) shares[0].construct(0, 0); + return *shares[0]; + } + + Main() : scheduler(_idle(), 1000, 100) { } + + void done() + { + Genode::log("done"); + while (1) ; + } + + unsigned share_id(Cpu_share & share) + { + for (unsigned i = 0; i < MAX_SHARES; i++) + if (shares[i].constructed() && (&*shares[i] == &share)) + return i; + return ~0U; + } + + Cpu_share & share(unsigned const id) + { + return *shares[id]; + } + + void create(unsigned const id) + { + switch (id) { + case 1: shares[id].construct(2, 230); break; + case 2: shares[id].construct(0, 170); break; + case 3: shares[id].construct(3, 110); break; + case 4: shares[id].construct(1, 90); break; + case 5: shares[id].construct(3, 120); break; + case 6: shares[id].construct(3, 0); break; + case 7: shares[id].construct(2, 180); break; + case 8: shares[id].construct(2, 100); break; + case 9: shares[id].construct(2, 0); break; + default: return; + } + scheduler.insert(*shares[id]); + } + + void destroy(unsigned const id) + { + if (!id || id >= MAX_SHARES) + return; + + scheduler.remove(share(id)); + shares[id].destruct(); + } + + unsigned time() + { + return scheduler.quota() - scheduler.residual(); + } + + void update_check(unsigned const l, unsigned const c, unsigned const t, + unsigned const s, unsigned const q) + { + current_time += c; + scheduler.update(current_time); + unsigned const st = time(); + if (t != st) { + log("wrong time ", st, " in line ", l); + done(); + } + Cpu_share & hs = scheduler.head(); + unsigned const hq = scheduler.head_quota(); + if (&hs != &share(s)) { + log("wrong share ", share_id(hs), " in line ", l); + done(); + } + if (hq != q) { + log("wrong quota ", hq, " in line ", l); + done(); + } + } + + void ready_check(unsigned const l, unsigned const s, bool const x) + { + scheduler.ready(share(s)); + if (scheduler.need_to_schedule() != x) { + log("wrong check result ", scheduler.need_to_schedule(), " in line ", l); + done(); + } + } + + void test(); }; -Data * data() -{ - static Data d; - return &d; -} - - -void done() -{ - Genode::log("done"); - while (1) ; -} - - -unsigned share_id(void * const pointer) -{ - addr_t const address = (addr_t)pointer; - addr_t const base = (addr_t)data()->shares; - if (address < base || address >= base + sizeof(data()->shares)) { - return 0; } - return (unsigned)((address - base) / sizeof(Cpu_share) + 1); -} - - -Cpu_share * share(unsigned const id) -{ - if (!id) { return &data()->idle; } - return reinterpret_cast(&data()->shares[id - 1]); -} - - -void create(unsigned const id) -{ - Cpu_share * const s = share(id); - void * const p = (void *)s; - switch (id) { - case 1: construct_at(p, 2, 230); break; - case 2: construct_at(p, 0, 170); break; - case 3: construct_at(p, 3, 110); break; - case 4: construct_at(p, 1, 90); break; - case 5: construct_at(p, 3, 120); break; - case 6: construct_at(p, 3, 0); break; - case 7: construct_at(p, 2, 180); break; - case 8: construct_at(p, 2, 100); break; - case 9: construct_at(p, 2, 0); break; - default: return; - } - data()->scheduler.insert(*s); -} - - -void destroy(unsigned const id) -{ - Cpu_share * const s = share(id); - data()->scheduler.remove(*s); - s->~Cpu_share(); -} - - -unsigned time() -{ - return data()->scheduler.quota() - - data()->scheduler.residual(); -} - - -void update_check(unsigned const l, unsigned const c, unsigned const t, - unsigned const s, unsigned const q) -{ - data()->scheduler.update(c); - unsigned const st = time(); - if (t != st) { - Genode::log("wrong time ", st, " in line ", l); - done(); - } - Cpu_share &hs = data()->scheduler.head(); - unsigned const hq = data()->scheduler.head_quota(); - if (&hs != share(s)) { - unsigned const hi = share_id(&hs); - Genode::log("wrong share ", hi, " in line ", l); - done(); - } - if (hq != q) { - Genode::log("wrong quota ", hq, " in line ", l); - done(); - } -} - - -void ready_check(unsigned const l, unsigned const s, bool const x) -{ - data()->scheduler.ready_check(*share(s)); - if (data()->scheduler.need_to_schedule() != x) { - Genode::log("wrong check result ", data()->scheduler.need_to_schedule(), " in line ", l); - done(); - } -} - /* * Shortcuts for all basic operations that the test consists of @@ -144,10 +129,10 @@ void ready_check(unsigned const l, unsigned const s, bool const x) #define C(s) create(s); #define D(s) destroy(s); -#define A(s) data()->scheduler.ready(*share(s)); -#define I(s) data()->scheduler.unready(*share(s)); -#define Y data()->scheduler.yield(); -#define Q(s, q) data()->scheduler.quota(*share(s), q); +#define A(s) scheduler.ready(share(s)); +#define I(s) scheduler.unready(share(s)); +#define Y scheduler.yield(); +#define Q(s, q) scheduler.quota(share(s), q); #define U(c, t, s, q) update_check(__LINE__, c, t, s, q); #define O(s) ready_check(__LINE__, s, true); #define N(s) ready_check(__LINE__, s, false); @@ -157,6 +142,13 @@ void ready_check(unsigned const l, unsigned const s, bool const x) * Main routine */ void Component::construct(Genode::Env &) +{ + static Main main; + main.test(); +} + + +void Main::test() { /* * Step-by-step testing diff --git a/repos/base-linux/recipes/api/base-linux/content.mk b/repos/base-linux/recipes/api/base-linux/content.mk index c77cf9d735..7839296c17 100644 --- a/repos/base-linux/recipes/api/base-linux/content.mk +++ b/repos/base-linux/recipes/api/base-linux/content.mk @@ -1,8 +1,7 @@ FROM_BASE_LINUX := etc src/lib/syscall src/lib/lx_hybrid lib/import include -FROM_BASE_LINUX_AND_BASE := lib/mk src/lib/base src/include -FROM_BASE := src/lib/timeout +FROM_BASE_LINUX_AND_BASE := src/lib/base src/include -content: $(FROM_BASE_LINUX) $(FROM_BASE_LINUX_AND_BASE) $(FROM_BASE) LICENSE +content: $(FROM_BASE_LINUX) $(FROM_BASE_LINUX_AND_BASE) LICENSE $(FROM_BASE_LINUX): mkdir -p $@ @@ -13,9 +12,30 @@ $(FROM_BASE_LINUX_AND_BASE): cp -r $(GENODE_DIR)/repos/base/$@/* $@ cp -r $(REP_DIR)/$@/* $@ -$(FROM_BASE): +BASE_LIB_MK_CONTENT := \ + $(addprefix lib/mk/,base-common.inc timeout.mk) + +content: $(BASE_LIB_MK_CONTENT) + +$(BASE_LIB_MK_CONTENT): + mkdir -p $(dir $@) + cp $(GENODE_DIR)/repos/base/$@ $@ + +content: src/lib/timeout + +src/lib/timeout: mkdir -p $@ cp -r $(GENODE_DIR)/repos/base/$@/* $@ +BASE_LINUX_LIB_MK_CONTENT := \ + $(addprefix lib/mk/,lx_hybrid.mk base-linux.inc base-linux-common.mk) \ + $(foreach S,arm arm_64 x86_32 x86_64,lib/mk/spec/$S/syscall-linux.mk) + +content: $(BASE_LINUX_LIB_MK_CONTENT) + +$(BASE_LINUX_LIB_MK_CONTENT): + mkdir -p $(dir $@) + cp $(REP_DIR)/$@ $@ + LICENSE: cp $(GENODE_DIR)/LICENSE $@ diff --git a/repos/base-linux/recipes/api/base-linux/hash b/repos/base-linux/recipes/api/base-linux/hash index 8c49e019b3..dbb7c16ebe 100644 --- a/repos/base-linux/recipes/api/base-linux/hash +++ b/repos/base-linux/recipes/api/base-linux/hash @@ -1 +1 @@ -2022-04-12 dcb2c9200b333adb17f9a8737620cbd84f641408 +2022-10-11 4544924c73b2ee1d8d2717672320f14732807267 diff --git a/repos/base-linux/recipes/src/base-linux/content.mk b/repos/base-linux/recipes/src/base-linux/content.mk index ad1db4cc75..ac78f59846 100644 --- a/repos/base-linux/recipes/src/base-linux/content.mk +++ b/repos/base-linux/recipes/src/base-linux/content.mk @@ -10,7 +10,6 @@ content: mv lib/mk/spec/$$spec/ld-linux.mk lib/mk/spec/$$spec/ld.mk; done; sed -i "/TARGET/s/core-linux/core/" src/core/linux/target.mk sed -i "s/BOARD.*unknown/BOARD := linux/" lib/mk/core-linux.inc - sed -i "s/ld-linux/ld/" src/lib/ld/linux/target.mk sed -i "s/linux_timer_drv/timer/" src/timer/linux/target.mk - rm -rf src/lib/initramfs + rm -rf src/initramfs diff --git a/repos/base-linux/recipes/src/base-linux/hash b/repos/base-linux/recipes/src/base-linux/hash index 8ae6c7808f..7f3752b7d0 100644 --- a/repos/base-linux/recipes/src/base-linux/hash +++ b/repos/base-linux/recipes/src/base-linux/hash @@ -1 +1 @@ -2022-05-24 4aea382035415c79bf5d551642ebfa64d42e4d21 +2022-10-11 d7e12d81f12f081bb7c00233c18f3c8ac2f00d67 diff --git a/repos/base-linux/src/lib/initramfs/init.c b/repos/base-linux/src/initramfs/init.c similarity index 100% rename from repos/base-linux/src/lib/initramfs/init.c rename to repos/base-linux/src/initramfs/init.c diff --git a/repos/base-linux/src/lib/initramfs/target.mk b/repos/base-linux/src/initramfs/target.mk similarity index 72% rename from repos/base-linux/src/lib/initramfs/target.mk rename to repos/base-linux/src/initramfs/target.mk index c684f26c29..b7146371f4 100644 --- a/repos/base-linux/src/lib/initramfs/target.mk +++ b/repos/base-linux/src/initramfs/target.mk @@ -5,14 +5,14 @@ REQUIRES = x86_64 INITRAMFS = initramfs INITRAMFS_SRC_C = init.c -EXT_OBJECTS += $(BUILD_BASE_DIR)/lib/initramfs/$(INITRAMFS) +EXT_OBJECTS += $(BUILD_BASE_DIR)/initramfs/$(INITRAMFS) $(TARGET): $(INITRAMFS) $(INITRAMFS): $(INITRAMFS_SRC_C) $(MSG_BUILD)$(INITRAMFS) $(VERBOSE)gcc $^ -O0 $(CC_MARCH) -Wall -W -Wextra -Werror -std=gnu99 -o $@ -Wl,-O3 -Wl,--as-needed -static - $(VERBOSE)ln -sf $(BUILD_BASE_DIR)/lib/initramfs/$(INITRAMFS) $(BUILD_BASE_DIR)/bin/ + $(VERBOSE)ln -sf $(BUILD_BASE_DIR)/initramfs/$(INITRAMFS) $(BUILD_BASE_DIR)/bin/ clean_initramfs: $(VERBOSE)rm -rf $(INITRAMFS) diff --git a/repos/base-linux/src/lib/base/region_map_mmap.cc b/repos/base-linux/src/lib/base/region_map_mmap.cc index 01946e4204..46b34ae66b 100644 --- a/repos/base-linux/src/lib/base/region_map_mmap.cc +++ b/repos/base-linux/src/lib/base/region_map_mmap.cc @@ -172,6 +172,24 @@ void Region_map_mmap::_add_to_rmap(Region const ®ion) } +/* + * Tracing must be inhibited in attach/detach as RPC trace points may trigger + * attachment of trace dataspaces, which would result in nested mutex + * acquisition. + */ + +namespace Genode { extern bool inhibit_tracing; } + +struct Inhibit_tracing_guard +{ + bool old_value = inhibit_tracing; + + Inhibit_tracing_guard() { inhibit_tracing = true; } + + ~Inhibit_tracing_guard() { inhibit_tracing = old_value; } +}; + + Region_map::Local_addr Region_map_mmap::attach(Dataspace_capability ds, size_t size, off_t offset, bool use_local_addr, @@ -180,6 +198,8 @@ Region_map::Local_addr Region_map_mmap::attach(Dataspace_capability ds, { Mutex::Guard mutex_guard(mutex()); + Inhibit_tracing_guard it_guard { }; + /* only support attach_at for sub RM sessions */ if (_sub_rm && !use_local_addr) { error("Region_map_mmap::attach: attaching w/o local addr not supported"); @@ -325,6 +345,8 @@ void Region_map_mmap::detach(Region_map::Local_addr local_addr) { Mutex::Guard mutex_guard(mutex()); + Inhibit_tracing_guard it_guard { }; + /* * Cases * diff --git a/repos/base-linux/src/lib/ld/linux/target.mk b/repos/base-linux/src/lib/ld/linux/target.mk deleted file mode 100644 index dbbcd910ba..0000000000 --- a/repos/base-linux/src/lib/ld/linux/target.mk +++ /dev/null @@ -1,4 +0,0 @@ -TARGET = ld-linux.lib -LIBS = ld-linux - -BUILD_ARTIFACTS := ld-linux.lib.so diff --git a/repos/base-nova/include/nova/syscall-generic.h b/repos/base-nova/include/nova/syscall-generic.h index 2eb5509383..281a9db4e6 100644 --- a/repos/base-nova/include/nova/syscall-generic.h +++ b/repos/base-nova/include/nova/syscall-generic.h @@ -260,6 +260,30 @@ namespace Nova { */ enum Pd_op { TRANSFER_QUOTA = 0U, PD_DEBUG = 2U }; + class Gsi_flags + { + private: + + uint8_t _value { 0 }; + + public: + + enum Mode { HIGH, LOW, EDGE }; + + Gsi_flags() { } + + Gsi_flags(Mode m) + { + switch (m) { + case HIGH: _value = 0b110; break; /* level-high */ + case LOW: _value = 0b111; break; /* level-low */ + case EDGE: _value = 0b100; break; /* edge-triggered */ + } + } + + uint8_t value() const { return _value; } + }; + class Descriptor { diff --git a/repos/base-nova/include/spec/32bit/nova/syscalls.h b/repos/base-nova/include/spec/32bit/nova/syscalls.h index e52c61d334..6fb41d4fee 100644 --- a/repos/base-nova/include/spec/32bit/nova/syscalls.h +++ b/repos/base-nova/include/spec/32bit/nova/syscalls.h @@ -457,12 +457,12 @@ namespace Nova { ALWAYS_INLINE inline uint8_t assign_gsi(mword_t sm, mword_t dev, mword_t cpu, mword_t &msi_addr, mword_t &msi_data, - mword_t si = ~0UL) + mword_t si = ~0UL, Gsi_flags flags = Gsi_flags()) { msi_addr = dev; msi_data = cpu; - return syscall_5(NOVA_ASSIGN_GSI, 0, sm, msi_addr, msi_data, si); + return syscall_5(NOVA_ASSIGN_GSI, flags.value(), sm, msi_addr, msi_data, si); } diff --git a/repos/base-nova/include/spec/64bit/nova/syscalls.h b/repos/base-nova/include/spec/64bit/nova/syscalls.h index 3ab7e887ed..9e8fa765fc 100644 --- a/repos/base-nova/include/spec/64bit/nova/syscalls.h +++ b/repos/base-nova/include/spec/64bit/nova/syscalls.h @@ -402,11 +402,11 @@ namespace Nova { ALWAYS_INLINE inline uint8_t assign_gsi(mword_t sm, mword_t dev, mword_t cpu, mword_t &msi_addr, mword_t &msi_data, - mword_t si = ~0UL) + mword_t si = ~0UL, Gsi_flags flags = Gsi_flags()) { msi_addr = dev; msi_data = cpu; - return syscall_5(NOVA_ASSIGN_GSI, 0, sm, msi_addr, msi_data, si); + return syscall_5(NOVA_ASSIGN_GSI, flags.value(), sm, msi_addr, msi_data, si); } } #endif /* _INCLUDE__SPEC__64BIT__NOVA__SYSCALLS_H_ */ diff --git a/repos/base-nova/ports/nova.port b/repos/base-nova/ports/nova.port index 5d15c9ba19..c46b0978e5 100644 --- a/repos/base-nova/ports/nova.port +++ b/repos/base-nova/ports/nova.port @@ -2,7 +2,7 @@ LICENSE := GPLv2 VERSION := git DOWNLOADS := nova.git -# r10 branch +# feature/numa branch URL(nova) := https://github.com/mmueller41/NOVA.git REV(nova) := 6479677bd61db47bcdcb4bd796566f83b9f655ef DIR(nova) := src/kernel/nova diff --git a/repos/base-nova/recipes/api/base-nova/content.mk b/repos/base-nova/recipes/api/base-nova/content.mk index c49d05cd49..dbb72ce372 100644 --- a/repos/base-nova/recipes/api/base-nova/content.mk +++ b/repos/base-nova/recipes/api/base-nova/content.mk @@ -1,5 +1,8 @@ FROM_BASE_NOVA := etc include -FROM_BASE := lib/mk/timeout.mk src/lib/timeout + +# base-nova.lib.a depends on timeout.lib.a, which includes base/internal/gloabls.h +FROM_BASE := lib/mk/timeout.mk src/lib/timeout \ + src/include/base/internal/globals.h content: $(FROM_BASE_NOVA) $(FROM_BASE) LICENSE diff --git a/repos/base-nova/recipes/api/base-nova/hash b/repos/base-nova/recipes/api/base-nova/hash index ee7a3a50cc..bbdab0a29c 100644 --- a/repos/base-nova/recipes/api/base-nova/hash +++ b/repos/base-nova/recipes/api/base-nova/hash @@ -1 +1 @@ -2022-05-24 91bc8d51bbe703d56f5671019d14e4636f21bf1f +2022-10-11 4458ea63a69ae070e19a3cb09a403137755d2cb0 diff --git a/repos/base-nova/recipes/src/base-nova/content.mk b/repos/base-nova/recipes/src/base-nova/content.mk index cf557b5dbe..41278a28a1 100644 --- a/repos/base-nova/recipes/src/base-nova/content.mk +++ b/repos/base-nova/recipes/src/base-nova/content.mk @@ -15,8 +15,7 @@ src/kernel/nova: src/kernel content: for spec in x86_32 x86_64; do \ - mv lib/mk/spec/$$spec/ld-nova.mk lib/mk/spec/$$spec/ld.mk; \ + mv lib/mk/spec/$$spec/ld-nova.mk lib/mk/spec/$$spec/ld.mk; \ done; - sed -i "s/ld-nova/ld/" src/lib/ld/nova/target.mk sed -i "s/nova_timer_drv/timer/" src/timer/nova/target.mk diff --git a/repos/base-nova/recipes/src/base-nova/hash b/repos/base-nova/recipes/src/base-nova/hash index 3fce06004a..c2b670f646 100644 --- a/repos/base-nova/recipes/src/base-nova/hash +++ b/repos/base-nova/recipes/src/base-nova/hash @@ -1 +1 @@ -2022-05-24 8b59a28ade1392bae4aa772bbead1584a2dde1de +2022-10-11 574204b7d442811236bba60e4fe3f79e34fe9985 diff --git a/repos/base-nova/src/core/include/irq_object.h b/repos/base-nova/src/core/include/irq_object.h index e3a681bd2d..869eeed784 100644 --- a/repos/base-nova/src/core/include/irq_object.h +++ b/repos/base-nova/src/core/include/irq_object.h @@ -13,7 +13,9 @@ #ifndef _CORE__INCLUDE__IRQ_OBJECT_H_ #define _CORE__INCLUDE__IRQ_OBJECT_H_ -namespace Genode { class Irq_object; } +#include /* Gsi_flags */ + +namespace Genode { class Irq_object; class Irq_args; } class Genode::Irq_object { @@ -26,22 +28,24 @@ class Genode::Irq_object addr_t _msi_data; addr_t _device_phys = 0; /* PCI config extended address */ + Nova::Gsi_flags _gsi_flags { }; + enum { KERNEL_CAP_COUNT_LOG2 = 0 }; - Genode::addr_t irq_sel() const { return _kernel_caps; } + addr_t irq_sel() const { return _kernel_caps; } public: Irq_object(); ~Irq_object(); - Genode::addr_t msi_address() const { return _msi_addr; } - Genode::addr_t msi_value() const { return _msi_data; } + addr_t msi_address() const { return _msi_addr; } + addr_t msi_value() const { return _msi_data; } void sigh(Signal_context_capability cap); void ack_irq(); - void start(unsigned irq, Genode::addr_t); + void start(unsigned irq, addr_t, Irq_args const &); }; #endif /* _CORE__INCLUDE__IRQ_OBJECT_H_ */ diff --git a/repos/base-nova/src/core/irq_session_component.cc b/repos/base-nova/src/core/irq_session_component.cc index 472d885ce1..2d98d3f5bc 100644 --- a/repos/base-nova/src/core/irq_session_component.cc +++ b/repos/base-nova/src/core/irq_session_component.cc @@ -18,6 +18,7 @@ /* core includes */ #include +#include #include /* NOVA includes */ @@ -27,13 +28,12 @@ using namespace Genode; -static bool irq_ctrl(Genode::addr_t irq_sel, - Genode::addr_t &msi_addr, Genode::addr_t &msi_data, - Genode::addr_t sig_sel, Genode::addr_t virt_addr = 0) +static bool irq_ctrl(addr_t irq_sel, addr_t &msi_addr, addr_t &msi_data, + addr_t sig_sel, Nova::Gsi_flags flags, addr_t virt_addr) { /* assign IRQ to CPU && request msi data to be used by driver */ uint8_t res = Nova::assign_gsi(irq_sel, virt_addr, boot_cpu(), - msi_addr, msi_data, sig_sel); + msi_addr, msi_data, sig_sel, flags); if (res != Nova::NOVA_OK) error("setting up MSI failed - error ", res); @@ -46,30 +46,28 @@ static bool irq_ctrl(Genode::addr_t irq_sel, } -static bool associate(Genode::addr_t irq_sel, - Genode::addr_t &msi_addr, Genode::addr_t &msi_data, - Genode::Signal_context_capability sig_cap, - Genode::addr_t virt_addr = 0) -{ - return irq_ctrl(irq_sel, msi_addr, msi_data, sig_cap.local_name(), - virt_addr); -} - - -static void deassociate(Genode::addr_t irq_sel) +static bool associate_gsi(addr_t irq_sel, Signal_context_capability sig_cap, + Nova::Gsi_flags gsi_flags) { addr_t dummy1 = 0, dummy2 = 0; - if (!irq_ctrl(irq_sel, dummy1, dummy2, irq_sel)) + return irq_ctrl(irq_sel, dummy1, dummy2, sig_cap.local_name(), gsi_flags, 0); +} + + +static void deassociate(addr_t irq_sel) +{ + addr_t dummy1 = 0, dummy2 = 0; + + if (!irq_ctrl(irq_sel, dummy1, dummy2, irq_sel, Nova::Gsi_flags(), 0)) warning("Irq could not be de-associated"); } -static bool msi(Genode::addr_t irq_sel, Genode::addr_t phys_mem, - Genode::addr_t &msi_addr, Genode::addr_t &msi_data, - Genode::Signal_context_capability sig_cap) +static bool associate_msi(addr_t irq_sel, addr_t phys_mem, addr_t &msi_addr, + addr_t &msi_data, Signal_context_capability sig_cap) { - return platform().region_alloc().alloc_aligned(4096, 12).convert( + return platform().region_alloc().alloc_aligned(4096, 12).convert( [&] (void *virt_ptr) { @@ -89,7 +87,7 @@ static bool msi(Genode::addr_t irq_sel, Genode::addr_t phys_mem, } /* try to assign MSI to device */ - bool res = associate(irq_sel, msi_addr, msi_data, sig_cap, virt_addr); + bool res = irq_ctrl(irq_sel, msi_addr, msi_data, sig_cap.local_name(), Nova::Gsi_flags(), virt_addr); unmap_local(Nova::Mem_crd(virt_addr >> 12, 0, Rights(true, true, true))); platform().region_alloc().free(virt_ptr, 4096); @@ -118,11 +116,12 @@ void Irq_object::sigh(Signal_context_capability cap) return; } + /* associate GSI or MSI to device belonging to device_phys */ bool ok = false; if (_device_phys) - ok = msi(irq_sel(), _device_phys, _msi_addr, _msi_data, cap); + ok = associate_msi(irq_sel(), _device_phys, _msi_addr, _msi_data, cap); else - ok = associate(irq_sel(), _msi_addr, _msi_data, cap); + ok = associate_gsi(irq_sel(), cap, _gsi_flags); if (!ok) { deassociate(irq_sel()); @@ -141,7 +140,7 @@ void Irq_object::ack_irq() } -void Irq_object::start(unsigned irq, Genode::addr_t const device_phys) +void Irq_object::start(unsigned irq, addr_t const device_phys, Irq_args const &irq_args) { /* map IRQ SM cap from kernel to core at irq_sel selector */ using Nova::Obj_crd; @@ -158,12 +157,29 @@ void Irq_object::start(unsigned irq, Genode::addr_t const device_phys) throw Service_denied(); } + /* initialize GSI IRQ flags */ + auto gsi_flags = [] (Irq_args const &args) { + if (args.trigger() == Irq_session::TRIGGER_UNCHANGED + || args.polarity() == Irq_session::POLARITY_UNCHANGED) + return Nova::Gsi_flags(); + + if (args.trigger() == Irq_session::TRIGGER_EDGE) + return Nova::Gsi_flags(Nova::Gsi_flags::EDGE); + + if (args.polarity() == Irq_session::POLARITY_HIGH) + return Nova::Gsi_flags(Nova::Gsi_flags::HIGH); + else + return Nova::Gsi_flags(Nova::Gsi_flags::LOW); + }; + + _gsi_flags = gsi_flags(irq_args); + /* associate GSI or MSI to device belonging to device_phys */ bool ok = false; if (device_phys) - ok = msi(irq_sel(), device_phys, _msi_addr, _msi_data, _sigh_cap); + ok = associate_msi(irq_sel(), device_phys, _msi_addr, _msi_data, _sigh_cap); else - ok = associate(irq_sel(), _msi_addr, _msi_data, _sigh_cap); + ok = associate_gsi(irq_sel(), _sigh_cap, _gsi_flags); if (!ok) throw Service_denied(); @@ -212,7 +228,9 @@ Irq_session_component::Irq_session_component(Range_allocator &irq_alloc, : _irq_number(~0U), _irq_alloc(irq_alloc), _irq_object() { - long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1); + Irq_args const irq_args(args); + + long irq_number = irq_args.irq_number(); long device_phys = Arg_string::find_arg(args, "device_config_phys").long_value(0); if (device_phys) { @@ -232,7 +250,7 @@ Irq_session_component::Irq_session_component(Range_allocator &irq_alloc, _irq_number = (unsigned)irq_number; - _irq_object.start(_irq_number, device_phys); + _irq_object.start(_irq_number, device_phys, irq_args); } @@ -241,7 +259,7 @@ Irq_session_component::~Irq_session_component() if (_irq_number == ~0U) return; - Genode::addr_t free_irq = _irq_number; + addr_t free_irq = _irq_number; _irq_alloc.free((void *)free_irq); } @@ -252,13 +270,13 @@ void Irq_session_component::ack_irq() } -void Irq_session_component::sigh(Genode::Signal_context_capability cap) +void Irq_session_component::sigh(Signal_context_capability cap) { _irq_object.sigh(cap); } -Genode::Irq_session::Info Irq_session_component::info() +Irq_session::Info Irq_session_component::info() { if (!_irq_object.msi_address() || !_irq_object.msi_value()) return { .type = Info::Type::INVALID, .address = 0, .value = 0 }; diff --git a/repos/base-nova/src/lib/ld/nova/target.mk b/repos/base-nova/src/lib/ld/nova/target.mk deleted file mode 100644 index f9615eec76..0000000000 --- a/repos/base-nova/src/lib/ld/nova/target.mk +++ /dev/null @@ -1,2 +0,0 @@ -TARGET = ld-nova -LIBS = ld-nova diff --git a/repos/base-okl4/recipes/src/base-okl4/content.mk b/repos/base-okl4/recipes/src/base-okl4/content.mk index 39d7d59d8a..4caca8c8cd 100644 --- a/repos/base-okl4/recipes/src/base-okl4/content.mk +++ b/repos/base-okl4/recipes/src/base-okl4/content.mk @@ -19,8 +19,7 @@ src/kernel/okl4: src/kernel content: for spec in x86_32; do \ - mv lib/mk/spec/$$spec/ld-okl4.mk lib/mk/spec/$$spec/ld.mk; \ + mv lib/mk/spec/$$spec/ld-okl4.mk lib/mk/spec/$$spec/ld.mk; \ done; - sed -i "s/ld-okl4/ld/" src/lib/ld/okl4/target.mk sed -i "s/pit_timer_drv/timer/" src/timer/pit/target.inc diff --git a/repos/base-okl4/recipes/src/base-okl4/hash b/repos/base-okl4/recipes/src/base-okl4/hash index 606a20a29b..acee3cdeb5 100644 --- a/repos/base-okl4/recipes/src/base-okl4/hash +++ b/repos/base-okl4/recipes/src/base-okl4/hash @@ -1 +1 @@ -2022-05-24 3b2acba4ebd649394e26217802598cf650a4b226 +2022-10-11 b81b8b94731cda35017a740b0110ff4e8e233e07 diff --git a/repos/base-okl4/src/lib/ld/okl4/target.mk b/repos/base-okl4/src/lib/ld/okl4/target.mk deleted file mode 100644 index 1d041e3cd2..0000000000 --- a/repos/base-okl4/src/lib/ld/okl4/target.mk +++ /dev/null @@ -1,2 +0,0 @@ -TARGET = ld-okl4 -LIBS = ld-okl4 diff --git a/repos/base-pistachio/recipes/src/base-pistachio/content.mk b/repos/base-pistachio/recipes/src/base-pistachio/content.mk index b8c9dbb474..c33056fc45 100644 --- a/repos/base-pistachio/recipes/src/base-pistachio/content.mk +++ b/repos/base-pistachio/recipes/src/base-pistachio/content.mk @@ -21,6 +21,5 @@ content: for spec in x86_32; do \ mv lib/mk/spec/$$spec/ld-pistachio.mk lib/mk/spec/$$spec/ld.mk; \ done; - sed -i "s/ld-pistachio/ld/" src/lib/ld/pistachio/target.mk sed -i "s/pit_timer_drv/timer/" src/timer/pit/target.inc diff --git a/repos/base-pistachio/recipes/src/base-pistachio/hash b/repos/base-pistachio/recipes/src/base-pistachio/hash index 73e511a7ee..6177cd0ad9 100644 --- a/repos/base-pistachio/recipes/src/base-pistachio/hash +++ b/repos/base-pistachio/recipes/src/base-pistachio/hash @@ -1 +1 @@ -2022-05-24 ca2c90ebcbaa61ade7373d6ea48a608912cd2629 +2022-10-11 b522663f9c8c779f255e2a5eb37f98b4301c5446 diff --git a/repos/base-pistachio/src/lib/ld/pistachio/target.mk b/repos/base-pistachio/src/lib/ld/pistachio/target.mk deleted file mode 100644 index af224bfef8..0000000000 --- a/repos/base-pistachio/src/lib/ld/pistachio/target.mk +++ /dev/null @@ -1,2 +0,0 @@ -TARGET = ld-pistachio -LIBS = ld-pistachio diff --git a/repos/base-sel4/recipes/src/base-sel4-imx6q_sabrelite/content.mk b/repos/base-sel4/recipes/src/base-sel4-imx6q_sabrelite/content.mk index 82d866de9c..3e4a0c2acb 100644 --- a/repos/base-sel4/recipes/src/base-sel4-imx6q_sabrelite/content.mk +++ b/repos/base-sel4/recipes/src/base-sel4-imx6q_sabrelite/content.mk @@ -35,7 +35,6 @@ etc/board.conf: content: mv lib/mk/spec/arm/ld-sel4.mk lib/mk/spec/arm/ld.mk; - sed -i "s/ld-sel4/ld/" src/lib/ld/sel4/target.mk sed -i "s/imx6_timer_drv/timer/" src/timer/epit/imx6/target.inc find lib/mk/spec -name kernel-sel4-*.mk -o -name syscall-sel4-*.mk |\ grep -v "sel4-imx6q_sabrelite.mk" | xargs rm -rf diff --git a/repos/base-sel4/recipes/src/base-sel4-imx6q_sabrelite/hash b/repos/base-sel4/recipes/src/base-sel4-imx6q_sabrelite/hash index e47ab7ffe0..9b27295d9e 100644 --- a/repos/base-sel4/recipes/src/base-sel4-imx6q_sabrelite/hash +++ b/repos/base-sel4/recipes/src/base-sel4-imx6q_sabrelite/hash @@ -1 +1 @@ -2022-05-24 5d9558d34f4bd3f3e34d9b175fe3eb37be3561be +2022-10-11 6966c1e6595fec6e545ae729b9a5893e745a9fc9 diff --git a/repos/base-sel4/recipes/src/base-sel4-imx7d_sabre/content.mk b/repos/base-sel4/recipes/src/base-sel4-imx7d_sabre/content.mk index bb357a3ed8..d339aec070 100644 --- a/repos/base-sel4/recipes/src/base-sel4-imx7d_sabre/content.mk +++ b/repos/base-sel4/recipes/src/base-sel4-imx7d_sabre/content.mk @@ -35,7 +35,6 @@ etc/board.conf: content: mv lib/mk/spec/arm/ld-sel4.mk lib/mk/spec/arm/ld.mk; - sed -i "s/ld-sel4/ld/" src/lib/ld/sel4/target.mk sed -i "s/imx7_timer_drv/timer/" src/timer/gpt/imx7/target.inc find lib/mk/spec -name kernel-sel4-*.mk -o -name syscall-sel4-*.mk |\ grep -v "sel4-imx7d_sabre.mk" | xargs rm -rf diff --git a/repos/base-sel4/recipes/src/base-sel4-imx7d_sabre/hash b/repos/base-sel4/recipes/src/base-sel4-imx7d_sabre/hash index 5ef0c29af4..bfb3e928ec 100644 --- a/repos/base-sel4/recipes/src/base-sel4-imx7d_sabre/hash +++ b/repos/base-sel4/recipes/src/base-sel4-imx7d_sabre/hash @@ -1 +1 @@ -2022-05-24 70a360e5c7b6aed126fb99fc3666cfce030cf53e +2022-10-11 e11873b5f947ab3013208e8b4ad7621113b00580 diff --git a/repos/base-sel4/recipes/src/base-sel4-x86/content.mk b/repos/base-sel4/recipes/src/base-sel4-x86/content.mk index 7d706f6fd2..cca289d09e 100644 --- a/repos/base-sel4/recipes/src/base-sel4-x86/content.mk +++ b/repos/base-sel4/recipes/src/base-sel4-x86/content.mk @@ -26,7 +26,6 @@ content: for spec in x86_32 x86_64 arm; do \ mv lib/mk/spec/$$spec/ld-sel4.mk lib/mk/spec/$$spec/ld.mk; \ done; - sed -i "s/ld-sel4/ld/" src/lib/ld/sel4/target.mk sed -i "s/pit_timer_drv/timer/" src/timer/pit/target.inc find lib/mk/spec -name kernel-sel4-*.mk -o -name syscall-sel4-*.mk |\ grep -v "sel4-pc.mk" | xargs rm -rf diff --git a/repos/base-sel4/recipes/src/base-sel4-x86/hash b/repos/base-sel4/recipes/src/base-sel4-x86/hash index 00c88112bc..44aa295142 100644 --- a/repos/base-sel4/recipes/src/base-sel4-x86/hash +++ b/repos/base-sel4/recipes/src/base-sel4-x86/hash @@ -1 +1 @@ -2022-05-24 fa03ec1bf7ea9b643319d67dbd52e146e0d98189 +2022-10-11 b816b62207fc76123ce72f844fa3914163949f56 diff --git a/repos/base-sel4/src/lib/ld/sel4/target.mk b/repos/base-sel4/src/lib/ld/sel4/target.mk deleted file mode 100644 index 4e78c9b5b4..0000000000 --- a/repos/base-sel4/src/lib/ld/sel4/target.mk +++ /dev/null @@ -1,2 +0,0 @@ -TARGET = ld-sel4 -LIBS = ld-sel4 diff --git a/repos/base/board/pc/devices b/repos/base/board/pc/devices new file mode 100644 index 0000000000..b5ca5a1261 --- /dev/null +++ b/repos/base/board/pc/devices @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/repos/base/board/virt_qemu/qemu_args b/repos/base/board/virt_qemu_arm_v7a/qemu_args similarity index 61% rename from repos/base/board/virt_qemu/qemu_args rename to repos/base/board/virt_qemu_arm_v7a/qemu_args index 2d21c33626..183d6293ad 100644 --- a/repos/base/board/virt_qemu/qemu_args +++ b/repos/base/board/virt_qemu_arm_v7a/qemu_args @@ -1,9 +1,8 @@ -m 2048 +-M virt,virtualization=true -cpu cortex-a15 -smp 2 -global virtio-mmio.force-legacy=false -device virtio-net-device,bus=virtio-mmio-bus.0,netdev=net0 -device virtio-mouse-device -device virtio-keyboard-device -device virtio-gpu-device -netdev user,id=net0 -arm_v8a: -M virt,virtualization=true,gic-version=3 -cpu cortex-a53 -smp 4 -arm_v7a: -M virt,virtualization=true -cpu cortex-a15 -smp 2 diff --git a/repos/base/board/virt_qemu_arm_v8a/qemu_args b/repos/base/board/virt_qemu_arm_v8a/qemu_args new file mode 100644 index 0000000000..a9c9e5f1f4 --- /dev/null +++ b/repos/base/board/virt_qemu_arm_v8a/qemu_args @@ -0,0 +1,8 @@ +-m 2048 +-M virt,virtualization=true,gic-version=3 -cpu cortex-a53 -smp 4 +-global virtio-mmio.force-legacy=false +-device virtio-net-device,bus=virtio-mmio-bus.0,netdev=net0 +-device virtio-mouse-device +-device virtio-keyboard-device +-device virtio-gpu-device +-netdev user,id=net0 diff --git a/repos/base/include/base/affinity.h b/repos/base/include/base/affinity.h index 81d56f2f40..a41bcc4a24 100644 --- a/repos/base/include/base/affinity.h +++ b/repos/base/include/base/affinity.h @@ -189,10 +189,10 @@ class Genode::Affinity Affinity::Space space { }; Affinity::Location location { }; - node.with_sub_node("affinity", [&] (Xml_node const &node) { - node.with_sub_node("space", [&] (Xml_node const &node) { + node.with_optional_sub_node("affinity", [&] (Xml_node const &node) { + node.with_optional_sub_node("space", [&] (Xml_node const &node) { space = Space::from_xml(node); }); - node.with_sub_node("location", [&] (Xml_node const &node) { + node.with_optional_sub_node("location", [&] (Xml_node const &node) { location = Location::from_xml(space, node); }); }); diff --git a/repos/base/include/base/rpc_server.h b/repos/base/include/base/rpc_server.h index 6749849d22..66998550eb 100644 --- a/repos/base/include/base/rpc_server.h +++ b/repos/base/include/base/rpc_server.h @@ -481,6 +481,17 @@ class Genode::Rpc_entrypoint : Thread, public Object_pool * This method is solely needed on Linux. */ bool is_myself() const; + + /** + * Check whether given stack info matches stack of the entrypoint. + * + * \noapi + * + */ + bool myself(addr_t const ptr) const + { + return addr_t(stack_base()) <= ptr && ptr <= addr_t(stack_top()); + } }; diff --git a/repos/base/include/base/trace/buffer.h b/repos/base/include/base/trace/buffer.h index 59222f5e89..4ad84bb640 100644 --- a/repos/base/include/base/trace/buffer.h +++ b/repos/base/include/base/trace/buffer.h @@ -257,6 +257,9 @@ class Genode::Trace::Simple_buffer size_t length() const { return _entry->len; } char const *data() const { return _entry->data; } + template + T const &object() const { return *reinterpret_cast(data()); } + /* return whether entry is valid, i.e. length field is present */ bool last() const { return _entry == 0; } diff --git a/repos/base/include/base/trace/events.h b/repos/base/include/base/trace/events.h index 0b6f61e48a..b5d6026174 100644 --- a/repos/base/include/base/trace/events.h +++ b/repos/base/include/base/trace/events.h @@ -25,6 +25,8 @@ namespace Genode { namespace Trace { struct Rpc_reply; struct Signal_submit; struct Signal_received; + struct Checkpoint; + struct Ethernet_packet; } } @@ -121,4 +123,62 @@ struct Genode::Trace::Signal_received }; +struct Genode::Trace::Checkpoint +{ + enum Type : unsigned char { + UNDEF = 0x0, + START = 0x1, + END = 0x2, + OBJ_NEW = 0x10, + OBJ_DEL = 0x11, + OBJ_STATE = 0x12, + EXCEPTION = 0xfe, + FAILURE = 0xff + }; + + char const *name; + unsigned long const data; + Type const type; + void *addr; + + Checkpoint(char const *name, unsigned long data, void *addr, Type type=Type::UNDEF) + : name(name), data(data), type(type), addr(addr) + { + Thread::trace(this); + } + + size_t generate(Policy_module &policy, char *dst) const { + return policy.checkpoint(dst, name, data, addr, type); } +}; + + +struct Genode::Trace::Ethernet_packet +{ + enum Direction : char { + RECV = 0x0, + SENT = 0x1 + }; + + char const *name; + Direction direction; + char *data; + size_t length; + + Ethernet_packet(char const *name, Direction direction, char *data, size_t len) + : name(name), direction(direction), data(data), length(len) + { + Thread::trace(this); + } + + Ethernet_packet(char const *name, Direction direction, void *data, size_t len) + : name(name), direction(direction), data((char*)data), length(len) + { + Thread::trace(this); + } + + size_t generate(Policy_module &policy, char *dst) const { + return policy.trace_eth_packet(dst, name, direction == Direction::SENT, data, length); } +}; + + #endif /* _INCLUDE__BASE__TRACE__EVENTS_H_ */ diff --git a/repos/base/include/base/trace/policy.h b/repos/base/include/base/trace/policy.h index 969c7ff062..05b8b2dd5a 100644 --- a/repos/base/include/base/trace/policy.h +++ b/repos/base/include/base/trace/policy.h @@ -31,14 +31,16 @@ namespace Genode { */ struct Genode::Trace::Policy_module { - size_t (*max_event_size) (); - size_t (*log_output) (char *, char const *, size_t); - size_t (*rpc_call) (char *, char const *, Msgbuf_base const &); - size_t (*rpc_returned) (char *, char const *, Msgbuf_base const &); - size_t (*rpc_dispatch) (char *, char const *); - size_t (*rpc_reply) (char *, char const *); - size_t (*signal_submit) (char *, unsigned const); - size_t (*signal_received) (char *, Signal_context const &, unsigned const); + size_t (*max_event_size) (); + size_t (*trace_eth_packet) (char *, char const *, bool, char *, size_t); + size_t (*checkpoint) (char *, char const *, unsigned long, void *, unsigned char); + size_t (*log_output) (char *, char const *, size_t); + size_t (*rpc_call) (char *, char const *, Msgbuf_base const &); + size_t (*rpc_returned) (char *, char const *, Msgbuf_base const &); + size_t (*rpc_dispatch) (char *, char const *); + size_t (*rpc_reply) (char *, char const *); + size_t (*signal_submit) (char *, unsigned const); + size_t (*signal_received) (char *, Signal_context const &, unsigned const); }; #endif /* _INCLUDE__BASE__TRACE__POLICY_H_ */ diff --git a/repos/base/include/irq_session/connection.h b/repos/base/include/irq_session/connection.h index 38cb643640..f4b8f85ced 100644 --- a/repos/base/include/irq_session/connection.h +++ b/repos/base/include/irq_session/connection.h @@ -42,6 +42,26 @@ struct Genode::Irq_connection : Connection, Irq_session_client irq, trigger, polarity, device_config_phys)), Irq_session_client(cap()) { } + + /** + * Constructor for label-based configuration (used by pin driver) + * + * \param label session label + */ + Irq_connection(Env &env, + char const *label) + : + Connection(env, session(env.parent(), + "ram_quota=%u, cap_quota=%u, " + "irq_number=%u, irq_trigger=%u, " + "irq_polarity=%u, device_config_phys=0x%lx, " + "label=\"%s\"", + RAM_QUOTA, CAP_QUOTA, 0, + Irq_session::TRIGGER_UNCHANGED, + Irq_session::POLARITY_UNCHANGED, + 0, label)), + Irq_session_client(cap()) + { } }; #endif /* _INCLUDE__IRQ_SESSION__CONNECTION_H_ */ diff --git a/repos/base/include/timer/timeout.h b/repos/base/include/timer/timeout.h index c9fab0c45a..a76178931d 100644 --- a/repos/base/include/timer/timeout.h +++ b/repos/base/include/timer/timeout.h @@ -123,6 +123,8 @@ class Genode::Timeout : private Noncopyable, void discard(); bool scheduled(); + + Microseconds deadline() const { return _deadline; } }; diff --git a/repos/base/include/timer_session/connection.h b/repos/base/include/timer_session/connection.h index cf126ca64b..4f24dea770 100644 --- a/repos/base/include/timer_session/connection.h +++ b/repos/base/include/timer_session/connection.h @@ -117,6 +117,8 @@ class Timer::One_shot_timeout : private Genode::Noncopyable, void discard() { _timeout.discard(); } bool scheduled() { return _timeout.scheduled(); } + + Microseconds deadline() const { return _timeout.deadline(); } }; diff --git a/repos/base/include/trace/probe.h b/repos/base/include/trace/probe.h new file mode 100644 index 0000000000..6a09ea7084 --- /dev/null +++ b/repos/base/include/trace/probe.h @@ -0,0 +1,85 @@ +/* + * \brief Trace probes + * \author Johannes Schlatow + * \date 2021-12-01 + * + * Convenience macros for creating user-defined trace checkpoints. + */ + +/* + * 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 _INCLUDE__TRACE__PROBE_H_ +#define _INCLUDE__TRACE__PROBE_H_ + +#include + +namespace Genode { namespace Trace { + + class Duration + { + private: + + char const *_name; + unsigned long const _data; + + Duration(Duration const &) = delete; + + Duration & operator = (Duration const &) = delete; + + public: + + Duration(char const * name, unsigned long data) + : _name(name), _data(data) + { Checkpoint(_name, _data, nullptr, Checkpoint::Type::START); } + + ~Duration() + { Checkpoint(_name, _data, nullptr, Checkpoint::Type::END); } + }; + +} } + + +/** + * Trace a single checkpoint named after the current function. + * + * The argument 'data' specifies the payload as an unsigned value. + */ +#define GENODE_TRACE_CHECKPOINT(data) \ + Genode::Trace::Checkpoint(__PRETTY_FUNCTION__, (unsigned long)data, nullptr); + + +/** + * Variant of 'GENODE_TRACE_CHECKPOINT' that accepts the name of the checkpoint as argument. + * + * The argument 'data' specifies the payload as an unsigned value. + * The argument 'name' specifies the name of the checkpoint. + */ +#define GENODE_TRACE_CHECKPOINT_NAMED(data, name) \ + Genode::Trace::Checkpoint(name, (unsigned long)data, nullptr); + + +/** + * Trace a pair of checkpoints when entering and leaving the current scope. + * + * The argument 'data' specifies the payload as an unsigned value. + */ +#define GENODE_TRACE_DURATION(data) \ + Genode::Trace::Duration duration(__PRETTY_FUNCTION__, (unsigned long)data); + + +/** + * Variant of 'GENODE_TRACE_DURATION' that accepts the name of the checkpoints as argument. + * + * The argument 'data' specifies the payload as an unsigned value. + * The argument 'name' specifies the names of the checkpoints + */ +#define GENODE_TRACE_DURATION_NAMED(data, name) \ + Genode::Trace::Duration duration(name, (unsigned long)data); + + +#endif /* _INCLUDE__TRACE__PROBE_H_ */ diff --git a/repos/base/include/trace_session/client.h b/repos/base/include/trace_session/client.h index 42276e607e..406bfbd93e 100644 --- a/repos/base/include/trace_session/client.h +++ b/repos/base/include/trace_session/client.h @@ -116,10 +116,6 @@ struct Genode::Trace::Session_client : Genode::Rpc_client(s, p, buffer_size); } - void rule(Session_label const &label, Thread_name const &thread, - Policy_id policy, size_t buffer_size) override { - call(label, thread, policy, buffer_size); } - void pause(Subject_id subject) override { call(subject); } diff --git a/repos/base/include/trace_session/trace_session.h b/repos/base/include/trace_session/trace_session.h index 1657aad55b..3bd61ba442 100644 --- a/repos/base/include/trace_session/trace_session.h +++ b/repos/base/include/trace_session/trace_session.h @@ -64,12 +64,6 @@ struct Genode::Trace::Session : Genode::Session */ virtual void trace(Subject_id, Policy_id, size_t buffer_size) = 0; - /** - * Install a matching rule for automatically tracing new threads - */ - virtual void rule(Session_label const &, Thread_name const &, - Policy_id, size_t buffer_size) = 0; - /** * Pause generation of tracing data * @@ -124,10 +118,6 @@ struct Genode::Trace::Session : Genode::Session Nonexistent_policy, Traced_by_other_session), Subject_id, Policy_id, size_t); - GENODE_RPC_THROW(Rpc_rule, void, rule, - GENODE_TYPE_LIST(Out_of_ram, Out_of_caps), - Session_label const &, Thread_name const &, - Policy_id, size_t); GENODE_RPC_THROW(Rpc_pause, void, pause, GENODE_TYPE_LIST(Nonexistent_subject), Subject_id); GENODE_RPC_THROW(Rpc_resume, void, resume, @@ -144,7 +134,7 @@ struct Genode::Trace::Session : Genode::Session GENODE_TYPE_LIST(Nonexistent_subject), Subject_id); GENODE_RPC_INTERFACE(Rpc_dataspace, Rpc_alloc_policy, Rpc_policy, - Rpc_unload_policy, Rpc_trace, Rpc_rule, Rpc_pause, + Rpc_unload_policy, Rpc_trace, Rpc_pause, Rpc_resume, Rpc_subjects, Rpc_buffer, Rpc_free, Rpc_subject_infos); }; diff --git a/repos/base/include/util/dictionary.h b/repos/base/include/util/dictionary.h new file mode 100644 index 0000000000..c393b0776c --- /dev/null +++ b/repos/base/include/util/dictionary.h @@ -0,0 +1,148 @@ +/* + * \brief Utility for accessing objects by name + * \author Norman Feske + * \date 2022-09-14 + */ + +/* + * Copyright (C) 2022 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 _INCLUDE__UTIL__DICTIONARY_H_ +#define _INCLUDE__UTIL__DICTIONARY_H_ + +#include +#include +#include +#include +#include + +namespace Genode { template class Dictionary; } + + +template +class Genode::Dictionary : Noncopyable +{ + private: + + Avl_tree _tree { }; + + public: + + class Element : private Avl_node + { + public: + + NAME const name; + + private: + + using This = Dictionary::Element; + + Dictionary &_dictionary; + + bool higher(T const *other) const { return name > other->This::name; } + + friend class Avl_tree; + friend class Avl_node; + friend class Dictionary; + + static T *_matching_sub_tree(T &curr, NAME const &name) + { + typename Avl_node::Side side = (curr.This::name > name); + return curr.Avl_node::child(side); + } + + public: + + Element(Dictionary &dictionary, NAME const &name) + : + name(name), _dictionary(dictionary) + { + if (_dictionary.exists(name)) + warning("dictionary entry '", name, "' is not unique"); + + _dictionary._tree.insert(this); + } + + ~Element() + { + _dictionary._tree.remove(this); + } + }; + + /** + * Call 'match_fn' with named constant dictionary element + * + * The 'match_fn' functor is called with a const reference to the + * matching dictionary element. If no maching element exists, + * 'no_match_fn' is called without argument. + */ + template + auto with_element(NAME const &name, FN1 const &match_fn, FN2 const &no_match_fn) + -> typename Trait::Functor::Return_type + { + T *curr_ptr = _tree.first(); + for (;;) { + if (!curr_ptr) + break; + + if (curr_ptr->Element::name == name) { + return match_fn(*curr_ptr); + } + + curr_ptr = Element::_matching_sub_tree(*curr_ptr, name); + } + return no_match_fn(); + } + + /** + * Call 'match_fn' with named mutable dictionary element + * + * The 'match_fn' functor is called with a non-const reference to the + * matching dictionary element. If no maching element exists, + * 'no_match_fn' is called without argument. + */ + template + auto with_element(NAME const &name, FN1 const &match_fn, FN2 const &no_match_fn) const + -> typename Trait::Functor::Return_type + { + auto const_match_fn = [&] (T const &e) { return match_fn(e); }; + auto non_const_this = const_cast(this); + return non_const_this->with_element(name, const_match_fn, no_match_fn); + } + + /** + * Call 'fn' with a non-const reference to any dictionary element + * + * \return true if 'fn' was called, or + * false if the dictionary is empty + * + * This method is intended for the orderly destruction of a dictionary. + * It allows for the consecutive destruction of all elements. + */ + template + bool with_any_element(FUNC const &fn) + { + T *curr_ptr = _tree.first(); + if (!curr_ptr) + return false; + + fn(*curr_ptr); + return true; + } + + template + void for_each(FN const &fn) const { _tree.for_each(fn); } + + bool exists(NAME const &name) const + { + return with_element(name, [] (T const &) { return true; }, + [] { return false; }); + } +}; + +#endif /* _INCLUDE__UTIL__DICTIONARY_H_ */ diff --git a/repos/base/include/util/string.h b/repos/base/include/util/string.h index 683070132e..5eb4eb2162 100644 --- a/repos/base/include/util/string.h +++ b/repos/base/include/util/string.h @@ -459,20 +459,21 @@ namespace Genode { /** - * Read signed long value from string + * Read signed value from string * * \return number of consumed characters */ - inline size_t ascii_to(const char *s, long &result) + template + inline size_t ascii_to_signed(const char *s, T &result) { - int i = 0; + size_t i = 0; /* read sign */ int sign = (*s == '-') ? -1 : 1; if (*s == '-' || *s == '+') { s++; i++; } - unsigned long value = 0; + T value = 0; size_t const j = ascii_to_unsigned(s, value, 0); @@ -484,6 +485,28 @@ namespace Genode { } + /** + * Read signed long value from string + * + * \return number of consumed characters + */ + inline size_t ascii_to(const char *s, long &result) + { + return ascii_to_signed(s, result); + } + + + /** + * Read signed integer value from string + * + * \return number of consumed characters + */ + inline size_t ascii_to(const char *s, int &result) + { + return ascii_to_signed(s, result); + } + + /** * Read 'Number_of_bytes' value from string and handle the size suffixes * @@ -785,6 +808,12 @@ class Genode::String return strcmp(string(), other.string()) != 0; } + template + bool operator > (String const &other) const + { + return strcmp(string(), other.string()) > 0; + } + void print(Output &out) const { Genode::print(out, string()); } }; diff --git a/repos/base/include/util/token.h b/repos/base/include/util/token.h index e67d6e633d..2d60d00b94 100644 --- a/repos/base/include/util/token.h +++ b/repos/base/include/util/token.h @@ -110,7 +110,7 @@ class Genode::Token /** * Access single characters of token */ - char operator [] (int idx) + char operator [] (int idx) const { return ((idx >= 0) && ((unsigned)idx < _len)) ? _start[idx] : 0; } diff --git a/repos/base/include/util/xml_node.h b/repos/base/include/util/xml_node.h index fede99d2b9..7dd4eefd0c 100644 --- a/repos/base/include/util/xml_node.h +++ b/repos/base/include/util/xml_node.h @@ -55,17 +55,16 @@ class Genode::Xml_attribute struct Tokens { Token name; - Token value; + Token equals { name .next().eat_whitespace() }; + Token value { equals.next().eat_whitespace() }; - Tokens(Token t) - : name(t.eat_whitespace()), value(name.next().next()) { }; + Tokens(Token t) : name(t.eat_whitespace()) { }; bool valid() const { - bool const tag_present = (name.type() == Token::IDENT); - bool const value_present = (name.next()[0] == '=' && - value.type() == Token::STRING); - return tag_present && value_present; + return (name.type() == Token::IDENT) + && (equals[0] == '=') + && (value.type() == Token::STRING); } } _tokens; @@ -103,7 +102,7 @@ class Genode::Xml_attribute /** * Return token following the attribute declaration */ - Token _next_token() const { return _tokens.name.next().next().next(); } + Token _next_token() const { return _tokens.value.next(); } public: @@ -355,7 +354,7 @@ class Genode::Xml_node } /** - * Return true if tag as at least one attribute + * Return true if tag has at least one attribute */ bool has_attribute() const { return Xml_attribute::_valid(_name.next()); } @@ -846,12 +845,27 @@ class Genode::Xml_node * If no matching sub node exists, the functor is not called. */ template - void with_sub_node(char const *type, FN const &fn) const + void with_optional_sub_node(char const *type, FN const &fn) const { if (has_sub_node(type)) fn(sub_node(type)); } + /** + * Apply functor 'fn' to first sub node of specified type + * + * The functor is called with the sub node as argument. + * If no matching sub node exists, the functor 'fn_nexists' is called. + */ + template + void with_sub_node(char const *type, FN const &fn, FN_NEXISTS const &fn_nexists) const + { + if (has_sub_node(type)) + fn(sub_node(type)); + else + fn_nexists(); + } + /** * Execute functor 'fn' for each sub node of specified type */ diff --git a/repos/base/lib/mk/ld.mk b/repos/base/lib/mk/ld.mk index 4ba705717b..23fed31558 100644 --- a/repos/base/lib/mk/ld.mk +++ b/repos/base/lib/mk/ld.mk @@ -15,3 +15,6 @@ SHARED_LIB := yes LD_OPT += -T$(BASE_DIR)/src/lib/ldso/linker.ld LIBS += $(addprefix ld-,$(KERNEL)) + +# as the stub libarary is not used at runtime, disregard it as build artifact +BUILD_ARTIFACTS := diff --git a/repos/base/lib/mk/timeout-arm.mk b/repos/base/lib/mk/timeout-arm.mk index e4af0c127f..064e501abd 100644 --- a/repos/base/lib/mk/timeout-arm.mk +++ b/repos/base/lib/mk/timeout-arm.mk @@ -3,6 +3,6 @@ SRC_CC += timer_connection.cc SRC_CC += arm/timer_connection_time.cc SRC_CC += duration.cc -INC_DIR += $(BASE_DIR)/src/include +REP_INC_DIR += src/include -vpath % $(BASE_DIR)/src/lib/timeout +vpath % $(call select_from_repositories,src/lib/timeout) diff --git a/repos/base/lib/mk/timeout.mk b/repos/base/lib/mk/timeout.mk index 5862c2343c..871948edda 100644 --- a/repos/base/lib/mk/timeout.mk +++ b/repos/base/lib/mk/timeout.mk @@ -4,6 +4,6 @@ SRC_CC += timer_connection_time.cc SRC_CC += timer_connection_timestamp.cc SRC_CC += duration.cc -INC_DIR += $(BASE_DIR)/src/include +REP_INC_DIR += src/include vpath % $(call select_from_repositories,src/lib/timeout) diff --git a/repos/base/mk/dep_lib.mk b/repos/base/mk/dep_lib.mk index c788b8ff64..fca6396daa 100644 --- a/repos/base/mk/dep_lib.mk +++ b/repos/base/mk/dep_lib.mk @@ -82,14 +82,19 @@ include $(BASE_DIR)/mk/base-libs.mk include $(LIB_MK) ifdef SHARED_LIB -LIBS += ldso_so_support +BUILD_ARTIFACTS ?= $(LIB).lib.so +endif # record creation of shared library build artifact append_artifact_to_progress_log: - @echo -e "\n# Build artifact $(LIB).lib.so\n" >> $(LIB_PROGRESS_LOG) + @( $(foreach A,$(BUILD_ARTIFACTS),\ + echo -e "\n# Build artifact $A\n";) true \ + ) >> $(LIB_PROGRESS_LOG) append_lib_to_progress_log: append_artifact_to_progress_log -endif +ifdef SHARED_LIB +LIBS += ldso_so_support +endif # # Hide archive dependencies of shared libraries from users of the shared @@ -119,8 +124,9 @@ warn_unsatisfied_requirements: generate_lib_rule_for_defect_library @$(ECHO) "Skip library $(LIB) because it requires $(DARK_COL)$(UNSATISFIED_REQUIREMENTS)$(DEFAULT_COL)" generate_lib_rule_for_defect_library: - @echo "INVALID_DEPS += $(LIB)" >> $(LIB_DEP_FILE) - @echo "" >> $(LIB_DEP_FILE) + @(echo "INVALID_DEPS += $(LIB)"; \ + echo "$(LIB).lib:"; \ + echo "") >> $(LIB_DEP_FILE) LIBS_TO_VISIT = $(filter-out $(LIBS_READY),$(LIBS)) diff --git a/repos/base/mk/prg.mk b/repos/base/mk/prg.mk index 6636d7f99d..3285274a33 100644 --- a/repos/base/mk/prg.mk +++ b/repos/base/mk/prg.mk @@ -183,7 +183,7 @@ $(LINK_ITEMS) $(TARGET): $(HOST_TOOLS) # # Trigger build of additional program specific targets # -$(TARGET): $(CUSTOM_TARGET_DEPS) +all: $(CUSTOM_TARGET_DEPS) LD_CMD += -Wl,--whole-archive -Wl,--start-group LD_CMD += $(LINK_ITEMS_BRIEF) diff --git a/repos/base/ports/grub2.hash b/repos/base/ports/grub2.hash index 7bab68e1ba..9bb012cc65 100644 --- a/repos/base/ports/grub2.hash +++ b/repos/base/ports/grub2.hash @@ -1 +1 @@ -856f9946a1482cbebc519818e3e4736bcd11e5e4 +f15e84afbb47b892ed26a5ae56f5bb038777a3c0 diff --git a/repos/base/ports/grub2.port b/repos/base/ports/grub2.port index e194a3483a..8daa867699 100644 --- a/repos/base/ports/grub2.port +++ b/repos/base/ports/grub2.port @@ -3,7 +3,7 @@ VERSION := git DOWNLOADS := g2fg.git URL(g2fg) := https://github.com/alex-ab/g2fg.git -REV(g2fg) := a0c3164b6b23afb25119f2be8c3b7490c1dcb9e2 +REV(g2fg) := 7da0601946bd2bb75f4e9c3b56cb18e44b2997a1 DIR(g2fg) := boot default: $(DOWNLOADS) diff --git a/repos/base/recipes/api/base/hash b/repos/base/recipes/api/base/hash index 4d1cf22bc1..65319582e1 100644 --- a/repos/base/recipes/api/base/hash +++ b/repos/base/recipes/api/base/hash @@ -1 +1 @@ -2022-05-24 d4b5b53bc270cebd87bf01a93c6da241077aad42 +2022-10-11 1574044ae0ee33a9ad3bdadb3c487c47d4f45bff diff --git a/repos/base/recipes/api/timer_session/hash b/repos/base/recipes/api/timer_session/hash index 29f62381b1..6c61c2e233 100644 --- a/repos/base/recipes/api/timer_session/hash +++ b/repos/base/recipes/api/timer_session/hash @@ -1 +1 @@ -2021-04-19 8628f8283cc104fdfd196d88fb029becaa39b258 +2022-08-16 1f83bc046ed3bb0c4fe6915e608d566dd5483e61 diff --git a/repos/base/recipes/pkg/test-ds_ownership/hash b/repos/base/recipes/pkg/test-ds_ownership/hash index ea2d8baf94..587dda17cb 100644 --- a/repos/base/recipes/pkg/test-ds_ownership/hash +++ b/repos/base/recipes/pkg/test-ds_ownership/hash @@ -1 +1 @@ -2022-05-24 5e486a0f27fdda0a70b9275d62257d98e26589c8 +2022-10-11 b08e70f6de91f200618103ec75f53898c6ef60e8 diff --git a/repos/base/recipes/pkg/test-entrypoint/hash b/repos/base/recipes/pkg/test-entrypoint/hash index 53f437789c..f392de77ae 100644 --- a/repos/base/recipes/pkg/test-entrypoint/hash +++ b/repos/base/recipes/pkg/test-entrypoint/hash @@ -1 +1 @@ -2022-05-24 e35abe047c7ec7fe02c0939de16bfc80ed421d38 +2022-10-11 ad5b85ab1377744e2f747ca2eb5010a3aee87f70 diff --git a/repos/base/recipes/pkg/test-log/hash b/repos/base/recipes/pkg/test-log/hash index b451eee8c5..e4d25877e6 100644 --- a/repos/base/recipes/pkg/test-log/hash +++ b/repos/base/recipes/pkg/test-log/hash @@ -1 +1 @@ -2022-05-24 79d43c7e33381048618dbd7ba6ca34a3eda23f6c +2022-10-11 3e1b9be9b239017a54b6b595cdec5891623ba59f diff --git a/repos/base/recipes/pkg/test-mmio/hash b/repos/base/recipes/pkg/test-mmio/hash index 19ea6f0fc4..63bb8c9fff 100644 --- a/repos/base/recipes/pkg/test-mmio/hash +++ b/repos/base/recipes/pkg/test-mmio/hash @@ -1 +1 @@ -2022-05-24 4b2af7d33e8264d080be962d0a4d9a6404ec4bc0 +2022-10-11 ee3cb10ce306e2afab97018d2bda4e33ce3f863c diff --git a/repos/base/recipes/pkg/test-new_delete/hash b/repos/base/recipes/pkg/test-new_delete/hash index f062e54171..8fdf563d97 100644 --- a/repos/base/recipes/pkg/test-new_delete/hash +++ b/repos/base/recipes/pkg/test-new_delete/hash @@ -1 +1 @@ -2022-05-24 ed1f37d2213211897d5360c9a8f32404d670722a +2022-10-11 dac71b5071da69f218826b2bdc5462b7cf0c28a3 diff --git a/repos/base/recipes/pkg/test-reconstructible/hash b/repos/base/recipes/pkg/test-reconstructible/hash index d7f9a74766..99f66adb70 100644 --- a/repos/base/recipes/pkg/test-reconstructible/hash +++ b/repos/base/recipes/pkg/test-reconstructible/hash @@ -1 +1 @@ -2022-05-24 f09098d18ca36bc8829a673be78dd80460c3d65e +2022-10-11 5f899fc663f34b1c1aeeba243e54edc092aa40fa diff --git a/repos/base/recipes/pkg/test-registry/hash b/repos/base/recipes/pkg/test-registry/hash index 53ada5cd94..ce25cb14f6 100644 --- a/repos/base/recipes/pkg/test-registry/hash +++ b/repos/base/recipes/pkg/test-registry/hash @@ -1 +1 @@ -2022-05-24 3f91b26dbd239c52bb9af22e8f7713743ee851f4 +2022-10-11 50b25d7a4bbde78fc1722a4e822370eb49cb6b95 diff --git a/repos/base/recipes/pkg/test-rm_fault/hash b/repos/base/recipes/pkg/test-rm_fault/hash index 49196a6937..2660982cdc 100644 --- a/repos/base/recipes/pkg/test-rm_fault/hash +++ b/repos/base/recipes/pkg/test-rm_fault/hash @@ -1 +1 @@ -2022-05-24 edbf57617935a054a681e097a611006496ed4c88 +2022-10-11 8882e9bea4fdc16ff4910913a79223d62aeb0cdc diff --git a/repos/base/recipes/pkg/test-rm_fault_no_nox/hash b/repos/base/recipes/pkg/test-rm_fault_no_nox/hash index 877b7bcb89..f0fed0ff13 100644 --- a/repos/base/recipes/pkg/test-rm_fault_no_nox/hash +++ b/repos/base/recipes/pkg/test-rm_fault_no_nox/hash @@ -1 +1 @@ -2022-05-24 ce2c9008ed6ea0db13999e9c6ab77a098d4f94a0 +2022-10-11 a2514b901565ebf0aa88a955c4431fe733964758 diff --git a/repos/base/recipes/pkg/test-rm_nested/hash b/repos/base/recipes/pkg/test-rm_nested/hash index 67b68c9a7d..617c2179b0 100644 --- a/repos/base/recipes/pkg/test-rm_nested/hash +++ b/repos/base/recipes/pkg/test-rm_nested/hash @@ -1 +1 @@ -2022-05-24 afd4f2249a2d56bb6b29b6c0d24923ef2ec215c9 +2022-10-11 3a4ebd01ee612ba2e12ae8df14d6299fb4431375 diff --git a/repos/base/recipes/pkg/test-rm_stress/hash b/repos/base/recipes/pkg/test-rm_stress/hash index 3d9787edac..a7c6d8a6d0 100644 --- a/repos/base/recipes/pkg/test-rm_stress/hash +++ b/repos/base/recipes/pkg/test-rm_stress/hash @@ -1 +1 @@ -2022-05-24 436a166f1c4371619d7a64bf879dd0ce2dc75429 +2022-10-11 5ac901826381a7d6de528cd3d3520b0767385f6c diff --git a/repos/base/recipes/pkg/test-sanitizer/hash b/repos/base/recipes/pkg/test-sanitizer/hash index 3662cf1783..655a1c5294 100644 --- a/repos/base/recipes/pkg/test-sanitizer/hash +++ b/repos/base/recipes/pkg/test-sanitizer/hash @@ -1 +1 @@ -2022-05-24 3877f6f98ff7c3921bdb7b2b83f40a161e9cd5bb +2022-10-11 36717c21923ac35c938ad73930f1d1576ecaf385 diff --git a/repos/base/recipes/pkg/test-stack_smash/hash b/repos/base/recipes/pkg/test-stack_smash/hash index bc4fb94d4a..3c46805904 100644 --- a/repos/base/recipes/pkg/test-stack_smash/hash +++ b/repos/base/recipes/pkg/test-stack_smash/hash @@ -1 +1 @@ -2022-05-24 00a8e3979871b2a0ab67088c3d2b57454ed653f9 +2022-10-11 b8e011ab9a1ae92c4293ab07f9a6b7df71c6aabc diff --git a/repos/base/recipes/pkg/test-synced_interface/hash b/repos/base/recipes/pkg/test-synced_interface/hash index aaff8bb4c0..053c382dc6 100644 --- a/repos/base/recipes/pkg/test-synced_interface/hash +++ b/repos/base/recipes/pkg/test-synced_interface/hash @@ -1 +1 @@ -2022-05-24 ab7b5f631d4abf8b01ed6b08c4da83b4164564a8 +2022-10-11 0a151f72dc20e2e6b8cca80b761128dee92bb7c5 diff --git a/repos/base/recipes/pkg/test-timer/hash b/repos/base/recipes/pkg/test-timer/hash index 15136b90af..56f8cf4688 100644 --- a/repos/base/recipes/pkg/test-timer/hash +++ b/repos/base/recipes/pkg/test-timer/hash @@ -1 +1 @@ -2022-05-24 91ed52185381c38cf7e425fb0c351b46c4548b4f +2022-10-11 8070010a6f4553f3be84c5fbe0729f50e5d3fde0 diff --git a/repos/base/recipes/pkg/test-tls/hash b/repos/base/recipes/pkg/test-tls/hash index f185bc03db..eb94a8999b 100644 --- a/repos/base/recipes/pkg/test-tls/hash +++ b/repos/base/recipes/pkg/test-tls/hash @@ -1 +1 @@ -2022-05-24 7ff4d04d0b470eb6974b633bb0dca1212158f625 +2022-10-11 5068ceee7e2285a398ac7b6936f6d16c8daa29ea diff --git a/repos/base/recipes/pkg/test-token/hash b/repos/base/recipes/pkg/test-token/hash index 4e94f5e5d6..513c91136b 100644 --- a/repos/base/recipes/pkg/test-token/hash +++ b/repos/base/recipes/pkg/test-token/hash @@ -1 +1 @@ -2022-05-24 b96b88fee3e0946fea12a44cea94963b2b16d173 +2022-10-11 c4e1fb742ffc41fdb81aeb2ca2638ca81459578d diff --git a/repos/base/recipes/pkg/test-xml_generator/hash b/repos/base/recipes/pkg/test-xml_generator/hash index 0340fa2e62..01508ca781 100644 --- a/repos/base/recipes/pkg/test-xml_generator/hash +++ b/repos/base/recipes/pkg/test-xml_generator/hash @@ -1 +1 @@ -2022-05-24 c2d9a2849fe51277372d301c9a46d034c4674ab9 +2022-10-11 f44af3d8cc1af7801408f855c1c8c168c8d84aa7 diff --git a/repos/base/recipes/pkg/test-xml_node/hash b/repos/base/recipes/pkg/test-xml_node/hash index 09ab49e610..fc516acfbc 100644 --- a/repos/base/recipes/pkg/test-xml_node/hash +++ b/repos/base/recipes/pkg/test-xml_node/hash @@ -1 +1 @@ -2022-05-24 88eb29b90a1e663e1f58de04a6a178f3a035f3f5 +2022-10-11 682420bf32f10e223946d7713bf70255ede1d451 diff --git a/repos/base/recipes/pkg/test-xml_node/runtime b/repos/base/recipes/pkg/test-xml_node/runtime index 080a24193b..e526210460 100644 --- a/repos/base/recipes/pkg/test-xml_node/runtime +++ b/repos/base/recipes/pkg/test-xml_node/runtime @@ -99,6 +99,9 @@ [init -> test-xml_node] -- Test backslash as attribute value -- [init -> test-xml_node] attribute value: '\' [init -> test-xml_node] + [init -> test-xml_node] -- Test whitespace around assignment character -- + [init -> test-xml_node] attribute value: '123' + [init -> test-xml_node] [init -> test-xml_node] -- Test exporting decoded content from XML node -- [init -> test-xml_node] step 1 [init -> test-xml_node] step 2 diff --git a/repos/base/recipes/src/test-ds_ownership/hash b/repos/base/recipes/src/test-ds_ownership/hash index 4dcb62cd3d..cd73f3f0ac 100644 --- a/repos/base/recipes/src/test-ds_ownership/hash +++ b/repos/base/recipes/src/test-ds_ownership/hash @@ -1 +1 @@ -2022-05-24 715bfaa6ea0bff54c0e2477c1bbccf56c0bfc935 +2022-10-11 359a8ba82f0a85f6f83c2e140120e0ec2fc2ff4b diff --git a/repos/base/recipes/src/test-entrypoint/hash b/repos/base/recipes/src/test-entrypoint/hash index 066abed7fa..9ea1110839 100644 --- a/repos/base/recipes/src/test-entrypoint/hash +++ b/repos/base/recipes/src/test-entrypoint/hash @@ -1 +1 @@ -2022-05-24 05d5db1ec0b7fff36e8526fe701873731fd08660 +2022-10-11 5a9a370fb5f6483aa652fd13e805f8970580d8d7 diff --git a/repos/base/recipes/src/test-log/hash b/repos/base/recipes/src/test-log/hash index c2a6422cbb..bf465ce443 100644 --- a/repos/base/recipes/src/test-log/hash +++ b/repos/base/recipes/src/test-log/hash @@ -1 +1 @@ -2022-05-24 7d26fbbb584ab24b8156eda78a8eca5bc9e1122f +2022-10-11 095026fa1d5dc144f0d2bd21f3b0aad4c1ddacbd diff --git a/repos/base/recipes/src/test-mmio/hash b/repos/base/recipes/src/test-mmio/hash index f51cd1f6dc..6247eefd30 100644 --- a/repos/base/recipes/src/test-mmio/hash +++ b/repos/base/recipes/src/test-mmio/hash @@ -1 +1 @@ -2022-05-24 6542fc1df645f45c9fc71b5c18b458a9e630470d +2022-10-11 2fc5a59b9a18db38188c8f0b5cd140f8af25debf diff --git a/repos/base/recipes/src/test-new_delete/hash b/repos/base/recipes/src/test-new_delete/hash index 2235c35484..196fd52868 100644 --- a/repos/base/recipes/src/test-new_delete/hash +++ b/repos/base/recipes/src/test-new_delete/hash @@ -1 +1 @@ -2022-05-24 67caefb3bbf5926dbd2ca46bbe933882de542db3 +2022-10-11 4b8f0df83f00b36d32640a767a861327034e51ed diff --git a/repos/base/recipes/src/test-reconstructible/hash b/repos/base/recipes/src/test-reconstructible/hash index a21bfcb092..62b89f129b 100644 --- a/repos/base/recipes/src/test-reconstructible/hash +++ b/repos/base/recipes/src/test-reconstructible/hash @@ -1 +1 @@ -2022-05-24 915f8bebfcdbfe4ef499ea94985303bacebeb8e8 +2022-10-11 03229606efad94460265721c6f828fdf4f1c1e36 diff --git a/repos/base/recipes/src/test-registry/hash b/repos/base/recipes/src/test-registry/hash index 400b893782..dd85d8a1ff 100644 --- a/repos/base/recipes/src/test-registry/hash +++ b/repos/base/recipes/src/test-registry/hash @@ -1 +1 @@ -2022-05-24 e1e3559b2f3010d96d19e81cbaa6abbeb07c6251 +2022-10-11 3a9a202788b631072f5bc4a6220083ea3f0804ee diff --git a/repos/base/recipes/src/test-rm_fault/hash b/repos/base/recipes/src/test-rm_fault/hash index 27bdb498e9..8bb4d51590 100644 --- a/repos/base/recipes/src/test-rm_fault/hash +++ b/repos/base/recipes/src/test-rm_fault/hash @@ -1 +1 @@ -2022-05-24 93812b90ee88b44d4fc3b26af77ad0344359e51a +2022-10-11 31d8bd8cf827651dc7996e6d3ca7b005ddc0bdcd diff --git a/repos/base/recipes/src/test-rm_nested/hash b/repos/base/recipes/src/test-rm_nested/hash index 07f64a4053..86599133e2 100644 --- a/repos/base/recipes/src/test-rm_nested/hash +++ b/repos/base/recipes/src/test-rm_nested/hash @@ -1 +1 @@ -2022-05-24 465cc6225756312ca657c39d5a398fd276088118 +2022-10-11 c81db79ecd943606a3113aad3e804c715fc33a1c diff --git a/repos/base/recipes/src/test-rm_stress/hash b/repos/base/recipes/src/test-rm_stress/hash index 92fcbd61b0..68e858396b 100644 --- a/repos/base/recipes/src/test-rm_stress/hash +++ b/repos/base/recipes/src/test-rm_stress/hash @@ -1 +1 @@ -2022-05-24 dd009dd4ea58101e1c15e5bd38cad4241f726fa4 +2022-10-11 ef88b5f407d0b49926354c8144d2322b778dfcad diff --git a/repos/base/recipes/src/test-sanitizer/hash b/repos/base/recipes/src/test-sanitizer/hash index 0cb0636545..2423895026 100644 --- a/repos/base/recipes/src/test-sanitizer/hash +++ b/repos/base/recipes/src/test-sanitizer/hash @@ -1 +1 @@ -2022-05-24 34b25aabaef3112a38eb0a24a13cf6e42da6ba65 +2022-10-11 27a1948a58c15301b3e1978f409ce9b076d704bc diff --git a/repos/base/recipes/src/test-segfault/hash b/repos/base/recipes/src/test-segfault/hash index 35e8c15921..f409498935 100644 --- a/repos/base/recipes/src/test-segfault/hash +++ b/repos/base/recipes/src/test-segfault/hash @@ -1 +1 @@ -2022-05-24 632e59190a6bcfe40a5a88ecff9f05e2924a43b1 +2022-10-11 29971db890cb657bb8d41bf07636ba21752ca8b3 diff --git a/repos/base/recipes/src/test-stack_smash/hash b/repos/base/recipes/src/test-stack_smash/hash index 8d2194a103..8202e3d036 100644 --- a/repos/base/recipes/src/test-stack_smash/hash +++ b/repos/base/recipes/src/test-stack_smash/hash @@ -1 +1 @@ -2022-05-24 4e254230305117e2ce5dd2c13caa650ea65251e7 +2022-10-11 483ee9045181e9912f60834b45436d0226763bb8 diff --git a/repos/base/recipes/src/test-synced_interface/hash b/repos/base/recipes/src/test-synced_interface/hash index 7ef1668a45..87e2688cb7 100644 --- a/repos/base/recipes/src/test-synced_interface/hash +++ b/repos/base/recipes/src/test-synced_interface/hash @@ -1 +1 @@ -2022-05-24 f9126bd0df2b402150c7ef76138d5ecb8cee05d4 +2022-10-11 bdabeb64387faee3c5307377d72bcb99f4086f00 diff --git a/repos/base/recipes/src/test-timer/hash b/repos/base/recipes/src/test-timer/hash index f49d5f06e7..80fa15879a 100644 --- a/repos/base/recipes/src/test-timer/hash +++ b/repos/base/recipes/src/test-timer/hash @@ -1 +1 @@ -2022-05-24 402acbf040b8f905dcc0979700f6077d36dc707d +2022-10-11 18675e4c9e59c67edede9b4c0eb0eb8bd8ff56d2 diff --git a/repos/base/recipes/src/test-tls/hash b/repos/base/recipes/src/test-tls/hash index 824a9dd8ab..26715c617c 100644 --- a/repos/base/recipes/src/test-tls/hash +++ b/repos/base/recipes/src/test-tls/hash @@ -1 +1 @@ -2022-05-24 4ddec10779302c6d0c47ccbeba806fe1278e182b +2022-10-11 e0674b3ea25b560f92bfe65b9ccbed95c3119665 diff --git a/repos/base/recipes/src/test-token/hash b/repos/base/recipes/src/test-token/hash index da0f7e3805..efd237b5be 100644 --- a/repos/base/recipes/src/test-token/hash +++ b/repos/base/recipes/src/test-token/hash @@ -1 +1 @@ -2022-05-24 f04c4162857259fd48d864e9076ae401c9093dbb +2022-10-11 6b24a7f9187ca2e87c5acffd6cd61c63bca52477 diff --git a/repos/base/recipes/src/test-xml_generator/hash b/repos/base/recipes/src/test-xml_generator/hash index 7ac579a8e7..0858b2605a 100644 --- a/repos/base/recipes/src/test-xml_generator/hash +++ b/repos/base/recipes/src/test-xml_generator/hash @@ -1 +1 @@ -2022-05-24 e91f2b05a682df2206b8f487b7cb01cc8150350e +2022-10-11 be8b5157c899db1007904028d0f77dc50acc1a7f diff --git a/repos/base/recipes/src/test-xml_node/hash b/repos/base/recipes/src/test-xml_node/hash index d9feccf844..4dd2a34d95 100644 --- a/repos/base/recipes/src/test-xml_node/hash +++ b/repos/base/recipes/src/test-xml_node/hash @@ -1 +1 @@ -2022-05-24 39a7ce53177b2bad4928846f40b8ef542d8f6840 +2022-10-11 53ba6ffafbcb4b78411e4117bbc3e7e3d721f20e diff --git a/repos/base/run/platform_drv.inc b/repos/base/run/platform_drv.inc index c442dff71d..3da9f74d87 100644 --- a/repos/base/run/platform_drv.inc +++ b/repos/base/run/platform_drv.inc @@ -188,6 +188,7 @@ proc platform_drv_config {} { + } diff --git a/repos/base/src/core/include/trace/session_component.h b/repos/base/src/core/include/trace/session_component.h index d115784ff6..dbdafbb847 100644 --- a/repos/base/src/core/include/trace/session_component.h +++ b/repos/base/src/core/include/trace/session_component.h @@ -78,7 +78,6 @@ class Genode::Trace::Session_component Dataspace_capability policy(Policy_id) override; void unload_policy(Policy_id) override; void trace(Subject_id, Policy_id, size_t) override; - void rule(Session_label const &, Thread_name const &, Policy_id, size_t) override; void pause(Subject_id) override; void resume(Subject_id) override; Dataspace_capability buffer(Subject_id) override; diff --git a/repos/base/src/core/trace_session_component.cc b/repos/base/src/core/trace_session_component.cc index 58308242ef..235da3555e 100644 --- a/repos/base/src/core/trace_session_component.cc +++ b/repos/base/src/core/trace_session_component.cc @@ -127,13 +127,6 @@ void Session_component::trace(Subject_id subject_id, Policy_id policy_id, } -void Session_component::rule(Session_label const &, Thread_name const &, - Policy_id, size_t) -{ - /* not implemented yet */ -} - - void Session_component::pause(Subject_id subject_id) { _subjects.lookup_by_id(subject_id).pause(); diff --git a/repos/base/src/lib/base/mutex.cc b/repos/base/src/lib/base/mutex.cc index f7bcfd8357..520617dec1 100644 --- a/repos/base/src/lib/base/mutex.cc +++ b/repos/base/src/lib/base/mutex.cc @@ -29,7 +29,7 @@ void Genode::Mutex::release() { Lock::Applicant myself(Thread::myself()); if (!_lock.lock_owner(myself)) { - Genode::error("denied non mutex owner the release, mutex=", + Genode::error("release denied, caller not owner, mutex=", this, ", return ip=", __builtin_return_address(0)); return; } diff --git a/repos/base/src/lib/ldso/include/config.h b/repos/base/src/lib/ldso/include/config.h index 5708df0930..2ad11c87a2 100644 --- a/repos/base/src/lib/ldso/include/config.h +++ b/repos/base/src/lib/ldso/include/config.h @@ -68,7 +68,7 @@ class Linker::Config : Noncopyable template void for_each_library(FN const &fn) const { - _config.with_sub_node("ld", [&] (Xml_node ld) { + _config.with_optional_sub_node("ld", [&] (Xml_node ld) { ld.for_each_sub_node("library", [&] (Xml_node lib) { diff --git a/repos/base/src/lib/target.mk b/repos/base/src/lib/target.mk deleted file mode 100644 index c7315d49ca..0000000000 --- a/repos/base/src/lib/target.mk +++ /dev/null @@ -1,33 +0,0 @@ -# -# This is a dummy target description file with the sole purpose of building -# all libraries. -# -TARGET = libs - -# -# Determine all 'lib/mk' sub directories residing within the repositories. -# Use 'wildcard' to handle the case when a repository does not host any -# 'lib/mk' sub directory. -# -LIB_MK_DIRS := $(wildcard $(addsuffix /lib/mk,$(REPOSITORIES))) - -# -# Scan the 'lib/mk' directories of all repositories for library description -# files. -# -ALL_LIB_MK_FILES := $(notdir $(foreach DIR,$(LIB_MK_DIRS),$(shell find $(DIR) -name "*.mk"))) - -# -# Make the pseudo target depend on all libraries, for which an lib.mk file -# exists. Discard the '.mk' suffix and remove duplicates (via 'sort'). -# -LIBS = $(sort $(ALL_LIB_MK_FILES:.mk=)) - -# -# Among all libraries found above, there may be several libraries with -# unsatisfied build requirements. Normally, the build system won't attempt to -# build the target (and its library dependencies) if one or more libraries -# cannot be built. By enabling 'FORCE_BUILD_LIBS', we let the build system -# visit all non-invalid libraries even in the presence of invalid libraries. -# -FORCE_BUILD_LIBS = yes diff --git a/repos/base/src/test/xml_node/test.cc b/repos/base/src/test/xml_node/test.cc index 494cdabd6b..4d26d66147 100644 --- a/repos/base/src/test/xml_node/test.cc +++ b/repos/base/src/test/xml_node/test.cc @@ -152,6 +152,10 @@ static const char *xml_test_comments = static const char *xml_test_backslash = ""; +/* withspace around attribute assignment character */ +static const char *xml_test_whitespace_assign = + ""; + /****************** ** Test program ** @@ -415,6 +419,12 @@ void Component::construct(Genode::Env &env) log("attribute value: '", node.attribute_value("attr", String<10>()), "'\n"); } + log("-- Test whitespace around assignment character --"); + { + Xml_node const node(xml_test_whitespace_assign); + log("attribute value: '", node.attribute_value("attr", String<10>()), "'\n"); + } + log("-- Test exporting decoded content from XML node --"); test_decoded_content<~0UL>(env, 1, xml_test_comments, 8, 119); test_decoded_content<119 >(env, 2, xml_test_comments, 8, 119); diff --git a/repos/dde_bsd/README b/repos/dde_bsd/README index 9bdd3e131c..9f30b6d92c 100644 --- a/repos/dde_bsd/README +++ b/repos/dde_bsd/README @@ -4,10 +4,8 @@ Audio ##### The audio driver is ported from OpenBSD 6.6 and includes support for -Intel HD Audio, ICH as well as for Ensoniq AudioPCI (ES1370) compatible -soundcards. The HDA driver works on real hardware and Virtualbox -whereas the ES1370 driver is only used in Qemu. The ICH driver is only -tested in Virtualbox where it produces audible artifacts. +Intel HD Audio devices. The HDA driver works on real hardware and +supposedly in VirtualBox. Usage and configuration diff --git a/repos/dde_bsd/audio.list b/repos/dde_bsd/audio.list index fa48dbcc7a..af13f3c404 100644 --- a/repos/dde_bsd/audio.list +++ b/repos/dde_bsd/audio.list @@ -1,18 +1,13 @@ sys/lib/libkern/strlcpy.c sys/dev/audio.c sys/dev/audio_if.h -sys/dev/pci/auich.c sys/dev/pci/azalia.c sys/dev/pci/azalia.h sys/dev/pci/azalia_codec.c -sys/dev/pci/eap.c -sys/dev/pci/eapreg.h sys/dev/pci/pcidevs.h sys/dev/pci/pcidevs_data.h sys/dev/mulaw.c sys/dev/mulaw.h -sys/dev/ic/ac97.c -sys/dev/ic/ac97.h sys/sys/audioio.h sys/sys/device.h sys/sys/queue.h diff --git a/repos/dde_bsd/lib/mk/dde_bsd_audio.inc b/repos/dde_bsd/lib/mk/dde_bsd_audio.inc index 2bb34dc03c..75a3b1d454 100644 --- a/repos/dde_bsd/lib/mk/dde_bsd_audio.inc +++ b/repos/dde_bsd/lib/mk/dde_bsd_audio.inc @@ -13,7 +13,7 @@ INC_DIR += $(AUDIO_CONTRIB_DIR) LIBS += dde_bsd_audio_include -SRC_CC += dummies.cc driver.cc irq.cc mem.cc misc.cc scheduler.cc timer.cc +SRC_CC += dummies.cc driver.cc mem.cc misc.cc scheduler.cc timer.cc SRC_C += bsd_emul.c SRC_S += setjmp.S diff --git a/repos/dde_bsd/lib/mk/dde_bsd_audio_pci.inc b/repos/dde_bsd/lib/mk/dde_bsd_audio_pci.inc new file mode 100644 index 0000000000..448f2f3c94 --- /dev/null +++ b/repos/dde_bsd/lib/mk/dde_bsd_audio_pci.inc @@ -0,0 +1,13 @@ +include $(REP_DIR)/lib/mk/dde_bsd_audio.inc + +SRC_C += bsd_emul_pci.c +SRC_CC += pci.cc + +# enable when debugging +#CC_OPT += -DAZALIA_DEBUG +#CC_OPT += -DDIAGNOSTIC + +# HDA driver +SRC_C += dev/pci/azalia.c dev/pci/azalia_codec.c + +# vi: set ft=make : diff --git a/repos/dde_bsd/lib/mk/dde_bsd_audio_pci.mk b/repos/dde_bsd/lib/mk/dde_bsd_audio_pci.mk deleted file mode 100644 index 6518114a49..0000000000 --- a/repos/dde_bsd/lib/mk/dde_bsd_audio_pci.mk +++ /dev/null @@ -1,49 +0,0 @@ -LIB_DIR = $(REP_DIR)/src/lib/audio -LIB_INC_DIR = $(LIB_DIR)/include - -AUDIO_CONTRIB_DIR := $(call select_from_ports,dde_bsd)/src/lib/audio - -# -# Set include paths up before adding the dde_bsd_audio_include library -# because it will use INC_DIR += and must be at the end -# -INC_DIR += $(LIB_DIR) -INC_DIR += $(LIB_INC_DIR) -INC_DIR += $(AUDIO_CONTRIB_DIR) - -LIBS += dde_bsd_audio_include - -SRC_C := bsd_emul_pci.c -SRC_CC += pci.cc - -CC_OPT += -Wno-unused-but-set-variable - -# disable builtins -CC_OPT += -fno-builtin-printf -fno-builtin-snprintf -fno-builtin-vsnprintf \ - -fno-builtin-malloc -fno-builtin-free -fno-builtin-log -fno-builtin-log2 - -CC_OPT += -D_KERNEL - -# enable when debugging -#CC_OPT += -DAC97_DEBUG -#CC_OPT += -DAUICH_DEBUG -#CC_OPT += -DAZALIA_DEBUG -#CC_OPT += -DDIAGNOSTIC - -# AC97 codec -SRC_C += dev/ic/ac97.c - -# HDA driver -SRC_C += dev/pci/azalia.c dev/pci/azalia_codec.c - -# ICH driver -SRC_C += dev/pci/auich.c - -# ES1370 -SRC_C += dev/pci/eap.c - -vpath %.c $(AUDIO_CONTRIB_DIR) -vpath %.c $(LIB_DIR) -vpath %.cc $(LIB_DIR) - -# vi: set ft=make : diff --git a/repos/dde_bsd/lib/mk/spec/x86_32/dde_bsd_audio.mk b/repos/dde_bsd/lib/mk/spec/x86_32/dde_bsd_audio.mk index 98f3796d58..357ca1c22c 100644 --- a/repos/dde_bsd/lib/mk/spec/x86_32/dde_bsd_audio.mk +++ b/repos/dde_bsd/lib/mk/spec/x86_32/dde_bsd_audio.mk @@ -1,6 +1,6 @@ INC_DIR += $(LIB_INC_DIR)/spec/x86_32 $(LIB_INC_DIR)/spec/x86 -include $(REP_DIR)/lib/mk/dde_bsd_audio.inc +include $(REP_DIR)/lib/mk/dde_bsd_audio_pci.inc vpath %.S $(LIB_DIR)/spec/x86_32 diff --git a/repos/dde_bsd/lib/mk/spec/x86_64/dde_bsd_audio.mk b/repos/dde_bsd/lib/mk/spec/x86_64/dde_bsd_audio.mk index fe3e57dfae..e573623a53 100644 --- a/repos/dde_bsd/lib/mk/spec/x86_64/dde_bsd_audio.mk +++ b/repos/dde_bsd/lib/mk/spec/x86_64/dde_bsd_audio.mk @@ -1,6 +1,6 @@ INC_DIR += $(LIB_INC_DIR)/spec/x86_64 $(LIB_INC_DIR)/spec/x86 -include $(REP_DIR)/lib/mk/dde_bsd_audio.inc +include $(REP_DIR)/lib/mk/dde_bsd_audio_pci.inc vpath %.S $(LIB_DIR)/spec/x86_64 diff --git a/repos/dde_bsd/patches/attach.patch b/repos/dde_bsd/patches/attach.patch new file mode 100644 index 0000000000..e1a4f9fd5f --- /dev/null +++ b/repos/dde_bsd/patches/attach.patch @@ -0,0 +1,14 @@ +To signal an successful attach attempt we set the ref counter +of the parent, i.e., the dummy pci bus and check that in our +'probe_cfdata' function. + +--- a/dev/pci/azalia.c ++++ b/dev/pci/azalia.c +@@ -591,6 +591,7 @@ + + audio_attach_mi(&azalia_hw_if, sc, NULL, &sc->dev); + ++ parent->dv_ref = 1; + return; + + err_exit: diff --git a/repos/dde_bsd/patches/azalia_c.patch b/repos/dde_bsd/patches/azalia_c.patch deleted file mode 100644 index 2c0526d870..0000000000 --- a/repos/dde_bsd/patches/azalia_c.patch +++ /dev/null @@ -1,55 +0,0 @@ ---- a/dev/pci/azalia.c -+++ b/dev/pci/azalia.c -@@ -492,7 +492,7 @@ - azalia_t *sc; - struct pci_attach_args *pa; - pcireg_t v; -- uint8_t reg; -+ // uint8_t reg; - pci_intr_handle_t ih; - const char *interrupt_str; - -@@ -518,12 +518,18 @@ - - azalia_configure_pci(sc); - -- /* disable MSI, use INTx instead */ -- if (PCI_VENDOR(sc->pciid) == PCI_VENDOR_INTEL) { -- reg = azalia_pci_read(sc->pc, sc->tag, ICH_PCI_MMC); -- reg &= ~(ICH_PCI_MMC_ME); -- azalia_pci_write(sc->pc, sc->tag, ICH_PCI_MMC, reg); -- } -+ // This was added in CVS rev 1.168 because certain devices do not -+ // support MSIs. For reasons that are not clear yet, this breaks -+ // when using the platform_drv on x86 with MSI support and IOMMU -+ // enabled. All hw we tested seems to work fine when it is removed, -+ // even older kernels, e.g. OKL4, that use legacy IRQs, -+ // -+ // /* disable MSI, use INTx instead */ -+ // if (PCI_VENDOR(sc->pciid) == PCI_VENDOR_INTEL) { -+ // reg = azalia_pci_read(sc->pc, sc->tag, ICH_PCI_MMC); -+ // reg &= ~(ICH_PCI_MMC_ME); -+ // azalia_pci_write(sc->pc, sc->tag, ICH_PCI_MMC, reg); -+ // } - - /* disable MSI for AMD Summit Ridge/Raven Ridge HD Audio */ - if (PCI_VENDOR(sc->pciid) == PCI_VENDOR_AMD) { -@@ -3973,6 +3979,10 @@ - azalia_set_blksz(void *v, int mode, - struct audio_params *p, struct audio_params *r, unsigned int blksz) - { -+ // XXX using mult leads to a blksz of 416 in case of a -+ // requested blksz of 441 which in return results in distored -+ // playback. -+#if 0 - int mult; - - /* must be multiple of 128 bytes */ -@@ -3981,6 +3991,7 @@ - blksz -= blksz % mult; - if (blksz == 0) - blksz = mult; -+#endif - - return blksz; - } diff --git a/repos/dde_bsd/patches/azalia_codec_c.patch b/repos/dde_bsd/patches/azalia_codec_c.patch deleted file mode 100644 index 06b26f6677..0000000000 --- a/repos/dde_bsd/patches/azalia_codec_c.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- a/dev/pci/azalia_codec.c -+++ b/dev/pci/azalia_codec.c -@@ -83,6 +83,13 @@ - this->name = "Realtek ALC221"; - this->qrks |= AZ_QRK_WID_CDIN_1C | AZ_QRK_WID_BEEP_1D; - break; -+ case 0x10ec0255: -+ this->name = "Realtek ALC255"; -+ DPRINTF(("Realtek ALC255 0x%8x\n", this->subid)); -+ if (this->subid == 0x193e10cf) { /* FUJITSU S938 */ -+ this->qrks |= AZ_QRK_WID_HEADSET; -+ } -+ break; - case 0x10ec0260: - this->name = "Realtek ALC260"; - if (this->subid == 0x008f1025) -@@ -656,6 +663,10 @@ - CORB_GET_PIN_SENSE, 0, &result); - if (!err && (result & CORB_PS_PRESENCE)) - vol = 1; -+ -+ // switch microphone to mic2 -+ if (!err) -+ notify_hp_sense(result & CORB_PS_PRESENCE); - } - if (err) - break; -@@ -2590,6 +2601,14 @@ - w->enable = 1; - } - -+ if (this->qrks & AZ_QRK_WID_HEADSET && -+ nid == 0x19) { -+ /* Fujitsu S398 headphone jack */ -+ w->d.pin.config = 0x03a19120; -+ azalia_pin_config_ov(w, CORB_CD_DEVICE_MASK, CORB_CD_MICIN); -+ w->enable = 1; -+ } -+ - if (this->qrks & AZ_QRK_WID_CDIN_1C && - nid == 0x1c && w->enable == 0 && w->d.pin.device == CORB_CD_CD) { - azalia_pin_config_ov(w, CORB_CD_PORT_MASK, CORB_CD_FIXED); diff --git a/repos/dde_bsd/patches/azalia_h.patch b/repos/dde_bsd/patches/azalia_h.patch deleted file mode 100644 index 7cfe946401..0000000000 --- a/repos/dde_bsd/patches/azalia_h.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/dev/pci/azalia.h -+++ b/dev/pci/azalia.h -@@ -513,6 +513,7 @@ - #define AZ_QRK_WID_TPDOCK1 0x00010000 - #define AZ_QRK_WID_TPDOCK2 0x00020000 - #define AZ_QRK_WID_TPDOCK3 0x00040000 -+#define AZ_QRK_WID_HEADSET 0x00080000 - #define AZ_QRK_WID_DOLBY_ATMOS 0x00100000 - #define AZ_QRK_WID_SPKR2_DAC 0x00200000 - diff --git a/repos/dde_bsd/patches/halt_corb.patch b/repos/dde_bsd/patches/halt_corb.patch new file mode 100644 index 0000000000..9c313a7151 --- /dev/null +++ b/repos/dde_bsd/patches/halt_corb.patch @@ -0,0 +1,25 @@ +--- a/dev/pci/azalia.c ++++ b/dev/pci/azalia.c +@@ -1063,10 +1063,6 @@ + uint16_t corbrp, corbwp; + uint8_t corbctl; + +- err = azalia_halt_corb(az); +- if (err) +- return(err); +- + if (!resuming) { + err = azalia_alloc_dmamem(az, + az->corb_entries * sizeof(corb_entry_t), 128, +@@ -1079,6 +1075,11 @@ + } + timeout_set(&az->unsol_to, azalia_rirb_kick_unsol_events, az); + ++ /* do after the allocation as it will access 'corb_dma' */ ++ err = azalia_halt_corb(az); ++ if (err) ++ return(err); ++ + AZ_WRITE_4(az, CORBLBASE, (uint32_t)AZALIA_DMA_DMAADDR(&az->corb_dma)); + AZ_WRITE_4(az, CORBUBASE, PTR_UPPER32(AZALIA_DMA_DMAADDR(&az->corb_dma))); + AZ_WRITE_1(az, CORBSIZE, az->corbsize); diff --git a/repos/dde_bsd/patches/notify.patch b/repos/dde_bsd/patches/notify.patch index fa15ae5e63..17f069cf16 100644 --- a/repos/dde_bsd/patches/notify.patch +++ b/repos/dde_bsd/patches/notify.patch @@ -1,19 +1,20 @@ -diff --git a/dev/audio.c b/dev/audio.c -index 1271bc7..6535d10 100644 +Instead of implementing softintr handling add our notification +functions directly. + --- a/dev/audio.c +++ b/dev/audio.c -@@ -411,6 +411,8 @@ audio_pintr(void *addr) - } - selwakeup(&sc->play.sel); +@@ -572,6 +572,8 @@ audio_pintr(void *addr) + */ + softintr_schedule(sc->play.softintr); } + + notify_play(); } /* -@@ -486,6 +488,8 @@ audio_rintr(void *addr) - } - selwakeup(&sc->rec.sel); +@@ -655,6 +657,8 @@ audio_rintr(void *addr) + */ + softintr_schedule(sc->rec.softintr); } + + notify_record(); diff --git a/repos/dde_bsd/patches/oppress_warning.patch b/repos/dde_bsd/patches/oppress_warning.patch deleted file mode 100644 index 0b3e1ec97f..0000000000 --- a/repos/dde_bsd/patches/oppress_warning.patch +++ /dev/null @@ -1,14 +0,0 @@ -dev/audio.c:XXX:Y: warning: ‘type’ may be used uninitialized in this function [-Wmaybe-uninitialized] -diff --git a/dev/audio.c b/dev/audio.c -index a9fa22b..da8a783 100644 ---- a/dev/audio.c -+++ b/dev/audio.c -@@ -639,7 +639,7 @@ int - audioprint(void *aux, const char *pnp) - { - struct audio_attach_args *arg = aux; -- const char *type; -+ const char *type = "never printed"; - - if (pnp != NULL) { - switch (arg->type) { diff --git a/repos/dde_bsd/patches/s938_headset_quirk.patch b/repos/dde_bsd/patches/s938_headset_quirk.patch new file mode 100644 index 0000000000..59f12019fc --- /dev/null +++ b/repos/dde_bsd/patches/s938_headset_quirk.patch @@ -0,0 +1,48 @@ +diff --git a/dev/pci/azalia.h b/dev/pci/azalia.h +index 8dd7641..2d3ce3a 100644 +--- a/dev/pci/azalia.h ++++ b/dev/pci/azalia.h +@@ -516,6 +516,7 @@ + #define AZ_QRK_WID_CLOSE_PCBEEP 0x00080000 ++#define AZ_QRK_WID_HEADSET 0x00100000 + #define AZ_QRK_ROUTE_SPKR2_DAC 0x01000000 + #define AZ_QRK_DOLBY_ATMOS 0x02000000 + + /* memory-mapped types */ + typedef struct { +diff --git a/dev/pci/azalia_codec.c b/dev/pci/azalia_codec.c +index 05d157b..8046b3b 100644 +--- a/dev/pci/azalia_codec.c ++++ b/dev/pci/azalia_codec.c +@@ -100,6 +100,8 @@ azalia_codec_init_vtbl(codec_t *this) + break; + case 0x10ec0255: + this->name = "Realtek ALC255"; ++ if (this->subid == 0x193e10cf) ++ this->qrks |= AZ_QRK_WID_HEADSET; + break; + case 0x10ec0256: + this->name = "Realtek ALC256"; +@@ -747,6 +749,9 @@ azalia_unsol_event(codec_t *this, int tag) + CORB_GET_PIN_SENSE, 0, &result); + if (!err && (result & CORB_PS_PRESENCE)) + vol = 1; ++ // switch microphone to mic2 ++ if (!err) ++ notify_hp_sense(result & CORB_PS_PRESENCE); + } + if (err) + break; +@@ -2702,6 +2707,12 @@ azalia_codec_widget_quirks(codec_t *this, nid_t nid) + 0x57d7, NULL); + } + ++ if (this->qrks & AZ_QRK_WID_HEADSET && nid == 0x19) { ++ w->d.pin.config = 0x03a19120; ++ azalia_pin_config_ov(w, CORB_CD_DEVICE_MASK, CORB_CD_MICIN); ++ w->enable = 1; ++ } ++ + return(0); + } + diff --git a/repos/dde_bsd/ports/dde_bsd.hash b/repos/dde_bsd/ports/dde_bsd.hash index a0f7b8dd2c..025ba4ecf6 100644 --- a/repos/dde_bsd/ports/dde_bsd.hash +++ b/repos/dde_bsd/ports/dde_bsd.hash @@ -1 +1 @@ -4d3a973ccec12ca00589f9213c2ce663d4a4e496 +771f320f0d4e11510d8f565fda456400b4793230 diff --git a/repos/dde_bsd/ports/dde_bsd.port b/repos/dde_bsd/ports/dde_bsd.port index 35f3b41e20..b4dfb5b6d9 100644 --- a/repos/dde_bsd/ports/dde_bsd.port +++ b/repos/dde_bsd/ports/dde_bsd.port @@ -3,13 +3,13 @@ VERSION := 1 DOWNLOADS := audio.archive # -# Audio drivers from OpenBSD 6.6 +# Audio drivers from OpenBSD 7.1 # SRC_DIR_AUDIO := src/lib/audio -VERSION_AUDIO := 6.6 -BASE_URL := https://ftp.openbsd.org/pub/OpenBSD +VERSION_AUDIO := 7.1 +BASE_URL := https://cdn.openbsd.org/pub/OpenBSD URL(audio) := $(BASE_URL)/$(VERSION_AUDIO)/sys.tar.gz -SHA(audio) := a1b19665989c02a2017a639d47a042f4fe7f584b6298727e982a5536020b832d +SHA(audio) := 890cb97c01052f26cefe5430d635e0fdf6047ca701a99992968e16801e2a6565 DIR(audio) := $(SRC_DIR_AUDIO) TAR_OPT(audio) := --strip-components=1 --files-from $(REP_DIR)/audio.list HASH_INPUT += $(REP_DIR)/audio.list @@ -18,12 +18,6 @@ HASH_INPUT += $(REP_DIR)/audio.list # Patches # PATCHES := $(addprefix patches/,$(notdir $(wildcard $(REP_DIR)/patches/*.patch))) - -AUDIO_OPT := -p1 -d$(SRC_DIR_AUDIO) -PATCH_OPT(patches/oppress_warning.patch) := $(AUDIO_OPT) -PATCH_OPT(patches/azalia_c.patch) := $(AUDIO_OPT) -PATCH_OPT(patches/azalia_h.patch) := $(AUDIO_OPT) -PATCH_OPT(patches/azalia_codec_c.patch) := $(AUDIO_OPT) -PATCH_OPT(patches/notify.patch) := $(AUDIO_OPT) +PATCH_OPT := -p1 -d$(SRC_DIR_AUDIO) # vi: set ft=make : diff --git a/repos/dde_bsd/recipes/pkg/bsd_audio_drv/hash b/repos/dde_bsd/recipes/pkg/bsd_audio_drv/hash index 19fe882a08..d0a0da2612 100644 --- a/repos/dde_bsd/recipes/pkg/bsd_audio_drv/hash +++ b/repos/dde_bsd/recipes/pkg/bsd_audio_drv/hash @@ -1 +1 @@ -2022-05-24 1457c977583577de2e68eae2ac492c7a95ba9e4c +2022-10-11 c9953284ebe0570c926982c35f37647a3132549d diff --git a/repos/dde_bsd/recipes/src/bsd_audio_drv/content.mk b/repos/dde_bsd/recipes/src/bsd_audio_drv/content.mk index f104af33c5..01764c9ed0 100644 --- a/repos/dde_bsd/recipes/src/bsd_audio_drv/content.mk +++ b/repos/dde_bsd/recipes/src/bsd_audio_drv/content.mk @@ -1,6 +1,6 @@ PORT_DIR := $(call port_dir,$(REP_DIR)/ports/dde_bsd) -MK_FILES := dde_bsd_audio.inc dde_bsd_audio_include.mk dde_bsd_audio_pci.mk +MK_FILES := dde_bsd_audio.inc dde_bsd_audio_include.mk dde_bsd_audio_pci.inc LIB_MK := $(addprefix lib/mk/, $(MK_FILES)) \ $(foreach SPEC,x86_32 x86_64,lib/mk/spec/$(SPEC)/dde_bsd_audio.mk) \ @@ -11,18 +11,13 @@ MIRROR_FROM_REP_DIR := $(LIB_MK) src/lib src/drivers patches include MIRROR_FROM_PORT_DIR := $(addprefix src/lib/audio/, \ dev/pci/azalia_codec.c \ dev/pci/pcidevs.h \ - dev/pci/eap.c \ dev/pci/pcidevs_data.h \ dev/pci/azalia.h \ - dev/pci/eapreg.h \ dev/pci/azalia.c \ - dev/pci/auich.c \ dev/mulaw.h \ dev/audio_if.h \ dev/mulaw.c \ dev/audio.c \ - dev/ic/ac97.h \ - dev/ic/ac97.c \ lib/libkern \ sys/device.h \ sys/audioio.h \ diff --git a/repos/dde_bsd/recipes/src/bsd_audio_drv/hash b/repos/dde_bsd/recipes/src/bsd_audio_drv/hash index 17fbba3f23..7893b4e706 100644 --- a/repos/dde_bsd/recipes/src/bsd_audio_drv/hash +++ b/repos/dde_bsd/recipes/src/bsd_audio_drv/hash @@ -1 +1 @@ -2022-05-24 d468d19c3211d09086b582583fa745223ff47594 +2022-10-11 eeb4565fb902ca980c98c6225c5c8141c8744011 diff --git a/repos/dde_bsd/run/audio_in.run b/repos/dde_bsd/run/audio_in.run index 03bce3867e..681ee398a2 100644 --- a/repos/dde_bsd/run/audio_in.run +++ b/repos/dde_bsd/run/audio_in.run @@ -17,13 +17,14 @@ if {[have_spec linux]} { set build_components { core init timer + drivers/acpi + drivers/platform + app/pci_decode + server/report_rom drivers/audio test/audio_in } -source ${genode_dir}/repos/base/run/platform_drv.inc -append_platform_drv_build_components - build $build_components create_boot_directory @@ -51,14 +52,68 @@ append config { - } + -append_platform_drv_config + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -append config { - - + + @@ -83,13 +138,11 @@ install_config $config # set boot_modules { - core ld.lib.so init timer test-audio_in + core ld.lib.so init timer + platform_drv acpi_drv pci_decode report_rom + pci_audio_drv test-audio_in } -append boot_modules [audio_drv_binary] - -append_platform_drv_boot_modules - build_boot_image $boot_modules run_genode_until forever diff --git a/repos/dde_bsd/run/audio_out.run b/repos/dde_bsd/run/audio_out.run index 462a23d43f..86bd1dc7ce 100644 --- a/repos/dde_bsd/run/audio_out.run +++ b/repos/dde_bsd/run/audio_out.run @@ -1,47 +1,33 @@ assert_spec x86 -# -# Check used commands -# +if {[have_include "power_on/qemu"]} { + puts "\nAudio_out test running on Qemu is not supported.\n" + exit 0 +} -set wget [installed_command wget] +if {[have_spec linux]} { + puts"\nAudio_out test running on Linux is not supported.\n" + exit 0 +} -# -# Configure -# -set use_mixer 0 - -# -# Build -# - -set build_components { +create_boot_directory +build { core init timer + drivers/acpi + drivers/platform + app/pci_decode + server/report_rom drivers/audio test/audio_out } -lappend_if $use_mixer build_components server/mixer - -source ${genode_dir}/repos/base/run/platform_drv.inc -append_platform_drv_build_components - -build $build_components - -create_boot_directory - -# -# Config -# - -append config { - +install_config { + - @@ -54,60 +40,87 @@ append config { - } + -append_platform_drv_config - -append_if $use_mixer config { - + - - - - - - } + + + + + + -append_if [have_spec linux] config { - } -append_if [expr ![have_spec linux]] config { - } -append config { - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + sample.raw - } -append_if $use_mixer config { - } -append config { + } -install_config $config - - # # Get sample file # -if {[info exists env(GENODE_SAMPLE_RAW)]} { - catch { exec $wget $::env(GENODE_SAMPLE_RAW) -O bin/sample.raw } -} - if {![file exists bin/sample.raw]} { puts "" puts "The sample file is missing. Please take a look at" @@ -117,22 +130,12 @@ if {![file exists bin/sample.raw]} { exit 1 } -# -# Boot modules -# - -append boot_modules { - core ld.lib.so init timer } [audio_drv_binary] { - test-audio_out sample.raw +build_boot_image { + core ld.lib.so init timer + platform_drv acpi_drv pci_decode report_rom + pci_audio_drv test-audio_out sample.raw } -lappend_if $use_mixer boot_modules mixer - -append_platform_drv_boot_modules - -build_boot_image $boot_modules - -append qemu_args " -nographic -soundhw es1370 " # # For obvious reasons the timeout depends on the total diff --git a/repos/dde_bsd/src/drivers/audio/main.cc b/repos/dde_bsd/src/drivers/audio/main.cc index 48f5471748..c16e791b19 100644 --- a/repos/dde_bsd/src/drivers/audio/main.cc +++ b/repos/dde_bsd/src/drivers/audio/main.cc @@ -142,6 +142,7 @@ class Audio_out::Out } else { _play_silence(); + return; } _advance_position(p_left, p_right); @@ -221,13 +222,10 @@ struct Audio_out::Root_policy { size_t ram_quota = Arg_string::find_arg(args, "ram_quota" ).ulong_value(0); - size_t session_size = - align_addr(sizeof(Audio_out::Session_component), 12); - if ((ram_quota < session_size) || - (sizeof(Stream) > ram_quota - session_size)) { + if (sizeof(Stream) > ram_quota) { Genode::error("insufficient 'ram_quota', got ", ram_quota, - " need ", sizeof(Stream) + session_size); + " need ", sizeof(Stream)); throw Genode::Insufficient_ram_quota(); } @@ -412,13 +410,11 @@ struct Audio_in::Root_policy void aquire(char const *args) { size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); - size_t session_size = align_addr(sizeof(Audio_in::Session_component), 12); - if ((ram_quota < session_size) || - (sizeof(Stream) > (ram_quota - session_size))) { + if (sizeof(Stream) > ram_quota) { Genode::error("insufficient 'ram_quota', got ", ram_quota, - " need ", sizeof(Stream) + session_size, - ", denying '",Genode::label_from_args(args),"'"); + " need ", sizeof(Stream), + ", denying '", Genode::label_from_args(args),"'"); throw Genode::Insufficient_ram_quota(); } diff --git a/repos/dde_bsd/src/drivers/audio/pci_audio_drv/target.mk b/repos/dde_bsd/src/drivers/audio/pci_audio_drv/target.mk index 9f089ea4bd..00a3f837c9 100644 --- a/repos/dde_bsd/src/drivers/audio/pci_audio_drv/target.mk +++ b/repos/dde_bsd/src/drivers/audio/pci_audio_drv/target.mk @@ -1,7 +1,7 @@ REQUIRES = x86 TARGET = pci_audio_drv SRC_CC = main.cc -LIBS = dde_bsd_audio dde_bsd_audio_pci base +LIBS = dde_bsd_audio base INC_DIR += $(REP_DIR)/include vpath %.cc $(REP_DIR)/src/drivers/audio diff --git a/repos/dde_bsd/src/lib/audio/bsd.h b/repos/dde_bsd/src/lib/audio/bsd.h index 8f60c79df7..919a9a05c1 100644 --- a/repos/dde_bsd/src/lib/audio/bsd.h +++ b/repos/dde_bsd/src/lib/audio/bsd.h @@ -24,25 +24,8 @@ namespace Bsd { int probe_drivers(Genode::Env&, Genode::Allocator&); void mem_init(Genode::Env&, Genode::Allocator &); - void irq_init(Genode::Entrypoint&, Genode::Allocator&); void timer_init(Genode::Env&); void update_time(); - - - /************************** - ** Bus_driver interface ** - **************************/ - - struct Bus_driver - { - virtual Genode::Irq_session_capability irq_session() = 0; - - virtual Genode::addr_t alloc(Genode::size_t size, int align) = 0; - virtual void free(Genode::addr_t virt, Genode::size_t size) = 0; - virtual Genode::addr_t virt_to_phys(Genode::addr_t virt) = 0; - virtual Genode::addr_t phys_to_virt(Genode::addr_t phys) = 0; - }; - } #endif /* _BSD_H_ */ diff --git a/repos/dde_bsd/src/lib/audio/bsd_emul_pci.c b/repos/dde_bsd/src/lib/audio/bsd_emul_pci.c index ad0886c663..2b2a0a26d3 100644 --- a/repos/dde_bsd/src/lib/audio/bsd_emul_pci.c +++ b/repos/dde_bsd/src/lib/audio/bsd_emul_pci.c @@ -40,13 +40,16 @@ short pv[] = { -1, PCI_BUS_PARENT }; struct cfdata cfdata[] = { {&audio_ca, &audio_cd, 0, 0, 0, 0, pv+0, 0, 0}, {&azalia_ca, &azalia_cd, 0, 0, 0, 0, pv+1, 0, 0}, - {&eap_ca, &eap_cd, 0, 0, 0, 0, pv+1, 0, 0}, - {&auich_ca, &auich_cd, 0, 0, 0, 0, pv+1, 0, 0}, }; struct device pci_bus = { DV_DULL, { 0, 0 }, 0, 0, { 'p', 'c', 'i', '0'}, 0, 0, 0 }; + +/* global unit counter */ +static int dv_unit; + + /** * This function is our little helper that matches and attaches * the driver to the device. @@ -74,12 +77,23 @@ int probe_cfdata(struct pci_attach_args *pa) M_DEVBUF, M_NOWAIT|M_ZERO); dev->dv_cfdata = cf; + dev->dv_unit = dv_unit++; snprintf(dev->dv_xname, sizeof(dev->dv_xname), "%s%d", cd->cd_name, dev->dv_unit); - printf("%s at %s\n", dev->dv_xname, pci_bus.dv_xname); + printf("%s [%x:%x]\n", dev->dv_xname, + pa->pa_id & 0xffffu, (pa->pa_id >> 16u) & 0xffffu); ca->ca_attach(&pci_bus, dev, pa); + /* + * The contrib code is patched to set the dv_ref when the + * driver attached successfully. + */ + if (!pci_bus.dv_ref) { + free(dev, M_DEVBUF, ca->ca_devsize); + return 0; + } + return 1; } } diff --git a/repos/dde_bsd/src/lib/audio/driver.cc b/repos/dde_bsd/src/lib/audio/driver.cc index bf8311fef3..ba34fa8e28 100644 --- a/repos/dde_bsd/src/lib/audio/driver.cc +++ b/repos/dde_bsd/src/lib/audio/driver.cc @@ -33,8 +33,8 @@ extern struct cfdriver audio_cd; -static dev_t const adev = 0x00; /* audio0 (minor nr 0) */ -static dev_t const mdev = 0x10; /* mixer0 (minor nr 16) */ +static dev_t const adev = 0x00; /* /dev/audio0 */ +static dev_t const mdev = 0xc0; /* /dev/audioctl */ static bool adev_usuable = false; @@ -327,6 +327,11 @@ static bool open_audio_device(dev_t dev) return false; int err = audioopen(dev, FWRITE|FREAD, 0 /* ifmt */, 0 /* proc */); + + /* try to open playback only, if capturing potentially failed */ + if (err == ENODEV) + err = audioopen(dev, FWRITE, 0 /* ifmt */, 0 /* proc */); + if (err) return false; @@ -616,7 +621,6 @@ void Audio::init_driver(Genode::Env &env, Genode::Allocator &alloc, Genode::Signal_context_capability announce_sigh) { Bsd::mem_init(env, alloc); - Bsd::irq_init(env.ep(), alloc); Bsd::timer_init(env); static Task bsd_task(env, alloc, config, announce_sigh); diff --git a/repos/dde_bsd/src/lib/audio/dummies.cc b/repos/dde_bsd/src/lib/audio/dummies.cc index cbcfcc74f9..28eea52e1b 100644 --- a/repos/dde_bsd/src/lib/audio/dummies.cc +++ b/repos/dde_bsd/src/lib/audio/dummies.cc @@ -46,21 +46,35 @@ DUMMY name(void) { \ DUMMY_RET(1, pci_intr_map_msi) /* do not support MSI API */ DUMMY_RET(0, pci_intr_string) +DUMMY(0, bus_dmamap_unload) +DUMMY(0, bus_dmamem_mmap) +DUMMY(0, bus_dmamem_unmap) DUMMY(0, bus_space_unmap) DUMMY(0, config_activate_children) DUMMY(0, config_deactivate) DUMMY(0, config_detach) DUMMY(0, config_detach_children) DUMMY(0, cpu_info_primary) +DUMMY(0, device_unref) +DUMMY(0, klist_free) +DUMMY(0, klist_init_mutex) +DUMMY(0, klist_insert_locked) +DUMMY(0, klist_invalidate) +DUMMY(0, klist_remove) +DUMMY(0, klist_remove_locked) +DUMMY(0, knote_modify) +DUMMY(0, knote_process) DUMMY(0, pci_findvendor) DUMMY(0, pci_intr_disestablish) DUMMY(0, pci_set_powerstate) DUMMY(0, psignal) DUMMY(0, selrecord) DUMMY(0, selwakeup) +DUMMY(0, softintr_disestablish) +DUMMY(0, softintr_schedule) DUMMY(0, tsleep) DUMMY(0, tsleep_nsec) DUMMY(0, vdevgone) -DUMMY(0, device_unref) +DUMMY(1, softintr_establish) } /* extern "C" */ diff --git a/repos/dde_bsd/src/lib/audio/include/bsd_emul.h b/repos/dde_bsd/src/lib/audio/include/bsd_emul.h index 379ed9afeb..cc09802601 100644 --- a/repos/dde_bsd/src/lib/audio/include/bsd_emul.h +++ b/repos/dde_bsd/src/lib/audio/include/bsd_emul.h @@ -65,6 +65,43 @@ typedef signed long long off_t; #define minor(x) ((int32_t)((x) & 0xff) | (((x) & 0xffff0000) >> 8)) +/******************* + ** machine/cpu.h ** + *******************/ + +struct cpu_info { }; +extern struct cpu_info cpu_info_primary; + +#define curcpu() (&cpu_info_primary) + + +/********************* + ** machine/mutex.h ** + *********************/ + +#define MUTEX_INITIALIZER(ipl) { 0, (ipl), 0, NULL } +#define MUTEX_ASSERT_UNLOCK(mtx) do { \ + if ((mtx)->mtx_owner != curcpu()) \ + panic("mutex %p not held in %s\n", (mtx), __func__); \ +} while (0) +#define MUTEX_ASSERT_LOCKED(mtx) do { \ + if ((mtx)->mtx_owner != curcpu()) \ + panic("mutex %p not held in %s\n", (mtx), __func__); \ +} while (0) +#define MUTEX_ASSERT_UNLOCKED(mtx) do { \ + if ((mtx)->mtx_owner == curcpu()) \ + panic("mutex %p held in %s\n", (mtx), __func__); \ +} while (0) + +struct mutex +{ + volatile int mtx_lock; + int mtx_wantipl; /* interrupt priority level */ + int mtx_oldipl; + void *mtx_owner; +}; + + /***************** ** sys/errno.h ** *****************/ @@ -215,12 +252,17 @@ struct kevent struct knote; SLIST_HEAD(klist, knote); +#define FILTEROP_ISFD 0x00000001 +#define FILTEROP_MPSAFE 0x00000002 + struct filterops { - int f_isfd; + int f_flags; int (*f_attach)(struct knote*); void (*f_detach)(struct knote*); int (*f_event)(struct knote*, long); + int (*f_modify)(struct kevent *, struct knote *); + int (*f_process)(struct knote *, struct kevent *); }; struct knote @@ -233,6 +275,15 @@ struct knote void *kn_hook; }; +int knote_modify(const struct kevent *kev, struct knote *kn); +int knote_process(struct knote *kn, struct kevent *kev); + +extern void klist_free(struct klist *); +extern void klist_init_mutex(struct klist *, struct mutex *); +extern void klist_insert(struct klist *, struct knote *); +extern void klist_invalidate(struct klist *); +extern void klist_remove(struct klist *, struct knote *); + /******************* ** sys/selinfo.h ** @@ -247,43 +298,6 @@ void selrecord(struct proc *selector, struct selinfo *); void selwakeup(struct selinfo *); -/******************* - ** machine/cpu.h ** - *******************/ - -struct cpu_info { }; -extern struct cpu_info cpu_info_primary; - -#define curcpu() (&cpu_info_primary) - - -/********************* - ** machine/mutex.h ** - *********************/ - -#define MUTEX_INITIALIZER(ipl) { 0, (ipl), 0, NULL } -#define MUTEX_ASSERT_UNLOCK(mtx) do { \ - if ((mtx)->mtx_owner != curcpu()) \ - panic("mutex %p not held in %s\n", (mtx), __func__); \ -} while (0) -#define MUTEX_ASSERT_LOCKED(mtx) do { \ - if ((mtx)->mtx_owner != curcpu()) \ - panic("mutex %p not held in %s\n", (mtx), __func__); \ -} while (0) -#define MUTEX_ASSERT_UNLOCKED(mtx) do { \ - if ((mtx)->mtx_owner == curcpu()) \ - panic("mutex %p held in %s\n", (mtx), __func__); \ -} while (0) - -struct mutex -{ - volatile int mtx_lock; - int mtx_wantipl; /* interrupt priority level */ - int mtx_oldipl; - void *mtx_owner; -}; - - /***************** ** sys/mutex.h ** *****************/ @@ -298,6 +312,8 @@ void mtx_leave(struct mutex *); #define INFSLP __UINT64_MAX__ +#define KERNEL_ASSERT_LOCKED() + extern int nchrdev; int enodev(void); @@ -315,6 +331,7 @@ void wakeup(const volatile void*); int tsleep(const volatile void *, int, const char *, int); int tsleep_nsec(const volatile void *, int, const char *, uint64_t); int msleep(const volatile void *, struct mutex *, int, const char*, int); +int msleep_nsec(const volatile void *, struct mutex *, int, const char*, uint64_t); int uiomove(void *, int, struct uio *); @@ -708,6 +725,13 @@ int timeout_del(struct timeout *); #define htole32(x) ((uint32_t)(x)) +/****************** + ** sys/stdint.h ** + ******************/ + +#define UINT64_MAX 0xffffffffffffffffULL + + /**************** ** sys/time.h ** ****************/ @@ -720,6 +744,24 @@ struct timeval void microuptime(struct timeval *); +static inline uint64_t SEC_TO_NSEC(uint64_t seconds) +{ + if (seconds > UINT64_MAX / 1000000000ULL) + return UINT64_MAX; + return seconds * 1000000000ULL; +} + + +/************************* + ** arch specifc intr.h ** + *************************/ + +#define IPL_SOFTNET 3 + +void *softintr_establish(int, void (*)(void *), void *); +void softintr_schedule(void *); +void softintr_disestablish(void *); + /*************************** ** lib/libkern/libkern.h ** diff --git a/repos/dde_bsd/src/lib/audio/irq.cc b/repos/dde_bsd/src/lib/audio/irq.cc deleted file mode 100644 index 1075b33f90..0000000000 --- a/repos/dde_bsd/src/lib/audio/irq.cc +++ /dev/null @@ -1,161 +0,0 @@ -/* - * \brief Signal context for IRQ's - * \author Josef Soentgen - * \date 2014-10-14 - */ - -/* - * Copyright (C) 2014-2020 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. - */ - -/* Genode includes */ -#include -#include -#include -#include -#include - -/* local includes */ -#include + + + + @@ -545,6 +551,8 @@ install_config { + + @@ -712,10 +720,15 @@ set fd [open [managed_config_path depot_query] w] puts $fd "" close $fd -foreach config { fonts wifi runtime event_filter } { - set from [ingredient_path $config default] - check_xml_syntax $from - file copy $from [managed_config_path $config] } +foreach config { fonts wifi runtime event_filter system } { + set ingredient [single_ingredient $config "default"] + if {$ingredient != ""} { + set from [ingredient_path $config $ingredient] + set to [managed_config_path $config] + check_xml_syntax $from + copy_file $from $to + } +} copy_file [file join [initial_config_dir] fb_drv] [managed_config_path fb_drv] @@ -790,12 +803,40 @@ proc pkg_archive_paths { values } { } +## +# Return which kind of depot archive is wanted: 'tar', 'omit', or 'list' +# +# tar - includes the depot content referenced by the deploy configuration as +# tar archive named 'depot.tar' +# +# omit - skips the evaluation of the deploy configuration +# +# list - outputs the list of packages needed for the deployment, which can +# taken as input for manually publishing those packages +# +proc depot_archive { } { + + global ::env + + set archive "tar" + if {[info exists ::env(DEPOT)]} { + set archive "$::env(DEPOT)" } + + if {$archive != "omit" && $archive != "tar" && $archive != "list"} { + puts stderr "Error: invalid value of DEPOT=$archive variable!" } + + return $archive +} + + # # Trigger the creation / updating of referenced depot content # # This step may update pkg versions if '--depot-auto-update' is enabled. # -_collect_from_depot [pkg_archive_paths [referenced_pkg_values]] +if {[depot_archive] == "tar" || [depot_archive] == "list"} { + _collect_from_depot [pkg_archive_paths [referenced_pkg_values]] +} # @@ -853,9 +894,20 @@ exec sed -i "/config/s/arch=\"\"/arch=\"[depot_spec]\"/" [initial_config_file de ## Depot content integrated in the Sculpt image ## -create_tar_from_depot_binaries [run_dir]/genode/depot.tar \ +proc create_depot_archive { } { + + if {[depot_archive] == "tar"} { + create_tar_from_depot_binaries [run_dir]/genode/depot.tar \ {*}[pkg_archive_paths [referenced_pkg_values]] + } elseif {[depot_archive] == "list"} { + puts "Do not forget to publish:" + puts [pkg_archive_paths [referenced_pkg_values]] + } +} + +create_depot_archive + # # Create initial_config.tar to be mounted at the root of the config fs diff --git a/repos/gems/run/sculpt/index b/repos/gems/run/sculpt/index index f4b3b057fc..3826f10387 100644 --- a/repos/gems/run/sculpt/index +++ b/repos/gems/run/sculpt/index @@ -34,8 +34,6 @@ - - diff --git a/repos/gems/run/text_painter.run b/repos/gems/run/text_painter.run index 0b29af7992..abbebde446 100644 --- a/repos/gems/run/text_painter.run +++ b/repos/gems/run/text_painter.run @@ -93,7 +93,7 @@ install_config { } -build { server/vfs test/text_painter lib/vfs/ttf } +build { server/vfs test/text_painter lib/vfs_ttf } set fd [open [run_dir]/genode/focus w] puts $fd " \" domain=\"default\"/>" diff --git a/repos/gems/run/trace_recorder.run b/repos/gems/run/trace_recorder.run new file mode 100644 index 0000000000..f29544d2e9 --- /dev/null +++ b/repos/gems/run/trace_recorder.run @@ -0,0 +1,194 @@ +assert_spec linux + +# check that babeltrace2 is present +set babeltrace_missing [catch { + spawn babeltrace2 -V + expect { + {Babeltrace 2.*} { } + eof { return } + timeout { return } + } +}] + +if {$babeltrace_missing} { + puts "\nPlease install babeltrace2 on your host system." + exit 1; +} + +# check that python-pcapng is present +set python_pcapng_missing [catch { + spawn -noecho sh -c "echo \"import pcapng\" | python" + expect { + {No module} { return } + {not found} { return } + eof { } + } +}] + +if {$python_pcapng_missing} { + puts "\nPlease install python-pcapng on your host system." + exit 1; +} + +build { app/ping server/lx_fs } + +create_boot_directory + +import_from_depot \ + [depot_user]/src/[base_src] \ + [depot_user]/src/init \ + [depot_user]/src/libc \ + [depot_user]/src/nic_router \ + [depot_user]/src/report_rom \ + [depot_user]/src/vfs \ + [depot_user]/src/linux_rtc_drv \ + [depot_user]/src/trace_recorder \ + [depot_user]/raw/trace_recorder \ + [depot_user]/src/trace_recorder_policy \ + [depot_user]/src/dynamic_rom + +install_config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +exec rm -rf bin/fs +exec mkdir -p bin/fs + +build_boot_image { lx_fs + fs + ping } + +append qemu_args " -nographic " + +run_genode_until {Enabled ctf writer for init -> ping -> ep} 20 +set spawn_id [output_spawn_id] +run_genode_until {.*child "ping" exited with exit value 0.*} 60 $spawn_id + +####################### +# validate CTF output # +####################### + +set ctf_path [exec find bin/fs -type d -name nic_router] +exec test -s $ctf_path/ep + +# check generated trace by reading CTF trace as fast as possible using a dummy output +exec babeltrace2 $ctf_path --output-format=dummy + + +########################## +# validate PCAPNG output # +########################## + +# create python script for pcapng parsing +set fd [open [run_dir]/genode/check_pcapng.py "w"] +puts $fd { +import sys +import pcapng + +with open(sys.argv[1], "rb") as fp: + scanner = pcapng.FileScanner(fp) + for block in pcapng.FileScanner(fp): + pass +} +close $fd + +set pcap_file [exec find bin/fs -name nic_router.pcapng] +exec test -s $pcap_file + +# check generated trace by python script +exec python [run_dir]/genode/check_pcapng.py $pcap_file diff --git a/repos/gems/run/trace_recorder_ctf.run b/repos/gems/run/trace_recorder_ctf.run new file mode 100644 index 0000000000..4310428a11 --- /dev/null +++ b/repos/gems/run/trace_recorder_ctf.run @@ -0,0 +1,175 @@ +assert_spec linux + +# check that babeltrace2 is present +set babeltrace_missing [catch { + spawn babeltrace2 -V + expect { + {Babeltrace 2.*} { } + eof { return } + timeout { return } + } +}] + +if {$babeltrace_missing} { + puts "\nPlease install babeltrace2 on your host system." + exit 1; +} + +build { server/lx_fs } + +create_boot_directory + +import_from_depot \ + [depot_user]/src/[base_src] \ + [depot_user]/src/init \ + [depot_user]/src/libc \ + [depot_user]/src/rom_logger \ + [depot_user]/src/report_rom \ + [depot_user]/src/vfs \ + [depot_user]/src/dummy_rtc_drv \ + [depot_user]/src/trace_recorder \ + [depot_user]/raw/trace_recorder \ + [depot_user]/src/trace_recorder_policy \ + [depot_user]/src/dynamic_rom + +install_config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +exec rm -rf bin/fs +exec mkdir -p bin/fs + +build_boot_image { lx_fs + fs } + +append qemu_args " -nographic " + +run_genode_until {Enabled ctf writer for init -> rom_logger -> ep} 20 +set spawn_id [output_spawn_id] +run_genode_until {} 60 $spawn_id + +# trace file has non-zero size +exec test -s bin/fs/0-0-0\ 0\:0\:0/init/rom_logger/ep + +# check generated trace by reading CTF trace as fast as possible using a dummy output +exec babeltrace2 bin/fs/0-0-0\ 0\:0\:0/init/rom_logger --output-format=dummy diff --git a/repos/gems/run/trace_recorder_pcapng.run b/repos/gems/run/trace_recorder_pcapng.run new file mode 100644 index 0000000000..27d6770b7c --- /dev/null +++ b/repos/gems/run/trace_recorder_pcapng.run @@ -0,0 +1,163 @@ +assert_spec linux + +# check that python-pcapng is present +set python_pcapng_missing [catch { + spawn -noecho sh -c "echo \"import pcapng\" | python" + expect { + {No module} { return } + {not found} { return } + eof { } + } +}] + +if {$python_pcapng_missing} { + puts "\nPlease install python-pcapng on your host system." + exit 1; +} + +build { server/lx_fs app/ping } + +create_boot_directory + +import_from_depot \ + [depot_user]/src/[base_src] \ + [depot_user]/src/init \ + [depot_user]/src/libc \ + [depot_user]/src/nic_router \ + [depot_user]/src/vfs \ + [depot_user]/src/linux_rtc_drv \ + [depot_user]/src/trace_recorder \ + [depot_user]/raw/trace_recorder \ + [depot_user]/src/trace_recorder_policy \ + [depot_user]/src/dynamic_rom + +install_config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +exec rm -rf bin/fs +exec mkdir -p bin/fs/ + +build_boot_image { lx_fs + fs + ping } + +append qemu_args " -nographic " + +run_genode_until {Enabled pcapng writer for init -> nic_router -> ep} 15 +set spawn_id [output_spawn_id] + +run_genode_until {.*child "ping" exited with exit value 0.*} 60 $spawn_id + +set pcap_file [exec find bin/fs -name nic_router.pcapng] + +# trace file has non-zero size? +exec test -s $pcap_file + +# create python script for pcapng parsing +set fd [open [run_dir]/genode/check_pcapng.py "w"] +puts $fd { +import sys +import pcapng + +with open(sys.argv[1], "rb") as fp: + scanner = pcapng.FileScanner(fp) + for block in pcapng.FileScanner(fp): + pass +} +close $fd + +# check generated trace by python script +exec python [run_dir]/genode/check_pcapng.py $pcap_file + diff --git a/repos/gems/run/vfs_cbe.run b/repos/gems/run/vfs_cbe.run index de7a0c94bc..4d44fdb21e 100644 --- a/repos/gems/run/vfs_cbe.run +++ b/repos/gems/run/vfs_cbe.run @@ -34,12 +34,12 @@ build { timer init server/lx_fs - lib/vfs/cbe - lib/vfs/cbe_crypto/aes_cbc - lib/vfs/cbe_crypto/memcopy - lib/vfs/cbe_trust_anchor - lib/vfs/import - lib/vfs/pipe + lib/vfs_cbe + lib/vfs_cbe_crypto_aes_cbc + lib/vfs_cbe_crypto_memcopy + lib/vfs_cbe_trust_anchor + lib/vfs_import + lib/vfs_pipe test/vfs_stress test/libc server/log_terminal diff --git a/repos/gems/run/vfs_cbe_init.run b/repos/gems/run/vfs_cbe_init.run index 9871156793..8feb899f0f 100644 --- a/repos/gems/run/vfs_cbe_init.run +++ b/repos/gems/run/vfs_cbe_init.run @@ -33,7 +33,7 @@ append build_components { app/cbe_init_trust_anchor app/cbe_init - lib/vfs/cbe_trust_anchor + lib/vfs_cbe_trust_anchor } build $build_components diff --git a/repos/gems/run/vfs_import.run b/repos/gems/run/vfs_import.run index d0d963dd6f..226378f67c 100644 --- a/repos/gems/run/vfs_import.run +++ b/repos/gems/run/vfs_import.run @@ -1,9 +1,9 @@ -if {[get_cmd_switch --autopilot] && [have_board riscv_qemu]} { +if {[get_cmd_switch --autopilot] && [have_board virt_qemu_riscv]} { puts "Autopilot mode is not supported on this platform." exit 0 } -build { app/sequence server/vfs lib/vfs/import test/libc } +build { app/sequence server/vfs lib/vfs_import test/libc } create_boot_directory diff --git a/repos/gems/sculpt/drivers/pc b/repos/gems/sculpt/drivers/pc index 0dae762755..8f2f2879cd 100644 --- a/repos/gems/sculpt/drivers/pc +++ b/repos/gems/sculpt/drivers/pc @@ -39,19 +39,23 @@ + - + + + - - + + + @@ -60,16 +64,19 @@ + + + @@ -80,9 +87,10 @@ - + + @@ -93,17 +101,49 @@ - - - - - - - + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -113,19 +153,18 @@ - - - + + + - - - + + + - - + @@ -221,7 +260,7 @@ - + @@ -248,6 +287,7 @@ + diff --git a/repos/gems/sculpt/leitzentrale/default b/repos/gems/sculpt/leitzentrale/default index 05d82c1409..d9aca015e7 100644 --- a/repos/gems/sculpt/leitzentrale/default +++ b/repos/gems/sculpt/leitzentrale/default @@ -239,6 +239,8 @@ + + diff --git a/repos/gems/src/app/backdrop/main.cc b/repos/gems/src/app/backdrop/main.cc index 42b34e2675..de00fa8aa6 100644 --- a/repos/gems/src/app/backdrop/main.cc +++ b/repos/gems/src/app/backdrop/main.cc @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -262,7 +261,7 @@ void Backdrop::Main::_apply_image(Xml_node operation) : anchor.vertical == Anchor::HIGH ? v_gap : 0; - Point const offset = Decorator::point_attribute(operation); + Point const offset = Point::from_xml(operation); Point const pos = Point(anchored_xpos, anchored_ypos) + offset; diff --git a/repos/gems/src/app/cbe_tester/verbose_node.h b/repos/gems/src/app/cbe_tester/verbose_node.h index 3b94a30a98..9aa0f1131f 100644 --- a/repos/gems/src/app/cbe_tester/verbose_node.h +++ b/repos/gems/src/app/cbe_tester/verbose_node.h @@ -37,7 +37,7 @@ class Verbose_node Verbose_node(Genode::Xml_node const &config) { - config.with_sub_node("verbose", [&] (Genode::Xml_node const &verbose) + config.with_optional_sub_node("verbose", [&] (Genode::Xml_node const &verbose) { _cmd_pool_cmd_pending = verbose.attribute_value("cmd_pool_cmd_pending" , false); _cmd_pool_cmd_in_progress = verbose.attribute_value("cmd_pool_cmd_in_progress", false); diff --git a/repos/gems/src/app/decorator/main.cc b/repos/gems/src/app/decorator/main.cc index 4440d51551..67983ffa2e 100644 --- a/repos/gems/src/app/decorator/main.cc +++ b/repos/gems/src/app/decorator/main.cc @@ -232,7 +232,7 @@ find_hover(Genode::Xml_node pointer_node, Decorator::Window_stack &window_stack) || !pointer_node.has_attribute("ypos")) return Decorator::Window_base::Hover(); - return window_stack.hover(Decorator::point_attribute(pointer_node)); + return window_stack.hover(Decorator::Point::from_xml(pointer_node)); } diff --git a/repos/gems/src/app/decorator/window.cc b/repos/gems/src/app/decorator/window.cc index ad67c6c900..5895388cf4 100644 --- a/repos/gems/src/app/decorator/window.cc +++ b/repos/gems/src/app/decorator/window.cc @@ -202,7 +202,7 @@ bool Decorator::Window::update(Genode::Xml_node window_node) /* * Detect geometry changes */ - Rect new_geometry = rect_attribute(window_node); + Rect new_geometry = Rect::from_xml(window_node); if (new_geometry.p1() != geometry().p1() || new_geometry.p2() != geometry().p2()) { diff --git a/repos/gems/src/app/depot_deploy/child.h b/repos/gems/src/app/depot_deploy/child.h index 0d7935b98d..cd55356324 100644 --- a/repos/gems/src/app/depot_deploy/child.h +++ b/repos/gems/src/app/depot_deploy/child.h @@ -428,11 +428,11 @@ void Depot_deploy::Child::gen_start_node(Xml_generator &xml, Affinity::Location location { }; if (affinity_from_launcher) - launcher_xml.with_sub_node("affinity", [&] (Xml_node node) { + launcher_xml.with_optional_sub_node("affinity", [&] (Xml_node node) { location = Affinity::Location::from_xml(affinity_space, node); }); if (affinity_from_start) - start_xml.with_sub_node("affinity", [&] (Xml_node node) { + start_xml.with_optional_sub_node("affinity", [&] (Xml_node node) { location = Affinity::Location::from_xml(affinity_space, node); }); xml.node("affinity", [&] () { diff --git a/repos/gems/src/app/depot_deploy/main.cc b/repos/gems/src/app/depot_deploy/main.cc index 65f51aa970..4d4fda8a20 100644 --- a/repos/gems/src/app/depot_deploy/main.cc +++ b/repos/gems/src/app/depot_deploy/main.cc @@ -81,11 +81,14 @@ struct Depot_deploy::Main if (prio_levels.value) xml.attribute("prio_levels", prio_levels.value); - Xml_node static_config = config.sub_node("static"); - static_config.with_raw_content([&] (char const *start, size_t length) { - xml.append(start, length); }); + config.with_sub_node("static", + [&] (Xml_node static_config) { + static_config.with_raw_content([&] (char const *start, size_t length) { + xml.append(start, length); }); + }, + [&] () { warning("config lacks node"); }); - config.with_sub_node("report", [&] (Xml_node const &report) { + config.with_optional_sub_node("report", [&] (Xml_node const &report) { auto copy_bool_attribute = [&] (char const* name) { if (report.has_attribute(name)) { @@ -120,17 +123,21 @@ struct Depot_deploy::Main }); }); - config.with_sub_node("heartbeat", [&] (Xml_node const &heartbeat) { + config.with_optional_sub_node("heartbeat", [&] (Xml_node const &heartbeat) { size_t const rate_ms = heartbeat.attribute_value("rate_ms", 2000UL); xml.node("heartbeat", [&] () { xml.attribute("rate_ms", rate_ms); }); }); - Child::Depot_rom_server const parent { }; - _children.gen_start_nodes(xml, config.sub_node("common_routes"), - prio_levels, Affinity::Space(1, 1), - parent, parent); + config.with_sub_node("common_routes", + [&] (Xml_node node) { + Child::Depot_rom_server const parent { }; + _children.gen_start_nodes(xml, node, + prio_levels, Affinity::Space(1, 1), + parent, parent); + }, + [&] () { warning("config lacks node"); }); }); /* update query for blueprints of all unconfigured start nodes */ diff --git a/repos/gems/src/app/depot_download_manager/gen_extract.cc b/repos/gems/src/app/depot_download_manager/gen_extract.cc index 4c1c66379e..f1947730b4 100644 --- a/repos/gems/src/app/depot_download_manager/gen_extract.cc +++ b/repos/gems/src/app/depot_download_manager/gen_extract.cc @@ -35,13 +35,16 @@ void Depot_download_manager::gen_extract_start_content(Xml_generator &xml, xml.node("vfs", [&] () { xml.node("dir", [&] () { xml.attribute("name", "public"); - xml.node("fs", [&] () { xml.attribute("label", "public"); }); + xml.node("fs", [&] () { + xml.attribute("buffer_size", 144u << 10); + xml.attribute("label", "public"); }); }); xml.node("dir", [&] () { xml.attribute("name", "depot"); xml.node("dir", [&] () { xml.attribute("name", user); xml.node("fs", [&] () { + xml.attribute("buffer_size", 144u << 10); xml.attribute("label", user_path); }); }); }); diff --git a/repos/gems/src/app/depot_download_manager/gen_fetchurl.cc b/repos/gems/src/app/depot_download_manager/gen_fetchurl.cc index a60a73e3e9..5e131f16bd 100644 --- a/repos/gems/src/app/depot_download_manager/gen_fetchurl.cc +++ b/repos/gems/src/app/depot_download_manager/gen_fetchurl.cc @@ -38,6 +38,7 @@ void Depot_download_manager::gen_fetchurl_start_content(Xml_generator &xml, xml.node("dir", [&] () { xml.attribute("name", "download"); xml.node("fs", [&] () { + xml.attribute("buffer_size", 144u << 10); xml.attribute("label", "download"); }); }); xml.node("dir", [&] () { diff --git a/repos/gems/src/app/depot_download_manager/gen_verify.cc b/repos/gems/src/app/depot_download_manager/gen_verify.cc index f40c4f00b1..a0bc66844d 100644 --- a/repos/gems/src/app/depot_download_manager/gen_verify.cc +++ b/repos/gems/src/app/depot_download_manager/gen_verify.cc @@ -32,11 +32,15 @@ void Depot_download_manager::gen_verify_start_content(Xml_generator &xml, xml.node("vfs", [&] () { xml.node("dir", [&] () { xml.attribute("name", "public"); - xml.node("fs", [&] () { xml.attribute("label", "public"); }); + xml.node("fs", [&] () { + xml.attribute("buffer_size", 144u << 10); + xml.attribute("label", "public"); }); }); xml.node("dir", [&] () { xml.attribute("name", "depot"); - xml.node("fs", [&] () { xml.attribute("label", "depot"); }); + xml.node("fs", [&] () { + xml.attribute("buffer_size", 144u << 10); + xml.attribute("label", "depot"); }); }); xml.node("dir", [&] () { xml.attribute("name", "dev"); diff --git a/repos/gems/src/app/depot_download_manager/main.cc b/repos/gems/src/app/depot_download_manager/main.cc index 2b29f57d0d..6c6b1a16ba 100644 --- a/repos/gems/src/app/depot_download_manager/main.cc +++ b/repos/gems/src/app/depot_download_manager/main.cc @@ -409,13 +409,13 @@ void Depot_download_manager::Main::_handle_query_result() Archive::User user { }; if (missing_index_files) - index.with_sub_node("missing", [&] (Xml_node missing) { + index.with_optional_sub_node("missing", [&] (Xml_node missing) { user = missing.attribute_value("user", Archive::User()); }); if (user.valid()) return user; - dependencies.with_sub_node("missing", [&] (Xml_node missing) { + dependencies.with_optional_sub_node("missing", [&] (Xml_node missing) { user = Archive::user(missing.attribute_value("path", Archive::Path())); }); if (!user.valid()) diff --git a/repos/gems/src/app/depot_query/main.cc b/repos/gems/src/app/depot_query/main.cc index 4ed59086b0..c1455eed2a 100644 --- a/repos/gems/src/app/depot_query/main.cc +++ b/repos/gems/src/app/depot_query/main.cc @@ -17,8 +17,8 @@ #include #include #include +#include #include -#include /* fs_query includes */ #include @@ -29,15 +29,93 @@ namespace Depot_query { typedef String<64> Rom_label; + struct Directory_cache; struct Recursion_limit; struct Dependencies; - class Stat_cache; - struct Rom_query; - class Cached_rom_query; struct Main; } +struct Depot_query::Directory_cache : Noncopyable +{ + Allocator &_alloc; + + using Name = Directory::Entry::Name; + + struct Listing; + using Listings = Dictionary; + + struct Listing : Listings::Element + { + Allocator &_alloc; + + struct File; + using Files = Dictionary; + + struct File : Files::Element + { + File(Files &files, Name const &name) : Files::Element(files, name) { } + }; + + Files _files { }; + + Listing(Listings &listings, Allocator &alloc, Directory &dir, + Directory::Path const &path) + : + Listings::Element(listings, path), _alloc(alloc) + { + try { + Directory(dir, path).for_each_entry([&] (Directory::Entry const &entry) { + new (_alloc) File(_files, entry.name()); }); + } + catch (Directory::Nonexistent_directory) { + warning("directory '", path, "' does not exist"); + } + } + + ~Listing() + { + auto destroy_fn = [&] (File &f) { destroy(_alloc, &f); }; + + while (_files.with_any_element(destroy_fn)); + } + + bool file_exists(Name const &name) const { return _files.exists(name); } + }; + + Listings mutable _listings { }; + + Directory_cache(Allocator &alloc) : _alloc(alloc) { } + + ~Directory_cache() + { + auto destroy_fn = [&] (Listing &l) { destroy(_alloc, &l); }; + + while (_listings.with_any_element(destroy_fn)); + } + + bool file_exists(Directory &dir, Directory::Path const &path, Name const &name) const + { + bool listing_known = false; + + bool const result = + _listings.with_element(path, + [&] /* match */ (Listing const &listing) { + listing_known = true; + return listing.file_exists(name); + }, + [&] /* no_match */ { return false; }); + + if (listing_known) + return result; + + Listing &new_listing = *new (_alloc) Listing(_listings, _alloc, dir, path); + + return new_listing.file_exists(name); + } +}; + + class Depot_query::Recursion_limit : Noncopyable { public: @@ -155,172 +233,7 @@ class Depot_query::Dependencies }; -class Depot_query::Stat_cache -{ - private: - - struct Key - { - struct Value - { - Archive::Path path; - - bool operator > (Value const &other) const - { - return strcmp(path.string(), other.path.string()) > 0; - } - - bool operator == (Value const &other) const - { - return path == other.path; - } - - } value; - }; - - struct Result { bool file_exists; }; - - typedef Lru_cache Cache; - - Cache::Size const _size; - - Cache _cache; - - Directory const &_dir; - - public: - - Stat_cache(Directory const &dir, Allocator &alloc, Xml_node const config) - : - _size({.value = config.attribute_value("stat_cache", Number_of_bytes(64*1024)) - / Cache::element_size()}), - _cache(alloc, _size), - _dir(dir) - { } - - bool file_exists(Archive::Path const path) - { - /* don't cache the state of the 'local' depot user */ - if (Archive::user(path) == "local") - return _dir.file_exists(path); - - bool result = false; - - auto hit_fn = [&] (Result const &cached_result) - { - result = cached_result.file_exists; - }; - - auto miss_fn = [&] (Cache::Missing_element &missing_element) - { - Result const stat_result { _dir.file_exists(path) }; - - /* - * Don't cache negative results because files may appear - * during installation. Later queries may find files absent - * from earlier queries. - */ - if (stat_result.file_exists) - missing_element.construct(stat_result); - }; - - Key const key { .value = { .path = path } }; - (void)_cache.try_apply(key, hit_fn, miss_fn); - - return result; - } -}; - - -struct Depot_query::Rom_query : Interface -{ - /** - * Look up ROM module 'rom_label' in the archives referenced by 'pkg_path' - * - * \throw Directory::Nonexistent_directory - * \throw Directory::Nonexistent_file - * \throw File::Truncated_during_read - * \throw Recursion_limit::Reached - */ - virtual Archive::Path find_rom_in_pkg(Directory::Path const &pkg_path, - Rom_label const &rom_label, - Recursion_limit recursion_limit) = 0; -}; - - -class Depot_query::Cached_rom_query : public Rom_query -{ - private: - - struct Key - { - struct Value - { - Archive::Path pkg; - Rom_label rom; - - bool operator > (Value const &other) const - { - return strcmp(pkg.string(), other.pkg.string()) > 0 - && strcmp(rom.string(), other.rom.string()) > 0; - } - - bool operator == (Value const &other) const - { - return pkg == other.pkg && rom == other.rom; - } - - } value; - }; - - typedef Lru_cache Cache; - - Cache::Size const _size; - - Cache mutable _cache; - - Rom_query &_rom_query; - - public: - - Cached_rom_query(Rom_query &rom_query, Allocator &alloc, Xml_node const config) - : - _size({.value = config.attribute_value("rom_query_cache", Number_of_bytes(64*1024)) - / Cache::element_size() }), - _cache(alloc, _size), - _rom_query(rom_query) - { } - - Archive::Path find_rom_in_pkg(Directory::Path const &pkg_path, - Rom_label const &rom_label, - Recursion_limit recursion_limit) override - { - /* don't cache the state of the 'local' depot user */ - if (Archive::user(pkg_path) == "local") - return _rom_query.find_rom_in_pkg(pkg_path, rom_label, recursion_limit); - - Archive::Path result { }; - - auto hit_fn = [&] (Archive::Path const &path) { result = path; }; - - auto miss_fn = [&] (Cache::Missing_element &missing_element) - { - Archive::Path const path = - _rom_query.find_rom_in_pkg(pkg_path, rom_label, recursion_limit); - - if (path.valid()) - missing_element.construct(path); - }; - - Key const key { .value = { .pkg = pkg_path, .rom = rom_label } }; - (void)_cache.try_apply(key, hit_fn, miss_fn); - - return result; - } -}; - - -struct Depot_query::Main : private Rom_query +struct Depot_query::Main { Env &_env; @@ -334,7 +247,7 @@ struct Depot_query::Main : private Rom_query Directory _depot_dir { _root, "depot" }; - Stat_cache _depot_stat_cache { _depot_dir, _heap, _config.xml() }; + Constructible _directory_cache { }; Signal_handler
_config_handler { _env.ep(), *this, &Main::_handle_config }; @@ -365,6 +278,16 @@ struct Depot_query::Main : private Rom_query Architecture _architecture { }; + bool _file_exists(Directory::Path const &path, Rom_label const &file_name) + { + if (!_directory_cache.constructed()) { + error("directory cache is unexpectedly not constructed"); + return false; + } + + return _directory_cache->file_exists(_depot_dir, path, file_name); + } + template void _with_file_content(Directory::Path const &path, char const *name, FN const &fn) { @@ -375,6 +298,7 @@ struct Depot_query::Main : private Rom_query } catch (File_content::Nonexistent_file) { } catch (Directory::Nonexistent_directory) { } + catch (File::Truncated_during_read) { } } /** @@ -399,14 +323,7 @@ struct Depot_query::Main : private Rom_query }); } - Cached_rom_query _cached_rom_query { *this, _heap, _config.xml() }; - - /** - * Rom_query interface - */ - Archive::Path find_rom_in_pkg(Directory::Path const &, Rom_label const &, - Recursion_limit) override; - + Archive::Path _find_rom_in_pkg(File_content const &, Rom_label const &, Recursion_limit); void _gen_rom_path_nodes(Xml_generator &, Xml_node const &, Archive::Path const &, Xml_node const &); void _gen_inherited_rom_path_nodes(Xml_generator &, Xml_node const &, @@ -425,6 +342,8 @@ struct Depot_query::Main : private Rom_query Xml_node const config = _config.xml(); + _directory_cache.construct(_heap); + /* * Depending of the 'query' config attribute, we obtain the query * information from a separate ROM session (attribute value "rom") @@ -449,8 +368,13 @@ struct Depot_query::Main : private Rom_query _construct_if(query.has_sub_node("scan"), _scan_reporter, _env, "scan", "scan"); + /* + * Use 64 KiB as initial report size to avoid the repetitive querying + * when successively expanding the reporter. + */ _construct_if(query.has_sub_node("blueprint"), - _blueprint_reporter, _env, "blueprint", "blueprint"); + _blueprint_reporter, _env, "blueprint", "blueprint", + Expanding_reporter::Initial_buffer_size { 64*1024 }); _construct_if(query.has_sub_node("dependencies"), _dependencies_reporter, _env, "dependencies", "dependencies"); @@ -535,21 +459,10 @@ struct Depot_query::Main : private Rom_query Depot_query::Archive::Path -Depot_query::Main::find_rom_in_pkg(Directory::Path const &pkg_path, - Rom_label const &rom_label, - Recursion_limit recursion_limit) +Depot_query::Main::_find_rom_in_pkg(File_content const &archives, + Rom_label const &rom_label, + Recursion_limit recursion_limit) { - /* - * \throw Directory::Nonexistent_directory - */ - Directory pkg_dir(_depot_dir, pkg_path); - - /* - * \throw Directory::Nonexistent_file - * \throw File::Truncated_during_read - */ - File_content archives(_heap, pkg_dir, "archives", File_content::Limit{16*1024}); - Archive::Path result; archives.for_each_line([&] (Archive::Path const &archive_path) { @@ -561,36 +474,38 @@ Depot_query::Main::find_rom_in_pkg(Directory::Path const &pkg_path, case Archive::SRC: { Archive::Path const - rom_path(Archive::user(archive_path), "/bin/", - _architecture, "/", - Archive::name(archive_path), "/", - Archive::version(archive_path), "/", rom_label); + rom_path(Archive::user(archive_path), "/bin/", + _architecture, "/", + Archive::name(archive_path), "/", + Archive::version(archive_path)); - if (_depot_stat_cache.file_exists(rom_path)) - result = rom_path; + if (_file_exists(rom_path, rom_label)) + result = Archive::Path(rom_path, "/", rom_label); } break; case Archive::RAW: { Archive::Path const - rom_path(Archive::user(archive_path), "/raw/", - Archive::name(archive_path), "/", - Archive::version(archive_path), "/", rom_label); + rom_path(Archive::user(archive_path), "/raw/", + Archive::name(archive_path), "/", + Archive::version(archive_path)); - if (_depot_stat_cache.file_exists(rom_path)) - result = rom_path; + if (_file_exists(rom_path, rom_label)) + result = Archive::Path(rom_path, "/", rom_label); } break; case Archive::PKG: - Archive::Path const result_from_pkg = - _cached_rom_query.find_rom_in_pkg(archive_path, rom_label, recursion_limit); + _with_file_content(archive_path, "archives", [&] (File_content const &archives) { - if (result_from_pkg.valid()) - result = result_from_pkg; + Archive::Path const result_from_pkg = + _find_rom_in_pkg(archives, rom_label, recursion_limit); + if (result_from_pkg.valid()) + result = result_from_pkg; + }); break; } }); @@ -603,43 +518,45 @@ void Depot_query::Main::_gen_rom_path_nodes(Xml_generator &xml, Archive::Path const &pkg_path, Xml_node const &runtime) { - runtime.for_each_sub_node("content", [&] (Xml_node content) { - content.for_each_sub_node([&] (Xml_node node) { + _with_file_content(pkg_path, "archives", [&] (File_content const &archives) { + runtime.for_each_sub_node("content", [&] (Xml_node content) { + content.for_each_sub_node([&] (Xml_node node) { - /* skip non-rom nodes */ - if (!node.has_type("rom")) - return; + /* skip non-rom nodes */ + if (!node.has_type("rom")) + return; - Rom_label const label = node.attribute_value("label", Rom_label()); + Rom_label const label = node.attribute_value("label", Rom_label()); - /* skip ROM that is provided by the environment */ - bool provided_by_env = false; - env_xml.for_each_sub_node("rom", [&] (Xml_node node) { - if (node.attribute_value("label", Rom_label()) == label) - provided_by_env = true; }); + /* skip ROM that is provided by the environment */ + bool provided_by_env = false; + env_xml.for_each_sub_node("rom", [&] (Xml_node node) { + if (node.attribute_value("label", Rom_label()) == label) + provided_by_env = true; }); - if (provided_by_env) { - xml.node("rom", [&] () { - xml.attribute("label", label); - xml.attribute("env", "yes"); - }); - return; - } + if (provided_by_env) { + xml.node("rom", [&] () { + xml.attribute("label", label); + xml.attribute("env", "yes"); + }); + return; + } - Archive::Path const rom_path = - _cached_rom_query.find_rom_in_pkg(pkg_path, label, Recursion_limit{8}); + Archive::Path const rom_path = + _find_rom_in_pkg(archives, label, Recursion_limit{8}); - if (rom_path.valid()) { - xml.node("rom", [&] () { - xml.attribute("label", label); - xml.attribute("path", rom_path); - }); + if (rom_path.valid()) { + xml.node("rom", [&] () { + xml.attribute("label", label); + xml.attribute("path", rom_path); + }); - } else { + } else { - xml.node("missing_rom", [&] () { - xml.attribute("label", label); }); - } + xml.node("missing_rom", [&] () { + xml.attribute("label", label); }); + } + }); }); }); } diff --git a/repos/gems/src/app/driver_manager/main.cc b/repos/gems/src/app/driver_manager/main.cc index fbac4c859c..85be9c78a4 100644 --- a/repos/gems/src/app/driver_manager/main.cc +++ b/repos/gems/src/app/driver_manager/main.cc @@ -358,7 +358,7 @@ struct Driver_manager::Main : private Block_devices_generator Attached_rom_dataspace _platform { _env, "platform_info" }; Attached_rom_dataspace _usb_devices { _env, "usb_devices" }; Attached_rom_dataspace _usb_policy { _env, "usb_policy" }; - Attached_rom_dataspace _pci_devices { _env, "pci_devices" }; + Attached_rom_dataspace _devices { _env, "devices" }; Attached_rom_dataspace _ahci_ports { _env, "ahci_ports" }; Attached_rom_dataspace _nvme_ns { _env, "nvme_ns" }; Attached_rom_dataspace _dynamic_state { _env, "dynamic_state" }; @@ -384,10 +384,10 @@ struct Driver_manager::Main : private Block_devices_generator return Boot_fb_driver::Mode(); } - void _handle_pci_devices_update(); + void _handle_devices_update(); - Signal_handler
_pci_devices_update_handler { - _env.ep(), *this, &Main::_handle_pci_devices_update }; + Signal_handler
_devices_update_handler { + _env.ep(), *this, &Main::_handle_devices_update }; void _handle_usb_devices_update(); @@ -434,7 +434,7 @@ struct Driver_manager::Main : private Block_devices_generator _usb_drv_config.enabled(true); _block_devices.enabled(true); - _pci_devices .sigh(_pci_devices_update_handler); + _devices .sigh(_devices_update_handler); _usb_policy .sigh(_usb_policy_update_handler); _ahci_ports .sigh(_ahci_ports_update_handler); _nvme_ns .sigh(_nvme_ns_update_handler); @@ -442,19 +442,19 @@ struct Driver_manager::Main : private Block_devices_generator _generate_init_config(_init_config); - _handle_pci_devices_update(); + _handle_devices_update(); _handle_ahci_ports_update(); _handle_nvme_ns_update(); } }; -void Driver_manager::Main::_handle_pci_devices_update() +void Driver_manager::Main::_handle_devices_update() { - _pci_devices.update(); + _devices.update(); /* decide about fb not before the first valid pci report is available */ - if (!_pci_devices.valid()) + if (!_devices.valid()) return; bool has_vga = false; @@ -464,33 +464,35 @@ void Driver_manager::Main::_handle_pci_devices_update() Boot_fb_driver::Mode const boot_fb_mode = _boot_fb_mode(); - _pci_devices.xml().for_each_sub_node([&] (Xml_node device) { + _devices.xml().for_each_sub_node([&] (Xml_node device) { + device.with_optional_sub_node("pci-config", [&] (Xml_node pci) { - uint16_t const vendor_id = (uint16_t)device.attribute_value("vendor_id", 0U); - uint16_t const class_code = (uint16_t)(device.attribute_value("class_code", 0U) >> 8); + uint16_t const vendor_id = (uint16_t)pci.attribute_value("vendor_id", 0U); + uint16_t const class_code = (uint16_t)(pci.attribute_value("class", 0U) >> 8); - enum { - VENDOR_VBOX = 0x80EEU, - VENDOR_INTEL = 0x8086U, - CLASS_VGA = 0x300U, - CLASS_AHCI = 0x106U, - CLASS_NVME = 0x108U, - }; + enum { + VENDOR_VBOX = 0x80EEU, + VENDOR_INTEL = 0x8086U, + CLASS_VGA = 0x300U, + CLASS_AHCI = 0x106U, + CLASS_NVME = 0x108U, + }; - if (class_code == CLASS_VGA) - has_vga = true; + if (class_code == CLASS_VGA) + has_vga = true; - if (vendor_id == VENDOR_INTEL && class_code == CLASS_VGA) - has_intel_graphics = true; + if (vendor_id == VENDOR_INTEL && class_code == CLASS_VGA) + has_intel_graphics = true; - if (vendor_id == VENDOR_INTEL && class_code == CLASS_AHCI) - has_ahci = true; + if (vendor_id == VENDOR_INTEL && class_code == CLASS_AHCI) + has_ahci = true; - if (vendor_id == VENDOR_VBOX) - _use_ohci = false; + if (vendor_id == VENDOR_VBOX) + _use_ohci = false; - if (class_code == CLASS_NVME) - has_nvme = true; + if (class_code == CLASS_NVME) + has_nvme = true; + }); }); if (!_intel_fb_driver.constructed() && has_intel_graphics) { diff --git a/repos/gems/src/app/file_vault/main.cc b/repos/gems/src/app/file_vault/main.cc index e944481640..e20ebd6bda 100644 --- a/repos/gems/src/app/file_vault/main.cc +++ b/repos/gems/src/app/file_vault/main.cc @@ -541,7 +541,7 @@ bool Main::cbe_control_file_yields_state_idle(Xml_node const &fs_query_listing, { bool result { false }; bool done { false }; - fs_query_listing.with_sub_node("dir", [&] (Xml_node const &node_0) { + fs_query_listing.with_optional_sub_node("dir", [&] (Xml_node const &node_0) { node_0.for_each_sub_node("file", [&] (Xml_node const &node_1) { if (done) { return; @@ -631,8 +631,8 @@ Main::State_string Main::_state_to_string(State state) Main::State Main::_state_from_fs_query_listing(Xml_node const &node) { State state { State::INVALID }; - node.with_sub_node("dir", [&] (Xml_node const &node_0) { - node_0.with_sub_node("file", [&] (Xml_node const &node_1) { + node.with_optional_sub_node("dir", [&] (Xml_node const &node_0) { + node_0.with_optional_sub_node("file", [&] (Xml_node const &node_1) { if (_has_name(node_1, "state")) { state = _state_from_string( node_1.decoded_content()); @@ -817,7 +817,7 @@ void Main::_handle_snapshots_fs_query_listing(Xml_node const &node) case State::CONTROLS_SECURITY_USER_PASSPHRASE: { bool update_dialog { false }; - node.with_sub_node("dir", [&] (Xml_node const &node_0) { + node.with_optional_sub_node("dir", [&] (Xml_node const &node_0) { _snapshots.for_each([&] (Snapshot const &snap) { @@ -931,8 +931,8 @@ void Main::_handle_client_fs_fs_query_listing(Xml_node const &node) switch (_state) { case State::STARTUP_DETERMINE_CLIENT_FS_SIZE: - node.with_sub_node("dir", [&] (Xml_node const &node_0) { - node_0.with_sub_node("file", [&] (Xml_node const &node_1) { + node.with_optional_sub_node("dir", [&] (Xml_node const &node_0) { + node_0.with_optional_sub_node("file", [&] (Xml_node const &node_1) { if (_has_name(node_1, "data")) { @@ -957,8 +957,8 @@ void Main::_handle_client_fs_fs_query_listing(Xml_node const &node) switch (_resizing_state) { case Resizing_state::DETERMINE_CLIENT_FS_SIZE: - node.with_sub_node("dir", [&] (Xml_node const &node_0) { - node_0.with_sub_node("file", [&] (Xml_node const &node_1) { + node.with_optional_sub_node("dir", [&] (Xml_node const &node_0) { + node_0.with_optional_sub_node("file", [&] (Xml_node const &node_1) { if (_has_name(node_1, "data")) { @@ -1010,8 +1010,8 @@ void Main::_handle_image_fs_query_listing(Xml_node const &node) case State::CONTROLS_SECURITY_USER_PASSPHRASE: { size_t size { 0 }; - node.with_sub_node("dir", [&] (Xml_node const &node_0) { - node_0.with_sub_node("file", [&] (Xml_node const &node_1) { + node.with_optional_sub_node("dir", [&] (Xml_node const &node_0) { + node_0.with_optional_sub_node("file", [&] (Xml_node const &node_1) { if (_has_name(node_1, "cbe.img")) { size = node_1.attribute_value("size", (size_t)0); } @@ -1063,7 +1063,7 @@ _child_nr_of_provided_sessions(Xml_node const &sandbox_state, if (child.attribute_value("name", String<128> { }) == child_state.start_name()) { - child.with_sub_node("provided", [&] (Xml_node const &provided) { + child.with_optional_sub_node("provided", [&] (Xml_node const &provided) { provided.for_each_sub_node("session", [&] (Xml_node const &session) { if (session.attribute_value("service", String<64> { }) == service_name) { @@ -3507,24 +3507,24 @@ void File_vault::Main::_handle_hover(Xml_node const &node) Setup_obtain_params_hover const prev_hover { _setup_obtain_params_hover }; Setup_obtain_params_hover next_hover { Setup_obtain_params_hover::NONE }; - node.with_sub_node("dialog", [&] (Xml_node const &node_0) { - node_0.with_sub_node("frame", [&] (Xml_node const &node_1) { - node_1.with_sub_node("vbox", [&] (Xml_node const &node_2) { + node.with_optional_sub_node("dialog", [&] (Xml_node const &node_0) { + node_0.with_optional_sub_node("frame", [&] (Xml_node const &node_1) { + node_1.with_optional_sub_node("vbox", [&] (Xml_node const &node_2) { - node_2.with_sub_node("float", [&] (Xml_node const &node_3) { + node_2.with_optional_sub_node("float", [&] (Xml_node const &node_3) { if (_has_name(node_3, "ok")) { next_hover = Setup_obtain_params_hover::START_BUTTON; } }); - node_2.with_sub_node("hbox", [&] (Xml_node const &node_3) { - node_3.with_sub_node("frame", [&] (Xml_node const &node_4) { + node_2.with_optional_sub_node("hbox", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("frame", [&] (Xml_node const &node_4) { if (_has_name(node_4, "Passphrase")) { next_hover = Setup_obtain_params_hover::PASSPHRASE_INPUT; } }); - node_3.with_sub_node("float", [&] (Xml_node const &node_4) { - node_4.with_sub_node("button", [&] (Xml_node const &node_5) { + node_3.with_optional_sub_node("float", [&] (Xml_node const &node_4) { + node_4.with_optional_sub_node("button", [&] (Xml_node const &node_5) { if (_has_name(node_5, "Show Hide")) { next_hover = Setup_obtain_params_hover::PASSPHRASE_SHOW_HIDE_BUTTON; @@ -3532,7 +3532,7 @@ void File_vault::Main::_handle_hover(Xml_node const &node) }); }); }); - node_2.with_sub_node("frame", [&] (Xml_node const &node_3) { + node_2.with_optional_sub_node("frame", [&] (Xml_node const &node_3) { if (_has_name(node_3, "Client FS Size")) { next_hover = Setup_obtain_params_hover::CLIENT_FS_SIZE_INPUT; @@ -3556,24 +3556,24 @@ void File_vault::Main::_handle_hover(Xml_node const &node) Setup_obtain_params_hover const prev_hover { _setup_obtain_params_hover }; Setup_obtain_params_hover next_hover { Setup_obtain_params_hover::NONE }; - node.with_sub_node("dialog", [&] (Xml_node const &node_0) { - node_0.with_sub_node("frame", [&] (Xml_node const &node_1) { - node_1.with_sub_node("vbox", [&] (Xml_node const &node_2) { + node.with_optional_sub_node("dialog", [&] (Xml_node const &node_0) { + node_0.with_optional_sub_node("frame", [&] (Xml_node const &node_1) { + node_1.with_optional_sub_node("vbox", [&] (Xml_node const &node_2) { - node_2.with_sub_node("float", [&] (Xml_node const &node_3) { + node_2.with_optional_sub_node("float", [&] (Xml_node const &node_3) { if (_has_name(node_3, "ok")) { next_hover = Setup_obtain_params_hover::START_BUTTON; } }); - node_2.with_sub_node("hbox", [&] (Xml_node const &node_3) { - node_3.with_sub_node("frame", [&] (Xml_node const &node_4) { + node_2.with_optional_sub_node("hbox", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("frame", [&] (Xml_node const &node_4) { if (_has_name(node_4, "Passphrase")) { next_hover = Setup_obtain_params_hover::PASSPHRASE_INPUT; } }); - node_3.with_sub_node("float", [&] (Xml_node const &node_4) { - node_4.with_sub_node("button", [&] (Xml_node const &node_5) { + node_3.with_optional_sub_node("float", [&] (Xml_node const &node_4) { + node_4.with_optional_sub_node("button", [&] (Xml_node const &node_5) { if (_has_name(node_5, "Show Hide")) { next_hover = Setup_obtain_params_hover::PASSPHRASE_SHOW_HIDE_BUTTON; @@ -3596,11 +3596,11 @@ void File_vault::Main::_handle_hover(Xml_node const &node) Controls_root_hover const prev_hover { _controls_root_hover }; Controls_root_hover next_hover { Controls_root_hover::NONE }; - node.with_sub_node("dialog", [&] (Xml_node const &node_0) { - node_0.with_sub_node("frame", [&] (Xml_node const &node_1) { - node_1.with_sub_node("vbox", [&] (Xml_node const &node_2) { - node_2.with_sub_node("hbox", [&] (Xml_node const &node_3) { - node_3.with_sub_node("button", [&] (Xml_node const &node_4) { + node.with_optional_sub_node("dialog", [&] (Xml_node const &node_0) { + node_0.with_optional_sub_node("frame", [&] (Xml_node const &node_1) { + node_1.with_optional_sub_node("vbox", [&] (Xml_node const &node_2) { + node_2.with_optional_sub_node("hbox", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("button", [&] (Xml_node const &node_4) { if (_has_name(node_4, "Shut down")) { @@ -3609,9 +3609,9 @@ void File_vault::Main::_handle_hover(Xml_node const &node) } }); }); - node_2.with_sub_node("frame", [&] (Xml_node const &node_3) { - node_3.with_sub_node("vbox", [&] (Xml_node const &node_4) { - node_4.with_sub_node("vbox", [&] (Xml_node const &node_5) { + node_2.with_optional_sub_node("frame", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("vbox", [&] (Xml_node const &node_4) { + node_4.with_optional_sub_node("vbox", [&] (Xml_node const &node_5) { if (_has_name(node_5, "Snapshots")) { @@ -3646,11 +3646,11 @@ void File_vault::Main::_handle_hover(Xml_node const &node) Snapshot_pointer const prev_snapshots_hover { _snapshots_hover }; Snapshot_pointer next_snapshots_hover { }; - node.with_sub_node("dialog", [&] (Xml_node const &node_0) { - node_0.with_sub_node("frame", [&] (Xml_node const &node_1) { - node_1.with_sub_node("vbox", [&] (Xml_node const &node_2) { - node_2.with_sub_node("hbox", [&] (Xml_node const &node_3) { - node_3.with_sub_node("button", [&] (Xml_node const &node_4) { + node.with_optional_sub_node("dialog", [&] (Xml_node const &node_0) { + node_0.with_optional_sub_node("frame", [&] (Xml_node const &node_1) { + node_1.with_optional_sub_node("vbox", [&] (Xml_node const &node_2) { + node_2.with_optional_sub_node("hbox", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("button", [&] (Xml_node const &node_4) { if (_has_name(node_4, "Shut down")) { @@ -3658,20 +3658,20 @@ void File_vault::Main::_handle_hover(Xml_node const &node) } }); }); - node_2.with_sub_node("frame", [&] (Xml_node const &node_3) { - node_3.with_sub_node("vbox", [&] (Xml_node const &node_4) { - node_4.with_sub_node("vbox", [&] (Xml_node const &node_5) { + node_2.with_optional_sub_node("frame", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("vbox", [&] (Xml_node const &node_4) { + node_4.with_optional_sub_node("vbox", [&] (Xml_node const &node_5) { if (_snapshots_select.valid()) { - node_5.with_sub_node("hbox", [&] (Xml_node const &node_6) { + node_5.with_optional_sub_node("hbox", [&] (Xml_node const &node_6) { if (_has_name(node_6, "Leave")) { next_hover = Controls_snapshots_hover::GENERATION_LEAVE_BUTTON; } }); - node_5.with_sub_node("button", [&] (Xml_node const &node_6) { + node_5.with_optional_sub_node("button", [&] (Xml_node const &node_6) { if (_has_name(node_6, "Discard")) { @@ -3681,18 +3681,18 @@ void File_vault::Main::_handle_hover(Xml_node const &node) } else { - node_5.with_sub_node("hbox", [&] (Xml_node const &node_6) { + node_5.with_optional_sub_node("hbox", [&] (Xml_node const &node_6) { if (_has_name(node_6, "Leave")) { next_hover = Controls_snapshots_hover::LEAVE_BUTTON; } }); - node_5.with_sub_node("vbox", [&] (Xml_node const &node_6) { + node_5.with_optional_sub_node("vbox", [&] (Xml_node const &node_6) { if (_has_name(node_6, "Generations")) { - node_6.with_sub_node("float", [&] (Xml_node const &node_7) { + node_6.with_optional_sub_node("float", [&] (Xml_node const &node_7) { Generation const generation { node_7.attribute_value( @@ -3710,7 +3710,7 @@ void File_vault::Main::_handle_hover(Xml_node const &node) }); } }); - node_5.with_sub_node("button", [&] (Xml_node const &node_6) { + node_5.with_optional_sub_node("button", [&] (Xml_node const &node_6) { if (_has_name(node_6, "Create")) { @@ -3741,11 +3741,11 @@ void File_vault::Main::_handle_hover(Xml_node const &node) Dimensions_hover const prev_hover { _dimensions_hover }; Dimensions_hover next_hover { Dimensions_hover::NONE }; - node.with_sub_node("dialog", [&] (Xml_node const &node_0) { - node_0.with_sub_node("frame", [&] (Xml_node const &node_1) { - node_1.with_sub_node("vbox", [&] (Xml_node const &node_2) { - node_2.with_sub_node("hbox", [&] (Xml_node const &node_3) { - node_3.with_sub_node("button", [&] (Xml_node const &node_4) { + node.with_optional_sub_node("dialog", [&] (Xml_node const &node_0) { + node_0.with_optional_sub_node("frame", [&] (Xml_node const &node_1) { + node_1.with_optional_sub_node("vbox", [&] (Xml_node const &node_2) { + node_2.with_optional_sub_node("hbox", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("button", [&] (Xml_node const &node_4) { if (_has_name(node_4, "Shut down")) { @@ -3753,16 +3753,16 @@ void File_vault::Main::_handle_hover(Xml_node const &node) } }); }); - node_2.with_sub_node("frame", [&] (Xml_node const &node_3) { - node_3.with_sub_node("vbox", [&] (Xml_node const &node_4) { - node_4.with_sub_node("hbox", [&] (Xml_node const &node_5) { + node_2.with_optional_sub_node("frame", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("vbox", [&] (Xml_node const &node_4) { + node_4.with_optional_sub_node("hbox", [&] (Xml_node const &node_5) { if (_has_name(node_5, "Leave")) { next_hover = Dimensions_hover::LEAVE_BUTTON; } }); - node_4.with_sub_node("vbox", [&] (Xml_node const &node_5) { + node_4.with_optional_sub_node("vbox", [&] (Xml_node const &node_5) { if (_has_name(node_5, "Expand Client FS")) { @@ -3793,11 +3793,11 @@ void File_vault::Main::_handle_hover(Xml_node const &node) Expand_client_fs_hover const prev_hover { _expand_client_fs_hover }; Expand_client_fs_hover next_hover { Expand_client_fs_hover::NONE }; - node.with_sub_node("dialog", [&] (Xml_node const &node_0) { - node_0.with_sub_node("frame", [&] (Xml_node const &node_1) { - node_1.with_sub_node("vbox", [&] (Xml_node const &node_2) { - node_2.with_sub_node("hbox", [&] (Xml_node const &node_3) { - node_3.with_sub_node("button", [&] (Xml_node const &node_4) { + node.with_optional_sub_node("dialog", [&] (Xml_node const &node_0) { + node_0.with_optional_sub_node("frame", [&] (Xml_node const &node_1) { + node_1.with_optional_sub_node("vbox", [&] (Xml_node const &node_2) { + node_2.with_optional_sub_node("hbox", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("button", [&] (Xml_node const &node_4) { if (_has_name(node_4, "Shut down")) { @@ -3806,24 +3806,24 @@ void File_vault::Main::_handle_hover(Xml_node const &node) } }); }); - node_2.with_sub_node("frame", [&] (Xml_node const &node_3) { - node_3.with_sub_node("vbox", [&] (Xml_node const &node_4) { - node_4.with_sub_node("vbox", [&] (Xml_node const &node_5) { - node_5.with_sub_node("hbox", [&] (Xml_node const &node_6) { + node_2.with_optional_sub_node("frame", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("vbox", [&] (Xml_node const &node_4) { + node_4.with_optional_sub_node("vbox", [&] (Xml_node const &node_5) { + node_5.with_optional_sub_node("hbox", [&] (Xml_node const &node_6) { if (_has_name(node_6, "Leave")) { next_hover = Expand_client_fs_hover::LEAVE_BUTTON; } }); - node_5.with_sub_node("float", [&] (Xml_node const &node_6) { + node_5.with_optional_sub_node("float", [&] (Xml_node const &node_6) { if (_has_name(node_6, "Start")) { next_hover = Expand_client_fs_hover::START_BUTTON; } }); - node_5.with_sub_node("frame", [&] (Xml_node const &node_6) { + node_5.with_optional_sub_node("frame", [&] (Xml_node const &node_6) { if (_has_name(node_6, "Contingent")) { @@ -3848,12 +3848,12 @@ void File_vault::Main::_handle_hover(Xml_node const &node) Expand_snapshot_buf_hover const prev_hover { _expand_snapshot_buf_hover }; Expand_snapshot_buf_hover next_hover { Expand_snapshot_buf_hover::NONE }; - node.with_sub_node("dialog", [&] (Xml_node const &node_0) { - node_0.with_sub_node("frame", [&] (Xml_node const &node_1) { - node_1.with_sub_node("vbox", [&] (Xml_node const &node_2) { - node_2.with_sub_node("hbox", [&] (Xml_node const &node_3) { + node.with_optional_sub_node("dialog", [&] (Xml_node const &node_0) { + node_0.with_optional_sub_node("frame", [&] (Xml_node const &node_1) { + node_1.with_optional_sub_node("vbox", [&] (Xml_node const &node_2) { + node_2.with_optional_sub_node("hbox", [&] (Xml_node const &node_3) { - node_3.with_sub_node("button", [&] (Xml_node const &node_4) { + node_3.with_optional_sub_node("button", [&] (Xml_node const &node_4) { if (_has_name(node_4, "Shut down")) { @@ -3862,25 +3862,25 @@ void File_vault::Main::_handle_hover(Xml_node const &node) } }); }); - node_2.with_sub_node("frame", [&] (Xml_node const &node_3) { - node_3.with_sub_node("vbox", [&] (Xml_node const &node_4) { - node_4.with_sub_node("vbox", [&] (Xml_node const &node_5) { + node_2.with_optional_sub_node("frame", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("vbox", [&] (Xml_node const &node_4) { + node_4.with_optional_sub_node("vbox", [&] (Xml_node const &node_5) { - node_5.with_sub_node("hbox", [&] (Xml_node const &node_6) { + node_5.with_optional_sub_node("hbox", [&] (Xml_node const &node_6) { if (_has_name(node_6, "Leave")) { next_hover = Expand_snapshot_buf_hover::LEAVE_BUTTON; } }); - node_5.with_sub_node("float", [&] (Xml_node const &node_6) { + node_5.with_optional_sub_node("float", [&] (Xml_node const &node_6) { if (_has_name(node_6, "Start")) { next_hover = Expand_snapshot_buf_hover::START_BUTTON; } }); - node_5.with_sub_node("frame", [&] (Xml_node const &node_6) { + node_5.with_optional_sub_node("frame", [&] (Xml_node const &node_6) { if (_has_name(node_6, "Contingent")) { @@ -3905,11 +3905,11 @@ void File_vault::Main::_handle_hover(Xml_node const &node) Controls_security_hover const prev_hover { _controls_security_hover }; Controls_security_hover next_hover { Controls_security_hover::NONE }; - node.with_sub_node("dialog", [&] (Xml_node const &node_0) { - node_0.with_sub_node("frame", [&] (Xml_node const &node_1) { - node_1.with_sub_node("vbox", [&] (Xml_node const &node_2) { - node_2.with_sub_node("hbox", [&] (Xml_node const &node_3) { - node_3.with_sub_node("button", [&] (Xml_node const &node_4) { + node.with_optional_sub_node("dialog", [&] (Xml_node const &node_0) { + node_0.with_optional_sub_node("frame", [&] (Xml_node const &node_1) { + node_1.with_optional_sub_node("vbox", [&] (Xml_node const &node_2) { + node_2.with_optional_sub_node("hbox", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("button", [&] (Xml_node const &node_4) { if (_has_name(node_4, "Shut down")) { @@ -3918,16 +3918,16 @@ void File_vault::Main::_handle_hover(Xml_node const &node) } }); }); - node_2.with_sub_node("frame", [&] (Xml_node const &node_3) { - node_3.with_sub_node("vbox", [&] (Xml_node const &node_4) { - node_4.with_sub_node("hbox", [&] (Xml_node const &node_5) { + node_2.with_optional_sub_node("frame", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("vbox", [&] (Xml_node const &node_4) { + node_4.with_optional_sub_node("hbox", [&] (Xml_node const &node_5) { if (_has_name(node_5, "Leave")) { next_hover = Controls_security_hover::SECURITY_EXPAND_BUTTON; } }); - node_4.with_sub_node("vbox", [&] (Xml_node const &node_5) { + node_4.with_optional_sub_node("vbox", [&] (Xml_node const &node_5) { if (_has_name(node_5, "Block Encryption Key")) { @@ -3959,11 +3959,11 @@ void File_vault::Main::_handle_hover(Xml_node const &node) Controls_security_block_encryption_key_hover const prev_hover { _controls_security_block_encryption_key_hover }; Controls_security_block_encryption_key_hover next_hover { Controls_security_block_encryption_key_hover::NONE }; - node.with_sub_node("dialog", [&] (Xml_node const &node_0) { - node_0.with_sub_node("frame", [&] (Xml_node const &node_1) { - node_1.with_sub_node("vbox", [&] (Xml_node const &node_2) { - node_2.with_sub_node("hbox", [&] (Xml_node const &node_3) { - node_3.with_sub_node("button", [&] (Xml_node const &node_4) { + node.with_optional_sub_node("dialog", [&] (Xml_node const &node_0) { + node_0.with_optional_sub_node("frame", [&] (Xml_node const &node_1) { + node_1.with_optional_sub_node("vbox", [&] (Xml_node const &node_2) { + node_2.with_optional_sub_node("hbox", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("button", [&] (Xml_node const &node_4) { if (_has_name(node_4, "Shut down")) { @@ -3972,16 +3972,16 @@ void File_vault::Main::_handle_hover(Xml_node const &node) } }); }); - node_2.with_sub_node("frame", [&] (Xml_node const &node_3) { - node_3.with_sub_node("vbox", [&] (Xml_node const &node_4) { - node_4.with_sub_node("button", [&] (Xml_node const &node_5) { + node_2.with_optional_sub_node("frame", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("vbox", [&] (Xml_node const &node_4) { + node_4.with_optional_sub_node("button", [&] (Xml_node const &node_5) { if (_has_name(node_5, "Rekey")) { next_hover = Controls_security_block_encryption_key_hover::REPLACE_BUTTON; } }); - node_4.with_sub_node("hbox", [&] (Xml_node const &node_5) { + node_4.with_optional_sub_node("hbox", [&] (Xml_node const &node_5) { if (_has_name(node_5, "Leave")) { @@ -4005,11 +4005,11 @@ void File_vault::Main::_handle_hover(Xml_node const &node) Controls_security_master_key_hover const prev_hover { _controls_security_master_key_hover }; Controls_security_master_key_hover next_hover { Controls_security_master_key_hover::NONE }; - node.with_sub_node("dialog", [&] (Xml_node const &node_0) { - node_0.with_sub_node("frame", [&] (Xml_node const &node_1) { - node_1.with_sub_node("vbox", [&] (Xml_node const &node_2) { - node_2.with_sub_node("hbox", [&] (Xml_node const &node_3) { - node_3.with_sub_node("button", [&] (Xml_node const &node_4) { + node.with_optional_sub_node("dialog", [&] (Xml_node const &node_0) { + node_0.with_optional_sub_node("frame", [&] (Xml_node const &node_1) { + node_1.with_optional_sub_node("vbox", [&] (Xml_node const &node_2) { + node_2.with_optional_sub_node("hbox", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("button", [&] (Xml_node const &node_4) { if (_has_name(node_4, "Shut down")) { @@ -4018,9 +4018,9 @@ void File_vault::Main::_handle_hover(Xml_node const &node) } }); }); - node_2.with_sub_node("frame", [&] (Xml_node const &node_3) { - node_3.with_sub_node("vbox", [&] (Xml_node const &node_4) { - node_4.with_sub_node("hbox", [&] (Xml_node const &node_5) { + node_2.with_optional_sub_node("frame", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("vbox", [&] (Xml_node const &node_4) { + node_4.with_optional_sub_node("hbox", [&] (Xml_node const &node_5) { if (_has_name(node_5, "Leave")) { @@ -4044,11 +4044,11 @@ void File_vault::Main::_handle_hover(Xml_node const &node) Controls_security_user_passphrase_hover const prev_hover { _controls_security_user_passphrase_hover }; Controls_security_user_passphrase_hover next_hover { Controls_security_user_passphrase_hover::NONE }; - node.with_sub_node("dialog", [&] (Xml_node const &node_0) { - node_0.with_sub_node("frame", [&] (Xml_node const &node_1) { - node_1.with_sub_node("vbox", [&] (Xml_node const &node_2) { - node_2.with_sub_node("hbox", [&] (Xml_node const &node_3) { - node_3.with_sub_node("button", [&] (Xml_node const &node_4) { + node.with_optional_sub_node("dialog", [&] (Xml_node const &node_0) { + node_0.with_optional_sub_node("frame", [&] (Xml_node const &node_1) { + node_1.with_optional_sub_node("vbox", [&] (Xml_node const &node_2) { + node_2.with_optional_sub_node("hbox", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("button", [&] (Xml_node const &node_4) { if (_has_name(node_4, "Shut down")) { @@ -4057,9 +4057,9 @@ void File_vault::Main::_handle_hover(Xml_node const &node) } }); }); - node_2.with_sub_node("frame", [&] (Xml_node const &node_3) { - node_3.with_sub_node("vbox", [&] (Xml_node const &node_4) { - node_4.with_sub_node("hbox", [&] (Xml_node const &node_5) { + node_2.with_optional_sub_node("frame", [&] (Xml_node const &node_3) { + node_3.with_optional_sub_node("vbox", [&] (Xml_node const &node_4) { + node_4.with_optional_sub_node("hbox", [&] (Xml_node const &node_5) { if (_has_name(node_5, "Leave")) { diff --git a/repos/gems/src/app/gpt_write/main.cc b/repos/gems/src/app/gpt_write/main.cc index 06cc00061b..11ca60f12f 100644 --- a/repos/gems/src/app/gpt_write/main.cc +++ b/repos/gems/src/app/gpt_write/main.cc @@ -762,7 +762,7 @@ struct Main } bool success = false; - config.with_sub_node("actions", [&] (Genode::Xml_node actions) { + config.with_optional_sub_node("actions", [&] (Genode::Xml_node actions) { success = _writer->execute_actions(actions); }); _env.parent().exit(success ? 0 : 1); diff --git a/repos/gems/src/app/menu_view/box_layout_widget.h b/repos/gems/src/app/menu_view/box_layout_widget.h index 7af362885b..51e22e3d17 100644 --- a/repos/gems/src/app/menu_view/box_layout_widget.h +++ b/repos/gems/src/app/menu_view/box_layout_widget.h @@ -56,6 +56,10 @@ struct Menu_view::Box_layout_widget : Widget w.position(position); + /* don't account space for zero-sized child widgets */ + if (child_min_size.count() == 0) + return; + if (_direction == VERTICAL) { unsigned const next_top_margin = w.next() ? w.next()->margin.top : 0; unsigned const dy = child_min_size.h() - min(w.margin.bottom, next_top_margin); @@ -65,6 +69,7 @@ struct Menu_view::Box_layout_widget : Widget unsigned const dx = child_min_size.w() - min(w.margin.right, next_left_margin); position = position + Point(dx, 0); } + _count++; }); @@ -99,7 +104,10 @@ struct Menu_view::Box_layout_widget : Widget w.position(w.geometry().p1() + Point(consumed_fp >> 8, 0)); w.size(Area(w.min_size().w() + padding_pixels, geometry().h())); } - consumed_fp = next_consumed_fp; + + /* don't account space for zero-sized child widgets */ + if (w.min_size().count()) + consumed_fp = next_consumed_fp; }); } diff --git a/repos/gems/src/app/menu_view/main.cc b/repos/gems/src/app/menu_view/main.cc index ef818f25ff..ae04f2f673 100644 --- a/repos/gems/src/app/menu_view/main.cc +++ b/repos/gems/src/app/menu_view/main.cc @@ -128,6 +128,10 @@ struct Menu_view::Main Attached_dataspace _input_ds { _env.rm(), _gui.input()->dataspace() }; + bool _opaque = false; + + Color _background_color { }; + Widget::Hovered _last_reported_hovered { }; void _handle_config(); @@ -255,14 +259,10 @@ void Menu_view::Main::_handle_dialog_update() { _styles.flush_outdated_styles(); - try { - Xml_node const config = _config.xml(); + Xml_node const config = _config.xml(); - _position = Decorator::point_attribute(config); - - _configured_size = Area(config.attribute_value("width", 0U), - config.attribute_value("height", 0U)); - } catch (...) { } + _position = Point::from_xml(config); + _configured_size = Area ::from_xml(config); _dialog_rom.update(); @@ -300,14 +300,20 @@ void Menu_view::Main::_handle_config() { _config.update(); + Xml_node const config = _config.xml(); + try { - _hover_reporter.enabled(_config.xml().sub_node("report") - .attribute_value("hover", false)); + _hover_reporter.enabled(config.sub_node("report") + .attribute_value("hover", false)); } catch (...) { _hover_reporter.enabled(false); } - _config.xml().with_sub_node("vfs", [&] (Xml_node const &vfs_node) { + _opaque = config.attribute_value("opaque", false); + + _background_color = config.attribute_value("background", Color(127, 127, 127, 255)); + + config.with_optional_sub_node("vfs", [&] (Xml_node const &vfs_node) { _vfs_env.root_dir().apply_config(vfs_node); }); _handle_dialog_update(); @@ -393,10 +399,17 @@ void Menu_view::Main::_handle_frame_timer() bool const size_increased = (max_size.w() > buffer_w) || (max_size.h() > buffer_h); - if (!_buffer.constructed() || size_increased) - _buffer.construct(_gui, max_size, _env.ram(), _env.rm()); - else + if (!_buffer.constructed() || size_increased) { + _buffer.construct(_gui, max_size, _env.ram(), _env.rm(), + _opaque ? Gui_buffer::Alpha::OPAQUE + : Gui_buffer::Alpha::ALPHA); + _buffer->reset_color = { _background_color.r, + _background_color.g, + _background_color.b, + _background_color.a }; + } else { _buffer->reset_surface(); + } _root_widget.position(Point(0, 0)); diff --git a/repos/gems/src/app/menu_view/style_database.h b/repos/gems/src/app/menu_view/style_database.h index 08a527e170..640d2d3165 100644 --- a/repos/gems/src/app/menu_view/style_database.h +++ b/repos/gems/src/app/menu_view/style_database.h @@ -126,7 +126,7 @@ class Menu_view::Style_database Style_database const &_style_database; - Cached_font::Limit _font_cache_limit { 256*1024 }; + Cached_font::Limit _font_cache_limit { 1024*1024 }; Vfs_font _vfs_font; Cached_font _cached_font; diff --git a/repos/gems/src/app/menu_view/styles/frame/important/background.png b/repos/gems/src/app/menu_view/styles/frame/important/background.png new file mode 100644 index 0000000000..231587c210 Binary files /dev/null and b/repos/gems/src/app/menu_view/styles/frame/important/background.png differ diff --git a/repos/gems/src/app/menu_view/target.mk b/repos/gems/src/app/menu_view/target.mk index 7deabdadfd..473b384127 100644 --- a/repos/gems/src/app/menu_view/target.mk +++ b/repos/gems/src/app/menu_view/target.mk @@ -3,9 +3,15 @@ SRC_CC = main.cc LIBS = base libc libm vfs libpng zlib blit file INC_DIR += $(PRG_DIR) +CC_OLEVEL := -O3 + CUSTOM_TARGET_DEPS += menu_view_styles.tar BUILD_ARTIFACTS := $(TARGET) menu_view_styles.tar +.PHONY: menu_view_styles.tar + menu_view_styles.tar: - $(VERBOSE)cd $(PRG_DIR); tar cf $(PWD)/bin/$@ styles + $(MSG_CONVERT)$@ + $(VERBOSE)tar cf $@ -C $(PRG_DIR) styles + $(VERBOSE)ln -sf $(BUILD_BASE_DIR)/$(PRG_REL_DIR)/$@ $(INSTALL_DIR)/$@ diff --git a/repos/gems/src/app/menu_view/types.h b/repos/gems/src/app/menu_view/types.h index 15860c2af4..99c24ff874 100644 --- a/repos/gems/src/app/menu_view/types.h +++ b/repos/gems/src/app/menu_view/types.h @@ -17,7 +17,6 @@ /* Genode includes */ #include #include -#include #include #include #include diff --git a/repos/gems/src/app/sculpt_manager/deploy.h b/repos/gems/src/app/sculpt_manager/deploy.h index 9670454c38..296ff54834 100644 --- a/repos/gems/src/app/sculpt_manager/deploy.h +++ b/repos/gems/src/app/sculpt_manager/deploy.h @@ -185,7 +185,6 @@ struct Sculpt::Deploy { _managed_deploy_rom.update(); handle_deploy(); - _depot_query.trigger_depot_query(); } /** diff --git a/repos/gems/src/app/sculpt_manager/graph.cc b/repos/gems/src/app/sculpt_manager/graph.cc index 2e179f5e8b..225d5a7ee2 100644 --- a/repos/gems/src/app/sculpt_manager/graph.cc +++ b/repos/gems/src/app/sculpt_manager/graph.cc @@ -302,25 +302,22 @@ Dialog::Hover_result Graph::hover(Xml_node hover) /* update anchor geometry of popup menu */ auto hovered_rect = [] (Xml_node const dialog) { - if (!dialog.has_type("dialog")) return Rect(); + if (!dialog.has_type("dialog")) + return Rect(); - auto point_from_xml = [] (Xml_node node) { - return Point((int)node.attribute_value("xpos", 0L), - (int)node.attribute_value("ypos", 0L)); }; + if (!dialog.has_sub_node("depgraph")) + return Rect(); - auto area_from_xml = [] (Xml_node node) { - return Area(node.attribute_value("width", 0U), - node.attribute_value("height", 0U)); }; - - if (!dialog.has_sub_node("depgraph")) return Rect(); Xml_node const depgraph = dialog.sub_node("depgraph"); - if (!depgraph.has_sub_node("button")) return Rect(); + if (!depgraph.has_sub_node("button")) + return Rect(); + Xml_node const button = depgraph.sub_node("button"); - return Rect(point_from_xml(dialog) + point_from_xml(depgraph) + - point_from_xml(button), - area_from_xml(button)); + return Rect(Point::from_xml(dialog) + Point::from_xml(depgraph) + + Point::from_xml(button), + Area::from_xml(button)); }; _popup_anchor = hovered_rect(hover); diff --git a/repos/gems/src/app/sculpt_manager/keyboard_focus.h b/repos/gems/src/app/sculpt_manager/keyboard_focus.h index 183e899bb0..3720dfdfa0 100644 --- a/repos/gems/src/app/sculpt_manager/keyboard_focus.h +++ b/repos/gems/src/app/sculpt_manager/keyboard_focus.h @@ -18,6 +18,7 @@ #include /* local includes */ +#include #include #include #include diff --git a/repos/gems/src/app/sculpt_manager/main.cc b/repos/gems/src/app/sculpt_manager/main.cc index 2c409c72a1..cd5a9785e5 100644 --- a/repos/gems/src/app/sculpt_manager/main.cc +++ b/repos/gems/src/app/sculpt_manager/main.cc @@ -53,6 +53,7 @@ struct Sculpt::Main : Input_event_handler, Dialog::Generator, Runtime_config_generator, Storage::Target_user, + Network::Action, Graph::Action, Panel_dialog::Action, Popup_dialog::Action, @@ -90,6 +91,14 @@ struct Sculpt::Main : Input_event_handler, handle_input_event(ev); }); } + Managed_config
_system_config { + _env, "system", "system", *this, &Main::_handle_system_config }; + + void _handle_system_config(Xml_node) + { + _system_config.try_generate_manually_managed(); + } + Signal_handler
_gui_mode_handler { _env.ep(), *this, &Main::_handle_gui_mode }; @@ -170,16 +179,19 @@ struct Sculpt::Main : Input_event_handler, void _handle_pci_devices() { _pci_devices.update(); - _pci_info.wifi_present = false; + _pci_info.wifi_present = false; + _pci_info.lan_present = true; + _pci_info.modem_present = false; _pci_devices.xml().for_each_sub_node("device", [&] (Xml_node device) { - - /* detect Intel Wireless card */ - if (device.attribute_value("class_code", 0UL) == 0x28000) - _pci_info.wifi_present = true; + device.with_optional_sub_node("pci-config", [&] (Xml_node pci) { + /* detect Intel Wireless card */ + if (pci.attribute_value("class", 0UL) == 0x28000) + _pci_info.wifi_present = true; + }); }); - _network.update_view(); + update_network_dialog(); } @@ -213,8 +225,20 @@ struct Sculpt::Main : Input_event_handler, generate_runtime_config(); } + Network _network { _env, _heap, *this, _child_states, *this, _runtime_state, _pci_info }; - Network _network { _env, _heap, _child_states, *this, *this, _runtime_state, _pci_info }; + Menu_view _network_menu_view { _env, _child_states, _network.dialog, "network_view", + Ram_quota{4*1024*1024}, Cap_quota{150}, + "network_dialog", "network_view_hover", + *this }; + + /** + * Network::Action interface + */ + void update_network_dialog() override + { + _network_menu_view.generate(); + } /************ @@ -362,7 +386,6 @@ struct Sculpt::Main : Input_event_handler, _deploy._handle_managed_deploy(); } - Deploy _deploy { _env, _heap, _child_states, _runtime_state, *this, *this, *this, _launcher_listing_rom, _blueprint_rom, _download_queue }; @@ -522,6 +545,7 @@ struct Sculpt::Main : Input_event_handler, Attached_rom_dataspace const _platform { _env, "platform_info" }; + /**************************************** ** Cached model of the runtime config ** ****************************************/ @@ -637,9 +661,9 @@ struct Sculpt::Main : Input_event_handler, _settings_menu_view.generate(); _clicked_seq_number.destruct(); } - else if (_network.dialog_hovered(seq)) { + else if (_network_menu_view.hovered(seq)) { _network.dialog.click(_network); - _network.update_view(); + _network_menu_view.generate(); _clicked_seq_number.destruct(); } else if (_file_browser_menu_view.hovered(seq)) { @@ -786,6 +810,11 @@ struct Sculpt::Main : Input_event_handler, _network.restart_wifi_drv_on_next_runtime_cfg(); generate_runtime_config(); + } else if (name == "usb_net") { + + _network.restart_usb_net_on_next_runtime_cfg(); + generate_runtime_config(); + } else { _runtime_state.restart(name); @@ -1219,7 +1248,6 @@ struct Sculpt::Main : Input_event_handler, */ _handle_gui_mode(); _storage.handle_storage_devices_update(); - _deploy.handle_deploy(); _handle_pci_devices(); _handle_runtime_config(); _handle_clicked(); @@ -1227,7 +1255,7 @@ struct Sculpt::Main : Input_event_handler, /* * Read static platform information */ - _platform.xml().with_sub_node("affinity-space", [&] (Xml_node const &node) { + _platform.xml().with_optional_sub_node("affinity-space", [&] (Xml_node const &node) { _affinity_space = Affinity::Space(node.attribute_value("width", 1U), node.attribute_value("height", 1U)); }); @@ -1289,9 +1317,7 @@ void Sculpt::Main::_handle_window_layout() _window_list.update(); Xml_node const window_list = _window_list.xml(); - auto win_size = [&] (Xml_node win) { - return Area(win.attribute_value("width", 0U), - win.attribute_value("height", 0U)); }; + auto win_size = [&] (Xml_node win) { return Area::from_xml(win); }; unsigned panel_height = 0; _with_window(window_list, panel_view_label, [&] (Xml_node win) { @@ -1543,7 +1569,7 @@ void Sculpt::Main::_handle_gui_mode() _panel_menu_view.min_width = _screen_size.w(); unsigned const menu_width = max((unsigned)(_font_size_px*21.0), 320u); _main_menu_view.min_width = menu_width; - _network.min_dialog_width(menu_width); + _network_menu_view.min_width = menu_width; /* font size may has changed, propagate fonts config of runtime view */ generate_runtime_config(); @@ -1572,20 +1598,21 @@ void Sculpt::Main::_handle_update_state() _download_queue.apply_update_state(update_state); _download_queue.remove_inactive_downloads(); - Xml_node const blueprint = _blueprint_rom.xml(); - bool const new_depot_query_needed = popup_watches_downloads - || blueprint_any_missing(blueprint) - || blueprint_any_rom_missing(blueprint); - if (new_depot_query_needed) - trigger_depot_query(); - - if (popup_watches_downloads) - _deploy.update_installation(); - bool const installation_complete = !update_state.attribute_value("progress", false); if (installation_complete) { + + Xml_node const blueprint = _blueprint_rom.xml(); + bool const new_depot_query_needed = popup_watches_downloads + || blueprint_any_missing(blueprint) + || blueprint_any_rom_missing(blueprint); + if (new_depot_query_needed) + trigger_depot_query(); + + if (popup_watches_downloads) + _deploy.update_installation(); + _deploy.reattempt_after_installation(); } } @@ -1719,9 +1746,6 @@ void Sculpt::Main::_handle_runtime_state() if (exit_state.exited) { _prepare_completed = _prepare_version; - /* trigger deployment */ - _deploy.handle_deploy(); - /* trigger update and deploy */ reconfigure_runtime = true; } @@ -1765,12 +1789,6 @@ void Sculpt::Main::_handle_runtime_state() } }); - /* - * Re-attempt NIC-router configuration as the uplink may have become - * available in the meantime. - */ - _network.reattempt_nic_router_config(); - if (_deploy.update_child_conditions()) { reconfigure_runtime = true; regenerate_dialog = true; @@ -1838,7 +1856,7 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const _panel_menu_view.gen_start_node(xml); _main_menu_view.gen_start_node(xml); _settings_menu_view.gen_start_node(xml); - _network._menu_view.gen_start_node(xml); + _network_menu_view.gen_start_node(xml); _popup_menu_view.gen_start_node(xml); _file_browser_menu_view.gen_start_node(xml); diff --git a/repos/gems/src/app/sculpt_manager/managed_config.h b/repos/gems/src/app/sculpt_manager/managed_config.h index 8188c262a5..0122f6b726 100644 --- a/repos/gems/src/app/sculpt_manager/managed_config.h +++ b/repos/gems/src/app/sculpt_manager/managed_config.h @@ -68,6 +68,12 @@ struct Sculpt::Managed_config (_obj.*_handle)(_manual_config_rom.xml()); } + template + void with_manual_config(FN const &fn) const + { + fn(_manual_config_rom.xml()); + } + /** * \return true if manually-managed configuration could be used */ diff --git a/repos/gems/src/app/sculpt_manager/menu_view.cc b/repos/gems/src/app/sculpt_manager/menu_view.cc index 8035b083ac..b6b01c8c89 100644 --- a/repos/gems/src/app/sculpt_manager/menu_view.cc +++ b/repos/gems/src/app/sculpt_manager/menu_view.cc @@ -35,7 +35,7 @@ void Menu_view::_handle_hover() _seq_number.construct(seq); } - hover.with_sub_node("dialog", [&] (Xml_node hover) { + hover.with_optional_sub_node("dialog", [&] (Xml_node hover) { _hovered = true; hover_result = _dialog.hover(hover); }); @@ -59,14 +59,16 @@ Menu_view::Menu_view(Env &env, Registry ®istry, Ram_quota ram_quota, Cap_quota cap_quota, Session_label const &dialog_report_name, Session_label const &hover_rom_name, - Hover_update_handler &hover_update_handler) + Hover_update_handler &hover_update_handler, + Alpha alpha, Color background_color) : _dialog(dialog), _hover_update_handler(hover_update_handler), _child_state(registry, name, Priority::LEITZENTRALE, ram_quota, cap_quota), _dialog_reporter(env, "dialog", dialog_report_name.string()), _hover_rom(env, hover_rom_name.string()), - _hover_handler(env.ep(), *this, &Menu_view::_handle_hover) + _hover_handler(env.ep(), *this, &Menu_view::_handle_hover), + _opaque(alpha == Alpha::OPAQUE), _background_color(background_color) { _hover_rom.sigh(_hover_handler); @@ -108,6 +110,9 @@ void Menu_view::_gen_start_node_content(Xml_generator &xml) const xml.node("config", [&] () { if (min_width) xml.attribute("width", min_width); if (min_height) xml.attribute("height", min_height); + if (_opaque) xml.attribute("opaque", "yes"); + + xml.attribute("background", String<20>(_background_color)); xml.node("libc", [&] () { xml.attribute("stderr", "/dev/log"); }); xml.node("report", [&] () { xml.attribute("hover", "yes"); }); diff --git a/repos/gems/src/app/sculpt_manager/menu_view.h b/repos/gems/src/app/sculpt_manager/menu_view.h index 6e9b8f8ea0..0c87b37492 100644 --- a/repos/gems/src/app/sculpt_manager/menu_view.h +++ b/repos/gems/src/app/sculpt_manager/menu_view.h @@ -46,6 +46,10 @@ struct Sculpt::Menu_view : Noncopyable Signal_handler _hover_handler; + bool const _opaque; + + Color const _background_color; + bool _hovered = false; Constructible _seq_number { }; @@ -57,11 +61,15 @@ struct Sculpt::Menu_view : Noncopyable void _gen_start_node_content(Xml_generator &) const; + enum class Alpha { OPAQUE, ALPHA }; + Menu_view(Env &, Registry ®istry, Dialog &, Start_name const &, Ram_quota, Cap_quota, Session_label const &dialog_report_name, Session_label const &hover_rom_name, - Hover_update_handler &); + Hover_update_handler &, + Alpha alpha = Alpha::ALPHA, + Color background = Color { 127, 127, 127, 255 }); void generate(); diff --git a/repos/gems/src/app/sculpt_manager/model/component.h b/repos/gems/src/app/sculpt_manager/model/component.h index 1010df658e..dc3eaf0e6b 100644 --- a/repos/gems/src/app/sculpt_manager/model/component.h +++ b/repos/gems/src/app/sculpt_manager/model/component.h @@ -67,12 +67,12 @@ struct Sculpt::Component : Noncopyable if (path != pkg.attribute_value("path", Path())) return; - pkg.with_sub_node("runtime", [&] (Xml_node runtime) { + pkg.with_optional_sub_node("runtime", [&] (Xml_node runtime) { ram = runtime.attribute_value("ram", Number_of_bytes()); caps = runtime.attribute_value("caps", 0UL); - runtime.with_sub_node("requires", [&] (Xml_node requires) { + runtime.with_optional_sub_node("requires", [&] (Xml_node requires) { routes.update_from_xml(_route_update_policy, requires); }); }); diff --git a/repos/gems/src/app/sculpt_manager/model/file_browser_state.h b/repos/gems/src/app/sculpt_manager/model/file_browser_state.h index 3eee4050bf..fc620b6c87 100644 --- a/repos/gems/src/app/sculpt_manager/model/file_browser_state.h +++ b/repos/gems/src/app/sculpt_manager/model/file_browser_state.h @@ -68,7 +68,7 @@ struct Sculpt::File_browser_state : Noncopyable { unsigned cnt = 0; with_query_result([&] (Xml_node node) { - node.with_sub_node("dir", [&] (Xml_node listing) { + node.with_optional_sub_node("dir", [&] (Xml_node listing) { listing.for_each_sub_node([&] (Xml_node entry) { if (Index(cnt++) == index) fn(entry); }); }); }); diff --git a/repos/gems/src/app/sculpt_manager/model/file_operation_queue.h b/repos/gems/src/app/sculpt_manager/model/file_operation_queue.h index 5c1934de19..bbdeca53e7 100644 --- a/repos/gems/src/app/sculpt_manager/model/file_operation_queue.h +++ b/repos/gems/src/app/sculpt_manager/model/file_operation_queue.h @@ -15,6 +15,7 @@ #define _MODEL__FILE_OPERATION_QUEUE_H_ #include +#include #include namespace Sculpt { struct File_operation_queue; } diff --git a/repos/gems/src/app/sculpt_manager/model/nic_target.h b/repos/gems/src/app/sculpt_manager/model/nic_target.h index 0ecd282262..712533aca6 100644 --- a/repos/gems/src/app/sculpt_manager/model/nic_target.h +++ b/repos/gems/src/app/sculpt_manager/model/nic_target.h @@ -32,7 +32,7 @@ struct Sculpt::Nic_target : Noncopyable * config is provided, it takes precedence over the 'UNDEFINED' managed * state. */ - enum Type { UNDEFINED, OFF, LOCAL, WIRED, WIFI }; + enum Type { UNDEFINED, OFF, DISCONNECTED, WIRED, WIFI, MODEM }; /** * Interactive selection by the user, used when managed policy is in effect @@ -68,15 +68,17 @@ struct Sculpt::Nic_target : Noncopyable return (result == UNDEFINED) ? OFF : result; } - bool local() const { return type() == LOCAL; } + bool local() const { return type() == DISCONNECTED; } bool wired() const { return type() == WIRED; } bool wifi() const { return type() == WIFI; } + bool modem() const { return type() == MODEM; } bool nic_router_needed() const { return type() != OFF; } bool ready() const { return type() == WIRED || type() == WIFI || - type() == LOCAL; } + type() == MODEM || + type() == DISCONNECTED; } }; #endif /* _MODEL__NIC_TARGET_H_ */ diff --git a/repos/gems/src/app/sculpt_manager/model/pci_info.h b/repos/gems/src/app/sculpt_manager/model/pci_info.h index e36b59e6f7..19b2b8977c 100644 --- a/repos/gems/src/app/sculpt_manager/model/pci_info.h +++ b/repos/gems/src/app/sculpt_manager/model/pci_info.h @@ -20,7 +20,9 @@ namespace Sculpt { struct Pci_info; } struct Sculpt::Pci_info { - bool wifi_present = false; + bool wifi_present = false; + bool lan_present = false; + bool modem_present = false; }; #endif /* _MODEL__PCI_INFO_H_ */ diff --git a/repos/gems/src/app/sculpt_manager/model/runtime_config.h b/repos/gems/src/app/sculpt_manager/model/runtime_config.h index a4fb9b56d3..c9eac86b36 100644 --- a/repos/gems/src/app/sculpt_manager/model/runtime_config.h +++ b/repos/gems/src/app/sculpt_manager/model/runtime_config.h @@ -47,13 +47,13 @@ class Sculpt::Runtime_config static Start_name _to_name(Xml_node node) { Start_name result { }; - node.with_sub_node("child", [&] (Xml_node child) { + node.with_optional_sub_node("child", [&] (Xml_node child) { result = child.attribute_value("name", Start_name()); }); if (result.valid()) return result; - node.with_sub_node("parent", [&] (Xml_node parent) { + node.with_optional_sub_node("parent", [&] (Xml_node parent) { Service::Type_name const service = node.attribute_value("name", Service::Type_name()); @@ -143,8 +143,8 @@ class Sculpt::Runtime_config static Start_name _primary_dependency(Xml_node const start) { Start_name result { }; - start.with_sub_node("route", [&] (Xml_node route) { - route.with_sub_node("service", [&] (Xml_node service) { + start.with_optional_sub_node("route", [&] (Xml_node route) { + route.with_optional_sub_node("service", [&] (Xml_node service) { result = _to_name(service); }); }); return result; @@ -291,14 +291,14 @@ class Sculpt::Runtime_config { Dep::Update_policy policy { _alloc }; - node.with_sub_node("route", [&] (Xml_node route) { + node.with_optional_sub_node("route", [&] (Xml_node route) { elem.deps.update_from_xml(policy, route); }); } { Child_service::Update_policy policy { elem.name, _alloc }; - node.with_sub_node("provides", [&] (Xml_node provides) { + node.with_optional_sub_node("provides", [&] (Xml_node provides) { elem._child_services.update_from_xml(policy, provides); }); } @@ -340,7 +340,7 @@ class Sculpt::Runtime_config _vimrc { _r, Type::ROM, "default vim configuration", "config -> vimrc" }, _fonts { _r, Type::ROM, "system font configuration", "config -> managed/fonts" }, _pf_info { _r, Type::ROM, "platform information", "platform_info" }, - _system { _r, Type::ROM, "system status", "config -> system" }, + _system { _r, Type::ROM, "system status", "config -> managed/system" }, _report { _r, Type::REPORT, "system reports" }, _shape { _r, Type::REPORT, "pointer shape", "shape", Service::Match_label::LAST }, _copy { _r, Type::REPORT, "global clipboard", "clipboard", Service::Match_label::LAST }, diff --git a/repos/gems/src/app/sculpt_manager/network.cc b/repos/gems/src/app/sculpt_manager/network.cc index 365a4994f8..b386fad5a9 100644 --- a/repos/gems/src/app/sculpt_manager/network.cc +++ b/repos/gems/src/app/sculpt_manager/network.cc @@ -50,22 +50,12 @@ void Sculpt::Network::handle_key_press(Codepoint code) if (_wifi_connection.state == Wifi_connection::CONNECTING) wifi_connect(_wifi_connection.bssid); - _menu_view.generate(); + _action.update_network_dialog(); } void Sculpt::Network::_generate_nic_router_config() { - if ((_nic_target.wired() && !_runtime_info.present_in_runtime("nic_drv")) - || (_nic_target.wifi() && !_runtime_info.present_in_runtime("wifi_drv"))) { - - /* defer NIC router reconfiguration until the needed uplink is present */ - _nic_router_config_up_to_date = false; - return; - } - - _nic_router_config_up_to_date = true; - if (_nic_router_config.try_generate_manually_managed()) return; @@ -90,8 +80,9 @@ void Sculpt::Network::_generate_nic_router_config() bool uplink_exists = true; switch (_nic_target.type()) { - case Nic_target::WIRED: _generate_nic_router_uplink(xml, "nic_drv -> "); break; - case Nic_target::WIFI: _generate_nic_router_uplink(xml, "wifi_drv -> "); break; + case Nic_target::WIRED: _generate_nic_router_uplink(xml, "nic_drv -> "); break; + case Nic_target::WIFI: _generate_nic_router_uplink(xml, "wifi_drv -> "); break; + case Nic_target::MODEM: _generate_nic_router_uplink(xml, "usb_net -> "); break; default: uplink_exists = false; } gen_named_node(xml, "domain", "default", [&] () { @@ -100,7 +91,7 @@ void Sculpt::Network::_generate_nic_router_config() xml.node("dhcp-server", [&] () { xml.attribute("ip_first", "10.0.1.2"); xml.attribute("ip_last", "10.0.1.200"); - if (_nic_target.type() != Nic_target::LOCAL) { + if (_nic_target.type() != Nic_target::DISCONNECTED) { xml.attribute("dns_config_from", "uplink"); } }); @@ -136,7 +127,7 @@ void Sculpt::Network::_handle_wlan_accesspoints() Access_point_update_policy policy(_alloc); _access_points.update_from_xml(policy, _wlan_accesspoints_rom.xml()); - _menu_view.generate(); + _action.update_network_dialog(); } @@ -144,7 +135,7 @@ void Sculpt::Network::_handle_wlan_state() { _wlan_state_rom.update(); _wifi_connection = Wifi_connection::from_xml(_wlan_state_rom.xml()); - _menu_view.generate(); + _action.update_network_dialog(); } @@ -156,7 +147,7 @@ void Sculpt::Network::_handle_nic_router_state() _nic_state = Nic_state::from_xml(_nic_router_state_rom.xml()); if (_nic_state.ipv4 != old_nic_state.ipv4) - _menu_view.generate(); + _action.update_network_dialog(); /* if the nic state becomes ready, consider spawning the update subsystem */ if (old_nic_state.ready() != _nic_state.ready()) @@ -164,53 +155,49 @@ void Sculpt::Network::_handle_nic_router_state() } -void Sculpt::Network::_handle_nic_router_config(Xml_node config) +void Sculpt::Network::_update_nic_target_from_config(Xml_node const &config) { - Nic_target::Type target = _nic_target.managed_type; - _nic_target.policy = config.has_type("empty") ? Nic_target::MANAGED : Nic_target::MANUAL; - if (_nic_target.manual()) { - - /* obtain uplink information from configuration */ - target = Nic_target::LOCAL; - + /* obtain uplink information from configuration */ + auto nic_target_from_config = [] (Xml_node const &config) + { if (!config.has_sub_node("domain")) - target = Nic_target::OFF; + return Nic_target::OFF; - struct Break : Exception { }; - try { - config.for_each_sub_node("domain", [&] (Xml_node domain) { + Nic_target::Type result = Nic_target::DISCONNECTED; - /* skip domains that are not called "uplink" */ - if (domain.attribute_value("name", String<16>()) != "uplink") - return; + config.for_each_sub_node("policy", [&] (Xml_node uplink) { - config.for_each_sub_node("policy", [&] (Xml_node uplink) { + /* skip uplinks not assigned to a domain called "uplink" */ + if (uplink.attribute_value("domain", String<16>()) != "uplink") + return; - /* skip uplinks not assigned to a domain called "uplink" */ - if (uplink.attribute_value("domain", String<16>()) != "uplink") - return; + if (uplink.attribute_value("label", String<16>()) == "nic_drv -> ") + result = Nic_target::WIRED; - if (uplink.attribute_value("label", String<16>()) == "nic_drv -> ") { - target = Nic_target::WIRED; - throw Break(); - } - if (uplink.attribute_value("label", String<16>()) == "wifi_drv -> ") { - target = Nic_target::WIFI; - throw Break(); - } - }); - }); - } catch (Break) { } - _nic_target.manual_type = target; - } + if (uplink.attribute_value("label", String<16>()) == "wifi_drv -> ") + result = Nic_target::WIFI; - nic_target(target); + if (uplink.attribute_value("label", String<16>()) == "usb_net -> ") + result = Nic_target::MODEM; + }); + return result; + }; + + if (_nic_target.manual()) + _nic_target.manual_type = nic_target_from_config(config); +} + + + +void Sculpt::Network::_handle_nic_router_config(Xml_node config) +{ + _update_nic_target_from_config(config); _generate_nic_router_config(); _runtime_config_generator.generate_runtime_config(); - _menu_view.generate(); + _action.update_network_dialog(); } @@ -235,17 +222,24 @@ void Sculpt::Network::gen_runtime_start_nodes(Xml_generator &xml) const xml.node("start", [&] () { gen_nic_router_start_content(xml); }); break; - case Nic_target::LOCAL: + case Nic_target::MODEM: + + xml.node("start", [&] () { + xml.attribute("version", _usb_net_version); + gen_usb_net_start_content(xml); + }); + xml.node("start", [&] () { gen_nic_router_start_content(xml); }); + break; + + case Nic_target::DISCONNECTED: xml.node("start", [&] () { gen_nic_router_start_content(xml); }); break; case Nic_target::OFF: - break; case Nic_target::UNDEFINED: - break; } } diff --git a/repos/gems/src/app/sculpt_manager/network.h b/repos/gems/src/app/sculpt_manager/network.h index 1eb41732e3..bfbdff0d60 100644 --- a/repos/gems/src/app/sculpt_manager/network.h +++ b/repos/gems/src/app/sculpt_manager/network.h @@ -20,6 +20,7 @@ /* local includes */ #include +#include #include #include #include @@ -35,9 +36,14 @@ struct Sculpt::Network : Network_dialog::Action Allocator &_alloc; - Registry &_child_states; + struct Action : Interface + { + virtual void update_network_dialog() = 0; + }; - Menu_view::Hover_update_handler &_hover_update_handler; + Action &_action; + + Registry &_child_states; Runtime_config_generator &_runtime_config_generator; @@ -47,12 +53,11 @@ struct Sculpt::Network : Network_dialog::Action Nic_target _nic_target { }; Nic_state _nic_state { }; - bool _nic_router_config_up_to_date = false; - Wpa_passphrase wpa_passphrase { }; - unsigned _nic_drv_version = 0; + unsigned _nic_drv_version = 0; unsigned _wifi_drv_version = 0; + unsigned _usb_net_version = 0; Attached_rom_dataspace _wlan_accesspoints_rom { _env, "report -> runtime/wifi_drv/accesspoints" }; @@ -103,19 +108,6 @@ struct Sculpt::Network : Network_dialog::Action _wifi_connection, _nic_state, wpa_passphrase, _wlan_config_policy, _pci_info }; - Menu_view _menu_view { _env, _child_states, dialog, "network_view", - Ram_quota{4*1024*1024}, Cap_quota{150}, - "network_dialog", "network_view_hover", - _hover_update_handler }; - - void min_dialog_width(unsigned value) { _menu_view.min_width = value; } - - bool dialog_hovered(Input::Seq_number seq) const { return _menu_view.hovered(seq); } - - void update_view() { _menu_view.generate(); } - - void trigger_dialog_restart() { _menu_view.trigger_restart(); } - Managed_config _wlan_config { _env, "config", "wifi", *this, &Network::_handle_wlan_config }; @@ -123,7 +115,7 @@ struct Sculpt::Network : Network_dialog::Action { if (_wlan_config.try_generate_manually_managed()) { _wlan_config_policy = Network_dialog::WLAN_CONFIG_MANUAL; - _menu_view.generate(); + _action.update_network_dialog(); return; } @@ -135,11 +127,7 @@ struct Sculpt::Network : Network_dialog::Action wifi_disconnect(); } - void reattempt_nic_router_config() - { - if (_nic_target.nic_router_needed() && !_nic_router_config_up_to_date) - _generate_nic_router_config(); - } + void _update_nic_target_from_config(Xml_node const &); /** * Network_dialog::Action interface @@ -150,7 +138,7 @@ struct Sculpt::Network : Network_dialog::Action _nic_target.managed_type = type; _generate_nic_router_config(); _runtime_config_generator.generate_runtime_config(); - _menu_view.generate(); + _action.update_network_dialog(); } } @@ -187,15 +175,9 @@ struct Sculpt::Network : Network_dialog::Action }); } - void restart_nic_drv_on_next_runtime_cfg() - { - _nic_drv_version++; - } - - void restart_wifi_drv_on_next_runtime_cfg() - { - _wifi_drv_version++; - } + void restart_nic_drv_on_next_runtime_cfg() { _nic_drv_version++; } + void restart_wifi_drv_on_next_runtime_cfg() { _wifi_drv_version++; } + void restart_usb_net_on_next_runtime_cfg() { _usb_net_version++; } void wifi_disconnect() override { @@ -225,24 +207,30 @@ struct Sculpt::Network : Network_dialog::Action _runtime_config_generator.generate_runtime_config(); } - Network(Env &env, Allocator &alloc, Registry &child_states, - Menu_view::Hover_update_handler &hover_update_handler, + Network(Env &env, Allocator &alloc, Action &action, + Registry &child_states, Runtime_config_generator &runtime_config_generator, Runtime_info const &runtime_info, Pci_info const &pci_info) : - _env(env), _alloc(alloc), _child_states(child_states), - _hover_update_handler(hover_update_handler), + _env(env), _alloc(alloc), _action(action), _child_states(child_states), _runtime_config_generator(runtime_config_generator), _runtime_info(runtime_info), _pci_info(pci_info) { - _generate_nic_router_config(); - /* * Subscribe to reports */ _wlan_accesspoints_rom.sigh(_wlan_accesspoints_handler); _wlan_state_rom .sigh(_wlan_state_handler); _nic_router_state_rom .sigh(_nic_router_state_handler); + + /* + * Evaluate and forward initial manually managed config + */ + _nic_router_config.with_manual_config([&] (Xml_node const &config) { + _update_nic_target_from_config(config); }); + + if (_nic_target.manual()) + _generate_nic_router_config(); } }; diff --git a/repos/gems/src/app/sculpt_manager/runtime.cc b/repos/gems/src/app/sculpt_manager/runtime.cc index 2e9f767aaf..d1455a6035 100644 --- a/repos/gems/src/app/sculpt_manager/runtime.cc +++ b/repos/gems/src/app/sculpt_manager/runtime.cc @@ -30,3 +30,4 @@ #include #include #include +#include diff --git a/repos/gems/src/app/sculpt_manager/runtime.h b/repos/gems/src/app/sculpt_manager/runtime.h index e61cc092d1..837c920109 100644 --- a/repos/gems/src/app/sculpt_manager/runtime.h +++ b/repos/gems/src/app/sculpt_manager/runtime.h @@ -71,6 +71,7 @@ namespace Sculpt { void gen_nic_drv_start_content(Xml_generator &); void gen_wifi_drv_start_content(Xml_generator &); + void gen_usb_net_start_content(Xml_generator &); void gen_nic_router_start_content(Xml_generator &); void gen_nic_router_uplink(Xml_generator &, char const *); diff --git a/repos/gems/src/app/sculpt_manager/runtime/file_system.cc b/repos/gems/src/app/sculpt_manager/runtime/file_system.cc index 57a6c5856b..4ed933b089 100644 --- a/repos/gems/src/app/sculpt_manager/runtime/file_system.cc +++ b/repos/gems/src/app/sculpt_manager/runtime/file_system.cc @@ -18,7 +18,7 @@ void Sculpt::gen_fs_start_content(Xml_generator &xml, File_system::Type fs_type) { gen_common_start_content(xml, target.fs(), - Cap_quota{400}, Ram_quota{64*1024*1024}, + Cap_quota{400}, Ram_quota{72*1024*1024}, Priority::STORAGE); gen_named_node(xml, "binary", "vfs"); diff --git a/repos/gems/src/app/sculpt_manager/runtime/inspect_view.cc b/repos/gems/src/app/sculpt_manager/runtime/inspect_view.cc index 4593d0efec..50977d652a 100644 --- a/repos/gems/src/app/sculpt_manager/runtime/inspect_view.cc +++ b/repos/gems/src/app/sculpt_manager/runtime/inspect_view.cc @@ -53,7 +53,7 @@ static void gen_vfs_start(Xml_generator &xml, Ram_fs_state const &ram_fs_state) { gen_common_start_content(xml, "vfs", - Cap_quota{200}, Ram_quota{5*1024*1024}, + Cap_quota{200}, Ram_quota{6*1024*1024}, Priority::LEITZENTRALE); gen_provides<::File_system::Session>(xml); @@ -79,7 +79,9 @@ static void gen_vfs_start(Xml_generator &xml, auto fs_dir = [&] (String<64> const &label) { gen_named_node(xml, "dir", label, [&] () { - xml.node("fs", [&] () { xml.attribute("label", label); }); }); }; + xml.node("fs", [&] () { + xml.attribute("buffer_size", 272u << 10); + xml.attribute("label", label); }); }); }; fs_dir("config"); fs_dir("report"); @@ -152,7 +154,7 @@ static void gen_fs_rom_start(Xml_generator &xml) static void gen_bash_start(Xml_generator &xml) { gen_common_start_content(xml, "bash", - Cap_quota{400}, Ram_quota{15*1024*1024}, + Cap_quota{400}, Ram_quota{16*1024*1024}, Priority::LEITZENTRALE); gen_named_node(xml, "binary", "/bin/bash", [&] () { }); @@ -167,7 +169,9 @@ static void gen_bash_start(Xml_generator &xml) xml.attribute("rtc", "/dev/rtc"); }); - xml.node("vfs", [&] () { xml.node("fs", [&] () { }); }); + xml.node("vfs", [&] () { + xml.node("fs", [&] () { + xml.attribute("buffer_size", 272u << 10); }); }); auto gen_env = [&] (auto key, auto value) { xml.node("env", [&] () { diff --git a/repos/gems/src/app/sculpt_manager/runtime/usb_net.cc b/repos/gems/src/app/sculpt_manager/runtime/usb_net.cc new file mode 100644 index 0000000000..5f8c5810ab --- /dev/null +++ b/repos/gems/src/app/sculpt_manager/runtime/usb_net.cc @@ -0,0 +1,52 @@ +/* + * \brief XML configuration for USB network driver + * \author Norman Feske + * \date 2022-08-24 + */ + +/* + * Copyright (C) 2022 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. + */ + +#include + +void Sculpt::gen_usb_net_start_content(Xml_generator &xml) +{ + gen_common_start_content(xml, "usb_net", + Cap_quota{200}, Ram_quota{20*1024*1024}, + Priority::NETWORK); + + xml.node("binary", [&] () { + xml.attribute("name", "usb_net_drv"); + }); + + xml.node("config", [&] () { + xml.attribute("mac", "02:00:00:00:01:05"); + }); + + xml.node("route", [&] () { + + xml.node("service", [&] () { + xml.attribute("name", "Uplink"); + xml.node("child", [&] () { + xml.attribute("name", "nic_router"); + xml.attribute("label", "usb_net -> "); + }); + }); + + gen_service_node(xml, [&] () { + xml.node("parent", [&] () { + xml.attribute("label", "usb_net"); }); }); + + gen_parent_rom_route(xml, "usb_net_drv"); + gen_parent_rom_route(xml, "ld.lib.so"); + gen_parent_route (xml); + gen_parent_route (xml); + gen_parent_route (xml); + gen_parent_route (xml); + gen_parent_route(xml); + }); +} diff --git a/repos/gems/src/app/sculpt_manager/runtime/wifi_drv.cc b/repos/gems/src/app/sculpt_manager/runtime/wifi_drv.cc index 84b00c0531..a72dd1af9f 100644 --- a/repos/gems/src/app/sculpt_manager/runtime/wifi_drv.cc +++ b/repos/gems/src/app/sculpt_manager/runtime/wifi_drv.cc @@ -87,6 +87,7 @@ void Sculpt::gen_wifi_drv_start_content(Xml_generator &xml) gen_parent_rom_route(xml, "iwlwifi-9000-pu-b0-jf-b0-34.ucode"); gen_parent_rom_route(xml, "iwlwifi-9000-pu-b0-jf-b0-46.ucode"); gen_parent_rom_route(xml, "iwlwifi-QuZ-a0-hr-b0-63.ucode"); + gen_parent_rom_route(xml, "iwlwifi-so-a0-hr-b0-64.ucode"); gen_parent_rom_route(xml, "regulatory.db"); gen_parent_rom_route(xml, "regulatory.db.p7s"); gen_parent_route (xml); diff --git a/repos/gems/src/app/sculpt_manager/view/dialog.h b/repos/gems/src/app/sculpt_manager/view/dialog.h index 57ce424c72..540d8e9f58 100644 --- a/repos/gems/src/app/sculpt_manager/view/dialog.h +++ b/repos/gems/src/app/sculpt_manager/view/dialog.h @@ -74,7 +74,7 @@ struct Sculpt::Dialog : Interface { Hover_result result = Hover_result::UNMODIFIED; - hover.with_sub_node(sub_node, [&] (Xml_node sub_hover) { + hover.with_optional_sub_node(sub_node, [&] (Xml_node sub_hover) { if (_match_sub_dialog(sub_hover, tail...) == Hover_result::CHANGED) result = Hover_result::CHANGED; }); diff --git a/repos/gems/src/app/sculpt_manager/view/file_browser_dialog.h b/repos/gems/src/app/sculpt_manager/view/file_browser_dialog.h index 084fe1dac3..4c972ee154 100644 --- a/repos/gems/src/app/sculpt_manager/view/file_browser_dialog.h +++ b/repos/gems/src/app/sculpt_manager/view/file_browser_dialog.h @@ -281,7 +281,7 @@ struct Sculpt::File_browser_dialog : Noncopyable, Dialog unsigned cnt = 0; _state.with_query_result([&] (Xml_node node) { - node.with_sub_node("dir", [&] (Xml_node listing) { + node.with_optional_sub_node("dir", [&] (Xml_node listing) { if (_state.path != "/") _gen_back_entry(xml); diff --git a/repos/gems/src/app/sculpt_manager/view/network_dialog.cc b/repos/gems/src/app/sculpt_manager/view/network_dialog.cc index 49bd64b578..3e1b0baa38 100644 --- a/repos/gems/src/app/sculpt_manager/view/network_dialog.cc +++ b/repos/gems/src/app/sculpt_manager/view/network_dialog.cc @@ -211,7 +211,7 @@ void Network_dialog::generate(Xml_generator &xml) const auto gen_nic_button = [&] (Hoverable_item::Id const &id, Nic_target::Type const type, - String<10> const &label) { + String<20> const &label) { gen_named_node(xml, "button", id, [&] () { _nic_item.gen_button_attr(xml, id); @@ -229,18 +229,23 @@ void Network_dialog::generate(Xml_generator &xml) const * Allow interactive selection only if NIC-router configuration * is not manually maintained. */ - if (_nic_target.managed() || _nic_target.manual_type == Nic_target::LOCAL) - gen_nic_button("local", Nic_target::LOCAL, "Local"); + if (_nic_target.managed() || _nic_target.manual_type == Nic_target::DISCONNECTED) + gen_nic_button("disconnected", Nic_target::DISCONNECTED, "Disconnected"); if (_nic_target.managed() || _nic_target.manual_type == Nic_target::WIRED) - gen_nic_button("wired", Nic_target::WIRED, "Wired"); + if (_pci_info.lan_present) + gen_nic_button("wired", Nic_target::WIRED, "Wired"); if (_nic_target.managed() || _nic_target.manual_type == Nic_target::WIFI) if (_pci_info.wifi_present) gen_nic_button("wifi", Nic_target::WIFI, "Wifi"); + + if (_nic_target.managed() || _nic_target.manual_type == Nic_target::MODEM) + if (_pci_info.modem_present) + gen_nic_button("modem", Nic_target::MODEM, "Mobile data"); }); - if (_nic_target.wifi() || _nic_target.wired()) { + if (_nic_target.wifi() || _nic_target.wired() || _nic_target.modem()) { gen_named_node(xml, "frame", "nic_info", [&] () { xml.node("vbox", [&] () { @@ -287,10 +292,11 @@ Dialog::Hover_result Network_dialog::hover(Xml_node hover) void Network_dialog::click(Action &action) { - if (_nic_item.hovered("off")) action.nic_target(Nic_target::OFF); - if (_nic_item.hovered("local")) action.nic_target(Nic_target::LOCAL); - if (_nic_item.hovered("wired")) action.nic_target(Nic_target::WIRED); - if (_nic_item.hovered("wifi")) action.nic_target(Nic_target::WIFI); + if (_nic_item.hovered("off")) action.nic_target(Nic_target::OFF); + if (_nic_item.hovered("disconnected")) action.nic_target(Nic_target::DISCONNECTED); + if (_nic_item.hovered("wired")) action.nic_target(Nic_target::WIRED); + if (_nic_item.hovered("wifi")) action.nic_target(Nic_target::WIFI); + if (_nic_item.hovered("modem")) action.nic_target(Nic_target::MODEM); if (_wifi_connection.connected() && _ap_item.hovered(_wifi_connection.bssid)) { action.wifi_disconnect(); diff --git a/repos/gems/src/app/sculpt_manager/view/ram_fs_dialog.h b/repos/gems/src/app/sculpt_manager/view/ram_fs_dialog.h index dfa39ac914..5326dbecee 100644 --- a/repos/gems/src/app/sculpt_manager/view/ram_fs_dialog.h +++ b/repos/gems/src/app/sculpt_manager/view/ram_fs_dialog.h @@ -15,6 +15,7 @@ #define _VIEW__RAM_FS_DIALOG_H_ #include +#include #include namespace Sculpt { struct Ram_fs_dialog; } diff --git a/repos/gems/src/app/text_area/dialog.cc b/repos/gems/src/app/text_area/dialog.cc index 285b4a50a2..88721e1eb1 100644 --- a/repos/gems/src/app/text_area/dialog.cc +++ b/repos/gems/src/app/text_area/dialog.cc @@ -631,8 +631,8 @@ void Dialog::handle_hover(Xml_node const &hover) _hovered_position.construct(max_x, y); - node.with_sub_node("float", [&] (Xml_node node) { - node.with_sub_node("label", [&] (Xml_node node) { + node.with_optional_sub_node("float", [&] (Xml_node node) { + node.with_optional_sub_node("label", [&] (Xml_node node) { Line::Index const x { node.attribute_value("at", max_x.value) }; @@ -654,14 +654,14 @@ void Dialog::handle_hover(Xml_node const &hover) _text_hovered = false; - hover.with_sub_node("frame", [&] (Xml_node node) { - node.with_sub_node("button", [&] (Xml_node node) { + hover.with_optional_sub_node("frame", [&] (Xml_node node) { + node.with_optional_sub_node("button", [&] (Xml_node node) { _text_hovered = true; - node.with_sub_node("float", [&] (Xml_node node) { - node.with_sub_node("vbox", [&] (Xml_node node) { - node.with_sub_node("hbox", [&] (Xml_node node) { + node.with_optional_sub_node("float", [&] (Xml_node node) { + node.with_optional_sub_node("vbox", [&] (Xml_node node) { + node.with_optional_sub_node("hbox", [&] (Xml_node node) { with_hovered_line(node); }); }); }); }); }); if (hover_changed || position_changed || (_text_hovered != orig_text_hovered)) diff --git a/repos/gems/src/app/text_area/main.cc b/repos/gems/src/app/text_area/main.cc index 5523784dd1..b6c2112ab9 100644 --- a/repos/gems/src/app/text_area/main.cc +++ b/repos/gems/src/app/text_area/main.cc @@ -92,7 +92,7 @@ struct Text_area::Main : Sandbox::Local_service_base::Wakeup, if (!node.has_sub_node("dialog")) _dialog.handle_hover(Xml_node("")); - node.with_sub_node("dialog", [&] (Xml_node const &dialog) { + node.with_optional_sub_node("dialog", [&] (Xml_node const &dialog) { _dialog.handle_hover(dialog); }); } @@ -462,7 +462,7 @@ struct Text_area::Main : Sandbox::Local_service_base::Wakeup, if (_editable()) { bool const orig_saved_reporter_enabled = _saved_reporter.constructed(); - config.with_sub_node("report", [&] (Xml_node const &node) { + config.with_optional_sub_node("report", [&] (Xml_node const &node) { _saved_reporter.conditional(node.attribute_value("saved", false), _env, "saved", "saved"); }); @@ -471,7 +471,7 @@ struct Text_area::Main : Sandbox::Local_service_base::Wakeup, Saved_version const orig_saved_version = _saved_version; - config.with_sub_node("save", [&] (Xml_node const &node) { + config.with_optional_sub_node("save", [&] (Xml_node const &node) { _saved_version.value = node.attribute_value("version", _saved_version.value); }); diff --git a/repos/gems/src/app/themed_decorator/main.cc b/repos/gems/src/app/themed_decorator/main.cc index a8d1f05b70..c751df8cc9 100644 --- a/repos/gems/src/app/themed_decorator/main.cc +++ b/repos/gems/src/app/themed_decorator/main.cc @@ -217,7 +217,7 @@ find_hover(Genode::Xml_node pointer_node, Decorator::Window_stack &window_stack) || !pointer_node.has_attribute("ypos")) return Decorator::Window_base::Hover(); - return window_stack.hover(Decorator::point_attribute(pointer_node)); + return window_stack.hover(Decorator::Point::from_xml(pointer_node)); } diff --git a/repos/gems/src/app/themed_decorator/theme.cc b/repos/gems/src/app/themed_decorator/theme.cc index 8b55f595ba..7c3bb785bb 100644 --- a/repos/gems/src/app/themed_decorator/theme.cc +++ b/repos/gems/src/app/themed_decorator/theme.cc @@ -149,8 +149,8 @@ Decorator::Theme::Margins Decorator::Theme::decor_margins() const Decorator::Rect Decorator::Theme::title_geometry() const { static Genode::Xml_node node = metadata(_alloc); - static Rect rect = node.has_sub_node("title") - ? rect_attribute(node.sub_node("title")) + static Rect rect = node.has_sub_node("title") + ? Rect::from_xml(node.sub_node("title")) : Rect(Point(0, 0), Area(0, 0)); return rect; } @@ -168,7 +168,7 @@ element_geometry(Genode::Ram_allocator &ram, Genode::Region_map &rm, if (!node.has_sub_node(sub_node_type)) return Rect(Point(0, 0), Area(0, 0)); - return Rect(point_attribute(node.sub_node(sub_node_type)), + return Rect(Point::from_xml(node.sub_node(sub_node_type)), texture_by_id(ram, rm, alloc, texture_id).size()); } diff --git a/repos/gems/src/app/themed_decorator/window.h b/repos/gems/src/app/themed_decorator/window.h index ba0fd04b39..39e3100f59 100644 --- a/repos/gems/src/app/themed_decorator/window.h +++ b/repos/gems/src/app/themed_decorator/window.h @@ -511,7 +511,7 @@ class Decorator::Window : public Window_base, public Animator::Item _motion = _config.motion(_title); Rect const old_geometry = geometry(); - Rect const new_geometry = rect_attribute(window_node); + Rect const new_geometry = Rect::from_xml(window_node); geometry(new_geometry); diff --git a/repos/gems/src/app/touch_keyboard/main.cc b/repos/gems/src/app/touch_keyboard/main.cc index c5b3719f32..8694744466 100644 --- a/repos/gems/src/app/touch_keyboard/main.cc +++ b/repos/gems/src/app/touch_keyboard/main.cc @@ -49,7 +49,7 @@ struct Touch_keyboard::Main : Sandbox::Local_service_base::Wakeup, Registry _children { }; Child_state _menu_view_child_state { _children, "menu_view", - Ram_quota { 4*1024*1024 }, + Ram_quota { 10*1024*1024 }, Cap_quota { 200 } }; /** * Sandbox::State_handler @@ -90,7 +90,7 @@ struct Touch_keyboard::Main : Sandbox::Local_service_base::Wakeup, { Input::Seq_number hover_seq { node.attribute_value("seq_number", 0U) }; - node.with_sub_node("dialog", [&] (Xml_node const &dialog) { + node.with_optional_sub_node("dialog", [&] (Xml_node const &dialog) { _dialog.handle_hover(hover_seq, dialog); }); } diff --git a/repos/gems/src/app/touch_keyboard/touch_keyboard_dialog.cc b/repos/gems/src/app/touch_keyboard/touch_keyboard_dialog.cc index 47d70011ff..5e772e7f02 100644 --- a/repos/gems/src/app/touch_keyboard/touch_keyboard_dialog.cc +++ b/repos/gems/src/app/touch_keyboard/touch_keyboard_dialog.cc @@ -48,6 +48,8 @@ void Dialog::produce_xml(Xml_generator &xml) xml.node("label", [&] () { xml.attribute("name", "label"); xml.attribute("text", key.label); + if (key.small) + xml.attribute("font", "annotation/regular"); }); }); }); @@ -103,10 +105,10 @@ void Dialog::handle_hover(Input::Seq_number seq, Xml_node const &dialog) Row::Id hovered_row_id { }; Key::Id hovered_key_id { }; - dialog.with_sub_node("frame", [&] (Xml_node const &frame) { - frame.with_sub_node("vbox", [&] (Xml_node const &vbox) { - vbox.with_sub_node("hbox", [&] (Xml_node const &hbox) { - hbox.with_sub_node("vbox", [&] (Xml_node const &button) { + dialog.with_optional_sub_node("frame", [&] (Xml_node const &frame) { + frame.with_optional_sub_node("vbox", [&] (Xml_node const &vbox) { + vbox.with_optional_sub_node("hbox", [&] (Xml_node const &hbox) { + hbox.with_optional_sub_node("vbox", [&] (Xml_node const &button) { hovered_row_id = hbox .attribute_value("name", Row::Id()); hovered_key_id = button.attribute_value("name", Key::Id()); }); diff --git a/repos/gems/src/app/touch_keyboard/touch_keyboard_dialog.h b/repos/gems/src/app/touch_keyboard/touch_keyboard_dialog.h index 73398c27af..c19abcbea9 100644 --- a/repos/gems/src/app/touch_keyboard/touch_keyboard_dialog.h +++ b/repos/gems/src/app/touch_keyboard/touch_keyboard_dialog.h @@ -68,6 +68,8 @@ struct Touch_keyboard::Dialog : private Dynamic_rom_session::Xml_producer unsigned min_ex = 0; + bool small = false; + Key(Id id) : _id(id) { } bool matches(Xml_node const &node) const { return _id == id_attr(node); } @@ -80,6 +82,7 @@ struct Touch_keyboard::Dialog : private Dynamic_rom_session::Xml_producer emit = { }; map = key.attribute_value("map", Map()); min_ex = key.attribute_value("min_ex", 0U); + small = key.attribute_value("small", false); if (key.has_attribute("char")) { label = key.attribute_value("char", Label()); diff --git a/repos/gems/src/app/trace_recorder/README b/repos/gems/src/app/trace_recorder/README new file mode 100644 index 0000000000..47c3ef5990 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/README @@ -0,0 +1,56 @@ +The trace recorder uses Genode's trace session to insert trace policies and +periodically process the trace buffers to record continuous traces in a file +system. The trace recorder comprises multiple backends that produce different +output formats. + +An examplary configuration is shown below: + +! +! +! +! +! +! + +The mandatory argument 'period_ms' specifies the trace-buffer sampling period +in milliseconds. The 'enable' attribute activates trace recording. +Whenever the 'enable' attribute is toggled from "no" to "yes", a new directory +is created (using the real-time clock) to record a new set of traces. + +The '' node can contain an arbitray number of '' nodes by which +the plugin determines what components and threads are traced. +The specified 'label_suffix', 'label_prefix' and/or 'label' attributes are +matched against the component labels. By default, all threads of the matching +component(s) will be traced. The mandatory 'policy' attribute specifies the name +of the trace policy to be applied to the matching threads. + +Every '' node must contain at least one sub-node specifying what +backend(s) shall be used for trace output. Currently, the following backends are +available: + +:'ctf': + Produces CTF (common trace format) traces of component interactions + and checkpoints. These traces can be processed with babeltrace or + visualised with TraceCompass. Note that the ctf backend opens a ROM + session "metadata" that is used as a blueprint for the + [https://diamon.org/ctf/ - CTF metadata file] created with the trace + files. Currently, only the frequency of the specified clock is adapted. + The metadata file is required for deserialisation of trace data. + +:'pcapng': + Captures packets (e.g. Ethernet packets) in a pcapng file that can be read + by wireshark, for instance. + + +The '' node may take the following optional attributes: + +:'enable': Enables/starts tracing (default: 'no') + +:'target_root': Sets the target root directory for trace output. + + +Furthermore, the '' nodes may take the following optional attributes: + +:'thread': Restricts the tracing to a certain thread of the matching component(s). + +:'buffer': Sets the size of the trace buffer (default: '64K'). diff --git a/repos/gems/src/app/trace_recorder/backend.h b/repos/gems/src/app/trace_recorder/backend.h new file mode 100644 index 0000000000..e3cf765b26 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/backend.h @@ -0,0 +1,58 @@ +/* + * \brief Factory base for creating writers + * \author Johannes Schlatow + * \date 2022-05-11 + */ + +/* + * Copyright (C) 2022 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 _BACKEND_H_ +#define _BACKEND_H_ + +/* Genode includes */ +#include + +/* local includes */ +#include + +namespace Trace_recorder { + class Backend_base; + + using Backend_name = Genode::String<64>; + using Backends = Genode::Dictionary; +} + + +class Trace_recorder::Backend_base : Backends::Element +{ + protected: + friend class Genode::Dictionary; + friend class Genode::Avl_node; + friend class Genode::Avl_tree; + + public: + using Name = Backend_name; + using Backends::Element::name; + + Backend_base(Backends & backends, Name const &name) + : Backends::Element(backends, name) + { } + + virtual ~Backend_base() { } + + /*************** + ** Interface ** + ***************/ + + virtual Writer_base &create_writer(Genode::Allocator &, + Genode::Registry &, + Directory &, + Directory::Path const &) = 0; +}; + +#endif /* _BACKEND_H_ */ diff --git a/repos/gems/src/app/trace_recorder/checkpointanalysis.xml b/repos/gems/src/app/trace_recorder/checkpointanalysis.xml new file mode 100644 index 0000000000..e8041bf38f --- /dev/null +++ b/repos/gems/src/app/trace_recorder/checkpointanalysis.xml @@ -0,0 +1,108 @@ + + + + + + + + diff --git a/repos/gems/src/app/trace_recorder/componentanalysis.xml b/repos/gems/src/app/trace_recorder/componentanalysis.xml new file mode 100644 index 0000000000..0bba7d0092 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/componentanalysis.xml @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + diff --git a/repos/gems/src/app/trace_recorder/config.xsd b/repos/gems/src/app/trace_recorder/config.xsd new file mode 100644 index 0000000000..737dc5bac3 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/config.xsd @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/repos/gems/src/app/trace_recorder/ctf/backend.cc b/repos/gems/src/app/trace_recorder/ctf/backend.cc new file mode 100644 index 0000000000..b639b7c0c2 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/ctf/backend.cc @@ -0,0 +1,59 @@ +/* + * \brief CTF backend + * \author Johannes Schlatow + * \date 2022-05-11 + */ + +/* + * Copyright (C) 2022 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. + */ + +/* local includes */ +#include + +using namespace Ctf; + +void Writer::start_iteration(Directory &root, + Directory::Path const &path, + ::Subject_info const &info) +{ + _file_path = Directory::join(path, info.thread_name()); + + try { + _dst_file.construct(root, _file_path); + + /* initialise packet header */ + _packet_buffer.init_header(info); + } + catch (Append_file::Create_failed) { + error("Could not create file."); } +} + +void Writer::process_event(Trace_recorder::Trace_event_base const &trace_event, size_t length) +{ + if (!_dst_file.constructed()) return; + + if (trace_event.type() != Trace_recorder::Event_type::CTF) return; + + try { + /* write to file if buffer is full */ + if (_packet_buffer.bytes_remaining() < length) + _packet_buffer.write_to_file(*_dst_file, _file_path); + + _packet_buffer.add_event(trace_event.event(), length - sizeof(Trace_event_base)); + + } + catch (Buffer::Buffer_too_small) { + error("Packet buffer overflow. (Trace buffer wrapped during read?)"); } +} + +void Writer::end_iteration() +{ + /* write buffer to file */ + _packet_buffer.write_to_file(*_dst_file, _file_path); + + _dst_file.destruct(); +} diff --git a/repos/gems/src/app/trace_recorder/ctf/backend.h b/repos/gems/src/app/trace_recorder/ctf/backend.h new file mode 100644 index 0000000000..c4ee82eee8 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/ctf/backend.h @@ -0,0 +1,96 @@ +/* + * \brief CTF backend + * \author Johannes Schlatow + * \date 2021-08-02 + */ + +/* + * 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 _CTF__BACKEND_H_ +#define _CTF__BACKEND_H_ + +/* local includes */ +#include +#include +#include +#include + +#include +#include + +namespace Ctf { + using namespace Trace_recorder; + + using Genode::Directory; + using Genode::Append_file; + + using Buffer = Write_buffer<32*1024>; + + class Backend; + class Writer; +} + + +class Ctf::Writer : public Trace_recorder::Writer_base +{ + private: + Buffer &_packet_buffer; + Constructible _dst_file { }; + Directory::Path _file_path { }; + + public: + Writer(Genode::Registry ®istry, Buffer &packet_buffer) + : Writer_base(registry), + _packet_buffer(packet_buffer) + { } + + virtual void start_iteration(Directory &, + Directory::Path const &, + ::Subject_info const &) override; + + virtual void process_event(Trace_recorder::Trace_event_base const &, Genode::size_t) override; + + virtual void end_iteration() override; +}; + + +class Ctf::Backend : Trace_recorder::Backend_base +{ + private: + + Attached_rom_dataspace _metadata_rom; + Metadata _metadata; + + Buffer _packet_buf { }; + + public: + + Backend(Env &env, Timestamp_calibrator const &ts_calibrator, Backends &backends) + : Backend_base(backends, "ctf"), + _metadata_rom(env, "metadata"), + _metadata(_metadata_rom, ts_calibrator.ticks_per_second()) + { } + + Writer_base &create_writer(Genode::Allocator &alloc, + Genode::Registry ®istry, + Directory &root, + Directory::Path const &path) override + { + /* copy metadata file while adapting clock declaration */ + Directory::Path metadata_path { Directory::join(path, "metadata") }; + if (!root.file_exists(metadata_path)) { + New_file metadata_file { root, metadata_path }; + _metadata.write_file(metadata_file); + } + + return *new (alloc) Writer(registry, _packet_buf); + } +}; + + +#endif /* _CTF__BACKEND_H_ */ diff --git a/repos/gems/src/app/trace_recorder/ctf/metadata b/repos/gems/src/app/trace_recorder/ctf/metadata new file mode 100644 index 0000000000..2e314f6ce2 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/ctf/metadata @@ -0,0 +1,121 @@ +/* CTF 1.8 */ + +typealias integer { size = 8; align = 8; signed = false; } := uint8_t; +typealias uint8_t := char; +typealias integer { size = 16; align = 8; signed = false; } := uint16_t; +typealias integer { size = 32; align = 8; signed = false; } := uint32_t; +typealias integer { size = 64; align = 8; signed = false; } := uint64_t; +typealias integer { size = 4; align = 1; signed = false; } := uint4_t; + +trace { + major = 1; + minor = 8; + uuid = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"; + byte_order = le; + packet.header := struct { + uint32_t magic; + uint32_t stream_id; + }; +}; + +clock { + name = "monotonic"; + freq = 1000000000; /* Frequency, in Hz (DO NOT REMOVE) */ +}; + +typealias integer { + size = 64; align = 8; signed = false; + map = clock.monotonic.value; +} := uint64_tsc_t; + +struct packet_context { + uint64_tsc_t timestamp_begin; + uint64_tsc_t timestamp_end; + uint32_t packet_size; + uint16_t _hdrsz; + uint4_t xpos; + uint4_t ypos; + uint4_t width; + uint4_t height; + uint8_t priority; + string session_label; + string thread_name; +}; + +struct event_header { + uint8_t id; + uint64_tsc_t timestamp; +} align(8); + +stream { + id = 0; + event.header := struct event_header; + packet.context := struct packet_context; +}; + +event { + name = "Rpc_call"; + id = 1; + stream_id = 0; + fields := struct { + string _name; + }; +}; + +event { + name = "Rpc_returned"; + id = 2; + stream_id = 0; + fields := struct { + string _name; + }; +}; + +event { + name = "Rpc_dispatch"; + id = 3; + stream_id = 0; + fields := struct { + string _name; + }; +}; + +event { + name = "Rpc_reply"; + id = 4; + stream_id = 0; + fields := struct { + string _name; + }; +}; + +event { + name = "Signal_submit"; + id = 5; + stream_id = 0; + fields := struct { + uint32_t _number; + }; +}; + +event { + name = "Signal_receive"; + id = 6; + stream_id = 0; + fields := struct { + uint32_t _number; + uint64_t _context; + }; +}; + +event { + name = "Checkpoint"; + id = 7; + stream_id = 0; + fields := struct { + uint32_t _data; + uint64_t _addr; + uint8_t _type; + string _name; + }; +}; diff --git a/repos/gems/src/app/trace_recorder/ctf/metadata.h b/repos/gems/src/app/trace_recorder/ctf/metadata.h new file mode 100644 index 0000000000..e4978afa06 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/ctf/metadata.h @@ -0,0 +1,106 @@ +/* + * \brief Metadata file writer + * \author Johannes Schlatow + * \date 2021-12-02 + */ + +/* + * 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 _CTF__METADATA_H_ +#define _CTF__METADATA_H_ + +#include +#include +#include + +namespace Ctf { + using namespace Genode; + + class Metadata; +} + +class Ctf::Metadata +{ + private: + Attached_rom_dataspace &_metadata_rom; + uint64_t _timestamp_freq; + + template + bool _with_metadata_rom(PROLOGUE && prologue, + EPILOGUE && epilogue) const + { + using Token = Genode::Token; + char const * rom_start = _metadata_rom.local_addr(); + size_t const rom_size = _metadata_rom.size(); + + Token token { rom_start, rom_size }; + + for (; token; token = token.next()) { + if (token.type() == Token::IDENT) { + if (token.matches("freq") && token.len() == 4) { + + prologue(rom_start, token.next().start() - rom_start); + + token = token.next_after("\n"); + + /* find null termination */ + char const * rom_end = token.start(); + for (; rom_end < rom_start+rom_size && rom_end && *rom_end; rom_end++); + + epilogue(token.start(), rom_end - token.start()); + + return true; + } + } + } + + error("Error parsing metadata ROM. Could not find 'freq' definition."); + return false; + } + + public: + + Metadata(Attached_rom_dataspace & metadata_rom, uint64_t freq) + : _metadata_rom(metadata_rom), + _timestamp_freq(freq) + { } + + void write_file(Genode::New_file & dst) const + { + using namespace Genode; + + bool write_error = false; + + auto write = [&] (char const *str) + { + if (dst.append(str, strlen(str)) != New_file::Append_result::OK) + write_error = true; + }; + Buffered_output<32, decltype(write)> output(write); + + _with_metadata_rom( + /* prologue, up to 'freq' */ + [&] (char const * start, size_t len) { + if (dst.append(start, len) != New_file::Append_result::OK) + write_error = true; + + print(output, " = ", _timestamp_freq, ";\n"); + }, + /* epilogue, everything after '\n' */ + [&] (char const * start, size_t len) { + if (dst.append(start, len) != New_file::Append_result::OK) + write_error = true; + }); + + if (write_error) + error("Write to 'metadata' failed"); + } +}; + + +#endif /* _CTF__METADATA_H_ */ diff --git a/repos/gems/src/app/trace_recorder/ctf/packet_header.h b/repos/gems/src/app/trace_recorder/ctf/packet_header.h new file mode 100644 index 0000000000..1dfeaef220 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/ctf/packet_header.h @@ -0,0 +1,133 @@ +/* + * \brief Packet header + * \author Johannes Schlatow + * \date 2021-08-04 + */ + +/* + * 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 _CTF__PACKET_HEADER_H_ +#define _CTF__PACKET_HEADER_H_ + +#include +#include +#include + +namespace Ctf { + using namespace Genode; + using Genode::Trace::Thread_name; + struct Packet_header; +} + +/** + * Definition of our CTF packet header. A CTF stream may contain multiple + * packets that bundle an arbitrary number of events. In order to reduce the + * payload for every CTF event, we put shared information (such as session and + * thread name) into the packet header. + * + * See https://diamon.org/ctf/ for the CTF spec. + */ +struct Ctf::Packet_header +{ + uint32_t _magic { 0xC1FC1FC1 }; + uint32_t _stream_id { }; + Timestamp_base _timestamp_start { }; + Timestamp_base _timestamp_end { }; + uint32_t _total_length { }; + uint16_t _hdr_length { sizeof(Packet_header) * 8 }; + uint16_t _affinity { }; + uint8_t _priority { }; + char _session_and_thread[0] { }; + + struct Affinity : Register<16> + { + struct Xpos : Bitfield<0,4> { }; + struct Ypos : Bitfield<4,4> { }; + struct Width : Bitfield<8,4> { }; + struct Height : Bitfield<12,4> { }; + }; + + Packet_header(Session_label const &label, + Thread_name const &thread, + Genode::Affinity::Location const &affinity, + unsigned priority, + Genode::size_t buflen, + unsigned streamid=0) + : _stream_id(streamid), + _affinity(Affinity::Xpos::bits((uint16_t)affinity.xpos()) | + Affinity::Ypos::bits((uint16_t)affinity.ypos()) | + Affinity::Width::bits((uint16_t)affinity.width()) | + Affinity::Height::bits((uint16_t)affinity.height())), + _priority((uint8_t)priority) + { + Genode::size_t char_offset = 0; + + if (_hdr_length/8 < buflen) { + Genode::size_t sess_len = Genode::min(label.length(), buflen - _hdr_length/8); + Genode::copy_cstring(&_session_and_thread[char_offset], label.string(), sess_len); + _hdr_length += (uint16_t)(sess_len * 8); + char_offset = sess_len; + } + + if (_hdr_length/8 < buflen) { + Genode::size_t thread_len = Genode::min(thread.length(), buflen - _hdr_length/8); + Genode::copy_cstring(&_session_and_thread[char_offset], thread.string(), thread_len); + _hdr_length += (uint16_t)(thread_len * 8); + } + + _total_length = _hdr_length; + } + + void reset() + { + _total_length = _hdr_length; + _timestamp_start = 0; + _timestamp_end = 0; + } + + /** + * If event fits into provided buffer, update struct with timestamp and + * length of new event. Makes sure that timestamps are monotonically + * increasing and calls the provided functor(char * ptr, Timestamp_base ts), + * where ptr is the target address and ts is the updated timestamp. + */ + template + void append_event(char * buffer, + Genode::size_t bufsz, + Timestamp_base timestamp, + Genode::size_t length, + FUNC && fn) + { + using Ctf::Timestamp; + + /* check whether event fits into buffer */ + if (total_length_bytes()+length > bufsz) + return; + + /* update timestamps */ + if (_timestamp_start == 0) + _timestamp_start = timestamp; + else if (Timestamp::extended() && + Timestamp::Base::get(_timestamp_end) > Timestamp::Base::get(timestamp)) { + /* timer wrapped, increase manually managed offset */ + Timestamp::Extension::set(_timestamp_end, Timestamp::Extension::get(_timestamp_end)+1); + } + Timestamp::Base::set(_timestamp_end, timestamp); + + /* call provided functor with target address and modified timestamp */ + fn(&buffer[total_length_bytes()], _timestamp_end); + + _total_length += (uint32_t)(length * 8); + } + + uint32_t total_length_bytes() const { return _total_length / 8; } + bool empty() const { return _total_length <= _hdr_length; } + +} __attribute__((packed)); + +#endif /* _CTF__PACKET_HEADER_H_ */ diff --git a/repos/gems/src/app/trace_recorder/ctf/write_buffer.h b/repos/gems/src/app/trace_recorder/ctf/write_buffer.h new file mode 100644 index 0000000000..490f236425 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/ctf/write_buffer.h @@ -0,0 +1,82 @@ +/* + * \brief Convenience helper for creating a CTF packet + * \author Johannes Schlatow + * \date 2021-08-06 + */ + +/* + * 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 _CTF__WRITE_BUFFER_H_ +#define _CTF__WRITE_BUFFER_H_ + +/* local includes */ +#include +#include + +/* Genode includes */ +#include +#include + +namespace Ctf { + template + class Write_buffer; +} + +template +class Ctf::Write_buffer +{ + public: + struct Buffer_too_small : Genode::Exception { }; + + private: + char _buffer[BUFSIZE] { }; + + Packet_header &_header() { return *(Packet_header*)_buffer; } + + public: + + void init_header(::Subject_info const &info) + { + construct_at(_buffer, + info.session_label(), + info.thread_name(), + info.affinity(), + info.priority(), + BUFSIZE); + } + + void add_event(Ctf::Event_header_base const &event, Genode::size_t length) + { + _header().append_event(_buffer, BUFSIZE, + event.timestamp(), length, + [&] (char * ptr, Timestamp_base ts) + { + /* copy event into buffer */ + memcpy(ptr, &event, length); + + /* update timestamp */ + ((Event_header_base *)ptr)->timestamp(ts); + }); + } + + void write_to_file(Genode::Append_file &dst, Genode::Directory::Path const &path) + { + if (_header().empty()) + return; + + if (dst.append(_buffer, _header().total_length_bytes()) != Append_file::Append_result::OK) + error("Write error for ", path); + + _header().reset(); + } + + Genode::size_t bytes_remaining() { return BUFSIZE - _header().total_length_bytes(); } +}; + + +#endif /* _CTF__WRITE_BUFFER_H_ */ diff --git a/repos/gems/src/app/trace_recorder/main.cc b/repos/gems/src/app/trace_recorder/main.cc new file mode 100644 index 0000000000..7650f3e18b --- /dev/null +++ b/repos/gems/src/app/trace_recorder/main.cc @@ -0,0 +1,77 @@ +/* + * \brief Record traces and store in file system + * \author Johannes Schlatow + * \date 2022-05-09 + */ + +/* + * Copyright (C) 2022 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. + */ + +/* local includes */ +#include + +/* Genode includes */ +#include +#include +#include + +namespace Trace_recorder { + using namespace Genode; + + struct Main; +} + + +class Trace_recorder::Main +{ + private: + Env &_env; + + Heap _heap { _env.ram(), _env.rm() }; + Monitor _monitor { _env, _heap }; + + Attached_rom_dataspace _config_rom { _env, "config" }; + + Signal_handler
_config_handler { _env.ep(), *this, &Main::_handle_config }; + + bool _enabled { false }; + + void _handle_config(); + + public: + + Main(Env & env) + : _env(env) + { + _config_rom.sigh(_config_handler); + + _handle_config(); + } +}; + + +void Trace_recorder::Main::_handle_config() +{ + _config_rom.update(); + + bool old_enabled { _enabled }; + + _enabled = _config_rom.xml().attribute_value("enable", false); + + if (old_enabled == _enabled) { + warning("Config update postponed. Need to toggle 'enable' attribute."); + return; + } + + if (_enabled) + _monitor.start(_config_rom.xml()); + else + _monitor.stop(); +} + + +void Component::construct(Genode::Env &env) { static Trace_recorder::Main main(env); } diff --git a/repos/gems/src/app/trace_recorder/monitor.cc b/repos/gems/src/app/trace_recorder/monitor.cc new file mode 100644 index 0000000000..c42e87a9de --- /dev/null +++ b/repos/gems/src/app/trace_recorder/monitor.cc @@ -0,0 +1,195 @@ +/* + * \brief Frontend for controlling the TRACE session + * \author Johannes Schlatow + * \date 2022-05-09 + */ + +/* + * Copyright (C) 2022 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. + */ + +/* local includes */ +#include "monitor.h" + +using namespace Genode; + +Directory::Path Trace_recorder::Monitor::Trace_directory::subject_path(::Subject_info const &info) +{ + typedef Path Label_path; + + Label_path label_path = path_from_label(info.session_label().string()); + Directory::Path subject_path(Directory::join(_path, label_path.string())); + + return subject_path; +} + + +void Trace_recorder::Monitor::Attached_buffer::process_events(Trace_directory &trace_directory) +{ + /* start iteration for every writer */ + _writers.for_each([&] (Writer_base &writer) { + writer.start_iteration(trace_directory.root(), + trace_directory.subject_path(info()), + info()); + }); + + /* iterate entries and pass each entry to every writer */ + _buffer.for_each_new_entry([&] (Trace::Buffer::Entry &entry) { + if (entry.length() == 0) + return true; + + _writers.for_each([&] (Writer_base &writer) { + writer.process_event(entry.object(), entry.length()); + }); + + return true; + }); + + /* end iteration for every writer */ + _writers.for_each([&] (Writer_base &writer) { writer.end_iteration(); }); +} + + +Session_policy Trace_recorder::Monitor::_session_policy(Trace::Subject_info const &info, Xml_node config) +{ + Session_label const label(info.session_label()); + Session_policy policy(label, config); + + /* must have policy attribute */ + if (!policy.has_attribute("policy")) + throw Session_policy::No_policy_defined(); + + if (policy.has_attribute("thread")) + if (policy.attribute_value("thread", Trace::Thread_name()) != info.thread_name()) + throw Session_policy::No_policy_defined(); + + return policy; +} + + +void Trace_recorder::Monitor::_handle_timeout() +{ + _trace_buffers.for_each([&] (Attached_buffer &buf) { + buf.process_events(*_trace_directory); + }); +} + + +void Trace_recorder::Monitor::start(Xml_node config) +{ + stop(); + + /* create new trace directory */ + _trace_directory.construct(_env, _alloc, config, _rtc); + + /* find matching subjects according to config and start tracing */ + _trace.for_each_subject_info([&] (Trace::Subject_id const &id, + Trace::Subject_info const &info) { + try { + /* skip dead subjects */ + if (info.state() == Trace::Subject_info::DEAD) + return; + + /* check if there is a matching policy in the XML config */ + Session_policy session_policy = _session_policy(info, config); + + if (!session_policy.has_attribute("policy")) + return; + + Number_of_bytes buffer_sz = + session_policy.attribute_value("buffer", Number_of_bytes(DEFAULT_BUFFER_SIZE)); + + /* find and assign policy; create/insert if not present */ + Policy::Name const policy_name = session_policy.attribute_value("policy", Policy::Name()); + bool const create = + _policies.with_element(policy_name, + [&] /* match */ (Policy & policy) { + _trace.trace(id, policy.id(), buffer_sz); + return false; + }, + [&] /* no_match */ { return true; } + ); + + /* create policy if it did not exist */ + if (create) { + Policy &policy = *new (_alloc) Policy(_env, _trace, policy_name, _policies); + _trace.trace(id, policy.id(), buffer_sz); + } + + log("Inserting trace policy \"", policy_name, "\" into ", + info.session_label(), " -> ", info.thread_name()); + + /* attach and remember trace buffer */ + Attached_buffer &buffer = *new (_alloc) Attached_buffer(_trace_buffers, + _env, + _trace.buffer(id), + info, + id); + + /* create and register writers at trace buffer */ + session_policy.for_each_sub_node([&] (Xml_node & node) { + bool const present = + _backends.with_element(node.type(), + [&] /* match */ (Backend_base &backend) { + backend.create_writer(_alloc, + buffer.writers(), + _trace_directory->root(), + _trace_directory->subject_path(buffer.info())); + return true; + }, + [&] /* no_match */ { return false; } + ); + + if (!present) + error("No writer available for <", node.type(), "/>."); + else + log("Enabled ", node.type(), " writer for ", info.session_label(), + " -> ", info.thread_name()); + }); + } + catch (Session_policy::No_policy_defined) { return; } + }); + + /* register timeout */ + unsigned period_ms { 0 }; + if (!config.has_attribute("period_ms")) + error("missing XML attribute 'period_ms'"); + else + period_ms = config.attribute_value("period_ms", period_ms); + + _timer.trigger_periodic(period_ms * 1000); +} + + +void Trace_recorder::Monitor::stop() +{ + _timer.trigger_periodic(0); + + _trace_buffers.for_each([&] (Attached_buffer &buf) { + try { + /* stop tracing */ + _trace.pause(buf.subject_id()); + } catch (Trace::Nonexistent_subject) { } + + /* read remaining events from buffers */ + buf.process_events(*_trace_directory); + + /* destroy writers */ + buf.writers().for_each([&] (Writer_base &writer) { + destroy(_alloc, &writer); + }); + + /* destroy buffer */ + destroy(_alloc, &buf); + + try { + /* detach buffer */ + _trace.free(buf.subject_id()); + } catch (Trace::Nonexistent_subject) { } + }); + + _trace_directory.destruct(); +} diff --git a/repos/gems/src/app/trace_recorder/monitor.h b/repos/gems/src/app/trace_recorder/monitor.h new file mode 100644 index 0000000000..64b5511bff --- /dev/null +++ b/repos/gems/src/app/trace_recorder/monitor.h @@ -0,0 +1,148 @@ +/* + * \brief Frontend for controlling the TRACE session + * \author Johannes Schlatow + * \date 2022-05-09 + */ + +/* + * Copyright (C) 2022 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 _MONITOR_H_ +#define _MONITOR_H_ + +/* local includes */ +#include +#include +#include +#include +#include +#include + +/* Genode includes */ +#include +#include +#include +#include +#include + +namespace Trace_recorder { + using namespace Genode; + + class Monitor; +} + +class Trace_recorder::Monitor +{ + private: + enum { DEFAULT_BUFFER_SIZE = 64 * 1024 }; + enum { TRACE_SESSION_RAM = 1024 * 1024 }; + enum { TRACE_SESSION_ARG_BUFFER = 128 * 1024 }; + + class Trace_directory + { + private: + Root_directory _root; + Directory::Path _path; + + public: + + static Directory::Path root_from_config(Xml_node &config) { + return config.attribute_value("target_root", Directory::Path("/")); } + + Trace_directory(Env &env, + Allocator &alloc, + Xml_node &config, + Rtc::Connection &rtc) + : _root(env, alloc, config.sub_node("vfs")), + _path(Directory::join(root_from_config(config), rtc.current_time())) + { }; + + Directory &root() { return _root; } + Directory::Path subject_path(::Subject_info const &info); + }; + + class Attached_buffer + { + private: + + Env &_env; + Trace_buffer _buffer; + Registry::Element _element; + Subject_info _info; + Trace::Subject_id _subject_id; + Registry _writers { }; + + public: + + Attached_buffer(Registry ®istry, + Genode::Env &env, + Genode::Dataspace_capability ds, + Trace::Subject_info const &info, + Trace::Subject_id id) + : _env(env), + _buffer(*((Trace::Buffer*)_env.rm().attach(ds))), + _element(registry, *this), + _info(info), + _subject_id(id) + { } + + ~Attached_buffer() + { + _env.rm().detach(_buffer.address()); + } + + void process_events(Trace_directory &); + + Registry &writers() { return _writers; } + + Subject_info const &info() const { return _info; } + Trace::Subject_id const subject_id() const { return _subject_id; } + }; + + Env &_env; + Allocator &_alloc; + Registry _trace_buffers { }; + Policies _policies { }; + Backends _backends { }; + Constructible _trace_directory { }; + + Rtc::Connection _rtc { _env }; + Timer::Connection _timer { _env }; + Trace::Connection _trace { _env, + TRACE_SESSION_RAM, + TRACE_SESSION_ARG_BUFFER, + 0 }; + + Signal_handler _timeout_handler { _env.ep(), + *this, + &Monitor::_handle_timeout }; + + Timestamp_calibrator _ts_calibrator { _env, _rtc, _timer }; + + /* built-in backends */ + Ctf::Backend _ctf_backend { _env, _ts_calibrator, _backends }; + Pcapng::Backend _pcapng_backend { _alloc, _ts_calibrator, _backends }; + + /* methods */ + Session_policy _session_policy(Trace::Subject_info const &info, Xml_node config); + void _handle_timeout(); + + public: + + Monitor(Env &env, Allocator &alloc) + : _env(env), + _alloc(alloc) + { + _timer.sigh(_timeout_handler); + } + + void start(Xml_node config); + void stop(); +}; + + +#endif /* _MONITOR_H_ */ diff --git a/repos/gems/src/app/trace_recorder/pcapng/backend.cc b/repos/gems/src/app/trace_recorder/pcapng/backend.cc new file mode 100644 index 0000000000..9014ebed18 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/pcapng/backend.cc @@ -0,0 +1,136 @@ +/* + * \brief PCAPNG backend + * \author Johannes Schlatow + * \date 2022-05-13 + */ + +/* + * Copyright (C) 2022 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. + */ + +/* local includes */ +#include +#include +#include +#include + +using namespace Pcapng; +using Append_error = Buffer::Append_error; +using Append_result = Buffer::Append_result; +using Pcapng_event = Trace_recorder::Pcapng_event; + + +void Writer::start_iteration(Directory &root, + Directory::Path const &path, + ::Subject_info const &) +{ + /* write to '${path}.pcapng */ + Path pcap_file { path }; + pcap_file.append(".pcapng"); + + _file_path = Directory::Path(pcap_file.string()); + + /* append to file */ + try { + _dst_file.construct(root, _file_path); + + _interface_registry.clear(); + _buffer.clear(); + _buffer.append(); + _empty_section = true; + } + catch (Append_file::Create_failed) { + error("Could not create file."); } +} + + +void Writer::process_event(Trace_recorder::Trace_event_base const &trace_event, size_t length) +{ + if (!_dst_file.constructed()) return; + + if (trace_event.type() != Trace_recorder::Event_type::PCAPNG) return; + + /* event is of type Pcapng::Trace_event */ + Pcapng_event const &event = trace_event.event(); + + /* map interface name to id of interface description block (IDB) */ + unsigned id = 0; + bool buffer_full = false; + _interface_registry.from_name(event.interface(), + [&] (Interface const &iface) { + /* IDB alread exists */ + id = iface.id(); + }, + [&] (Interface_name const &if_name, unsigned if_id) { /* IDB must be created */ + id = if_id; + Append_result result = + _buffer.append(if_name, + Enhanced_packet_block::MAX_CAPTURE_LENGTH); + + result.with_error([&] (Append_error err) { + switch (err) + { + case Append_error::OUT_OF_MEM: + /* non-error, write to file and retry */ + buffer_full = true; + break; + case Append_error::OVERFLOW: + error("Interface_description_block exceeds its MAX_SIZE"); + break; + } + }); + return !buffer_full; + } + ); + + /* add enhanced packet block to buffer */ + if (!buffer_full) { + uint64_t us_since_epoch = _ts_calibrator.epoch_from_timestamp_in_us(event.timestamp()); + Append_result result = _buffer.append(id, event.packet(), us_since_epoch); + + result.with_error([&] (Append_error err) { + switch (err) + { + case Append_error::OUT_OF_MEM: + /* non-error, write to file and retry */ + buffer_full = true; + break; + case Append_error::OVERFLOW: + error("Enhanced_packet_block exceeds its MAX_SIZE"); + break; + } + }); + } + + /* write to file if buffer is full and process current event again */ + if (buffer_full) { + _buffer.write_to_file(*_dst_file, _file_path); + process_event(event, length); + } + else { + _empty_section = false; + } +} + + +void Writer::end_iteration() +{ + /* write buffer to file */ + if (!_empty_section) + _buffer.write_to_file(*_dst_file, _file_path); + + _buffer.clear(); + _dst_file.destruct(); +} + + +Trace_recorder::Writer_base &Backend::create_writer(Genode::Allocator &alloc, + Genode::Registry ®istry, + Directory &, + Directory::Path const &) +{ + return *new (alloc) Writer(registry, _interface_registry, _buffer, _ts_calibrator); +} diff --git a/repos/gems/src/app/trace_recorder/pcapng/backend.h b/repos/gems/src/app/trace_recorder/pcapng/backend.h new file mode 100644 index 0000000000..392bcffd72 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/pcapng/backend.h @@ -0,0 +1,90 @@ +/* + * \brief PCAPNG backend + * \author Johannes Schlatow + * \date 2022-05-13 + */ + +/* + * Copyright (C) 2022 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 _PCAPNG__BACKEND_H_ +#define _PCAPNG__BACKEND_H_ + +/* local includes */ +#include +#include +#include +#include + +/* Genode includes */ +#include + +namespace Pcapng { + using namespace Trace_recorder; + + using Genode::Directory; + using Genode::Append_file; + + using Buffer = Write_buffer<32*1024>; + + class Backend; + class Writer; +} + + +class Pcapng::Writer : public Trace_recorder::Writer_base +{ + private: + Interface_registry &_interface_registry; + Buffer &_buffer; + Timestamp_calibrator const &_ts_calibrator; + Constructible _dst_file { }; + Directory::Path _file_path { }; + bool _empty_section { false }; + + public: + Writer(Genode::Registry ®istry, Interface_registry &interface_registry, Buffer &buffer, Timestamp_calibrator const &ts_calibrator) + : Writer_base(registry), + _interface_registry(interface_registry), + _buffer(buffer), + _ts_calibrator(ts_calibrator) + { } + + virtual void start_iteration(Directory &, + Directory::Path const &, + ::Subject_info const &) override; + + virtual void process_event(Trace_recorder::Trace_event_base const &, Genode::size_t) override; + + virtual void end_iteration() override; +}; + + +class Pcapng::Backend : Trace_recorder::Backend_base +{ + private: + + Interface_registry _interface_registry; + Buffer _buffer { }; + Timestamp_calibrator const &_ts_calibrator; + + public: + + Backend(Allocator &alloc, Timestamp_calibrator const &ts_calibrator, Backends &backends) + : Backend_base(backends, "pcapng"), + _interface_registry(alloc), + _ts_calibrator(ts_calibrator) + { } + + Writer_base &create_writer(Genode::Allocator &, + Genode::Registry &, + Directory &, + Directory::Path const &) override; +}; + + +#endif /* _PCAPNG__BACKEND_H_ */ diff --git a/repos/gems/src/app/trace_recorder/pcapng/block.h b/repos/gems/src/app/trace_recorder/pcapng/block.h new file mode 100644 index 0000000000..c621f864bb --- /dev/null +++ b/repos/gems/src/app/trace_recorder/pcapng/block.h @@ -0,0 +1,88 @@ +/* + * \brief Generic type for PCAPNG blocks + * \author Johannes Schlatow + * \date 2022-05-12 + */ + +/* + * Copyright (C) 2022 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 _PCAPNG__BLOCK_H_ +#define _PCAPNG__BLOCK_H_ + +/* Genode includes */ +#include + +namespace Pcapng { + struct Block_base; + + template + struct Block; +} + +struct Pcapng::Block_base +{ + /** + * Layout: ----- 32-bit ----- + * | Type | + * ------------------ + * | Length | + * ------------------ + * | ... | + * ------------------ + * | Length | + * ------------------ + */ + + uint32_t const _type; + uint32_t _length { 0 }; + + static constexpr uint32_t padded_size(uint32_t hdr_sz) + { + /* add padding to 4-byte boundary */ + const uint32_t hdr_sz_padded = Genode::align_addr(hdr_sz, 2); + + return hdr_sz_padded; + } + + static constexpr uint32_t block_size(uint32_t sz) + { + return padded_size(sz) + sizeof(uint32_t); + } + + Block_base(uint32_t type) + : _type(type) + { } + + void commit(uint32_t hdr_sz) + { + const uint32_t hdr_sz_padded = padded_size(hdr_sz); + + _length = hdr_sz_padded + sizeof(uint32_t); + + /* store length also after payload to support backward navigation */ + ((uint32_t*)this)[hdr_sz_padded/4] = _length; + } + + bool has_type(uint32_t type) const { return _type == type; } + uint32_t size() const { return _length; } + +} __attribute__((packed)); + + +template +struct Pcapng::Block : Pcapng::Block_base +{ + Block() + : Block_base(TYPE_ID) + { } + + static uint32_t type() { return TYPE_ID; }; + +} __attribute__((packed)); + +#endif /* _PCAPNG__BLOCK_H_ */ diff --git a/repos/gems/src/app/trace_recorder/pcapng/enhanced_packet_block.h b/repos/gems/src/app/trace_recorder/pcapng/enhanced_packet_block.h new file mode 100644 index 0000000000..f9ec1fdd25 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/pcapng/enhanced_packet_block.h @@ -0,0 +1,81 @@ +/* + * \brief Enhanced packet block + * \author Johannes Schlatow + * \date 2022-05-12 + */ + +/* + * Copyright (C) 2022 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 _PCAPNG__ENHANCED_PACKET_BLOCK_H_ +#define _PCAPNG__ENHANCED_PACKET_BLOCK_H_ + +/* local includes */ +#include + +/* Genode includes */ +#include + +namespace Pcapng { + using namespace Genode; + + struct Enhanced_packet_block; +} + + +/* converts Traced_packet into a Pcapng block structure */ +struct Pcapng::Enhanced_packet_block : Block<0x6> +{ + /** + * Layout: -------- 32-bit ------- + * | 0x00000006 | + * ----------------------- + * | Length | + * ----------------------- + * | Interface ID | + * ----------------------- + * | Timestamp High | + * ----------------------- + * | Timestamp Low | + * ----------------------- + * | Captured Length | + * ----------------------- + * | Original Length | + * ----------------------- + * | Packet Data | + * | ... | + * | (padded) | + * ----------------------- + * | Length | + * ----------------------- + */ + + uint32_t _interface_id; + uint32_t _timestamp_high; + uint32_t _timestamp_low; + Traced_packet _data; + + enum { + MAX_CAPTURE_LENGTH = 1600, + MAX_SIZE = block_size(sizeof(Block_base) + + sizeof(_interface_id) + + sizeof(_timestamp_high) + + sizeof(_timestamp_low) + + sizeof(Traced_packet) + + MAX_CAPTURE_LENGTH) + }; + + Enhanced_packet_block(uint32_t interface_id, Traced_packet const &packet, uint64_t timestamp) + : _interface_id(interface_id), + _timestamp_high((uint32_t)(timestamp >> 32)), + _timestamp_low(timestamp & 0xFFFFFFFF), + _data(packet) + { commit(sizeof(Enhanced_packet_block) + _data.data_length()); } + +} __attribute__((packed)); + +#endif /* _PCAPNG__ENHANCED_PACKET_BLOCK_H_ */ diff --git a/repos/gems/src/app/trace_recorder/pcapng/interface_description_block.h b/repos/gems/src/app/trace_recorder/pcapng/interface_description_block.h new file mode 100644 index 0000000000..55ac4e7b3e --- /dev/null +++ b/repos/gems/src/app/trace_recorder/pcapng/interface_description_block.h @@ -0,0 +1,82 @@ +/* + * \brief Interface description block + * \author Johannes Schlatow + * \date 2022-05-12 + */ + +/* + * Copyright (C) 2022 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 _PCAPNG__INTERFACE_DESCRIPTION_BLOCK_H_ +#define _PCAPNG__INTERFACE_DESCRIPTION_BLOCK_H_ + +/* local includes */ +#include +#include + +/* genode includes */ +#include + +namespace Pcapng { + using namespace Genode; + + struct Interface_description_block; +} + + +struct Pcapng::Interface_description_block : Block<0x1> +{ + /** + * Layout: -------- 32-bit ------- + * | 0x00000001 | + * ----------------------- + * | Length | + * ----------------------- + * | LinkType | Reserved | + * ----------------------- + * | SnapLen | + * ----------------------- + * | 0x0002 | NameLen | + * ----------------------- + * | Name | + * | ... | + * | (padded) | + * ----------------------- + * | 0x0001 | 0x0000 | + * ----------------------- + * | Length | + * ----------------------- + */ + + uint16_t const _link_type; + uint16_t const _reserved { 0 }; + uint32_t _snaplen; + uint32_t _data[0] { }; + + enum { + MAX_SIZE = block_size(sizeof(Block_base) + + Interface_name::MAX_NAME_LEN + + sizeof(_link_type) + + sizeof(_reserved) + + sizeof(_snaplen) + + sizeof(Option_ifname) + + sizeof(Option_end)) + }; + + Interface_description_block(Interface_name const &name, uint32_t snaplen) + : _link_type(name._link_type), + _snaplen(snaplen) + { + Option_ifname &opt_ifname = *construct_at(&_data[0], name); + Option_end &opt_end = *construct_at (&_data[opt_ifname.total_length()/4]); + + commit((uint32_t)sizeof(Interface_description_block) + opt_ifname.total_length() + opt_end.total_length()); + } + +} __attribute__((packed)); + +#endif /* _PCAPNG__INTERFACE_DESCRIPTION_BLOCK_H_ */ diff --git a/repos/gems/src/app/trace_recorder/pcapng/interface_registry.h b/repos/gems/src/app/trace_recorder/pcapng/interface_registry.h new file mode 100644 index 0000000000..de1063cbf8 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/pcapng/interface_registry.h @@ -0,0 +1,101 @@ +/* + * \brief Registry for storing interfaces description blocks + * \author Johannes Schlatow + * \date 2022-05-16 + */ + +/* + * Copyright (C) 2022 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 _PCAPNG__INTERFACE_REGISTRY_H_ +#define _PCAPNG__INTERFACE_REGISTRY_H_ + +/* local includes */ +#include +#include + +namespace Pcapng { + using namespace Trace_recorder; + using namespace Genode; + + class Interface; + class Interface_registry; +} + + +class Pcapng::Interface +{ + public: + + using Name = String; + + private: + + Name const _name; + unsigned const _id; + + Registry::Element _element; + + public: + + Interface(Name const &name, unsigned id, Registry ®istry) + : _name(name), + _id(id), + _element(registry, *this) + { } + + /************* + * Accessors * + *************/ + + unsigned id() const { return _id; } + Name const &name() const { return _name; } +}; + + +class Pcapng::Interface_registry : private Registry +{ + private: + + unsigned _next_id { 0 }; + Allocator &_alloc; + + public: + + Interface_registry(Allocator &alloc) + : _alloc(alloc) + { } + + /* apply to existing Interface or create new one */ + template + void from_name(Interface_name const &name, FUNC_EXISTS && fn_exists, FUNC_NEW && fn_new) + { + bool found = false; + for_each([&] (Interface const &iface) { + if (iface.name() == name.string()) { + found = true; + fn_exists(iface); + } + }); + + /* create new interface */ + if (!found) { + if (fn_new(name, _next_id)) + new (_alloc) Interface(Interface::Name(name.string()), _next_id++, *this); + } + } + + void clear() + { + for_each([&] (Interface &iface) { destroy(_alloc, &iface); }); + + _next_id = 0; + } +}; + + +#endif /* _PCAPNG__INTERFACE_REGISTRY_H_ */ diff --git a/repos/gems/src/app/trace_recorder/pcapng/option.h b/repos/gems/src/app/trace_recorder/pcapng/option.h new file mode 100644 index 0000000000..38addc84ad --- /dev/null +++ b/repos/gems/src/app/trace_recorder/pcapng/option.h @@ -0,0 +1,69 @@ +/* + * \brief Option fields + * \author Johannes Schlatow + * \date 2022-05-12 + */ + +/* + * Copyright (C) 2022 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 _PCAPNG__OPTION_H_ +#define _PCAPNG__OPTION_H_ + +#include + +namespace Pcapng { + using namespace Genode; + + template + struct Option; + + struct Option_ifname; + struct Option_end; +} + +template +struct Pcapng::Option +{ + uint16_t _type { TYPE }; + uint16_t _length; + uint32_t _data[0]; + + static uint16_t padded_size(uint16_t sz) { + return (uint16_t)align_addr((uint32_t)sz, 2); } + + Option(uint16_t length) + : _length(length) + { } + + template + T *data() { return (T*)_data; } + + uint16_t total_length() const { return padded_size(sizeof(Option) + _length); } +} __attribute__((packed)); + + +struct Pcapng::Option_end : Option<1> +{ + Option_end() : Option(0) { } +} __attribute__((packed)); + + +struct Pcapng::Option_ifname : Option<2> +{ + static uint16_t padded_size(Interface_name const &name) { + return (uint16_t)align_addr((uint32_t)name.data_length() - 1, 2); } + + Option_ifname(Interface_name const &name) + : Option((uint16_t)(name.data_length()-1)) + { + /* copy string leaving out null-termination */ + memcpy(data(), name.string(), name.data_length()-1); + } +} __attribute__((packed)); + +#endif /* _PCAPNG__OPTION_H_ */ diff --git a/repos/gems/src/app/trace_recorder/pcapng/section_header_block.h b/repos/gems/src/app/trace_recorder/pcapng/section_header_block.h new file mode 100644 index 0000000000..4bec4917bc --- /dev/null +++ b/repos/gems/src/app/trace_recorder/pcapng/section_header_block.h @@ -0,0 +1,71 @@ +/* + * \brief Section header block + * \author Johannes Schlatow + * \date 2022-05-12 + */ + +/* + * Copyright (C) 2022 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 _PCAPNG__SECTION_HEADER_BLOCK_H_ +#define _PCAPNG__SECTION_HEADER_BLOCK_H_ + +/* local includes */ +#include + +namespace Pcapng { + using namespace Genode; + + struct Section_header_block; +} + + +struct Pcapng::Section_header_block : Block<0x0A0D0D0A> +{ + /** + * Layout: ----- 32-bit ---- + * | 0x0A0D0D0A | + * ----------------- + * | Length | + * ----------------- + * | 0x1A2B3C4D | + * ----------------- + * | Major | Minor | + * ----------------- + * | SectionLen Hi | + * ----------------- + * | SectionLen Lo | + * ----------------- + * | Length | + * ----------------- + */ + + uint32_t const _byte_order_magic { 0x1A2B3C4D }; + uint16_t const _major_version { 1 }; + uint16_t const _minor_version { 0 }; + uint64_t const _section_length { 0xFFFFFFFFFFFFFFFF }; /* unspecified */ + + enum : size_t { + MAX_SIZE = block_size(sizeof(Block_base) + + sizeof(_byte_order_magic) + + sizeof(_major_version) + + sizeof(_minor_version) + + sizeof(_section_length)) + }; + + Section_header_block() + { commit(sizeof(Section_header_block)); } + + /** + * XXX instead of using an unspecified section length, we could add an + * interface similar to Ctf::Packet_header for append sub-blocks and + * keeping track of the length field. + */ + +} __attribute__((packed)); + +#endif /* _PCAPNG__SECTION_HEADER_BLOCK_H_ */ diff --git a/repos/gems/src/app/trace_recorder/pcapng/write_buffer.h b/repos/gems/src/app/trace_recorder/pcapng/write_buffer.h new file mode 100644 index 0000000000..349092daea --- /dev/null +++ b/repos/gems/src/app/trace_recorder/pcapng/write_buffer.h @@ -0,0 +1,79 @@ +/* + * \brief Convenience helper for batching pcapng blocks before writing to file + * \author Johannes Schlatow + * \date 2022-05-16 + */ + +/* + * Copyright (C) 2022 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 _PCAPNG__WRITE_BUFFER_H_ +#define _PCAPNG__WRITE_BUFFER_H_ + +/* Genode includes */ +#include +#include + +namespace Pcapng +{ + using namespace Genode; + + template + class Write_buffer; +} + +template +class Pcapng::Write_buffer +{ + public: + + enum class Append_error { OUT_OF_MEM, OVERFLOW }; + struct Append_ok { }; + using Append_result = Attempt; + + private: + + size_t _total_length { 0 }; + char _buffer[BUFSIZE] { }; + + public: + + template + Append_result append(ARGS &&... args) + { + if (T::MAX_SIZE > BUFSIZE || _total_length > BUFSIZE - T::MAX_SIZE) + return Append_error::OUT_OF_MEM; + + void *ptr = &_buffer[_total_length]; + + T const &block = *construct_at(ptr, args...); + + if (block.size() > T::MAX_SIZE) { + error("block size of ", block.size(), " exceeds reserved size ", (unsigned)T::MAX_SIZE); + return Append_error::OVERFLOW; + } + + _total_length += block.size(); + + return Append_ok(); + } + + void write_to_file(Genode::Append_file &dst, Directory::Path const &path) + { + if (_total_length == 0) + return; + + if (dst.append(_buffer, _total_length) != Append_file::Append_result::OK) + error("Write error for ", path); + + clear(); + } + + void clear() { _total_length = 0; } +}; + +#endif /* _PCAPNG__WRITE_BUFFER_H_ */ diff --git a/repos/gems/src/app/trace_recorder/policy.cc b/repos/gems/src/app/trace_recorder/policy.cc new file mode 100644 index 0000000000..f39fbce27f --- /dev/null +++ b/repos/gems/src/app/trace_recorder/policy.cc @@ -0,0 +1,33 @@ +/* + * \brief Installs and maintains a tracing policy + * \author Johannes Schlatow + * \date 2022-05-10 + */ + +/* + * Copyright (C) 2022 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. + */ + +/* local includes */ +#include + +using namespace Genode; + +Trace_recorder::Policy::Policy(Env &env, + Trace::Connection &trace, + Policy::Name const &name, + Policies &policies) +: + Policies::Element(policies, name), + _env(env), _trace(trace), _rom(env, name.string()) +{ + Dataspace_capability dst_ds = _trace.policy(_id); + void *dst = _env.rm().attach(dst_ds); + void *src = _env.rm().attach(_ds); + memcpy(dst, src, _size); + _env.rm().detach(dst); + _env.rm().detach(src); +} diff --git a/repos/gems/src/app/trace_recorder/policy.h b/repos/gems/src/app/trace_recorder/policy.h new file mode 100644 index 0000000000..6653b329dd --- /dev/null +++ b/repos/gems/src/app/trace_recorder/policy.h @@ -0,0 +1,66 @@ +/* + * \brief Installs and maintains a tracing policy + * \author Johannes Schlatow + * \date 2022-05-10 + */ + +/* + * Copyright (C) 2022 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 _POLICY_H_ +#define _POLICY_H_ + +/* Genode includes */ +#include +#include +#include +#include + +namespace Trace_recorder { + class Policy; + + using Policy_name = Genode::String<64>; + using Policies = Genode::Dictionary; +} + + +/** + * Installs and maintains a tracing policy + */ +class Trace_recorder::Policy : Policies::Element +{ + private: + friend class Genode::Dictionary; + friend class Genode::Avl_node; + friend class Genode::Avl_tree; + + Genode::Env &_env; + Genode::Trace::Connection &_trace; + Genode::Rom_connection _rom; + Genode::Rom_dataspace_capability const _ds { _rom.dataspace() }; + Genode::size_t const _size { Genode::Dataspace_client(_ds).size() }; + Genode::Trace::Policy_id const _id { _trace.alloc_policy(_size) }; + + public: + + using Name = Policy_name; + using Policies::Element::name; + + Policy(Genode::Env &env, + Genode::Trace::Connection &trace, + Name const &name, + Policies &policies); + + + /*************** + ** Accessors ** + ***************/ + + Genode::Trace::Policy_id id() const { return _id; } +}; + +#endif /* _POLICY_H_ */ diff --git a/repos/gems/src/app/trace_recorder/subject_info.h b/repos/gems/src/app/trace_recorder/subject_info.h new file mode 100644 index 0000000000..c26dd35411 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/subject_info.h @@ -0,0 +1,39 @@ +/* + * \brief Helper for storing static parts of Trace::Subject_info + * \author Johannes Schlatow + * \date 2021-08-06 + */ + +/* + * 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 _SUBJECT_INFO_H_ +#define _SUBJECT_INFO_H_ + +#include + +struct Subject_info +{ + Genode::Session_label _session_label; + Genode::Trace::Thread_name _thread_name; + Genode::Affinity::Location _affinity; + unsigned _priority; + + Subject_info(Genode::Trace::Subject_info const &info) + : _session_label(info.session_label()), + _thread_name(info.thread_name()), + _affinity(info.affinity()), + _priority(info.execution_time().priority) + { } + + Genode::Session_label const &session_label() const { return _session_label; } + Genode::Trace::Thread_name const &thread_name() const { return _thread_name; } + Genode::Affinity::Location const &affinity() const { return _affinity; } + unsigned priority() const { return _priority; } +}; + +#endif /* _SUBJECT_INFO_H_ */ diff --git a/repos/gems/src/app/trace_recorder/target.mk b/repos/gems/src/app/trace_recorder/target.mk new file mode 100644 index 0000000000..4660175b93 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/target.mk @@ -0,0 +1,5 @@ +TARGET = trace_recorder +INC_DIR += $(PRG_DIR) +SRC_CC = main.cc monitor.cc policy.cc ctf/backend.cc pcapng/backend.cc +CONFIG_XSD = config.xsd +LIBS += base vfs diff --git a/repos/gems/src/app/trace_recorder/timestamp_calibrator.h b/repos/gems/src/app/trace_recorder/timestamp_calibrator.h new file mode 100644 index 0000000000..2675890fe6 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/timestamp_calibrator.h @@ -0,0 +1,127 @@ +/* + * \brief Helper for converting Trace::Timestamp to epoch + * \author Johannes Schlatow + * \date 2022-05-19 + */ + +/* + * Copyright (C) 2022 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 _TIMESTAMP_CALIBRATOR_H_ +#define _TIMESTAMP_CALIBRATOR_H_ + +/* Genode includes */ +#include +#include +#include +#include + +namespace Trace_recorder { + using namespace Genode; + + class Timestamp_calibrator; +} + + +class Trace_recorder::Timestamp_calibrator +{ + private: + + uint64_t const _frequency_hz; + uint64_t const _epoch_start_in_us; + Trace::Timestamp const _ts_start { Trace::timestamp() }; + + enum : uint64_t { + USEC_PER_SEC = 1000ULL * 1000ULL, + USEC_PER_MIN = USEC_PER_SEC * 60, + USEC_PER_HOUR = USEC_PER_MIN * 60, + USEC_PER_DAY = USEC_PER_HOUR * 24, + }; + + static uint64_t _day_of_year(Rtc::Timestamp time) + { + /* look up table, starts with month=0 */ + unsigned days_until_month[] = { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; + + uint64_t result = time.day + days_until_month[time.month]; + + /* check for leap year */ + if (time.month >= 3) { + if ((time.year % 1000) == 0 || ((time.year % 4) == 0 && !(time.year % 100) == 0)) + return result + 1; + } + + return result; + } + + uint64_t _timestamp_frequency(Env &env, Timer::Connection &timer) + { + using namespace Genode; + + /* try getting tsc frequency from platform info, measure if failed */ + try { + Attached_rom_dataspace const platform_info (env, "platform_info"); + Xml_node const hardware = platform_info.xml().sub_node("hardware"); + uint64_t const tsc_freq = hardware.sub_node("tsc").attribute_value("freq_khz", 0ULL); + bool const invariant = hardware.sub_node("tsc").attribute_value("invariant", true); + + if (!invariant) + error("No invariant TSC available"); + + if (tsc_freq) + return tsc_freq * 1000ULL; + } catch (...) { } + + warning("Falling back to measured timestamp frequency"); + /* measure frequency using timer */ + Trace::Timestamp start = Trace::timestamp(); + timer.msleep(1000); + return (Trace::timestamp() - start); + } + + uint64_t _current_epoch_us(Rtc::Connection &rtc) + { + Rtc::Timestamp const current_time { rtc.current_time() }; + + // assuming year > 2000 or year == 0 + uint64_t usec_until_y2k = (30*365 + 30/4) * USEC_PER_DAY; + uint64_t years_since_y2k = current_time.year ? current_time.year - 2000 : 0; + uint64_t days_since_y2k = years_since_y2k * 365 + years_since_y2k/4 - + years_since_y2k/100 + + years_since_y2k/1000 + + _day_of_year(current_time); + + return usec_until_y2k + + days_since_y2k * USEC_PER_DAY + + current_time.hour * USEC_PER_HOUR + + current_time.minute * USEC_PER_MIN + + current_time.second * USEC_PER_SEC + + current_time.microsecond; + } + + public: + + Timestamp_calibrator(Env &env, Rtc::Connection &rtc, Timer::Connection &timer) + : _frequency_hz (_timestamp_frequency(env, timer)), + _epoch_start_in_us(_current_epoch_us(rtc)) + { + log("Timestamp frequency is ", _frequency_hz, "Hz"); + } + + uint64_t ticks_per_second() const { return _frequency_hz; } + + uint64_t epoch_from_timestamp_in_us(Trace::Timestamp ts) const + { + /* intentionally ignoring timestamp wraparounds */ + uint64_t ts_diff = ts - _ts_start; + + return _epoch_start_in_us + (ts_diff / (ticks_per_second() / USEC_PER_SEC)); + } +}; + + +#endif /* _TIMESTAMP_CALIBRATOR_H_ */ diff --git a/repos/gems/src/app/trace_recorder/writer.h b/repos/gems/src/app/trace_recorder/writer.h new file mode 100644 index 0000000000..5dd95074e0 --- /dev/null +++ b/repos/gems/src/app/trace_recorder/writer.h @@ -0,0 +1,62 @@ +/* + * \brief Base class for processing traces and writing outputs + * \author Johannes Schlatow + * \date 2022-05-11 + */ + +/* + * Copyright (C) 2022 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 _WRITER_H_ +#define _WRITER_H_ + +/* local includes */ +#include + +/* Genode includes */ +#include +#include +#include +#include + +namespace Trace_recorder { + class Writer_base; + + using Directory = Genode::Directory; + using Writer_registry = Genode::Registry; +} + + +class Trace_recorder::Writer_base +{ + protected: + + Writer_registry::Element _element; + + public: + + Writer_base(Writer_registry ®istry) + : _element(registry, *this) + { } + + virtual ~Writer_base() { } + + /*************** + ** Interface ** + ***************/ + + virtual void start_iteration(Directory &, + Directory::Path const &, + ::Subject_info const &) = 0; + + virtual void process_event(Trace_recorder::Trace_event_base const &, Genode::size_t) = 0; + + virtual void end_iteration() = 0; +}; + + +#endif /* _WRITER_H_ */ diff --git a/repos/gems/src/app/window_layouter/assign.h b/repos/gems/src/app/window_layouter/assign.h index 840177db0e..8ecea234af 100644 --- a/repos/gems/src/app/window_layouter/assign.h +++ b/repos/gems/src/app/window_layouter/assign.h @@ -81,8 +81,8 @@ class Window_layouter::Assign : public List_model::Element _maximized = assign.attribute_value("maximized", false); _xpos_any = assign.attribute_value("xpos", String<20>()) == "any"; _ypos_any = assign.attribute_value("ypos", String<20>()) == "any"; - _pos = point_attribute(assign); - _size = area_attribute(assign); + _pos = Point::from_xml(assign); + _size = Area::from_xml(assign); } /* diff --git a/repos/gems/src/app/window_layouter/types.h b/repos/gems/src/app/window_layouter/types.h index a331faaed3..254fcc37e1 100644 --- a/repos/gems/src/app/window_layouter/types.h +++ b/repos/gems/src/app/window_layouter/types.h @@ -15,19 +15,15 @@ #define _TYPES_H_ /* Genode includes */ -#include -#include +#include namespace Window_layouter { using namespace Genode; - typedef Decorator::Point Point; - typedef Decorator::Area Area; - typedef Decorator::Rect Rect; - - using Decorator::area_attribute; - using Decorator::point_attribute; + typedef Surface_base::Point Point; + typedef Surface_base::Area Area; + typedef Surface_base::Rect Rect; struct Window_id { diff --git a/repos/gems/src/app/window_layouter/window_list.h b/repos/gems/src/app/window_layouter/window_list.h index 6945de0cf7..851b2ee1bd 100644 --- a/repos/gems/src/app/window_layouter/window_list.h +++ b/repos/gems/src/app/window_layouter/window_list.h @@ -72,7 +72,7 @@ class Window_layouter::Window_list Window &create_element(Xml_node node) { unsigned const id = node.attribute_value("id", 0U); - Area const initial_size = area_attribute(node); + Area const initial_size = Area::from_xml(node); Window::Label const label = node.attribute_value("label",Window::Label()); @@ -85,7 +85,7 @@ class Window_layouter::Window_list void update_element(Window &win, Xml_node node) { - win.client_size(area_attribute(node)); + win.client_size(Area::from_xml(node)); win.title (node.attribute_value("title", Window::Title(""))); win.has_alpha (node.attribute_value("has_alpha", false)); win.hidden (node.attribute_value("hidden", false)); diff --git a/repos/gems/src/lib/cpu_sampler_platform-foc/target.mk b/repos/gems/src/lib/cpu_sampler_platform-foc/target.mk deleted file mode 100644 index 608795f52a..0000000000 --- a/repos/gems/src/lib/cpu_sampler_platform-foc/target.mk +++ /dev/null @@ -1,4 +0,0 @@ -TARGET = cpu_sampler_platform-foc -LIBS = cpu_sampler_platform-foc - -CC_CXX_WARN_STRICT = diff --git a/repos/gems/src/lib/cpu_sampler_platform-generic/target.mk b/repos/gems/src/lib/cpu_sampler_platform-generic/target.mk deleted file mode 100644 index c5fb6e353f..0000000000 --- a/repos/gems/src/lib/cpu_sampler_platform-generic/target.mk +++ /dev/null @@ -1,4 +0,0 @@ -TARGET = cpu_sampler_platform-generic -LIBS = cpu_sampler_platform-generic - -CC_CXX_WARN_STRICT = diff --git a/repos/gems/src/lib/cpu_sampler_platform-nova/target.mk b/repos/gems/src/lib/cpu_sampler_platform-nova/target.mk deleted file mode 100644 index 8316496f5b..0000000000 --- a/repos/gems/src/lib/cpu_sampler_platform-nova/target.mk +++ /dev/null @@ -1,4 +0,0 @@ -TARGET = cpu_sampler_platform-nova -LIBS = cpu_sampler_platform-nova - -CC_CXX_WARN_STRICT = diff --git a/repos/gems/src/lib/vfs/audit/target.mk b/repos/gems/src/lib/vfs/audit/target.mk deleted file mode 100644 index f18d7b3788..0000000000 --- a/repos/gems/src/lib/vfs/audit/target.mk +++ /dev/null @@ -1,4 +0,0 @@ -TARGET = dummy-vfs_audit -LIBS = vfs_audit - -BUILD_ARTIFACTS := diff --git a/repos/gems/src/lib/vfs/cbe/target.mk b/repos/gems/src/lib/vfs/cbe/target.mk deleted file mode 100644 index 6f9ef45af1..0000000000 --- a/repos/gems/src/lib/vfs/cbe/target.mk +++ /dev/null @@ -1,5 +0,0 @@ -TARGET := lib-vfs-cbe -REQUIRES = x86_64 -LIBS = vfs_cbe - -BUILD_ARTIFACTS := diff --git a/repos/gems/src/lib/vfs/cbe_crypto/aes_cbc/target.mk b/repos/gems/src/lib/vfs/cbe_crypto/aes_cbc/target.mk deleted file mode 100644 index 3ae9ca776d..0000000000 --- a/repos/gems/src/lib/vfs/cbe_crypto/aes_cbc/target.mk +++ /dev/null @@ -1,3 +0,0 @@ -TARGET := lib-vfs-cbe_crypto-aes_cbc -REQUIRES = x86_64 -LIBS = vfs_cbe_crypto_aes_cbc diff --git a/repos/gems/src/lib/vfs/cbe_crypto/memcopy/target.mk b/repos/gems/src/lib/vfs/cbe_crypto/memcopy/target.mk deleted file mode 100644 index 2056779d98..0000000000 --- a/repos/gems/src/lib/vfs/cbe_crypto/memcopy/target.mk +++ /dev/null @@ -1,3 +0,0 @@ -TARGET := lib-vfs-cbe_crypto-memcopy -REQUIRES = x86_64 -LIBS = vfs_cbe_crypto_memcopy diff --git a/repos/gems/src/lib/vfs/cbe_trust_anchor/target.mk b/repos/gems/src/lib/vfs/cbe_trust_anchor/target.mk deleted file mode 100644 index b2cdea8241..0000000000 --- a/repos/gems/src/lib/vfs/cbe_trust_anchor/target.mk +++ /dev/null @@ -1,5 +0,0 @@ -TARGET := lib-vfs-cbe_trust_anchor -REQUIRES = x86_64 -LIBS = vfs_cbe_trust_anchor - -BUILD_ARTIFACTS := diff --git a/repos/gems/src/lib/vfs/gpu/target.mk b/repos/gems/src/lib/vfs/gpu/target.mk deleted file mode 100644 index e9e3b042f4..0000000000 --- a/repos/gems/src/lib/vfs/gpu/target.mk +++ /dev/null @@ -1,3 +0,0 @@ -LIBS = vfs_gpu - -BUILD_ARTIFACTS := diff --git a/repos/gems/src/lib/vfs/import/target.mk b/repos/gems/src/lib/vfs/import/target.mk deleted file mode 100644 index fb15587c9a..0000000000 --- a/repos/gems/src/lib/vfs/import/target.mk +++ /dev/null @@ -1,4 +0,0 @@ -TARGET = dummy-vfs_import -LIBS = vfs_import - -BUILD_ARTIFACTS := diff --git a/repos/gems/src/lib/vfs/pipe/target.mk b/repos/gems/src/lib/vfs/pipe/target.mk deleted file mode 100644 index adb1db499e..0000000000 --- a/repos/gems/src/lib/vfs/pipe/target.mk +++ /dev/null @@ -1,4 +0,0 @@ -TARGET = dummy-vfs_pipe -LIBS = vfs_pipe base - -BUILD_ARTIFACTS := diff --git a/repos/gems/src/lib/vfs/trace/target.mk b/repos/gems/src/lib/vfs/trace/target.mk deleted file mode 100644 index 2ac95e2cde..0000000000 --- a/repos/gems/src/lib/vfs/trace/target.mk +++ /dev/null @@ -1,3 +0,0 @@ -LIBS = vfs_trace - -BUILD_ARTIFACTS := diff --git a/repos/gems/src/lib/vfs/ttf/target.mk b/repos/gems/src/lib/vfs/ttf/target.mk deleted file mode 100644 index 5c7e547164..0000000000 --- a/repos/gems/src/lib/vfs/ttf/target.mk +++ /dev/null @@ -1,4 +0,0 @@ -TARGET = dummy-vfs_ttf -LIBS = vfs_ttf - -BUILD_ARTIFACTS := diff --git a/repos/gems/src/server/terminal/main.cc b/repos/gems/src/server/terminal/main.cc index 4b6d3a2dc7..a77da2c8a5 100644 --- a/repos/gems/src/server/terminal/main.cc +++ b/repos/gems/src/server/terminal/main.cc @@ -211,7 +211,7 @@ struct Terminal::Main : Character_consumer _fb_mode = _gui.mode(); /* apply initial size from config, if provided */ - _config.xml().with_sub_node("initial", [&] (Xml_node const &initial) { + _config.xml().with_optional_sub_node("initial", [&] (Xml_node const &initial) { _fb_mode.area = Area(initial.attribute_value("width", _fb_mode.area.w()), initial.attribute_value("height", _fb_mode.area.h())); }); diff --git a/repos/gems/src/trace_recorder/policy/ctf0/policy.cc b/repos/gems/src/trace_recorder/policy/ctf0/policy.cc new file mode 100644 index 0000000000..a072019b3a --- /dev/null +++ b/repos/gems/src/trace_recorder/policy/ctf0/policy.cc @@ -0,0 +1,80 @@ +#include +#include +#include + +using namespace Genode; +using namespace Ctf; + +enum { MAX_EVENT_SIZE = 64 }; + +size_t max_event_size() +{ + return MAX_EVENT_SIZE; +} + +size_t trace_eth_packet(char *, char const *, bool, char *, size_t) +{ + return 0; +} + +size_t checkpoint(char *dst, char const *name, unsigned long data, void *addr, unsigned char type) +{ + size_t len = strlen(name) + 1; + + new (dst) Checkpoint(name, len, data, addr, type); + + return len + sizeof(Checkpoint); +} + +size_t log_output(char *dst, char const *log_message, size_t len) { + return 0; +} + +size_t rpc_call(char *dst, char const *rpc_name, Msgbuf_base const &) +{ + size_t len = strlen(rpc_name) + 1; + + new (dst) Rpc_call(rpc_name, len); + + return len + sizeof(Rpc_call); +} + +size_t rpc_returned(char *dst, char const *rpc_name, Msgbuf_base const &) +{ + size_t len = strlen(rpc_name) + 1; + + new (dst) Rpc_returned(rpc_name, len); + + return len + sizeof(Rpc_returned); +} + +size_t rpc_dispatch(char *dst, char const *rpc_name) +{ + size_t len = strlen(rpc_name) + 1; + + new (dst) Rpc_dispatch(rpc_name, len); + + return len + sizeof(Rpc_dispatch); +} + +size_t rpc_reply(char *dst, char const *rpc_name) +{ + size_t len = strlen(rpc_name) + 1; + + new (dst) Rpc_reply(rpc_name, len); + + return len + sizeof(Rpc_reply); +} + +size_t signal_submit(char *dst, unsigned const num) +{ + new (dst) Signal_submit(num); + + return sizeof(Signal_submit); +} + +size_t signal_receive(char *dst, Signal_context const & context, unsigned num) +{ + new (dst) Signal_receive(num, (void*)&context); + return 0; +} diff --git a/repos/gems/src/trace_recorder/policy/ctf0/target.mk b/repos/gems/src/trace_recorder/policy/ctf0/target.mk new file mode 100644 index 0000000000..5ca9d7bb90 --- /dev/null +++ b/repos/gems/src/trace_recorder/policy/ctf0/target.mk @@ -0,0 +1,5 @@ +TARGET = ctf0_policy + +TARGET_POLICY = ctf0 + +include $(PRG_DIR)/../policy.inc diff --git a/repos/gems/src/trace_recorder/policy/ctf0_pcapng/policy.cc b/repos/gems/src/trace_recorder/policy/ctf0_pcapng/policy.cc new file mode 100644 index 0000000000..0f1e795d75 --- /dev/null +++ b/repos/gems/src/trace_recorder/policy/ctf0_pcapng/policy.cc @@ -0,0 +1,83 @@ +#include +#include +#include +#include + +using namespace Genode; +using namespace Ctf; + +enum { MAX_CAPTURE_LEN = 100 }; + +size_t max_event_size() { + return Trace_recorder::Pcapng_event::max_size(MAX_CAPTURE_LEN); } + +size_t trace_eth_packet(char *dst, char const *if_name, bool out, char *pkt_data, size_t pkt_len) +{ + using namespace Pcapng; + Trace_recorder::Pcapng_event *e = + new (dst) Trace_recorder::Pcapng_event(Link_type::ETHERNET, if_name, out, pkt_len, pkt_data, MAX_CAPTURE_LEN); + + return e->total_length(); +} + +size_t checkpoint(char *dst, char const *name, unsigned long data, void *addr, unsigned char type) +{ + size_t len = strlen(name) + 1; + + new (dst) Checkpoint(name, len, data, addr, type); + + return len + sizeof(Checkpoint); +} + +size_t log_output(char *dst, char const *log_message, size_t len) { + return 0; +} + +size_t rpc_call(char *dst, char const *rpc_name, Msgbuf_base const &) +{ + size_t len = strlen(rpc_name) + 1; + + new (dst) Rpc_call(rpc_name, len); + + return len + sizeof(Rpc_call); +} + +size_t rpc_returned(char *dst, char const *rpc_name, Msgbuf_base const &) +{ + size_t len = strlen(rpc_name) + 1; + + new (dst) Rpc_returned(rpc_name, len); + + return len + sizeof(Rpc_returned); +} + +size_t rpc_dispatch(char *dst, char const *rpc_name) +{ + size_t len = strlen(rpc_name) + 1; + + new (dst) Rpc_dispatch(rpc_name, len); + + return len + sizeof(Rpc_dispatch); +} + +size_t rpc_reply(char *dst, char const *rpc_name) +{ + size_t len = strlen(rpc_name) + 1; + + new (dst) Rpc_reply(rpc_name, len); + + return len + sizeof(Rpc_reply); +} + +size_t signal_submit(char *dst, unsigned const num) +{ + new (dst) Signal_submit(num); + + return sizeof(Signal_submit); +} + +size_t signal_receive(char *dst, Signal_context const & context, unsigned num) +{ + new (dst) Signal_receive(num, (void*)&context); + return 0; +} diff --git a/repos/gems/src/trace_recorder/policy/ctf0_pcapng/target.mk b/repos/gems/src/trace_recorder/policy/ctf0_pcapng/target.mk new file mode 100644 index 0000000000..2c152477c6 --- /dev/null +++ b/repos/gems/src/trace_recorder/policy/ctf0_pcapng/target.mk @@ -0,0 +1,5 @@ +TARGET = ctf0_pcapng_policy + +TARGET_POLICY = ctf0_pcapng + +include $(PRG_DIR)/../policy.inc diff --git a/repos/gems/src/trace_recorder/policy/pcapng/policy.cc b/repos/gems/src/trace_recorder/policy/pcapng/policy.cc new file mode 100644 index 0000000000..3d76c23e7f --- /dev/null +++ b/repos/gems/src/trace_recorder/policy/pcapng/policy.cc @@ -0,0 +1,60 @@ +#include +#include + +using namespace Genode; + +enum { MAX_CAPTURE_LEN = 100 }; + + +size_t max_event_size() { + return Trace_recorder::Pcapng_event::max_size(MAX_CAPTURE_LEN); } + + +size_t trace_eth_packet(char *dst, char const *if_name, bool out, char *pkt_data, size_t pkt_len) +{ + using namespace Pcapng; + Trace_recorder::Pcapng_event *e = + new (dst) Trace_recorder::Pcapng_event(Link_type::ETHERNET, if_name, out, pkt_len, pkt_data, MAX_CAPTURE_LEN); + + return e->total_length(); +} + +size_t checkpoint(char *dst, char const *, unsigned long, void *, unsigned char) +{ + return 0; +} + +size_t log_output(char *dst, char const *log_message, size_t len) +{ + return 0; +} + +size_t rpc_call(char *dst, char const *rpc_name, Msgbuf_base const &) +{ + return 0; +} + +size_t rpc_returned(char *dst, char const *rpc_name, Msgbuf_base const &) +{ + return 0; +} + +size_t rpc_dispatch(char *dst, char const *rpc_name) +{ + return 0; +} + +size_t rpc_reply(char *dst, char const *rpc_name) +{ + return 0; +} + +size_t signal_submit(char *dst, unsigned const) +{ + return 0; +} + +size_t signal_receive(char *dst, Signal_context const &, unsigned) +{ + return 0; +} diff --git a/repos/gems/src/trace_recorder/policy/pcapng/target.mk b/repos/gems/src/trace_recorder/policy/pcapng/target.mk new file mode 100644 index 0000000000..ff7affa0cc --- /dev/null +++ b/repos/gems/src/trace_recorder/policy/pcapng/target.mk @@ -0,0 +1,5 @@ +TARGET = pcapng_policy + +TARGET_POLICY = pcapng + +include $(PRG_DIR)/../policy.inc diff --git a/repos/gems/src/trace_recorder/policy/policy.inc b/repos/gems/src/trace_recorder/policy/policy.inc new file mode 100644 index 0000000000..7c57d6f54e --- /dev/null +++ b/repos/gems/src/trace_recorder/policy/policy.inc @@ -0,0 +1,41 @@ +# +# \brief Common build rules for creating trace-policy modules +# \author Josef Soentgen +# \date 2013-08-12 +# + +CXX_OPT = -g -ffreestanding -fPIC -fno-exceptions -fno-rtti \ + -nostdinc -nostdlib -MMD + +CXX_OPT += $(CC_CXX_OPT_STD) + +LD_SCRIPT= $(PRG_DIR)/../policy.ld + +-include *.d +-include ../*.d + +table.o: table.cc + $(MSG_COMP)$@ + $(VERBOSE)$(CXX) -c $(CC_MARCH) $(CXX_OPT) $(INCLUDES) $< -o $@ + +policy.o: policy.cc + $(MSG_COMP)$@ + $(VERBOSE)$(CXX) -c $(CC_MARCH) $(CXX_OPT) $(INCLUDES) $< -o $@ + +$(TARGET_POLICY).elf: table.o policy.o + $(MSG_LINK)$@ + $(VERBOSE)$(LD) $(LD_MARCH) -T $(LD_SCRIPT) -Ttext=0 \ + $^ $(shell $(CXX) $(CC_MARCH) -print-libgcc-file-name) -o $@ + +$(INSTALL_DIR)/$(TARGET_POLICY): $(TARGET_POLICY).elf + $(VERBOSE)$(OBJCOPY) -O binary $< $@ + +$(TARGET): $(INSTALL_DIR)/$(TARGET_POLICY) + +clean cleanall: clean_policy + +clean_policy: + $(VERBOSE)$(RM) ../*.o ../*.d *.o *.d $(TARGET_POLICY).elf \ + $(BUILD_BASE_DIR)/bin/$(TARGET_POLICY) + +vpath table.cc $(REP_DIR)/src/trace_recorder/policy diff --git a/repos/os/src/lib/trace/policy/policy.ld b/repos/gems/src/trace_recorder/policy/policy.ld similarity index 100% rename from repos/os/src/lib/trace/policy/policy.ld rename to repos/gems/src/trace_recorder/policy/policy.ld diff --git a/repos/os/src/lib/trace/policy/table.cc b/repos/gems/src/trace_recorder/policy/table.cc similarity index 94% rename from repos/os/src/lib/trace/policy/table.cc rename to repos/gems/src/trace_recorder/policy/table.cc index 2541f60749..e92331d297 100644 --- a/repos/os/src/lib/trace/policy/table.cc +++ b/repos/gems/src/trace_recorder/policy/table.cc @@ -19,6 +19,8 @@ extern "C" { Genode::Trace::Policy_module policy_jump_table = { max_event_size, + trace_eth_packet, + checkpoint, log_output, rpc_call, rpc_returned, diff --git a/repos/libports/include/acpica/acpica.h b/repos/libports/include/acpica/acpica.h index 7033906291..34bd990bf3 100644 --- a/repos/libports/include/acpica/acpica.h +++ b/repos/libports/include/acpica/acpica.h @@ -21,11 +21,7 @@ namespace Genode { namespace Acpica { - struct Wait_acpi_ready { bool enabled; }; - struct Act_as_acpi_drv { bool enabled; }; - - void init(Genode::Env &, Genode::Allocator &, Wait_acpi_ready, - Act_as_acpi_drv); + void init(Genode::Env &, Genode::Allocator &); void use_platform_drv(); } diff --git a/repos/libports/include/libdrm/ioctl_dispatch.h b/repos/libports/include/libdrm/ioctl_dispatch.h new file mode 100644 index 0000000000..df238795da --- /dev/null +++ b/repos/libports/include/libdrm/ioctl_dispatch.h @@ -0,0 +1,24 @@ +/* + * \brief Libdrm ioctl back end dispatcher + * \author Josef Soentgen + * \date 2022-07-15 + */ + +/* + * Copyright (C) 2022 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 _INCLUDE__LIBDRM__IOCTL_DISPATCH_H_ +#define _INCLUDE__LIBDRM__IOCTL_DISPATCH_H_ + +namespace Libdrm { + enum Driver { INVALID, ETNAVIV, LIMA }; +}; /* namespace Libdrm */ + +void drm_init(Libdrm::Driver); + +#endif /* #ifndef _INCLUDE__LIBDRM__IOCTL_DISPATCH_H_ */ diff --git a/repos/libports/lib/import/import-libdrm.mk b/repos/libports/lib/import/import-libdrm.mk index 2e233fbbb4..e9761840d1 100644 --- a/repos/libports/lib/import/import-libdrm.mk +++ b/repos/libports/lib/import/import-libdrm.mk @@ -5,6 +5,7 @@ DRM_SRC_DIR = $(call select_from_ports,libdrm)/src/lib/libdrm endif INC_DIR += $(DRM_SRC_DIR) +INC_DIR += $(DRM_SRC_DIR)/include INC_DIR += $(addprefix $(DRM_SRC_DIR)/,include/etnaviv include/drm include) INC_DIR += $(addprefix $(DRM_SRC_DIR)/,etnaviv) INC_DIR += $(addprefix $(DRM_SRC_DIR)/,iris) diff --git a/repos/libports/lib/import/import-pcsc-lite.mk b/repos/libports/lib/import/import-pcsc-lite.mk index 63fadc8239..eeda106512 100644 --- a/repos/libports/lib/import/import-pcsc-lite.mk +++ b/repos/libports/lib/import/import-pcsc-lite.mk @@ -1 +1,5 @@ +ifeq ($(CONTRIB_DIR),) +REP_INC_DIR += include/PCSC +else INC_DIR += $(call select_from_ports,pcsc-lite)/include/PCSC +endif diff --git a/repos/libports/lib/import/import-qt5_cmake.mk b/repos/libports/lib/import/import-qt5_cmake.mk new file mode 100644 index 0000000000..8f727b7ff6 --- /dev/null +++ b/repos/libports/lib/import/import-qt5_cmake.mk @@ -0,0 +1,210 @@ +# +# The following externally defined variables are evaluated: +# +# CMAKE_LISTS_DIR: path to the CMakeLists.txt file +# CMAKE_TARGET_BINARIES binaries to be stripped and linked into 'bin' and 'debug' directories +# QT5_PORT_LIBS: Qt5 libraries used from port (for example libQt5Core) +# + +QT_TOOLS_DIR = /usr/local/genode/qt5/22.08 + +ifeq ($(filter-out $(SPECS),arm),) +QT_PLATFORM = genode-arm-g++ +else ifeq ($(filter-out $(SPECS),arm_64),) +QT_PLATFORM = genode-aarch64-g++ +else ifeq ($(filter-out $(SPECS),x86_32),) +QT_PLATFORM = genode-x86_32-g++ +else ifeq ($(filter-out $(SPECS),x86_64),) +QT_PLATFORM = genode-x86_64-g++ +else +$(error Error: unsupported platform) +endif + +ifeq ($(CONTRIB_DIR),) +QT_DIR = $(call select_from_repositories,src/lib/qt5) +QT_API_DIR = $(call select_from_repositories,mkspecs)/.. +else +QT_PORT_DIR = $(call select_from_ports,qt5) +QT_DIR = $(QT_PORT_DIR)/src/lib/qt5 +QT_API_DIR = $(QT_DIR)/genode/api +endif + +ifneq ($(VERBOSE),) +QT5_OUTPUT_FILTER = > /dev/null +endif + +# +# Genode libraries to be linked to Qt applications and libraries +# + +QT5_GENODE_LIBS_APP = libc.lib.so libm.lib.so stdcxx.lib.so qt5_component.lib.so +QT5_GENODE_LIBS_SHLIB = libc.lib.so libm.lib.so stdcxx.lib.so + +# +# flags to be passed to CMake +# + +GENODE_CMAKE_CFLAGS = \ + -D__FreeBSD__=12 \ + -D__GENODE__ \ + -ffunction-sections \ + -fno-strict-aliasing \ + $(CC_OPT_NOSTDINC) \ + $(CC_MARCH) \ + $(CC_OPT_PIC) \ + $(filter-out -I.,$(INCLUDES)) \ + -I$(CURDIR)/cmake_root/include/QtCore/spec/$(QT_PLATFORM) + +GENODE_CMAKE_LFLAGS_APP = \ + $(addprefix $(LD_OPT_PREFIX),$(LD_MARCH)) \ + $(addprefix $(LD_OPT_PREFIX),$(LD_OPT_GC_SECTIONS)) \ + $(addprefix $(LD_OPT_PREFIX),$(LD_OPT_ALIGN_SANE)) \ + $(addprefix $(LD_OPT_PREFIX),--dynamic-list=$(BASE_DIR)/src/ld/genode_dyn.dl) \ + $(LD_OPT_NOSTDLIB) \ + -Wl,-Ttext=0x01000000 \ + $(CC_MARCH) \ + -Wl,--dynamic-linker=$(DYNAMIC_LINKER).lib.so \ + -Wl,--eh-frame-hdr \ + -Wl,-rpath-link=. \ + -Wl,-T -Wl,$(LD_SCRIPT_DYN) \ + -L$(CURDIR)/cmake_root/lib \ + -Wl,--whole-archive \ + -Wl,--start-group \ + $(addprefix -l:,$(QT5_GENODE_LIBS_APP)) \ + $(shell $(CC) $(CC_MARCH) -print-libgcc-file-name) \ + -Wl,--end-group \ + -Wl,--no-whole-archive + +GENODE_CMAKE_LFLAGS_SHLIB = \ + $(LD_OPT_NOSTDLIB) \ + -Wl,-shared \ + -Wl,--eh-frame-hdr \ + $(addprefix $(LD_OPT_PREFIX),$(LD_MARCH)) \ + $(addprefix $(LD_OPT_PREFIX),$(LD_OPT_GC_SECTIONS)) \ + $(addprefix $(LD_OPT_PREFIX),$(LD_OPT_ALIGN_SANE)) \ + -Wl,-T -Wl,$(LD_SCRIPT_SO) \ + $(addprefix $(LD_OPT_PREFIX),--entry=0x0) \ + -L$(CURDIR)/cmake_root/lib \ + -Wl,--whole-archive \ + -Wl,--start-group \ + $(addprefix -l:,$(QT5_GENODE_LIBS_SHLIB)) \ + $(shell $(CC) $(CC_MARCH) -print-libgcc-file-name) \ + -l:ldso_so_support.lib.a \ + -Wl,--end-group \ + -Wl,--no-whole-archive + +ifeq ($(CONTRIB_DIR),) +GENODE_CMAKE_GL_INCDIRS = $(call select_from_repositories,include/GL)/.. +else +GENODE_CMAKE_GL_INCDIRS = $(call select_from_ports,mesa)/include +endif + +GENODE_CMAKE_OPENGL_LIBS = $(CURDIR)/cmake_root/lib/mesa.lib.so + +# +# prepare a directory named 'cmake_root' where CMake can find needed files +# + +cmake_root: + $(VERBOSE)mkdir -p $@ + +cmake_root/bin: cmake_root + $(VERBOSE)mkdir -p $@ + $(VERBOSE)ln -sf $(QT_TOOLS_DIR)/bin/* $@/ + +cmake_root/include: cmake_root + $(VERBOSE)mkdir -p $@ + $(VERBOSE)ln -snf $(QT_API_DIR)/include/* $@/ + +cmake_root/lib: cmake_root + $(VERBOSE)mkdir -p $@ + +cmake_root/lib/cmake: cmake_root/lib + $(VERBOSE)ln -snf $(QT_API_DIR)/lib/cmake $@ + +cmake_root/lib/%.lib.so: cmake_root/lib + $(VERBOSE)ln -sf $(BUILD_BASE_DIR)/var/libcache/$*/$*.abi.so $@ + +cmake_root/lib/%.lib.a: cmake_root/lib + $(VERBOSE)ln -sf $(BUILD_BASE_DIR)/var/libcache/$*/$*.lib.a $@ + +cmake_root/mkspecs: cmake_root + $(VERBOSE)ln -snf $(QT_API_DIR)/mkspecs $@ + +cmake_prepared.tag: \ + cmake_root/bin \ + cmake_root/include \ + cmake_root/lib/cmake \ + cmake_root/lib/libc.lib.so \ + cmake_root/lib/libm.lib.so \ + cmake_root/lib/egl.lib.so \ + cmake_root/lib/mesa.lib.so \ + cmake_root/lib/qt5_component.lib.so \ + cmake_root/lib/stdcxx.lib.so \ + cmake_root/lib/ldso_so_support.lib.a \ + cmake_root/mkspecs + +# add symlinks for Qt5 libraries listed in the 'QT5_PORT_LIBS' variable +ifeq ($(CONTRIB_DIR),) + $(VERBOSE)for qt5_lib in $(QT5_PORT_LIBS); do \ + ln -sf $(BUILD_BASE_DIR)/var/libcache/$${qt5_lib}/$${qt5_lib}.abi.so cmake_root/lib/$${qt5_lib}.lib.so; \ + done +else + $(VERBOSE)for qt5_lib in $(QT5_PORT_LIBS); do \ + ln -sf $(BUILD_BASE_DIR)/bin/$${qt5_lib}.lib.so cmake_root/lib/; \ + done +endif + $(VERBOSE)touch $@ + +.PHONY: build_with_cmake + +# 'make' called by CMake uses '/bin/sh', which does not understand '-o pipefail' +unexport .SHELLFLAGS + +ifeq ($(VERBOSE),) +CMAKE_MAKE_VERBOSE="1" +endif + +build_with_cmake: cmake_prepared.tag + $(VERBOSE)CMAKE_PREFIX_PATH="$(CURDIR)/cmake_root" \ + cmake \ + --no-warn-unused-cli \ + -DCMAKE_MODULE_PATH="$(CURDIR)/cmake_root/lib/cmake/Modules" \ + -DCMAKE_SYSTEM_NAME="Genode" \ + -DCMAKE_AR="$(AR)" \ + -DCMAKE_C_COMPILER="$(CC)" \ + -DCMAKE_C_FLAGS="$(GENODE_CMAKE_CFLAGS)" \ + -DCMAKE_CXX_COMPILER="$(CXX)" \ + -DCMAKE_CXX_STANDARD="17" \ + -DCMAKE_CXX_FLAGS="$(GENODE_CMAKE_CFLAGS)" \ + -DCMAKE_EXE_LINKER_FLAGS="$(GENODE_CMAKE_LFLAGS_APP)" \ + -DCMAKE_SHARED_LINKER_FLAGS="$(GENODE_CMAKE_LFLAGS_SHLIB)" \ + -DCMAKE_MODULE_LINKER_FLAGS="$(GENODE_CMAKE_LFLAGS_SHLIB)" \ + -DCMAKE_GL_INCDIRS="$(GENODE_CMAKE_GL_INCDIRS)" \ + -DCMAKE_OPENGL_LIBS="$(GENODE_CMAKE_OPENGL_LIBS)" \ + $(CMAKE_LISTS_DIR) \ + $(QT5_OUTPUT_FILTER) + + $(VERBOSE)$(MAKE) VERBOSE=$(CMAKE_MAKE_VERBOSE) $(QT5_OUTPUT_FILTER) + +# +# Not every CMake project has an 'install' target, so execute +# this target only if a binary to be installed has "install/" in +# its path. +# +ifneq ($(findstring install/,$(CMAKE_TARGET_BINARIES)),) + $(VERBOSE)$(MAKE) VERBOSE=$(CMAKE_MAKE_VERBOSE) DESTDIR=install install $(QT5_OUTPUT_FILTER) +endif + + $(VERBOSE)for cmake_target_binary in $(CMAKE_TARGET_BINARIES); do \ + $(STRIP) $${cmake_target_binary} -o $${cmake_target_binary}.stripped; \ + ln -sf $(CURDIR)/$${cmake_target_binary}.stripped $(PWD)/bin/`basename $${cmake_target_binary}`; \ + ln -sf $(CURDIR)/$${cmake_target_binary} $(PWD)/debug/; \ + done + +# +# build applications with CMake +# +TARGET ?= $(CMAKE_LISTS_DIR).cmake_target +.PHONY: $(TARGET) +$(TARGET): build_with_cmake diff --git a/repos/libports/lib/import/import-qt5_qmake.mk b/repos/libports/lib/import/import-qt5_qmake.mk index 349d5ced96..271cfcbd6c 100644 --- a/repos/libports/lib/import/import-qt5_qmake.mk +++ b/repos/libports/lib/import/import-qt5_qmake.mk @@ -6,7 +6,7 @@ # QT5_PORT_LIBS: Qt5 libraries used from port (for example libQt5Core) # -QT_TOOLS_DIR = /usr/local/genode/qt5/20.08 +QT_TOOLS_DIR = /usr/local/genode/qt5/22.08 QMAKE = $(QT_TOOLS_DIR)/bin/qmake ifeq ($(filter-out $(SPECS),arm),) @@ -161,6 +161,9 @@ qmake_root/lib/%.lib.a: qmake_root/lib qmake_root/mkspecs: qmake_root $(VERBOSE)mkdir -p $@ $(VERBOSE)ln -sf $(QT_API_DIR)/mkspecs/* $@/ + $(VERBOSE)rm -f $@/modules + $(VERBOSE)mkdir $@/modules + $(VERBOSE)ln -snf $(QT_API_DIR)/mkspecs/modules/* $@/modules/ $(VERBOSE)ln -sf $(QMAKE_PLATFORM)/qconfig.pri $@/ $(VERBOSE)ln -sf $(QMAKE_PLATFORM)/qmodule.pri $@/ diff --git a/repos/libports/lib/mk/e2fsprogs.mk b/repos/libports/lib/mk/e2fsprogs.mk index f2df773ac6..b6c31f96a7 100644 --- a/repos/libports/lib/mk/e2fsprogs.mk +++ b/repos/libports/lib/mk/e2fsprogs.mk @@ -12,33 +12,6 @@ CC_DEF += -DLOCALEDIR=\"/share/locale\" CC_DEF += -DLIBDIR=\"/lib\" CC_DEF += -DLOCALE_ALIAS_PATH=\"/share/locale\" -SRC_C_intl := \ - intl/bindtextdom.c \ - intl/dcgettext.c \ - intl/dgettext.c \ - intl/gettext.c \ - intl/finddomain.c \ - intl/loadmsgcat.c \ - intl/localealias.c \ - intl/textdomain.c \ - intl/l10nflist.c \ - intl/dcigettext.c \ - intl/explodename.c \ - intl/dcngettext.c \ - intl/dngettext.c \ - intl/ngettext.c \ - intl/plural.c \ - intl/plural-exp.c \ - intl/localcharset.c \ - intl/relocatable.c \ - intl/log.c \ - intl/localename.c \ - intl/printf.c \ - intl/osdep.c \ - intl/intl-compat.c -INC_DIR_intl := $(E2FSPROGS_DIR)/intl $(REP_DIR)/src/lib/e2fsprogs/intl -CC_OPT_intl/dcigettext += -DSTATIC= - SRC_C_libblkid := \ lib/blkid/cache.c \ lib/blkid/devname.c \ @@ -63,6 +36,7 @@ SRC_C_libcom_err := \ INC_DIR_libcom_err := $(E2FSPROGS_DIR)/lib/et SRC_C_libe2p := \ + lib/e2p/encoding.c \ lib/e2p/feature.c \ lib/e2p/fgetflags.c \ lib/e2p/fgetversion.c \ @@ -90,6 +64,7 @@ SRC_C_libext2fs := \ lib/ext2fs/alloc_sb.c \ lib/ext2fs/alloc_stats.c \ lib/ext2fs/alloc_tables.c \ + lib/ext2fs/atexit.c \ lib/ext2fs/badblocks.c \ lib/ext2fs/bb_compat.c \ lib/ext2fs/bb_inode.c \ @@ -115,21 +90,25 @@ SRC_C_libext2fs := \ lib/ext2fs/ext2_err.c \ lib/ext2fs/ext_attr.c \ lib/ext2fs/extent.c \ + lib/ext2fs/fallocate.c \ lib/ext2fs/fileio.c \ lib/ext2fs/finddev.c \ lib/ext2fs/flushb.c \ lib/ext2fs/freefs.c \ lib/ext2fs/gen_bitmap.c \ lib/ext2fs/gen_bitmap64.c \ + lib/ext2fs/get_num_dirs.c \ lib/ext2fs/get_pathname.c \ lib/ext2fs/getsectsize.c \ lib/ext2fs/getsize.c \ + lib/ext2fs/hashmap.c \ lib/ext2fs/i_block.c \ lib/ext2fs/icount.c \ lib/ext2fs/imager.c \ lib/ext2fs/ind_block.c \ lib/ext2fs/initialize.c \ lib/ext2fs/inline.c \ + lib/ext2fs/inline_data.c \ lib/ext2fs/inode.c \ lib/ext2fs/inode_io.c \ lib/ext2fs/io_manager.c \ @@ -143,6 +122,7 @@ SRC_C_libext2fs := \ lib/ext2fs/namei.c \ lib/ext2fs/native.c \ lib/ext2fs/newdir.c \ + lib/ext2fs/nls_utf8.c \ lib/ext2fs/openfs.c \ lib/ext2fs/progress.c \ lib/ext2fs/punch.c \ @@ -152,6 +132,8 @@ SRC_C_libext2fs := \ lib/ext2fs/read_bb_file.c \ lib/ext2fs/res_gdt.c \ lib/ext2fs/rw_bitmaps.c \ + lib/ext2fs/sha512.c \ + lib/ext2fs/sparse_io.c \ lib/ext2fs/swapfs.c \ lib/ext2fs/symlink.c \ lib/ext2fs/tdb.c \ @@ -164,13 +146,17 @@ SRC_C_libext2fs := \ lib/ext2fs/write_bb_file.c INC_DIR_libext2fs := $(E2FSPROGS_DIR)/lib/ext2fs $(REP_DIR)/src/lib/e2fsprogs/lib/ext2fs -SRC_C_libquota := \ - lib/quota/mkquota.c \ - lib/quota/quotaio.c \ - lib/quota/quotaio_v2.c \ - lib/quota/quotaio_tree.c \ - e2fsck/dict.c -INC_DIR_libquota := $(E2FSPROGS_DIR)/lib/quota +SRC_C_libsupport := \ + lib/support/dict.c \ + lib/support/mkquota.c \ + lib/support/plausible.c \ + lib/support/parse_qtype.c \ + lib/support/prof_err.c \ + lib/support/profile.c \ + lib/support/quotaio.c \ + lib/support/quotaio_tree.c \ + lib/support/quotaio_v2.c +INC_DIR_libsupport := $(E2FSPROGS_DIR)/lib/support SRC_C_libuuid := \ lib/uuid/clear.c \ @@ -186,23 +172,22 @@ SRC_C_libuuid := \ INC_DIR_libuuid := $(E2FSPROGS_DIR)/lib/uuid SRC_C := \ - $(SRC_C_intl) \ $(SRC_C_libblkid) \ $(SRC_C_libcom_err) \ $(SRC_C_libe2p) \ $(SRC_C_libext2fs) \ - $(SRC_C_libquota) \ - $(SRC_C_libuuid) + $(SRC_C_libsupport) \ + $(SRC_C_libuuid) \ + dummies.c INC_DIR += $(E2FSPROGS_DIR)/lib INC_DIR += $(REP_DIR)/src/lib/e2fsprogs INC_DIR += $(REP_DIR)/src/lib/e2fsprogs/lib -INC_DIR += $(INC_DIR_intl) INC_DIR += $(INC_DIR_libblkid) INC_DIR += $(INC_DIR_libcom_err) INC_DIR += $(INC_DIR_libe2p) INC_DIR += $(INC_DIR_libext2fs) -INC_DIR += $(INC_DIR_libquota) +INC_DIR += $(INC_DIR_libsupport) INC_DIR += $(INC_DIR_libuuid) @@ -210,6 +195,7 @@ CC_DEF += -D__BSD_VISIBLE CC_DEF += -DHAVE_CONFIG_H vpath %.c $(E2FSPROGS_DIR) +vpath %.c $(REP_DIR)/src/lib/e2fsprogs # # Generate header files diff --git a/repos/libports/lib/mk/e2fsprogs_host_tools.mk b/repos/libports/lib/mk/e2fsprogs_host_tools.mk index 730ab6e15e..ce28f8a0ba 100644 --- a/repos/libports/lib/mk/e2fsprogs_host_tools.mk +++ b/repos/libports/lib/mk/e2fsprogs_host_tools.mk @@ -3,9 +3,8 @@ # EXT2FS_GEN_CRC := $(BUILD_BASE_DIR)/tool/e2fsprogs/gen_crc32ctable -E2FSCK_GEN_CRC := $(BUILD_BASE_DIR)/tool/e2fsprogs/gen_crc32table -HOST_TOOLS += $(EXT2FS_GEN_CRC) $(E2FSCK_GEN_CRC) +HOST_TOOLS += $(EXT2FS_GEN_CRC) E2FSPROGS_DIR := $(call select_from_ports,e2fsprogs-lib)/src/lib/e2fsprogs @@ -14,9 +13,4 @@ $(EXT2FS_GEN_CRC): $(E2FSPROGS_DIR) $(VERBOSE)mkdir -p $(dir $@) $(VERBOSE)gcc $(E2FSPROGS_DIR)/lib/ext2fs/$(notdir $@).c -o $@ -$(E2FSCK_GEN_CRC): $(E2FSPROGS_DIR) - $(MSG_BUILD)$(notdir $@) - $(VERBOSE)mkdir -p $(dir $@) - $(VERBOSE)gcc $(E2FSPROGS_DIR)/e2fsck/$(notdir $@).c -o $@ - CC_CXX_WARN_STRICT = diff --git a/repos/libports/lib/mk/gmp.mk b/repos/libports/lib/mk/gmp.mk index 17482e83df..0be6470cd7 100644 --- a/repos/libports/lib/mk/gmp.mk +++ b/repos/libports/lib/mk/gmp.mk @@ -10,7 +10,7 @@ SRC_C += assert.c compat.c errno.c extract-dbl.c invalid.c \ mp_minv_tab.c mp_get_fns.c mp_set_fns.c rand.c randclr.c \ randdef.c randiset.c randlc2s.c randlc2x.c randmt.c \ randmts.c rands.c randsd.c randsdui.c randbui.c randmui.c \ - version.c tal-reent.c + version.c tal-reent.c nextprime.c # # Source codes from subdirectories diff --git a/repos/libports/lib/mk/libQt5QmlModels.mk b/repos/libports/lib/mk/libQt5QmlModels.mk new file mode 100644 index 0000000000..a1e8b27d37 --- /dev/null +++ b/repos/libports/lib/mk/libQt5QmlModels.mk @@ -0,0 +1,6 @@ +# +# This individual library description file is needed to get the abi +# library generated when building Qt5 packages. +# + +LIBS = qt5_declarative diff --git a/repos/libports/lib/mk/libQt5QmlWorkerScript.mk b/repos/libports/lib/mk/libQt5QmlWorkerScript.mk new file mode 100644 index 0000000000..a1e8b27d37 --- /dev/null +++ b/repos/libports/lib/mk/libQt5QmlWorkerScript.mk @@ -0,0 +1,6 @@ +# +# This individual library description file is needed to get the abi +# library generated when building Qt5 packages. +# + +LIBS = qt5_declarative diff --git a/repos/libports/lib/mk/libc-net.mk b/repos/libports/lib/mk/libc-net.mk index 3fb1e946fe..a3b7ed666f 100644 --- a/repos/libports/lib/mk/libc-net.mk +++ b/repos/libports/lib/mk/libc-net.mk @@ -15,6 +15,9 @@ SRC_C += gethostnamadr.c gethostbydns.c gethostbyht.c map_v4v6.c # needed for getprotobyname() SRC_C += getprotoent.c getprotoname.c +# needed by send() +SRC_C += sendmsg.c + # defines in6addr_any SRC_C += vars.c @@ -53,4 +56,7 @@ nsparser.c: nsparser.y vpath nsparser.y $(LIBC_NET_DIR) +vpath sendmsg.c $(REP_DIR)/src/lib/libc + CC_CXX_WARN_STRICT = + diff --git a/repos/libports/lib/mk/libdrm.inc b/repos/libports/lib/mk/libdrm.inc index c2b873a469..36e9a5b868 100644 --- a/repos/libports/lib/mk/libdrm.inc +++ b/repos/libports/lib/mk/libdrm.inc @@ -2,9 +2,11 @@ LIB_DIR := $(REP_DIR)/src/lib/libdrm # include before to shadow libdrm_macros.h INC_DIR += $(LIB_DIR)/include +INC_DIR += $(REP_DIR)/src/lib/libdrm LIBDRM_PORT_DIR := $(call select_from_ports,libdrm)/src/lib/libdrm +REP_INC_DIR += include/libdrm REP_INC_DIR += include/drm LIBS := libc diff --git a/repos/libports/lib/mk/mesa.inc b/repos/libports/lib/mk/mesa.inc index 86c4447a03..ba3271f4b8 100644 --- a/repos/libports/lib/mk/mesa.inc +++ b/repos/libports/lib/mk/mesa.inc @@ -232,6 +232,7 @@ SRC_C += compiler/glsl/glcpp/pp.c \ compiler/nir/nir_lower_drawpixels.c \ compiler/nir/nir_lower_flatshade.c \ compiler/nir/nir_lower_flrp.c \ + compiler/nir/nir_lower_fragcoord_wtrans.c \ compiler/nir/nir_lower_frexp.c \ compiler/nir/nir_lower_global_vars_to_local.c \ compiler/nir/nir_lower_goto_ifs.c \ @@ -253,6 +254,7 @@ SRC_C += compiler/glsl/glcpp/pp.c \ compiler/nir/nir_lower_patch_vertices.c \ compiler/nir/nir_lower_phis_to_scalar.c \ compiler/nir/nir_lower_pntc_ytransform.c \ + compiler/nir/nir_lower_point_size.c \ compiler/nir/nir_lower_point_size_mov.c \ compiler/nir/nir_lower_regs_to_ssa.c \ compiler/nir/nir_lower_returns.c \ @@ -268,6 +270,7 @@ SRC_C += compiler/glsl/glcpp/pp.c \ compiler/nir/nir_lower_variable_initializers.c \ compiler/nir/nir_lower_vars_to_ssa.c \ compiler/nir/nir_lower_vec_to_movs.c \ + compiler/nir/nir_lower_viewport_transform.c \ compiler/nir/nir_lower_wpos_ytransform.c \ compiler/nir/nir_metadata.c \ compiler/nir/nir_move_vec_src_uses_to_dest.c \ @@ -448,6 +451,7 @@ SRC_C += compiler/glsl/glcpp/pp.c \ gallium/auxiliary/util/u_sampler.c \ gallium/auxiliary/util/u_screen.c \ gallium/auxiliary/util/u_simple_shaders.c \ + gallium/auxiliary/util/u_split_draw.c \ gallium/auxiliary/util/u_surface.c \ gallium/auxiliary/util/u_tests.c \ gallium/auxiliary/util/u_texture.c \ diff --git a/repos/libports/lib/mk/qt5_base.mk b/repos/libports/lib/mk/qt5_base.mk index 081d119db8..098cc7a4e7 100644 --- a/repos/libports/lib/mk/qt5_base.mk +++ b/repos/libports/lib/mk/qt5_base.mk @@ -25,6 +25,7 @@ built.tag: qmake_prepared.tag qmake_root/lib/ld.lib.so -no-feature-dbus \ -no-feature-networkinterface \ -no-feature-process \ + -no-feature-relocatable \ -no-feature-vulkan \ $(QT5_OUTPUT_FILTER) diff --git a/repos/libports/lib/mk/qt5_declarative.mk b/repos/libports/lib/mk/qt5_declarative.mk index fbf8dd3aa1..ac2ecac6aa 100644 --- a/repos/libports/lib/mk/qt5_declarative.mk +++ b/repos/libports/lib/mk/qt5_declarative.mk @@ -4,6 +4,31 @@ QT5_PORT_LIBS = libQt5Core libQt5Gui libQt5Network libQt5Sql libQt5Test libQt5Wi LIBS = libc libm mesa stdcxx $(QT5_PORT_LIBS) +INSTALL_LIBS = lib/libQt5Qml.lib.so \ + lib/libQt5QmlModels.lib.so \ + lib/libQt5QmlWorkerScript.lib.so \ + lib/libQt5Quick.lib.so \ + lib/libQt5QuickParticles.lib.so \ + lib/libQt5QuickShapes.lib.so \ + lib/libQt5QuickTest.lib.so \ + lib/libQt5QuickWidgets.lib.so \ + qml/Qt/labs/animation/liblabsanimationplugin.lib.so \ + qml/Qt/labs/folderlistmodel/libqmlfolderlistmodelplugin.lib.so \ + qml/Qt/labs/qmlmodels/liblabsmodelsplugin.lib.so \ + qml/Qt/labs/settings/libqmlsettingsplugin.lib.so \ + qml/Qt/labs/wavefrontmesh/libqmlwavefrontmeshplugin.lib.so \ + qml/QtQml/Models.2/libmodelsplugin.lib.so \ + qml/QtQml/StateMachine/libqtqmlstatemachine.lib.so \ + qml/QtQml/WorkerScript.2/libworkerscriptplugin.lib.so \ + qml/QtQml/libqmlplugin.lib.so \ + qml/QtQuick.2/libqtquick2plugin.lib.so \ + qml/QtQuick/Layouts/libqquicklayoutsplugin.lib.so \ + qml/QtQuick/LocalStorage/libqmllocalstorageplugin.lib.so \ + qml/QtQuick/Particles.2/libparticlesplugin.lib.so \ + qml/QtQuick/Shapes/libqmlshapesplugin.lib.so \ + qml/QtQuick/Window.2/libwindowplugin.lib.so \ + qml/QtTest/libqmltestplugin.lib.so + built.tag: qmake_prepared.tag @# @@ -15,6 +40,7 @@ built.tag: qmake_prepared.tag $(QT_DIR)/qtdeclarative/qtdeclarative.pro \ -- \ -no-feature-qml-devtools \ + -no-feature-qml-jit \ $(QT5_OUTPUT_FILTER) @# @@ -32,51 +58,15 @@ built.tag: qmake_prepared.tag $(VERBOSE)ln -sf .$(CURDIR)/qmake_root install/qt @# - @# create stripped versions + @# strip libs and create symlinks in 'bin' and 'debug' directories @# - $(VERBOSE)cd $(CURDIR)/install/qt/lib && \ - $(STRIP) libQt5Qml.lib.so -o libQt5Qml.lib.so.stripped && \ - $(STRIP) libQt5Quick.lib.so -o libQt5Quick.lib.so.stripped && \ - $(STRIP) libQt5QuickWidgets.lib.so -o libQt5QuickWidgets.lib.so.stripped - - $(VERBOSE)cd $(CURDIR)/install/qt/qml/Qt/labs/folderlistmodel && \ - $(STRIP) libqmlfolderlistmodelplugin.lib.so -o libqmlfolderlistmodelplugin.lib.so.stripped - - $(VERBOSE)cd $(CURDIR)/install/qt/qml/QtQuick.2 && \ - $(STRIP) libqtquick2plugin.lib.so -o libqtquick2plugin.lib.so.stripped - - $(VERBOSE)cd $(CURDIR)/install/qt/qml/QtQuick/Layouts && \ - $(STRIP) libqquicklayoutsplugin.lib.so -o libqquicklayoutsplugin.lib.so.stripped - - $(VERBOSE)cd $(CURDIR)/install/qt/qml/QtQuick/Window.2 && \ - $(STRIP) libwindowplugin.lib.so -o libwindowplugin.lib.so.stripped - - @# - @# create symlinks in 'bin' directory - @# - - $(VERBOSE)ln -sf $(CURDIR)/install/qt/lib/libQt5Qml.lib.so.stripped $(PWD)/bin/libQt5Qml.lib.so - $(VERBOSE)ln -sf $(CURDIR)/install/qt/lib/libQt5Quick.lib.so.stripped $(PWD)/bin/libQt5Quick.lib.so - $(VERBOSE)ln -sf $(CURDIR)/install/qt/lib/libQt5QuickWidgets.lib.so.stripped $(PWD)/bin/libQt5QuickWidgets.lib.so - - $(VERBOSE)ln -sf $(CURDIR)/install/qt/qml/Qt/labs/folderlistmodel/libqmlfolderlistmodelplugin.lib.so.stripped $(PWD)/bin/libqmlfolderlistmodelplugin.lib.so - $(VERBOSE)ln -sf $(CURDIR)/install/qt/qml/QtQuick.2/libqtquick2plugin.lib.so.stripped $(PWD)/bin/libqtquick2plugin.lib.so - $(VERBOSE)ln -sf $(CURDIR)/install/qt/qml/QtQuick/Layouts/libqquicklayoutsplugin.lib.so.stripped $(PWD)/bin/libqquicklayoutsplugin.lib.so - $(VERBOSE)ln -sf $(CURDIR)/install/qt/qml/QtQuick/Window.2/libwindowplugin.lib.so.stripped $(PWD)/bin/libwindowplugin.lib.so - - @# - @# create symlinks in 'debug' directory - @# - - $(VERBOSE)ln -sf $(CURDIR)/install/qt/lib/libQt5Qml.lib.so $(PWD)/debug/ - $(VERBOSE)ln -sf $(CURDIR)/install/qt/lib/libQt5Quick.lib.so $(PWD)/debug/ - $(VERBOSE)ln -sf $(CURDIR)/install/qt/lib/libQt5QuickWidgets.lib.so $(PWD)/debug/ - - $(VERBOSE)ln -sf $(CURDIR)/install/qt/qml/Qt/labs/folderlistmodel/libqmlfolderlistmodelplugin.lib.so $(PWD)/debug/ - $(VERBOSE)ln -sf $(CURDIR)/install/qt/qml/QtQuick.2/libqtquick2plugin.lib.so $(PWD)/debug/ - $(VERBOSE)ln -sf $(CURDIR)/install/qt/qml/QtQuick/Layouts/libqquicklayoutsplugin.lib.so $(PWD)/debug/ - $(VERBOSE)ln -sf $(CURDIR)/install/qt/qml/QtQuick/Window.2/libwindowplugin.lib.so $(PWD)/debug/ + for LIB in $(INSTALL_LIBS); do \ + cd $(CURDIR)/install/qt/$$(dirname $${LIB}) && \ + $(STRIP) $$(basename $${LIB}) -o $$(basename $${LIB}).stripped; \ + ln -sf $(CURDIR)/install/qt/$${LIB}.stripped $(PWD)/bin/$$(basename $${LIB}); \ + ln -sf $(CURDIR)/install/qt/$${LIB} $(PWD)/debug/; \ + done @# @# create tar archives diff --git a/repos/libports/lib/mk/qt5_graphicaleffects.mk b/repos/libports/lib/mk/qt5_graphicaleffects.mk new file mode 100644 index 0000000000..412633b2f1 --- /dev/null +++ b/repos/libports/lib/mk/qt5_graphicaleffects.mk @@ -0,0 +1,62 @@ +include $(call select_from_repositories,lib/import/import-qt5_qmake.mk) + +QT5_PORT_LIBS += libQt5Core libQt5Gui libQt5Network +QT5_PORT_LIBS += libQt5Qml libQt5QmlModels libQt5Quick + +LIBS = libc libm mesa stdcxx $(QT5_PORT_LIBS) + +INSTALL_LIBS = qml/QtGraphicalEffects/libqtgraphicaleffectsplugin.lib.so \ + qml/QtGraphicalEffects/private/libqtgraphicaleffectsprivate.lib.so + +built.tag: qmake_prepared.tag + + @# + @# run qmake + @# + + $(VERBOSE)source env.sh && $(QMAKE) \ + -qtconf qmake_root/mkspecs/$(QMAKE_PLATFORM)/qt.conf \ + $(QT_DIR)/qtgraphicaleffects/qtgraphicaleffects.pro \ + $(QT5_OUTPUT_FILTER) + + @# + @# build + @# + + $(VERBOSE)source env.sh && $(MAKE) sub-src $(QT5_OUTPUT_FILTER) + + @# + @# install into local 'install' directory + @# + + $(VERBOSE)$(MAKE) INSTALL_ROOT=$(CURDIR)/install sub-src-install_subtargets $(QT5_OUTPUT_FILTER) + + $(VERBOSE)ln -sf .$(CURDIR)/qmake_root install/qt + + @# + @# strip libs and create symlinks in 'bin' and 'debug' directories + @# + + for LIB in $(INSTALL_LIBS); do \ + cd $(CURDIR)/install/qt/$$(dirname $${LIB}) && \ + $(STRIP) $$(basename $${LIB}) -o $$(basename $${LIB}).stripped; \ + ln -sf $(CURDIR)/install/qt/$${LIB}.stripped $(PWD)/bin/$$(basename $${LIB}); \ + ln -sf $(CURDIR)/install/qt/$${LIB} $(PWD)/debug/; \ + done + + @# + @# create tar archives + @# + + $(VERBOSE)tar chf $(PWD)/bin/qt5_graphicaleffects_qml.tar --exclude='*.lib.so' --transform='s/\.stripped//' -C install qt/qml + + @# + @# mark as done + @# + + $(VERBOSE)touch $@ + + +ifeq ($(called_from_lib_mk),yes) +all: built.tag +endif diff --git a/repos/libports/lib/mk/qt5_quickcontrols.mk b/repos/libports/lib/mk/qt5_quickcontrols.mk index 1c40f2b0fa..c980e41a44 100644 --- a/repos/libports/lib/mk/qt5_quickcontrols.mk +++ b/repos/libports/lib/mk/qt5_quickcontrols.mk @@ -1,7 +1,7 @@ include $(call select_from_repositories,lib/import/import-qt5_qmake.mk) QT5_PORT_LIBS += libQt5Core libQt5Gui libQt5Network libQt5Widgets -QT5_PORT_LIBS += libQt5Qml libQt5Quick +QT5_PORT_LIBS += libQt5Qml libQt5QmlModels libQt5Quick LIBS = libc libm mesa stdcxx $(QT5_PORT_LIBS) diff --git a/repos/libports/lib/mk/qt5_quickcontrols2.mk b/repos/libports/lib/mk/qt5_quickcontrols2.mk index a774fef751..c7937b01fe 100644 --- a/repos/libports/lib/mk/qt5_quickcontrols2.mk +++ b/repos/libports/lib/mk/qt5_quickcontrols2.mk @@ -1,7 +1,7 @@ include $(call select_from_repositories,lib/import/import-qt5_qmake.mk) QT5_PORT_LIBS += libQt5Core libQt5Gui libQt5Network libQt5Widgets -QT5_PORT_LIBS += libQt5Qml libQt5Quick +QT5_PORT_LIBS += libQt5Qml libQt5QmlModels libQt5Quick LIBS = libc libm mesa stdcxx $(QT5_PORT_LIBS) diff --git a/repos/libports/lib/mk/qt5_virtualkeyboard.mk b/repos/libports/lib/mk/qt5_virtualkeyboard.mk index d9f96df908..2a57a037ae 100644 --- a/repos/libports/lib/mk/qt5_virtualkeyboard.mk +++ b/repos/libports/lib/mk/qt5_virtualkeyboard.mk @@ -1,7 +1,7 @@ include $(call select_from_repositories,lib/import/import-qt5_qmake.mk) QT5_PORT_LIBS = libQt5Core libQt5Gui libQt5Network libQt5Widgets -QT5_PORT_LIBS += libQt5Qml libQt5Quick +QT5_PORT_LIBS += libQt5Qml libQt5QmlModels libQt5Quick QT5_PORT_LIBS += libQt5Svg LIBS = libc libm mesa stdcxx $(QT5_PORT_LIBS) diff --git a/repos/libports/lib/mk/etnaviv.mk b/repos/libports/lib/mk/spec/arm_v8/etnaviv.mk similarity index 100% rename from repos/libports/lib/mk/etnaviv.mk rename to repos/libports/lib/mk/spec/arm_v8/etnaviv.mk diff --git a/repos/libports/lib/mk/spec/arm_v8/libdrm.mk b/repos/libports/lib/mk/spec/arm_v8/libdrm.mk index 0278876f51..36683650b4 100644 --- a/repos/libports/lib/mk/spec/arm_v8/libdrm.mk +++ b/repos/libports/lib/mk/spec/arm_v8/libdrm.mk @@ -1,5 +1,8 @@ include $(REP_DIR)/lib/mk/libdrm.inc -include $(call select_from_repositories,lib/import/import-libdrm.mk) +LIBS += vfs_gpu -SRC_CC := ioctl_etnaviv.cc +include $(call select_from_repositories,lib/import/import-libdrm.mk) +include $(call select_from_repositories,lib/import/import-mesa_api.mk) + +SRC_CC := ioctl_dispatch.cc ioctl_etnaviv.cc ioctl_lima.cc diff --git a/repos/libports/lib/mk/spec/arm_v8/lima.mk b/repos/libports/lib/mk/spec/arm_v8/lima.mk new file mode 100644 index 0000000000..21493852b6 --- /dev/null +++ b/repos/libports/lib/mk/spec/arm_v8/lima.mk @@ -0,0 +1,64 @@ +LIBS = libc libdrm + +include $(REP_DIR)/lib/mk/mesa-common.inc + +INC_DIR += $(MESA_SRC_DIR)/src/compiler/nir \ + $(MESA_SRC_DIR)/src/gallium/auxiliary \ + $(MESA_SRC_DIR)/src/gallium/drivers \ + $(MESA_SRC_DIR)/src/gallium/drivers/lima \ + $(MESA_SRC_DIR)/src/panfrost/shared \ + $(MESA_SRC_DIR)/src/util \ + $(MESA_GEN_DIR)/src/compiler/nir \ + $(MESA_PORT_DIR)/include/drm-uapi + +REP_INC_DIR += include/drm-uapi + +SRC_C := \ + gallium/drivers/lima/lima_draw.c \ + gallium/drivers/lima/lima_job.c \ + gallium/drivers/lima/lima_context.c \ + gallium/drivers/lima/ir/pp/node_to_instr.c \ + gallium/drivers/lima/ir/pp/liveness.c \ + gallium/drivers/lima/ir/pp/codegen.c \ + gallium/drivers/lima/ir/pp/nir.c \ + gallium/drivers/lima/ir/pp/disasm.c \ + gallium/drivers/lima/ir/pp/regalloc.c \ + gallium/drivers/lima/ir/pp/node.c \ + gallium/drivers/lima/ir/pp/instr.c \ + gallium/drivers/lima/ir/pp/lower.c \ + gallium/drivers/lima/ir/pp/scheduler.c \ + gallium/drivers/lima/ir/gp/codegen.c \ + gallium/drivers/lima/ir/gp/nir.c \ + gallium/drivers/lima/ir/gp/disasm.c \ + gallium/drivers/lima/ir/gp/regalloc.c \ + gallium/drivers/lima/ir/gp/optimize.c \ + gallium/drivers/lima/ir/gp/node.c \ + gallium/drivers/lima/ir/gp/reduce_scheduler.c \ + gallium/drivers/lima/ir/gp/instr.c \ + gallium/drivers/lima/ir/gp/lower.c \ + gallium/drivers/lima/ir/gp/scheduler.c \ + gallium/drivers/lima/ir/lima_nir_split_load_input.c \ + gallium/drivers/lima/ir/lima_nir_duplicate_consts.c \ + gallium/drivers/lima/ir/lima_nir_duplicate_intrinsic.c \ + gallium/drivers/lima/ir/lima_nir_lower_uniform_to_scalar.c \ + gallium/drivers/lima/lima_bo.c \ + gallium/drivers/lima/lima_context.c \ + gallium/drivers/lima/lima_draw.c \ + gallium/drivers/lima/lima_fence.c \ + gallium/drivers/lima/lima_format.c \ + gallium/drivers/lima/lima_job.c \ + gallium/drivers/lima/lima_parser.c \ + gallium/drivers/lima/lima_program.c \ + gallium/drivers/lima/lima_query.c \ + gallium/drivers/lima/lima_resource.c \ + gallium/drivers/lima/lima_screen.c \ + gallium/drivers/lima/lima_state.c \ + gallium/drivers/lima/lima_texture.c \ + gallium/drivers/lima/lima_util.c \ + gallium/drivers/lima/lima_nir_algebraic.c \ + gallium/winsys/lima/drm/lima_drm_winsys.c \ + panfrost/shared/pan_minmax_cache.c \ + panfrost/shared/pan_tiling.c + +vpath %.c $(MESA_SRC_DIR)/src +vpath %.c $(MESA_SRC_DIR)/../../../generated/src diff --git a/repos/libports/lib/mk/spec/arm_v8/mesa.mk b/repos/libports/lib/mk/spec/arm_v8/mesa.mk index f8874ce1cf..ff57794caf 100644 --- a/repos/libports/lib/mk/spec/arm_v8/mesa.mk +++ b/repos/libports/lib/mk/spec/arm_v8/mesa.mk @@ -1,10 +1,13 @@ SHARED_LIB := yes LIBS += libdrm -LIBS += etnaviv +CC_OPT += -DHAVE_UINT128 -CC_OPT += -DGALLIUM_ETNAVIV \ - -DHAVE_UINT128 +LIBS += etnaviv +CC_OPT += -DGALLIUM_ETNAVIV + +LIBS += lima +CC_OPT += -DGALLIUM_LIMA include $(REP_DIR)/lib/mk/mesa.inc diff --git a/repos/libports/lib/mk/mesa_gpu-etnaviv.mk b/repos/libports/lib/mk/spec/arm_v8/mesa_gpu-etnaviv.mk similarity index 100% rename from repos/libports/lib/mk/mesa_gpu-etnaviv.mk rename to repos/libports/lib/mk/spec/arm_v8/mesa_gpu-etnaviv.mk diff --git a/repos/libports/lib/mk/spec/arm_v8/mesa_gpu-lima.mk b/repos/libports/lib/mk/spec/arm_v8/mesa_gpu-lima.mk new file mode 100644 index 0000000000..d88c593519 --- /dev/null +++ b/repos/libports/lib/mk/spec/arm_v8/mesa_gpu-lima.mk @@ -0,0 +1,19 @@ +SHARED_LIB := yes +LIBS := libc egl + +include $(REP_DIR)/lib/mk/mesa-common.inc + +SRC_CC := drm_init.cc +SRC_C := platform_lima.c + +CC_OPT += -DHAVE_GENODE_PLATFORM + +INC_DIR += $(MESA_SRC_DIR)/src/egl/drivers/dri2 \ + $(MESA_SRC_DIR)/src/egl/main \ + $(MESA_SRC_DIR)/src/mapi \ + $(MESA_SRC_DIR)/src/mesa + +vpath %.c $(LIB_DIR)/lima +vpath %.cc $(LIB_DIR)/lima + +CC_CXX_WARN_STRICT := diff --git a/repos/libports/lib/mk/spec/x86_64/gmp-mpn.mk b/repos/libports/lib/mk/spec/x86_64/gmp-mpn.mk index 27c516fd9e..6ed596b5b6 100644 --- a/repos/libports/lib/mk/spec/x86_64/gmp-mpn.mk +++ b/repos/libports/lib/mk/spec/x86_64/gmp-mpn.mk @@ -4,8 +4,7 @@ GMP_MPN_DIR = $(GMP_DIR)/mpn # this file uses the 'sdiv_qrnnd' symbol which is not defined FILTER_OUT += udiv_w_sdiv.c -FILTER_OUT += pre_divrem_1.c sec_div.c sec_pi1_div.c copyi.c copyd.c - +FILTER_OUT += pre_divrem_1.c sec_pi1_div.c copyi.c copyd.c # add x86_64-specific assembly files and filter out the generic C files if needed @@ -13,6 +12,8 @@ SRC_ASM += copyd.asm copyi.asm invert_limb.asm invert_limb_table.asm CC_OPT_add_n = -DOPERATION_add_n CC_OPT_sub_n = -DOPERATION_sub_n +CC_OPT_sec_aors_1 = -DOPERATION_sec_add_1 +CC_OPT_sec_div = -DOPERATION_sec_div_r FILTER_OUT += popham.c @@ -23,7 +24,7 @@ include $(REP_DIR)/lib/mk/gmp.inc PWD := $(shell pwd) -SRC_O += $(SRC_ASM:.asm=.o) hamdist.o popcount.o +SRC_O += $(SRC_ASM:.asm=.o) hamdist.o popcount.o sqr_diag_addlsh1.o # # Create execution environment for the m4-ccas tool, which is used by the gmp diff --git a/repos/libports/lib/mk/vfs_libusb.mk b/repos/libports/lib/mk/vfs_libusb.mk index 6d7d7e734d..1a794b2444 100644 --- a/repos/libports/lib/mk/vfs_libusb.mk +++ b/repos/libports/lib/mk/vfs_libusb.mk @@ -1,5 +1,7 @@ SRC_CC = vfs_libusb.cc +LIBS += libusb + vpath %.cc $(REP_DIR)/src/lib/vfs/libusb SHARED_LIB = yes diff --git a/repos/libports/lib/symbols/gmp b/repos/libports/lib/symbols/gmp index dc22e3b24a..08503e3a36 100644 --- a/repos/libports/lib/symbols/gmp +++ b/repos/libports/lib/symbols/gmp @@ -13,7 +13,7 @@ __gmp_default_allocate T __gmp_default_fp_limb_precision D 8 __gmp_default_free T __gmp_default_reallocate T -__gmp_digit_value_tab R 480 +__gmp_digit_value_tab R 464 __gmp_divide_by_zero T __gmp_doprnt T __gmp_doprnt_integer T @@ -22,6 +22,7 @@ __gmp_doscan T __gmp_errno B 4 __gmp_exception T __gmp_extract_double T +__gmp_fac2cnt_table R 40 __gmp_fib_table R 760 __gmp_fprintf T __gmp_fprintf_funs D 32 @@ -29,9 +30,15 @@ __gmp_free_func D 8 __gmp_fscanf T __gmp_fscanf_funs D 32 __gmp_get_memory_functions T +__gmp_init_primesieve T __gmp_invalid_operation T +__gmp_jacobi_table R 208 __gmp_junk B 4 +__gmp_limbroots_table R 64 __gmp_mt_recalc_buffer T +__gmp_nextprime T +__gmp_odd2fac_table R 136 +__gmp_oddfac_table R 544 __gmp_printf T __gmp_randclear T __gmp_randclear_mt T @@ -76,10 +83,12 @@ __gmpf_add T __gmpf_add_ui T __gmpf_ceil T __gmpf_clear T +__gmpf_clears T __gmpf_cmp T __gmpf_cmp_d T __gmpf_cmp_si T __gmpf_cmp_ui T +__gmpf_cmp_z T __gmpf_div T __gmpf_div_2exp T __gmpf_div_ui T @@ -106,6 +115,7 @@ __gmpf_init_set_d T __gmpf_init_set_si T __gmpf_init_set_str T __gmpf_init_set_ui T +__gmpf_inits T __gmpf_inp_str T __gmpf_integer_p T __gmpf_mul T @@ -138,37 +148,57 @@ __gmpf_ui_sub T __gmpf_urandomb T __gmpn_add T __gmpn_add_1 T +__gmpn_add_err1_n T +__gmpn_add_err2_n T +__gmpn_add_err3_n T __gmpn_add_n T +__gmpn_add_n_sub_n T __gmpn_addmul_1 T -__gmpn_addmul_2 T -__gmpn_addsub_n T __gmpn_bases R 10280 +__gmpn_bc_mulmod_bnm1 T __gmpn_bc_set_str T __gmpn_bdiv_dbm1c T -__gmpn_bdivmod T +__gmpn_bdiv_q T +__gmpn_bdiv_q_1 T +__gmpn_bdiv_q_itch T +__gmpn_bdiv_qr T +__gmpn_bdiv_qr_itch T __gmpn_binvert T __gmpn_binvert_itch T +__gmpn_broot T +__gmpn_broot_invm1 T +__gmpn_brootinv T +__gmpn_bsqrt T +__gmpn_bsqrtinv T __gmpn_cmp T +__gmpn_cnd_add_n T +__gmpn_cnd_sub_n T +__gmpn_cnd_swap T +__gmpn_com T __gmpn_copyd T __gmpn_copyi T -__gmpn_dc_bdiv_q T -__gmpn_dc_bdiv_q_n T -__gmpn_dc_bdiv_q_n_itch T -__gmpn_dc_bdiv_qr T -__gmpn_dc_bdiv_qr_n T -__gmpn_dc_bdiv_qr_n_itch T -__gmpn_dc_div_q T -__gmpn_dc_div_qr T -__gmpn_dc_div_qr_n T -__gmpn_dc_divappr_q T -__gmpn_dc_divappr_q_n T -__gmpn_dc_divrem_n T __gmpn_dc_set_str T +__gmpn_dcpi1_bdiv_q T +__gmpn_dcpi1_bdiv_q_n T +__gmpn_dcpi1_bdiv_q_n_itch T +__gmpn_dcpi1_bdiv_qr T +__gmpn_dcpi1_bdiv_qr_n T +__gmpn_dcpi1_bdiv_qr_n_itch T +__gmpn_dcpi1_div_q T +__gmpn_dcpi1_div_qr T +__gmpn_dcpi1_div_qr_n T +__gmpn_dcpi1_divappr_q T +__gmpn_dcpi1_divappr_q_n T +__gmpn_div_q T +__gmpn_div_qr_1 T +__gmpn_div_qr_1n_pi1 T +__gmpn_div_qr_2 T +__gmpn_div_qr_2n_pi1 T +__gmpn_div_qr_2u_pi1 T __gmpn_divexact T __gmpn_divexact_1 T __gmpn_divexact_by3 T __gmpn_divexact_by3c T -__gmpn_divexact_itch T __gmpn_divisible_p T __gmpn_divmod_1 T __gmpn_divrem T @@ -180,36 +210,45 @@ __gmpn_fft_next_size T __gmpn_fib2_ui T __gmpn_gcd T __gmpn_gcd_1 T -__gmpn_gcd_lehmer_n T __gmpn_gcd_subdiv_step T __gmpn_gcdext T __gmpn_gcdext_1 T +__gmpn_gcdext_hook T __gmpn_gcdext_lehmer_n T -__gmpn_gcdext_subdiv_step T __gmpn_get_d T __gmpn_get_str T __gmpn_hamdist T __gmpn_hgcd T __gmpn_hgcd2 T +__gmpn_hgcd2_jacobi T +__gmpn_hgcd_appr T +__gmpn_hgcd_appr_itch T __gmpn_hgcd_itch T -__gmpn_hgcd_lehmer T +__gmpn_hgcd_jacobi T __gmpn_hgcd_matrix_adjust T __gmpn_hgcd_matrix_init T __gmpn_hgcd_matrix_mul T -__gmpn_hgcd_mul_matrix1_inverse_vector T +__gmpn_hgcd_matrix_mul_1 T +__gmpn_hgcd_matrix_update_q T __gmpn_hgcd_mul_matrix1_vector T +__gmpn_hgcd_reduce T +__gmpn_hgcd_reduce_itch T +__gmpn_hgcd_step T __gmpn_invert T -__gmpn_invert_itch T +__gmpn_invert_limb T +__gmpn_invertappr T +__gmpn_jacobi_2 T __gmpn_jacobi_base T -__gmpn_kara_mul_n T -__gmpn_kara_sqr_n T +__gmpn_jacobi_n T __gmpn_lshift T +__gmpn_lshiftc T __gmpn_matrix22_mul T +__gmpn_matrix22_mul1_inverse_vector T __gmpn_matrix22_mul_itch T __gmpn_matrix22_mul_strassen T __gmpn_mod_1 T -__gmpn_mod_1s_1p T -__gmpn_mod_1s_1p_cps T +__gmpn_mod_1_1p T +__gmpn_mod_1_1p_cps T __gmpn_mod_1s_2p T __gmpn_mod_1s_2p_cps T __gmpn_mod_1s_3p T @@ -222,7 +261,9 @@ __gmpn_modexact_1c_odd T __gmpn_mu_bdiv_q T __gmpn_mu_bdiv_q_itch T __gmpn_mu_bdiv_qr T +__gmpn_mu_bdiv_qr_itch T __gmpn_mu_div_q T +__gmpn_mu_div_q_itch T __gmpn_mu_div_qr T __gmpn_mu_div_qr_choose_in T __gmpn_mu_div_qr_itch T @@ -234,70 +275,120 @@ __gmpn_mul_1 T __gmpn_mul_1c T __gmpn_mul_basecase T __gmpn_mul_fft T -__gmpn_mul_fft_full T __gmpn_mul_n T -__gmpn_mullow_basecase T -__gmpn_mullow_n T -__gmpn_neg_n T +__gmpn_mullo_basecase T +__gmpn_mullo_n T +__gmpn_mulmid T +__gmpn_mulmid_basecase T +__gmpn_mulmid_n T +__gmpn_mulmod_bnm1 T +__gmpn_mulmod_bnm1_next_size T +__gmpn_neg T +__gmpn_ni_invertappr T +__gmpn_nussbaumer_mul T +__gmpn_perfect_power_p T __gmpn_perfect_square_p T +__gmpn_pi1_bdiv_q_1 T __gmpn_popcount T __gmpn_pow_1 T __gmpn_powlo T __gmpn_powm T -__gmpn_powm_sec T -__gmpn_preinv_dc_div_qr T -__gmpn_preinv_dc_divappr_q T __gmpn_preinv_divrem_1 T __gmpn_preinv_mod_1 T __gmpn_preinv_mu_div_qr T +__gmpn_preinv_mu_div_qr_itch T __gmpn_preinv_mu_divappr_q T __gmpn_random T __gmpn_random2 T __gmpn_redc_1 T __gmpn_redc_2 T +__gmpn_redc_n T +__gmpn_remove T __gmpn_rootrem T __gmpn_rshift T -__gmpn_sb_bdiv_q T -__gmpn_sb_bdiv_qr T -__gmpn_sb_div_q T -__gmpn_sb_div_qr T -__gmpn_sb_divappr_q T -__gmpn_sb_divrem_mn T +__gmpn_sbpi1_bdiv_q T +__gmpn_sbpi1_bdiv_qr T +__gmpn_sbpi1_div_q T +__gmpn_sbpi1_div_qr T +__gmpn_sbpi1_divappr_q T __gmpn_scan0 T __gmpn_scan1 T +__gmpn_sec_add_1 T +__gmpn_sec_add_1_itch T +__gmpn_sec_div_r T +__gmpn_sec_div_r_itch T +__gmpn_sec_invert T +__gmpn_sec_invert_itch T +__gmpn_sec_mul T +__gmpn_sec_mul_itch T +__gmpn_sec_powm T +__gmpn_sec_powm_itch T +__gmpn_sec_sqr T +__gmpn_sec_sqr_itch T +__gmpn_sec_tabselect T __gmpn_set_str T __gmpn_set_str_compute_powtab T +__gmpn_sizeinbase T __gmpn_sqr T __gmpn_sqr_basecase T +__gmpn_sqr_diag_addlsh1 T +__gmpn_sqrlo T +__gmpn_sqrlo_basecase T +__gmpn_sqrmod_bnm1 T +__gmpn_sqrmod_bnm1_next_size T __gmpn_sqrtrem T __gmpn_sub T __gmpn_sub_1 T +__gmpn_sub_err1_n T +__gmpn_sub_err2_n T +__gmpn_sub_err3_n T __gmpn_sub_n T -__gmpn_subcnd_n T __gmpn_submul_1 T -__gmpn_tabselect T __gmpn_tdiv_qr T __gmpn_toom22_mul T __gmpn_toom2_sqr T __gmpn_toom32_mul T __gmpn_toom33_mul T -__gmpn_toom3_mul_n T __gmpn_toom3_sqr T -__gmpn_toom3_sqr_n T __gmpn_toom42_mul T +__gmpn_toom42_mulmid T +__gmpn_toom43_mul T __gmpn_toom44_mul T __gmpn_toom4_sqr T +__gmpn_toom52_mul T __gmpn_toom53_mul T +__gmpn_toom54_mul T __gmpn_toom62_mul T +__gmpn_toom63_mul T +__gmpn_toom6_sqr T +__gmpn_toom6h_mul T +__gmpn_toom8_sqr T +__gmpn_toom8h_mul T +__gmpn_toom_couple_handling T +__gmpn_toom_eval_dgr3_pm1 T +__gmpn_toom_eval_dgr3_pm2 T +__gmpn_toom_eval_pm1 T +__gmpn_toom_eval_pm2 T +__gmpn_toom_eval_pm2exp T +__gmpn_toom_eval_pm2rexp T +__gmpn_toom_interpolate_12pts T +__gmpn_toom_interpolate_16pts T __gmpn_toom_interpolate_5pts T +__gmpn_toom_interpolate_6pts T __gmpn_toom_interpolate_7pts T +__gmpn_toom_interpolate_8pts T +__gmpn_trialdiv T +__gmpn_zero T +__gmpn_zero_p T __gmpq_abs T __gmpq_add T __gmpq_canonicalize T __gmpq_clear T +__gmpq_clears T __gmpq_cmp T __gmpq_cmp_si T __gmpq_cmp_ui T +__gmpq_cmp_z T __gmpq_div T __gmpq_div_2exp T __gmpq_equal T @@ -306,6 +397,7 @@ __gmpq_get_den T __gmpq_get_num T __gmpq_get_str T __gmpq_init T +__gmpq_inits T __gmpq_inp_str T __gmpq_inv T __gmpq_mul T @@ -323,6 +415,7 @@ __gmpq_set_ui T __gmpq_set_z T __gmpq_sub T __gmpq_swap T +__gmpz_2fac_ui T __gmpz_abs T __gmpz_add T __gmpz_add_ui T @@ -343,6 +436,7 @@ __gmpz_cdiv_r_2exp T __gmpz_cdiv_r_ui T __gmpz_cdiv_ui T __gmpz_clear T +__gmpz_clears T __gmpz_clrbit T __gmpz_cmp T __gmpz_cmp_d T @@ -400,6 +494,7 @@ __gmpz_init_set_d T __gmpz_init_set_si T __gmpz_init_set_str T __gmpz_init_set_ui T +__gmpz_inits T __gmpz_inp_raw T __gmpz_inp_str T __gmpz_inp_str_nowhite T @@ -411,8 +506,13 @@ __gmpz_kronecker_ui T __gmpz_lcm T __gmpz_lcm_ui T __gmpz_legendre T +__gmpz_limbs_finish T +__gmpz_limbs_modify T +__gmpz_limbs_read T +__gmpz_limbs_write T __gmpz_lucnum2_ui T __gmpz_lucnum_ui T +__gmpz_mfac_uiui T __gmpz_millerrabin T __gmpz_mod T __gmpz_mul T @@ -422,6 +522,7 @@ __gmpz_mul_ui T __gmpz_n_pow_ui T __gmpz_neg T __gmpz_nextprime T +__gmpz_oddfac_1 T __gmpz_out_raw T __gmpz_out_str T __gmpz_perfect_power_p T @@ -429,13 +530,17 @@ __gmpz_perfect_square_p T __gmpz_popcount T __gmpz_pow_ui T __gmpz_powm T +__gmpz_powm_sec T __gmpz_powm_ui T +__gmpz_primorial_ui T __gmpz_probab_prime_p T +__gmpz_prodlimbs T __gmpz_random T __gmpz_random2 T __gmpz_realloc T __gmpz_realloc2 T __gmpz_remove T +__gmpz_roinit_n T __gmpz_root T __gmpz_rootrem T __gmpz_rrandomb T @@ -475,3 +580,7 @@ __gmpz_ui_sub T __gmpz_urandomb T __gmpz_urandomm T __gmpz_xor T +__gnu_Unwind_Find_exidx T +dl_unwind_find_exidx W +mpn_div_qr_1n_pi2 T +mpn_div_qr_1u_pi2 T diff --git a/repos/libports/lib/symbols/libc b/repos/libports/lib/symbols/libc index 39bfa2f733..e3de45d2d5 100644 --- a/repos/libports/lib/symbols/libc +++ b/repos/libports/lib/symbols/libc @@ -1294,6 +1294,7 @@ __cxa_guard_release T __cxa_init_primary_exception T __cxa_pure_virtual T __cxa_rethrow T +__cxa_thread_atexit T __cxa_throw T __cxa_throw_bad_array_length T __cxa_throw_bad_array_new_length T diff --git a/repos/libports/ports/e2fsprogs-lib.hash b/repos/libports/ports/e2fsprogs-lib.hash index 15b9d161f0..e60d7a5de5 100644 --- a/repos/libports/ports/e2fsprogs-lib.hash +++ b/repos/libports/ports/e2fsprogs-lib.hash @@ -1 +1 @@ -66fa19adc056fa1e55e3585ae5962c2f7d20dbe4 +d41e0f3b2517a1625a84c394c468530676d0551a diff --git a/repos/libports/ports/e2fsprogs-lib.port b/repos/libports/ports/e2fsprogs-lib.port index 99c0335842..4ded92b95e 100644 --- a/repos/libports/ports/e2fsprogs-lib.port +++ b/repos/libports/ports/e2fsprogs-lib.port @@ -1,5 +1,5 @@ LICENSE := GPLv2 -VERSION := 1.42.9 +VERSION := 1.46.5 DOWNLOADS := e2fsprogs.git E2FSPROGS_DIR := src/lib/e2fsprogs @@ -24,26 +24,15 @@ DIR_CONTENT($(INCLUDE_DIR)) := \ BLKID_HEADER := $(INCLUDE_DIR)/blkid/blkid.h EXT2FS_HEADER := $(INCLUDE_DIR)/ext2fs/ext2_types.h -INTL_HEADER := $(INCLUDE_DIR)/libgnuintl.h UUID_HEADER := $(INCLUDE_DIR)/uuid/uuid.h DEFAULT_PROFILE_C := $(addsuffix /misc/default_profile.c, $(E2FSPROGS_DIR)) _dirs: \ $(BLKID_HEADER) \ $(EXT2FS_HEADER) \ - $(INTL_HEADER) \ $(UUID_HEADER) \ $(DEFAULT_PROFILE_C) -$(INTL_HEADER): - @$(MSG_GENERATE)$(notdir $@) - $(VERBOSE)sed -e 's,@''HAVE_POSIX_PRINTF''@,1,g' \ - -e 's,@''HAVE_ASPRINTF''@,1,g' \ - -e 's,@''HAVE_SNPRINTF''@,1,g' \ - -e 's,@''HAVE_WPRINTF''@,0,g' \ - < $(E2FSPROGS_DIR)/intl/libgnuintl.h.in > $@ - $(VERBOSE)ln -sf $(notdir $@) $(dir $@)/libintl.h - $(BLKID_HEADER): @$(MSG_GENERATE)$(notdir $@) $(VERBOSE)mkdir -p $(dir $@) @@ -69,7 +58,7 @@ $(EXT2FS_HEADER): $(VERBOSE)sed -e 's,@''E2FSPROGS_VERSION''@,$(VERSION),g' \ < $(E2FSPROGS_DIR)/lib/ext2fs/ext2_err.et.in \ > $(E2FSPROGS_DIR)/lib/ext2fs/ext2_err.et && \ - for file in lib/ext2fs/ext2_err e2fsck/prof_err; do \ + for file in lib/ext2fs/ext2_err lib/support/prof_err; do \ $(MSG_GENERATE)$${file}.h && \ gawk -f $(E2FSPROGS_DIR)/lib/et/et_h.awk \ "outfile=$(E2FSPROGS_DIR)/$${file}.h" \ diff --git a/repos/libports/ports/expat.hash b/repos/libports/ports/expat.hash index d4268bbd2d..18e0f7956f 100644 --- a/repos/libports/ports/expat.hash +++ b/repos/libports/ports/expat.hash @@ -1 +1 @@ -6af8cf04ee4b5325ad883f9922d9320548c853bc +0670a7b071ea29d0287d5f89c7fba1b852c8a146 diff --git a/repos/libports/ports/expat.port b/repos/libports/ports/expat.port index 301c450a45..3cd81de14a 100644 --- a/repos/libports/ports/expat.port +++ b/repos/libports/ports/expat.port @@ -1,9 +1,9 @@ LICENSE := MIT DOWNLOADS := expat.archive -VERSION := 2.4.6 +VERSION := 2.4.9 URL(expat) := http://sourceforge.net/projects/expat/files/expat/$(VERSION)/expat-$(VERSION).tar.gz -SHA(expat) := a0eb5af56b1c2ba812051c49bf3b4e5763293fe5394a0219df7208845c3efb8c +SHA(expat) := 4415710268555b32c4e5ab06a583bea9fec8ff89333b218b70b43d4ca10e38fa DIR(expat) := src/lib/expat/contrib DIRS := include diff --git a/repos/libports/ports/libc.hash b/repos/libports/ports/libc.hash index a332d026c5..f0b791929a 100644 --- a/repos/libports/ports/libc.hash +++ b/repos/libports/ports/libc.hash @@ -1 +1 @@ -c7cd230b11ca71979f32950803bc78b45adfa0ce +a4d148016cfbc4c494b277e164d67617cf540e31 diff --git a/repos/libports/ports/libc.port b/repos/libports/ports/libc.port index b276c57968..9a3911546c 100644 --- a/repos/libports/ports/libc.port +++ b/repos/libports/ports/libc.port @@ -129,7 +129,7 @@ DIR_CONTENT(include/libc/sys) := \ utsname.h elf.h mtio.h _stdint.h atomic_common.h _ucontext.h \ _cpuset.h _bitset.h bitset.h _stdarg.h _uio.h auxv.h random.h \ _sockaddr_storage.h termios.h _termios.h _umtx.h kerneldump.h \ - conf.h disk_zone.h counter.h soundcard.h pciio.h) + conf.h disk_zone.h counter.h soundcard.h pciio.h timex.h) DIRS += include/libc/sys/disk DIR_CONTENT(include/libc/sys/disk) := $(D)/sys/sys/disk/*h diff --git a/repos/libports/ports/mesa.hash b/repos/libports/ports/mesa.hash index 2b978bef9b..10cd30a7c9 100644 --- a/repos/libports/ports/mesa.hash +++ b/repos/libports/ports/mesa.hash @@ -1 +1 @@ -2a8726a52ca7b243fcf40d07da28a52aba4c767f +a195203391df18dabe0e9c247301d9f3df1c8192 diff --git a/repos/libports/ports/mesa.port b/repos/libports/ports/mesa.port index 63de2f8adb..ffb87f3a4d 100644 --- a/repos/libports/ports/mesa.port +++ b/repos/libports/ports/mesa.port @@ -23,15 +23,17 @@ PATCHES := src/lib/mesa/patches/bitset_redefined.patch \ src/lib/mesa/patches/lseek.patch \ src/lib/mesa/patches/mesa.patch \ src/lib/mesa/patches/os_mmap.patch \ - src/lib/mesa/patches/softpipe_cache.patch + src/lib/mesa/patches/softpipe_cache.patch \ + src/lib/mesa/patches/lima.patch \ + src/lib/mesa/patches/sync_wait.patch PATCH_OPT := -p1 # # Generated Mesa sources # -URL(generated) = https://github.com/ssumpf/mesa_generated.git -REV(generated) = 396d4b08cbcff941126640e6d3e3d2a5f807d527 +URL(generated) = https://github.com/cnuke/mesa_generated.git +REV(generated) = c3954da3f66d6cb961421f03c09d589faade1784 DIR(generated) = generated # @@ -110,7 +112,8 @@ generated_files = $(GEN_TARGET)/src/compiler/glsl/float64_glsl.h \ $(GEN_TARGET)/src/intel/genxml/genX_bits.h \ $(GEN_TARGET)/src/intel/genxml/genX_xml.h \ $(GEN_TARGET)/src/intel/isl/isl_format_layout.c \ - $(GEN_TARGET)/src/intel/perf/gen_perf_metrics.h + $(GEN_TARGET)/src/intel/perf/gen_perf_metrics.h \ + $(GEN_TARGET)/src/gallium/drivers/lima/lima_nir_algebraic.c # # Print message and create directory @@ -345,6 +348,11 @@ $(GEN_TARGET)/src/intel/perf/gen_perf_metrics.h: $(SRC)/src/intel/perf/oa-sklgt4.xml \ $(SRC)/src/intel/perf/oa-tgl.xml +$(GEN_TARGET)/src/gallium/drivers/lima/lima_nir_algebraic.c: + $(MSG_DIR) + $(VERBOSE)$(PYTHON) $(SRC)/src/gallium/drivers/lima/ir/lima_nir_algebraic.py \ + -p $(SRC)/src/compiler/nir/ > $@ + CMD(glcpp-lex.c) = glcpp-lex.l CMD(glsl_lexer.cpp) = glsl_lexer.ll CMD(lex.yy.c) = program_lexer.l diff --git a/repos/libports/ports/qt5-host.hash b/repos/libports/ports/qt5-host.hash index a0c4084adf..451b4d34f3 100644 --- a/repos/libports/ports/qt5-host.hash +++ b/repos/libports/ports/qt5-host.hash @@ -1 +1 @@ -21e078acd47b0d6888fe0f289eafbc8682da7a05 +baf211394cbf3981c3d03ed4c68bc9b266f768df diff --git a/repos/libports/ports/qt5-host.port b/repos/libports/ports/qt5-host.port index 507185778b..82e0889968 100644 --- a/repos/libports/ports/qt5-host.port +++ b/repos/libports/ports/qt5-host.port @@ -1,15 +1,23 @@ LICENSE := GPL -VERSION := 5.13.2 +VERSION := 5.15.2 -QTBASE := qtbase-everywhere-src-${VERSION} -QTTOOLS := qttools-everywhere-src-${VERSION} +QTBASE := qtbase-everywhere-src-${VERSION} +QTDECLARATIVE := qtdeclarative-everywhere-src-${VERSION} +QTTOOLS := qttools-everywhere-src-${VERSION} -DOWNLOADS := ${QTBASE}.archive $(QTTOOLS).archive +DOWNLOADS := ${QTBASE}.archive $(QTDECLARATIVE).archive $(QTTOOLS).archive -URL(${QTBASE}) := https://download.qt.io/archive/qt/5.13/$(VERSION)/submodules/$(QTBASE).tar.xz -SHA(${QTBASE}) := 26b6b686d66a7ad28eaca349e55e2894e5a735f3831e45f2049e93b1daa92121 +URL(${QTBASE}) := https://download.qt.io/archive/qt/5.15/$(VERSION)/submodules/$(QTBASE).tar.xz +SHA(${QTBASE}) := 909fad2591ee367993a75d7e2ea50ad4db332f05e1c38dd7a5a274e156a4e0f8 DIR(${QTBASE}) := src/lib/qtbase -URL(${QTTOOLS}) := https://download.qt.io/archive/qt/5.13/$(VERSION)/submodules/$(QTTOOLS).tar.xz -SHA(${QTTOOLS}) := 919a2713b6d2d7873a09ad85bd93cf4282606e5bf84d5884250f665a253ec06e +URL(${QTDECLARATIVE}) := https://download.qt.io/archive/qt/5.15/$(VERSION)/submodules/$(QTDECLARATIVE).tar.xz +SHA(${QTDECLARATIVE}) := c600d09716940f75d684f61c5bdaced797f623a86db1627da599027f6c635651 +DIR(${QTDECLARATIVE}) := src/lib/qtdeclarative + +URL(${QTTOOLS}) := https://download.qt.io/archive/qt/5.15/$(VERSION)/submodules/$(QTTOOLS).tar.xz +SHA(${QTTOOLS}) := c189d0ce1ff7c739db9a3ace52ac3e24cb8fd6dbf234e49f075249b38f43c1cc DIR(${QTTOOLS}) := src/lib/qttools + +PATCHES := src/lib/qt5-host/qt5-qtbase-gcc11.patch +PATCH_OPT := -p1 -d $(DIR(${QTBASE})) diff --git a/repos/libports/ports/qt5.hash b/repos/libports/ports/qt5.hash index dc7f9a9f4d..9e579599f1 100644 --- a/repos/libports/ports/qt5.hash +++ b/repos/libports/ports/qt5.hash @@ -1 +1 @@ -8c77588a4c223886c942a3de31bf8f0b3aca6ca1 +42324c0a611d86fbfdaf5ded294650807038421e diff --git a/repos/libports/ports/qt5.port b/repos/libports/ports/qt5.port index 64fc7f5c32..23538678b0 100644 --- a/repos/libports/ports/qt5.port +++ b/repos/libports/ports/qt5.port @@ -1,8 +1,8 @@ LICENSE := GPL -VERSION := 5.13.2 +VERSION := 5.15.2 DOWNLOADS := qt5.git URL(qt5) := https://github.com/cproc/qt5.git -REV(qt5) := issue4453 +REV(qt5) := issue4621 DIR(qt5) := src/lib/qt5 diff --git a/repos/libports/recipes/api/expat/hash b/repos/libports/recipes/api/expat/hash index c15657de21..e8422873fe 100644 --- a/repos/libports/recipes/api/expat/hash +++ b/repos/libports/recipes/api/expat/hash @@ -1 +1 @@ -2022-02-27 6b600a1d1c95fce5722a9e6d38bdb1208fce0d89 +2022-10-11 4f9a1485df5176990ac710c56b5fd4cdc9c18f69 diff --git a/repos/libports/recipes/api/gmp/hash b/repos/libports/recipes/api/gmp/hash index 45cb5555b1..6a1e2b760f 100644 --- a/repos/libports/recipes/api/gmp/hash +++ b/repos/libports/recipes/api/gmp/hash @@ -1 +1 @@ -2021-02-22 85dd7243bee149bbd1a691c89182fe9bd0fd1835 +2022-08-16 d4a72d7d1594d587711791b324466c3c0103c38b diff --git a/repos/libports/recipes/api/libc/hash b/repos/libports/recipes/api/libc/hash index 94e074262f..f6958bd282 100644 --- a/repos/libports/recipes/api/libc/hash +++ b/repos/libports/recipes/api/libc/hash @@ -1 +1 @@ -2022-07-04 32713565e2d1160d12e88c2620f894f87dbad85c +2022-08-30 6943e7821ad6e8c36ce46b109db41ca2e6d730f1 \ No newline at end of file diff --git a/repos/libports/recipes/api/libdrm/content.mk b/repos/libports/recipes/api/libdrm/content.mk index 9938d01386..3790641f41 100644 --- a/repos/libports/recipes/api/libdrm/content.mk +++ b/repos/libports/recipes/api/libdrm/content.mk @@ -19,6 +19,8 @@ include: cp -r $(PORT_DIR)/src/lib/libdrm/intel/*.h $@/intel mkdir -p $@/etnaviv cp -r $(PORT_DIR)/src/lib/libdrm/etnaviv/*.h $@/etnaviv + mkdir -p $@/libdrm + cp $(REP_DIR)/include/libdrm/ioctl_dispatch.h $@/libdrm content: LICENSE diff --git a/repos/libports/recipes/api/libdrm/hash b/repos/libports/recipes/api/libdrm/hash index 6e252fce6a..132163e5ae 100644 --- a/repos/libports/recipes/api/libdrm/hash +++ b/repos/libports/recipes/api/libdrm/hash @@ -1 +1 @@ -2021-11-29 82e8cd40bd7c44247a7559f1db8374538e714b05 +2022-08-16 4b9e10789ce5311dfa3aa688ce0e0dbee532e13f diff --git a/repos/libports/recipes/api/libgcov/content.mk b/repos/libports/recipes/api/libgcov/content.mk index d309a4f5fd..38f2ef1bb0 100644 --- a/repos/libports/recipes/api/libgcov/content.mk +++ b/repos/libports/recipes/api/libgcov/content.mk @@ -22,7 +22,6 @@ src/gcov: src/lib/gcov: $(mirror_from_rep_dir) - echo "LIBS = libgcov" > $@/target.mk LICENSE: cp $(PORT_DIR)/src/gcov/COPYING $@ diff --git a/repos/libports/recipes/api/libgcov/hash b/repos/libports/recipes/api/libgcov/hash index 833ff32269..6472dbecf9 100644 --- a/repos/libports/recipes/api/libgcov/hash +++ b/repos/libports/recipes/api/libgcov/hash @@ -1 +1 @@ -2022-02-14 de05203f758e663b228d1166a4054b11fca56d10 +2022-09-20 b00d5d04adde01f4724f6a3a9005e5a06721f432 diff --git a/repos/libports/recipes/api/pcsc-lite/content.mk b/repos/libports/recipes/api/pcsc-lite/content.mk new file mode 100644 index 0000000000..63e9fb9ace --- /dev/null +++ b/repos/libports/recipes/api/pcsc-lite/content.mk @@ -0,0 +1,19 @@ +MIRROR_FROM_REP_DIR := lib/import/import-pcsc-lite.mk + +content: $(MIRROR_FROM_REP_DIR) + +$(MIRROR_FROM_REP_DIR): + $(mirror_from_rep_dir) + +PORT_DIR := $(call port_dir,$(REP_DIR)/ports/pcsc-lite) + +content: include + +include: + mkdir -p $@ + cp -r $(PORT_DIR)/include/PCSC/* $@ + +content: LICENSE + +LICENSE: + cp $(PORT_DIR)/src/lib/pcsc-lite/COPYING $@ diff --git a/repos/libports/recipes/api/pcsc-lite/hash b/repos/libports/recipes/api/pcsc-lite/hash new file mode 100644 index 0000000000..899ef488d9 --- /dev/null +++ b/repos/libports/recipes/api/pcsc-lite/hash @@ -0,0 +1 @@ +2022-08-30 d9e0d7a0a115b076da34b678283a202bc641bd47 diff --git a/repos/libports/recipes/api/qt5/content.mk b/repos/libports/recipes/api/qt5/content.mk index 0320150e96..8886da1dbe 100644 --- a/repos/libports/recipes/api/qt5/content.mk +++ b/repos/libports/recipes/api/qt5/content.mk @@ -1,4 +1,5 @@ -MIRROR_FROM_REP_DIR := lib/import/import-qt5_qmake.mk +MIRROR_FROM_REP_DIR := lib/import/import-qt5_cmake.mk \ + lib/import/import-qt5_qmake.mk content: $(MIRROR_FROM_REP_DIR) diff --git a/repos/libports/recipes/api/qt5/hash b/repos/libports/recipes/api/qt5/hash index 70a9796a26..10f95be2ed 100644 --- a/repos/libports/recipes/api/qt5/hash +++ b/repos/libports/recipes/api/qt5/hash @@ -1 +1 @@ -2021-01-22 4856d458c6d53bb57d3e61e4a81fc5b06eaa8e2b +2022-08-30 300d4abc0fa184cacd1c11cd56f23a7877f847b5 diff --git a/repos/libports/recipes/pkg/acpica/hash b/repos/libports/recipes/pkg/acpica/hash index 3f63d6b7e3..5cdc831b33 100644 --- a/repos/libports/recipes/pkg/acpica/hash +++ b/repos/libports/recipes/pkg/acpica/hash @@ -1 +1 @@ -2022-05-24 b1075721a92e875333d8b96d78c158c1d1288550 +2022-10-11 010ed31b6429fe9c7500b1477e737eea4abb9f16 diff --git a/repos/libports/recipes/pkg/acpica/runtime b/repos/libports/recipes/pkg/acpica/runtime index b465913ea4..3df07ea803 100644 --- a/repos/libports/recipes/pkg/acpica/runtime +++ b/repos/libports/recipes/pkg/acpica/runtime @@ -1,4 +1,4 @@ - + diff --git a/repos/libports/recipes/pkg/gcov/hash b/repos/libports/recipes/pkg/gcov/hash index 8f42a7d528..75fbbd8b1e 100644 --- a/repos/libports/recipes/pkg/gcov/hash +++ b/repos/libports/recipes/pkg/gcov/hash @@ -1 +1 @@ -2022-05-24 03da3e26ba9ed52b75338d1b3c64c5ea447cadb2 +2022-10-11 7c4dca705f1a0534841465b849b1a51ae0771ec7 diff --git a/repos/libports/recipes/pkg/mesa_gears/hash b/repos/libports/recipes/pkg/mesa_gears/hash index 8fa1d4bec0..8ebc61b586 100644 --- a/repos/libports/recipes/pkg/mesa_gears/hash +++ b/repos/libports/recipes/pkg/mesa_gears/hash @@ -1 +1 @@ -2022-05-24 81812410d94da51b3c1019553140b5c5d232ede6 +2022-10-13 cfa9c3c161538a4684b21882e12080853b53fce0 diff --git a/repos/libports/recipes/pkg/mesa_gpu-cpu/hash b/repos/libports/recipes/pkg/mesa_gpu-cpu/hash index d032bf204d..35e9d36675 100644 --- a/repos/libports/recipes/pkg/mesa_gpu-cpu/hash +++ b/repos/libports/recipes/pkg/mesa_gpu-cpu/hash @@ -1 +1 @@ -2022-05-24 feff7105f296557e932377c8d0dd0211efda3e0a +2022-10-11 28685840b44eb4fb4040405e5380703512e7f4cd diff --git a/repos/libports/recipes/pkg/mesa_gpu-etnaviv/hash b/repos/libports/recipes/pkg/mesa_gpu-etnaviv/hash index 59ef074a8d..e2a03613ff 100644 --- a/repos/libports/recipes/pkg/mesa_gpu-etnaviv/hash +++ b/repos/libports/recipes/pkg/mesa_gpu-etnaviv/hash @@ -1 +1 @@ -2022-05-24 1fe9669720b0f61b9953baaa2dc36576a3c5e866 +2022-10-11 aacfa725e1707e027f5443cbbe091e6c4ead4024 diff --git a/repos/libports/recipes/pkg/mesa_gpu-intel/hash b/repos/libports/recipes/pkg/mesa_gpu-intel/hash index 673b1c80e8..aefdc0b5aa 100644 --- a/repos/libports/recipes/pkg/mesa_gpu-intel/hash +++ b/repos/libports/recipes/pkg/mesa_gpu-intel/hash @@ -1 +1 @@ -2022-05-24 2c0dfe3c79d85972f8946340b6a29aca6c3ed30c +2022-10-11 a19bdb0ebc89fe526154ba1b20ed5637084aff9a diff --git a/repos/libports/recipes/pkg/pdf_view/hash b/repos/libports/recipes/pkg/pdf_view/hash index f3faf2c704..b391eab46e 100644 --- a/repos/libports/recipes/pkg/pdf_view/hash +++ b/repos/libports/recipes/pkg/pdf_view/hash @@ -1 +1 @@ -2022-05-24 43a153dd7796b69e2705aa8a2d6c1763cdae7c0b +2022-10-13 6a7f926f0ba2b94e41c88013eb2d8732a69e6f51 diff --git a/repos/libports/recipes/pkg/qt5_textedit/hash b/repos/libports/recipes/pkg/qt5_textedit/hash index 8abf3d623a..82f7485a7c 100644 --- a/repos/libports/recipes/pkg/qt5_textedit/hash +++ b/repos/libports/recipes/pkg/qt5_textedit/hash @@ -1 +1 @@ -2022-05-24 a78e8b3b90d0fec6c9bd4f54e5ae9e373cb0c1c9 +2022-10-13 73be73a9a8085a69e2317f49f0a39ef7d485f498 diff --git a/repos/libports/recipes/pkg/qt5_textedit/runtime b/repos/libports/recipes/pkg/qt5_textedit/runtime index 3197f7621b..8c271e1340 100644 --- a/repos/libports/recipes/pkg/qt5_textedit/runtime +++ b/repos/libports/recipes/pkg/qt5_textedit/runtime @@ -6,6 +6,7 @@ + diff --git a/repos/libports/recipes/pkg/system_clock-pc/hash b/repos/libports/recipes/pkg/system_clock-pc/hash index 41f5159588..e4c9fdd48c 100644 --- a/repos/libports/recipes/pkg/system_clock-pc/hash +++ b/repos/libports/recipes/pkg/system_clock-pc/hash @@ -1 +1 @@ -2022-05-24 491f3407cd7fc93f9fb50f4736362117f57a0900 +2022-10-11 6703af7d1d42c5ef9abc0b1eae59b36ed5e7e8e9 diff --git a/repos/libports/recipes/pkg/system_rtc-linux/hash b/repos/libports/recipes/pkg/system_rtc-linux/hash index ff9ba1c79e..d9631eefe6 100644 --- a/repos/libports/recipes/pkg/system_rtc-linux/hash +++ b/repos/libports/recipes/pkg/system_rtc-linux/hash @@ -1 +1 @@ -2022-05-24 83007e26ddab12746ccd935efacf9634dd259f1f +2022-10-11 1179a2775ec1e504dbb35fcf632d65c2ad20800b diff --git a/repos/libports/recipes/pkg/system_rtc-pc/hash b/repos/libports/recipes/pkg/system_rtc-pc/hash index ff64081e26..e22e8d4e51 100644 --- a/repos/libports/recipes/pkg/system_rtc-pc/hash +++ b/repos/libports/recipes/pkg/system_rtc-pc/hash @@ -1 +1 @@ -2022-05-24 7314ffd53ce1d9f266a45b149455ffe4f39e26a7 +2022-10-11 4894e0037fdadbf7743a17d0986e318f127219ad diff --git a/repos/libports/recipes/pkg/test-expat/hash b/repos/libports/recipes/pkg/test-expat/hash index 6daf040553..aa92241f67 100644 --- a/repos/libports/recipes/pkg/test-expat/hash +++ b/repos/libports/recipes/pkg/test-expat/hash @@ -1 +1 @@ -2022-05-24 550d42cde275043f0861578bb0384425c2e61576 +2022-10-11 6cdc95e5e667701b1b7a4803537b61bdb4722121 diff --git a/repos/libports/recipes/pkg/test-ldso/hash b/repos/libports/recipes/pkg/test-ldso/hash index de2f846d1a..45569f78e1 100644 --- a/repos/libports/recipes/pkg/test-ldso/hash +++ b/repos/libports/recipes/pkg/test-ldso/hash @@ -1 +1 @@ -2022-05-24 467270387a1dc0410425ea81a6f7a0a06dd93bcd +2022-10-11 70b6c3d065e4836869ee8bbaf5f29c2c1caeedb4 diff --git a/repos/libports/recipes/pkg/test-libc/hash b/repos/libports/recipes/pkg/test-libc/hash index e607bb4e45..17364c1eca 100644 --- a/repos/libports/recipes/pkg/test-libc/hash +++ b/repos/libports/recipes/pkg/test-libc/hash @@ -1 +1 @@ -2022-05-24 3b0f396f81721b26b295f08c4e7953e314459b36 +2022-10-11 f4852024822ef5b9015fafd5cba97a2c3f09addb diff --git a/repos/libports/recipes/pkg/test-libc_connect_lwip/hash b/repos/libports/recipes/pkg/test-libc_connect_lwip/hash index a6930bd229..0301a10696 100644 --- a/repos/libports/recipes/pkg/test-libc_connect_lwip/hash +++ b/repos/libports/recipes/pkg/test-libc_connect_lwip/hash @@ -1 +1 @@ -2022-05-24 c496953343092623bab4dc48bb6062f3a272a599 +2022-10-11 d619be6ebfcfe5fa939926dfd4bce27ff0531c79 diff --git a/repos/libports/recipes/pkg/test-libc_connect_lxip/hash b/repos/libports/recipes/pkg/test-libc_connect_lxip/hash index cc2ccfaa6b..f1a635a65a 100644 --- a/repos/libports/recipes/pkg/test-libc_connect_lxip/hash +++ b/repos/libports/recipes/pkg/test-libc_connect_lxip/hash @@ -1 +1 @@ -2022-05-24 b6e9db1e216f8d07cf7a9c3f9b5c477efe038d35 +2022-10-11 dc311df66d06ec7ddcb7cab2c3c17ec97aa6e827 diff --git a/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/hash b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/hash index 44320150d5..49db64435b 100644 --- a/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/hash +++ b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/hash @@ -1 +1 @@ -2022-05-24 bbe5f043dfd6d6da43558ec2f037ca6ae962fed7 +2022-10-11 9750f56cdf2fee65677c6be816686dcfff865d2b diff --git a/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/hash b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/hash index 6a6c7a03c4..6266173a5b 100644 --- a/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/hash +++ b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/hash @@ -1 +1 @@ -2022-05-24 0052b3766bae0649337f0a8ea4b523e73bbca0e1 +2022-10-11 29e4e47dcb4b1beaa266e55c787e82c7b7fdbb88 diff --git a/repos/libports/recipes/pkg/test-libc_counter/hash b/repos/libports/recipes/pkg/test-libc_counter/hash index eed8ccc4d8..eb28b7e36a 100644 --- a/repos/libports/recipes/pkg/test-libc_counter/hash +++ b/repos/libports/recipes/pkg/test-libc_counter/hash @@ -1 +1 @@ -2022-05-24 f4eff430bbd7076067c6c091d5682e6bcbcaa30f +2022-10-11 a58d662a69a0e033a82e4b0276cf3dc6808a658b diff --git a/repos/libports/recipes/pkg/test-libc_execve/hash b/repos/libports/recipes/pkg/test-libc_execve/hash index e4b38f9ff5..92d5abe35e 100644 --- a/repos/libports/recipes/pkg/test-libc_execve/hash +++ b/repos/libports/recipes/pkg/test-libc_execve/hash @@ -1 +1 @@ -2022-05-24 7ca1271740c179db624b8fdb468861c0363fb846 +2022-10-11 a6da458cc4475893d8d5dbb4e6f82ab0fba9ddff diff --git a/repos/libports/recipes/pkg/test-libc_fifo_pipe/hash b/repos/libports/recipes/pkg/test-libc_fifo_pipe/hash index 58b5600cd2..fe5ae4e7f8 100644 --- a/repos/libports/recipes/pkg/test-libc_fifo_pipe/hash +++ b/repos/libports/recipes/pkg/test-libc_fifo_pipe/hash @@ -1 +1 @@ -2022-05-24 1dd1f34f47b98815525696e152696cfa443a8468 +2022-10-11 b9d99184dc03b5d7463e38a88cae5e8e9b8fd3eb diff --git a/repos/libports/recipes/pkg/test-libc_fork/hash b/repos/libports/recipes/pkg/test-libc_fork/hash index 5b7c63f543..03ecd4a371 100644 --- a/repos/libports/recipes/pkg/test-libc_fork/hash +++ b/repos/libports/recipes/pkg/test-libc_fork/hash @@ -1 +1 @@ -2022-05-24 13950c69012005b54a3549bd3d19bf2e8838ae60 +2022-10-11 f88a4f41243030217cac55b2fac678ce85c471a4 diff --git a/repos/libports/recipes/pkg/test-libc_getenv/hash b/repos/libports/recipes/pkg/test-libc_getenv/hash index 5c3ca36dcf..9f30e33310 100644 --- a/repos/libports/recipes/pkg/test-libc_getenv/hash +++ b/repos/libports/recipes/pkg/test-libc_getenv/hash @@ -1 +1 @@ -2022-05-24 8f4f5d3639e7f4c664c239172a6ba047e327a93b +2022-10-11 a945322eb922856b9b9b84a979bc2f236baf3655 diff --git a/repos/libports/recipes/pkg/test-libc_pipe/hash b/repos/libports/recipes/pkg/test-libc_pipe/hash index 8c6a82a616..7a2ccf8304 100644 --- a/repos/libports/recipes/pkg/test-libc_pipe/hash +++ b/repos/libports/recipes/pkg/test-libc_pipe/hash @@ -1 +1 @@ -2022-05-24 ae37de3ed8ff292e28d0faebad91a2e09b4a8631 +2022-10-11 a2d01973e762a100f58c9245bc2383669cc62bfc diff --git a/repos/libports/recipes/pkg/test-libc_vfs/hash b/repos/libports/recipes/pkg/test-libc_vfs/hash index 37215e2e84..25de530e25 100644 --- a/repos/libports/recipes/pkg/test-libc_vfs/hash +++ b/repos/libports/recipes/pkg/test-libc_vfs/hash @@ -1 +1 @@ -2022-05-24 ba6dc394c49c14d0d4f6115aab9fb8f57aee9e5e +2022-10-11 58abaa720f3d07a129ff8e757ddab2bf502e92b6 diff --git a/repos/libports/recipes/pkg/test-libc_vfs_block/hash b/repos/libports/recipes/pkg/test-libc_vfs_block/hash index 42f82fa7f7..a1544c89f5 100644 --- a/repos/libports/recipes/pkg/test-libc_vfs_block/hash +++ b/repos/libports/recipes/pkg/test-libc_vfs_block/hash @@ -1 +1 @@ -2022-05-24 e9535d95ddeb0f274941d0488ca3ccb127da5701 +2022-10-11 0da2881ead0fd9e952c0586c43ae433666aa2410 diff --git a/repos/libports/recipes/pkg/test-libc_vfs_counter/hash b/repos/libports/recipes/pkg/test-libc_vfs_counter/hash index 5efa6fbd78..23d6ae5bc7 100644 --- a/repos/libports/recipes/pkg/test-libc_vfs_counter/hash +++ b/repos/libports/recipes/pkg/test-libc_vfs_counter/hash @@ -1 +1 @@ -2022-05-24 6c9cbde101399c39a5130c724991ba4d2775482b +2022-10-11 63a14aa5aa1cdae19b67777a9e3b1150340fac25 diff --git a/repos/libports/recipes/pkg/test-libc_vfs_fs/hash b/repos/libports/recipes/pkg/test-libc_vfs_fs/hash index ef18f5ac95..c193a619b8 100644 --- a/repos/libports/recipes/pkg/test-libc_vfs_fs/hash +++ b/repos/libports/recipes/pkg/test-libc_vfs_fs/hash @@ -1 +1 @@ -2022-05-24 471118d62e6a79b936d095d77dfea31b1d04941f +2022-10-11 f5ec4eaeae3ff7b9cbb5f8b0df126a3ebb07690d diff --git a/repos/libports/recipes/pkg/test-libc_vfs_fs_chained/hash b/repos/libports/recipes/pkg/test-libc_vfs_fs_chained/hash index 00fa81f7a6..81dd32f88d 100644 --- a/repos/libports/recipes/pkg/test-libc_vfs_fs_chained/hash +++ b/repos/libports/recipes/pkg/test-libc_vfs_fs_chained/hash @@ -1 +1 @@ -2022-05-24 2f1a7aad31d8fdb02082460f52d9b2e2a5200761 +2022-10-11 e6cec3a18012f9adcc9224f17113d7b5693e294f diff --git a/repos/libports/recipes/pkg/test-libc_vfs_ram/hash b/repos/libports/recipes/pkg/test-libc_vfs_ram/hash index 9692391637..20f0cf0745 100644 --- a/repos/libports/recipes/pkg/test-libc_vfs_ram/hash +++ b/repos/libports/recipes/pkg/test-libc_vfs_ram/hash @@ -1 +1 @@ -2022-05-24 2795ab1252b22e8a6733c5bc7df28bf89fa1037f +2022-10-11 4c9a757c6963232d8deb113d2c1f09d4d9d0ac30 diff --git a/repos/libports/recipes/pkg/test-pthread/hash b/repos/libports/recipes/pkg/test-pthread/hash index 344561c346..1b0e3cf289 100644 --- a/repos/libports/recipes/pkg/test-pthread/hash +++ b/repos/libports/recipes/pkg/test-pthread/hash @@ -1 +1 @@ -2022-05-24 a9a0d35a8b39b7f0f4f22fdf1a47311d47950de2 +2022-10-11 d5d4a5658647fe48b695cac310b765db8cf60de8 diff --git a/repos/libports/recipes/pkg/test-sequence/hash b/repos/libports/recipes/pkg/test-sequence/hash index 4f9edcc070..59d0cc901c 100644 --- a/repos/libports/recipes/pkg/test-sequence/hash +++ b/repos/libports/recipes/pkg/test-sequence/hash @@ -1 +1 @@ -2022-05-24 9c39d49a72d4d5f974dca649fadd746a2a42ca52 +2022-10-11 08680caf1b7c83c1561c9ad608bb5d80b156c854 diff --git a/repos/libports/recipes/pkg/test-spark/hash b/repos/libports/recipes/pkg/test-spark/hash index 771e83468e..2067ef247d 100644 --- a/repos/libports/recipes/pkg/test-spark/hash +++ b/repos/libports/recipes/pkg/test-spark/hash @@ -1 +1 @@ -2022-05-24 7c4fb075bf9faf2662cd073fecfee4dd54b30558 +2022-10-11 e3932a70a7495781bdb74c651ff2a5f96d18812b diff --git a/repos/libports/recipes/pkg/test-spark_exception/hash b/repos/libports/recipes/pkg/test-spark_exception/hash index 0cad9a793b..7520e5091a 100644 --- a/repos/libports/recipes/pkg/test-spark_exception/hash +++ b/repos/libports/recipes/pkg/test-spark_exception/hash @@ -1 +1 @@ -2022-05-24 186d15b4851f80b43c30eb341f00546b0f96d896 +2022-10-11 0983fe9b5f2473dd9ae86a89271416f159ce8ff6 diff --git a/repos/libports/recipes/pkg/test-spark_secondary_stack/hash b/repos/libports/recipes/pkg/test-spark_secondary_stack/hash index 2cf43b6cf8..055dc51e02 100644 --- a/repos/libports/recipes/pkg/test-spark_secondary_stack/hash +++ b/repos/libports/recipes/pkg/test-spark_secondary_stack/hash @@ -1 +1 @@ -2022-05-24 13f324893b5c4b86ac77ee826066b3ab88d6f2fb +2022-10-11 700d158cb3226460047663da00fe3ecc14af91d7 diff --git a/repos/libports/recipes/pkg/test-stdcxx/hash b/repos/libports/recipes/pkg/test-stdcxx/hash index 7f171500de..5d8819d614 100644 --- a/repos/libports/recipes/pkg/test-stdcxx/hash +++ b/repos/libports/recipes/pkg/test-stdcxx/hash @@ -1 +1 @@ -2022-05-24 cfda7f156d11fb4fe4c6d723aa4ff7e0774cfb11 +2022-10-11 16dea14e86385295418e3d78487f863c0f91611d diff --git a/repos/libports/recipes/pkg/test-tcp_bulk_lwip/hash b/repos/libports/recipes/pkg/test-tcp_bulk_lwip/hash index e9d84b81b2..f6577f2d99 100644 --- a/repos/libports/recipes/pkg/test-tcp_bulk_lwip/hash +++ b/repos/libports/recipes/pkg/test-tcp_bulk_lwip/hash @@ -1 +1 @@ -2022-05-24 804e1a0be3fdccc66a090e211486f4913e3b3c6a +2022-10-11 96563e3769e7277446ab7f9db5526f6904205c40 diff --git a/repos/libports/recipes/pkg/test-tcp_bulk_lxip/hash b/repos/libports/recipes/pkg/test-tcp_bulk_lxip/hash index 9aa9fc6c30..5a5731f746 100644 --- a/repos/libports/recipes/pkg/test-tcp_bulk_lxip/hash +++ b/repos/libports/recipes/pkg/test-tcp_bulk_lxip/hash @@ -1 +1 @@ -2022-05-24 fb4fe5ddd20d2072c6cff13313c34c066bd933e8 +2022-10-11 5f998ee868e6f23cd9b6dd64adc04db7eff8533b diff --git a/repos/libports/recipes/pkg/usb_webcam/hash b/repos/libports/recipes/pkg/usb_webcam/hash index 258cb8f2c7..09c3d9c560 100644 --- a/repos/libports/recipes/pkg/usb_webcam/hash +++ b/repos/libports/recipes/pkg/usb_webcam/hash @@ -1 +1 @@ -2022-05-24 8ab9eb555588f812673968e1c0f292b3616362c6 +2022-10-13 eaefe067dcf1b9742f8296db7db582233f186f88 diff --git a/repos/libports/recipes/src/acpica/hash b/repos/libports/recipes/src/acpica/hash index e48e995eb4..2d23877e4b 100644 --- a/repos/libports/recipes/src/acpica/hash +++ b/repos/libports/recipes/src/acpica/hash @@ -1 +1 @@ -2022-05-24 6bbe7dece8237551559205222369e818dd6fc42f +2022-10-11 ff22a592fe565270bd64d7f5fbe8533dc55e2d71 diff --git a/repos/libports/recipes/src/curl/content.mk b/repos/libports/recipes/src/curl/content.mk index 4af15e8206..a1a4e1b049 100644 --- a/repos/libports/recipes/src/curl/content.mk +++ b/repos/libports/recipes/src/curl/content.mk @@ -8,11 +8,6 @@ content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -content: src/lib/curl/target.mk - -src/lib/curl/target.mk: src/lib/curl - echo "LIBS += curl" > $@ - PORT_DIR := $(call port_dir,$(REP_DIR)/ports/curl) content: src/lib/curl diff --git a/repos/libports/recipes/src/curl/hash b/repos/libports/recipes/src/curl/hash index d9567492e0..32ff57deca 100644 --- a/repos/libports/recipes/src/curl/hash +++ b/repos/libports/recipes/src/curl/hash @@ -1 +1 @@ -2022-04-27 ad3563708e657d670eec9b49e59d87a3efcadb14 +2022-09-20 2b42dc9b73136d8971e0a660daf8c12479be5ec2 diff --git a/repos/libports/recipes/src/expat/content.mk b/repos/libports/recipes/src/expat/content.mk index dd777dcc7f..4e1557d5d3 100644 --- a/repos/libports/recipes/src/expat/content.mk +++ b/repos/libports/recipes/src/expat/content.mk @@ -1,14 +1,10 @@ MIRROR_FROM_REP_DIR := lib/mk/expat.mk -content: $(MIRROR_FROM_REP_DIR) src/lib/expat/target.mk +content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -src/lib/expat/target.mk: - mkdir -p $(dir $@) - echo "LIBS = expat" > $@ - PORT_DIR := $(call port_dir,$(REP_DIR)/ports/expat) MIRROR_FROM_PORT_DIR := src/lib/expat/contrib \ diff --git a/repos/libports/recipes/src/expat/hash b/repos/libports/recipes/src/expat/hash index a018e58301..87b6331174 100644 --- a/repos/libports/recipes/src/expat/hash +++ b/repos/libports/recipes/src/expat/hash @@ -1 +1 @@ -2022-04-27 0976e30a88558de4690593a40d41726ac168e73a +2022-10-11 e2a4ccd47e295414514051d675c4da6d9b9e3ba7 diff --git a/repos/libports/recipes/src/extract/hash b/repos/libports/recipes/src/extract/hash index 7caf393ad2..66211778fc 100644 --- a/repos/libports/recipes/src/extract/hash +++ b/repos/libports/recipes/src/extract/hash @@ -1 +1 @@ -2022-05-24 2bc833bc38da39a3a429d760792a0868252cc6f5 +2022-10-11 8a3e451403f1179ed1831ab1881a479fa72e48f4 diff --git a/repos/libports/recipes/src/fetchurl/hash b/repos/libports/recipes/src/fetchurl/hash index 276a43c252..4153cfc4c8 100644 --- a/repos/libports/recipes/src/fetchurl/hash +++ b/repos/libports/recipes/src/fetchurl/hash @@ -1 +1 @@ -2022-05-24 e8da373e14207540c4421015fb1316ac5f07d58e +2022-10-11 7b4b05eec74a47b664b8f2f5ecc889325316784c diff --git a/repos/libports/recipes/src/ffi/content.mk b/repos/libports/recipes/src/ffi/content.mk index 73e48139e9..2543358c86 100644 --- a/repos/libports/recipes/src/ffi/content.mk +++ b/repos/libports/recipes/src/ffi/content.mk @@ -10,7 +10,6 @@ src/lib/ffi: mkdir -p $@ cp -r $(PORT_DIR)/src/lib/ffi/* $@ cp -r $(REP_DIR)/src/lib/ffi/* $@ - echo "LIBS = ffi" > $@/target.mk $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) diff --git a/repos/libports/recipes/src/ffi/hash b/repos/libports/recipes/src/ffi/hash index 46c22fc510..103fa42c11 100644 --- a/repos/libports/recipes/src/ffi/hash +++ b/repos/libports/recipes/src/ffi/hash @@ -1 +1 @@ -2022-02-27 01130e4ef8bc5cbe7415834e1a19e11a450d41ae +2022-09-20 2884df560359edc475faf202944e6d2c33461d58 diff --git a/repos/libports/recipes/src/freetype/content.mk b/repos/libports/recipes/src/freetype/content.mk index 6ee93d7f08..ace9828cc4 100644 --- a/repos/libports/recipes/src/freetype/content.mk +++ b/repos/libports/recipes/src/freetype/content.mk @@ -5,7 +5,6 @@ PORT_DIR := $(call port_dir,$(REP_DIR)/ports/freetype) src/lib/freetype: mkdir -p $(dir $@) cp -r $(PORT_DIR)/src/lib/freetype $@ - echo "LIBS = freetype" > $@/target.mk include/freetype-genode: $(mirror_from_rep_dir) diff --git a/repos/libports/recipes/src/freetype/hash b/repos/libports/recipes/src/freetype/hash index 54bdd81f2a..6afaa9a40b 100644 --- a/repos/libports/recipes/src/freetype/hash +++ b/repos/libports/recipes/src/freetype/hash @@ -1 +1 @@ -2022-02-27 d04249140c9d0138c047ab755504027fe99a83b2 +2022-09-20 679662de62ef840937909e168d687efba4eaeb01 diff --git a/repos/libports/recipes/src/fs_utils/content.mk b/repos/libports/recipes/src/fs_utils/content.mk index d2f8a2f4ba..25ecf971c4 100644 --- a/repos/libports/recipes/src/fs_utils/content.mk +++ b/repos/libports/recipes/src/fs_utils/content.mk @@ -16,7 +16,7 @@ src/lib/e2fsprogs: cp -a $(REP_DIR)/src/lib/e2fsprogs/* $@ LICENSE: - cp $(PORT_DIR)/src/lib/e2fsprogs/COPYING $@ + cp $(PORT_DIR)/src/lib/e2fsprogs/NOTICE $@ $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) diff --git a/repos/libports/recipes/src/fs_utils/hash b/repos/libports/recipes/src/fs_utils/hash index 96a0ac7795..a7363d9f71 100644 --- a/repos/libports/recipes/src/fs_utils/hash +++ b/repos/libports/recipes/src/fs_utils/hash @@ -1 +1 @@ -2022-02-27 662acade7f29303a0dcdf2ae9360d2fa8e15de64 +2022-08-30 b2450ad64d1379a400d4cf49f5dcd87e944d515c diff --git a/repos/libports/recipes/src/gcov/hash b/repos/libports/recipes/src/gcov/hash index e6d1e199a4..8028287bf7 100644 --- a/repos/libports/recipes/src/gcov/hash +++ b/repos/libports/recipes/src/gcov/hash @@ -1 +1 @@ -2022-05-24 337041d656fae9ffc8fb3b11fbf7723d966cc1e4 +2022-10-11 ead970c91c1867e13ff7810507f79ef4ce0e9811 diff --git a/repos/libports/recipes/src/gmp/content.mk b/repos/libports/recipes/src/gmp/content.mk index 383b2c3716..502e04a2a6 100644 --- a/repos/libports/recipes/src/gmp/content.mk +++ b/repos/libports/recipes/src/gmp/content.mk @@ -59,7 +59,6 @@ src/lib/gmp: mkdir -p $@ cp -r $(PORT_SRC_DIR)/* $@ cp -r $(REP_DIR)/src/lib/gmp/* $@ - echo "LIBS = gmp" > $@/target.mk LICENSE: cp $(PORT_SRC_DIR)/COPYING $@ diff --git a/repos/libports/recipes/src/gmp/hash b/repos/libports/recipes/src/gmp/hash index 4dedb372f6..6479928113 100644 --- a/repos/libports/recipes/src/gmp/hash +++ b/repos/libports/recipes/src/gmp/hash @@ -1 +1 @@ -2022-05-24 982fbc9f71641fafa7ed3ab0cd438b0ac0dc158e +2022-09-20 b5b7cedcb6d1c91e90df4e237044d4b615b171bc diff --git a/repos/libports/recipes/src/icu/content.mk b/repos/libports/recipes/src/icu/content.mk index 2fa3b431d5..dafd8ba4cb 100644 --- a/repos/libports/recipes/src/icu/content.mk +++ b/repos/libports/recipes/src/icu/content.mk @@ -5,7 +5,6 @@ PORT_DIR := $(call port_dir,$(REP_DIR)/ports/icu) src/lib/icu: mkdir -p $@ cp -a $(PORT_DIR)/src/lib/icu/* $@/ - echo "LIBS = icu" > $@/target.mk lib/mk/icu.mk: $(mirror_from_rep_dir) diff --git a/repos/libports/recipes/src/icu/hash b/repos/libports/recipes/src/icu/hash index 7c58ef5347..aac6b686b7 100644 --- a/repos/libports/recipes/src/icu/hash +++ b/repos/libports/recipes/src/icu/hash @@ -1 +1 @@ -2022-05-24 35bedbb6951e28d038f96801f029b0b3944f2259 +2022-09-20 2c33a86082764c248d194ee056510d3618c6fb3e diff --git a/repos/libports/recipes/src/jbig2dec/content.mk b/repos/libports/recipes/src/jbig2dec/content.mk index 330060df76..17a6c191bb 100644 --- a/repos/libports/recipes/src/jbig2dec/content.mk +++ b/repos/libports/recipes/src/jbig2dec/content.mk @@ -5,7 +5,6 @@ PORT_DIR := $(call port_dir,$(REP_DIR)/ports/jbig2dec) src/lib/jbig2dec: mkdir -p $@ cp -a $(PORT_DIR)/src/lib/jbig2dec/* $@/ - echo "LIBS = jbig2dec" > $@/target.mk lib/mk/%.mk: $(mirror_from_rep_dir) diff --git a/repos/libports/recipes/src/jbig2dec/hash b/repos/libports/recipes/src/jbig2dec/hash index fa326125d6..646155e6cc 100644 --- a/repos/libports/recipes/src/jbig2dec/hash +++ b/repos/libports/recipes/src/jbig2dec/hash @@ -1 +1 @@ -2022-04-27 671c2d33d3a4bd4d8f05a76defc16555bf8895c6 +2022-09-20 1a9994db1bf4b4a33ccba255d80398eefe9b0b8c diff --git a/repos/libports/recipes/src/jpeg/content.mk b/repos/libports/recipes/src/jpeg/content.mk index 3013409349..35b89cc6da 100644 --- a/repos/libports/recipes/src/jpeg/content.mk +++ b/repos/libports/recipes/src/jpeg/content.mk @@ -5,7 +5,6 @@ PORT_DIR := $(call port_dir,$(REP_DIR)/ports/jpeg) src/lib/jpeg: mkdir -p $(dir $@) cp -r $(PORT_DIR)/src/lib/jpeg $@ - echo "LIBS = jpeg" > $@/target.mk lib/mk/%.mk: $(mirror_from_rep_dir) diff --git a/repos/libports/recipes/src/jpeg/hash b/repos/libports/recipes/src/jpeg/hash index ee96d7256e..beca8ba600 100644 --- a/repos/libports/recipes/src/jpeg/hash +++ b/repos/libports/recipes/src/jpeg/hash @@ -1 +1 @@ -2022-04-27 ef1445e8b64b103ae010b0dd12e470d686012498 +2022-09-20 041bd52075e34cf85c25f8afe43aa24ea7683a3a diff --git a/repos/libports/recipes/src/libarchive/content.mk b/repos/libports/recipes/src/libarchive/content.mk index 23d0d0006f..8204e55e45 100644 --- a/repos/libports/recipes/src/libarchive/content.mk +++ b/repos/libports/recipes/src/libarchive/content.mk @@ -9,7 +9,6 @@ src/lib/libarchive: mkdir -p $@ cp -r $(PORT_DIR)/src/lib/libarchive/* $@ cp $(REP_DIR)/src/lib/libarchive/* $@ - echo "LIBS = libarchive" > $@/target.mk lib/mk/libarchive.mk: $(mirror_from_rep_dir) diff --git a/repos/libports/recipes/src/libarchive/hash b/repos/libports/recipes/src/libarchive/hash index 1c6f56005c..5753f6768c 100644 --- a/repos/libports/recipes/src/libarchive/hash +++ b/repos/libports/recipes/src/libarchive/hash @@ -1 +1 @@ -2022-04-27 a878914b64b19ebb177b03daf43e4bdde18d1cbb +2022-09-20 da2a277ee6fd4078d223a1005a71e38362265a70 diff --git a/repos/libports/recipes/src/libc/content.mk b/repos/libports/recipes/src/libc/content.mk index af9a9a3413..0d0aef61f6 100644 --- a/repos/libports/recipes/src/libc/content.mk +++ b/repos/libports/recipes/src/libc/content.mk @@ -1,4 +1,4 @@ -content: include/libc-plugin src/lib/libc/target.mk lib/mk LICENSE +content: include/libc-plugin src/lib/libc lib/mk LICENSE LIBC_PORT_DIR := $(call port_dir,$(REP_DIR)/ports/libc) LIBM_PORT_DIR := $(LIBC_PORT_DIR) @@ -8,11 +8,7 @@ src/lib/libc: cp -r $(LIBC_PORT_DIR)/src/lib/libc/* $@ cp -r $(REP_DIR)/src/lib/libc/* $@ -# target.mk for triggering the build of both libraries libc and libm -src/lib/libc/target.mk: src/lib/libc - echo "LIBS += libc libm" > $@ - -include/libc-plugin include/libc/sys/ucontext.h: +include/libc-plugin: $(mirror_from_rep_dir) lib/mk: diff --git a/repos/libports/recipes/src/libc/hash b/repos/libports/recipes/src/libc/hash index 61f69bbbb7..52898bf921 100644 --- a/repos/libports/recipes/src/libc/hash +++ b/repos/libports/recipes/src/libc/hash @@ -1 +1 @@ -2022-05-24 c97b089b965a64f8362e22e8c831caa7468d09f8 +2022-10-13 fdff5ab92d134ae67156c8d146623b2a3598cf31 diff --git a/repos/libports/recipes/src/libdrm/content.mk b/repos/libports/recipes/src/libdrm/content.mk index 9810c29aef..08f2c526d5 100644 --- a/repos/libports/recipes/src/libdrm/content.mk +++ b/repos/libports/recipes/src/libdrm/content.mk @@ -2,21 +2,20 @@ MIRROR_FROM_REP_DIR := lib/mk/libdrm.mk \ lib/mk/libdrm.inc \ lib/mk/spec/arm_v8/libdrm.mk \ lib/mk/spec/x86_64/libdrm.mk \ + include/libdrm/ioctl_dispatch.h \ src/lib/libdrm/include \ src/lib/libdrm/dummies.c \ src/lib/libdrm/ioctl_dummy.cc \ src/lib/libdrm/ioctl_iris.cc \ src/lib/libdrm/ioctl_etnaviv.cc \ + src/lib/libdrm/ioctl_dispatch.cc \ + src/lib/libdrm/ioctl_lima.cc -content: $(MIRROR_FROM_REP_DIR) src/lib/libdrm/target.mk +content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -src/lib/libdrm/target.mk: - mkdir -p $(dir $@) - echo "LIBS = libdrm" > $@ - PORT_DIR := $(call port_dir,$(REP_DIR)/ports/libdrm) MIRROR_FROM_PORT_DIR := $(addprefix src/lib/libdrm/,\ diff --git a/repos/libports/recipes/src/libdrm/hash b/repos/libports/recipes/src/libdrm/hash index 77b471dc82..292975a948 100644 --- a/repos/libports/recipes/src/libdrm/hash +++ b/repos/libports/recipes/src/libdrm/hash @@ -1 +1 @@ -2022-05-24 2c3b6f341a8ca08017cdddee7b79248817284d1d +2022-10-11 af750390f99c4153594d76efc8e13ed182cf2673 diff --git a/repos/libports/recipes/src/libdrm/used_apis b/repos/libports/recipes/src/libdrm/used_apis index d33079a30a..5f9364f5c4 100644 --- a/repos/libports/recipes/src/libdrm/used_apis +++ b/repos/libports/recipes/src/libdrm/used_apis @@ -2,3 +2,4 @@ base gpu_session libc vfs_gpu +mesa diff --git a/repos/libports/recipes/src/libiconv/content.mk b/repos/libports/recipes/src/libiconv/content.mk index a8e156d43a..43721cf690 100644 --- a/repos/libports/recipes/src/libiconv/content.mk +++ b/repos/libports/recipes/src/libiconv/content.mk @@ -17,7 +17,6 @@ src/lib/libiconv: mkdir -p $@ cp -r $(PORT_DIR)/src/lib/libiconv/* $@ cp -r $(REP_DIR)/src/lib/libiconv/private $@ - echo "LIBS = libiconv" > $@/target.mk content: LICENSE diff --git a/repos/libports/recipes/src/libiconv/hash b/repos/libports/recipes/src/libiconv/hash index accd5f8f29..9d949face1 100644 --- a/repos/libports/recipes/src/libiconv/hash +++ b/repos/libports/recipes/src/libiconv/hash @@ -1 +1 @@ -2022-04-27 a4ac3a81917efff8e4887f64787c0cb03f8904c8 +2022-09-20 b0d0abcfe4bf3cea9cf0f8bad058511692bdb275 diff --git a/repos/libports/recipes/src/liblzma/content.mk b/repos/libports/recipes/src/liblzma/content.mk index 71f42d2f81..56367905d6 100644 --- a/repos/libports/recipes/src/liblzma/content.mk +++ b/repos/libports/recipes/src/liblzma/content.mk @@ -8,7 +8,6 @@ include: src/lib/liblzma: mkdir -p $@ cp $(REP_DIR)/src/lib/liblzma/config.h $@ - echo "LIBS = liblzma" > $@/target.mk src/xz: mkdir -p $@ diff --git a/repos/libports/recipes/src/liblzma/hash b/repos/libports/recipes/src/liblzma/hash index fdbfc1b1c8..03b777390d 100644 --- a/repos/libports/recipes/src/liblzma/hash +++ b/repos/libports/recipes/src/liblzma/hash @@ -1 +1 @@ -2022-04-27 f67100f4556224963709ba6481878ab41c05aeb7 +2022-09-20 657a45131c8ce48b2e136eb7f6e3e92eddc8ee6b diff --git a/repos/libports/recipes/src/libpng/content.mk b/repos/libports/recipes/src/libpng/content.mk index 57bba3ed7d..934dce5c21 100644 --- a/repos/libports/recipes/src/libpng/content.mk +++ b/repos/libports/recipes/src/libpng/content.mk @@ -5,7 +5,6 @@ PORT_DIR := $(call port_dir,$(REP_DIR)/ports/libpng) src/lib/libpng: $(mirror_from_rep_dir) cp -r $(PORT_DIR)/src/lib/libpng/* $@ - echo "LIBS = libpng" > $@/target.mk lib/mk/libpng.mk lib/mk/libpng.inc lib/mk/spec/arm_v8/libpng.mk: $(mirror_from_rep_dir) diff --git a/repos/libports/recipes/src/libpng/hash b/repos/libports/recipes/src/libpng/hash index 482c8a8b17..c3d8f83dc4 100644 --- a/repos/libports/recipes/src/libpng/hash +++ b/repos/libports/recipes/src/libpng/hash @@ -1 +1 @@ -2022-04-27 b3762435831493ee008337f8d565e45c8949cbe1 +2022-09-20 844606386400336a4f72d4b5a6ddd7db5028da8f diff --git a/repos/libports/recipes/src/libqgenodeviewwidget/content.mk b/repos/libports/recipes/src/libqgenodeviewwidget/content.mk index 01dd2e58ce..2d90418a74 100644 --- a/repos/libports/recipes/src/libqgenodeviewwidget/content.mk +++ b/repos/libports/recipes/src/libqgenodeviewwidget/content.mk @@ -1,14 +1,10 @@ MIRROR_FROM_REP_DIR := lib/mk/libqgenodeviewwidget.mk \ src/lib/qgenodeviewwidget -content: $(MIRROR_FROM_REP_DIR) LICENSE src/lib/qgenodeviewwidget/target.mk +content: $(MIRROR_FROM_REP_DIR) LICENSE $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -src/lib/qgenodeviewwidget/target.mk: - mkdir -p $(dir $@) - echo "LIBS = libqgenodeviewwidget" > $@ - LICENSE: cp $(GENODE_DIR)/LICENSE $@ diff --git a/repos/libports/recipes/src/libqgenodeviewwidget/hash b/repos/libports/recipes/src/libqgenodeviewwidget/hash index f7d1aeeac1..45168a9998 100644 --- a/repos/libports/recipes/src/libqgenodeviewwidget/hash +++ b/repos/libports/recipes/src/libqgenodeviewwidget/hash @@ -1 +1 @@ -2022-05-24 37c4717f0d8a695fd56f1261ecc168bad10fe5e3 +2022-10-11 7d98fc5f71a4e471c599fc07ef7a031f2282954a diff --git a/repos/libports/recipes/src/libqpluginwidget/content.mk b/repos/libports/recipes/src/libqpluginwidget/content.mk index 181990123f..4ab0384681 100644 --- a/repos/libports/recipes/src/libqpluginwidget/content.mk +++ b/repos/libports/recipes/src/libqpluginwidget/content.mk @@ -1,14 +1,10 @@ MIRROR_FROM_REP_DIR := lib/mk/libqpluginwidget.mk \ src/lib/qpluginwidget -content: $(MIRROR_FROM_REP_DIR) LICENSE src/lib/qpluginwidget/target.mk +content: $(MIRROR_FROM_REP_DIR) LICENSE $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -src/lib/qpluginwidget/target.mk: - mkdir -p $(dir $@) - echo "LIBS = libqpluginwidget" > $@ - LICENSE: cp $(GENODE_DIR)/LICENSE $@ diff --git a/repos/libports/recipes/src/libqpluginwidget/hash b/repos/libports/recipes/src/libqpluginwidget/hash index 148014b56b..9cb491e3c2 100644 --- a/repos/libports/recipes/src/libqpluginwidget/hash +++ b/repos/libports/recipes/src/libqpluginwidget/hash @@ -1 +1 @@ -2022-05-24 327a85ec4a9708a232e7eda3d5896fa64589b4f0 +2022-10-11 5e56e0ce38b347524e091d6f9ca076d3c9097c6f diff --git a/repos/libports/recipes/src/libsparkcrypto/content.mk b/repos/libports/recipes/src/libsparkcrypto/content.mk index 0d3c22cdf9..859b2f4ff7 100644 --- a/repos/libports/recipes/src/libsparkcrypto/content.mk +++ b/repos/libports/recipes/src/libsparkcrypto/content.mk @@ -79,9 +79,3 @@ content: LICENSE LICENSE: echo "BSD-3-Clause-Attribution, see libsparkcrypto/README.rst" > $@ - -content: src/lib/libsparkcrypto/target.mk - -src/lib/libsparkcrypto/target.mk: - mkdir -p $(dir $@) - echo "LIBS = libsparkcrypto" > $@ diff --git a/repos/libports/recipes/src/libsparkcrypto/hash b/repos/libports/recipes/src/libsparkcrypto/hash index e1f21a8e84..e12ff0ed14 100644 --- a/repos/libports/recipes/src/libsparkcrypto/hash +++ b/repos/libports/recipes/src/libsparkcrypto/hash @@ -1 +1 @@ -2022-05-24 f2d05364d0db879f0cbf372ab0c88fb0b26f26dc +2022-10-11 646a27ce2aab9762af8d731948b58c1ff7ad751c diff --git a/repos/libports/recipes/src/libssh/content.mk b/repos/libports/recipes/src/libssh/content.mk index 013ef7a3da..cf215f29b9 100644 --- a/repos/libports/recipes/src/libssh/content.mk +++ b/repos/libports/recipes/src/libssh/content.mk @@ -1,4 +1,4 @@ -content: src/lib/libssh/target.mk lib/mk LICENSE +content: src/lib/libssh lib/mk LICENSE PORT_DIR := $(call port_dir,$(REP_DIR)/ports/libssh) @@ -7,9 +7,6 @@ src/lib/libssh: cp -r $(PORT_DIR)/src/lib/libssh/* $@ cp -r $(REP_DIR)/src/lib/libssh/config.h $@ -src/lib/libssh/target.mk: src/lib/libssh - echo "LIBS += libssh" > $@ - lib/mk: mkdir -p $@ cp $(REP_DIR)/lib/mk/libssh.mk $@ diff --git a/repos/libports/recipes/src/libssh/hash b/repos/libports/recipes/src/libssh/hash index 432cba24d2..d4ac9156dc 100644 --- a/repos/libports/recipes/src/libssh/hash +++ b/repos/libports/recipes/src/libssh/hash @@ -1 +1 @@ -2022-02-27 c3f794f683058386e890490b7d6ae8fca998579a +2022-09-20 55658b63d0770036d91d8db34fbae90d65a1d285 diff --git a/repos/libports/recipes/src/libusb/content.mk b/repos/libports/recipes/src/libusb/content.mk index 8e154f94e4..fe6121c7bd 100644 --- a/repos/libports/recipes/src/libusb/content.mk +++ b/repos/libports/recipes/src/libusb/content.mk @@ -10,7 +10,6 @@ PORT_DIR := $(call port_dir,$(REP_DIR)/ports/libusb) src/lib/libusb: mkdir -p $(dir $@) cp -r $(PORT_DIR)/src/lib/libusb $@ - echo "LIBS = libusb" > $@/target.mk $(mirror_from_rep_dir) $(MIRROR_FROM_REP_DIR): diff --git a/repos/libports/recipes/src/libusb/hash b/repos/libports/recipes/src/libusb/hash index 50b2fe39bc..cd1b5d5576 100644 --- a/repos/libports/recipes/src/libusb/hash +++ b/repos/libports/recipes/src/libusb/hash @@ -1 +1 @@ -2022-05-24 addbef0fb4d08fab9d5de50201f3932341eb6f1a +2022-10-11 03995e51617a0fabbc87101a9c222fd8cb08d304 diff --git a/repos/libports/recipes/src/libuvc/content.mk b/repos/libports/recipes/src/libuvc/content.mk index 1e97c7aa13..590045575e 100644 --- a/repos/libports/recipes/src/libuvc/content.mk +++ b/repos/libports/recipes/src/libuvc/content.mk @@ -8,7 +8,6 @@ src/lib/libuvc: mkdir -p $(dir $@) cp -r $(PORT_DIR)/src/lib/libuvc $@ rm -rf $@/.git - echo "LIBS = libuvc" > $@/target.mk include: mkdir -p $@ diff --git a/repos/libports/recipes/src/libuvc/hash b/repos/libports/recipes/src/libuvc/hash index 40f4894a92..d8abaf3769 100644 --- a/repos/libports/recipes/src/libuvc/hash +++ b/repos/libports/recipes/src/libuvc/hash @@ -1 +1 @@ -2022-02-27 bae978448ea062e8a26631abe9a2db7439e030d7 +2022-09-20 d338f6475fafa2a202a8259ddfbf1c9ad0bde31d diff --git a/repos/libports/recipes/src/libyuv/content.mk b/repos/libports/recipes/src/libyuv/content.mk index f4e76d4de5..9b83f440e6 100644 --- a/repos/libports/recipes/src/libyuv/content.mk +++ b/repos/libports/recipes/src/libyuv/content.mk @@ -11,13 +11,11 @@ PORT_DIR := $(call port_dir,$(REP_DIR)/ports/libyuv) src/lib/libyuv: mkdir -p $@ cp -r $(PORT_DIR)/src/lib/libyuv/source $@ - echo "LIBS = libyuv" > $@/target.mk include: mkdir -p $@ cp -a $(PORT_DIR)/include/* $@ - $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) diff --git a/repos/libports/recipes/src/libyuv/hash b/repos/libports/recipes/src/libyuv/hash index bc63fc4a3a..58b928f5cc 100644 --- a/repos/libports/recipes/src/libyuv/hash +++ b/repos/libports/recipes/src/libyuv/hash @@ -1 +1 @@ -2022-04-27 2cd47c7f60713e3c2bcd623a1fa8fe8259a902bb +2022-09-20 bf41103397fdfdbd5e460638b8617159747b634d diff --git a/repos/libports/recipes/src/mesa/content.mk b/repos/libports/recipes/src/mesa/content.mk index 95f4c16cad..355218e4bf 100644 --- a/repos/libports/recipes/src/mesa/content.mk +++ b/repos/libports/recipes/src/mesa/content.mk @@ -3,9 +3,7 @@ all: content MIRROR_FROM_REP_DIR := \ lib/mk/egl.mk \ - lib/mk/mesa_gpu-etnaviv.mk \ lib/mk/mesa_gpu-softpipe.mk \ - lib/mk/etnaviv.mk \ lib/mk/iris_gen.inc \ lib/mk/isl_gen.inc \ lib/mk/glapi.mk \ @@ -13,7 +11,11 @@ MIRROR_FROM_REP_DIR := \ lib/mk/mesa_api.mk \ lib/mk/mesa-common.inc \ lib/mk/softpipe.mk \ + lib/mk/spec/arm_v8/etnaviv.mk \ + lib/mk/spec/arm_v8/lima.mk \ lib/mk/spec/arm_v8/mesa.mk \ + lib/mk/spec/arm_v8/mesa_gpu-etnaviv.mk \ + lib/mk/spec/arm_v8/mesa_gpu-lima.mk \ lib/mk/spec/x86/mesa_gpu-iris.mk \ lib/mk/spec/x86/iris.mk \ lib/mk/spec/x86/iris_gen110.mk \ @@ -29,15 +31,11 @@ MIRROR_FROM_REP_DIR := \ lib/mk/spec/x86_64/mesa.mk \ src/lib/mesa -content: $(MIRROR_FROM_REP_DIR) src/lib/mesa/target.mk +content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -src/lib/mesa/target.mk: - mkdir -p $(dir $@) - echo "LIBS = mesa" > $@ - PORT_DIR := $(call port_dir,$(REP_DIR)/ports/mesa) MIRROR_FROM_PORT_DIR := src/lib/mesa/src generated diff --git a/repos/libports/recipes/src/mesa/hash b/repos/libports/recipes/src/mesa/hash index 5c84935abe..35e2aba98b 100644 --- a/repos/libports/recipes/src/mesa/hash +++ b/repos/libports/recipes/src/mesa/hash @@ -1 +1 @@ -2022-05-24 ec5e9fd76329cbfbb3cfa71fda6269dc1e9e3d6a +2022-10-11 80a21453436fce0ae3669a9e2b87a190c0631f67 diff --git a/repos/libports/recipes/src/mesa_gears/hash b/repos/libports/recipes/src/mesa_gears/hash index bc30fca0bd..696633fa93 100644 --- a/repos/libports/recipes/src/mesa_gears/hash +++ b/repos/libports/recipes/src/mesa_gears/hash @@ -1 +1 @@ -2022-05-24 6e47f102520274898f9ebf775155364179bf539e +2022-10-11 b84518c009820d3e8cf980cb318d1dc9c62a8c63 diff --git a/repos/libports/recipes/src/mupdf/content.mk b/repos/libports/recipes/src/mupdf/content.mk index 011a0d56a1..3c3d5dcbbf 100644 --- a/repos/libports/recipes/src/mupdf/content.mk +++ b/repos/libports/recipes/src/mupdf/content.mk @@ -5,7 +5,6 @@ PORT_DIR := $(call port_dir,$(REP_DIR)/ports/mupdf) src/lib/mupdf: mkdir -p $(dir $@) cp -r $(PORT_DIR)/src/lib/mupdf $@ - echo "LIBS = mupdf" > $@/target.mk lib/mk/%.mk: $(mirror_from_rep_dir) diff --git a/repos/libports/recipes/src/mupdf/hash b/repos/libports/recipes/src/mupdf/hash index 51ef99be63..2af03489ca 100644 --- a/repos/libports/recipes/src/mupdf/hash +++ b/repos/libports/recipes/src/mupdf/hash @@ -1 +1 @@ -2022-02-27 59f555ef24730583a787493b8d58c9836e71286c +2022-09-20 b23e9f4006299c420f3fdfacf841527ac24d63e9 diff --git a/repos/libports/recipes/src/ncurses/content.mk b/repos/libports/recipes/src/ncurses/content.mk index 5ef2e6d994..7107d4e485 100644 --- a/repos/libports/recipes/src/ncurses/content.mk +++ b/repos/libports/recipes/src/ncurses/content.mk @@ -5,7 +5,6 @@ PORT_DIR := $(call port_dir,$(REP_DIR)/ports/ncurses) src/lib/ncurses: mkdir -p $@ cp -r $(PORT_DIR)/src/lib/ncurses/* $@ - echo "LIBS = ncurses" > $@/target.mk lib/mk/ncurses.mk: $(mirror_from_rep_dir) diff --git a/repos/libports/recipes/src/ncurses/hash b/repos/libports/recipes/src/ncurses/hash index 2fa2d3efa9..cf7db41134 100644 --- a/repos/libports/recipes/src/ncurses/hash +++ b/repos/libports/recipes/src/ncurses/hash @@ -1 +1 @@ -2022-02-27 c7812b128b3d3c8cd9e27ac8ba91e189f19dae70 +2022-09-20 a326fde06a4c3de889c82aafc654d79bb5864d47 diff --git a/repos/libports/recipes/src/openjpeg/content.mk b/repos/libports/recipes/src/openjpeg/content.mk index 3c835333ba..b25b40cf66 100644 --- a/repos/libports/recipes/src/openjpeg/content.mk +++ b/repos/libports/recipes/src/openjpeg/content.mk @@ -5,7 +5,6 @@ PORT_DIR := $(call port_dir,$(REP_DIR)/ports/openjpeg) src/lib/openjpeg: mkdir -p $(dir $@) cp -r $(PORT_DIR)/src/lib/openjpeg $@ - echo "LIBS = openjpeg" > $@/target.mk lib/mk/%.mk: $(mirror_from_rep_dir) diff --git a/repos/libports/recipes/src/openjpeg/hash b/repos/libports/recipes/src/openjpeg/hash index ae27eed2ec..f23f210ceb 100644 --- a/repos/libports/recipes/src/openjpeg/hash +++ b/repos/libports/recipes/src/openjpeg/hash @@ -1 +1 @@ -2022-04-27 9cd976edbdb7c2350cf42aa92f69c1862a844b99 +2022-09-20 9ff601aceafac1b63c4fb079923b93e59d411979 diff --git a/repos/libports/recipes/src/openssl/content.mk b/repos/libports/recipes/src/openssl/content.mk index 7772fe0d7a..1f9ab3c2d0 100644 --- a/repos/libports/recipes/src/openssl/content.mk +++ b/repos/libports/recipes/src/openssl/content.mk @@ -11,12 +11,6 @@ content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -content: src/lib/openssl/target.mk - -src/lib/openssl/target.mk: src/lib/openssl - mkdir -p $(dir $@) - echo "LIBS += libcrypto libssl" > $@ - PORT_DIR := $(call port_dir,$(REP_DIR)/ports/openssl) content: src/lib/openssl diff --git a/repos/libports/recipes/src/openssl/hash b/repos/libports/recipes/src/openssl/hash index f3385dddc7..42f9121328 100644 --- a/repos/libports/recipes/src/openssl/hash +++ b/repos/libports/recipes/src/openssl/hash @@ -1 +1 @@ -2022-02-27 dead81c4adc98995bd57d60195091f4e418daa4d +2022-09-20 1f50428a4a36a39cda1186a6101bcfd2cc4192aa diff --git a/repos/libports/recipes/src/pcre/content.mk b/repos/libports/recipes/src/pcre/content.mk index dae4ed37b1..8432441459 100644 --- a/repos/libports/recipes/src/pcre/content.mk +++ b/repos/libports/recipes/src/pcre/content.mk @@ -6,7 +6,6 @@ src/lib/pcre: mkdir -p $@ cp -a $(PORT_DIR)/src/lib/pcre/* $@ cp -a $(REP_DIR)/src/lib/pcre/* $@ - echo "LIBS = pcre" > $@/target.mk lib/mk/pcre.mk: $(mirror_from_rep_dir) diff --git a/repos/libports/recipes/src/pcre/hash b/repos/libports/recipes/src/pcre/hash index 82aa27e38e..df4ccc6f57 100644 --- a/repos/libports/recipes/src/pcre/hash +++ b/repos/libports/recipes/src/pcre/hash @@ -1 +1 @@ -2022-05-24 f13e1c922e84419aefc9438cd0647366162e3220 +2022-09-20 c33bc2cf1d617362619763ecdfa47bd3b04ec024 diff --git a/repos/libports/recipes/src/pcre16/content.mk b/repos/libports/recipes/src/pcre16/content.mk index 3bd3eabc11..8c43d0699f 100644 --- a/repos/libports/recipes/src/pcre16/content.mk +++ b/repos/libports/recipes/src/pcre16/content.mk @@ -6,7 +6,6 @@ src/lib/pcre: mkdir -p $@ cp -a $(PORT_DIR)/src/lib/pcre/* $@ cp -a $(REP_DIR)/src/lib/pcre/* $@ - echo "LIBS = pcre16" > $@/target.mk lib/mk/pcre16.mk: $(mirror_from_rep_dir) diff --git a/repos/libports/recipes/src/pcre16/hash b/repos/libports/recipes/src/pcre16/hash index b0bacc5913..67f6e3c959 100644 --- a/repos/libports/recipes/src/pcre16/hash +++ b/repos/libports/recipes/src/pcre16/hash @@ -1 +1 @@ -2022-05-24 0f5ac6a0ebdb46269e5e04d7e5ee944166434da2 +2022-09-20 9012960553c3c4cf8cbcb96ef8f8b7222c465d9d diff --git a/repos/libports/recipes/src/pcsc-lite/api b/repos/libports/recipes/src/pcsc-lite/api new file mode 100644 index 0000000000..5d61c52aeb --- /dev/null +++ b/repos/libports/recipes/src/pcsc-lite/api @@ -0,0 +1 @@ +pcsc-lite diff --git a/repos/libports/recipes/src/pcsc-lite/content.mk b/repos/libports/recipes/src/pcsc-lite/content.mk new file mode 100644 index 0000000000..1569be42d8 --- /dev/null +++ b/repos/libports/recipes/src/pcsc-lite/content.mk @@ -0,0 +1,58 @@ +CCID_DIR := $(call port_dir,$(REP_DIR)/ports/ccid) +PCSC_DIR := $(call port_dir,$(REP_DIR)/ports/pcsc-lite) + +MIRROR_FROM_CCID_DIR := \ + $(shell \ + cd $(CCID_DIR); \ + find src/lib/ccid -type f | \ + grep -v "\.git") + +MIRROR_FROM_PCSC_DIR := \ + $(shell cd $(PCSC_DIR); find include -type f) \ + $(shell \ + cd $(PCSC_DIR); \ + find src/lib/pcsc-lite -type f | \ + grep -v "\.git") \ + +MIRROR_FROM_REP_DIR += \ + lib/mk/pcsc-lite.mk \ + lib/mk/ccid.mk \ + $(shell cd $(REP_DIR) && find src/lib/pcsc-lite -type f) \ + $(shell cd $(REP_DIR) && find src/lib/ccid -type f) + +MIRROR_FROM_CCID_DIR := \ + $(filter-out $(MIRROR_FROM_REP_DIR), $(MIRROR_FROM_CCID_DIR)) + +MIRROR_FROM_PCSC_DIR := \ + $(filter-out $(MIRROR_FROM_REP_DIR), $(MIRROR_FROM_PCSC_DIR)) + +content: $(MIRROR_FROM_CCID_DIR) + +$(MIRROR_FROM_CCID_DIR): + mkdir -p $(dir $@) + cp -r $(CCID_DIR)/$@ $(dir $@) + +content: $(MIRROR_FROM_PCSC_DIR) + +$(MIRROR_FROM_PCSC_DIR): + mkdir -p $(dir $@) + cp -r $(PCSC_DIR)/$@ $(dir $@) + +content: $(MIRROR_FROM_REP_DIR) + +$(MIRROR_FROM_REP_DIR): + $(mirror_from_rep_dir) + +content: LICENSE + +LICENSE: + echo "" >> $@ + echo "ccid library" >> $@ + echo "############" >> $@ + echo "" >> $@ + cat $(CCID_DIR)/src/lib/ccid/COPYING >> $@ + echo "" >> $@ + echo "pcsc-lite library" >> $@ + echo "#################" >> $@ + echo "" >> $@ + cat $(PCSC_DIR)/src/lib/pcsc-lite/COPYING >> $@ diff --git a/repos/libports/recipes/src/pcsc-lite/hash b/repos/libports/recipes/src/pcsc-lite/hash new file mode 100644 index 0000000000..707f62b207 --- /dev/null +++ b/repos/libports/recipes/src/pcsc-lite/hash @@ -0,0 +1 @@ +2022-10-11 3ee3a9bcd5b952cc1c56676ce651775250bc8af8 diff --git a/repos/libports/recipes/src/pcsc-lite/used_apis b/repos/libports/recipes/src/pcsc-lite/used_apis new file mode 100644 index 0000000000..92e540435e --- /dev/null +++ b/repos/libports/recipes/src/pcsc-lite/used_apis @@ -0,0 +1,3 @@ +base +libc +libusb diff --git a/repos/libports/recipes/src/pdf_view/hash b/repos/libports/recipes/src/pdf_view/hash index 17769d508a..750312ad0d 100644 --- a/repos/libports/recipes/src/pdf_view/hash +++ b/repos/libports/recipes/src/pdf_view/hash @@ -1 +1 @@ -2022-05-24 88a13fcf79c53a7b1f865f44c5d0941682440ae8 +2022-10-11 80b92e892bfefecca2b23476ed89656a475ed132 diff --git a/repos/libports/recipes/src/posix/content.mk b/repos/libports/recipes/src/posix/content.mk index 9c937d11e0..603dc50643 100644 --- a/repos/libports/recipes/src/posix/content.mk +++ b/repos/libports/recipes/src/posix/content.mk @@ -1,14 +1,10 @@ MIRROR_FROM_REP_DIR := lib/mk/posix.mk src/lib/posix -content: $(MIRROR_FROM_REP_DIR) LICENSE src/lib/posix/target.mk +content: $(MIRROR_FROM_REP_DIR) LICENSE $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -src/lib/posix/target.mk: - mkdir -p $(dir $@) - echo "LIBS = posix" > $@ - LICENSE: cp $(GENODE_DIR)/LICENSE $@ diff --git a/repos/libports/recipes/src/posix/hash b/repos/libports/recipes/src/posix/hash index 23dae929f8..fbdeb891ab 100644 --- a/repos/libports/recipes/src/posix/hash +++ b/repos/libports/recipes/src/posix/hash @@ -1 +1 @@ -2022-05-24 204d6518a60004cc5b2ef065e434d281520dd513 +2022-10-11 28d0e6f82eca5822b451f823ff7f7c5e402c95f1 diff --git a/repos/libports/recipes/src/qt5_base/content.mk b/repos/libports/recipes/src/qt5_base/content.mk index d6378a1e31..0bb6ccac65 100644 --- a/repos/libports/recipes/src/qt5_base/content.mk +++ b/repos/libports/recipes/src/qt5_base/content.mk @@ -1,14 +1,10 @@ MIRROR_FROM_REP_DIR := lib/mk/qt5_base.mk -content: $(MIRROR_FROM_REP_DIR) src/lib/qt5_base/target.mk +content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -src/lib/qt5_base/target.mk: - mkdir -p $(dir $@) - echo "LIBS = qt5_base" > $@ - PORT_DIR := $(call port_dir,$(REP_DIR)/ports/qt5) MIRROR_FROM_PORT_DIR := src/lib/qt5/qtbase diff --git a/repos/libports/recipes/src/qt5_base/hash b/repos/libports/recipes/src/qt5_base/hash index c2337bdff8..4895f3ff45 100644 --- a/repos/libports/recipes/src/qt5_base/hash +++ b/repos/libports/recipes/src/qt5_base/hash @@ -1 +1 @@ -2022-05-24 a3e77f5a876ec6b1593425f123e0a57c0b0ed5e1 +2022-10-11 d8a53fcab0988af397a33814d962f20c876a5e3b diff --git a/repos/libports/recipes/src/qt5_calculatorform/hash b/repos/libports/recipes/src/qt5_calculatorform/hash index 6ab325d688..9139a0d39e 100644 --- a/repos/libports/recipes/src/qt5_calculatorform/hash +++ b/repos/libports/recipes/src/qt5_calculatorform/hash @@ -1 +1 @@ -2022-05-24 91c63f8907dd6e7c5cba6d13e3aeacc64b213ef4 +2022-08-30 b44671ee2b979fdc7836c7e7bae6399e207214ca diff --git a/repos/libports/recipes/src/qt5_component/content.mk b/repos/libports/recipes/src/qt5_component/content.mk index b41763cbc8..27f492420c 100644 --- a/repos/libports/recipes/src/qt5_component/content.mk +++ b/repos/libports/recipes/src/qt5_component/content.mk @@ -1,15 +1,10 @@ MIRROR_FROM_REP_DIR := lib/mk/qt5_component.mk \ src/lib/qt5_component/qt_component.cc -content: $(MIRROR_FROM_REP_DIR) LICENSE src/lib/qt5_component/target.mk +content: $(MIRROR_FROM_REP_DIR) LICENSE $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -src/lib/qt5_component/target.mk: - mkdir -p $(dir $@) - echo "LIBS = qt5_component" > $@ - LICENSE: cp $(GENODE_DIR)/LICENSE $@ - diff --git a/repos/libports/recipes/src/qt5_component/hash b/repos/libports/recipes/src/qt5_component/hash index 81f31d2e50..8fbc39cda1 100644 --- a/repos/libports/recipes/src/qt5_component/hash +++ b/repos/libports/recipes/src/qt5_component/hash @@ -1 +1 @@ -2022-05-24 1f98f976e133bd14275da8530ba8629564c66945 +2022-10-11 2fadcbd4659e661b1cf1892dd98c372db00d65a1 diff --git a/repos/libports/recipes/src/qt5_declarative/content.mk b/repos/libports/recipes/src/qt5_declarative/content.mk index 53a9af087f..f741863ff0 100644 --- a/repos/libports/recipes/src/qt5_declarative/content.mk +++ b/repos/libports/recipes/src/qt5_declarative/content.mk @@ -1,14 +1,10 @@ MIRROR_FROM_REP_DIR := lib/mk/qt5_declarative.mk -content: $(MIRROR_FROM_REP_DIR) src/lib/qt5_declarative/target.mk +content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -src/lib/qt5_declarative/target.mk: - mkdir -p $(dir $@) - echo "LIBS = qt5_declarative" > $@ - PORT_DIR := $(call port_dir,$(REP_DIR)/ports/qt5) MIRROR_FROM_PORT_DIR := src/lib/qt5/qtdeclarative diff --git a/repos/libports/recipes/src/qt5_declarative/hash b/repos/libports/recipes/src/qt5_declarative/hash index 22af624391..7d3c28d59d 100644 --- a/repos/libports/recipes/src/qt5_declarative/hash +++ b/repos/libports/recipes/src/qt5_declarative/hash @@ -1 +1 @@ -2022-05-24 1195b1637935e2075f45203a0b1de4cde892a506 +2022-09-20 55e8fcd3ee409df0dbf9c2f5cd02778fe21b7e86 diff --git a/repos/libports/recipes/src/qt5_graphicaleffects/api b/repos/libports/recipes/src/qt5_graphicaleffects/api new file mode 100644 index 0000000000..7d275211d0 --- /dev/null +++ b/repos/libports/recipes/src/qt5_graphicaleffects/api @@ -0,0 +1 @@ +qt5 diff --git a/repos/libports/recipes/src/qt5_graphicaleffects/content.mk b/repos/libports/recipes/src/qt5_graphicaleffects/content.mk new file mode 100644 index 0000000000..45c9e4ab1a --- /dev/null +++ b/repos/libports/recipes/src/qt5_graphicaleffects/content.mk @@ -0,0 +1,21 @@ +MIRROR_FROM_REP_DIR := lib/mk/qt5_graphicaleffects.mk + +content: $(MIRROR_FROM_REP_DIR) + +$(MIRROR_FROM_REP_DIR): + $(mirror_from_rep_dir) + +PORT_DIR := $(call port_dir,$(REP_DIR)/ports/qt5) + +MIRROR_FROM_PORT_DIR := src/lib/qt5/qtgraphicaleffects + +content: $(MIRROR_FROM_PORT_DIR) + +$(MIRROR_FROM_PORT_DIR): + mkdir -p $(dir $@) + cp -r $(PORT_DIR)/$@ $(dir $@) + +content: LICENSE + +LICENSE: + cp $(PORT_DIR)/src/lib/qt5/LICENSE.LGPLv3 $@ diff --git a/repos/libports/recipes/src/qt5_graphicaleffects/hash b/repos/libports/recipes/src/qt5_graphicaleffects/hash new file mode 100644 index 0000000000..f78b9f2255 --- /dev/null +++ b/repos/libports/recipes/src/qt5_graphicaleffects/hash @@ -0,0 +1 @@ +2022-09-20 6cf72310c4eb2905e3efbe3adfec288433f2e934 diff --git a/repos/libports/recipes/src/qt5_graphicaleffects/used_apis b/repos/libports/recipes/src/qt5_graphicaleffects/used_apis new file mode 100644 index 0000000000..38a7553adb --- /dev/null +++ b/repos/libports/recipes/src/qt5_graphicaleffects/used_apis @@ -0,0 +1,4 @@ +libc +mesa +so +stdcxx diff --git a/repos/libports/recipes/src/qt5_launchpad/hash b/repos/libports/recipes/src/qt5_launchpad/hash index 0f8dc6eb42..ee224b7379 100644 --- a/repos/libports/recipes/src/qt5_launchpad/hash +++ b/repos/libports/recipes/src/qt5_launchpad/hash @@ -1 +1 @@ -2022-05-24 f2e59b4b05968da4209f9f694721a81623576404 +2022-10-11 d71a7793511c4289527cd5baf105448922b79402 diff --git a/repos/libports/recipes/src/qt5_openglwindow/hash b/repos/libports/recipes/src/qt5_openglwindow/hash index c2da47386e..bdc3974e9d 100644 --- a/repos/libports/recipes/src/qt5_openglwindow/hash +++ b/repos/libports/recipes/src/qt5_openglwindow/hash @@ -1 +1 @@ -2022-05-24 dea473c15f64558d2a969369c55a2aae65d13359 +2022-08-30 851f203cd6105315d2c2054183a8d9efcd3b43f8 diff --git a/repos/libports/recipes/src/qt5_quickcontrols/content.mk b/repos/libports/recipes/src/qt5_quickcontrols/content.mk index 37f5d15097..8cf841f090 100644 --- a/repos/libports/recipes/src/qt5_quickcontrols/content.mk +++ b/repos/libports/recipes/src/qt5_quickcontrols/content.mk @@ -1,14 +1,10 @@ MIRROR_FROM_REP_DIR := lib/mk/qt5_quickcontrols.mk -content: $(MIRROR_FROM_REP_DIR) src/lib/qt5_quickcontrols/target.mk +content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -src/lib/qt5_quickcontrols/target.mk: - mkdir -p $(dir $@) - echo "LIBS = qt5_quickcontrols" > $@ - PORT_DIR := $(call port_dir,$(REP_DIR)/ports/qt5) MIRROR_FROM_PORT_DIR := src/lib/qt5/qtquickcontrols diff --git a/repos/libports/recipes/src/qt5_quickcontrols/hash b/repos/libports/recipes/src/qt5_quickcontrols/hash index bc5838f990..d1f627e5d7 100644 --- a/repos/libports/recipes/src/qt5_quickcontrols/hash +++ b/repos/libports/recipes/src/qt5_quickcontrols/hash @@ -1 +1 @@ -2022-05-24 a85d9997ab8147234d764feae4d2c938ad4bd33e +2022-09-20 4fefc4a7c46449a25e150001b73bdb5f98e22c95 diff --git a/repos/libports/recipes/src/qt5_quickcontrols2/content.mk b/repos/libports/recipes/src/qt5_quickcontrols2/content.mk index 42f4ef72cf..8b764635f1 100644 --- a/repos/libports/recipes/src/qt5_quickcontrols2/content.mk +++ b/repos/libports/recipes/src/qt5_quickcontrols2/content.mk @@ -1,14 +1,10 @@ MIRROR_FROM_REP_DIR := lib/mk/qt5_quickcontrols2.mk -content: $(MIRROR_FROM_REP_DIR) src/lib/qt5_quickcontrols2/target.mk +content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -src/lib/qt5_quickcontrols2/target.mk: - mkdir -p $(dir $@) - echo "LIBS = qt5_quickcontrols2" > $@ - PORT_DIR := $(call port_dir,$(REP_DIR)/ports/qt5) MIRROR_FROM_PORT_DIR := src/lib/qt5/qtquickcontrols2 diff --git a/repos/libports/recipes/src/qt5_quickcontrols2/hash b/repos/libports/recipes/src/qt5_quickcontrols2/hash index 7c75027747..32cde01a3c 100644 --- a/repos/libports/recipes/src/qt5_quickcontrols2/hash +++ b/repos/libports/recipes/src/qt5_quickcontrols2/hash @@ -1 +1 @@ -2022-05-24 9986644b107b7c4db17e200ac1b675d9301faad2 +2022-10-11 a0e802568223e4fae71e7115bba3143d70e84c6b diff --git a/repos/libports/recipes/src/qt5_samegame/hash b/repos/libports/recipes/src/qt5_samegame/hash index e0da9c7ff9..64e481575e 100644 --- a/repos/libports/recipes/src/qt5_samegame/hash +++ b/repos/libports/recipes/src/qt5_samegame/hash @@ -1 +1 @@ -2022-05-24 a56002044cb824ef3cab27d6df88ce88e4a7b246 +2022-08-30 b9eceb7e1abf3b4ff2c8c510e237720e9ab6dfed diff --git a/repos/libports/recipes/src/qt5_svg/content.mk b/repos/libports/recipes/src/qt5_svg/content.mk index 0b1c104e9e..5eec4583c5 100644 --- a/repos/libports/recipes/src/qt5_svg/content.mk +++ b/repos/libports/recipes/src/qt5_svg/content.mk @@ -1,14 +1,10 @@ MIRROR_FROM_REP_DIR := lib/mk/qt5_svg.mk -content: $(MIRROR_FROM_REP_DIR) src/lib/qt5_svg/target.mk +content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -src/lib/qt5_svg/target.mk: - mkdir -p $(dir $@) - echo "LIBS = qt5_svg" > $@ - PORT_DIR := $(call port_dir,$(REP_DIR)/ports/qt5) MIRROR_FROM_PORT_DIR := src/lib/qt5/qtsvg diff --git a/repos/libports/recipes/src/qt5_svg/hash b/repos/libports/recipes/src/qt5_svg/hash index 15624eaa35..a5fa8477d3 100644 --- a/repos/libports/recipes/src/qt5_svg/hash +++ b/repos/libports/recipes/src/qt5_svg/hash @@ -1 +1 @@ -2022-05-24 e5c71d2c5bc7336b8a79021fcc376622aaf3221f +2022-10-11 51837b4dcdb04fc9e81d67051aec225cd00224bb diff --git a/repos/libports/recipes/src/qt5_testqstring/hash b/repos/libports/recipes/src/qt5_testqstring/hash index 6c3cab3b0e..ab5c83dd6e 100644 --- a/repos/libports/recipes/src/qt5_testqstring/hash +++ b/repos/libports/recipes/src/qt5_testqstring/hash @@ -1 +1 @@ -2022-05-24 b481f2969d7220678dadfb9e49d4d8caa3a5f11c +2022-08-30 33e6402a6faa06b35c92afc9342315093b201225 diff --git a/repos/libports/recipes/src/qt5_tetrix/hash b/repos/libports/recipes/src/qt5_tetrix/hash index 30c2f1a56b..68b3dfc984 100644 --- a/repos/libports/recipes/src/qt5_tetrix/hash +++ b/repos/libports/recipes/src/qt5_tetrix/hash @@ -1 +1 @@ -2022-05-24 806991c5e482295a3cecb703477d2160debdd062 +2022-08-30 cc1350a99df2aab2e7e17ffbb7d67314fce2fc84 diff --git a/repos/libports/recipes/src/qt5_textedit/hash b/repos/libports/recipes/src/qt5_textedit/hash index 717636819e..b19245a587 100644 --- a/repos/libports/recipes/src/qt5_textedit/hash +++ b/repos/libports/recipes/src/qt5_textedit/hash @@ -1 +1 @@ -2022-04-27 cc8cbc78c84e63b79b8d121e5f2032dc33cfe446 +2022-08-30 d6d0a086cd494b22d8cf2a7e05aeeb73060b09a0 diff --git a/repos/libports/recipes/src/qt5_virtualkeyboard/content.mk b/repos/libports/recipes/src/qt5_virtualkeyboard/content.mk index 329fceec80..3d77606630 100644 --- a/repos/libports/recipes/src/qt5_virtualkeyboard/content.mk +++ b/repos/libports/recipes/src/qt5_virtualkeyboard/content.mk @@ -1,14 +1,10 @@ MIRROR_FROM_REP_DIR := lib/mk/qt5_virtualkeyboard.mk -content: $(MIRROR_FROM_REP_DIR) src/lib/qt5_virtualkeyboard/target.mk +content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -src/lib/qt5_virtualkeyboard/target.mk: - mkdir -p $(dir $@) - echo "LIBS = qt5_virtualkeyboard" > $@ - PORT_DIR := $(call port_dir,$(REP_DIR)/ports/qt5) MIRROR_FROM_PORT_DIR := src/lib/qt5/qtvirtualkeyboard diff --git a/repos/libports/recipes/src/qt5_virtualkeyboard/hash b/repos/libports/recipes/src/qt5_virtualkeyboard/hash index 2bfa9cc2d1..36e3279481 100644 --- a/repos/libports/recipes/src/qt5_virtualkeyboard/hash +++ b/repos/libports/recipes/src/qt5_virtualkeyboard/hash @@ -1 +1 @@ -2022-05-24 147a4db76a7ab16317de549d1aae24a192ec8651 +2022-09-20 06964a1a05dc8fbb04c04bdbc975e770e316f183 diff --git a/repos/libports/recipes/src/qt5_virtualkeyboard_example/hash b/repos/libports/recipes/src/qt5_virtualkeyboard_example/hash index b1a0fc9e46..cc2a907ad9 100644 --- a/repos/libports/recipes/src/qt5_virtualkeyboard_example/hash +++ b/repos/libports/recipes/src/qt5_virtualkeyboard_example/hash @@ -1 +1 @@ -2022-05-24 13688d0459b06f7d5cd02d17013262055d0395a2 +2022-08-30 10a0c02f2d5e8cd608332d2a80bcd7d32627b098 diff --git a/repos/libports/recipes/src/sanitizer/content.mk b/repos/libports/recipes/src/sanitizer/content.mk index 6299fcce4f..bd902c5efa 100644 --- a/repos/libports/recipes/src/sanitizer/content.mk +++ b/repos/libports/recipes/src/sanitizer/content.mk @@ -13,7 +13,6 @@ PORT_DIR := $(call port_dir,$(REP_DIR)/ports/sanitizer) src/lib/sanitizer: mkdir -p $@ cp -r $(PORT_DIR)/src/lib/sanitizer/* $@ - echo "LIBS = libsanitizer_common libubsan" > $@/target.mk content: LICENSE diff --git a/repos/libports/recipes/src/sanitizer/hash b/repos/libports/recipes/src/sanitizer/hash index b88a18d310..fe0c5cdc91 100644 --- a/repos/libports/recipes/src/sanitizer/hash +++ b/repos/libports/recipes/src/sanitizer/hash @@ -1 +1 @@ -2022-05-24 b98ba7f58b9b87dbc019927934c7c4e2fcbd1d0a +2022-10-11 b58cf7feadf436304b142cf97d754d9c12ba15f7 diff --git a/repos/libports/recipes/src/spark/content.mk b/repos/libports/recipes/src/spark/content.mk index b1d2bdf9bf..1b079ab24b 100644 --- a/repos/libports/recipes/src/spark/content.mk +++ b/repos/libports/recipes/src/spark/content.mk @@ -71,9 +71,3 @@ content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) - -content: src/lib/spark/target.mk - -src/lib/spark/target.mk: - mkdir -p $(dir $@) - echo "LIBS = spark" > $@ diff --git a/repos/libports/recipes/src/spark/hash b/repos/libports/recipes/src/spark/hash index 9618c14cfd..fae8908f29 100644 --- a/repos/libports/recipes/src/spark/hash +++ b/repos/libports/recipes/src/spark/hash @@ -1 +1 @@ -2022-05-24 e1e466e518ae19920c18462e3a66ba4bf824591c +2022-10-11 82dec2574027d3de35cb3eccae8485693ba5a240 diff --git a/repos/libports/recipes/src/stdcxx/content.mk b/repos/libports/recipes/src/stdcxx/content.mk index 78d1e7c35f..38c840d8a3 100644 --- a/repos/libports/recipes/src/stdcxx/content.mk +++ b/repos/libports/recipes/src/stdcxx/content.mk @@ -4,14 +4,11 @@ MIRROR_FROM_REP_DIR := lib/mk/stdcxx-c++98.mk \ MIRROR_FROM_PORT_DIR := src/lib/stdcxx -content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_PORT_DIR) src/lib/stdcxx/target.mk +content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_PORT_DIR) $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -src/lib/stdcxx/target.mk: $(MIRROR_FROM_PORT_DIR) - echo "LIBS = stdcxx" > $@ - PORT_DIR := $(call port_dir,$(REP_DIR)/ports/stdcxx) $(MIRROR_FROM_PORT_DIR): diff --git a/repos/libports/recipes/src/stdcxx/hash b/repos/libports/recipes/src/stdcxx/hash index 47ff06d8a0..b331c7e1aa 100644 --- a/repos/libports/recipes/src/stdcxx/hash +++ b/repos/libports/recipes/src/stdcxx/hash @@ -1 +1 @@ -2022-07-04 f503ea018719d7b26808145f5b4bb8b7934dc6ec +2022-09-20 824f40cafadc0c65375f7cac6493a7929651d9a7 \ No newline at end of file diff --git a/repos/libports/recipes/src/stdin2out/hash b/repos/libports/recipes/src/stdin2out/hash index 2a4e2d29df..b95205be2d 100644 --- a/repos/libports/recipes/src/stdin2out/hash +++ b/repos/libports/recipes/src/stdin2out/hash @@ -1 +1 @@ -2022-02-27 791574e631168790f69211ed676e6e0b20fd67a6 +2022-08-30 8618b5f910007d008cdf1db4ac5ad610046ffc69 diff --git a/repos/libports/recipes/src/system_rtc/hash b/repos/libports/recipes/src/system_rtc/hash index 9886567c25..530dec7195 100644 --- a/repos/libports/recipes/src/system_rtc/hash +++ b/repos/libports/recipes/src/system_rtc/hash @@ -1 +1 @@ -2022-05-24 f19649677d866da951e8a8cfab69e5d5a3c191e1 +2022-10-11 c0be5474be58af327cb8b46af18996382c91f22f diff --git a/repos/libports/recipes/src/test-expat/hash b/repos/libports/recipes/src/test-expat/hash index 78faee5bba..9dc4e5ffcc 100644 --- a/repos/libports/recipes/src/test-expat/hash +++ b/repos/libports/recipes/src/test-expat/hash @@ -1 +1 @@ -2022-02-27 9b58990b45b440b4b94d959b14688269fb6bf1ac +2022-10-11 3453dad7cb7fede0194d97947cf95c3171732f74 diff --git a/repos/libports/recipes/src/test-ldso/hash b/repos/libports/recipes/src/test-ldso/hash index c96544661f..d7766ef8b3 100644 --- a/repos/libports/recipes/src/test-ldso/hash +++ b/repos/libports/recipes/src/test-ldso/hash @@ -1 +1 @@ -2022-05-24 1fecb5304a83289fa1f48a9f9f58f17b0ab07ed1 +2022-10-11 95c52dc593f10432df5414e202a600acfcf7ea92 diff --git a/repos/libports/recipes/src/test-libc/hash b/repos/libports/recipes/src/test-libc/hash index 6b3a7102ff..d37c53f12a 100644 --- a/repos/libports/recipes/src/test-libc/hash +++ b/repos/libports/recipes/src/test-libc/hash @@ -1 +1 @@ -2022-02-27 94284e930365ef6ce0f7ca0c28d4096f1799a39e +2022-09-20 d7e9e58cca32fff50f25f6c4d0e1539c770c2731 diff --git a/repos/libports/recipes/src/test-libc_connect/hash b/repos/libports/recipes/src/test-libc_connect/hash index fc2f55aa68..b3c042b80d 100644 --- a/repos/libports/recipes/src/test-libc_connect/hash +++ b/repos/libports/recipes/src/test-libc_connect/hash @@ -1 +1 @@ -2022-02-27 dce057a246f5d3e6047c0b1388cedbfe1175bbd4 +2022-08-30 721aade6ef3918b7f1678a888dd0e246ce613f6c diff --git a/repos/libports/recipes/src/test-libc_counter/hash b/repos/libports/recipes/src/test-libc_counter/hash index e45c5c87b0..6b24a1fc80 100644 --- a/repos/libports/recipes/src/test-libc_counter/hash +++ b/repos/libports/recipes/src/test-libc_counter/hash @@ -1 +1 @@ -2022-02-27 6ec9c14e9ce73ea9f9ce5a9fe48ed8554b33d586 +2022-08-30 fc3eb0626f9158e4d16960cad5508f41c84852cd diff --git a/repos/libports/recipes/src/test-libc_execve/hash b/repos/libports/recipes/src/test-libc_execve/hash index d497092e77..beea9bf5a3 100644 --- a/repos/libports/recipes/src/test-libc_execve/hash +++ b/repos/libports/recipes/src/test-libc_execve/hash @@ -1 +1 @@ -2022-02-27 423330be738f0ab9ff41d71d886bd5f706e5a9de +2022-08-30 604a34bd18457ad5f82c82a1e7c0d12104983c34 diff --git a/repos/libports/recipes/src/test-libc_fifo_pipe/hash b/repos/libports/recipes/src/test-libc_fifo_pipe/hash index 8b7221a048..dd8f022beb 100644 --- a/repos/libports/recipes/src/test-libc_fifo_pipe/hash +++ b/repos/libports/recipes/src/test-libc_fifo_pipe/hash @@ -1 +1 @@ -2022-05-24 2f576830f658f93b42aae51b0714f6de235abcae +2022-10-11 48434f5ed85d393949d3e387ed1446291de89efe diff --git a/repos/libports/recipes/src/test-libc_fork/hash b/repos/libports/recipes/src/test-libc_fork/hash index ab6f67d358..7bc56ed945 100644 --- a/repos/libports/recipes/src/test-libc_fork/hash +++ b/repos/libports/recipes/src/test-libc_fork/hash @@ -1 +1 @@ -2022-02-27 7439bd4f2fa0092ea95551c9dc17301954ec4d28 +2022-08-30 2f935eefc09c791fcf107c932145ac47e8d256d8 diff --git a/repos/libports/recipes/src/test-libc_getenv/hash b/repos/libports/recipes/src/test-libc_getenv/hash index bc7ab269b6..ca372b6f05 100644 --- a/repos/libports/recipes/src/test-libc_getenv/hash +++ b/repos/libports/recipes/src/test-libc_getenv/hash @@ -1 +1 @@ -2022-02-27 e4fbeae508dd5ba8711871cc920aba456b16f85e +2022-08-30 1309024893b556cf4ef8c8cb1bec807cf90ab136 diff --git a/repos/libports/recipes/src/test-libc_pipe/hash b/repos/libports/recipes/src/test-libc_pipe/hash index 2a86d9cd14..559d2280ca 100644 --- a/repos/libports/recipes/src/test-libc_pipe/hash +++ b/repos/libports/recipes/src/test-libc_pipe/hash @@ -1 +1 @@ -2022-02-27 67f7ef1f900f3a2845119986e2f833bd2a11990a +2022-08-30 6b40102c373fd2055891a034e0cce4bf719ba21b diff --git a/repos/libports/recipes/src/test-libc_vfs/hash b/repos/libports/recipes/src/test-libc_vfs/hash index 5ff878150f..59779b3029 100644 --- a/repos/libports/recipes/src/test-libc_vfs/hash +++ b/repos/libports/recipes/src/test-libc_vfs/hash @@ -1 +1 @@ -2022-05-24 8843fd557e655b7546fed12211d7aadb444db71a +2022-10-11 f56404d7b90c8918407a54700dcc4f8ed8b61e34 diff --git a/repos/libports/recipes/src/test-libc_vfs_block/hash b/repos/libports/recipes/src/test-libc_vfs_block/hash index 42ce55fe86..a425ca58bc 100644 --- a/repos/libports/recipes/src/test-libc_vfs_block/hash +++ b/repos/libports/recipes/src/test-libc_vfs_block/hash @@ -1 +1 @@ -2022-05-24 5325e7a056ae86ee5f6fa010fe8ab60205ae7614 +2022-10-11 8d10d9cc36ee0ac926306bb8bef583652ad8bdd5 diff --git a/repos/libports/recipes/src/test-netty/hash b/repos/libports/recipes/src/test-netty/hash index 7ef5cc10ee..0691a1d531 100644 --- a/repos/libports/recipes/src/test-netty/hash +++ b/repos/libports/recipes/src/test-netty/hash @@ -1 +1 @@ -2022-05-24 bcb1f8eb5c3f82f327ec79e3b077017bccd6b2e1 +2022-10-11 4a91a51af6e2dcd10147d7c518cb58d26927c4bd diff --git a/repos/libports/recipes/src/test-pthread/hash b/repos/libports/recipes/src/test-pthread/hash index feb5359201..59fb93c51e 100644 --- a/repos/libports/recipes/src/test-pthread/hash +++ b/repos/libports/recipes/src/test-pthread/hash @@ -1 +1 @@ -2022-05-24 98a9c312538f65ea05073eac8eda0dad0b95cd68 +2022-10-11 b57a6326cda95e2b2ea063ed52e67ce84f04cc1a diff --git a/repos/libports/recipes/src/test-qpluginwidget/hash b/repos/libports/recipes/src/test-qpluginwidget/hash index ccb2208db5..11ea581505 100644 --- a/repos/libports/recipes/src/test-qpluginwidget/hash +++ b/repos/libports/recipes/src/test-qpluginwidget/hash @@ -1 +1 @@ -2022-05-24 a1d49bbd776a1ca0d993ba032016b7fceba3c0ef +2022-10-11 a49ec21d38c46209ec91ca45ecb8e4ea01fdc3af diff --git a/repos/libports/recipes/src/test-qt_core/hash b/repos/libports/recipes/src/test-qt_core/hash index b62ab86db5..67739c2d19 100644 --- a/repos/libports/recipes/src/test-qt_core/hash +++ b/repos/libports/recipes/src/test-qt_core/hash @@ -1 +1 @@ -2022-05-24 4844bcab5ee8df3e2a9ab9a6bbcbb19152950621 +2022-08-30 e2c7f2e03c87f975a2bbd5237258d3b7c8669b74 diff --git a/repos/libports/recipes/src/test-qt_core_cmake/content.mk b/repos/libports/recipes/src/test-qt_core_cmake/content.mk new file mode 100644 index 0000000000..f2efe2974d --- /dev/null +++ b/repos/libports/recipes/src/test-qt_core_cmake/content.mk @@ -0,0 +1,10 @@ +MIRROR_FROM_REP_DIR := src/test/qt5/qt_core_cmake + +content: $(MIRROR_FROM_REP_DIR) LICENSE + +$(MIRROR_FROM_REP_DIR): + $(mirror_from_rep_dir) + +LICENSE: + cp $(GENODE_DIR)/LICENSE $@ + diff --git a/repos/libports/recipes/src/test-qt_core_cmake/hash b/repos/libports/recipes/src/test-qt_core_cmake/hash new file mode 100644 index 0000000000..237d5a9ea9 --- /dev/null +++ b/repos/libports/recipes/src/test-qt_core_cmake/hash @@ -0,0 +1 @@ +2022-08-30 9c6c12ef146561485ddf030a3e6627ed92145742 diff --git a/repos/libports/recipes/src/test-qt_core_cmake/used_apis b/repos/libports/recipes/src/test-qt_core_cmake/used_apis new file mode 100644 index 0000000000..7939ec008e --- /dev/null +++ b/repos/libports/recipes/src/test-qt_core_cmake/used_apis @@ -0,0 +1,5 @@ +libc +qt5 +qt5_component +so +stdcxx diff --git a/repos/libports/recipes/src/test-qt_quick/hash b/repos/libports/recipes/src/test-qt_quick/hash index 0fdbf56d13..0028c06d1f 100644 --- a/repos/libports/recipes/src/test-qt_quick/hash +++ b/repos/libports/recipes/src/test-qt_quick/hash @@ -1 +1 @@ -2022-05-24 7bfb359d0a97c6be8620b28bf5f019c18873d7b7 +2022-08-30 dd31841c322eb2117674fc19aab62f92ad0b2a12 diff --git a/repos/libports/recipes/src/test-spark/hash b/repos/libports/recipes/src/test-spark/hash index c1039b6943..51bca8ddb0 100644 --- a/repos/libports/recipes/src/test-spark/hash +++ b/repos/libports/recipes/src/test-spark/hash @@ -1 +1 @@ -2022-05-24 f6f19c5a38c21c9225f1cd27578f867520b8b34b +2022-10-11 074a982ea2a545ddfcf27b51455085b5f944d61b diff --git a/repos/libports/recipes/src/test-spark_exception/hash b/repos/libports/recipes/src/test-spark_exception/hash index bf86f18ee8..f30fb3eda8 100644 --- a/repos/libports/recipes/src/test-spark_exception/hash +++ b/repos/libports/recipes/src/test-spark_exception/hash @@ -1 +1 @@ -2022-05-24 f7f4567be392cbdfd52feba273d339ca9c404ceb +2022-10-11 e388164b9b47cd31543b8b1b66f13f59644446ff diff --git a/repos/libports/recipes/src/test-spark_secondary_stack/hash b/repos/libports/recipes/src/test-spark_secondary_stack/hash index 8fd2c066da..affb4af0e5 100644 --- a/repos/libports/recipes/src/test-spark_secondary_stack/hash +++ b/repos/libports/recipes/src/test-spark_secondary_stack/hash @@ -1 +1 @@ -2022-05-24 54137fabc25fe744833a82a1c1fb6ee459a68707 +2022-10-11 64d7c92796d4a3c1c04c10092a58b458ebade3b5 diff --git a/repos/libports/recipes/src/test-stdcxx/hash b/repos/libports/recipes/src/test-stdcxx/hash index 10fbdb3d0c..44c0675381 100644 --- a/repos/libports/recipes/src/test-stdcxx/hash +++ b/repos/libports/recipes/src/test-stdcxx/hash @@ -1 +1 @@ -2022-05-24 e4c349482fdfb081b4359d5f90b0c75c04832bdf +2022-08-30 635de877f0b8942d45ecf0939ddcfb7b0708c928 diff --git a/repos/libports/recipes/src/test-tcp/hash b/repos/libports/recipes/src/test-tcp/hash index fe26152b15..8bc3aedb06 100644 --- a/repos/libports/recipes/src/test-tcp/hash +++ b/repos/libports/recipes/src/test-tcp/hash @@ -1 +1 @@ -2022-05-24 8de1893617e35e2b9fe0f9b57924717b37cab979 +2022-10-11 611d06974faa2a15f658c7cb5f684e7c3a548cd5 diff --git a/repos/libports/recipes/src/usb_webcam/hash b/repos/libports/recipes/src/usb_webcam/hash index a63c382942..39f5e56858 100644 --- a/repos/libports/recipes/src/usb_webcam/hash +++ b/repos/libports/recipes/src/usb_webcam/hash @@ -1 +1 @@ -2022-05-24 b9fb7ef76601809f0740e130bbfcbda167841891 +2022-10-11 a8cc0dbcc7fc421c45af6400b9a566fb03c4f44e diff --git a/repos/libports/recipes/src/vesa_drv/hash b/repos/libports/recipes/src/vesa_drv/hash index 4ae52a0a33..146cbce7dd 100644 --- a/repos/libports/recipes/src/vesa_drv/hash +++ b/repos/libports/recipes/src/vesa_drv/hash @@ -1 +1 @@ -2022-05-24 4759829aaf07e57bef7152c9aeb7b91ab2e154c5 +2022-10-11 3746a88365ebfdcc6440d39be669e01903a2133a diff --git a/repos/libports/recipes/src/vfs_fatfs/hash b/repos/libports/recipes/src/vfs_fatfs/hash index 281f25213e..349cad888f 100644 --- a/repos/libports/recipes/src/vfs_fatfs/hash +++ b/repos/libports/recipes/src/vfs_fatfs/hash @@ -1 +1 @@ -2022-05-24 5c0aec951b3bd792d3676958980c708ae5e99b2e +2022-10-11 b8f687011ad5d750782a7ed6494e801b6c05176f diff --git a/repos/libports/recipes/src/vfs_jitterentropy/hash b/repos/libports/recipes/src/vfs_jitterentropy/hash index cb9184ce00..a35776ba74 100644 --- a/repos/libports/recipes/src/vfs_jitterentropy/hash +++ b/repos/libports/recipes/src/vfs_jitterentropy/hash @@ -1 +1 @@ -2022-05-24 047f1de625b1585ca24e316268cbf9bf117e7ef3 +2022-10-11 c948d2c7ce11bd5fed263570fe046e74eefe0e3c diff --git a/repos/libports/recipes/src/vfs_libusb/hash b/repos/libports/recipes/src/vfs_libusb/hash index 21ab440d71..e5409277c6 100644 --- a/repos/libports/recipes/src/vfs_libusb/hash +++ b/repos/libports/recipes/src/vfs_libusb/hash @@ -1 +1 @@ -2022-05-24 2d8d519fef0fcd9ff70507d269593e1559159051 +2022-10-11 5812aa31e5b4bcf3dfbe2e888424f4e39fa97436 diff --git a/repos/libports/recipes/src/vfs_libusb/used_apis b/repos/libports/recipes/src/vfs_libusb/used_apis index 5830357be3..41c5737b00 100644 --- a/repos/libports/recipes/src/vfs_libusb/used_apis +++ b/repos/libports/recipes/src/vfs_libusb/used_apis @@ -3,3 +3,4 @@ os so usb_session vfs +libusb diff --git a/repos/libports/recipes/src/vfs_lwip/hash b/repos/libports/recipes/src/vfs_lwip/hash index 5807d82656..60016f5697 100644 --- a/repos/libports/recipes/src/vfs_lwip/hash +++ b/repos/libports/recipes/src/vfs_lwip/hash @@ -1 +1 @@ -2022-05-24 8ad999ef6d6979532e1f8e083b80723b69712d4d +2022-10-11 280016dd3a9af5336d614c926c000aa2bffb52db diff --git a/repos/libports/recipes/src/vfs_oss/hash b/repos/libports/recipes/src/vfs_oss/hash index bccf686e6f..78b9aeaa36 100644 --- a/repos/libports/recipes/src/vfs_oss/hash +++ b/repos/libports/recipes/src/vfs_oss/hash @@ -1 +1 @@ -2022-05-24 f71fd0bf7bd69675d5ae8f1f19e2ba9bbf223631 +2022-10-11 de27f5f6110cbdcaa80364992e550ec92f646c49 diff --git a/repos/libports/recipes/src/zlib/content.mk b/repos/libports/recipes/src/zlib/content.mk index 6ae1a807aa..b200740119 100644 --- a/repos/libports/recipes/src/zlib/content.mk +++ b/repos/libports/recipes/src/zlib/content.mk @@ -5,7 +5,6 @@ PORT_DIR := $(call port_dir,$(REP_DIR)/ports/zlib) src/lib/zlib: mkdir -p $@ cp -r $(PORT_DIR)/src/lib/zlib/* $@ - echo "LIBS = zlib" > $@/target.mk lib/mk/zlib.mk: $(mirror_from_rep_dir) diff --git a/repos/libports/recipes/src/zlib/hash b/repos/libports/recipes/src/zlib/hash index fa8607ed61..c28bbde692 100644 --- a/repos/libports/recipes/src/zlib/hash +++ b/repos/libports/recipes/src/zlib/hash @@ -1 +1 @@ -2022-02-27 dd039e77c8e498cc9e5e2d92c8a6658b37d60c96 +2022-09-20 7dcd0c79c0ada0df3a5279207760e61e86367c2f diff --git a/repos/libports/run/acpica.run b/repos/libports/run/acpica.run index cf75822097..cd180a7290 100644 --- a/repos/libports/run/acpica.run +++ b/repos/libports/run/acpica.run @@ -9,47 +9,25 @@ if { set build_components { core init timer - drivers/ps2 - server/dynamic_rom - server/event_filter - server/report_rom + drivers/platform server/event_dump + app/pci_decode app/acpica app/acpi_event } -set use_acpica_as_acpi_drv 0 - -source ${genode_dir}/repos/base/run/platform_drv.inc - -if {!$use_acpica_as_acpi_drv} { - - # override default platform driver policy - proc platform_drv_policy {} { - return { - - } - } - - # add routing information - proc platform_drv_add_routing {} { - return { - } - } - - # override default config to react on 'acpi_ready' ROM change - proc platform_drv_config_config {} { - return { - } - } -} - -append_platform_drv_build_components - build $build_components create_boot_directory +import_from_depot [depot_user]/src/dynamic_rom \ + [depot_user]/src/event_filter \ + [depot_user]/src/pc_usb_host_drv \ + [depot_user]/src/ps2_drv \ + [depot_user]/src/rom_filter \ + [depot_user]/src/report_rom \ + [depot_user]/src/usb_hid_drv + set config { @@ -65,91 +43,80 @@ set config { - - + + - } + -append_if [expr !$use_acpica_as_acpi_drv] config { - - - + + + + + + + + + + + + + + + - - + - } + -append config { - - - - - - - - - - - - - - - - + + - + + + - } + -append config { - - - - - - - - - - - - - - - - - } - -append config { - - - - - - - - - + + + + + + + + + - - - - + + + + + - } + -append config { - + + + + + + + + + + + + + + + + + @@ -160,17 +127,93 @@ append config { - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - } + -append config { - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -178,9 +221,9 @@ append config { - - - + + + @@ -196,33 +239,74 @@ append config { - } + -append_platform_drv_config + + + + + + + + + + + + + -append config { - + } install_config $config +# non PCI devices for platform_drv, e.g. ps2/pit +file copy [select_from_repositories board/[board]/devices] [run_dir]/genode/devices + set boot_modules { - core init - ld.lib.so - timer - ps2_drv - event_filter - report_rom - dynamic_rom + core init ld.lib.so + timer platform_drv pci_decode acpi_drv acpica acpi_event event_dump } -append_platform_drv_boot_modules - build_boot_image $boot_modules append qemu_args "-nographic " run_genode_until {\[init -\> acpi.*SCI IRQ:.*\n} 30 + +if {![have_include "power_on/qemu"]} { + exit 0 +} + +set spawn_id $qemu_spawn_id + +sleep 1 + +# send Ctrl-a+c to enter Qemu's monitor mode +send "\x01\x63" + +# wait for monitor to become ready +run_genode_until {(qemu)} 20 $spawn_id + + +for {set i 0} {$i < 3} {incr i} { + + sleep 1 + send "system_powerdown\n" + run_genode_until {.*key count: 0.*} 3 $spawn_id +} + +puts "\nTest succeeded\n" +exit 0 diff --git a/repos/libports/run/extract.run b/repos/libports/run/extract.run index 699e69c553..3369bdc1c3 100644 --- a/repos/libports/run/extract.run +++ b/repos/libports/run/extract.run @@ -1,6 +1,6 @@ create_boot_directory -if {[get_cmd_switch --autopilot] && [have_board riscv_qemu]} { +if {[get_cmd_switch --autopilot] && [have_board virt_qemu_riscv]} { puts "Autopilot mode is not supported on this platform." exit 0 } diff --git a/repos/libports/run/fetchurl.inc b/repos/libports/run/fetchurl.inc index 1a218d36e0..c81d851462 100644 --- a/repos/libports/run/fetchurl.inc +++ b/repos/libports/run/fetchurl.inc @@ -10,7 +10,7 @@ if {[have_board rpi3] || [have_board imx53_qsb_tz]} { } if {[get_cmd_switch --autopilot] && ([have_board linux] || - [have_board riscv_qemu])} { + [have_board virt_qemu_riscv])} { puts "Autopilot mode is not supported on this platform." exit 0 } diff --git a/repos/libports/run/fs_rom_update_fat.run b/repos/libports/run/fs_rom_update_fat.run index a009d2863e..9ae4876ff9 100644 --- a/repos/libports/run/fs_rom_update_fat.run +++ b/repos/libports/run/fs_rom_update_fat.run @@ -5,8 +5,8 @@ set build_components { core init timer app/rom_logger app/rom_to_file - lib/vfs/fatfs - lib/vfs/import + lib/vfs_fatfs + lib/vfs_import server/dynamic_rom server/fs_rom server/vfs_block diff --git a/repos/libports/run/libc_block.run b/repos/libports/run/libc_block.run index 0bdb124524..1e46c7a2b7 100644 --- a/repos/libports/run/libc_block.run +++ b/repos/libports/run/libc_block.run @@ -8,7 +8,7 @@ create_boot_directory build { core init timer server/vfs_block - lib/vfs/import + lib/vfs_import test/libc_block } diff --git a/repos/libports/run/libc_select.run b/repos/libports/run/libc_select.run index bc56c3c30a..d27bdd8794 100644 --- a/repos/libports/run/libc_select.run +++ b/repos/libports/run/libc_select.run @@ -1,7 +1,7 @@ set build_components { core init timer server/terminal_crosslink test/libc_select test/libc_counter - lib/vfs/pipe + lib/vfs_pipe } build $build_components diff --git a/repos/libports/run/libc_vfs_fat.run b/repos/libports/run/libc_vfs_fat.run index 8ea6c53b83..a5c17123ec 100644 --- a/repos/libports/run/libc_vfs_fat.run +++ b/repos/libports/run/libc_vfs_fat.run @@ -1,7 +1,7 @@ set mkfs_cmd [installed_command mkfs.vfat] set mkfs_opts "-F32 -nlibc_vfs" -set test_build_components lib/vfs/fatfs +set test_build_components lib/vfs_fatfs set test_vfs_config "" set test_boot_modules vfs_fatfs.lib.so diff --git a/repos/libports/run/libc_vfs_filesystem_test.inc b/repos/libports/run/libc_vfs_filesystem_test.inc index c683027e16..48fab0b55c 100644 --- a/repos/libports/run/libc_vfs_filesystem_test.inc +++ b/repos/libports/run/libc_vfs_filesystem_test.inc @@ -68,7 +68,7 @@ set config { - + } append_if [have_include "power_on/qemu"] config { @@ -87,7 +87,7 @@ append config { - + @@ -104,7 +104,7 @@ append config { append_if $use_vfs_server config " - + diff --git a/repos/libports/run/libc_vfs_fs_fat.run b/repos/libports/run/libc_vfs_fs_fat.run index cbf12c61f3..f1ac461c1a 100644 --- a/repos/libports/run/libc_vfs_fs_fat.run +++ b/repos/libports/run/libc_vfs_fs_fat.run @@ -1,4 +1,4 @@ -if {[get_cmd_switch --autopilot] && [have_board riscv_qemu]} { +if {[get_cmd_switch --autopilot] && [have_board virt_qemu_riscv]} { puts "Autopilot mode is not supported on this platform." exit 0 } @@ -6,7 +6,7 @@ if {[get_cmd_switch --autopilot] && [have_board riscv_qemu]} { set mkfs_cmd [installed_command mkfs.vfat] set mkfs_opts "-F32 -nlibc_vfs" -set test_build_components lib/vfs/fatfs +set test_build_components lib/vfs_fatfs set test_vfs_config "" set test_boot_modules vfs_fatfs.lib.so diff --git a/repos/libports/run/libc_vfs_select.run b/repos/libports/run/libc_vfs_select.run index 83d12fd4f3..f7d6949688 100644 --- a/repos/libports/run/libc_vfs_select.run +++ b/repos/libports/run/libc_vfs_select.run @@ -1,7 +1,7 @@ set build_components { core init timer server/terminal_crosslink server/vfs test/libc_select test/libc_counter - lib/vfs/pipe + lib/vfs_pipe } build $build_components diff --git a/repos/libports/run/lwip.run b/repos/libports/run/lwip.run index 8881d41d53..144db0030c 100644 --- a/repos/libports/run/lwip.run +++ b/repos/libports/run/lwip.run @@ -25,7 +25,7 @@ if {[have_board linux] || [have_board rpi3]} { puts "\n Run script is not supported on this platform. \n"; exit 0 } -if {[get_cmd_switch --autopilot] && [have_board riscv_qemu]} { +if {[get_cmd_switch --autopilot] && [have_board virt_qemu_riscv]} { puts "Autopilot mode is not supported on this platform." exit 0 } diff --git a/repos/libports/run/lwip_lx.run b/repos/libports/run/lwip_lx.run index e0cdc92afa..723518b9fa 100644 --- a/repos/libports/run/lwip_lx.run +++ b/repos/libports/run/lwip_lx.run @@ -30,7 +30,7 @@ build { core init timer drivers/nic test/lwip/http_srv - lib/vfs/lwip + lib/vfs_lwip server/nic_router server/report_rom } diff --git a/repos/libports/run/mesa.inc b/repos/libports/run/mesa.inc index 5503fb0e97..43f7dc4b7c 100644 --- a/repos/libports/run/mesa.inc +++ b/repos/libports/run/mesa.inc @@ -26,12 +26,12 @@ import_from_depot $imports set build_components { drivers/gpu/intel - lib/mesa/softpipe + lib/mesa_softpipe core init timer } -lappend_if $use_iris build_components lib/mesa/iris -lappend_if $use_etnaviv build_components lib/mesa/etnaviv +lappend_if $use_iris build_components lib/mesa_iris +lappend_if $use_etnaviv build_components lib/mesa_etnaviv lappend_if $use_etnaviv build_components drivers/gpu/etnaviv lappend build_components $demo_component diff --git a/repos/libports/run/nic_bridge.run b/repos/libports/run/nic_bridge.run index 7aac8e2276..12b1f6199f 100644 --- a/repos/libports/run/nic_bridge.run +++ b/repos/libports/run/nic_bridge.run @@ -8,7 +8,7 @@ if {[have_board rpi3]} { exit 0 } -if {[get_cmd_switch --autopilot] && [have_board riscv_qemu]} { +if {[get_cmd_switch --autopilot] && [have_board virt_qemu_riscv]} { puts "Autopilot mode is not supported on this platform." exit 0 } diff --git a/repos/libports/run/nic_router.inc b/repos/libports/run/nic_router.inc index 6e0fd49dc9..d7db704bfb 100644 --- a/repos/libports/run/nic_router.inc +++ b/repos/libports/run/nic_router.inc @@ -1,11 +1,11 @@ -if {[get_cmd_switch --autopilot] && [have_board riscv_qemu]} { +if {[get_cmd_switch --autopilot] && [have_board virt_qemu_riscv]} { puts "Autopilot mode is not supported on this platform." exit 0 } set targets "core init timer server/nic_router server/nic_bridge test/lwip/http_srv test/lwip/http_clnt test/lwip/udp - server/nic_loopback lib/vfs/lwip " + server/nic_loopback lib/vfs_lwip " proc client_bin { prot } { if {$prot == "udp"} { return "test-lwip-udp-client" } diff --git a/repos/libports/run/oss.run b/repos/libports/run/oss.run index e41c34ac67..c6c070d4e7 100644 --- a/repos/libports/run/oss.run +++ b/repos/libports/run/oss.run @@ -11,7 +11,7 @@ if {[have_include "power_on/qemu"]} { set build_components { core init timer drivers/audio - lib/vfs/oss test/oss + lib/vfs_oss test/oss } source ${genode_dir}/repos/base/run/platform_drv.inc diff --git a/repos/libports/run/qt5.run b/repos/libports/run/qt5.run index b0d7998c16..7e4ba737fd 100644 --- a/repos/libports/run/qt5.run +++ b/repos/libports/run/qt5.run @@ -76,7 +76,9 @@ append config { - + + + diff --git a/repos/libports/run/qt5_core_cmake.run b/repos/libports/run/qt5_core_cmake.run new file mode 100644 index 0000000000..8d66fb09ef --- /dev/null +++ b/repos/libports/run/qt5_core_cmake.run @@ -0,0 +1,52 @@ +create_boot_directory + +import_from_depot [depot_user]/src/[base_src] \ + [depot_user]/src/init \ + [depot_user]/src/libc \ + [depot_user]/src/qt5_base \ + [depot_user]/src/qt5_component \ + [depot_user]/src/stdcxx \ + [depot_user]/src/vfs \ + [depot_user]/src/zlib \ + [depot_user]/src/test-qt_core_cmake + +install_config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +build_boot_image { } + +append qemu_args " -nographic " + +run_genode_until "Test done.*\n" 10 diff --git a/repos/libports/run/qt5_samegame.run b/repos/libports/run/qt5_samegame.run index a26569b1d3..a3e8e81722 100644 --- a/repos/libports/run/qt5_samegame.run +++ b/repos/libports/run/qt5_samegame.run @@ -23,7 +23,7 @@ append config { append config [qt5_start_nodes] append config { - + diff --git a/repos/libports/run/qt5_virtualkeyboard.run b/repos/libports/run/qt5_virtualkeyboard.run index 85f846b842..53018d533d 100644 --- a/repos/libports/run/qt5_virtualkeyboard.run +++ b/repos/libports/run/qt5_virtualkeyboard.run @@ -25,7 +25,7 @@ append config { append config [qt5_start_nodes] append config { - + diff --git a/repos/libports/run/smartcard.run b/repos/libports/run/smartcard.run index cfa92347f7..27df436400 100644 --- a/repos/libports/run/smartcard.run +++ b/repos/libports/run/smartcard.run @@ -22,26 +22,14 @@ proc smartcard_product_id {} { return "0x5116" } # Build # -set build_components { - core init timer - drivers/usb_host - test/smartcard - lib/vfs/libusb - lib/vfs/pipe -} - -source ${genode_dir}/repos/base/run/platform_drv.inc -append_platform_drv_build_components - -build $build_components - create_boot_directory +import_from_depot [depot_user]/src/[base_src] \ + [depot_user]/pkg/test_usb_host_drv-[board] \ + [depot_user]/src/report_rom \ + [depot_user]/src/init +build { test/smartcard lib/vfs_libusb lib/vfs_pipe } -# -# Generate config -# - -append config { +install_config { @@ -56,35 +44,34 @@ append config { - } + -append_platform_drv_config - -append config { + - - - - - - - - - - - - + + + + + + + + + + + + + - + + @@ -110,26 +97,25 @@ append config { } -install_config $config - # -# Boot modules +# Define USB host controller config # +append usb_config { + + + +} +set fd [open [run_dir]/genode/usb_host_drv.config w] +puts $fd $usb_config +close $fd -# generic modules -set boot_modules { - core init timer test-smartcard +build_boot_image { + test-smartcard ld.lib.so pcsc-lite.lib.so ccid.lib.so libusb.lib.so libc.lib.so vfs.lib.so libm.lib.so posix.lib.so Info.plist vfs_libusb.lib.so vfs_pipe.lib.so } -lappend boot_modules [usb_host_drv_binary] - -append_platform_drv_boot_modules - -build_boot_image $boot_modules - run_genode_until { Response: 62 0A 82 01 38 83 02 3F 00 8A 01 05 90 00} 30 exec rm bin/Info.plist diff --git a/repos/libports/run/system_rtc.run b/repos/libports/run/system_rtc.run index e817b9b566..15e1029987 100644 --- a/repos/libports/run/system_rtc.run +++ b/repos/libports/run/system_rtc.run @@ -89,10 +89,9 @@ set config { install_config $config set build_components { test/system_rtc test/libc_rtc } -set boot_components { test-system_rtc test-libc_rtc } build $build_components -build_boot_image $boot_components +build_boot_image [build_artifacts] append qemu_args " -nographic " diff --git a/repos/libports/run/vfs_lwip.inc b/repos/libports/run/vfs_lwip.inc index c972685d63..dfcd3b9acc 100644 --- a/repos/libports/run/vfs_lwip.inc +++ b/repos/libports/run/vfs_lwip.inc @@ -1,6 +1,6 @@ proc append_socket_fs_build_components { } { global build_components - append build_components { lib/vfs/lwip } + append build_components { lib/vfs_lwip } } proc socket_fs_plugin {} { return lwip } diff --git a/repos/libports/run/webcam.inc b/repos/libports/run/webcam.inc index e0d90fc2b1..bd74817677 100644 --- a/repos/libports/run/webcam.inc +++ b/repos/libports/run/webcam.inc @@ -40,7 +40,7 @@ build $build_components append config { - + @@ -110,33 +110,38 @@ append config { - - - } -append config $test_vfs_config -append config { - - - - - - - - - - + - + - - - - - + + + + + + + + + + + + + } +append config $test_vfs_config +append config { + + + + + + + + + @@ -146,20 +151,21 @@ append config { - - - - - - + + + - - - + + + + + + + - + diff --git a/repos/libports/src/app/acpica/README b/repos/libports/src/app/acpica/README index ec0129edd7..5c654b8d53 100644 --- a/repos/libports/src/app/acpica/README +++ b/repos/libports/src/app/acpica/README @@ -27,15 +27,6 @@ changes of the 'state' attribute: ! -Additionally, if the config attributes 'acpi_ready' is set to yes, the -application generates a reports named 'acpi_ready' and set the state to - -! - -after finishing the ACPI bring up. This is used by platform_drv to finally -announce the Platform session, so that drivers can start after acpica has -finished. - If the ROM changes to 'state="reset"' the application tries to reset the machine immediately. If the ROM changes to 'state="poweroff"' the application tries to poweroff @@ -45,22 +36,9 @@ The attempt to reset or to poweroff may fail. One reason, we have seen so far, is that the required resources are already owned by other components in the system. -Furthermore the ACPICA library triggers depended on the ACPI table content -I/O operations on various PCI devices and partly re-configure it. Because of -this a policy rule at the platform driver is required, that permits access -to the required devices. - -Acpica as acpi_drv replacement ------------------------------- - -The application acpica may also be run as replacement of the original acpi_drv -when the 'act_as_acpi_drv' attribute is set to yes: - -! - -The acpica driver will parse in this mode the ACPI tables and will generate -the same content in the ACPI report, which is transformed by a report_rom -service into a ACPI ROM expected initially by the platform driver. +Furthermore the ACPICA library may trigger, dependent on the ACPI ASL code, +various I/O port and I/O mem accesses to hardware. Accesses to PCI devices are +ignored and dropped by this component. Excerpt of important parts of the acpica configuration ------------------------------------------------------ @@ -68,7 +46,7 @@ Excerpt of important parts of the acpica configuration ! ! ! ... -! +! ! ! ! diff --git a/repos/libports/src/app/acpica/bridge.h b/repos/libports/src/app/acpica/bridge.h deleted file mode 100644 index 7bea7fbe9f..0000000000 --- a/repos/libports/src/app/acpica/bridge.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * \brief Handle PCI Root bridge - * \author Alexander Boettcher - * - */ - -/* - * Copyright (C) 2018 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. - */ - -class Bridge { - - private: - - ACPI_HANDLE _bridge; - - unsigned bdf_bridge(ACPI_HANDLE bridge) - { - /* address (high word = device, low word = function) (6.1.1) */ - unsigned bridge_adr = 0; - /* Base bus number (6.5.5) */ - unsigned bridge_bbn = 0; - /* Segment object located under host bridge (6.5.6) */ - unsigned bridge_seg = 0; - - Acpica::Buffer adr; - ACPI_STATUS res = AcpiEvaluateObjectTyped(bridge, - ACPI_STRING("_ADR"), - nullptr, &adr, - ACPI_TYPE_INTEGER); - - if (res != AE_OK) { - Genode::error("could not detect address of bridge - ", res); - return 0; - } else - bridge_adr = adr.object.Integer.Value; - - Acpica::Buffer bbn; - res = AcpiEvaluateObjectTyped(bridge, ACPI_STRING("_BBN"), - nullptr, &bbn, ACPI_TYPE_INTEGER); - if (res != AE_OK) { - Genode::warning("_BBN missing for bridge"); - } else - bridge_bbn = bbn.object.Integer.Value; - - Acpica::Buffer seg; - res = AcpiEvaluateObjectTyped(bridge, ACPI_STRING("_SEG"), - nullptr, &seg, ACPI_TYPE_INTEGER); - - /* according to ACPI spec assume segment 0 if method unavailable */ - if (res == AE_OK) - bridge_seg = seg.object.Integer.Value; - - unsigned const bridge_bdf = ((0xffffU & bridge_seg) << 16) | - ((0x00ffU & bridge_bbn) << 8) | - (0xffU & ((bridge_adr >> 16) << 3)) | - (bridge_adr & 0x7); - - return bridge_bdf; - } - - void _gen_bridge(ACPI_HANDLE bridge, Genode::Xml_generator &xml, - unsigned const bridge_bdf) - { - Acpica::Buffer irqs; - ACPI_STATUS res = AcpiGetIrqRoutingTable (bridge, &irqs); - if (res != AE_OK) { - Genode::error("buffer for PCI IRQ routing information to " - "small - ", irqs.Length, " required"); - return; - } - - ACPI_PCI_ROUTING_TABLE *s = reinterpret_cast(irqs.Pointer); - ACPI_PCI_ROUTING_TABLE *e = reinterpret_cast(reinterpret_cast(&irqs) + irqs.Length); - for (ACPI_PCI_ROUTING_TABLE *c = s; c < e && c->Length; ) { - - using Genode::Hex; - using Genode::String; - - xml.node("routing", [&] () { - xml.attribute("gsi", String<16>(Hex(c->SourceIndex))); - xml.attribute("bridge_bdf", String<16>(Hex(bridge_bdf))); - xml.attribute("device", String<16>(Hex((c->Address >> 16) & 0x1f))); - xml.attribute("device_pin", String<16>(Hex(c->Pin))); - }); - - c = reinterpret_cast(reinterpret_cast(c) + c->Length); - } - } - - void _sub_bridges(ACPI_HANDLE handle, Genode::Xml_generator &xml) - { - ACPI_STATUS res = AcpiEvaluateObject(handle, ACPI_STRING("_PRT"), - nullptr, nullptr); - - if (res != AE_OK) - return; - - /* got another bridge, generate irq routing information to xml */ - Bridge::_gen_bridge(handle, xml, bdf_bridge(handle)); - - ACPI_HANDLE child = nullptr; - - /* lookup next bridge behind the bridge */ - while (AE_OK == (res = AcpiGetNextObject(ACPI_TYPE_DEVICE, handle, - child, &child))) - { - _sub_bridges(child, xml); - } - } - - public: - - Bridge(void *, ACPI_HANDLE bridge) - : - _bridge(bridge) - { } - - static ACPI_STATUS detect(ACPI_HANDLE bridge, UINT32, void * m, - void **return_bridge); - - void generate(Genode::Xml_generator &xml) - { - unsigned const root_bridge_bdf = bdf_bridge(_bridge); - - xml.node("root_bridge", [&] () { - xml.attribute("bdf", Genode::String<8>(Genode::Hex(root_bridge_bdf))); - }); - - /* irq routing information of this (pci root) bridge */ - _gen_bridge(_bridge, xml, root_bridge_bdf); - - /* lookup all pci-to-pci bridges and add irq routing information */ - _sub_bridges(_bridge, xml); - } -}; diff --git a/repos/libports/src/app/acpica/ec.h b/repos/libports/src/app/acpica/ec.h index dfb42406a4..173568cbac 100644 --- a/repos/libports/src/app/acpica/ec.h +++ b/repos/libports/src/app/acpica/ec.h @@ -81,7 +81,7 @@ class Ec : Acpica::Callback { State::access_t state = ec->ec_cmdsta->inb(ec->ec_port_cmdsta); if (!State::Sci_evt::get(state)) { - Genode::error("unknown status ", Genode::Hex(state)); + Genode::error("unknown status ", Genode::Hex(state)); return ACPI_REENABLE_GPE; /* gpe is acked and re-enabled */ } diff --git a/repos/libports/src/app/acpica/os.cc b/repos/libports/src/app/acpica/os.cc index aade55f8a8..0a576a90a5 100644 --- a/repos/libports/src/app/acpica/os.cc +++ b/repos/libports/src/app/acpica/os.cc @@ -116,11 +116,14 @@ struct Acpica::Main static struct Irq_handler { UINT32 irq; + Genode::Irq_session::Trigger trigger; + Genode::Irq_session::Polarity polarity; + ACPI_OSD_HANDLER handler; void *context; } irq_handler; - void init_acpica(Acpica::Wait_acpi_ready, Acpica::Act_as_acpi_drv); + void init_acpica(); Main(Genode::Env &env) : @@ -131,14 +134,11 @@ struct Acpica::Main bool const enable_reset = config.xml().attribute_value("reset", false); bool const enable_poweroff = config.xml().attribute_value("poweroff", false); bool const enable_report = config.xml().attribute_value("report", false); - bool const enable_ready = config.xml().attribute_value("acpi_ready", false); - bool const act_as_acpi_drv = config.xml().attribute_value("act_as_acpi_drv", false); if (enable_report) report = new (heap) Acpica::Reportstate(env); - init_acpica(Wait_acpi_ready{enable_ready}, - Act_as_acpi_drv{act_as_acpi_drv}); + init_acpica(); if (enable_report) report->enable(); @@ -152,22 +152,13 @@ struct Acpica::Main return; } - sci_conn.construct(env, irq_handler.irq); + sci_conn.construct(env, irq_handler.irq, irq_handler.trigger, irq_handler.polarity); - Genode::log("SCI IRQ: ", irq_handler.irq); + Genode::log("SCI IRQ: ", irq_handler.irq, + " (", irq_handler.trigger, "-", irq_handler.polarity, ")"); sci_conn->sigh(sci_irq); sci_conn->ack_irq(); - - if (!enable_ready) - return; - - /* we are ready - signal it via changing system state */ - static Genode::Reporter _system_rom(env, "system", "acpi_ready"); - _system_rom.enabled(true); - Genode::Reporter::Xml_generator xml(_system_rom, [&] () { - xml.attribute("state", "acpi_ready"); - }); } void acpi_irq() @@ -209,7 +200,6 @@ struct Acpica::Main #include "lid.h" #include "sb.h" #include "ec.h" -#include "bridge.h" #include "fujitsu.h" ACPI_STATUS init_pic_mode() @@ -229,26 +219,10 @@ ACPI_STATUS init_pic_mode() &arguments, nullptr); } -ACPI_STATUS Bridge::detect(ACPI_HANDLE bridge, UINT32, void * m, - void **return_bridge) + +void Acpica::Main::init_acpica() { - Acpica::Main * main = reinterpret_cast(m); - Bridge * dev_obj = new (main->heap) Bridge(main->report, bridge); - - if (*return_bridge == (void *)PCI_ROOT_HID_STRING) - Genode::log("detected - bridge - PCI root bridge"); - if (*return_bridge == (void *)PCI_EXPRESS_ROOT_HID_STRING) - Genode::log("detected - bridge - PCIE root bridge"); - - *return_bridge = dev_obj; - - return AE_OK; -} - -void Acpica::Main::init_acpica(Wait_acpi_ready wait_acpi_ready, - Act_as_acpi_drv act_as_acpi_drv) -{ - Acpica::init(env, heap, wait_acpi_ready, act_as_acpi_drv); + Acpica::init(env, heap); /* enable debugging: */ if (false) { @@ -276,6 +250,67 @@ void Acpica::Main::init_acpica(Wait_acpi_ready wait_acpi_ready, return; } + { + using Genode::Irq_session; + + /* + * ACPI Spec 2.1 General ACPI Terminology + * + * System Control Interrupt (SCI) A system interrupt used by hardware + * to notify the OS of ACPI events. The SCI is an active, low, + * shareable, level interrupt. + */ + irq_handler.irq = AcpiGbl_FADT.SciInterrupt; + irq_handler.trigger = Irq_session::TRIGGER_LEVEL; + irq_handler.polarity = Irq_session::POLARITY_LOW; + + /* apply potential override in MADT */ + ACPI_TABLE_MADT *madt = nullptr; + + ACPI_STATUS status = AcpiGetTable(ACPI_STRING(ACPI_SIG_MADT), 0, (ACPI_TABLE_HEADER **)&madt); + if (status == AE_OK) { + using Genode::String; + + for_each_element(madt, (ACPI_SUBTABLE_HEADER *) nullptr, + [&](ACPI_SUBTABLE_HEADER const * const s) { + + if (s->Type != ACPI_MADT_TYPE_INTERRUPT_OVERRIDE) + return; + + ACPI_MADT_INTERRUPT_OVERRIDE const * const irq = + reinterpret_cast(s); + + auto polarity_from_flags = [] (UINT16 flags) { + switch (flags & 0b11) { + case 0b01: return Irq_session::POLARITY_HIGH; + case 0b11: return Irq_session::POLARITY_LOW; + case 0b00: + default: + return Irq_session::POLARITY_UNCHANGED; + } + }; + + auto trigger_from_flags = [] (UINT16 flags) { + switch ((flags & 0b1100) >> 2) { + case 0b01: return Irq_session::TRIGGER_EDGE; + case 0b11: return Irq_session::TRIGGER_LEVEL; + case 0b00: + default: + return Irq_session::TRIGGER_UNCHANGED; + } + }; + + if (irq->SourceIrq == AcpiGbl_FADT.SciInterrupt) { + irq_handler.irq = irq->GlobalIrq; + irq_handler.trigger = trigger_from_flags(irq->IntiFlags); + irq_handler.polarity = polarity_from_flags(irq->IntiFlags); + + AcpiGbl_FADT.SciInterrupt = irq->GlobalIrq; + } + }, [](ACPI_SUBTABLE_HEADER const * const s) { return s->Length; }); + } + } + status = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION); if (status != AE_OK) { Genode::error("AcpiEnableSubsystem failed, status=", status); @@ -363,35 +398,6 @@ void Acpica::Main::init_acpica(Wait_acpi_ready wait_acpi_ready, Genode::error("AcpiGetDevices (FUJ02E3) failed, status=", status); return; } - - if (act_as_acpi_drv.enabled) { - /* lookup PCI root bridge */ - void * pci_bridge = (void *)PCI_ROOT_HID_STRING; - status = AcpiGetDevices(ACPI_STRING(PCI_ROOT_HID_STRING), Bridge::detect, - this, &pci_bridge); - if (status != AE_OK || pci_bridge == (void *)PCI_ROOT_HID_STRING) - pci_bridge = nullptr; - - /* lookup PCI Express root bridge */ - void * pcie_bridge = (void *)PCI_EXPRESS_ROOT_HID_STRING; - status = AcpiGetDevices(ACPI_STRING(PCI_EXPRESS_ROOT_HID_STRING), - Bridge::detect, this, &pcie_bridge); - if (status != AE_OK || pcie_bridge == (void *)PCI_EXPRESS_ROOT_HID_STRING) - pcie_bridge = nullptr; - - if (pcie_bridge && pci_bridge) - Genode::log("PCI and PCIE root bridge found - using PCIE for IRQ " - "routing information"); - - Bridge *bridge = pcie_bridge ? reinterpret_cast(pcie_bridge) - : reinterpret_cast(pci_bridge); - - /* Generate report for platform driver */ - Acpica::generate_report(env, bridge); - } - - /* Tell PCI backend to use platform_drv for PCI device access from now on */ - Acpica::use_platform_drv(); } @@ -401,7 +407,12 @@ struct Acpica::Main::Irq_handler Acpica::Main::irq_handler; ACPI_STATUS AcpiOsInstallInterruptHandler(UINT32 irq, ACPI_OSD_HANDLER handler, void *context) { - Acpica::Main::irq_handler.irq = irq; + if (irq != Acpica::Main::irq_handler.irq) { + Genode::error("SCI interrupt is ", Acpica::Main::irq_handler.irq, + " but library requested ", irq); + return AE_BAD_PARAMETER; + } + Acpica::Main::irq_handler.handler = handler; Acpica::Main::irq_handler.context = context; return AE_OK; diff --git a/repos/libports/src/app/acpica/report.cc b/repos/libports/src/app/acpica/report.cc deleted file mode 100644 index b737d155e6..0000000000 --- a/repos/libports/src/app/acpica/report.cc +++ /dev/null @@ -1,183 +0,0 @@ -/* - * \brief Generate XML report - * \author Alexander Boettcher - */ - -/* - * Copyright (C) 2018 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. - */ - -#include -#include - -#include "util.h" -#include "bridge.h" - -using Genode::Reporter; - -extern void AcpiGenodeFreeIOMem(ACPI_PHYSICAL_ADDRESS const phys, ACPI_SIZE const size); - -template -void for_each_element(H const head, S *, F const &fn, FSIZE const &fn_size) -{ - for(S const * e = reinterpret_cast(head + 1); - e < reinterpret_cast(reinterpret_cast(head) + head->Header.Length); - e = reinterpret_cast(reinterpret_cast(e) + fn_size(e))) - { - fn(e); - } -} - -static void add_madt(ACPI_TABLE_MADT const * const madt, - Reporter::Xml_generator &xml) -{ - typedef ACPI_SUBTABLE_HEADER Madt_sub; - - using Genode::String; - - for_each_element(madt, (Madt_sub *) nullptr, [&](Madt_sub const * const s) { - - if (s->Type != ACPI_MADT_TYPE_INTERRUPT_OVERRIDE) - return; - - typedef ACPI_MADT_INTERRUPT_OVERRIDE Irq; - Irq const * const irq = reinterpret_cast(s); - - xml.node("irq_override", [&] () { - xml.attribute("irq", irq->SourceIrq); - xml.attribute("gsi", irq->GlobalIrq); - xml.attribute("flags", String<16>(Genode::Hex(irq->IntiFlags))); - xml.attribute("bus", irq->Bus); - }); - }, [](Madt_sub const * const s) { return s->Length; }); -} - -static void add_mcfg(ACPI_TABLE_MCFG const * const mcfg, - Reporter::Xml_generator &xml) -{ - using namespace Genode; - - typedef ACPI_MCFG_ALLOCATION Mcfg_sub; - - for_each_element(mcfg, (Mcfg_sub *) nullptr, [&](Mcfg_sub const * const e) { - - /* bus_count * up to 32 devices * 8 function per device * 4k */ - uint32_t const bus_count = e->EndBusNumber - e->StartBusNumber + 1; - uint32_t const func_count = bus_count * 32 * 8; - uint32_t const bus_start = e->StartBusNumber * 32 * 8; - - xml.node("bdf", [&] () { - xml.attribute("start", bus_start); - xml.attribute("count", func_count); - xml.attribute("base", String<24>(Hex(e->Address))); - }); - - /* force freeing I/O mem so that platform driver can use it XXX */ - AcpiGenodeFreeIOMem(e->Address, 0x1000UL * func_count); - - }, [](Mcfg_sub const * const e) { return sizeof(*e); }); -} - -static void add_dmar(ACPI_TABLE_DMAR const * const dmar_table, - Reporter::Xml_generator &xml) -{ - using Genode::String; - using Genode::Hex; - - auto scope_length = [](ACPI_DMAR_DEVICE_SCOPE const * const e) { - return e->Length; }; - - auto scope_lambda = [&](ACPI_DMAR_DEVICE_SCOPE const * const e) { - xml.node("scope", [&] () { - xml.attribute("bus_start", e->Bus); - xml.attribute("type", e->EntryType); - - unsigned const count = (e->Length < 6) ? 0 : ((e->Length - 6) / 2); - - ACPI_DMAR_PCI_PATH * path = ACPI_CAST_PTR(ACPI_DMAR_PCI_PATH, e + 1); - for (unsigned i = 0; i < count; i++) { - xml.node("path", [&] () { - xml.attribute("dev", String<8>(Hex(path->Device))); - xml.attribute("func", String<8>(Hex(path->Function))); - }); - } - }); - }; - - for_each_element(dmar_table, (ACPI_DMAR_HEADER *) nullptr, [&](ACPI_DMAR_HEADER const * const e) { - if (e->Type == ACPI_DMAR_TYPE_RESERVED_MEMORY) { - ACPI_DMAR_RESERVED_MEMORY const * const dmar = ACPI_CAST_PTR (ACPI_DMAR_RESERVED_MEMORY, e); - - xml.node("rmrr", [&] () { - xml.attribute("start", String<24>(Hex(dmar->BaseAddress))); - xml.attribute("end" , String<24>(Hex(dmar->EndAddress))); - - for_each_element(dmar, (ACPI_DMAR_DEVICE_SCOPE *) nullptr, - scope_lambda, scope_length); - }); - } else - if (e->Type == ACPI_DMAR_TYPE_HARDWARE_UNIT) { - ACPI_DMAR_HARDWARE_UNIT const * const drhd = ACPI_CAST_PTR (ACPI_DMAR_HARDWARE_UNIT, e); - - xml.node("drhd", [&] () { - xml.attribute("phys", String<24>(Hex(drhd->Address))); - xml.attribute("flags", String<4>(Hex(drhd->Flags))); - xml.attribute("segment", String<8>(Hex(drhd->Segment))); - - for_each_element(drhd, (ACPI_DMAR_DEVICE_SCOPE *) nullptr, - scope_lambda, scope_length); - }); - } - }, [](ACPI_DMAR_HEADER const * const e) { return e->Length; }); -} - -static void add_ivdb(ACPI_TABLE_IVRS const * const ivrs_table, - Reporter::Xml_generator &xml) -{ - typedef ACPI_IVRS_HEADER Ivdb; - - for_each_element(ivrs_table, (Ivdb *) nullptr, [&](Ivdb const * const e) { - xml.node("ivdb", [&] () { - xml.attribute("type", e->Type); - }); - }, [](Ivdb const * const e) { return e->Length; }); -} - -void Acpica::generate_report(Genode::Env &env, Bridge *pci_root_bridge) -{ - enum { REPORT_SIZE = 5 * 4096 }; - static Reporter acpi(env, "acpi", "acpi", REPORT_SIZE); - acpi.enabled(true); - - Reporter::Xml_generator xml(acpi, [&] () { - ACPI_TABLE_HEADER *header = nullptr; - - ACPI_STATUS status = AcpiGetTable((char *)ACPI_SIG_MADT, 0, &header); - if (status == AE_OK) - add_madt(reinterpret_cast(header), xml); - - status = AcpiGetTable((char *)ACPI_SIG_MCFG, 0, &header); - if (status == AE_OK) - add_mcfg(reinterpret_cast(header), xml); - - for (unsigned instance = 1; ; instance ++) { - - status = AcpiGetTable(ACPI_STRING(ACPI_SIG_DMAR), instance, - &header); - if (status != AE_OK) - break; - - add_dmar(reinterpret_cast(header), xml); - } - - status = AcpiGetTable((char *)ACPI_SIG_IVRS, 0, &header); - if (status == AE_OK) - add_ivdb(reinterpret_cast(header), xml); - - if (pci_root_bridge) - pci_root_bridge->generate(xml); - }); -} diff --git a/repos/libports/src/app/acpica/target.mk b/repos/libports/src/app/acpica/target.mk index 0db7d0f48c..1a09936831 100644 --- a/repos/libports/src/app/acpica/target.mk +++ b/repos/libports/src/app/acpica/target.mk @@ -1,5 +1,5 @@ TARGET := acpica -SRC_CC := os.cc printf.cc report.cc +SRC_CC := os.cc printf.cc REQUIRES := x86 LIBS += base acpica diff --git a/repos/libports/src/app/acpica/util.h b/repos/libports/src/app/acpica/util.h index 578f82e1a6..40643e68c9 100644 --- a/repos/libports/src/app/acpica/util.h +++ b/repos/libports/src/app/acpica/util.h @@ -10,6 +10,9 @@ * under the terms of the GNU Affero General Public License version 3. */ +#ifndef _ACPICA__UTIL_H_ +#define _ACPICA__UTIL_H_ + extern "C" { #include "acpi.h" } @@ -20,6 +23,9 @@ namespace Acpica { template class Buffer; template class Callback; void generate_report(Genode::Env &, Bridge *); + + template + void for_each_element(H const head, S *, F const &fn, FSIZE const &fn_size); } template @@ -48,3 +54,17 @@ class Acpica::Callback : public Genode::List >::Element reinterpret_cast(this)->generate(xml); } }; + + +template +void Acpica::for_each_element(H const head, S *, F const &fn, FSIZE const &fn_size) +{ + for(S const * e = reinterpret_cast(head + 1); + e < reinterpret_cast(reinterpret_cast(head) + head->Header.Length); + e = reinterpret_cast(reinterpret_cast(e) + fn_size(e))) + { + fn(e); + } +} + +#endif /* _ACPICA__UTIL_H_ */ diff --git a/repos/libports/src/app/e2fsck/target.mk b/repos/libports/src/app/e2fsck/target.mk index a9cb56a4a3..f35bc52494 100644 --- a/repos/libports/src/app/e2fsck/target.mk +++ b/repos/libports/src/app/e2fsck/target.mk @@ -14,12 +14,13 @@ CC_OPT += -Wno-unused-variable -Wno-parentheses # e2fsck/dict.c SRC_C := \ badblocks.c \ - crc32.c \ dirinfo.c \ dx_dirinfo.c \ e2fsck.c \ ea_refcount.c \ ehandler.c \ + encrypted_files.c \ + extents.c \ journal.c \ logfile.c \ message.c \ @@ -30,10 +31,9 @@ SRC_C := \ pass4.c \ pass5.c \ problem.c \ - prof_err.c \ - profile.c \ quota.c \ recovery.c \ + readahead.c \ region.c \ rehash.c \ revoke.c \ @@ -46,20 +46,4 @@ INC_DIR += $(PRG_DIR) vpath %.c $(E2FSCK_DIR) -# -# Generate CRC32 header -# -E2FSCK_GEN_CRC := $(BUILD_BASE_DIR)/tool/e2fsprogs/gen_crc32table - -CRC_HEADER := $(BUILD_BASE_DIR)/app/e2fsck/crc32table.h - -$(SRC_C:.c=.o): $(CRC_HEADER) - -$(CRC_HEADER): - $(MSG_CONVERT)$(notdir $@) - $(VERBOSE)mkdir -p $(dir $@) - $(VERBOSE)$(E2FSCK_GEN_CRC) > $@ - -INC_DIR += $(BUILD_BASE_DIR)/$(dir $(CRC_HEADER)) - CC_CXX_WARN_STRICT = diff --git a/repos/libports/src/app/mke2fs/target.mk b/repos/libports/src/app/mke2fs/target.mk index 34618e8f64..d016174f6d 100644 --- a/repos/libports/src/app/mke2fs/target.mk +++ b/repos/libports/src/app/mke2fs/target.mk @@ -7,9 +7,13 @@ INC_DIR += $(E2FS_DIR)/e2fsck CC_DEF += -DROOT_SYSCONFDIR=\"/etc\" -SRC_C := $(addprefix misc/, mke2fs.c util.c default_profile.c) -SRC_C += $(addprefix e2fsck/, profile.c prof_err.c) +SRC_C := \ + create_inode.c \ + default_profile.c \ + mk_hugefiles.c \ + mke2fs.c \ + util.c -vpath %.c $(E2FS_DIR) +vpath %.c $(E2FS_DIR)/misc CC_CXX_WARN_STRICT = diff --git a/repos/libports/src/app/qt5/examples/samegame/target.mk b/repos/libports/src/app/qt5/examples/samegame/target.mk index f7dba1e7be..7e0d810ce8 100644 --- a/repos/libports/src/app/qt5/examples/samegame/target.mk +++ b/repos/libports/src/app/qt5/examples/samegame/target.mk @@ -3,7 +3,7 @@ QMAKE_PROJECT_FILE = $(PRG_DIR)/samegame.pro QMAKE_TARGET_BINARIES = samegame QT5_PORT_LIBS += libQt5Core libQt5Gui libQt5Network -QT5_PORT_LIBS += libQt5Qml libQt5Quick +QT5_PORT_LIBS += libQt5Qml libQt5QmlModels libQt5Quick LIBS = libc libm mesa qt5_component stdcxx $(QT5_PORT_LIBS) diff --git a/repos/libports/src/app/qt5/examples/virtualkeyboard/target.mk b/repos/libports/src/app/qt5/examples/virtualkeyboard/target.mk index 0e037995e4..35b2729bf3 100644 --- a/repos/libports/src/app/qt5/examples/virtualkeyboard/target.mk +++ b/repos/libports/src/app/qt5/examples/virtualkeyboard/target.mk @@ -3,7 +3,7 @@ QMAKE_PROJECT_FILE = $(QT_DIR)/qtvirtualkeyboard/examples/virtualkeyboard/basic/ QMAKE_TARGET_BINARIES = basic QT5_PORT_LIBS += libQt5Core libQt5Gui libQt5Network -QT5_PORT_LIBS += libQt5Qml libQt5Quick +QT5_PORT_LIBS += libQt5Qml libQt5QmlModels libQt5Quick QT5_PORT_LIBS += libQt5VirtualKeyboard LIBS = libc libm mesa qt5_component stdcxx $(QT5_PORT_LIBS) diff --git a/repos/libports/src/drivers/framebuffer/vesa/framebuffer.cc b/repos/libports/src/drivers/framebuffer/vesa/framebuffer.cc index 68ffca72e7..fb225c0339 100644 --- a/repos/libports/src/drivers/framebuffer/vesa/framebuffer.cc +++ b/repos/libports/src/drivers/framebuffer/vesa/framebuffer.cc @@ -16,7 +16,6 @@ #include #include #include -#include /* local includes */ #include "framebuffer.h" @@ -263,16 +262,6 @@ int Framebuffer::set_mode(unsigned &width, unsigned &height, unsigned mode) void Framebuffer::init(Genode::Env &env, Genode::Allocator &heap) { local_init_genode_env(env, heap); - - { - /* - * Wait until Acpi/Pci driver initialization is done to avoid - * potentially concurrent access by this driver and the Acpi/Pci driver - * to the graphics device, i.e., to the PCI config space. - */ - Platform::Connection sync(env); - } - hw_emul_init(env); X86emu::init(env, heap); } diff --git a/repos/libports/src/drivers/framebuffer/vesa/hw_emul.cc b/repos/libports/src/drivers/framebuffer/vesa/hw_emul.cc index 6f21c597f7..f53ab27ab7 100644 --- a/repos/libports/src/drivers/framebuffer/vesa/hw_emul.cc +++ b/repos/libports/src/drivers/framebuffer/vesa/hw_emul.cc @@ -33,8 +33,7 @@ static const bool verbose = false; ** PCI virtualization ** ************************/ -#include -#include +#include enum { PCI_ADDR_REG = 0xcf8, @@ -42,89 +41,59 @@ enum { }; -struct Devfn -{ - unsigned char b, d, f; - - Devfn(Platform::Device &device) { device.bus_address(&b, &d, &f); } - - Devfn(unsigned short devfn) - : b((devfn >> 8) & 0xff), d((devfn >> 3) & 0x1f), f(devfn & 7) { } - - unsigned short devfn() const { return b << 8 | d << 3 | f; } - - void print(Genode::Output &out) const - { - Genode::print(out, Hex(b, Hex::OMIT_PREFIX, Hex::PAD), ":", - Hex(d, Hex::OMIT_PREFIX, Hex::PAD), ".", - Hex(f, Hex::OMIT_PREFIX)); - } -}; - - class Pci_card { private: - Platform::Connection _pci_drv; - Platform::Device_client _device; - Devfn _devfn; + enum { BAR_MAX = 6 }; - Platform::Device_capability _first_device() - { - return _pci_drv.with_upgrade([&] () { - return _pci_drv.first_device(); }); - } - - Platform::Device_capability _next_device(Platform::Device_capability prev) - { - return _pci_drv.with_upgrade([&] () { - return _pci_drv.next_device(prev); }); - } - - Platform::Device_capability _find_vga_card() - { - /* - * Iterate through all accessible devices. - */ - Platform::Device_capability prev_device_cap, device_cap; - for (device_cap = _first_device(); - device_cap.valid(); - device_cap = _next_device(prev_device_cap)) { - - Platform::Device_client device(device_cap); - - if (prev_device_cap.valid()) - _pci_drv.release_device(prev_device_cap); - /* - * If the device is an VGA compatible controller with base - * class 0x03 and sub class 0x00 stop iteration. (We shift out - * the interface bits.) - */ - if ((device.class_code() >> 8) == 0x0300) - break; - - prev_device_cap = device_cap; - } - - if (!device_cap.valid()) { - Genode::error("PCI VGA card not found."); - throw Framebuffer::Fatal(); - } - - return device_cap; - } + Platform::Connection _pci_drv; + Platform::Device _device { _pci_drv }; + unsigned _vendor_device_id { 0 }; + unsigned _class_code { 0 }; + uint32_t _bar[BAR_MAX] { 0xffffffff}; public: - Pci_card(Genode::Env &env) - : _pci_drv(env), _device(_find_vga_card()), _devfn(_device) + struct Invalid_bar : Exception {}; + + Pci_card(Genode::Env &env) : _pci_drv(env) { - Genode::log("Found PCI VGA at ", _devfn); + _pci_drv.update(); + _pci_drv.with_xml([&] (Xml_node node) { + node.with_optional_sub_node("device", [&] (Xml_node node) { + node.for_each_sub_node("io_mem", [&] (Xml_node node) { + unsigned bar = node.attribute_value("pci_bar", 0U); + uint32_t addr = node.attribute_value("phys_addr", 0UL); + if (bar >= BAR_MAX) throw Invalid_bar(); + _bar[bar] = addr; + }); + node.for_each_sub_node("io_port_range", [&] (Xml_node node) { + unsigned bar = node.attribute_value("pci_bar", 0U); + uint32_t addr = node.attribute_value("phys_addr", 0UL); + if (bar >= BAR_MAX) throw Invalid_bar(); + _bar[bar] = addr | 1; + }); + node.with_optional_sub_node("pci-config", [&] (Xml_node node) { + unsigned v = node.attribute_value("vendor_id", 0U); + unsigned d = node.attribute_value("device_id", 0U); + unsigned c = node.attribute_value("class", 0U); + unsigned r = node.attribute_value("revision", 0U); + _vendor_device_id = v | d << 16; + _class_code = r | c << 8; + }); + }); + }); } - Platform::Device &device() { return _device; } - unsigned short devfn() const { return _devfn.devfn(); } + unsigned vendor_device_id() { return _vendor_device_id; } + unsigned class_code() { return _class_code; } + + uint32_t bar(unsigned bar) + { + if (bar >= BAR_MAX) throw Invalid_bar(); + return _bar[bar]; + } }; @@ -154,14 +123,6 @@ static bool handle_pci_port_write(unsigned short port, T val) return true; } - unsigned const devfn = (val >> 8) & 0xffff; - if (devfn != pci_card->devfn()) { - if (verbose) - warning("accessing unknown PCI device ", Devfn(devfn)); - pci_cfg_addr_valid = false; - return true; - } - /* remember the configuration address */ pci_cfg_addr = val & 0xfc; pci_cfg_addr_valid = true; @@ -208,14 +169,12 @@ static bool handle_pci_port_read(unsigned short port, T *val) switch (pci_cfg_addr) { case 0: /* vendor / device ID */ - raw_val = pci_card->device().vendor_id() | - (pci_card->device().device_id() << 16); + raw_val = pci_card->vendor_device_id(); break; case 4: /* status and command */ case 8: /* class code / revision ID */ - raw_val = pci_card->device().config_read(pci_cfg_addr, - Platform::Device::ACCESS_32BIT); + raw_val = pci_card->class_code(); break; case 0x10: /* base address register 0 */ @@ -225,16 +184,8 @@ static bool handle_pci_port_read(unsigned short port, T *val) case 0x20: /* base address register 4 */ case 0x24: /* base address register 5 */ { - unsigned bar = (pci_cfg_addr - 0x10) / 4; - Platform::Device::Resource res = pci_card->device().resource(bar); - if (res.type() == Platform::Device::Resource::INVALID) { - warning("requested PCI resource ", bar, " invalid"); - *val = 0; - return true; - } - - raw_val = res.bar(); - break; + raw_val = pci_card->bar((pci_cfg_addr-0x10)/4); + break; } default: diff --git a/repos/libports/src/lib/acpica/env.cc b/repos/libports/src/lib/acpica/env.cc index a474a13560..3e088229bf 100644 --- a/repos/libports/src/lib/acpica/env.cc +++ b/repos/libports/src/lib/acpica/env.cc @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2016-2017 Genode Labs GmbH + * Copyright (C) 2016-2022 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. @@ -14,7 +14,7 @@ /* Genode includes */ #include #include -#include +#include #include "env.h" @@ -27,26 +27,9 @@ struct Acpica::Env Genode::Env &env; Genode::Allocator &heap; - Wait_acpi_ready const wait_acpi_ready; - bool use_platform_drv; + Genode::Constructible platform; - Genode::Parent::Service_name announce_for_acpica { - wait_acpi_ready.enabled ? "Acpi" : Platform::Session::service_name() }; - - Genode::Parent::Client parent_client; - - Genode::Id_space::Element id_space_element { - parent_client, env.id_space() }; - - Genode::Constructible> cap; - Genode::Constructible platform; - - Env(Genode::Env &env, Genode::Allocator &heap, - Wait_acpi_ready wait_acpi_ready) - : - env(env), heap(heap), wait_acpi_ready(wait_acpi_ready), - use_platform_drv(!wait_acpi_ready.enabled) - { } + Env(Genode::Env &env, Genode::Allocator &heap) : env(env), heap(heap) { } }; static Genode::Constructible instance; @@ -56,27 +39,16 @@ Genode::Allocator & Acpica::heap() { return instance->heap; } Genode::Env & Acpica::env() { return instance->env; } Platform::Client & Acpica::platform() { - if (!instance->cap.constructed()) { - instance->cap.construct(Genode::reinterpret_cap_cast( - instance->env.session(instance->announce_for_acpica, - instance->id_space_element.id(), - "ram_quota=36K", Genode::Affinity()))); + if (!instance->platform.constructed()) + instance->platform.construct(instance->env); - instance->platform.construct(*instance->cap); - } return *instance->platform; } -bool Acpica::platform_drv() { return instance->use_platform_drv; } -void Acpica::use_platform_drv() { instance->use_platform_drv = true; } -void Acpica::init(Genode::Env &env, Genode::Allocator &heap, - Wait_acpi_ready const wait_acpi_ready, - Act_as_acpi_drv const act_as_acpi_drv) +void Acpica::init(Genode::Env &env, Genode::Allocator &heap) { - instance.construct(env, heap, wait_acpi_ready); + instance.construct(env, heap); - /* if not running as acpi_drv, block until original acpi_drv is done */ - if (!act_as_acpi_drv.enabled) - platform(); + platform(); } diff --git a/repos/libports/src/lib/acpica/env.h b/repos/libports/src/lib/acpica/env.h index 4806ca8288..ec92270992 100644 --- a/repos/libports/src/lib/acpica/env.h +++ b/repos/libports/src/lib/acpica/env.h @@ -16,7 +16,7 @@ #include #include -#include +#include namespace Acpica { Genode::Env & env(); diff --git a/repos/libports/src/lib/acpica/pci.cc b/repos/libports/src/lib/acpica/pci.cc index 442a552786..4f5897aa57 100644 --- a/repos/libports/src/lib/acpica/pci.cc +++ b/repos/libports/src/lib/acpica/pci.cc @@ -12,7 +12,6 @@ */ #include -#include #include "env.h" @@ -41,97 +40,6 @@ struct Bdf } }; -static void dump_read(char const * const func, ACPI_PCI_ID *pcidev, - UINT32 reg, UINT64 value, UINT32 width) -{ - using namespace Genode; - - log(func, ": ", Bdf(pcidev->Bus, pcidev->Device, pcidev->Function), " " - "reg=", Hex(reg, Hex::PREFIX, Hex::PAD), " " - "width=", width, width < 10 ? " " : "", " -> " - "value=", Genode::Hex(value)); -} - -static void dump_write(char const * const func, ACPI_PCI_ID *pcidev, - UINT32 reg, UINT64 value, UINT32 width) -{ - using namespace Genode; - - warning(func, ": ", Bdf(pcidev->Bus, pcidev->Device, pcidev->Function), " " - "reg=", Hex(reg, Hex::PREFIX, Hex::PAD), " " - "width=", width, width < 10 ? " " : "", " -> " - "value=", Genode::Hex(value)); -} - -static void dump_error(char const * const func, ACPI_PCI_ID *pcidev, - UINT32 reg, UINT32 width) -{ - error(func, " unknown device - segment=", pcidev->Segment, " ", - "bdf=", Bdf(pcidev->Bus, pcidev->Device, pcidev->Function), " ", - "reg=", Genode::Hex(reg), " " - "width=", Genode::Hex(width)); -} - - -/******************************* - * Accessing PCI via I/O ports * - *******************************/ - -enum { REG_ADDR = 0xcf8, REG_DATA = 0xcfc, REG_SIZE = 4 }; - -static Genode::Io_port_connection &pci_io_port() { - static Genode::Io_port_connection conn(Acpica::env(), REG_ADDR, REG_SIZE); - return conn; -} - -static unsigned pci_io_cfg_addr(unsigned const bus, unsigned const device, - unsigned const function, unsigned const addr) -{ - return (1U << 31) | - (bus << 16) | - ((device & 0x1fU) << 11) | - ((function & 0x07U) << 8) | - (addr & ~3U); -} - -static unsigned pci_io_read(unsigned const bus, unsigned const device, - unsigned const function, unsigned const addr, - unsigned const width) -{ - /* write target address */ - pci_io_port().outl(REG_ADDR, pci_io_cfg_addr(bus, device, function, addr)); - - switch (width) { - case 8: - return pci_io_port().inb(REG_DATA + (addr & 3)); - case 16: - return pci_io_port().inw(REG_DATA + (addr & 2)); - case 32: - return pci_io_port().inl(REG_DATA); - default: - return ~0U; - } -} - -static void pci_io_write(unsigned const bus, unsigned const device, - unsigned const function, unsigned const addr, - unsigned const width, unsigned value) -{ - /* write target address */ - pci_io_port().outl(REG_ADDR, pci_io_cfg_addr(bus, device, function, addr)); - - switch (width) { - case 8: - pci_io_port().outb(REG_DATA + (addr & 3), value); - return; - case 16: - pci_io_port().outw(REG_DATA + (addr & 2), value); - return; - case 32: - pci_io_port().outl(REG_DATA, value); - return; - } -} /************************* * Acpica PCI OS backend * @@ -142,121 +50,24 @@ ACPI_STATUS AcpiOsInitialize (void) { return AE_OK; } ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg, UINT64 *value, UINT32 width) { - if (!Acpica::platform_drv()) { - try { - *value = pci_io_read(pcidev->Bus, pcidev->Device, pcidev->Function, - reg, width); - dump_read(__func__, pcidev, reg, *value, width); - } catch (...) { - dump_error(__func__, pcidev, reg, width); - return AE_ERROR; - } - return AE_OK; - } + using namespace Genode; - Platform::Device_capability cap = Acpica::platform().first_device(); + Bdf bdf(pcidev->Bus, pcidev->Device, pcidev->Function); - while (cap.valid()) { - Platform::Device_client client(cap); + error(__func__, " ", bdf, " ", Hex(reg), " width=", width); - unsigned char bus, dev, fn; - client.bus_address(&bus, &dev, &fn); - - if (pcidev->Bus == bus && pcidev->Device == dev && - pcidev->Function == fn) { - - Platform::Device_client::Access_size access_size; - switch (width) { - case 8: - access_size = Platform::Device_client::Access_size::ACCESS_8BIT; - break; - case 16: - access_size = Platform::Device_client::Access_size::ACCESS_16BIT; - break; - case 32: - access_size = Platform::Device_client::Access_size::ACCESS_32BIT; - break; - default: - Genode::error(__func__, " : unsupported access size ", width); - Acpica::platform().release_device(client.rpc_cap()); - return AE_ERROR; - }; - - *value = client.config_read(reg, access_size); - - dump_read(__func__, pcidev, reg, *value, width); - - Acpica::platform().release_device(client.rpc_cap()); - return AE_OK; - } - - cap = Acpica::platform().next_device(cap); - - Acpica::platform().release_device(client.rpc_cap()); - } - - dump_error(__func__, pcidev, reg, width); - - return AE_ERROR; + *value = ~0U; + return AE_OK; } ACPI_STATUS AcpiOsWritePciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg, UINT64 value, UINT32 width) { - if (!Acpica::platform_drv()) { - try { - dump_write(__func__, pcidev, reg, value, width); - pci_io_write(pcidev->Bus, pcidev->Device, pcidev->Function, reg, - width, value); - return AE_OK; - } catch (...) { - dump_error(__func__, pcidev, reg, width); - return AE_ERROR; - } - } + using namespace Genode; - Platform::Device_capability cap = Acpica::platform().first_device(); + Bdf bdf(pcidev->Bus, pcidev->Device, pcidev->Function); - while (cap.valid()) { - Platform::Device_client client(cap); + error(__func__, " ", bdf, " ", Hex(reg), "=", Hex(value), " width=", width); - unsigned char bus, dev, fn; - client.bus_address(&bus, &dev, &fn); - - if (pcidev->Bus == bus && pcidev->Device == dev && - pcidev->Function == fn) { - - Platform::Device_client::Access_size access_size; - switch (width) { - case 8: - access_size = Platform::Device_client::Access_size::ACCESS_8BIT; - break; - case 16: - access_size = Platform::Device_client::Access_size::ACCESS_16BIT; - break; - case 32: - access_size = Platform::Device_client::Access_size::ACCESS_32BIT; - break; - default: - Genode::error(__func__, " : unsupported access size ", width); - Acpica::platform().release_device(client.rpc_cap()); - return AE_ERROR; - }; - - client.config_write(reg, value, access_size); - - dump_write(__func__, pcidev, reg, value, width); - - Acpica::platform().release_device(client.rpc_cap()); - return AE_OK; - } - - cap = Acpica::platform().next_device(cap); - - Acpica::platform().release_device(client.rpc_cap()); - } - - dump_error(__func__, pcidev, reg, width); - - return AE_ERROR; + return AE_OK; } diff --git a/repos/libports/src/lib/e2fsprogs/config.h b/repos/libports/src/lib/e2fsprogs/config.h index b13d8afc43..0c162b1728 100644 --- a/repos/libports/src/lib/e2fsprogs/config.h +++ b/repos/libports/src/lib/e2fsprogs/config.h @@ -1,5 +1,4 @@ #define ENABLE_HTREE 1 -#define ENABLE_NLS 1 #define HAVE_ALLOCA 1 #define HAVE_ASPRINTF 1 #define HAVE_DECL_FEOF_UNLOCKED 1 diff --git a/repos/libports/src/lib/e2fsprogs/dummies.c b/repos/libports/src/lib/e2fsprogs/dummies.c new file mode 100644 index 0000000000..b1db651443 --- /dev/null +++ b/repos/libports/src/lib/e2fsprogs/dummies.c @@ -0,0 +1,31 @@ +/* + * \brief Dummies to prevent unneeded warnings + * \author Josef Soentgen + * \date 2022-06-05 + */ + +/* + * Copyright (C) 2022 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. + */ + +#include +#include +#include + + +int getrusage(int who, struct rusage *usage) +{ + (void)who; + (void)usage; + return -1; +} + + +void *sbrk(intptr_t increment) +{ + (void)increment; + return (void*)0; +} diff --git a/repos/libports/src/lib/e2fsprogs/patches/e2fsck_util_c.patch b/repos/libports/src/lib/e2fsprogs/patches/e2fsck_util_c.patch new file mode 100644 index 0000000000..4879d1f41c --- /dev/null +++ b/repos/libports/src/lib/e2fsprogs/patches/e2fsck_util_c.patch @@ -0,0 +1,11 @@ +--- src/lib/e2fsprogs/e2fsck/util.c ++++ src/lib/e2fsprogs/e2fsck/util.c +@@ -115,7 +115,7 @@ + void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned long size, + const char *description) + { +- void *ret; ++ void *ret = NULL; + char buf[256]; + + #ifdef DEBUG_ALLOCATE_MEMORY diff --git a/repos/libports/src/lib/e2fsprogs/patches/quotaio_strncat.patch b/repos/libports/src/lib/e2fsprogs/patches/quotaio_strncat.patch deleted file mode 100644 index a9513eeb27..0000000000 --- a/repos/libports/src/lib/e2fsprogs/patches/quotaio_strncat.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git src/lib/e2fsprogs/lib/quota/quotaio.c src/lib/e2fsprogs/lib/quota/quotaio.c -index 1bdcba6c..8bd253d4 100644 ---- src/lib/e2fsprogs/lib/quota/quotaio.c -+++ src/lib/e2fsprogs/lib/quota/quotaio.c -@@ -64,7 +64,7 @@ const char *quota_get_qf_path(const char *mntpt, int qtype, int fmt, - return NULL; - - strncpy(path_buf, mntpt, path_buf_size); -- strncat(path_buf, "/", 1); -+ strncat(path_buf, "/", path_buf_size - strlen(path_buf)); - strncat(path_buf, quota_get_qf_name(qtype, fmt, qf_name), - path_buf_size - strlen(path_buf)); - diff --git a/repos/libports/src/lib/e2fsprogs/patches/unix_io.c.patch b/repos/libports/src/lib/e2fsprogs/patches/unix_io.c.patch deleted file mode 100644 index cab5708a07..0000000000 --- a/repos/libports/src/lib/e2fsprogs/patches/unix_io.c.patch +++ /dev/null @@ -1,13 +0,0 @@ -Remove io->align check because it is not needed in our case -and rather leads to an memory allocation error (we cannot satisfy -the alignment). -+++ src/lib/e2fsprogs/lib/ext2fs/unix_io.c -@@ -558,7 +558,7 @@ static errcode_t unix_open(const char *name, int flags, io_channel *channel) - } - #endif - --#if defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -+#if 0 - /* - * Some operating systems require that the buffers be aligned, - * regardless of O_DIRECT diff --git a/repos/libports/src/lib/libc/file_operations.cc b/repos/libports/src/lib/libc/file_operations.cc index 5cf4e7351b..b0da2ce4f0 100644 --- a/repos/libports/src/lib/libc/file_operations.cc +++ b/repos/libports/src/lib/libc/file_operations.cc @@ -71,8 +71,8 @@ void Libc::init_file_operations(Cwd &cwd, { _cwd_ptr = &cwd; - config_accessor.config().with_sub_node("libc", [&] (Xml_node libc) { - libc.with_sub_node("mmap", [&] (Xml_node mmap) { + config_accessor.config().with_optional_sub_node("libc", [&] (Xml_node libc) { + libc.with_optional_sub_node("mmap", [&] (Xml_node mmap) { _mmap_align_log2 = mmap.attribute_value("align_log2", (unsigned int)PAGE_SHIFT); }); diff --git a/repos/libports/src/lib/libc/fork.cc b/repos/libports/src/lib/libc/fork.cc index 4a2f6d54a1..c2b8e505d6 100644 --- a/repos/libports/src/lib/libc/fork.cc +++ b/repos/libports/src/lib/libc/fork.cc @@ -140,7 +140,7 @@ void Libc::Child_config::_generate(Xml_generator &xml, Xml_node config) xml.attribute("pid", _pid); typedef String Path; - config.with_sub_node("libc", [&] (Xml_node node) { + config.with_optional_sub_node("libc", [&] (Xml_node node) { if (node.has_attribute("rtc")) xml.attribute("rtc", node.attribute_value("rtc", Path())); if (node.has_attribute("pipe")) diff --git a/repos/libports/src/lib/libc/internal/rtc.h b/repos/libports/src/lib/libc/internal/rtc.h index b38b25d12c..cb10fd1335 100644 --- a/repos/libports/src/lib/libc/internal/rtc.h +++ b/repos/libports/src/lib/libc/internal/rtc.h @@ -47,14 +47,14 @@ struct Libc::Rtc : Vfs::Watch_response_handler try { File_content const content(_alloc, root_dir, _rtc_path.string(), File_content::Limit{4096U}); - content.bytes([&] (char const *ptr, size_t size) { char buf[32] { }; ::memcpy(buf, ptr, min(sizeof(buf) - 1, size)); struct tm tm { }; - if (strptime(buf, "%Y-%m-%d %R", &tm)) { + if (strptime(buf, "%Y-%m-%d %H:%M:%S", &tm) + || strptime(buf, "%Y-%m-%d %H:%M", &tm)) { _rtc_value = mktime(&tm); if (_rtc_value == (time_t)-1) _rtc_value = 0; diff --git a/repos/libports/src/lib/libc/internal/vfs_plugin.h b/repos/libports/src/lib/libc/internal/vfs_plugin.h index d88a8bae0c..b3d7fc5847 100644 --- a/repos/libports/src/lib/libc/internal/vfs_plugin.h +++ b/repos/libports/src/lib/libc/internal/vfs_plugin.h @@ -145,7 +145,7 @@ class Libc::Vfs_plugin final : public Plugin static bool _init_pipe_configured(Xml_node config) { bool result = false; - config.with_sub_node("libc", [&] (Xml_node libc_node) { + config.with_optional_sub_node("libc", [&] (Xml_node libc_node) { result = libc_node.has_attribute("pipe"); }); return result; } diff --git a/repos/libports/src/lib/libc/kernel.cc b/repos/libports/src/lib/libc/kernel.cc index a5f3e53ee5..2324951b0f 100644 --- a/repos/libports/src/lib/libc/kernel.cc +++ b/repos/libports/src/lib/libc/kernel.cc @@ -47,7 +47,7 @@ size_t Libc::Kernel::_user_stack_size() { size_t size = Component::stack_size(); - _libc_env.libc_config().with_sub_node("stack", [&] (Xml_node stack) { + _libc_env.libc_config().with_optional_sub_node("stack", [&] (Xml_node stack) { size = stack.attribute_value("size", Number_of_bytes(0)); }); return size; @@ -176,43 +176,53 @@ void Libc::Kernel::_init_file_descriptors() if (!node.has_attribute(attr)) return; - Absolute_path const path { - resolve_absolute_path(node.attribute_value(attr, Path())) }; + Path const attr_value { node.attribute_value(attr, Path()) }; + try { + Absolute_path const path { resolve_absolute_path(attr_value) }; - struct stat out_stat { }; - if (_vfs.stat_from_kernel(path.string(), &out_stat) != 0) - return; + struct stat out_stat { }; + if (_vfs.stat_from_kernel(path.string(), &out_stat) != 0) { + warning("failed to call 'stat' on ", path); + return; + } - File_descriptor *fd = _vfs.open_from_kernel(path.string(), flags, libc_fd); - if (!fd) - return; + File_descriptor *fd = + _vfs.open_from_kernel(path.string(), flags, libc_fd); - if (fd->libc_fd != libc_fd) { - error("could not allocate fd ",libc_fd," for ",path,", " - "got fd ",fd->libc_fd); - _vfs.close_from_kernel(fd); + if (!fd) + return; + + if (fd->libc_fd != libc_fd) { + error("could not allocate fd ",libc_fd," for ",path,", " + "got fd ",fd->libc_fd); + _vfs.close_from_kernel(fd); + return; + } + + fd->cloexec = node.attribute_value("cloexec", false); + + /* + * We need to manually register the path. Normally this is done + * by '_open'. But we call the local 'open' function directly + * because we want to explicitly specify the libc fd ID. + */ + if (fd->fd_path) + warning("may leak former FD path memory"); + + { + char *dst = (char *)_heap.alloc(path.max_len()); + copy_cstring(dst, path.string(), path.max_len()); + fd->fd_path = dst; + } + + ::off_t const seek = node.attribute_value("seek", 0ULL); + if (seek) + _vfs.lseek_from_kernel(fd, seek); + + } catch (Symlink_resolve_error) { + warning("failed to resolve path for ", attr_value); return; } - - fd->cloexec = node.attribute_value("cloexec", false); - - /* - * We need to manually register the path. Normally this is done - * by '_open'. But we call the local 'open' function directly - * because we want to explicitly specify the libc fd ID. - */ - if (fd->fd_path) - warning("may leak former FD path memory"); - - { - char *dst = (char *)_heap.alloc(path.max_len()); - copy_cstring(dst, path.string(), path.max_len()); - fd->fd_path = dst; - } - - ::off_t const seek = node.attribute_value("seek", 0ULL); - if (seek) - _vfs.lseek_from_kernel(fd, seek); }; if (_vfs.root_dir_has_dirents()) { diff --git a/repos/libports/src/lib/libc/patches/thread_local.patch b/repos/libports/src/lib/libc/patches/thread_local.patch index 89fa01b06b..f3356ff325 100644 --- a/repos/libports/src/lib/libc/patches/thread_local.patch +++ b/repos/libports/src/lib/libc/patches/thread_local.patch @@ -21,3 +21,23 @@ #endif /* __STDC_VERSION__ || __STDC_VERSION__ < 201112L */ /* +--- src/lib/libc/lib/libc/stdlib/cxa_thread_atexit_impl.c.orig 2022-08-16 17:53:26.334343226 +0200 ++++ src/lib/libc/lib/libc/stdlib/cxa_thread_atexit_impl.c 2022-08-17 13:37:34.445860493 +0200 +@@ -105,12 +105,17 @@ + { + struct dl_phdr_info phdr_info; + ++/* XXX this unload detection mechanism does not work on Genode */ ++#if 0 + if (_rtld_addr_phdr(dtor->dso, &phdr_info) && + __elf_phdr_match_addr(&phdr_info, dtor->func)) ++#endif + dtor->func(dtor->obj); ++#if 0 + else + fprintf(stderr, "__cxa_thread_call_dtors: dtr %p from " + "unloaded dso, skipping\n", (void *)(dtor->func)); ++#endif + } + + static void diff --git a/repos/libports/src/lib/libc/pthread.cc b/repos/libports/src/lib/libc/pthread.cc index 9619800dd7..8481dac372 100644 --- a/repos/libports/src/lib/libc/pthread.cc +++ b/repos/libports/src/lib/libc/pthread.cc @@ -685,8 +685,15 @@ extern "C" { } + /* implemented in libc contrib sources */ + void __cxa_thread_call_dtors(); + void pthread_exit(void *value_ptr) { + /* call 'thread_local' destructors */ + + __cxa_thread_call_dtors(); + /* call TLS key destructors */ bool at_least_one_destructor_called; diff --git a/repos/libports/src/lib/libc/sendmsg.c b/repos/libports/src/lib/libc/sendmsg.c new file mode 100644 index 0000000000..2c61f80253 --- /dev/null +++ b/repos/libports/src/lib/libc/sendmsg.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + /* + * NOTE: @author : Aditya Kousik + * @email : adit267.kousik@gmail.com + * + * This implementation is for the libc-net port of Genode + * + */ + +#include + +#include +#include +#include + +#include +#include + +#include + +ssize_t sendmsg(int s, const struct msghdr *msg, int flags) +{ + ssize_t ret; + size_t tot = 0; + int i; + char *buf, *p; + struct iovec *iov = msg->msg_iov; + + for(i = 0; i < msg->msg_iovlen; ++i) + tot += iov[i].iov_len; + buf = malloc(tot); + if (tot != 0 && buf == NULL) { + //errno = ENOMEM; + return -1; + } + p = buf; + for (i = 0; i < msg->msg_iovlen; ++i) { + memcpy (p, iov[i].iov_base, iov[i].iov_len); + p += iov[i].iov_len; + } + ret = _sendto(s, buf, tot, flags, msg->msg_name, msg->msg_namelen); + free (buf); + return ret; +} \ No newline at end of file diff --git a/repos/libports/src/lib/libc/socket_fs_plugin.cc b/repos/libports/src/lib/libc/socket_fs_plugin.cc index 7295ab3be7..24c34726b5 100644 --- a/repos/libports/src/lib/libc/socket_fs_plugin.cc +++ b/repos/libports/src/lib/libc/socket_fs_plugin.cc @@ -632,7 +632,7 @@ extern "C" int socket_fs_bind(int libc_fd, sockaddr const *addr, socklen_t addrl if (!addr) return Errno(EFAULT); if (addr->sa_family != AF_INET) { - error(__func__, ": family not supported"); + error(__func__, ": family ", addr->sa_family, " not supported"); return Errno(EAFNOSUPPORT); } @@ -842,8 +842,78 @@ extern "C" ssize_t socket_fs_recv(int libc_fd, void *buf, ::size_t len, int flag extern "C" ssize_t socket_fs_recvmsg(int libc_fd, msghdr *msg, int flags) { - warning("########## TODO ########## ", __func__); - return 0; + /* TODO just a simple implementation that handles the easy cases */ + size_t numberOfBytes = 0; + char *data = nullptr; + size_t length = 0; + char *buffer; + ssize_t res; + size_t amount; + socklen_t client_address_len; + + /* iterate over all msg_iov to get the number of bytes that have to be read. */ + for (int i = 0; i < msg->msg_iovlen; i++) { + numberOfBytes += msg->msg_iov[i].iov_len; + /* + * As an optimization, we set the initial values of DATA and LEN from + * the first non-empty iovec. This kicks-in in the case where the whole + * packet fits into the first iovec buffer. + */ + if (data == nullptr && msg->msg_iov[i].iov_len > 0) { + data = (char*)msg->msg_iov[i].iov_base; + length = msg->msg_iov[i].iov_len; + } + } + + buffer = data; + + struct sockaddr_in client_address; + client_address_len = sizeof (client_address); + + /* do socket communication */ + res = socket_fs_recvfrom(libc_fd, buffer, length, flags, + (struct sockaddr *) &client_address, + &client_address_len); + + if(res < 0) { + return res; + } + + /* copy client address to msg_name */ + if (msg->msg_name != nullptr && client_address_len > 0) { + if (msg->msg_namelen > client_address_len) { + msg->msg_namelen = client_address_len; + } + + ::memcpy (msg->msg_name, &client_address, msg->msg_namelen); + } else if (msg->msg_name != nullptr) { + msg->msg_namelen = 0; + } + + /* handle payload */ + if (buffer == data) { + buffer += length; + } else { + amount = length; + buffer = data; + for (int i = 0; i < msg->msg_iovlen; i++) { +#define min(a, b) ((a) > (b) ? (b) : (a)) + size_t copy = min (msg->msg_iov[i].iov_len, amount); + ::memcpy (msg->msg_iov[i].iov_base, buffer, copy); + buffer += copy; + amount -= copy; + if (length == 0) + break; + } + + Libc::Allocator alloc { }; + destroy(alloc, data); + } + + /* handle control data, not supported yet */ + msg->msg_controllen = 0; + + return res; } @@ -1065,6 +1135,13 @@ extern "C" int socket_fs_socket(int domain, int type, int protocol) Socket_fs::Context(proto, handle_fd); } catch (New_socket_failed) { return Errno(ENFILE); } + if (context) { + int flags = 0; + if (type & SOCK_NONBLOCK) flags |= O_NONBLOCK; + if (type & SOCK_CLOEXEC) flags |= O_CLOEXEC; + context->fd_flags(flags); + } + File_descriptor *fd = file_descriptor_allocator()->alloc(&plugin(), context); if (!fd) { Libc::Allocator alloc { }; @@ -1143,6 +1220,11 @@ int Socket_fs::Plugin::fcntl(File_descriptor *fd, int cmd, long arg) if (!context) return Errno(EBADF); switch (cmd) { + case F_GETFD: + return context->fd_flags(); + case F_SETFD: + context->fd_flags(arg); + return 0; case F_GETFL: return context->fd_flags() | O_RDWR; case F_SETFL: diff --git a/repos/libports/src/lib/libc/time.cc b/repos/libports/src/lib/libc/time.cc index 0ec663caa4..a6168111ff 100644 --- a/repos/libports/src/lib/libc/time.cc +++ b/repos/libports/src/lib/libc/time.cc @@ -78,8 +78,10 @@ int clock_gettime(clockid_t clk_id, struct timespec *ts) if (!_current_real_time_ptr) throw Missing_call_of_init_time(); - if (!_current_real_time_ptr->has_real_time()) + if (!_current_real_time_ptr->has_real_time()) { + warning("clock_gettime(): missing real-time clock"); return Errno(EINVAL); + } *ts = _current_real_time_ptr->current_real_time(); break; diff --git a/repos/libports/src/lib/libc/vfs_plugin.cc b/repos/libports/src/lib/libc/vfs_plugin.cc index 56abd0d337..89db7eab71 100644 --- a/repos/libports/src/lib/libc/vfs_plugin.cc +++ b/repos/libports/src/lib/libc/vfs_plugin.cc @@ -101,7 +101,7 @@ static Libc::Plugin_context *vfs_context(Vfs::Vfs_handle *vfs_handle) static void vfs_stat_to_libc_stat_struct(Vfs::Directory_service::Stat const &src, struct stat *dst) { - enum { FS_BLOCK_SIZE = 4096 }; + enum { FS_BLOCK_SIZE = 4096 * 16 }; unsigned const readable_bits = S_IRUSR, writeable_bits = S_IWUSR, @@ -1682,7 +1682,41 @@ Libc::Vfs_plugin::_ioctl_sndctl(File_descriptor *fd, unsigned long request, char if (!argp) return { true, EINVAL }; - /* dummy implementation */ + int mask = *(int *)argp; + + if (((fd->flags & O_ACCMODE) == O_RDONLY) || + ((fd->flags & O_ACCMODE) == O_RDWR)) { + + char enable_input_string[2]; + + ::snprintf(enable_input_string, sizeof(enable_input_string), + "%u", (mask & PCM_ENABLE_INPUT) ? 1 : 0); + + Absolute_path enable_input_path = ioctl_dir(*fd); + enable_input_path.append_element("enable_input"); + File_descriptor *enable_input_fd = open(enable_input_path.base(), O_WRONLY); + if (!enable_input_fd) + return { true, ENOTSUP }; + write(enable_input_fd, enable_input_string, sizeof(enable_input_string)); + close(enable_input_fd); + } + + if (((fd->flags & O_ACCMODE) == O_WRONLY) || + ((fd->flags & O_ACCMODE) == O_RDWR)) { + + char enable_output_string[2]; + + ::snprintf(enable_output_string, sizeof(enable_output_string), + "%u", (mask & PCM_ENABLE_OUTPUT) ? 1 : 0); + + Absolute_path enable_output_path = ioctl_dir(*fd); + enable_output_path.append_element("enable_output"); + File_descriptor *enable_output_fd = open(enable_output_path.base(), O_WRONLY); + if (!enable_output_fd) + return { true, ENOTSUP }; + write(enable_output_fd, enable_output_string, sizeof(enable_output_string)); + close(enable_output_fd); + } handled = true; diff --git a/repos/libports/src/lib/libdrm/ioctl_dispatch.cc b/repos/libports/src/lib/libdrm/ioctl_dispatch.cc new file mode 100644 index 0000000000..6932529e39 --- /dev/null +++ b/repos/libports/src/lib/libdrm/ioctl_dispatch.cc @@ -0,0 +1,130 @@ +/* + * \brief DRM ioctl back end dispatcher + * \author Josef Soentgen + * \date 2022-07-15 + */ + +/* + * Copyright (C) 2022 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. + */ + +/* Genode includes */ +#include +#include + +extern "C" { +#include +#include +#include +#include +#include +#include +#include +} + + +/* etnaviv driver */ + +extern void etnaviv_drm_init(); +extern int etnaviv_drm_ioctl(unsigned long, void *); +extern void *etnaviv_drm_mmap(off_t, size_t); +extern int etnaviv_drm_munmap(void *); + +/* lima driver */ + +extern void lima_drm_init(); +extern int lima_drm_ioctl(unsigned long, void *); +extern void *lima_drm_mmap(off_t, size_t); +extern int lima_drm_munmap(void *); +extern int lima_drm_poll(int); + + +static Libdrm::Driver drm_backend_type = Libdrm::Driver::INVALID; + + +/** + * Initialize DRM back end and set type + */ +void drm_init(Libdrm::Driver driver) +{ + switch (driver) { + case Libdrm::Driver::ETNAVIV: + etnaviv_drm_init(); + drm_backend_type = Libdrm::Driver::ETNAVIV; + break; + case Libdrm::Driver::LIMA: + lima_drm_init(); + drm_backend_type = Libdrm::Driver::LIMA; + break; + default: + Genode::error(__func__, ": unknown back end, abort"); + abort(); + } +} + + +/** + * Perfom I/O control request + */ +extern "C" int genode_ioctl(int /* fd */, unsigned long request, void *arg) +{ + switch (drm_backend_type) { + case Libdrm::Driver::ETNAVIV: return etnaviv_drm_ioctl(request, arg); + case Libdrm::Driver::LIMA: return lima_drm_ioctl(request, arg); + default: return -1; + } +} + + +/** + * Map DRM buffer-object + */ +extern "C" void *drm_mmap(void *addr, size_t length, int prot, int flags, + int fd, off_t offset) +{ + (void)addr; + (void)prot; + (void)flags; + (void)fd; + + switch (drm_backend_type) { + case Libdrm::Driver::ETNAVIV: return etnaviv_drm_mmap(offset, length); + case Libdrm::Driver::LIMA: return lima_drm_mmap(offset, length); + default: return NULL; + } +} + + +/** + * Unmap DRM buffer-object + */ +extern "C" int drm_munmap(void *addr, size_t length) +{ + (void)length; + + switch (drm_backend_type) { + case Libdrm::Driver::ETNAVIV: return etnaviv_drm_munmap(addr); + case Libdrm::Driver::LIMA: return lima_drm_munmap(addr); + default: return -1; + } +} + + +extern "C" int drm_poll(struct pollfd *fds, nfds_t nfds, int timeout) +{ + (void)timeout; + + if (nfds > 1) { + Genode::error(__func__, ": cannot handle more the 1 pollfd"); + return -1; + } + + switch (drm_backend_type) { + case Libdrm::Driver::ETNAVIV: return -1; + case Libdrm::Driver::LIMA: return lima_drm_poll(fds[0].fd); + default: return -1; + } +} diff --git a/repos/libports/src/lib/libdrm/ioctl_etnaviv.cc b/repos/libports/src/lib/libdrm/ioctl_etnaviv.cc index 8663f29536..2a1a44d765 100644 --- a/repos/libports/src/lib/libdrm/ioctl_etnaviv.cc +++ b/repos/libports/src/lib/libdrm/ioctl_etnaviv.cc @@ -21,7 +21,11 @@ #include #include +#include + extern "C" { +#include +#include #include #include #include @@ -34,6 +38,7 @@ extern "C" { enum { verbose_ioctl = false }; +namespace { /** * Get DRM command number @@ -103,8 +108,10 @@ const char *command_name(unsigned long request) } } +} /* anonymous namespace */ -namespace Drm { + +namespace Etnaviv { size_t get_payload_size(drm_etnaviv_gem_submit const &submit); @@ -126,7 +133,7 @@ namespace Drm { } /* anonymous namespace */ -size_t Drm::get_payload_size(drm_etnaviv_gem_submit const &submit) +size_t Etnaviv::get_payload_size(drm_etnaviv_gem_submit const &submit) { size_t size = 0; @@ -139,7 +146,7 @@ size_t Drm::get_payload_size(drm_etnaviv_gem_submit const &submit) } -void Drm::serialize(drm_etnaviv_gem_submit *submit, char *content) +void Etnaviv::serialize(drm_etnaviv_gem_submit *submit, char *content) { size_t offset = 0; @@ -202,7 +209,7 @@ void Drm::serialize(drm_etnaviv_gem_submit *submit, char *content) } -size_t Drm::get_payload_size(drm_version const &version) +size_t Etnaviv::get_payload_size(drm_version const &version) { size_t size = 0; size += version.name_len; @@ -212,7 +219,7 @@ size_t Drm::get_payload_size(drm_version const &version) } -void Drm::serialize(drm_version *version, char *content) +void Etnaviv::serialize(drm_version *version, char *content) { size_t offset = 0; char *start = 0; @@ -234,7 +241,7 @@ void Drm::serialize(drm_version *version, char *content) } -void Drm::deserialize(drm_version *version, char *content) +void Etnaviv::deserialize(drm_version *version, char *content) { drm_version *cversion = reinterpret_cast(content); @@ -256,8 +263,9 @@ void Drm::deserialize(drm_version *version, char *content) } -namespace Gpu { +namespace Etnaviv { using namespace Genode; + using namespace Gpu; struct Call; } /* namespace Gpu */ @@ -267,16 +275,16 @@ struct Gpu::Buffer { Gpu::Connection &_gpu; - Id_space::Element const _elem; + Genode::Id_space::Element const _elem; - Dataspace_capability const cap; - size_t const size; + Genode::Dataspace_capability const cap; + size_t const size; - Constructible _attached_buffer { }; + Genode::Constructible _attached_buffer { }; - Buffer(Gpu::Connection &gpu, - size_t size, - Id_space &space) + Buffer(Gpu::Connection &gpu, + size_t size, + Genode::Id_space &space) : _gpu { gpu }, _elem { *this, space }, @@ -310,7 +318,7 @@ struct Gpu::Buffer }; -class Gpu::Call +class Etnaviv::Call { private: @@ -320,14 +328,14 @@ class Gpu::Call Call(Call const &) = delete; Call &operator=(Call const &) = delete; - Genode::Env &_env; + Genode::Env &_env { *vfs_gpu_env() }; Genode::Heap _heap { _env.ram(), _env.rm() }; /***************** ** Gpu session ** *****************/ - Gpu::Connection _gpu_session; + Gpu::Connection _gpu_session { _env }; Gpu::Info_etnaviv const &_gpu_info { *_gpu_session.attached_info() }; @@ -475,7 +483,7 @@ class Gpu::Call int _drm_etnaviv_gem_submit(drm_etnaviv_gem_submit &arg) { - size_t const payload_size = Drm::get_payload_size(arg); + size_t const payload_size = Etnaviv::get_payload_size(arg); if (payload_size > EXEC_BUFFER_SIZE) { Genode::error(__func__, ": exec buffer too small (", (unsigned)EXEC_BUFFER_SIZE, ") needed ", payload_size); @@ -488,7 +496,7 @@ class Gpu::Call */ char *local_exec_buffer = (char*)_exec_buffer->mmap_addr(); Genode::memset(local_exec_buffer, 0, EXEC_BUFFER_SIZE); - Drm::serialize(&arg, local_exec_buffer); + Etnaviv::serialize(&arg, local_exec_buffer); try { Genode::uint64_t const pending_exec_buffer = @@ -592,17 +600,24 @@ class Gpu::Call int _drm_version(drm_version &version) { - static char buffer[1] = { '\0' }; - version.version_major = 1; version.version_minor = 3; version.version_patchlevel = 0; - version.name_len = 0; - version.name = buffer; - version.date_len = 0; - version.date = buffer; - version.desc_len = 0; - version.desc = buffer; + + /** + * Libdrm probes the length by calling version twice + * and the second time strings are allocated. + */ + + version.name_len = 1; + if (version.name) + version.name[0] = '\0'; + version.date_len = 1; + if (version.date) + version.date[0] = '\0'; + version.desc_len = 1; + if (version.desc) + version.desc[0] = '\0'; return 0; } @@ -629,10 +644,7 @@ class Gpu::Call public: - Call(Env &env) - : - _env { env }, - _gpu_session { _env } + Call() { try { _exec_buffer.construct(_gpu_session, @@ -674,18 +686,22 @@ class Gpu::Call }; -static Genode::Constructible _drm; +static Genode::Constructible _drm; -void drm_init(Genode::Env &env) +void etnaviv_drm_init() { - _drm.construct(env); + struct ::stat buf; + if (stat("/dev/gpu", &buf) < 0) { + Genode::error("'/dev/gpu' not accessible: ", + "try configure '' in 'dev' directory of VFS'"); + return; + } + + _drm.construct(); } -/** - * Dump I/O control request to LOG - */ static void dump_ioctl(unsigned long request) { using namespace Genode; @@ -699,10 +715,7 @@ static void dump_ioctl(unsigned long request) } -/** - * Perfom I/O control request - */ -extern "C" int genode_ioctl(int /* fd */, unsigned long request, void *arg) +int etnaviv_drm_ioctl(unsigned long request, void *arg) { if (verbose_ioctl) dump_ioctl(request); @@ -720,28 +733,14 @@ extern "C" int genode_ioctl(int /* fd */, unsigned long request, void *arg) } -/** - * Map DRM buffer-object - */ -void *drm_mmap(void *addr, size_t length, int prot, int flags, - int fd, off_t offset) +void *etnaviv_drm_mmap(off_t offset, size_t length) { - (void)addr; - (void)prot; - (void)flags; - (void)fd; - return _drm->mmap(offset, length); } -/** - * Unmap DRM buffer-object - */ -int drm_munmap(void *addr, size_t length) +int etnaviv_drm_munmap(void *addr) { - (void)length; - _drm->munmap(addr); return 0; } diff --git a/repos/libports/src/lib/libdrm/ioctl_lima.cc b/repos/libports/src/lib/libdrm/ioctl_lima.cc new file mode 100644 index 0000000000..358f0a0b06 --- /dev/null +++ b/repos/libports/src/lib/libdrm/ioctl_lima.cc @@ -0,0 +1,864 @@ +/* + * \brief DRM ioctl backend + * \author Sebastian Sumpf + * \author Josef Soentgen + * \date 2017-05-10 + */ + +/* + * Copyright (C) 2017-2022 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. + */ + +/* Genode includes */ +#include +#include +#include +#include +#include +#include +#include + +#include + +extern "C" { +#include +#include +#include +#include +#include +#include + +#include +#include +#include +} + + +enum { verbose_ioctl = false }; + + +/** + * Get DRM command number + */ +static unsigned long constexpr command_number(unsigned long request) +{ + return request & 0xffu; +} + + +/** + * Get device specific command number + */ +static unsigned long device_number(unsigned long request) +{ + return command_number(request) - DRM_COMMAND_BASE; +} + + +/** + * Check if request is device command + */ +static bool device_ioctl(unsigned long request) +{ + long const cmd = command_number(request); + return cmd >= DRM_COMMAND_BASE && cmd < DRM_COMMAND_END; +} + + +/** + * Return name of DRM command + */ +const char *command_name(unsigned long request) +{ + if (IOCGROUP(request) != DRM_IOCTL_BASE) + return ""; + + if (!device_ioctl(request)) { + switch (command_number(request)) { + case command_number(DRM_IOCTL_GEM_CLOSE): return "DRM_IOCTL_GEM_CLOSE"; + case command_number(DRM_IOCTL_GEM_FLINK): return "DRM_IOCTL_GEM_FLINK"; + case command_number(DRM_IOCTL_GEM_OPEN): return "DRM_IOCTL_GEM_OPEN"; + case command_number(DRM_IOCTL_GET_CAP): return "DRM_IOCTL_GET_CAP"; + case command_number(DRM_IOCTL_GET_UNIQUE): return "DRM_IOCTL_GET_UNIQUE"; + case command_number(DRM_IOCTL_PRIME_FD_TO_HANDLE): return "DRM_IOCTL_PRIME_FD_TO_HANDLE"; + case command_number(DRM_IOCTL_PRIME_HANDLE_TO_FD): return "DRM_IOCTL_PRIME_HANDLE_TO_FD"; + case command_number(DRM_IOCTL_SYNCOBJ_CREATE): return "DRM_IOCTL_SYNCOBJ_CREATE"; + case command_number(DRM_IOCTL_SYNCOBJ_DESTROY): return "DRM_IOCTL_SYNCOBJ_DESTROY"; + case command_number(DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD): return "DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD"; + case command_number(DRM_IOCTL_VERSION): return "DRM_IOCTL_VERSION"; + default: return ""; + } + } + + switch (device_number(request)) { + case DRM_LIMA_CTX_CREATE: return "DRM_LIMA_CTX_CREATE"; + case DRM_LIMA_CTX_FREE: return "DRM_LIMA_CTX_FREE"; + case DRM_LIMA_GET_PARAM: return "DRM_LIMA_GET_PARAM"; + case DRM_LIMA_GEM_CREATE: return "DRM_LIMA_GEM_CREATE"; + case DRM_LIMA_GEM_INFO: return "DRM_LIMA_GEM_INFO"; + case DRM_LIMA_GEM_SUBMIT: return "DRM_LIMA_GEM_SUBMIT"; + case DRM_LIMA_GEM_WAIT: return "DRM_LIMA_GEM_WAIT"; + default: return ""; + } +} + + +namespace Lima { + + size_t get_payload_size(drm_lima_gem_submit const &submit); + + // XXX better implement as 'size_t for_each_object(T const *t, unsigned len, FN const &fn, char *dst)' + template void for_each_object(T const *t, unsigned len, FN const &fn) + { + for (unsigned i = 0; i < len; i++) { + T const *obj = &t[i]; + fn(obj); + } + } + + void serialize(drm_lima_gem_submit *submit, char *content); + + size_t get_payload_size(drm_version const &version); + +} /* anonymous namespace */ + + +size_t Lima::get_payload_size(drm_lima_gem_submit const &submit) +{ + size_t size = 0; + + size += sizeof (drm_lima_gem_submit_bo) * submit.nr_bos; + size += submit.frame_size; + + return size; +} + + +void Lima::serialize(drm_lima_gem_submit *submit, char *content) +{ + size_t offset = 0; + + /* leave place for object itself first */ + offset += sizeof (*submit); + + /* next are the buffer-objects */ + if (submit->nr_bos) { + size_t const new_start = offset; + + auto copy_bos = [&] (drm_lima_gem_submit_bo const *bo) { + char * const dst = content + offset; + Genode::memcpy(dst, bo, sizeof (*bo)); + offset += sizeof (*bo); + }; + for_each_object((drm_lima_gem_submit_bo*)submit->bos, + submit->nr_bos, copy_bos); + submit->bos = reinterpret_cast<__u64>(new_start); + } + + /* next is the frame */ + { + size_t const new_start = offset; + + char * const dst = content + offset; + Genode::memcpy(dst, reinterpret_cast(submit->frame), submit->frame_size); + offset += submit->frame_size; + submit->frame = reinterpret_cast<__u64>(new_start); + } + + /* copy submit object last but into the front */ + Genode::memcpy(content, submit, sizeof (*submit)); +} + + +size_t Lima::get_payload_size(drm_version const &version) +{ + size_t size = 0; + size += version.name_len; + size += version.date_len; + size += version.desc_len; + return size; +} + + +namespace Lima { + using namespace Genode; + using namespace Gpu; + + struct Call; +} /* namespace Gpu */ + + +struct Gpu::Buffer +{ + Gpu::Connection &_gpu; + + Genode::Id_space::Element const _elem; + + Genode::Dataspace_capability const cap; + size_t const size; + + Genode::Constructible _attached_buffer { }; + + Buffer(Gpu::Connection &gpu, + size_t size, + Genode::Id_space &space) + : + _gpu { gpu }, + _elem { *this, space }, + cap { _gpu.alloc_buffer(_elem.id(), size) }, + size { size } + { } + + virtual ~Buffer() + { + _gpu.free_buffer(_elem.id()); + } + + bool mmap(Genode::Env &env) + { + if (!_attached_buffer.constructed()) { + _attached_buffer.construct(env.rm(), cap); + } + + return _attached_buffer.constructed(); + } + + Genode::addr_t mmap_addr() + { + return reinterpret_cast(_attached_buffer->local_addr()); + } + + Gpu::Buffer_id id() const + { + return _elem.id(); + } +}; + + +class Lima::Call +{ + private: + + /* + * Noncopyable + */ + Call(Call const &) = delete; + Call &operator=(Call const &) = delete; + + Genode::Env &_env { *vfs_gpu_env() }; + Genode::Heap _heap { _env.ram(), _env.rm() }; + + /***************** + ** Gpu session ** + *****************/ + + struct Gpu_context + { + int const fd; + unsigned long const _gpu_id; + + Gpu::Connection &_gpu { *vfs_gpu_connection(_gpu_id) }; + + using Id_space = Genode::Id_space; + Id_space::Element const _elem; + + Gpu_context(int fd, unsigned long gpu, + Genode::Id_space &space) + : fd { fd }, _gpu_id { gpu }, _elem { *this, space } { } + + virtual ~Gpu_context() + { + ::close(fd); + } + + unsigned long id() const + { + return _elem.id().value; + } + + Gpu::Connection& gpu() + { + return _gpu; + } + }; + + using Gpu_context_space = Genode::Id_space; + Gpu_context_space _gpu_context_space { }; + + Gpu_context &_create_ctx() + { + int const fd = ::open("/dev/gpu", 0); + if (fd < 0) { + Genode::error("Failed to open '/dev/gpu': ", + "try configure '' in 'dev' directory of VFS'"); + throw Gpu::Session::Invalid_state(); + } + + struct ::stat buf; + if (::fstat(fd, &buf) < 0) { + Genode::error("Could not stat '/dev/gpu'"); + ::close(fd); + throw Gpu::Session::Invalid_state(); + } + Gpu_context * context = + new (_heap) Gpu_context(fd, buf.st_ino, _gpu_context_space); + + return *context; + } + + struct Syncobj + { + /* + * Noncopyable + */ + Syncobj(Syncobj const &) = delete; + Syncobj &operator=(Syncobj const &) = delete; + + + Gpu_context *_gc { nullptr }; + Gpu::Sequence_number _seqno { 0 }; + + using Id_space = Genode::Id_space; + Id_space::Element const _elem; + + Syncobj(Id_space &space) + : _elem { *this, space } { } + + unsigned long id() const + { + return _elem.id().value; + } + + void adopt(Gpu_context &gc, Gpu::Sequence_number seqno) + { + _gc = &gc; + _seqno = seqno; + } + + Gpu_context &gpu_context() + { + if (!_gc) { + struct Invalid_gpu_context { }; + throw Invalid_gpu_context(); + } + + return *_gc; + } + + Gpu::Sequence_number seqno() const + { + return _seqno; + } + }; + Genode::Id_space _syncobj_space { }; + + struct Gpu_session + { + int const fd; + unsigned long const id; + + Gpu_session(int fd, unsigned long id) + : fd { fd }, id { id } { } + + virtual ~Gpu_session() + { + ::close(fd); + } + + Gpu::Connection &gpu() + { + return *vfs_gpu_connection(id); + } + }; + + Gpu_session _open_gpu() + { + int const fd = ::open("/dev/gpu", 0); + if (fd < 0) { + Genode::error("Failed to open '/dev/gpu': ", + "try configure '' in 'dev' directory of VFS'"); + throw Gpu::Session::Invalid_state(); + } + + struct ::stat buf; + if (::fstat(fd, &buf) < 0) { + Genode::error("Could not stat '/dev/gpu'"); + ::close(fd); + throw Gpu::Session::Invalid_state(); + } + + return Gpu_session { fd, buf.st_ino }; + } + + Gpu_session _gpu_session { _open_gpu() }; + + Gpu::Connection &_gpu { _gpu_session.gpu() }; + Gpu::Info_lima const &_gpu_info { + *_gpu.attached_info() }; + + Id_space _buffer_space { }; + + /* + * Play it safe, glmark2 apparently submits araound 110 KiB at + * some point. + */ + enum { EXEC_BUFFER_SIZE = 256u << 10 }; + Constructible _exec_buffer { }; + + void _wait_for_mapping(uint32_t handle, unsigned op) + { + Buffer_id const id { .value = handle }; + do { + if (_gpu.set_tiling(id, op)) + break; + + char buf; + (void)::read(_gpu_session.fd, &buf, sizeof(buf)); + } while (true); + } + + void _wait_for_syncobj(unsigned int handle) + { + Syncobj::Id_space::Id syncobj_id { .value = handle }; + + try { + auto wait = [&] (Syncobj &sync_obj) { + + Gpu_context &gc = sync_obj.gpu_context(); + do { + if (gc.gpu().complete(sync_obj.seqno())) + break; + + char buf; + (void)::read(gc.fd, &buf, sizeof(buf)); + } while (true); + }; + _syncobj_space.apply(syncobj_id, wait); + } catch (Genode::Id_space::Unknown_id) { } + } + + template + bool _apply_handle(uint32_t handle, FN const &fn) + { + Buffer_id const id { .value = handle }; + + bool found = false; + _buffer_space.apply(id, [&] (Buffer &b) { + fn(b); + found = true; + }); + + return found; + } + + Dataspace_capability _lookup_cap_from_handle(uint32_t handle) + { + Dataspace_capability cap { }; + auto lookup_cap = [&] (Buffer const &b) { + cap = b.cap; + }; + (void)_apply_handle(handle, lookup_cap); + return cap; + } + + /****************************** + ** Device DRM I/O controls ** + ******************************/ + + int _drm_lima_gem_info(drm_lima_gem_info &arg) + { + int result = -1; + (void)_apply_handle(arg.handle, [&] (Buffer &b) { + if (!b.mmap(_env)) + return; + arg.offset = reinterpret_cast<::uint64_t>(b.mmap_addr()); + + Gpu::addr_t const va = _gpu.query_buffer_ppgtt(b.id()); + if (va == (Gpu::addr_t)-1) + return; + arg.va = (uint32_t)va; + + result = 0; + }); + + return result; + } + + template + void _alloc_buffer(::uint64_t const size, FUNC const &fn) + { + size_t donate = size; + Buffer *buffer = nullptr; + + retry( + [&] () { + retry( + [&] () { + buffer = + new (&_heap) Buffer(_gpu, size, + _buffer_space); + }, + [&] () { + _gpu.upgrade_caps(2); + }); + }, + [&] () { + _gpu.upgrade_ram(donate); + }); + + if (buffer) + fn(*buffer); + } + + int _drm_lima_gem_create(drm_lima_gem_create &arg) + { + ::uint64_t const size = arg.size; + + try { + _alloc_buffer(size, [&](Buffer const &b) { + arg.handle = b.id().value; + }); + return 0; + } catch (...) { + return -1; + } + } + + int _drm_lima_gem_submit(drm_lima_gem_submit &arg) + { + Gpu_context::Id_space::Id ctx_id { .value = arg.ctx }; + + Syncobj::Id_space::Id syncobj_id { .value = arg.out_sync }; + + bool result = false; + _syncobj_space.apply(syncobj_id, [&] (Syncobj &sync_obj) { + + _gpu_context_space.apply(ctx_id, [&] (Gpu_context &gc) { + + size_t const payload_size = Lima::get_payload_size(arg); + if (payload_size > EXEC_BUFFER_SIZE) { + Genode::error(__func__, ": exec buffer too small (", + (unsigned)EXEC_BUFFER_SIZE, ") needed ", payload_size); + return; + } + + /* + * Copy each array flat to the exec buffer and adjust the + * addresses in the submit object. + */ + char *local_exec_buffer = (char*)_exec_buffer->mmap_addr(); + Genode::memset(local_exec_buffer, 0, EXEC_BUFFER_SIZE); + Lima::serialize(&arg, local_exec_buffer); + + try { + Gpu::Connection &gpu = gc.gpu(); + + Gpu::Sequence_number const seqno = + gpu.exec_buffer(_exec_buffer->id(), EXEC_BUFFER_SIZE); + + sync_obj.adopt(gc, seqno); + + result = true; + } catch (Gpu::Session::Invalid_state) { } + }); + }); + + return result ? 0 : -1; + } + + int _drm_lima_gem_wait(drm_lima_gem_wait &arg) + { + /* + * For the moment we do not handle timeouts + */ + (void)arg.timeout_ns; + _wait_for_mapping(arg.handle, arg.op); + return 0; + } + + int _drm_lima_get_param(drm_lima_get_param &arg) + { + if (arg.param > Gpu::Info_lima::MAX_LIMA_PARAMS) { + errno = EINVAL; + return -1; + } + + arg.value = _gpu_info.param[arg.param]; + return 0; + } + + int _drm_lima_ctx_create(drm_lima_ctx_create &arg) + { + try { + Gpu_context &ctx = _create_ctx(); + + arg.id = ctx.id(); + return 0; + } catch (... /* intentional catch-all ... */) { + /* ... as the lima GPU driver will not throw */ + } + return -1; + } + + int _drm_lima_ctx_free(drm_lima_ctx_free &arg) + { + Gpu_context::Id_space::Id id { .value = arg.id }; + + bool result = false; + auto free_ctx = [&] (Gpu_context &ctx) { + ::close(ctx.fd); + Genode::destroy(_heap, &ctx); + result = true; + }; + _gpu_context_space.apply(id, free_ctx); + + return result ? 0 : -1; + } + + int _device_ioctl(unsigned cmd, void *arg) + { + if (!arg) { + errno = EINVAL; + return -1; + } + + switch (cmd) { + case DRM_LIMA_CTX_CREATE: + return _drm_lima_ctx_create(*reinterpret_cast(arg)); + case DRM_LIMA_CTX_FREE: + return _drm_lima_ctx_free(*reinterpret_cast(arg)); + case DRM_LIMA_GEM_INFO: + return _drm_lima_gem_info(*reinterpret_cast(arg)); + case DRM_LIMA_GEM_CREATE: + return _drm_lima_gem_create(*reinterpret_cast(arg)); + case DRM_LIMA_GEM_SUBMIT: + return _drm_lima_gem_submit(*reinterpret_cast(arg)); + case DRM_LIMA_GEM_WAIT: + return _drm_lima_gem_wait(*reinterpret_cast(arg)); + case DRM_LIMA_GET_PARAM: + return _drm_lima_get_param(*reinterpret_cast(arg)); + default: break; + } + + return 0; + } + + /******************************* + ** Generic DRM I/O controls ** + *******************************/ + + int _drm_gem_close(drm_gem_close const &gem_close) + { + return _apply_handle(gem_close.handle, + [&] (Gpu::Buffer &b) { + destroy(_heap, &b); + }) ? 0 : -1; + } + + int _drm_version(drm_version &version) + { + version.version_major = 1; + version.version_minor = 1; + version.version_patchlevel = 0; + + /** + * Libdrm probes the length by calling version twice + * and the second time strings are allocated. + */ + + version.name_len = 1; + if (version.name) + version.name[0] = '\0'; + version.date_len = 1; + if (version.date) + version.date[0] = '\0'; + version.desc_len = 1; + if (version.desc) + version.desc[0] = '\0'; + + return 0; + } + + int _drm_syncobj_create(drm_syncobj_create &arg) + { + try { + Syncobj *obj = new (_heap) Syncobj(_syncobj_space); + arg.handle = (uint32_t)obj->id(); + return 0; + } catch (... /* XXX which exceptions can occur? */) { } + return -1; + } + + int _drm_syncobj_destroy(drm_syncobj_destroy &arg) + { + Syncobj::Id_space::Id id { .value = arg.handle }; + + bool result = false; + _syncobj_space.apply(id, [&] (Syncobj &obj) { + Genode::destroy(_heap, &obj); + result = true; + }); + return result ? 0 : -1; + } + + int _drm_syncobj_handle_to_fd(drm_syncobj_handle &arg) + { + arg.fd = arg.handle + SYNC_FD; + return 0; + } + + int _generic_ioctl(unsigned cmd, void *arg) + { + if (!arg) { + errno = EINVAL; + return -1; + } + + switch (cmd) { + case command_number(DRM_IOCTL_GEM_CLOSE): + return _drm_gem_close(*reinterpret_cast(arg)); + case command_number(DRM_IOCTL_VERSION): + return _drm_version(*reinterpret_cast(arg)); + case command_number(DRM_IOCTL_SYNCOBJ_CREATE): + return _drm_syncobj_create(*reinterpret_cast(arg)); + case command_number(DRM_IOCTL_SYNCOBJ_DESTROY): + return _drm_syncobj_destroy(*reinterpret_cast(arg)); + case command_number(DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD): + return _drm_syncobj_handle_to_fd(*reinterpret_cast(arg)); + default: + error("unhandled generic DRM ioctl: ", Genode::Hex(cmd)); + break; + } + + return -1; + } + + + public: + + static constexpr int const SYNC_FD { 384 }; + + Call() + { + try { + _exec_buffer.construct(_gpu, + (size_t)EXEC_BUFFER_SIZE, + _buffer_space); + } catch (...) { + throw Gpu::Session::Invalid_state(); + } + if (!_exec_buffer->mmap(_env)) + throw Gpu::Session::Invalid_state(); + } + + ~Call() + { + while (_gpu_context_space.apply_any([&] (Gpu_context &ctx) { + Genode::destroy(_heap, &ctx); })) { ; } + + while (_syncobj_space.apply_any([&] (Syncobj &obj) { + Genode::destroy(_heap, &obj); })) { ; } + } + + int ioctl(unsigned long request, void *arg) + { + bool const device_request = device_ioctl(request); + return device_request ? _device_ioctl(device_number(request), arg) + : _generic_ioctl(command_number(request), arg); + } + + void *mmap(unsigned long offset, unsigned long /* size */) + { + /* + * Buffer should have been mapped during GEM INFO call. + */ + return (void*)offset; + } + + void munmap(void *addr) + { + /* + * We rely on GEM CLOSE to destroy the buffer and thereby + * to remove the local mapping. AFAICT the 'munmap' is indeed + * (always) followed by the CLOSE I/O control. + */ + (void)addr; + } + + void wait_for_syncobj(unsigned int handle) + { + _wait_for_syncobj(handle); + } +}; + + +static Genode::Constructible _drm; + + +void lima_drm_init() +{ + /* make sure VFS is initialized */ + struct ::stat buf; + if (stat("/dev/gpu", &buf) < 0) { + Genode::error("'/dev/gpu' not accessible: ", + "try configure '' in 'dev' directory of VFS'"); + return; + } + + _drm.construct(); +} + + +static void dump_ioctl(unsigned long request) +{ + using namespace Genode; + + log("ioctl(request=", Hex(request), + (request & 0xe0000000u) == IOC_OUT ? " out" : + (request & 0xe0000000u) == IOC_IN ? " in" : + (request & 0xe0000000u) == IOC_INOUT ? " inout" : " void", + " len=", IOCPARM_LEN(request), + " cmd=", command_name(request), " (", Hex(command_number(request)), "))"); +} + + +int lima_drm_ioctl(unsigned long request, void *arg) +{ + if (verbose_ioctl) + dump_ioctl(request); + + try { + int ret = _drm->ioctl(request, arg); + + if (verbose_ioctl) + Genode::log("returned ", ret); + + return ret; + } catch (...) { } + + return -1; +} + + +void *lima_drm_mmap(off_t offset, size_t length) +{ + return _drm->mmap(offset, length); +} + + +int lima_drm_munmap(void *addr) +{ + _drm->munmap(addr); + return 0; +} + + +int lima_drm_poll(int fd) +{ + int const handle = fd - Lima::Call::SYNC_FD; + _drm->wait_for_syncobj((unsigned)handle); + return 0; +} diff --git a/repos/libports/src/lib/mesa/etnaviv/drm_init.cc b/repos/libports/src/lib/mesa/etnaviv/drm_init.cc index a49db15b3a..90a8306551 100644 --- a/repos/libports/src/lib/mesa/etnaviv/drm_init.cc +++ b/repos/libports/src/lib/mesa/etnaviv/drm_init.cc @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2021 Genode Labs GmbH + * Copyright (C) 2021-2022 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. @@ -15,13 +15,13 @@ #include <../include/util/list.h> #include +#include + extern "C" { #include } -extern void drm_init(Genode::Env &env); - void genode_drm_init() { - drm_init(*genode_env); + drm_init(Libdrm::Driver::ETNAVIV); } diff --git a/repos/libports/src/lib/mesa/etnaviv/target.mk b/repos/libports/src/lib/mesa/etnaviv/target.mk deleted file mode 100644 index 0037f20053..0000000000 --- a/repos/libports/src/lib/mesa/etnaviv/target.mk +++ /dev/null @@ -1 +0,0 @@ -LIBS := mesa_gpu-etnaviv diff --git a/repos/libports/src/lib/mesa/files.list b/repos/libports/src/lib/mesa/files.list index 2139e3ea97..153d765346 100644 --- a/repos/libports/src/lib/mesa/files.list +++ b/repos/libports/src/lib/mesa/files.list @@ -285,6 +285,7 @@ mesa-21.0.0/src/compiler/nir/nir_lower_double_ops.c mesa-21.0.0/src/compiler/nir/nir_lower_drawpixels.c mesa-21.0.0/src/compiler/nir/nir_lower_flatshade.c mesa-21.0.0/src/compiler/nir/nir_lower_flrp.c +mesa-21.0.0/src/compiler/nir/nir_lower_fragcoord_wtrans.c mesa-21.0.0/src/compiler/nir/nir_lower_frexp.c mesa-21.0.0/src/compiler/nir/nir_lower_global_vars_to_local.c mesa-21.0.0/src/compiler/nir/nir_lower_goto_ifs.c @@ -305,6 +306,7 @@ mesa-21.0.0/src/compiler/nir/nir_lower_passthrough_edgeflags.c mesa-21.0.0/src/compiler/nir/nir_lower_patch_vertices.c mesa-21.0.0/src/compiler/nir/nir_lower_phis_to_scalar.c mesa-21.0.0/src/compiler/nir/nir_lower_pntc_ytransform.c +mesa-21.0.0/src/compiler/nir/nir_lower_point_size.c mesa-21.0.0/src/compiler/nir/nir_lower_point_size_mov.c mesa-21.0.0/src/compiler/nir/nir_lower_regs_to_ssa.c mesa-21.0.0/src/compiler/nir/nir_lower_returns.c @@ -320,6 +322,7 @@ mesa-21.0.0/src/compiler/nir/nir_lower_var_copies.c mesa-21.0.0/src/compiler/nir/nir_lower_variable_initializers.c mesa-21.0.0/src/compiler/nir/nir_lower_vars_to_ssa.c mesa-21.0.0/src/compiler/nir/nir_lower_vec_to_movs.c +mesa-21.0.0/src/compiler/nir/nir_lower_viewport_transform.c mesa-21.0.0/src/compiler/nir/nir_lower_wpos_ytransform.c mesa-21.0.0/src/compiler/nir/nir_metadata.c mesa-21.0.0/src/compiler/nir/nir_move_vec_src_uses_to_dest.c @@ -733,6 +736,7 @@ mesa-21.0.0/src/gallium/auxiliary/util/u_screen.c mesa-21.0.0/src/gallium/auxiliary/util/u_screen.h mesa-21.0.0/src/gallium/auxiliary/util/u_simple_shaders.c mesa-21.0.0/src/gallium/auxiliary/util/u_simple_shaders.h +mesa-21.0.0/src/gallium/auxiliary/util/u_split_draw.c mesa-21.0.0/src/gallium/auxiliary/util/u_split_draw.h mesa-21.0.0/src/gallium/auxiliary/util/u_split_prim.h mesa-21.0.0/src/gallium/auxiliary/util/u_sse.h @@ -841,6 +845,63 @@ mesa-21.0.0/src/gallium/drivers/etnaviv/hw/state_3d.xml.h mesa-21.0.0/src/gallium/drivers/etnaviv/hw/state_blt.xml.h mesa-21.0.0/src/gallium/drivers/etnaviv/hw/state.xml.h mesa-21.0.0/src/gallium/drivers/etnaviv/hw/texdesc_3d.xml.h + +mesa-21.0.0/src/gallium/drivers/lima/ir/gp/codegen.c +mesa-21.0.0/src/gallium/drivers/lima/ir/gp/codegen.h +mesa-21.0.0/src/gallium/drivers/lima/ir/gp/disasm.c +mesa-21.0.0/src/gallium/drivers/lima/ir/gp/gpir.h +mesa-21.0.0/src/gallium/drivers/lima/ir/gp/instr.c +mesa-21.0.0/src/gallium/drivers/lima/ir/gp/lower.c +mesa-21.0.0/src/gallium/drivers/lima/ir/gp/nir.c +mesa-21.0.0/src/gallium/drivers/lima/ir/gp/node.c +mesa-21.0.0/src/gallium/drivers/lima/ir/gp/optimize.c +mesa-21.0.0/src/gallium/drivers/lima/ir/gp/reduce_scheduler.c +mesa-21.0.0/src/gallium/drivers/lima/ir/gp/regalloc.c +mesa-21.0.0/src/gallium/drivers/lima/ir/gp/scheduler.c +mesa-21.0.0/src/gallium/drivers/lima/ir/lima_ir.h +mesa-21.0.0/src/gallium/drivers/lima/ir/lima_nir_algebraic.py +mesa-21.0.0/src/gallium/drivers/lima/ir/lima_nir_duplicate_consts.c +mesa-21.0.0/src/gallium/drivers/lima/ir/lima_nir_duplicate_intrinsic.c +mesa-21.0.0/src/gallium/drivers/lima/ir/lima_nir_lower_uniform_to_scalar.c +mesa-21.0.0/src/gallium/drivers/lima/ir/lima_nir_split_load_input.c +mesa-21.0.0/src/gallium/drivers/lima/ir/pp/codegen.c +mesa-21.0.0/src/gallium/drivers/lima/ir/pp/codegen.h +mesa-21.0.0/src/gallium/drivers/lima/ir/pp/disasm.c +mesa-21.0.0/src/gallium/drivers/lima/ir/pp/instr.c +mesa-21.0.0/src/gallium/drivers/lima/ir/pp/liveness.c +mesa-21.0.0/src/gallium/drivers/lima/ir/pp/lower.c +mesa-21.0.0/src/gallium/drivers/lima/ir/pp/nir.c +mesa-21.0.0/src/gallium/drivers/lima/ir/pp/node.c +mesa-21.0.0/src/gallium/drivers/lima/ir/pp/node_to_instr.c +mesa-21.0.0/src/gallium/drivers/lima/ir/pp/ppir.h +mesa-21.0.0/src/gallium/drivers/lima/ir/pp/regalloc.c +mesa-21.0.0/src/gallium/drivers/lima/ir/pp/scheduler.c +mesa-21.0.0/src/gallium/drivers/lima/lima_bo.c +mesa-21.0.0/src/gallium/drivers/lima/lima_bo.h +mesa-21.0.0/src/gallium/drivers/lima/lima_context.c +mesa-21.0.0/src/gallium/drivers/lima/lima_context.h +mesa-21.0.0/src/gallium/drivers/lima/lima_draw.c +mesa-21.0.0/src/gallium/drivers/lima/lima_fence.c +mesa-21.0.0/src/gallium/drivers/lima/lima_fence.h +mesa-21.0.0/src/gallium/drivers/lima/lima_format.c +mesa-21.0.0/src/gallium/drivers/lima/lima_format.h +mesa-21.0.0/src/gallium/drivers/lima/lima_gpu.h +mesa-21.0.0/src/gallium/drivers/lima/lima_job.c +mesa-21.0.0/src/gallium/drivers/lima/lima_job.h +mesa-21.0.0/src/gallium/drivers/lima/lima_parser.c +mesa-21.0.0/src/gallium/drivers/lima/lima_parser.h +mesa-21.0.0/src/gallium/drivers/lima/lima_program.c +mesa-21.0.0/src/gallium/drivers/lima/lima_program.h +mesa-21.0.0/src/gallium/drivers/lima/lima_query.c +mesa-21.0.0/src/gallium/drivers/lima/lima_resource.c +mesa-21.0.0/src/gallium/drivers/lima/lima_resource.h +mesa-21.0.0/src/gallium/drivers/lima/lima_screen.c +mesa-21.0.0/src/gallium/drivers/lima/lima_screen.h +mesa-21.0.0/src/gallium/drivers/lima/lima_state.c +mesa-21.0.0/src/gallium/drivers/lima/lima_texture.c +mesa-21.0.0/src/gallium/drivers/lima/lima_texture.h +mesa-21.0.0/src/gallium/drivers/lima/lima_util.c +mesa-21.0.0/src/gallium/drivers/lima/lima_util.h mesa-21.0.0/src/gallium/drivers/softpipe/sp_buffer.c mesa-21.0.0/src/gallium/drivers/softpipe/sp_buffer.h mesa-21.0.0/src/gallium/drivers/softpipe/sp_clear.c @@ -934,6 +995,8 @@ mesa-21.0.0/src/gallium/include/pipe/p_video_state.h mesa-21.0.0/src/gallium/targets/dri/target.c mesa-21.0.0/src/gallium/winsys/etnaviv/drm/etnaviv_drm_public.h mesa-21.0.0/src/gallium/winsys/etnaviv/drm/etnaviv_drm_winsys.c +mesa-21.0.0/src/gallium/winsys/lima/drm/lima_drm_winsys.c +mesa-21.0.0/src/gallium/winsys/lima/drm/lima_drm_public.h mesa-21.0.0/src/gallium/winsys/sw/dri/dri_sw_winsys.c mesa-21.0.0/src/gallium/winsys/sw/dri/dri_sw_winsys.h mesa-21.0.0/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.h @@ -1584,6 +1647,10 @@ mesa-21.0.0/src/mesa/x86/norm_args.h mesa-21.0.0/src/mesa/x86/sse.h mesa-21.0.0/src/mesa/x86/x86_xform.h mesa-21.0.0/src/mesa/x86/xform_args.h +mesa-21.0.0/src/panfrost/shared/pan_minmax_cache.c +mesa-21.0.0/src/panfrost/shared/pan_minmax_cache.h +mesa-21.0.0/src/panfrost/shared/pan_tiling.c +mesa-21.0.0/src/panfrost/shared/pan_tiling.h mesa-21.0.0/src/util/anon_file.h mesa-21.0.0/src/util/bigmath.h mesa-21.0.0/src/util/bitscan.h diff --git a/repos/libports/src/lib/mesa/iris/target.mk b/repos/libports/src/lib/mesa/iris/target.mk deleted file mode 100644 index c103ff56f7..0000000000 --- a/repos/libports/src/lib/mesa/iris/target.mk +++ /dev/null @@ -1,2 +0,0 @@ -TARGET = dummy-mesa_gpu-iris -LIBS = mesa_gpu-iris diff --git a/repos/libports/src/lib/mesa/lima/drm_init.cc b/repos/libports/src/lib/mesa/lima/drm_init.cc new file mode 100644 index 0000000000..53c9ab7e6f --- /dev/null +++ b/repos/libports/src/lib/mesa/lima/drm_init.cc @@ -0,0 +1,27 @@ +/** + * \brief Initialize DRM libraries session interface + * \author Josef Soentgen + * \date 2021-04-30 + */ + +/* + * Copyright (C) 2021-2022 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. + */ + +/* Genode includes */ +#include <../include/util/list.h> +#include + +#include + +extern "C" { +#include +} + +void genode_drm_init(void) +{ + drm_init(Libdrm::Driver::LIMA); +} diff --git a/repos/libports/src/lib/mesa/lima/platform_lima.c b/repos/libports/src/lib/mesa/lima/platform_lima.c new file mode 100644 index 0000000000..ae0e1053e0 --- /dev/null +++ b/repos/libports/src/lib/mesa/lima/platform_lima.c @@ -0,0 +1,269 @@ +/** + * \brief lima (mali) EGL-DRI2 back end + * \author Sebastian Sumpf + * \author Josef Soentgen + * \date 2021-04-30 + */ + +/* + * Copyright (C) 2021-2022 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. + */ +/* + * Mesa + */ +#include +#include +/* + * Libc + */ +#include +#include + +/* + * Local + */ +#include + + +static int stride(int value) +{ + /* 32-bit RGB888 */ + return value * 4; +} + + +static void +dri2_genode_lima_put_image(__DRIdrawable * draw, int op, + int x, int y, int w, int h, + char *data, void *loaderPrivate) +{ + struct dri2_egl_surface *dri2_surf = loaderPrivate; + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); + struct Genode_egl_window *window = dri2_surf->g_win; + unsigned char *dst = window->addr; + + int src_stride; + int dst_stride = stride(dri2_surf->base.Width); + dri2_dpy->image->queryImage(dri2_surf->back_image, __DRI_IMAGE_ATTRIB_STRIDE, &src_stride); + + int copy_width = src_stride; + int x_offset = stride(x); + + dst += x_offset; + dst += y * dst_stride; + + /* copy width over stride boundary */ + if (copy_width > dst_stride - x_offset) + copy_width = dst_stride - x_offset; + + /* limit height */ + if (h > dri2_surf->base.Height - y) + h = dri2_surf->base.Height - y; + + /* copy to frame buffer and refresh */ + genode_blit(data, src_stride, dst, dst_stride, copy_width, h); +} + + +static EGLBoolean +dri2_genode_lima_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw) +{ + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); + + dri2_flush_drawable_for_swapbuffers(disp, draw); + dri2_dpy->flush->invalidate(dri2_surf->dri_drawable); + + _EGLContext *ctx = _eglGetCurrentContext(); + struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); + void *map_data = NULL; + int stride; + void *data = + dri2_dpy->image->mapImage(dri2_ctx->dri_context, dri2_surf->back_image, + 0, 0, + dri2_surf->base.Width, + dri2_surf->base.Height, + __DRI_IMAGE_TRANSFER_READ, &stride, + &map_data); + if (data) { + dri2_genode_lima_put_image(dri2_surf->dri_drawable, 0, 0, 0, + dri2_surf->base.Width, dri2_surf->base.Height, + (char *)data, (void *)dri2_surf); + + dri2_dpy->image->unmapImage(dri2_ctx->dri_context, + dri2_surf->back_image, map_data); + } + + return EGL_TRUE; +} + + +static struct dri2_egl_display_vtbl dri2_genode_display_vtbl = { + .authenticate = NULL, + .create_window_surface = dri2_genode_create_window_surface, + .create_pixmap_surface = dri2_genode_create_pixmap_surface, + .destroy_surface = dri2_genode_destroy_surface, + .swap_interval = dri2_genode_swap_interval, + .swap_buffers = dri2_genode_lima_swap_buffers, + .get_dri_drawable = dri2_surface_get_dri_drawable, +}; + + +static __DRIbuffer * +dri2_genode_get_buffers(__DRIdrawable * driDrawable, + int *width, int *height, + unsigned int *attachments, int count, + int *out_count, void *loaderPrivate) +{ + _eglError(EGL_BAD_PARAMETER, "dri2_genode_get_buffers not implemented"); + *out_count = 0; + return NULL; +} + + +static void +dri2_genode_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate) +{ + _eglError(EGL_BAD_PARAMETER, "dri2_genode_flush_front_buffer not implemented"); +} + + +static __DRIbuffer * +dri2_genode_get_buffers_with_format(__DRIdrawable * driDrawable, + int *width, int *height, + unsigned int *attachments, int count, + int *out_count, void *loaderPrivate) +{ + _eglError(EGL_BAD_PARAMETER, "dri2_genode_get_buffers_with_format not implemented"); + *out_count = 0; + return NULL; +} + + +static int +dri2_genode_image_get_buffers(__DRIdrawable *driDrawable, + unsigned int format, + uint32_t *stamp, + void *loaderPrivate, + uint32_t buffer_mask, + struct __DRIimageList *buffers) +{ + struct dri2_egl_surface *dri2_surf = loaderPrivate; + + buffers->image_mask = 0; + buffers->front = NULL; + buffers->back = NULL; + + buffers->image_mask = __DRI_IMAGE_BUFFER_BACK; + buffers->back = dri2_surf->back_image; + + return 1; +} + + +static const __DRIdri2LoaderExtension dri2_loader_extension = { + .base = { __DRI_DRI2_LOADER, 3 }, + + .getBuffers = dri2_genode_get_buffers, + .flushFrontBuffer = dri2_genode_flush_front_buffer, + .getBuffersWithFormat = dri2_genode_get_buffers_with_format, +}; + + +static const __DRIimageLoaderExtension image_loader_extension = { + .base = { __DRI_IMAGE_LOADER, 1 }, + .getBuffers = dri2_genode_image_get_buffers, + .flushFrontBuffer = dri2_genode_flush_front_buffer, +}; + +static const __DRIextension *dri2_loader_extensions[] = { + &dri2_loader_extension.base, + &image_loader_extension.base, + &image_lookup_extension.base, + &background_callable_extension.base, + NULL, +}; + + + +static EGLBoolean dri2_initialize_genode_lima(_EGLDisplay *disp) +{ + struct dri2_egl_display *dri2_dpy; + static int rgb888_shifts[4] = { 16, 8, 0, 24 }; + static unsigned rgb888_sizes[4] = { 8, 8, 8, 8 }; + int i; + + /* initialize DRM back end */ + genode_drm_init(); + + dri2_dpy = calloc(1, sizeof *dri2_dpy); + if (!dri2_dpy) + return _eglError(EGL_BAD_ALLOC, "eglInitialize"); + + dri2_dpy->fd = 44; + dri2_dpy->driver_name = strdup("lima"); + + disp->DriverData = (void *)dri2_dpy; + if (!dri2_load_driver_dri3(disp)) + goto close_driver; + + dri2_dpy->dri2_major = 2; + dri2_dpy->dri2_minor = __DRI_DRI2_VERSION; + + dri2_dpy->loader_extensions = dri2_loader_extensions; + + /* + * The driver extensions are queried by the loader, where the + * extensions point to '__driDriverGetExtensions_lima' that + * in return is wraps the 'galliumdrm_driver_extensions'. + * The the third entry in the 'galliumdrm_driver_extensions' array + * points 'driDRI2Extension.base', which is the extension we are + * interested in. + * + * extern const __DRIextension **__driDriverGetExtensions_lima(void); + * dri2_dpy->driver_extensions = __driDriverGetExtensions_lima(); + */ + dri2_dpy->dri2 = (const __DRIdri2Extension*)dri2_dpy->driver_extensions[2]; + + if (!dri2_create_screen(disp)) + goto close_screen; + + if (!dri2_setup_extensions(disp)) + goto close_screen; + + dri2_setup_screen(disp); + + EGLint attrs[] = { + EGL_DEPTH_SIZE, 0, /* set in loop below (from DRI config) */ + EGL_NATIVE_VISUAL_TYPE, 0, + EGL_NATIVE_VISUAL_ID, 0, + EGL_NONE }; + + for (i = 0; dri2_dpy->driver_configs[i]; i++) { + /* set depth size in attrs */ + attrs[1] = dri2_dpy->driver_configs[i]->modes.depthBits; + dri2_add_config(disp, dri2_dpy->driver_configs[i], i, + EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT, + attrs, rgb888_shifts, rgb888_sizes); + } + + dri2_dpy->vtbl = &dri2_genode_display_vtbl; + + return EGL_TRUE; + +close_screen: + dlclose(dri2_dpy->driver); +close_driver: + free(dri2_dpy); + + return EGL_FALSE; +} + + +EGLBoolean dri2_initialize_genode_backend(_EGLDisplay *disp) +{ + return dri2_initialize_genode_lima(disp); +} diff --git a/repos/libports/src/lib/mesa/patches/lima.patch b/repos/libports/src/lib/mesa/patches/lima.patch new file mode 100644 index 0000000000..a8cc8a9243 --- /dev/null +++ b/repos/libports/src/lib/mesa/patches/lima.patch @@ -0,0 +1,12 @@ +--- a/src/lib/mesa/src/loader/loader.c +--- b/src/lib/mesa/src/loader/loader.c +@@ -473,6 +473,9 @@ + if (fd == 43) { + return strdup("iris"); + } ++ if (fd == 44) { ++ return strdup("lima"); ++ } + char *driver; + + /* Allow an environment variable to force choosing a different driver diff --git a/repos/libports/src/lib/mesa/patches/sync_wait.patch b/repos/libports/src/lib/mesa/patches/sync_wait.patch new file mode 100644 index 0000000000..e64e0754f2 --- /dev/null +++ b/repos/libports/src/lib/mesa/patches/sync_wait.patch @@ -0,0 +1,20 @@ +--- a/src/lib/mesa/src/util/libsync.h ++++ b/src/lib/mesa/src/util/libsync.h +@@ -65,6 +65,8 @@ + #define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 3, struct sync_merge_data) + #endif + ++extern int drm_poll(struct pollfd *, nfds_t, int); ++ + static inline int sync_wait(int fd, int timeout) + { + struct pollfd fds = {0}; +@@ -74,7 +76,7 @@ + fds.events = POLLIN; + + do { +- ret = poll(&fds, 1, timeout); ++ ret = drm_poll(&fds, 1, timeout); + if (ret > 0) { + if (fds.revents & (POLLERR | POLLNVAL)) { + errno = EINVAL; diff --git a/repos/libports/src/lib/mesa/softpipe/target.mk b/repos/libports/src/lib/mesa/softpipe/target.mk deleted file mode 100644 index 682115dbee..0000000000 --- a/repos/libports/src/lib/mesa/softpipe/target.mk +++ /dev/null @@ -1 +0,0 @@ -LIBS := mesa_gpu-softpipe diff --git a/repos/libports/src/lib/qemu-usb/host.cc b/repos/libports/src/lib/qemu-usb/host.cc index 233435aa07..cd2bbbbbe8 100644 --- a/repos/libports/src/lib/qemu-usb/host.cc +++ b/repos/libports/src/lib/qemu-usb/host.cc @@ -28,7 +28,8 @@ static bool const verbose_warnings = false; Mutex _mutex; static void update_ep(USBDevice *, uint8_t, uint8_t); -static bool claim_interfaces(USBDevice *dev); +static bool claim_interfaces(USBDevice *); +static void reset_alt_settings(USBDevice *); using Packet_alloc_failed = Usb::Session::Tx::Source::Packet_alloc_failed; using Packet_type = Usb::Packet_descriptor::Type; @@ -182,8 +183,15 @@ struct Completion : Usb::Completion case Packet_type::CONFIG: if (!claim_interfaces(dev)) p->status = USB_RET_IOERROR; + else + reset_alt_settings(dev); + + usb_generic_async_ctrl_complete(dev, p); + break; case Packet_type::ALT_SETTING: update_ep(dev, packet.interface.number, packet.interface.alt_setting); + usb_generic_async_ctrl_complete(dev, p); + break; case Packet_type::CTRL: usb_generic_async_ctrl_complete(dev, p); break; @@ -269,7 +277,8 @@ struct Usb_host_device : List::Element for (unsigned i = 0; i < cdescr.num_interfaces; i++) { try { usb_raw.release_interface(i); } - catch (Usb::Session::Device_not_found) { return; } + catch (Usb::Session::Device_not_found) { return; } + catch (Usb::Session::Interface_not_found) { return; } } } @@ -287,7 +296,7 @@ struct Usb_host_device : List::Element usb_raw.claim_interface(i); } catch (Usb::Session::Interface_already_claimed) { result = false; - } + } catch (Usb::Session::Interface_not_found) { } } if (!result) error("device already claimed"); @@ -663,6 +672,22 @@ struct Usb_host_device : List::Element } } + + void reset_alt_settings(USBDevice *udev) + { + /* retrieve device speed */ + Usb::Config_descriptor cdescr; + Usb::Device_descriptor ddescr; + + try { usb_raw.config_descriptor(&ddescr, &cdescr); } + catch (Usb::Session::Device_not_found) { return; } + + for (unsigned i = 0; i < cdescr.num_interfaces; i++) { + udev->altsetting[i] = usb_raw.alt_settings(i); + } + } + + void update_ep(USBDevice *udev) { usb_ep_reset(udev); @@ -675,22 +700,24 @@ struct Usb_host_device : List::Element catch (Usb::Session::Device_not_found) { return; } for (unsigned i = 0; i < cdescr.num_interfaces; i++) { - Usb::Interface_descriptor iface; - uint8_t const altsetting = udev->altsetting[i]; - usb_raw.interface_descriptor(i, altsetting, &iface); - for (unsigned k = 0; k < iface.num_endpoints; k++) { - Usb::Endpoint_descriptor endp; - usb_raw.endpoint_descriptor(i, altsetting, k, &endp); + try { + Usb::Interface_descriptor iface; + uint8_t const altsetting = udev->altsetting[i]; + usb_raw.interface_descriptor(i, altsetting, &iface); + for (unsigned k = 0; k < iface.num_endpoints; k++) { + Usb::Endpoint_descriptor endp; + usb_raw.endpoint_descriptor(i, altsetting, k, &endp); - int const pid = (endp.address & USB_DIR_IN) ? USB_TOKEN_IN : USB_TOKEN_OUT; - int const ep = (endp.address & 0xf); - uint8_t const type = (endp.attributes & 0x3); + int const pid = (endp.address & USB_DIR_IN) ? USB_TOKEN_IN : USB_TOKEN_OUT; + int const ep = (endp.address & 0xf); + uint8_t const type = (endp.attributes & 0x3); - usb_ep_set_max_packet_size(udev, pid, ep, endp.max_packet_size); - usb_ep_set_type(udev, pid, ep, type); - usb_ep_set_ifnum(udev, pid, ep, i); - usb_ep_set_halted(udev, pid, ep, 0); - } + usb_ep_set_max_packet_size(udev, pid, ep, endp.max_packet_size); + usb_ep_set_type(udev, pid, ep, type); + usb_ep_set_ifnum(udev, pid, ep, i); + usb_ep_set_halted(udev, pid, ep, 0); + } + } catch (Usb::Session::Interface_not_found) { } } } }; @@ -706,6 +733,15 @@ struct Usb_host_device : List::Element OBJECT_CHECK(USBHostDevice, (obj), TYPE_USB_HOST_DEVICE) +static void reset_alt_settings(USBDevice *udev) +{ + USBHostDevice *d = USB_HOST_DEVICE(udev); + Usb_host_device *dev = (Usb_host_device *)d->data; + + dev->reset_alt_settings(udev); +} + + static void update_ep(USBDevice *udev, uint8_t interface, uint8_t altsetting) { USBHostDevice *d = USB_HOST_DEVICE(udev); @@ -787,7 +823,8 @@ static void usb_host_handle_data(USBDevice *udev, USBPacket *p) return; default: error("not supported data request"); - break; + p->status = USB_RET_NAK; + return; } try { diff --git a/repos/libports/src/lib/qemu-usb/qemu_emul.cc b/repos/libports/src/lib/qemu-usb/qemu_emul.cc index e8ed3b7fae..748ac2727e 100644 --- a/repos/libports/src/lib/qemu-usb/qemu_emul.cc +++ b/repos/libports/src/lib/qemu-usb/qemu_emul.cc @@ -104,7 +104,7 @@ Qemu::Controller *Qemu::usb_init(Timer_queue &tq, Pci_device &pci, _type_init_xhci_pci_register_types(); _type_init_usb_host_register_types(&ep, &alloc, &env); - config.with_sub_node("webcam", [&] (Genode::Xml_node const &node) { + config.with_optional_sub_node("webcam", [&] (Genode::Xml_node const &node) { _type_init_host_webcam_register_types(env, node); }); @@ -297,6 +297,7 @@ struct Object_pool for (unsigned i = USB_FIRST_FREE; i < MAX; i++) { if (used[i] == false) { used[i] = true; + memset(&obj[i], 0, sizeof(obj[i])); return &obj[i]; } } diff --git a/repos/libports/src/lib/qt5-host/qt5-qtbase-gcc11.patch b/repos/libports/src/lib/qt5-host/qt5-qtbase-gcc11.patch new file mode 100644 index 0000000000..2f29de0fc5 --- /dev/null +++ b/repos/libports/src/lib/qt5-host/qt5-qtbase-gcc11.patch @@ -0,0 +1,175 @@ +qt5-qtbase-gcc11.patch + +Source: https://github.com/OpenMandrivaAssociation/qt5-qtbase/blob/master/qt5-qtbase-gcc11.patch + +diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp +index 06fd88da..dbff3239 100644 +--- a/src/corelib/codecs/qtextcodec.cpp ++++ b/src/corelib/codecs/qtextcodec.cpp +@@ -38,6 +38,7 @@ + ** + ****************************************************************************/ + ++#include + #include "qplatformdefs.h" + + #include "qtextcodec.h" +diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp +index 8561f908..8128d3cf 100644 +--- a/src/corelib/codecs/qutfcodec.cpp ++++ b/src/corelib/codecs/qutfcodec.cpp +@@ -38,6 +38,8 @@ + ** + ****************************************************************************/ + ++#include ++ + #include "qutfcodec_p.h" + #include "qlist.h" + #include "qendian.h" +diff --git a/src/corelib/global/qendian.cpp b/src/corelib/global/qendian.cpp +index eb08b2f8..6b41b3dd 100644 +--- a/src/corelib/global/qendian.cpp ++++ b/src/corelib/global/qendian.cpp +@@ -38,6 +38,7 @@ + ** + ****************************************************************************/ + ++#include + #include "qendian.h" + + #include "qalgorithms.h" +diff --git a/src/corelib/global/qfloat16.cpp b/src/corelib/global/qfloat16.cpp +index c9733174..c62a1972 100644 +--- a/src/corelib/global/qfloat16.cpp ++++ b/src/corelib/global/qfloat16.cpp +@@ -38,6 +38,7 @@ + ** + ****************************************************************************/ + ++#include + #include "qfloat16.h" + #include "private/qsimd_p.h" + #include // for fpclassify()'s return values +diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp +index 10672c1f..6d5fd63e 100644 +--- a/src/corelib/global/qrandom.cpp ++++ b/src/corelib/global/qrandom.cpp +@@ -40,6 +40,7 @@ + // for rand_s + #define _CRT_RAND_S + ++#include + #include "qrandom.h" + #include "qrandom_p.h" + #include +diff --git a/src/corelib/plugin/qelfparser_p.cpp b/src/corelib/plugin/qelfparser_p.cpp +index 13eee353..9e7a7a41 100644 +--- a/src/corelib/plugin/qelfparser_p.cpp ++++ b/src/corelib/plugin/qelfparser_p.cpp +@@ -37,6 +37,7 @@ + ** + ****************************************************************************/ + ++#include + #include "qelfparser_p.h" + + #if defined (Q_OF_ELF) && defined(Q_CC_GNU) +diff --git a/src/corelib/plugin/qmachparser.cpp b/src/corelib/plugin/qmachparser.cpp +index 11670caf..39f5596b 100644 +--- a/src/corelib/plugin/qmachparser.cpp ++++ b/src/corelib/plugin/qmachparser.cpp +@@ -37,6 +37,8 @@ + ** + ****************************************************************************/ + ++#include ++ + #include "qmachparser_p.h" + + #if defined(Q_OF_MACH_O) +diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp +index 83873edf..5aafb4e5 100644 +--- a/src/corelib/plugin/quuid.cpp ++++ b/src/corelib/plugin/quuid.cpp +@@ -38,6 +38,7 @@ + ** + ****************************************************************************/ + ++#include + #include "quuid.h" + + #include "qcryptographichash.h" +diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp +index 5082a8cb..7eecfcca 100644 +--- a/src/corelib/serialization/qdatastream.cpp ++++ b/src/corelib/serialization/qdatastream.cpp +@@ -40,6 +40,8 @@ + #include "qdatastream.h" + #include "qdatastream_p.h" + ++#include ++ + #if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED) + #include "qbuffer.h" + #include "qfloat16.h" +diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp +index 9a72df58..6651ee98 100644 +--- a/src/corelib/text/qbytearray.cpp ++++ b/src/corelib/text/qbytearray.cpp +@@ -39,6 +39,7 @@ + ** + ****************************************************************************/ + ++#include + #include "qbytearray.h" + #include "qbytearraymatcher.h" + #include "private/qtools_p.h" +diff --git a/src/corelib/text/qbytearraymatcher.cpp b/src/corelib/text/qbytearraymatcher.cpp +index 72e09226..80511cb5 100644 +--- a/src/corelib/text/qbytearraymatcher.cpp ++++ b/src/corelib/text/qbytearraymatcher.cpp +@@ -37,6 +37,7 @@ + ** + ****************************************************************************/ + ++#include + #include "qbytearraymatcher.h" + + #include +diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp +index ab3054d5..22efb3a0 100644 +--- a/src/corelib/tools/qbitarray.cpp ++++ b/src/corelib/tools/qbitarray.cpp +@@ -38,6 +38,7 @@ + ** + ****************************************************************************/ + ++#include + #include "qbitarray.h" + #include + #include +diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp +index fa8d21e0..cd85956d 100644 +--- a/src/corelib/tools/qcryptographichash.cpp ++++ b/src/corelib/tools/qcryptographichash.cpp +@@ -38,6 +38,7 @@ + ** + ****************************************************************************/ + ++#include + #include + #include + +diff --git a/src/gui/text/qfontengine_qpf2.cpp b/src/gui/text/qfontengine_qpf2.cpp +index e00f9d05..917ab5f9 100644 +--- a/src/gui/text/qfontengine_qpf2.cpp ++++ b/src/gui/text/qfontengine_qpf2.cpp +@@ -37,6 +37,7 @@ + ** + ****************************************************************************/ + ++#include + #include "qfontengine_qpf2_p.h" + + #include diff --git a/repos/libports/src/lib/vfs/fatfs/target.mk b/repos/libports/src/lib/vfs/fatfs/target.mk deleted file mode 100644 index bee93b557c..0000000000 --- a/repos/libports/src/lib/vfs/fatfs/target.mk +++ /dev/null @@ -1,6 +0,0 @@ -TARGET = dummy-vfs_fatfs -LIBS = vfs_fatfs - -BUILD_ARTIFACTS := - -CC_CXX_WARN_STRICT = diff --git a/repos/libports/src/lib/vfs/jitterentropy/target.mk b/repos/libports/src/lib/vfs/jitterentropy/target.mk deleted file mode 100644 index bd2594b30b..0000000000 --- a/repos/libports/src/lib/vfs/jitterentropy/target.mk +++ /dev/null @@ -1,6 +0,0 @@ -TARGET = dummy-vfs_jitterentropy -LIBS = vfs_jitterentropy - -BUILD_ARTIFACTS := - -CC_CXX_WARN_STRICT = diff --git a/repos/libports/src/lib/vfs/libusb/target.mk b/repos/libports/src/lib/vfs/libusb/target.mk deleted file mode 100644 index 73c07409c7..0000000000 --- a/repos/libports/src/lib/vfs/libusb/target.mk +++ /dev/null @@ -1,6 +0,0 @@ -TARGET = dummy-vfs_libusb -LIBS = vfs_libusb - -BUILD_ARTIFACTS := - -CC_CXX_WARN_STRICT = diff --git a/repos/libports/src/lib/vfs/lwip/target.mk b/repos/libports/src/lib/vfs/lwip/target.mk deleted file mode 100644 index 1049802bb0..0000000000 --- a/repos/libports/src/lib/vfs/lwip/target.mk +++ /dev/null @@ -1,4 +0,0 @@ -TARGET = dummy-vfs_lwip -LIBS = vfs_lwip - -BUILD_ARTIFACTS := diff --git a/repos/libports/src/lib/vfs/oss/README b/repos/libports/src/lib/vfs/oss/README index 3f66208634..799643e29a 100644 --- a/repos/libports/src/lib/vfs/oss/README +++ b/repos/libports/src/lib/vfs/oss/README @@ -71,6 +71,14 @@ presents all files: * halt_output (wo): writing anything into this file halts output processing. Corresponding OSS commands: SNDCTL_DSP_HALT + * enable_input (rw): writing 1 or 0 into this file enables or disables + input processing. + Corresponding OSS commands: SNDCTL_DSP_SETTRIGGER + + * enable_output (rw): writing 1 or 0 into this file enables or disables + output processing. + Corresponding OSS commands: SNDCTL_DSP_SETTRIGGER + In its current state the plugin is merely enough to use simple applications requiring nothing more than a minimal set of the OSSv4 API. It does not allow altering of all parameters and will only work when 44100Hz/s16le is used. diff --git a/repos/libports/src/lib/vfs/oss/target.mk b/repos/libports/src/lib/vfs/oss/target.mk deleted file mode 100644 index 836274ded1..0000000000 --- a/repos/libports/src/lib/vfs/oss/target.mk +++ /dev/null @@ -1,4 +0,0 @@ -TARGET = dummy-vfs_oss -LIBS = vfs_oss - -BUILD_ARTIFACTS := diff --git a/repos/libports/src/lib/vfs/oss/vfs_oss.cc b/repos/libports/src/lib/vfs/oss/vfs_oss.cc index 806b530da8..9939e8b338 100644 --- a/repos/libports/src/lib/vfs/oss/vfs_oss.cc +++ b/repos/libports/src/lib/vfs/oss/vfs_oss.cc @@ -193,6 +193,9 @@ struct Vfs::Oss_file_system::Audio Audio(Audio const &); Audio &operator = (Audio const &); + bool _audio_out_enabled { true }; + bool _audio_in_enabled { true }; + bool _audio_out_started { false }; bool _audio_in_started { false }; @@ -208,6 +211,23 @@ struct Vfs::Oss_file_system::Audio size_t _read_sample_offset { 0 }; size_t _write_sample_offset { 0 }; + void _start_input() + { + if (!_audio_in_started && _audio_in_enabled) { + _in->start(); + _audio_in_started = true; + } + } + + void _start_output() + { + if (!_audio_out_started && _audio_out_enabled) { + _out[0]->start(); + _out[1]->start(); + _audio_out_started = true; + } + } + public: Audio(Genode::Env &env, @@ -302,6 +322,28 @@ struct Vfs::Oss_file_system::Audio } } + void enable_input(bool enable) + { + if (enable) { + _audio_in_enabled = true; + _start_input(); + } else { + halt_input(); + _audio_in_enabled = false; + } + } + + void enable_output(bool enable) + { + if (enable) { + _audio_out_enabled = true; + _start_output(); + } else { + halt_output(); + _audio_out_enabled = false; + } + } + /* * Handle Audio_out progress signal. * @@ -404,10 +446,7 @@ struct Vfs::Oss_file_system::Audio { out_size = 0; - if (!_audio_in_started) { - _in->start(); - _audio_in_started = true; - } + _start_input(); if (_info.ifrag_bytes == 0) { /* block */ @@ -493,11 +532,7 @@ struct Vfs::Oss_file_system::Audio return false; } - if (!_audio_out_started) { - _audio_out_started = true; - _out[0]->start(); - _out[1]->start(); - } + _start_output(); unsigned stream_samples_written = 0; @@ -756,6 +791,8 @@ struct Vfs::Oss_file_system::Local_factory : File_system_factory Readonly_value_file_system _optr_samples_fs { "optr_samples", 0LL }; Readonly_value_file_system _optr_fifo_samples_fs { "optr_fifo_samples", 0U }; Value_file_system _play_underruns_fs { "play_underruns", 0U }; + Value_file_system _enable_input_fs { "enable_input", 1U }; + Value_file_system _enable_output_fs { "enable_output", 1U }; /* WO files */ Value_file_system _halt_input_fs { "halt_input", 0U }; @@ -773,6 +810,18 @@ struct Vfs::Oss_file_system::Local_factory : File_system_factory Audio _audio { _env.env(), _info, _info_fs }; + Genode::Watch_handler _enable_input_handler { + _enable_input_fs, "/enable_input", + _env.alloc(), + *this, + &Vfs::Oss_file_system::Local_factory::_enable_input_changed }; + + Genode::Watch_handler _enable_output_handler { + _enable_output_fs, "/enable_output", + _env.alloc(), + *this, + &Vfs::Oss_file_system::Local_factory::_enable_output_changed }; + Genode::Watch_handler _halt_input_handler { _halt_input_fs, "/halt_input", _env.alloc(), @@ -829,6 +878,18 @@ struct Vfs::Oss_file_system::Local_factory : File_system_factory ** Watch handlers ** ********************/ + void _enable_input_changed() + { + bool enable = (bool)_enable_input_fs.value(); + _audio.enable_input(enable); + } + + void _enable_output_changed() + { + bool enable = (bool)_enable_output_fs.value(); + _audio.enable_output(enable); + } + void _halt_input_changed() { _audio.halt_input(); @@ -988,6 +1049,14 @@ struct Vfs::Oss_file_system::Local_factory : File_system_factory if (node.has_type(Value_file_system::type_name())) { + if (_enable_input_fs.matches(node)) { + return &_enable_input_fs; + } + + if (_enable_output_fs.matches(node)) { + return &_enable_output_fs; + } + if (_halt_input_fs.matches(node)) { return &_halt_input_fs; } @@ -1060,6 +1129,14 @@ class Vfs::Oss_file_system::Compound_file_system : private Local_factory, xml.attribute("name", "format"); }); + xml.node("value", [&] { + xml.attribute("name", "enable_input"); + }); + + xml.node("value", [&] { + xml.attribute("name", "enable_output"); + }); + xml.node("value", [&] { xml.attribute("name", "halt_input"); }); diff --git a/repos/libports/src/test/libc/main.cc b/repos/libports/src/test/libc/main.cc index 85032dc131..f74357b268 100644 --- a/repos/libports/src/test/libc/main.cc +++ b/repos/libports/src/test/libc/main.cc @@ -215,7 +215,8 @@ int main(int argc, char **argv) ts.tv_sec = ts.tv_nsec = 0; clock_gettime(CLOCK_REALTIME, &ts); - printf("sleep/gettime(CLOCK_REALTIME): %.09f\n", ts.tv_sec + ts.tv_nsec / 1000000000.0); + printf("sleep/gettime(CLOCK_REALTIME): %.09f %s\n", + ts.tv_sec + ts.tv_nsec / 1000000000.0, asctime(localtime(&ts.tv_sec))); { unsigned long long buf = 0; diff --git a/repos/libports/src/test/libc_rtc/main.cc b/repos/libports/src/test/libc_rtc/main.cc index 3b88a9987c..8aeba3a3f8 100644 --- a/repos/libports/src/test/libc_rtc/main.cc +++ b/repos/libports/src/test/libc_rtc/main.cc @@ -21,23 +21,18 @@ int main() unsigned idx = 1; while (1) { struct timespec ts; - if (clock_gettime(0, &ts)) { + if (clock_gettime(0, &ts)) return -1; - } struct tm *tm = localtime((time_t*)&ts.tv_sec); - if (!tm) { + if (!tm) return -1; - } - printf("Timestamp #%d: %d-%d-%d %d:%d %ds\n", - idx++, - 1900 + tm->tm_year, - 1 + tm->tm_mon, - tm->tm_mday, - tm->tm_hour, - tm->tm_min, - tm->tm_sec); + char time_str[32]; + if (!strftime(time_str, sizeof(time_str), "%F %T", tm)) + return -1; + + printf("Timestamp #%d: %s\n", idx++, time_str); sleep(1); } diff --git a/repos/libports/src/test/pthread/main.cc b/repos/libports/src/test/pthread/main.cc index 4fce74233c..bf7a9e406c 100644 --- a/repos/libports/src/test/pthread/main.cc +++ b/repos/libports/src/test/pthread/main.cc @@ -1153,6 +1153,46 @@ static void test_tls() } +static bool thread_local_destructor_called = false; + + +struct Thread_local +{ + int x = 0; + + ~Thread_local() + { + thread_local_destructor_called = true; + } +}; + + +static thread_local Thread_local thread_local_var; + + +static void *thread_local_test_func(void *) +{ + /* must access the variable to have the destructor called */ + thread_local_var.x = 1; + return nullptr; +} + + +static void test_thread_local_destructor() +{ + pthread_t t; + void *retval; + + pthread_create(&t, 0, thread_local_test_func, nullptr); + pthread_join(t, &retval); + + if (!thread_local_destructor_called) { + Genode::error("thread_local destructor was not called"); + exit(-1); + } +} + + int main(int argc, char **argv) { printf("--- pthread test ---\n"); @@ -1171,6 +1211,7 @@ int main(int argc, char **argv) test_cond(); test_cleanup(); test_tls(); + test_thread_local_destructor(); printf("--- returning from main ---\n"); return 0; diff --git a/repos/libports/src/test/qt5/qt_core_cmake/CMakeLists.txt b/repos/libports/src/test/qt5/qt_core_cmake/CMakeLists.txt new file mode 100644 index 0000000000..41cba87d23 --- /dev/null +++ b/repos/libports/src/test/qt5/qt_core_cmake/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.10.0) + +project(test-qt_core_cmake LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +find_package(Qt5 COMPONENTS Core REQUIRED) + +add_executable(test-qt_core_cmake + main.cpp +) + +target_link_libraries(test-qt_core_cmake Qt5::Core) diff --git a/repos/libports/src/test/qt5/qt_core_cmake/main.cpp b/repos/libports/src/test/qt5/qt_core_cmake/main.cpp new file mode 100644 index 0000000000..1fdc13ba02 --- /dev/null +++ b/repos/libports/src/test/qt5/qt_core_cmake/main.cpp @@ -0,0 +1,12 @@ +/* + * \brief QtCore test + * \author Christian Prochaska + * \date 2018-01-16 + */ + +#include + +int main(int argc, char *argv[]) +{ + qInfo() << "Test done."; +} diff --git a/repos/libports/src/test/qt5/qt_core_cmake/target.mk b/repos/libports/src/test/qt5/qt_core_cmake/target.mk new file mode 100644 index 0000000000..bb6d19bfd3 --- /dev/null +++ b/repos/libports/src/test/qt5/qt_core_cmake/target.mk @@ -0,0 +1,9 @@ +CMAKE_LISTS_DIR = $(PRG_DIR) + +CMAKE_TARGET_BINARIES = test-qt_core_cmake + +QT5_PORT_LIBS = libQt5Core + +LIBS = libc libm qt5_component stdcxx $(QT5_PORT_LIBS) + +include $(call select_from_repositories,lib/import/import-qt5_cmake.mk) diff --git a/repos/libports/src/test/qt5/qt_quick/target.mk b/repos/libports/src/test/qt5/qt_quick/target.mk index 66a61131f3..f0624293bf 100644 --- a/repos/libports/src/test/qt5/qt_quick/target.mk +++ b/repos/libports/src/test/qt5/qt_quick/target.mk @@ -3,7 +3,7 @@ QMAKE_PROJECT_FILE = $(PRG_DIR)/qt_quick.pro QMAKE_TARGET_BINARIES = test-qt_quick QT5_PORT_LIBS += libQt5Core libQt5Gui libQt5Network -QT5_PORT_LIBS += libQt5Qml libQt5Quick +QT5_PORT_LIBS += libQt5Qml libQt5QmlModels libQt5Quick LIBS = libc libm mesa qt5_component stdcxx $(QT5_PORT_LIBS) diff --git a/repos/os/include/audio_in_session/audio_in_session.h b/repos/os/include/audio_in_session/audio_in_session.h index 8f2cc1f394..c01fe7abd8 100644 --- a/repos/os/include/audio_in_session/audio_in_session.h +++ b/repos/os/include/audio_in_session/audio_in_session.h @@ -80,7 +80,7 @@ class Audio_in::Packet Genode::memcpy(_data, data, (samples > PERIOD ? PERIOD : samples) * SAMPLE_SIZE); if (samples < PERIOD) - Genode::memset(data + samples, 0, (PERIOD - samples) * SAMPLE_SIZE); + Genode::memset(_data + samples, 0, (PERIOD - samples) * SAMPLE_SIZE); } /** diff --git a/repos/os/include/audio_out_session/audio_out_session.h b/repos/os/include/audio_out_session/audio_out_session.h index a5f57437de..c1d00e25d1 100644 --- a/repos/os/include/audio_out_session/audio_out_session.h +++ b/repos/os/include/audio_out_session/audio_out_session.h @@ -252,8 +252,8 @@ class Audio_out::Stream { if (full()) throw Alloc_failed(); - unsigned pos = _tail; + _tail = (_tail + 1) % QUEUE_SIZE; Packet *p = get(pos); @@ -267,7 +267,7 @@ class Audio_out::Stream * * This means that allocation will start at current queue position. */ - void reset() { _tail = (_pos + 1) % QUEUE_SIZE; } + void reset() { _tail = _pos; } /** diff --git a/repos/os/include/block/component.h b/repos/os/include/block/component.h index 0ec6df8ca3..b9b899b30d 100644 --- a/repos/os/include/block/component.h +++ b/repos/os/include/block/component.h @@ -292,21 +292,14 @@ class Block::Root : public Genode::Root_component ram_quota - session_size) { + if (tx_buf_size > ram_quota) { error("insufficient 'ram_quota', got ", ram_quota, ", need ", - tx_buf_size + session_size); + tx_buf_size); throw Insufficient_ram_quota(); } diff --git a/repos/os/include/decorator/xml_utils.h b/repos/os/include/decorator/xml_utils.h index ab99a433e0..73c7ce7859 100644 --- a/repos/os/include/decorator/xml_utils.h +++ b/repos/os/include/decorator/xml_utils.h @@ -16,42 +16,7 @@ #include - -namespace Decorator { - - static Point point_attribute(Xml_node const &); - static Area area_attribute(Xml_node const &); - static Rect rect_attribute(Xml_node const &); - static Color color(Xml_node const &); -} - - -/** - * Read point position from XML node - */ -static inline Decorator::Point Decorator::point_attribute(Genode::Xml_node const &point) -{ - return Point((int)point.attribute_value("xpos", 0L), - (int)point.attribute_value("ypos", 0L)); } - - -/** - * Read area size from XML node - */ -static inline Decorator::Area Decorator::area_attribute(Genode::Xml_node const &area) -{ - return Area(area.attribute_value("width", 0U), - area.attribute_value("height", 0U)); -} - - -/** - * Read rectangle coordinates from XML node - */ -static inline Decorator::Rect Decorator::rect_attribute(Genode::Xml_node const &rect) -{ - return Rect(point_attribute(rect), area_attribute(rect)); -} +namespace Decorator { static Color color(Xml_node const &); } /** diff --git a/repos/os/include/file_system_session/client.h b/repos/os/include/file_system_session/client.h index 01164eee91..f9d94003a8 100644 --- a/repos/os/include/file_system_session/client.h +++ b/repos/os/include/file_system_session/client.h @@ -112,6 +112,11 @@ class File_system::Session_client : public Genode::Rpc_client { call(from_dir, from_name, to_dir, to_name); } + + unsigned num_entries(Dir_handle dir) override + { + return call(dir); + } }; #endif /* _INCLUDE__FILE_SYSTEM_SESSION__CLIENT_H_ */ diff --git a/repos/os/include/file_system_session/file_system_session.h b/repos/os/include/file_system_session/file_system_session.h index c744a53cc8..7e7fca9de5 100644 --- a/repos/os/include/file_system_session/file_system_session.h +++ b/repos/os/include/file_system_session/file_system_session.h @@ -474,6 +474,13 @@ struct File_system::Session : public Genode::Session virtual void move(Dir_handle, Name const &from, Dir_handle, Name const &to) = 0; + /** + * Return number of directory entries + * + * \throw Invalid_handle the directory handle is invalid + */ + virtual unsigned num_entries(Dir_handle) = 0; + /******************* ** RPC interface ** @@ -525,12 +532,14 @@ struct File_system::Session : public Genode::Session GENODE_TYPE_LIST(Invalid_handle, Invalid_name, Lookup_failed, Permission_denied, Unavailable), Dir_handle, Name const &, Dir_handle, Name const &); + GENODE_RPC_THROW(Rpc_num_entries, unsigned, num_entries, + GENODE_TYPE_LIST(Invalid_handle), + Dir_handle); GENODE_RPC_INTERFACE(Rpc_tx_cap, - Rpc_file, Rpc_symlink, Rpc_dir, - Rpc_node, Rpc_watch, + Rpc_file, Rpc_symlink, Rpc_dir, Rpc_node, Rpc_watch, Rpc_close, Rpc_status, Rpc_control, Rpc_unlink, - Rpc_truncate, Rpc_move); + Rpc_truncate, Rpc_move, Rpc_num_entries); }; #endif /* _INCLUDE__FILE_SYSTEM_SESSION__FILE_SYSTEM_SESSION_H_ */ diff --git a/repos/os/include/genode_c_api/event.h b/repos/os/include/genode_c_api/event.h index 5b95e0fc10..826f68965a 100644 --- a/repos/os/include/genode_c_api/event.h +++ b/repos/os/include/genode_c_api/event.h @@ -1,6 +1,7 @@ /* * \brief C interface to Genode's event session * \author Norman Feske + * \author Christian Helmuth * \date 2021-09-29 */ @@ -62,9 +63,16 @@ struct genode_event_submit; /** * Interface called by 'genode_event_generator_t' to submit events + * + * Note, keycode values must conform to os/include/input/keycodes.h. */ struct genode_event_submit { + void (*press) (struct genode_event_submit *, unsigned keycode); + void (*release) (struct genode_event_submit *, unsigned keycode); + + void (*rel_motion) (struct genode_event_submit *, int x, int y); + void (*touch) (struct genode_event_submit *, struct genode_event_touch_args const *); diff --git a/repos/os/include/genode_c_api/usb.h b/repos/os/include/genode_c_api/usb.h index 207a17e455..e7335c3598 100644 --- a/repos/os/include/genode_c_api/usb.h +++ b/repos/os/include/genode_c_api/usb.h @@ -148,8 +148,6 @@ struct genode_usb_request_control }; enum Iso { MAX_PACKETS = 32 }; -enum Transfer { BULK, IRQ, ISOC }; -typedef enum Transfer genode_usb_transfer_type_t; struct genode_usb_request_transfer { @@ -161,6 +159,27 @@ struct genode_usb_request_transfer unsigned long actual_packet_size[MAX_PACKETS]; }; +enum Urb_type { CTRL, BULK, IRQ, ISOC, NONE }; +typedef enum Urb_type genode_usb_urb_t; + +struct genode_usb_request_urb +{ + genode_usb_urb_t type; + void * req; +}; + +static inline struct genode_usb_request_control * +genode_usb_get_request_control(struct genode_usb_request_urb * urb) +{ + return (urb->type == CTRL) ? (struct genode_usb_request_control*)urb->req : 0; +} + +static inline struct genode_usb_request_transfer * +genode_usb_get_request_transfer(struct genode_usb_request_urb * urb) +{ + return (urb->type != CTRL) ? (struct genode_usb_request_transfer*)urb->req : 0; +} + enum Request_return_error { NO_ERROR, INTERFACE_OR_ENDPOINT_ERROR, @@ -174,43 +193,46 @@ enum Request_return_error { }; typedef enum Request_return_error genode_usb_request_ret_t; -typedef genode_usb_request_ret_t (*genode_usb_req_ctrl_t) - (struct genode_usb_request_control * req, - void * payload, - unsigned long payload_size, - void * opaque_data); +typedef void (*genode_usb_req_urb_t) + (struct genode_usb_request_urb req, + genode_usb_session_handle_t session_handle, + genode_usb_request_handle_t request_handle, + void * payload, + unsigned long payload_size, + void * opaque_data); -typedef genode_usb_request_ret_t (*genode_usb_req_transfer_t) - (struct genode_usb_request_transfer * req, - genode_usb_transfer_type_t type, - genode_usb_session_handle_t session_handle, - genode_usb_request_handle_t request_handle, - void * payload, - unsigned long payload_size, - void * opaque_data); - -typedef genode_usb_request_ret_t (*genode_usb_req_string_t) +typedef void (*genode_usb_req_string_t) (struct genode_usb_request_string * req, + genode_usb_session_handle_t session_handle, + genode_usb_request_handle_t request_handle, void * payload, unsigned long payload_size, void * opaque_data); -typedef genode_usb_request_ret_t (*genode_usb_req_altsetting_t) - (unsigned iface, unsigned alt_setting, void * opaque_data); +typedef void (*genode_usb_req_altsetting_t) + (unsigned iface, unsigned alt_setting, + genode_usb_session_handle_t session_handle, + genode_usb_request_handle_t request_handle, + void * opaque_data); -typedef genode_usb_request_ret_t (*genode_usb_req_config_t) - (unsigned config_idx, void * opaque_data); +typedef void (*genode_usb_req_config_t) + (unsigned config_idx, + genode_usb_session_handle_t session_handle, + genode_usb_request_handle_t request_handle, + void * opaque_data); -typedef genode_usb_request_ret_t (*genode_usb_req_flush_t) - (unsigned char ep, void * opaque_data); +typedef void (*genode_usb_req_flush_t) + (unsigned char ep, + genode_usb_session_handle_t session_handle, + genode_usb_request_handle_t request_handle, + void * opaque_data); typedef genode_usb_request_ret_t (*genode_usb_response_t) - (struct genode_usb_request_transfer * req, - void * opaque_data); + (struct genode_usb_request_urb req, + void * opaque_data); struct genode_usb_request_callbacks { - genode_usb_req_ctrl_t control_fn; - genode_usb_req_transfer_t transfer_fn; + genode_usb_req_urb_t urb_fn; genode_usb_req_string_t string_fn; genode_usb_req_altsetting_t altsetting_fn; genode_usb_req_config_t config_fn; diff --git a/repos/os/include/gpu/info_lima.h b/repos/os/include/gpu/info_lima.h new file mode 100644 index 0000000000..1906f2f4e5 --- /dev/null +++ b/repos/os/include/gpu/info_lima.h @@ -0,0 +1,43 @@ +/* + * \brief Gpu Information Lima + * \author Josef Soentgen + * \date 2022-06-14 + */ + +/* + * Copyright (C) 2022 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 _INCLUDE__GPU_INFO_LIMA_H_ +#define _INCLUDE__GPU_INFO_LIMA_H_ + +#include +#include +#include + +namespace Gpu { + + struct Info_lima; +} /* namespace Gpu */ + + +/* + * Gpu information + * + * Used to query information in the DRM backend + */ +struct Gpu::Info_lima +{ + /* + * Size the array based on the list of params in + * lima_drm.h that allow for 1:1 access. + */ + enum { MAX_LIMA_PARAMS = 4, }; + using Param = Genode::uint64_t; + Param param[MAX_LIMA_PARAMS] { }; +}; + +#endif /* _INCLUDE__GPU_INFO_LIMA_H_ */ diff --git a/repos/os/include/gpu_session/client.h b/repos/os/include/gpu_session/client.h index f98d6bda2b..24491bdefa 100644 --- a/repos/os/include/gpu_session/client.h +++ b/repos/os/include/gpu_session/client.h @@ -76,6 +76,9 @@ class Gpu::Session_client : public Genode::Rpc_client void unmap_buffer_ppgtt(Buffer_id id, Gpu::addr_t va) override { call(id, va); } + Gpu::addr_t query_buffer_ppgtt(Gpu::Buffer_id id) override { + return call(id); } + bool set_tiling(Buffer_id id, unsigned mode) override { return call(id, mode); } }; diff --git a/repos/os/include/gpu_session/gpu_session.h b/repos/os/include/gpu_session/gpu_session.h index bb2547a828..6fcc1f9b9d 100644 --- a/repos/os/include/gpu_session/gpu_session.h +++ b/repos/os/include/gpu_session/gpu_session.h @@ -197,7 +197,14 @@ struct Gpu::Session : public Genode::Session * * \param id buffer id */ - virtual void unmap_buffer_ppgtt(Buffer_id id, Gpu::addr_t) = 0; + virtual void unmap_buffer_ppgtt(Buffer_id id, Gpu::addr_t va) = 0; + + /** + * Get virtual address of buffer in the PPGTT + * + * \param id buffer id to be associated with the buffer + */ + virtual Gpu::addr_t query_buffer_ppgtt(Buffer_id) = 0; /** * Set tiling for buffer @@ -237,6 +244,7 @@ struct Gpu::Session : public Genode::Session Gpu::Buffer_id, Gpu::addr_t); GENODE_RPC(Rpc_unmap_buffer_ppgtt, void, unmap_buffer_ppgtt, Gpu::Buffer_id, Gpu::addr_t); + GENODE_RPC(Rpc_query_buffer_ppgtt, Gpu::addr_t, query_buffer_ppgtt, Gpu::Buffer_id); GENODE_RPC(Rpc_set_tiling, bool, set_tiling, Gpu::Buffer_id, unsigned); @@ -244,7 +252,7 @@ struct Gpu::Session : public Genode::Session Rpc_complete, Rpc_completion_sigh, Rpc_alloc_buffer, Rpc_free_buffer, Rpc_export_buffer, Rpc_import_buffer, Rpc_map_buffer, Rpc_unmap_buffer, - Rpc_map_buffer_ppgtt, Rpc_unmap_buffer_ppgtt, + Rpc_map_buffer_ppgtt, Rpc_unmap_buffer_ppgtt, Rpc_query_buffer_ppgtt, Rpc_set_tiling); }; diff --git a/repos/os/include/legacy/x86/platform_device/platform_device.h b/repos/os/include/legacy/x86/platform_device/platform_device.h index 7fbedef03a..e628a5d689 100644 --- a/repos/os/include/legacy/x86/platform_device/platform_device.h +++ b/repos/os/include/legacy/x86/platform_device/platform_device.h @@ -1,6 +1,7 @@ /* * \brief PCI-device interface * \author Norman Feske + * \author Christian Helmuth * \date 2008-01-28 */ @@ -80,10 +81,10 @@ struct Platform::Device : Platform::Abstract_device { /* * Mask out the resource-description bits of the base - * address register. I/O resources use the lowest 3 + * address register. I/O resources use the lowest 2 * bits, memory resources use the lowest 4 bits. */ - return _bar & ((type() == IO) ? ~7 : ~15); + return _bar & ((type() == IO) ? ~3 : ~15); } /** diff --git a/repos/os/include/net/icmp.h b/repos/os/include/net/icmp.h index f1da401979..288a56bb6f 100644 --- a/repos/os/include/net/icmp.h +++ b/repos/os/include/net/icmp.h @@ -114,6 +114,8 @@ class Net::Icmp_packet void update_checksum(Genode::size_t data_sz); + void update_checksum(Internet_checksum_diff const &icd); + bool checksum_error(Genode::size_t data_sz) const; @@ -157,6 +159,9 @@ class Net::Icmp_packet void query_id(Genode::uint16_t v) { _rest_of_header_u16[0] = host_to_big_endian(v); } void query_seq(Genode::uint16_t v) { _rest_of_header_u16[1] = host_to_big_endian(v); } + void type_and_code(Type t, Code c, Internet_checksum_diff &icd); + void query_id(Genode::uint16_t v, Internet_checksum_diff &icd); + /********* ** log ** diff --git a/repos/os/include/net/internet_checksum.h b/repos/os/include/net/internet_checksum.h index 9ba0701eef..b0bfe27385 100644 --- a/repos/os/include/net/internet_checksum.h +++ b/repos/os/include/net/internet_checksum.h @@ -42,16 +42,50 @@ namespace Net { } __attribute__((packed)); - Genode::uint16_t internet_checksum(Packed_uint16 const *addr, - Genode::size_t size, - Genode::addr_t init_sum = 0); + Genode::uint16_t internet_checksum(Packed_uint16 const *data_ptr, + Genode::size_t data_sz); - Genode::uint16_t internet_checksum_pseudo_ip(Packed_uint16 const *addr, - Genode::size_t size, - Genode::uint16_t size_be, - Ipv4_packet::Protocol ip_prot, - Ipv4_address &ip_src, - Ipv4_address &ip_dst); + Genode::uint16_t + internet_checksum_pseudo_ip(Packed_uint16 const *data_ptr, + Genode::size_t data_sz, + Genode::uint16_t ip_data_sz_be, + Ipv4_packet::Protocol ip_prot, + Ipv4_address &ip_src, + Ipv4_address &ip_dst); + + /** + * Accumulating modifier for incremental updates of internet checksums + */ + class Internet_checksum_diff + { + private: + + signed long _value { 0 }; + + public: + + /** + * Update modifier according to a data update in the target region + * + * PRECONDITIONS + * + * * The pointers must refer to data that is at an offset inside + * the checksum'd region that is a multiple of 2 bytes (16 bits). + */ + void add_up_diff(Packed_uint16 const *new_data_ptr, + Packed_uint16 const *old_data_ptr, + Genode::size_t data_sz); + + /** + * Update this modifier by adding up another modifier + */ + void add_up_diff(Internet_checksum_diff const &icd); + + /** + * Return the given checksum with this modifier applied + */ + Genode::uint16_t apply_to(signed long sum) const; + }; } #endif /* _NET__INTERNET_CHECKSUM_H_ */ diff --git a/repos/os/include/net/ipv4.h b/repos/os/include/net/ipv4.h index 7609bd9b9d..3327bf9962 100644 --- a/repos/os/include/net/ipv4.h +++ b/repos/os/include/net/ipv4.h @@ -27,8 +27,10 @@ namespace Genode { class Output; } namespace Net { + enum { IPV4_ADDR_LEN = 4 }; + class Internet_checksum_diff; class Ipv4_address; class Ipv4_packet; @@ -54,6 +56,8 @@ struct Net::Ipv4_address : Network_address bool is_in_range(Ipv4_address const &first, Ipv4_address const &last) const; + + bool is_multicast() const; } __attribute__((packed)); @@ -94,6 +98,11 @@ class Net::Ipv4_packet void update_checksum(); + void update_checksum(Internet_checksum_diff const &icd); + + void update_checksum(Internet_checksum_diff const &icd, + Internet_checksum_diff &caused_icd); + bool checksum_error() const; private: @@ -237,6 +246,9 @@ class Net::Ipv4_packet _offset_6_u16 = host_to_big_endian(be); } + void src(Ipv4_address v, Internet_checksum_diff &icd); + void dst(Ipv4_address v, Internet_checksum_diff &icd); + /********* ** log ** diff --git a/repos/os/include/net/tcp.h b/repos/os/include/net/tcp.h index a4f38a66dd..8d0cec9a56 100644 --- a/repos/os/include/net/tcp.h +++ b/repos/os/include/net/tcp.h @@ -72,6 +72,8 @@ class Net::Tcp_packet Ipv4_address ip_dst, size_t tcp_size); + void update_checksum(Internet_checksum_diff const &icd); + /*************** ** Accessors ** @@ -99,6 +101,9 @@ class Net::Tcp_packet void src_port(Port p) { _src_port = host_to_big_endian(p.value); } void dst_port(Port p) { _dst_port = host_to_big_endian(p.value); } + void src_port(Port p, Internet_checksum_diff &icd); + void dst_port(Port p, Internet_checksum_diff &icd); + /********* ** log ** diff --git a/repos/os/include/net/udp.h b/repos/os/include/net/udp.h index fc1e50310f..f275aa14f2 100644 --- a/repos/os/include/net/udp.h +++ b/repos/os/include/net/udp.h @@ -84,6 +84,8 @@ class Net::Udp_packet void update_checksum(Ipv4_address ip_src, Ipv4_address ip_dst); + void update_checksum(Internet_checksum_diff const &icd); + bool checksum_error(Ipv4_address ip_src, Ipv4_address ip_dst) const; @@ -103,6 +105,9 @@ class Net::Udp_packet void src_port_big_endian(Genode::uint16_t v) { _src_port = v; } void dst_port_big_endian(Genode::uint16_t v) { _dst_port = v; } + void src_port(Port p, Internet_checksum_diff &icd); + void dst_port(Port p, Internet_checksum_diff &icd); + /********* ** log ** diff --git a/repos/os/include/os/packet_stream.h b/repos/os/include/os/packet_stream.h index bd9545de5b..7a7a498b26 100644 --- a/repos/os/include/os/packet_stream.h +++ b/repos/os/include/os/packet_stream.h @@ -444,13 +444,13 @@ class Genode::Packet_descriptor_receiver return packet; } - bool rx_wakeup() + bool rx_wakeup(bool omit_signal) { Genode::Mutex::Guard mutex_guard(_rx_queue_mutex); bool signal_submitted = false; - if (_rx_wakeup_needed) { + if (_rx_wakeup_needed && !omit_signal) { _tx_ready.submit(); signal_submitted = true; } @@ -639,6 +639,10 @@ class Genode::Packet_stream_source : private Packet_stream_base class Saturated_submit_queue : Exception { }; class Empty_ack_queue : Exception { }; + enum class Alloc_packet_error { FAILED }; + + using Alloc_packet_result = Attempt; + /** * Constructor * @@ -726,6 +730,29 @@ class Genode::Packet_stream_source : private Packet_stream_base throw Packet_alloc_failed(); }); } + /** + * Allocate packet without throwing exceptions + * + * \param size size of packet in bytes + * \param align alignment of packet as log2 value, default is 1 byte + * \return an Attempt object that either contains an error or a + * packet descriptor with an assigned range within the + * bulk buffer shared between source and sink + */ + Alloc_packet_result alloc_packet_attempt(Genode::size_t size, unsigned align = PACKET_ALIGNMENT) + { + if (size == 0) + return Packet_descriptor(0, 0); + + return _packet_alloc.alloc_aligned(size, align).convert( + + [&] (void *base) { + return Packet_descriptor((Genode::off_t)base, size); }, + + [&] (Allocator::Alloc_error) { + return Alloc_packet_error::FAILED; }); + } + /** * Get pointer to the content of the specified packet * @@ -772,12 +799,13 @@ class Genode::Packet_stream_source : private Packet_stream_base * Wake up the packet sink if needed * * This method assumes that the same signal handler is used for - * the submit transmitter and the ack receiver. + * the submit transmitter and the ack receiver. The ack receiver is not + * signalled if the submit transmitter was already signalled. */ void wakeup() { - /* submit only one signal */ - _submit_transmitter.tx_wakeup() || _ack_receiver.rx_wakeup(); + /* submit only one signal, prefer submit transmitter over ack receiver */ + _ack_receiver.rx_wakeup(_submit_transmitter.tx_wakeup()); } /** @@ -930,12 +958,13 @@ class Genode::Packet_stream_sink : private Packet_stream_base * Wake up the packet source if needed * * This method assumes that the same signal handler is used for - * the submit receiver and the ack transmitter. + * the submit receiver and the ack transmitter. The submit receiver + * is not signalled if the ack transmitter was already signalled. */ void wakeup() { - /* submit only one signal */ - _submit_receiver.rx_wakeup() || _ack_transmitter.tx_wakeup(); + /* submit only one signal, prefer ack_avail signal over ready_to_submit */ + _submit_receiver.rx_wakeup(_ack_transmitter.tx_wakeup()); } /** diff --git a/repos/os/include/os/session_policy.h b/repos/os/include/os/session_policy.h index 7e0b58c6c8..9d800ad481 100644 --- a/repos/os/include/os/session_policy.h +++ b/repos/os/include/os/session_policy.h @@ -193,7 +193,7 @@ void Genode::with_matching_policy(String const &label, /* fall back to default policy if no match exists */ if (best_match.has_type("none")) - policies.with_sub_node("default-policy", [&] (Xml_node const &policy) { + policies.with_optional_sub_node("default-policy", [&] (Xml_node const &policy) { best_match = policy; }); if (best_match.has_type("none")) diff --git a/repos/os/include/os/vfs.h b/repos/os/include/os/vfs.h index 66cf242681..59dceef48f 100644 --- a/repos/os/include/os/vfs.h +++ b/repos/os/include/os/vfs.h @@ -27,6 +27,8 @@ namespace Genode { struct File; class Readonly_file; class File_content; + class Writeable_file; + class Append_file; class New_file; class Watcher; template @@ -124,6 +126,8 @@ struct Genode::Directory : Noncopyable, Interface friend class Readonly_file; friend class Root_directory; friend class Watcher; + friend class Writeable_file; + friend class Append_file; friend class New_file; /* @@ -668,22 +672,21 @@ class Genode::File_content /** - * Utility for writing data to a file via the Genode VFS library + * Base class of `New_file` and `Append_file` providing open for write, sync, + * and append functionality. */ -class Genode::New_file : Noncopyable +class Genode::Writeable_file : Noncopyable { public: struct Create_failed : Exception { }; - private: + enum class Append_result { OK, WRITE_ERROR }; - Entrypoint &_ep; - Allocator &_alloc; - Vfs::File_system &_fs; - Vfs::Vfs_handle &_handle; + protected: - Vfs::Vfs_handle &_init_handle(Directory &dir, Directory::Path const &rel_path) + static Vfs::Vfs_handle &_init_handle(Directory &dir, + Directory::Path const &rel_path) { /* create compound directory */ { @@ -701,39 +704,24 @@ class Genode::New_file : Noncopyable Vfs::Vfs_handle *handle_ptr = nullptr; Vfs::Directory_service::Open_result const res = - _fs.open(path.string(), mode, &handle_ptr, _alloc); + dir._fs.open(path.string(), mode, &handle_ptr, dir._alloc); if (res != Vfs::Directory_service::OPEN_OK || (handle_ptr == nullptr)) { - error("failed to create file '", path, "', res=", (int)res); + error("failed to create/open file '", path, "' for writing, res=", (int)res); throw Create_failed(); } - handle_ptr->fs().ftruncate(handle_ptr, 0); - return *handle_ptr; } - public: - - /** - * Constructor - * - * \throw Create_failed - */ - New_file(Directory &dir, Directory::Path const &path) - : - _ep(dir._ep), _alloc(dir._alloc), _fs(dir._fs), - _handle(_init_handle(dir, path)) - { } - - ~New_file() + static void _sync(Vfs::Vfs_handle &handle, Entrypoint &ep) { - while (_handle.fs().queue_sync(&_handle) == false) - _ep.wait_and_dispatch_one_io_signal(); + while (handle.fs().queue_sync(&handle) == false) + ep.wait_and_dispatch_one_io_signal(); for (bool sync_done = false; !sync_done; ) { - switch (_handle.fs().complete_sync(&_handle)) { + switch (handle.fs().complete_sync(&handle)) { case Vfs::File_io_service::SYNC_QUEUED: break; @@ -749,14 +737,12 @@ class Genode::New_file : Noncopyable } if (!sync_done) - _ep.wait_and_dispatch_one_io_signal(); + ep.wait_and_dispatch_one_io_signal(); } - _handle.ds().close(&_handle); } - enum class Append_result { OK, WRITE_ERROR }; - - Append_result append(char const *src, size_t size) + static Append_result _append(Vfs::Vfs_handle &handle, Entrypoint &ep, + char const *src, size_t size) { bool write_error = false; @@ -771,7 +757,7 @@ class Genode::New_file : Noncopyable using Write_result = Vfs::File_io_service::Write_result; - switch (_handle.fs().write(&_handle, src, remaining_bytes, + switch (handle.fs().write(&handle, src, remaining_bytes, out_count)) { case Write_result::WRITE_ERR_AGAIN: @@ -789,7 +775,7 @@ class Genode::New_file : Noncopyable out_count = min((Vfs::file_size)remaining_bytes, out_count); remaining_bytes -= (size_t)out_count; src += out_count; - _handle.advance_seek(out_count); + handle.advance_seek(out_count); break; }; } @@ -797,7 +783,7 @@ class Genode::New_file : Noncopyable stalled = true; } if (stalled) - _ep.wait_and_dispatch_one_io_signal(); + ep.wait_and_dispatch_one_io_signal(); } return write_error ? Append_result::WRITE_ERROR : Append_result::OK; @@ -805,6 +791,81 @@ class Genode::New_file : Noncopyable }; +/** + * Utility for appending data to an existing file via the Genode VFS library + */ +class Genode::Append_file : public Writeable_file +{ + private: + + Entrypoint &_ep; + Vfs::Vfs_handle &_handle; + + public: + + /** + * Constructor + * + * \throw Create_failed + */ + Append_file(Directory &dir, Directory::Path const &path) + : + _ep(dir._ep), + _handle(_init_handle(dir, path)) + { + Vfs::Directory_service::Stat stat { }; + if (_handle.ds().stat(path.string(), stat) == Vfs::Directory_service::STAT_OK) + _handle.seek(stat.size); + } + + ~Append_file() + { + _sync(_handle, _ep); + _handle.ds().close(&_handle); + } + + Append_result append(char const *src, size_t size) { + return _append(_handle, _ep, src, size); } +}; + + +/** + * Utility for writing data to a new file via the Genode VFS library + */ +class Genode::New_file : public Writeable_file +{ + private: + + Entrypoint &_ep; + Vfs::Vfs_handle &_handle; + + public: + + using Writeable_file::Append_result; + using Writeable_file::Create_failed; + + /** + * Constructor + * + * \throw Create_failed + */ + New_file(Directory &dir, Directory::Path const &path) + : + _ep(dir._ep), + _handle(_init_handle(dir, path)) + { _handle.fs().ftruncate(&_handle, 0); } + + ~New_file() + { + _sync(_handle, _ep); + _handle.ds().close(&_handle); + } + + Append_result append(char const *src, size_t size) { + return _append(_handle, _ep, src, size); } +}; + + class Genode::Watcher { private: diff --git a/repos/os/include/pci/config.h b/repos/os/include/pci/config.h index 4e5b61db59..6e2580257b 100644 --- a/repos/os/include/pci/config.h +++ b/repos/os/include/pci/config.h @@ -44,16 +44,17 @@ struct Pci::Config : Genode::Mmio struct Command : Register<0x4, 16> { - struct Io_space_enable : Bitfield<0, 1> {}; - struct Memory_space_enable : Bitfield<1, 1> {}; - struct Bus_master_enable : Bitfield<2, 1> {}; - struct Special_cycle_enable : Bitfield<3, 1> {}; - struct Memory_write_invalidate : Bitfield<4, 1> {}; - struct Vga_palette_snoop : Bitfield<5, 1> {}; - struct Parity_error_response : Bitfield<6, 1> {}; - struct Idsel : Bitfield<7, 1> {}; - struct Serror_enable : Bitfield<8, 1> {}; - struct Interrupt_enable : Bitfield<10, 1> {}; + struct Io_space_enable : Bitfield<0, 1> {}; + struct Memory_space_enable : Bitfield<1, 1> {}; + struct Bus_master_enable : Bitfield<2, 1> {}; + struct Special_cycle_enable : Bitfield<3, 1> {}; + struct Memory_write_invalidate : Bitfield<4, 1> {}; + struct Vga_palette_snoop : Bitfield<5, 1> {}; + struct Parity_error_response : Bitfield<6, 1> {}; + struct Idsel : Bitfield<7, 1> {}; + struct Serror_enable : Bitfield<8, 1> {}; + struct Fast_back_to_back_enable : Bitfield<9, 1> {}; + struct Interrupt_enable : Bitfield<10, 1> {}; }; struct Status : Register<0x6, 16> @@ -64,6 +65,7 @@ struct Pci::Config : Genode::Mmio struct Class_code_rev_id : Register<0x8, 32> { + struct Revision : Bitfield<0, 8> {}; struct Class_code : Bitfield<8, 24> {}; }; @@ -94,43 +96,79 @@ struct Pci::Config : Genode::Mmio enum { SIZE_32BIT = 0, SIZE_64BIT = 2 }; }; + struct Memory_prefetchable : Bitfield<3,1> {}; + struct Io_base : Bitfield<2, 30> {}; struct Memory_base : Bitfield<7, 25> {}; }; struct Upper_bits : Register<0x4, 32> { }; - Bar_32bit::access_t _conf { 0 }; + Bar_32bit::access_t _conf_value { 0 }; - Base_address(Genode::addr_t base) : Mmio(base) + template + typename REG::access_t _get_and_set(typename REG::access_t value) { - Bar_32bit::access_t v = read(); - write(0xffffffff); - _conf = read(); - write(v); + write(0xffffffff); + typename REG::access_t ret = read(); + write(value); + return ret; } - bool valid() { return _conf != 0; } + Bar_32bit::access_t _conf() + { + /* + * Initialize _conf_value on demand only to prevent read-write + * operations on BARs of invalid devices at construction time. + */ + if (!_conf_value) + _conf_value = _get_and_set(read()); + return _conf_value; + } + + Base_address(Genode::addr_t base) : Mmio(base) { } + + bool valid() { return _conf() != 0; } bool memory() { - return !Bar_32bit::Memory_space_indicator::get(_conf); } + return !Bar_32bit::Memory_space_indicator::get(_conf()); } bool bit64() { - return Bar_32bit::Memory_type::get(_conf) == + return Bar_32bit::Memory_type::get(_conf()) == Bar_32bit::Memory_type::SIZE_64BIT; } + bool prefetchable() { + return Bar_32bit::Memory_prefetchable::get(_conf()); } + Genode::size_t size() { - return 1 + (memory() ? ~Bar_32bit::Memory_base::masked(_conf) - : ~Bar_32bit::Io_base::masked(_conf)); + return 1 + (memory() ? ~Bar_32bit::Memory_base::masked(_conf()) + : ~Bar_32bit::Io_base::masked(_conf())); } Genode::uint64_t addr() { - return (bit64() ? ((Genode::uint64_t)read()<<32) : 0UL) - | Bar_32bit::Memory_base::masked(read()); + if (memory()) + return (bit64() + ? ((Genode::uint64_t)read()<<32) : 0UL) + | Bar_32bit::Memory_base::masked(read()); + else + return Bar_32bit::Io_base::masked(read()); + } + + void set(Genode::uint64_t v) + { + if (!valid() || v == addr()) + return; + + if (memory()) { + if (bit64()) + _get_and_set((Upper_bits::access_t)(v >> 32)); + _get_and_set(Bar_32bit::Memory_base::masked(v & ~0U)); + } else + _get_and_set(Bar_32bit::Io_base::masked(v & ~0U)); } }; @@ -184,14 +222,53 @@ struct Pci::Config : Genode::Mmio struct Power_management_capability : Pci_capability { - struct Capabilities : Register<0x2, 16> {}; + struct Capabilities : Register<0x2, 16> {}; + struct Control_status : Register<0x4, 16> { - struct Pme_status : Bitfield<15,1> {}; + struct Power_state : Bitfield<0, 2> + { + enum { D0, D1, D2, D3 }; + }; + + struct No_soft_reset : Bitfield<3, 1> {}; + struct Pme_status : Bitfield<15,1> {}; }; - struct Data : Register<0x7, 8> {}; + + struct Data : Register<0x7, 8> {}; using Pci_capability::Pci_capability; + + bool power_on(Delayer & delayer) + { + using Reg = Control_status::Power_state; + if (read() == Reg::D0) + return false; + + write(Reg::D0); + + /* + * PCI Express 4.3 - 5.3.1.4. D3 State + * + * "Unless Readiness Notifications mechanisms are used ..." + * "a minimum recovery time following a D3 hot → D0 transition of" + * "at least 10 ms ..." + */ + delayer.usleep(10'000); + return true; + } + + void power_off() + { + using Reg = Control_status::Power_state; + if (read() != Reg::D3) write(Reg::D3); + } + + + bool soft_reset() + { + return !read(); + } }; @@ -235,6 +312,7 @@ struct Pci::Config : Genode::Mmio { struct Control : Register<0x2, 16> { + struct Slots : Bitfield<0, 10> {}; struct Size : Bitfield<0, 11> {}; struct Function_mask : Bitfield<14, 1> {}; struct Enable : Bitfield<15, 1> {}; @@ -254,6 +332,8 @@ struct Pci::Config : Genode::Mmio struct Table_entry : Genode::Mmio { + enum { SIZE = 16 }; + struct Address_64_lower : Register<0x0, 32> { }; struct Address_64_upper : Register<0x4, 32> { }; struct Data : Register<0x8, 32> { }; @@ -266,16 +346,40 @@ struct Pci::Config : Genode::Mmio }; using Pci_capability::Pci_capability; + + Genode::uint8_t bar() { + return (Genode::uint8_t) read(); } + + Genode::size_t table_offset() { + return read() << 3; } + + unsigned slots() { return read(); } + + void enable() + { + Control::access_t ctrl = read(); + Control::Function_mask::set(ctrl, 0); + Control::Enable::set(ctrl, 1); + write(ctrl); + } }; struct Pci_express_capability : Pci_capability { - struct Capabilities : Register<0x2, 16> {}; - struct Device_capabilities : Register<0x4, 32> {}; - struct Device_control : Register<0x8, 16> {}; + struct Capabilities : Register<0x2, 16> {}; - struct Device_status : Register<0xa, 16> + struct Device_capabilities : Register<0x4, 32> + { + struct Function_level_reset : Bitfield<28,1> {}; + }; + + struct Device_control : Register<0x8, 16> + { + struct Function_level_reset : Bitfield<15,1> {}; + }; + + struct Device_status : Register<0xa, 16> { struct Correctable_error : Bitfield<0, 1> {}; struct Non_fatal_error : Bitfield<1, 1> {}; @@ -353,6 +457,17 @@ struct Pci::Config : Genode::Mmio write(1); write(1); } + + void reset(Delayer & delayer) + { + if (!read()) + return; + write(1); + try { + wait_for(Attempts(100), Microseconds(10000), delayer, + Device_status::Transactions_pending::Equal(0)); + } catch(Polling_timeout) { } + } }; @@ -364,7 +479,7 @@ struct Pci::Config : Genode::Mmio struct Pci_express_extended_capability : Genode::Mmio { - struct Id : Register<0,16> + struct Id : Register<0x0, 16> { enum { INVALID = 0x0, @@ -377,7 +492,7 @@ struct Pci::Config : Genode::Mmio }; }; - struct Next_and_version : Register<16, 8> + struct Next_and_version : Register<0x2, 16> { struct Offset : Bitfield<4, 12> {}; }; @@ -451,19 +566,8 @@ struct Pci::Config : Genode::Mmio case Pci_capability::Id::PCI_E: pci_e_cap.construct(base()+off); break; - case Pci_capability::Id::AGP: - case Pci_capability::Id::VITAL_PRODUCT: - case Pci_capability::Id::SATA: - case Pci_capability::Id::VENDOR: - case Pci_capability::Id::ADVANCED: - case Pci_capability::Id::BRIDGE_SUB: - case Pci_capability::Id::DEBUG: - break; - default: - warning("Found unhandled capability ", - cap.read(), - " at offset ", Hex(base()+off)); + /* ignore unhandled capability */ ; } off = cap.read(); } @@ -480,15 +584,8 @@ struct Pci::Config : Genode::Mmio case Pci_express_extended_capability::Id::ADVANCED_ERROR_REPORTING: adv_err_cap.construct(base() + off); break; - case Pci_express_extended_capability::Id::VENDOR: - case Pci_express_extended_capability::Id::VIRTUAL_CHANNEL: - case Pci_express_extended_capability::Id::MULTI_ROOT_IO_VIRT: - break; - default: - warning("Found unhandled extended capability ", - cap.read(), - " at offset ", Hex(base()+off)); + /* ignore unhandled extended capability */ ; } off = cap.read(); } @@ -518,12 +615,35 @@ struct Pci::Config : Genode::Mmio if (!reg0.valid()) continue; if (reg0.memory()) { + memory(reg0.addr(), reg0.size(), i, reg0.prefetchable()); if (reg0.bit64()) i++; - memory(reg0.addr(), reg0.size()); } else - io(reg0.addr(), reg0.size()); + io(reg0.addr(), reg0.size(), i); } }; + + void set_bar_address(unsigned idx, Genode::uint64_t addr) + { + if (idx > 5 || (idx > 1 && bridge())) + return; + + Base_address bar { base() + BASE_ADDRESS_0 + idx*0x4 }; + bar.set(addr); + } + + void power_on(Delayer & delayer) + { + if (!power_cap.constructed() || !power_cap->power_on(delayer)) + return; + + if (power_cap->soft_reset() && pci_e_cap.constructed()) + pci_e_cap->reset(delayer); + } + + void power_off() + { + if (power_cap.constructed()) power_cap->power_off(); + } }; @@ -537,6 +657,9 @@ struct Pci::Config_type0 : Pci::Config Base_address bar3 { base() + BASE_ADDRESS_0 + 0xc }; Base_address bar4 { base() + BASE_ADDRESS_0 + 0x10 }; Base_address bar5 { base() + BASE_ADDRESS_0 + 0x14 }; + + struct Subsystem_vendor : Register<0x2c, 16> { }; + struct Subsystem_device : Register<0x2e, 16> { }; }; diff --git a/repos/os/include/pci/types.h b/repos/os/include/pci/types.h index d18c219b9e..9376e39f62 100644 --- a/repos/os/include/pci/types.h +++ b/repos/os/include/pci/types.h @@ -15,6 +15,7 @@ #define __INCLUDE__PCI__TYPES_H__ #include +#include #include namespace Pci { @@ -41,6 +42,7 @@ namespace Pci { using vendor_t = Genode::uint16_t; using device_t = Genode::uint16_t; using class_t = Genode::uint32_t; + using rev_t = Genode::uint8_t; } diff --git a/repos/os/include/platform_session/connection.h b/repos/os/include/platform_session/connection.h index 350c8c7a1d..fbfa62a024 100644 --- a/repos/os/include/platform_session/connection.h +++ b/repos/os/include/platform_session/connection.h @@ -39,10 +39,11 @@ class Platform::Connection : public Genode::Connection, friend class Device; friend class Dma_buffer; - Env &_env; - Rom_session_client _rom {devices_rom()}; - Constructible _ds {}; - Constructible> _handler {}; + Env & _env; + Rom_session_client _rom { devices_rom() }; + Constructible _ds {}; + Io_signal_handler _handler { _env.ep(), *this, + &Connection::_handle_io }; void _try_attach() { @@ -60,19 +61,8 @@ class Platform::Connection : public Genode::Connection, for (;;) { /* repeatedly check for availability of device */ Capability cap = fn(); - if (cap.valid()) { - if (_handler.constructed()) { - sigh(Signal_context_capability()); - _handler.destruct(); - } + if (cap.valid()) return cap; - } - - if (!_handler.constructed()) { - _handler.construct(_env.ep(), *this, - &Connection::_handle_io); - sigh(*_handler); - } _env.ep().wait_and_dispatch_one_io_signal(); } @@ -89,6 +79,12 @@ class Platform::Connection : public Genode::Connection, _env(env) { _try_attach(); + + /* + * Initially register dummy handler, to be able to receive signals + * if _wait_for_device probes for a valid devices rom + */ + sigh(_handler); } void update() diff --git a/repos/os/include/platform_session/device.h b/repos/os/include/platform_session/device.h index 736fc5ceeb..4906f99956 100644 --- a/repos/os/include/platform_session/device.h +++ b/repos/os/include/platform_session/device.h @@ -49,9 +49,9 @@ class Platform::Device : Interface, Noncopyable return _cap.call(index); } - Io_mem_session_capability _io_mem(unsigned index, Range &range, Cache cache) + Io_mem_session_capability _io_mem(unsigned index, Range &range) { - return _cap.call(index, range, cache); + return _cap.call(index, range); } Io_port_session_capability _io_port_range(unsigned index) @@ -92,7 +92,7 @@ class Platform::Device::Mmio : Range, Attached_dataspace, public Genode::Mmio Dataspace_capability _ds_cap(Device &device, unsigned id) { - Io_mem_session_client io_mem(device._io_mem(id, *this, UNCACHED)); + Io_mem_session_client io_mem(device._io_mem(id, *this)); return io_mem.dataspace(); } @@ -117,6 +117,8 @@ class Platform::Device::Mmio : Range, Attached_dataspace, public Genode::Mmio template T *local_addr() { return reinterpret_cast(_local_addr()); } + + Dataspace_capability cap() { return Attached_dataspace::cap(); } }; diff --git a/repos/os/include/platform_session/platform_session.h b/repos/os/include/platform_session/platform_session.h index 6818276188..863764f9f0 100644 --- a/repos/os/include/platform_session/platform_session.h +++ b/repos/os/include/platform_session/platform_session.h @@ -42,7 +42,7 @@ struct Platform::Device_interface : Interface GENODE_RPC(Rpc_irq, Irq_session_capability, irq, unsigned); GENODE_RPC(Rpc_io_mem, Io_mem_session_capability, io_mem, - unsigned, Range &, Cache); + unsigned, Range &); GENODE_RPC(Rpc_io_port_range, Io_port_session_capability, io_port_range, unsigned); diff --git a/repos/os/include/report_rom/report_service.h b/repos/os/include/report_rom/report_service.h index a66b50cf60..2474b17be9 100644 --- a/repos/os/include/report_rom/report_service.h +++ b/repos/os/include/report_rom/report_service.h @@ -121,10 +121,7 @@ struct Report::Root : Genode::Root_component size_t const buffer_size = Arg_string::find_arg(args, "buffer_size").aligned_size(); - size_t const session_size = - max(sizeof(Session_component), 4096U) + buffer_size; - - if (ram_quota < session_size) { + if (ram_quota < buffer_size) { Genode::error("insufficient ram donation from ", label.string()); throw Insufficient_ram_quota(); } diff --git a/repos/os/include/trace/policy.h b/repos/os/include/trace/policy.h index 6304c35003..c387302459 100644 --- a/repos/os/include/trace/policy.h +++ b/repos/os/include/trace/policy.h @@ -21,11 +21,13 @@ namespace Genode { struct Signal_context; } -extern "C" size_t max_event_size (); -extern "C" size_t log_output (char *dst, char const *log_message, size_t len); -extern "C" size_t rpc_call (char *dst, char const *rpc_name, Genode::Msgbuf_base const &); -extern "C" size_t rpc_returned (char *dst, char const *rpc_name, Genode::Msgbuf_base const &); -extern "C" size_t rpc_dispatch (char *dst, char const *rpc_name); -extern "C" size_t rpc_reply (char *dst, char const *rpc_name); -extern "C" size_t signal_submit (char *dst, unsigned const); -extern "C" size_t signal_receive (char *dst, Genode::Signal_context const &, unsigned); +extern "C" size_t max_event_size (); +extern "C" size_t trace_eth_packet (char *dst, char const *name, bool out, char *data, size_t len); +extern "C" size_t checkpoint (char *dst, char const *name, unsigned long, void *, unsigned char); +extern "C" size_t log_output (char *dst, char const *log_message, size_t len); +extern "C" size_t rpc_call (char *dst, char const *rpc_name, Genode::Msgbuf_base const &); +extern "C" size_t rpc_returned (char *dst, char const *rpc_name, Genode::Msgbuf_base const &); +extern "C" size_t rpc_dispatch (char *dst, char const *rpc_name); +extern "C" size_t rpc_reply (char *dst, char const *rpc_name); +extern "C" size_t signal_submit (char *dst, unsigned const); +extern "C" size_t signal_receive (char *dst, Genode::Signal_context const &, unsigned); diff --git a/repos/os/include/usb_session/usb_session.h b/repos/os/include/usb_session/usb_session.h index 723bd21506..48ea6f8d94 100644 --- a/repos/os/include/usb_session/usb_session.h +++ b/repos/os/include/usb_session/usb_session.h @@ -219,17 +219,18 @@ struct Usb::Session : public Genode::Session GENODE_RPC(Rpc_tx_cap, Capability, _tx_cap); GENODE_RPC_THROW(Rpc_config_descr, void, config_descriptor, GENODE_TYPE_LIST(Device_not_found), Device_descriptor *, Config_descriptor *); - GENODE_RPC(Rpc_alt_settings, unsigned, alt_settings, unsigned); + GENODE_RPC_THROW(Rpc_alt_settings, unsigned, alt_settings, GENODE_TYPE_LIST(Device_not_found, + Interface_not_found), unsigned); GENODE_RPC_THROW(Rpc_iface_descr, void, interface_descriptor, GENODE_TYPE_LIST(Device_not_found, Interface_not_found), unsigned, unsigned, Interface_descriptor *); GENODE_RPC_THROW(Rpc_iface_extra, bool, interface_extra, GENODE_TYPE_LIST(Device_not_found, Interface_not_found), unsigned, unsigned, Interface_extra *); GENODE_RPC_THROW(Rpc_ep_descr, void, endpoint_descriptor, GENODE_TYPE_LIST(Device_not_found, Interface_not_found), unsigned, unsigned, unsigned, Endpoint_descriptor *); - GENODE_RPC_THROW(Rpc_claim_interface, void, claim_interface, GENODE_TYPE_LIST(Interface_not_found, - Interface_already_claimed), unsigned); - GENODE_RPC_THROW(Rpc_release_interface, void, release_interface, GENODE_TYPE_LIST(Interface_not_found), - unsigned); + GENODE_RPC_THROW(Rpc_claim_interface, void, claim_interface, GENODE_TYPE_LIST(Device_not_found, + Interface_not_found, Interface_already_claimed), unsigned); + GENODE_RPC_THROW(Rpc_release_interface, void, release_interface, GENODE_TYPE_LIST(Device_not_found, + Interface_not_found), unsigned); GENODE_RPC_INTERFACE(Rpc_plugged, Rpc_sigh_state_change, Rpc_tx_cap, Rpc_config_descr, Rpc_iface_descr, Rpc_iface_extra, Rpc_ep_descr, Rpc_alt_settings, Rpc_claim_interface, Rpc_release_interface); diff --git a/repos/os/include/util/geometry.h b/repos/os/include/util/geometry.h index 7fdbef5c38..a4080cc936 100644 --- a/repos/os/include/util/geometry.h +++ b/repos/os/include/util/geometry.h @@ -15,6 +15,7 @@ #define _INCLUDE__UTIL__GEOMETRY_H_ #include +#include #include #include @@ -68,6 +69,17 @@ class Genode::Point Genode::print(out, _x >= 0 ? "+" : "-", abs(_x), _y >= 0 ? "+" : "-", abs(_y)); } + + /** + * Construct point from XML node attributes + * + * The XML node is expected to feature the attributes 'xpos' and 'ypos'. + */ + static Point from_xml(Xml_node const &node) + { + return Point((CT)node.attribute_value("xpos", (CT)0), + (CT)node.attribute_value("ypos", (CT)0)); + } }; @@ -104,6 +116,18 @@ class Genode::Area bool operator == (Area const &a) const { return a.w() == _w && a.h() == _h; } void print(Output &out) const { Genode::print(out, _w, "x", _h); } + + /** + * Construct area from XML node attributes + * + * The XML node is expected to feature the attributes 'width' and + * 'height'. + */ + static Area from_xml(Xml_node const &node) + { + return Area((DT)node.attribute_value("width", (DT)0), + (DT)node.attribute_value("height", (DT)0)); + } }; @@ -210,9 +234,21 @@ class Genode::Rect * * The output has the form 'width' x 'height' +/- 'p1.x' +/- 'p1.y'. * For example, a rectange of size 15x16 as position (-13, 14) is - * printed as "15x16-13+14" + * printed as "15x16-13+14". */ void print(Output &out) const { Genode::print(out, area(), p1()); } + + /** + * Construct rectangle from XML node attributes + * + * The XML node is expected to feature the attributes 'xpos', 'ypos'. + * 'width', and 'height'. If an attribute is absent, the corresponding + * value is set to 0. + */ + static Rect from_xml(Xml_node const &node) + { + return Rect(Point::from_xml(node), Area
::from_xml(node)); + } }; #endif /* _INCLUDE__UTIL__GEOMETRY_H_ */ diff --git a/repos/os/include/virtio/pci_device.h b/repos/os/include/virtio/pci_device.h index 57e4c99a1d..088e494ace 100644 --- a/repos/os/include/virtio/pci_device.h +++ b/repos/os/include/virtio/pci_device.h @@ -14,10 +14,7 @@ #ifndef _INCLUDE__VIRTIO__PCI_DEVICE_H_ #define _INCLUDE__VIRTIO__PCI_DEVICE_H_ -#include -#include -#include -#include +#include #include namespace Virtio { @@ -26,7 +23,7 @@ namespace Virtio { class Device; } -struct Virtio::Device_mmio : public Attached_mmio +struct Virtio::Device_mmio : public Genode::Mmio { struct DeviceFeatureSelect : Register<0x00, 32> { }; struct DeviceFeature : Register<0x04, 32> { }; @@ -54,10 +51,7 @@ struct Virtio::Device_mmio : public Attached_mmio struct IrqReason : Register<0x0, 32> { }; - Device_mmio(Genode::Env &env, - Genode::addr_t base, - Genode::size_t size) - : Attached_mmio(env, base, size, false) { } + using Mmio::Mmio; }; class Virtio::Device @@ -93,133 +87,112 @@ class Virtio::Device enum { VIRTIO_PCI_BASE_ID = 0x1040, - VIRTIO_MSI_NO_VECTOR = 0xffff + VIRTIO_MSI_NO_VECTOR = 0xffff, + MMIO_MAX = 6U }; - Genode::Env &_env; - Platform::Device_client &_device; - Genode::Irq_session_client _irq { _device.irq(0) }; - uint32_t _notify_offset_multiplier = 0; - Genode::Constructible _cfg_common { }; - Genode::Constructible _dev_config { }; - Genode::Constructible _notify { }; - Genode::Constructible _isr { }; + Env & _env; + Platform::Connection & _plat; + Platform::Device _device { _plat }; + Platform::Device::Irq _irq { _device, { 0 } }; + Constructible _mmio[MMIO_MAX] { }; - void _configure() + Mmio _cfg_common { _bar_offset("common") }; + Mmio _dev_config { _bar_offset("device") }; + Mmio _notify { _bar_offset("notify") }; + Mmio _isr { _bar_offset("irq_status") }; + size_t _notify_offset_multiplier { 0 }; + + template + void with_virtio_range(String<16> type, FN const & fn) { - typedef Platform::Device Pdev; + _plat.update(); + _plat.with_xml([&] (Xml_node xml) { + xml.with_optional_sub_node("device", [&] (Xml_node xml) { + xml.with_optional_sub_node("pci-config", + [&] (Xml_node xml) { + xml.for_each_sub_node("virtio_range", + [&] (Xml_node xml) { + if (xml.attribute_value("type", String<16>()) == + type) + fn(xml); + }); + }); + }); + }); + } - enum { PCI_STATUS = 0x6, PCI_CAPABILITIES = 0x34, }; + addr_t _bar_offset(String<16> type) + { + unsigned idx = MMIO_MAX; + addr_t off = ~0UL; + with_virtio_range(type, [&] (Xml_node xml) { + idx = xml.attribute_value("index", MMIO_MAX); + off = xml.attribute_value("offset", ~0UL); + }); - auto status = _device.config_read(PCI_STATUS, Pdev::ACCESS_16BIT); - if (!(status & 0x10)) { - error("PCI capabilities missing according to device status!"); - throw Configuration_failed(); - } - - auto addr = _device.config_read(PCI_CAPABILITIES, Pdev::ACCESS_8BIT); - addr &= 0xFC; - - while (addr) { - enum { ID_VNDR = 0x09 }; - enum { CAP_ID = 0, CAP_LIST_NEXT = 1 }; - - auto const cap_id = _device.config_read(addr + CAP_ID, Pdev::ACCESS_8BIT); - auto const cap_next = _device.config_read(addr + CAP_LIST_NEXT, Pdev::ACCESS_8BIT); - - if (cap_id == ID_VNDR) { - enum { CFG_TYPE = 0x3, BAR = 0x4, OFFSET = 0x8, - LENGTH = 0xC, NOTIFY_OFFSET_MULT = 0x10 }; - enum { COMMON_CFG = 1, NOTIFY_CFG = 2, ISR_CFG = 3, - DEVICE_CFG = 4, PCI_CFG = 5 }; - - auto const cfg_type = _device.config_read(addr + CFG_TYPE, Pdev::ACCESS_8BIT); - auto const bar = _device.config_read(addr + BAR, Pdev::ACCESS_8BIT); - auto const off = _device.config_read(addr + OFFSET, Pdev::ACCESS_32BIT); - auto const len = _device.config_read(addr + LENGTH, Pdev::ACCESS_32BIT); - - if (cfg_type == COMMON_CFG) { - auto const r = _device.resource(bar); - _cfg_common.construct(_env, r.base() + off, len); - } else if (cfg_type == DEVICE_CFG) { - auto const r = _device.resource(bar); - _dev_config.construct(_env, r.base() + off, len); - } else if (cfg_type == NOTIFY_CFG) { - _notify_offset_multiplier = _device.config_read( - addr + NOTIFY_OFFSET_MULT, Pdev::ACCESS_32BIT); - auto const r = _device.resource(bar); - _notify.construct(_env, r.base() + off, len); - } else if (cfg_type == ISR_CFG) { - auto const r = _device.resource(bar); - _isr.construct(_env, r.base() + off, len); - } - } - - addr = cap_next; - } - - if (!_cfg_common.constructed() || !_dev_config.constructed() || - !_notify.constructed() || !_isr.constructed()) { - error("Required VirtIO PCI capabilities not found!"); + if (idx >= MMIO_MAX || off == ~0UL) throw Configuration_failed(); - } - _cfg_common->write(VIRTIO_MSI_NO_VECTOR); + if (!_mmio[idx].constructed()) + _mmio[idx].construct(_device, + Platform::Device::Mmio::Index{idx}); + return _mmio[idx]->base() + off; } public: - Device(Genode::Env &env, - Platform::Device_client device) - : _env(env), _device(device) + Device(Genode::Env & env, + Platform::Connection & plat) + : _env(env), _plat(plat) { - _configure(); + with_virtio_range("notify", [&] (Xml_node xml) { + _notify_offset_multiplier = xml.attribute_value("factor", 0UL); + }); + + _cfg_common.write(VIRTIO_MSI_NO_VECTOR); } - uint32_t vendor_id() { return _device.vendor_id(); } - uint32_t device_id() { - return _device.device_id() - VIRTIO_PCI_BASE_ID; } - uint8_t get_status() { - return _cfg_common->read(); } + return _cfg_common.read(); } bool set_status(uint8_t status) { - _cfg_common->write(status); - return _cfg_common->read() == status; + _cfg_common.write(status); + return _cfg_common.read() == status; } uint32_t get_features(uint32_t selection) { - _cfg_common->write(selection); - return _cfg_common->read(); + _cfg_common.write(selection); + return _cfg_common.read(); } void set_features(uint32_t selection, uint32_t features) { - _cfg_common->write(selection); - _cfg_common->write(features); + _cfg_common.write(selection); + _cfg_common.write(features); } uint8_t get_config_generation() { - return _cfg_common->read(); } + return _cfg_common.read(); } uint16_t get_max_queue_size(uint16_t queue_index) { - _cfg_common->write(queue_index); - return _cfg_common->read(); + _cfg_common.write(queue_index); + return _cfg_common.read(); } uint32_t read_config(uint8_t offset, Access_size size) { switch (size) { case Device::ACCESS_8BIT: - return _dev_config->read(offset); + return _dev_config.read(offset); case Device::ACCESS_16BIT: - return _dev_config->read(offset >> 1); + return _dev_config.read(offset >> 1); case Device::ACCESS_32BIT: - return _dev_config->read(offset >> 2); + return _dev_config.read(offset >> 2); } return 0; } @@ -228,63 +201,63 @@ class Virtio::Device { switch (size) { case Device::ACCESS_8BIT: - _dev_config->write(value, offset); + _dev_config.write(value, offset); break; case Device::ACCESS_16BIT: - _dev_config->write(value, offset >> 1); + _dev_config.write(value, offset >> 1); break; case Device::ACCESS_32BIT: - _dev_config->write(value, offset >> 2); + _dev_config.write(value, offset >> 2); break; } } bool configure_queue(uint16_t queue_index, Virtio::Queue_description desc) { - _cfg_common->write(queue_index); + _cfg_common.write(queue_index); - if (_cfg_common->read()) { + if (_cfg_common.read()) { warning("VirtIO queues can't be re-configured after being enabled!"); return false; } - _cfg_common->write(VIRTIO_MSI_NO_VECTOR); - if (_cfg_common->read() != VIRTIO_MSI_NO_VECTOR) { + _cfg_common.write(VIRTIO_MSI_NO_VECTOR); + if (_cfg_common.read() != VIRTIO_MSI_NO_VECTOR) { error("Failed to disable MSI-X for queue ", queue_index); return false; } - _cfg_common->write(desc.size); + _cfg_common.write(desc.size); uint64_t addr = desc.desc; - _cfg_common->write((uint32_t)addr); - _cfg_common->write((uint32_t)(addr >> 32)); + _cfg_common.write((uint32_t)addr); + _cfg_common.write((uint32_t)(addr >> 32)); addr = desc.avail; - _cfg_common->write((uint32_t)addr); - _cfg_common->write((uint32_t)(addr >> 32)); + _cfg_common.write((uint32_t)addr); + _cfg_common.write((uint32_t)(addr >> 32)); addr = desc.used; - _cfg_common->write((uint32_t)addr); - _cfg_common->write((uint32_t)(addr >> 32)); - _cfg_common->write(1); - return _cfg_common->read() != 0; + _cfg_common.write((uint32_t)addr); + _cfg_common.write((uint32_t)(addr >> 32)); + _cfg_common.write(1); + return _cfg_common.read() != 0; } void notify_buffers_available(uint16_t queue_index) { - _cfg_common->write(queue_index); - auto const offset = _cfg_common->read(); + _cfg_common.write(queue_index); + auto const offset = _cfg_common.read(); auto const addr = (offset * _notify_offset_multiplier >> 1) + 1; - _notify->local_addr()[addr] = queue_index; + *(uint16_t*)(_notify.base() + addr) = queue_index; } uint32_t read_isr() { - return _isr->read(); } + return _isr.read(); } void irq_sigh(Signal_context_capability cap) { _irq.sigh(cap); } - void irq_ack() { _irq.ack_irq(); } + void irq_ack() { _irq.ack(); } }; #endif /* _INCLUDE__VIRTIO__PCI_DEVICE_H_ */ diff --git a/repos/os/include/virtio/queue.h b/repos/os/include/virtio/queue.h index f37b792110..529dee2ddf 100644 --- a/repos/os/include/virtio/queue.h +++ b/repos/os/include/virtio/queue.h @@ -14,9 +14,8 @@ #ifndef _INCLUDE__VIRTIO__QUEUE_H_ #define _INCLUDE__VIRTIO__QUEUE_H_ -#include +#include #include -#include #include namespace Virtio @@ -138,7 +137,7 @@ class Virtio::Queue Buffer_pool(Buffer_pool const &) = delete; Buffer_pool &operator = (Buffer_pool const &) = delete; - Attached_dataspace _ds; + Platform::Dma_buffer _ds; uint16_t const _buffer_count; uint16_t const _buffer_size; addr_t const _phys_base; @@ -156,16 +155,14 @@ class Virtio::Queue }; Buffer_pool(Platform::Connection & plat, - Region_map & rm, uint16_t const buffer_count, uint16_t const buffer_size) : - _ds(rm, plat.alloc_dma_buffer(buffer_count * - align_natural(buffer_size), - CACHED)), + _ds(plat, buffer_count * align_natural(buffer_size), + CACHED), _buffer_count(buffer_count), _buffer_size(buffer_size), - _phys_base(_dma_addr(plat, _ds.cap())) {} + _phys_base(_ds.dma_addr()) {} const Buffer get(uint16_t descriptor_idx) const { @@ -211,7 +208,7 @@ class Virtio::Queue uint16_t const _queue_size; - Attached_dataspace _ds; + Platform::Dma_buffer _ds; Buffer_pool _buffers; Avail volatile * const _avail; Used volatile * const _used; @@ -565,18 +562,16 @@ class Virtio::Queue print(output, _queue_size); } - Queue(Region_map & rm, - Platform::Connection & plat, + Queue(Platform::Connection & plat, uint16_t queue_size, uint16_t buffer_size) : _queue_size(queue_size), - _ds(rm, plat.alloc_dma_buffer(_ds_size(queue_size), UNCACHED)), - _buffers(plat, rm, queue_size, _check_buffer_size(buffer_size)), + _ds(plat, _ds_size(queue_size), UNCACHED), + _buffers(plat, queue_size, _check_buffer_size(buffer_size)), _avail(_init_avail(_ds.local_addr(), queue_size)), _used(_init_used(_ds.local_addr(), queue_size)), _descriptors(_ds.local_addr(), queue_size), - _description(_init_description(queue_size, - _dma_addr(plat, _ds.cap()))) + _description(_init_description(queue_size, _ds.dma_addr())) { _fill_descriptor_table(); } diff --git a/repos/os/recipes/api/audio_in_session/hash b/repos/os/recipes/api/audio_in_session/hash index 4f5c566935..02684fcfcb 100644 --- a/repos/os/recipes/api/audio_in_session/hash +++ b/repos/os/recipes/api/audio_in_session/hash @@ -1 +1 @@ -2022-01-18 248c7dfdbd29bf3c4b117cd0d70973a00757718d +2022-08-16 2ef529898c2fcf111c474f468de106a48bc4ba1e diff --git a/repos/os/recipes/api/audio_out_session/hash b/repos/os/recipes/api/audio_out_session/hash index 08f7723b57..84980f4d00 100644 --- a/repos/os/recipes/api/audio_out_session/hash +++ b/repos/os/recipes/api/audio_out_session/hash @@ -1 +1 @@ -2022-01-18 7e8b0238ef01fa0e844a513d490f26e3a0d8df02 +2022-09-20 367b89903fd6b510ad8c7aa429cd367361981e6b diff --git a/repos/os/recipes/api/block_session/hash b/repos/os/recipes/api/block_session/hash index 2eee581ef0..99a88989b1 100644 --- a/repos/os/recipes/api/block_session/hash +++ b/repos/os/recipes/api/block_session/hash @@ -1 +1 @@ -2022-04-27 e6220d7163d0212598b00d45f0755d56aa43575e +2022-08-16 79d59088effa972bdd9b0220a154f48c16f1f780 diff --git a/repos/os/recipes/api/file_system_session/hash b/repos/os/recipes/api/file_system_session/hash index 30ff43282f..a004571a1a 100644 --- a/repos/os/recipes/api/file_system_session/hash +++ b/repos/os/recipes/api/file_system_session/hash @@ -1 +1 @@ -2022-02-14 620c7c83e3285d08858d8a4e69894bf9d35d0dbd +2022-09-20 077fa78b70134123b3b5005eb7bd7d0dcc4d1d6c diff --git a/repos/os/recipes/api/genode_c_api/hash b/repos/os/recipes/api/genode_c_api/hash index ad71a7f22e..faaf835e4d 100644 --- a/repos/os/recipes/api/genode_c_api/hash +++ b/repos/os/recipes/api/genode_c_api/hash @@ -1 +1 @@ -2022-04-27 0a8bcdae6027d192c36195042c1e8a5c2a48d5a9 +2022-09-20 a4488c152b5ff9071cdcd7d135f62efcaf53b6ac diff --git a/repos/os/recipes/api/gpu_session/hash b/repos/os/recipes/api/gpu_session/hash index 07ffa6a00d..a828008be2 100644 --- a/repos/os/recipes/api/gpu_session/hash +++ b/repos/os/recipes/api/gpu_session/hash @@ -1 +1 @@ -2022-02-14 e95cd305d2fde59948e1e1fb8ed4251f3d83653c +2022-08-16 7b3ada81f3f160f6ae0032f6d4e40a10793cbae9 diff --git a/repos/os/recipes/api/net/hash b/repos/os/recipes/api/net/hash index 09610c99b5..ca004de671 100644 --- a/repos/os/recipes/api/net/hash +++ b/repos/os/recipes/api/net/hash @@ -1 +1 @@ -2022-05-24 b04cf4a45f75349c92b73773cff265f637f801fc +2022-10-13 e9d4eef65b30010955d36fdee8f346c44cae541f diff --git a/repos/os/recipes/api/nic_session/hash b/repos/os/recipes/api/nic_session/hash index 91b3d53ee3..2a21572f1c 100644 --- a/repos/os/recipes/api/nic_session/hash +++ b/repos/os/recipes/api/nic_session/hash @@ -1 +1 @@ -2022-05-24 eebf0a6e36d56ecbbf4fb603bb969ea8a45e4c26 +2022-08-30 e1de77019b959b55c45ac857cdc136796e59774c diff --git a/repos/os/recipes/api/os/content.mk b/repos/os/recipes/api/os/content.mk index ee41b4da74..016e20cee3 100644 --- a/repos/os/recipes/api/os/content.mk +++ b/repos/os/recipes/api/os/content.mk @@ -1,5 +1,5 @@ -INCLUDE_SUB_DIRS := os util packet_stream_rx packet_stream_tx spec/x86_64/os \ - spec/arm/os spec/x86_32/os spec/arm_64/os +INCLUDE_SUB_DIRS := os util packet_stream_rx packet_stream_tx pci \ + spec/x86_64/os spec/arm/os spec/x86_32/os spec/arm_64/os MIRRORED_FROM_REP_DIR := $(addprefix include/,$(INCLUDE_SUB_DIRS)) diff --git a/repos/os/recipes/api/os/hash b/repos/os/recipes/api/os/hash index 98abcbaf87..77df326c5c 100644 --- a/repos/os/recipes/api/os/hash +++ b/repos/os/recipes/api/os/hash @@ -1 +1 @@ -2022-04-12 17ca6587c67923f25e0f7e004af991c213302828 +2022-10-11 d2302f0d0fdb9b8f616461c5295d83ea0da48e36 diff --git a/repos/os/recipes/api/platform_session/hash b/repos/os/recipes/api/platform_session/hash index 0b4d8866de..4680c2190e 100644 --- a/repos/os/recipes/api/platform_session/hash +++ b/repos/os/recipes/api/platform_session/hash @@ -1 +1 @@ -2022-05-24 23561753de5a37868ae04d46d4f643f5deeddb06 +2022-10-11 adcb54072a44c3bcd981b58ede26ab822fdbf328 diff --git a/repos/os/recipes/api/trace/hash b/repos/os/recipes/api/trace/hash index 4cb1c3bc53..0fd134e65c 100644 --- a/repos/os/recipes/api/trace/hash +++ b/repos/os/recipes/api/trace/hash @@ -1 +1 @@ -2022-05-24 2e443e4291b530a90c91f2943b5bde7f1fa567fc +2022-08-16 88eda27c18c227cd2216501caaef1a45a6392f07 diff --git a/repos/os/recipes/api/uplink_session/hash b/repos/os/recipes/api/uplink_session/hash index a4e902f217..7e6e0348f6 100644 --- a/repos/os/recipes/api/uplink_session/hash +++ b/repos/os/recipes/api/uplink_session/hash @@ -1 +1 @@ -2022-05-24 996ab9d103b7cafd48f0813bb474da789cefc895 +2022-08-30 9b11856ee11375c27b0b647e67bf8797c25369e8 diff --git a/repos/os/recipes/api/usb_session/hash b/repos/os/recipes/api/usb_session/hash index 92974f6912..396423c23a 100644 --- a/repos/os/recipes/api/usb_session/hash +++ b/repos/os/recipes/api/usb_session/hash @@ -1 +1 @@ -2022-04-12 b3aee50282918f3b8e28218ecce8fb94fc71802c +2022-08-30 63fbe4de4dc753a71f69abcc1079393284e11fee diff --git a/repos/os/recipes/api/virtio/hash b/repos/os/recipes/api/virtio/hash index 9e2c01e800..fd48445dee 100644 --- a/repos/os/recipes/api/virtio/hash +++ b/repos/os/recipes/api/virtio/hash @@ -1 +1 @@ -2022-02-14 ba487bac0db1f052bf39aeaf594e0fce0db77dde +2022-10-11 f07f668b4d84d0343a706aa296c2026a6a97736e diff --git a/repos/os/recipes/pkg/black_hole/hash b/repos/os/recipes/pkg/black_hole/hash index 86376bfb3f..65a4815378 100644 --- a/repos/os/recipes/pkg/black_hole/hash +++ b/repos/os/recipes/pkg/black_hole/hash @@ -1 +1 @@ -2022-05-24 9aca5262f6a13bd8bbf4f27f1e014abfc829035f +2022-10-11 aea241129878eba26a3b9d29ad03a0131b10a5f3 diff --git a/repos/os/recipes/pkg/chroot/hash b/repos/os/recipes/pkg/chroot/hash index b1ee84dfa2..0bbc73e616 100644 --- a/repos/os/recipes/pkg/chroot/hash +++ b/repos/os/recipes/pkg/chroot/hash @@ -1 +1 @@ -2022-05-24 747ad1f302337ba23c934d737fdc5a28685f90af +2022-10-11 bb7ae9efbe99d15190ff498c32a8f0dd0597d8de diff --git a/repos/os/recipes/pkg/clipboard/hash b/repos/os/recipes/pkg/clipboard/hash index a9b42c6995..f474fccf2c 100644 --- a/repos/os/recipes/pkg/clipboard/hash +++ b/repos/os/recipes/pkg/clipboard/hash @@ -1 +1 @@ -2022-05-24 7007b602b9f4761b57e5e9223b1f57f865914474 +2022-10-11 3c99bdb273857e2988a2054330d59acdd5de7378 diff --git a/repos/os/recipes/pkg/cpu_balancer/hash b/repos/os/recipes/pkg/cpu_balancer/hash index cfbde002e0..123b952894 100644 --- a/repos/os/recipes/pkg/cpu_balancer/hash +++ b/repos/os/recipes/pkg/cpu_balancer/hash @@ -1 +1 @@ -2022-05-24 5aad956d8b98c81addea84313c88ac2299dd8d02 +2022-10-11 723ea5fbde749abfe6ac49b8a8b8d9eb76a9f77c diff --git a/repos/os/recipes/pkg/cpu_balancer_config/hash b/repos/os/recipes/pkg/cpu_balancer_config/hash index 3eff3cdef5..8c17f2af46 100644 --- a/repos/os/recipes/pkg/cpu_balancer_config/hash +++ b/repos/os/recipes/pkg/cpu_balancer_config/hash @@ -1 +1 @@ -2022-05-24 140b0e88708dcd9acb0521024e1e7f0b0aa810d0 +2022-10-11 daa7ac3ab6dfa7e8cc98b455b3aba13c0ecfbe0a diff --git a/repos/os/recipes/pkg/drivers_interactive-linux/hash b/repos/os/recipes/pkg/drivers_interactive-linux/hash index b9f0b8b6ad..b3ff078e62 100644 --- a/repos/os/recipes/pkg/drivers_interactive-linux/hash +++ b/repos/os/recipes/pkg/drivers_interactive-linux/hash @@ -1 +1 @@ -2022-05-24 35671e6b5193e75ed65695aaa82baccae3b89149 +2022-10-11 d31991d2b17ff1cf82d6ef022ccbdf2f51560769 diff --git a/repos/os/recipes/pkg/drivers_interactive-pbxa9/hash b/repos/os/recipes/pkg/drivers_interactive-pbxa9/hash index da16eb4284..9527d6544f 100644 --- a/repos/os/recipes/pkg/drivers_interactive-pbxa9/hash +++ b/repos/os/recipes/pkg/drivers_interactive-pbxa9/hash @@ -1 +1 @@ -2022-05-24 466f7e78b04661510969b8b1bd2977e528a2cc51 +2022-10-11 29a8a43cc84a40b4e6f131d9b76532367fbadf2f diff --git a/repos/os/recipes/pkg/drivers_interactive-pc/archives b/repos/os/recipes/pkg/drivers_interactive-pc/archives index 764954b3de..3749d1bf72 100644 --- a/repos/os/recipes/pkg/drivers_interactive-pc/archives +++ b/repos/os/recipes/pkg/drivers_interactive-pc/archives @@ -5,5 +5,8 @@ _/src/pc_usb_host_drv _/src/usb_hid_drv _/src/vesa_drv _/src/report_rom +_/src/rom_filter _/src/event_filter +_/src/pci_decode _/raw/drivers_interactive-pc +_/raw/pc-devices diff --git a/repos/os/recipes/pkg/drivers_interactive-pc/hash b/repos/os/recipes/pkg/drivers_interactive-pc/hash index 36d5abf0d6..22053e77a3 100644 --- a/repos/os/recipes/pkg/drivers_interactive-pc/hash +++ b/repos/os/recipes/pkg/drivers_interactive-pc/hash @@ -1 +1 @@ -2022-05-30 a0cc3bb28e490b98435e434b40b8b7d177b65c09 +2022-10-11 4cf6004aa40c9e7bf02b5e0d9c8776753ea7cd7d diff --git a/repos/os/recipes/pkg/drivers_interactive-virt_qemu/hash b/repos/os/recipes/pkg/drivers_interactive-virt_qemu/hash deleted file mode 100644 index cc5bb87ede..0000000000 --- a/repos/os/recipes/pkg/drivers_interactive-virt_qemu/hash +++ /dev/null @@ -1 +0,0 @@ -2022-05-24 882323bc8a17974e55dcf61ddb6c39028d4481ef diff --git a/repos/os/recipes/pkg/drivers_interactive-virt_qemu/README b/repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v7a/README similarity index 100% rename from repos/os/recipes/pkg/drivers_interactive-virt_qemu/README rename to repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v7a/README diff --git a/repos/os/recipes/pkg/drivers_interactive-virt_qemu/archives b/repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v7a/archives similarity index 71% rename from repos/os/recipes/pkg/drivers_interactive-virt_qemu/archives rename to repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v7a/archives index 9b392ccf04..bb1b5d8f0f 100644 --- a/repos/os/recipes/pkg/drivers_interactive-virt_qemu/archives +++ b/repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v7a/archives @@ -3,4 +3,4 @@ _/src/virtio_input_drv _/src/platform_drv _/src/event_filter _/src/virtdev_rom -_/raw/drivers_interactive-virt_qemu +_/raw/drivers_interactive-virt_qemu_arm diff --git a/repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v7a/hash b/repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v7a/hash new file mode 100644 index 0000000000..c7d9ae1f3d --- /dev/null +++ b/repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v7a/hash @@ -0,0 +1 @@ +2022-10-11 62e92d13e82a37bd498799e6fa5d06cb8ef930ed diff --git a/repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v8a/README b/repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v8a/README new file mode 100644 index 0000000000..3273ce23de --- /dev/null +++ b/repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v8a/README @@ -0,0 +1,3 @@ + + Device drivers needed to run interactive + scenarios on the Virt platform as emulated by Qemu diff --git a/repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v8a/archives b/repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v8a/archives new file mode 100644 index 0000000000..bb1b5d8f0f --- /dev/null +++ b/repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v8a/archives @@ -0,0 +1,6 @@ +_/src/virtio_fb_drv +_/src/virtio_input_drv +_/src/platform_drv +_/src/event_filter +_/src/virtdev_rom +_/raw/drivers_interactive-virt_qemu_arm diff --git a/repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v8a/hash b/repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v8a/hash new file mode 100644 index 0000000000..c7d9ae1f3d --- /dev/null +++ b/repos/os/recipes/pkg/drivers_interactive-virt_qemu_arm_v8a/hash @@ -0,0 +1 @@ +2022-10-11 62e92d13e82a37bd498799e6fa5d06cb8ef930ed diff --git a/repos/os/recipes/pkg/drivers_nic-linux/hash b/repos/os/recipes/pkg/drivers_nic-linux/hash index a00b3cadef..d02a57c5d6 100644 --- a/repos/os/recipes/pkg/drivers_nic-linux/hash +++ b/repos/os/recipes/pkg/drivers_nic-linux/hash @@ -1 +1 @@ -2022-05-24 8761c075cfc4e7e6e2444426ba359351efdd6f75 +2022-10-11 baf260966e8c88ecc60415016fa9144ccb51db04 diff --git a/repos/os/recipes/pkg/drivers_nic-pbxa9/hash b/repos/os/recipes/pkg/drivers_nic-pbxa9/hash index a1185e5154..7bb82af8ee 100644 --- a/repos/os/recipes/pkg/drivers_nic-pbxa9/hash +++ b/repos/os/recipes/pkg/drivers_nic-pbxa9/hash @@ -1 +1 @@ -2022-05-24 13b0147828f8273244d69b1d23ad4f9601f17d18 +2022-10-11 c6c8e9464cffc6a7e467d534a2cc25b729ebb738 diff --git a/repos/os/recipes/pkg/drivers_nic-virt_qemu/hash b/repos/os/recipes/pkg/drivers_nic-virt_qemu/hash deleted file mode 100644 index 9a9d475c55..0000000000 --- a/repos/os/recipes/pkg/drivers_nic-virt_qemu/hash +++ /dev/null @@ -1 +0,0 @@ -2022-05-24 4ed87f751b0a53cba22cb8132bb18ac8d935228b diff --git a/repos/os/recipes/pkg/drivers_nic-virt_qemu/README b/repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v7a/README similarity index 100% rename from repos/os/recipes/pkg/drivers_nic-virt_qemu/README rename to repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v7a/README diff --git a/repos/os/recipes/pkg/drivers_nic-virt_qemu/archives b/repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v7a/archives similarity index 64% rename from repos/os/recipes/pkg/drivers_nic-virt_qemu/archives rename to repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v7a/archives index 9aae66c752..c947c8bdc9 100644 --- a/repos/os/recipes/pkg/drivers_nic-virt_qemu/archives +++ b/repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v7a/archives @@ -1,4 +1,4 @@ -_/raw/drivers_nic-virt_qemu +_/raw/drivers_nic-virt_qemu_arm _/src/virtdev_rom _/src/platform_drv _/src/virtio_nic_drv diff --git a/repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v7a/hash b/repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v7a/hash new file mode 100644 index 0000000000..05f713cf78 --- /dev/null +++ b/repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v7a/hash @@ -0,0 +1 @@ +2022-10-11 d86aa4f30cf763d57ff20df4d088d97dff64548a diff --git a/repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v8a/README b/repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v8a/README new file mode 100644 index 0000000000..b9ad938515 --- /dev/null +++ b/repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v8a/README @@ -0,0 +1,3 @@ + + Device drivers needed for scenarios + using one network interface diff --git a/repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v8a/archives b/repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v8a/archives new file mode 100644 index 0000000000..c947c8bdc9 --- /dev/null +++ b/repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v8a/archives @@ -0,0 +1,4 @@ +_/raw/drivers_nic-virt_qemu_arm +_/src/virtdev_rom +_/src/platform_drv +_/src/virtio_nic_drv diff --git a/repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v8a/hash b/repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v8a/hash new file mode 100644 index 0000000000..05f713cf78 --- /dev/null +++ b/repos/os/recipes/pkg/drivers_nic-virt_qemu_arm_v8a/hash @@ -0,0 +1 @@ +2022-10-11 d86aa4f30cf763d57ff20df4d088d97dff64548a diff --git a/repos/os/recipes/pkg/fs_report/hash b/repos/os/recipes/pkg/fs_report/hash index e4b33fa267..54ece5c94f 100644 --- a/repos/os/recipes/pkg/fs_report/hash +++ b/repos/os/recipes/pkg/fs_report/hash @@ -1 +1 @@ -2022-05-24 2a1ec14f9c409dc0a26f8397cb0314f4268b0191 +2022-10-11 700987d4bfce4e0f84375e90519a2558fe7054cd diff --git a/repos/os/recipes/pkg/fs_rom/hash b/repos/os/recipes/pkg/fs_rom/hash index 0c7f0c30fe..7ff34aedef 100644 --- a/repos/os/recipes/pkg/fs_rom/hash +++ b/repos/os/recipes/pkg/fs_rom/hash @@ -1 +1 @@ -2022-05-24 abaf3d0ab7b0620d23c9aa20de619f3059032302 +2022-10-11 32048032d17845fac915a51d8010a658b2d135c7 diff --git a/repos/os/recipes/pkg/mixer/hash b/repos/os/recipes/pkg/mixer/hash index adda007301..36c782acf9 100644 --- a/repos/os/recipes/pkg/mixer/hash +++ b/repos/os/recipes/pkg/mixer/hash @@ -1 +1 @@ -2022-05-24 1d3e4f5921f6aa3202d0f24d8e5bbe5f00aec39d +2022-10-11 d5c13f8da5e61dba061ffebb2bc8645c110acd48 diff --git a/repos/os/recipes/pkg/nic_router-nat/hash b/repos/os/recipes/pkg/nic_router-nat/hash index e1f261d042..4d28460ced 100644 --- a/repos/os/recipes/pkg/nic_router-nat/hash +++ b/repos/os/recipes/pkg/nic_router-nat/hash @@ -1 +1 @@ -2022-05-24 b82ff7c385589028426c560dcd215e88f6a1dc32 +2022-10-13 91cf27f8392f854540f919bb89bffa416d230903 diff --git a/repos/os/recipes/pkg/nit_focus/hash b/repos/os/recipes/pkg/nit_focus/hash index c814daf565..d3ba9ea7a7 100644 --- a/repos/os/recipes/pkg/nit_focus/hash +++ b/repos/os/recipes/pkg/nit_focus/hash @@ -1 +1 @@ -2022-05-24 b38e298c4ed31ae2d768fa2ca443b5cf7de6ccfd +2022-10-11 4246fb270937a5e17ac6e251c957d0a7623dc670 diff --git a/repos/os/recipes/pkg/part_block/README b/repos/os/recipes/pkg/part_block/README new file mode 100644 index 0000000000..01c6efbebb --- /dev/null +++ b/repos/os/recipes/pkg/part_block/README @@ -0,0 +1,2 @@ + + Runtime for deploying the part_block component from the depot diff --git a/repos/os/recipes/pkg/part_block/archives b/repos/os/recipes/pkg/part_block/archives new file mode 100755 index 0000000000..aa60826d35 --- /dev/null +++ b/repos/os/recipes/pkg/part_block/archives @@ -0,0 +1 @@ +_/src/part_block diff --git a/repos/os/recipes/pkg/part_block/hash b/repos/os/recipes/pkg/part_block/hash new file mode 100644 index 0000000000..55111b2cd8 --- /dev/null +++ b/repos/os/recipes/pkg/part_block/hash @@ -0,0 +1 @@ +2022-10-11 a4317ecd68cfaff34eec8c70d90bed48ec92c5cd diff --git a/repos/os/recipes/pkg/part_block/runtime b/repos/os/recipes/pkg/part_block/runtime new file mode 100755 index 0000000000..8a36f3df10 --- /dev/null +++ b/repos/os/recipes/pkg/part_block/runtime @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/repos/os/recipes/pkg/recall_fs/hash b/repos/os/recipes/pkg/recall_fs/hash index 385fb1546f..cd3a9a30b1 100644 --- a/repos/os/recipes/pkg/recall_fs/hash +++ b/repos/os/recipes/pkg/recall_fs/hash @@ -1 +1 @@ -2022-05-24 8082e0ae34aca5eb35270dbd5a81876e6175b2ab +2022-10-11 dfc16bacfcb776ca8232cb1072afdcde9232f206 diff --git a/repos/os/recipes/pkg/report_rom/hash b/repos/os/recipes/pkg/report_rom/hash index c092845683..fa4da740c2 100644 --- a/repos/os/recipes/pkg/report_rom/hash +++ b/repos/os/recipes/pkg/report_rom/hash @@ -1 +1 @@ -2022-05-24 3c3466652c1f17c20d971de7baa1d390e53a6dd5 +2022-10-11 5a392e0400332aa46243f87f3434143e5a1a3e31 diff --git a/repos/os/recipes/pkg/rom_filter/hash b/repos/os/recipes/pkg/rom_filter/hash index 41e6875a20..d839f63300 100644 --- a/repos/os/recipes/pkg/rom_filter/hash +++ b/repos/os/recipes/pkg/rom_filter/hash @@ -1 +1 @@ -2022-05-24 ea344a29334a0ddaaabe1d09fcba08aec0356e07 +2022-10-11 51081176262ccb5ed8d517138ea3da1440bf7d3b diff --git a/repos/os/recipes/pkg/rom_reporter/hash b/repos/os/recipes/pkg/rom_reporter/hash index 0992b38504..33de8309d7 100644 --- a/repos/os/recipes/pkg/rom_reporter/hash +++ b/repos/os/recipes/pkg/rom_reporter/hash @@ -1 +1 @@ -2022-05-24 6427bbe49b53e5ee09af7780938a8202b6e10c49 +2022-10-11 b4f86a6bdf4073a55edb47d0a68e02066d47b78f diff --git a/repos/os/recipes/pkg/test-black_hole/hash b/repos/os/recipes/pkg/test-black_hole/hash index eeb55a4c1e..3aea8699c7 100644 --- a/repos/os/recipes/pkg/test-black_hole/hash +++ b/repos/os/recipes/pkg/test-black_hole/hash @@ -1 +1 @@ -2022-05-24 1e7dbf3094ab393d7e5ad2234eea13662e7967b9 +2022-10-11 7ce1c14c911cc0a419045151504ff157f5d26b7d diff --git a/repos/os/recipes/pkg/test-capture/hash b/repos/os/recipes/pkg/test-capture/hash index e54ee5ce5c..b0c4635de8 100644 --- a/repos/os/recipes/pkg/test-capture/hash +++ b/repos/os/recipes/pkg/test-capture/hash @@ -1 +1 @@ -2022-05-24 c882f21370f2d4786f49a7a8ed54b69add592051 +2022-10-11 7d3945b9a8d6bfb01dea1e97b1256b566aaf0ef7 diff --git a/repos/os/recipes/pkg/test-clipboard/hash b/repos/os/recipes/pkg/test-clipboard/hash index e976379ebc..4f1d95a27d 100644 --- a/repos/os/recipes/pkg/test-clipboard/hash +++ b/repos/os/recipes/pkg/test-clipboard/hash @@ -1 +1 @@ -2022-05-24 5ed950f62ac45790f1a203274c53973d969fbc3a +2022-10-11 eee75418fdbaf99c4a426a611e8216daf6fda7ea diff --git a/repos/os/recipes/pkg/test-dynamic_config/hash b/repos/os/recipes/pkg/test-dynamic_config/hash index ec4000e3dd..1f8c86082b 100644 --- a/repos/os/recipes/pkg/test-dynamic_config/hash +++ b/repos/os/recipes/pkg/test-dynamic_config/hash @@ -1 +1 @@ -2022-05-24 41e91cc9e70f61afdc3751bb2fbc255562376f4a +2022-10-11 30054f67f3b1ddfe6688f4b8da7cacdf55b136a1 diff --git a/repos/os/recipes/pkg/test-dynamic_config_loader/hash b/repos/os/recipes/pkg/test-dynamic_config_loader/hash index 72f4e84bc6..c1c3fbd530 100644 --- a/repos/os/recipes/pkg/test-dynamic_config_loader/hash +++ b/repos/os/recipes/pkg/test-dynamic_config_loader/hash @@ -1 +1 @@ -2022-05-24 bf27e7dea892769078cb1e1f4aadb38b613a641d +2022-10-11 87ef09d7d73ceb319c965567f8ed356a10eb1b3e diff --git a/repos/os/recipes/pkg/test-fault_detection/hash b/repos/os/recipes/pkg/test-fault_detection/hash index 40dfc6af23..5b6c221e78 100644 --- a/repos/os/recipes/pkg/test-fault_detection/hash +++ b/repos/os/recipes/pkg/test-fault_detection/hash @@ -1 +1 @@ -2022-05-24 e866a5508179797dc70e6ddfb690a37814514f88 +2022-10-11 cf2cb45d256b1882fc55ec8b647beab0e3c71401 diff --git a/repos/os/recipes/pkg/test-fs_packet/hash b/repos/os/recipes/pkg/test-fs_packet/hash index bb1926212a..eaee6465c8 100644 --- a/repos/os/recipes/pkg/test-fs_packet/hash +++ b/repos/os/recipes/pkg/test-fs_packet/hash @@ -1 +1 @@ -2022-05-24 2fa8b8039815d81b80d72e0d04afc91b9a56d41f +2022-10-11 c8153a4ad7a626febc1a470f3873f94f56c0f4c4 diff --git a/repos/os/recipes/pkg/test-fs_report/hash b/repos/os/recipes/pkg/test-fs_report/hash index f82be0cc5b..9c9ebed335 100644 --- a/repos/os/recipes/pkg/test-fs_report/hash +++ b/repos/os/recipes/pkg/test-fs_report/hash @@ -1 +1 @@ -2022-05-24 b6d52193cb7d1566d97edcd752c0e5884cc903c8 +2022-10-11 7a4ed19dd9e3950d915e96dcd90d0e634d5055f6 diff --git a/repos/os/recipes/pkg/test-fs_rom_update/hash b/repos/os/recipes/pkg/test-fs_rom_update/hash index b880893a93..f42c1b2c1e 100644 --- a/repos/os/recipes/pkg/test-fs_rom_update/hash +++ b/repos/os/recipes/pkg/test-fs_rom_update/hash @@ -1 +1 @@ -2022-05-24 f21b7216d3d58b969bd518fb44b00b9fc7f6ee42 +2022-10-11 6e44b98ab57f654631bb885d2a59c4d2f7c62d94 diff --git a/repos/os/recipes/pkg/test-fs_rom_update_fs/hash b/repos/os/recipes/pkg/test-fs_rom_update_fs/hash index 58ccfb98c1..b1ed756ecf 100644 --- a/repos/os/recipes/pkg/test-fs_rom_update_fs/hash +++ b/repos/os/recipes/pkg/test-fs_rom_update_fs/hash @@ -1 +1 @@ -2022-05-24 76a1d4a9c74fbabd3989644c1c0e6449c6a6cd8a +2022-10-11 3903f54c0be779846ac6d74cd022fef3281d1064 diff --git a/repos/os/recipes/pkg/test-fs_rom_update_ram/hash b/repos/os/recipes/pkg/test-fs_rom_update_ram/hash index 42ecbf0e16..9e9a5014e3 100644 --- a/repos/os/recipes/pkg/test-fs_rom_update_ram/hash +++ b/repos/os/recipes/pkg/test-fs_rom_update_ram/hash @@ -1 +1 @@ -2022-05-24 86f6d13794611f414dd2d187db0e50978e419e38 +2022-10-11 161dc221eda72a95b546a335bb1ab31ac8f42ad2 diff --git a/repos/os/recipes/pkg/test-init/hash b/repos/os/recipes/pkg/test-init/hash index 8b3798f593..b1fbc5b9f1 100644 --- a/repos/os/recipes/pkg/test-init/hash +++ b/repos/os/recipes/pkg/test-init/hash @@ -1 +1 @@ -2022-05-24 aca9ff105cbe1363c9b36a0d6051c8acf95fdbe0 +2022-10-11 06b93fe3cddb656a2f0284262d364e8d2412c4a4 diff --git a/repos/os/recipes/pkg/test-init/runtime b/repos/os/recipes/pkg/test-init/runtime index 3bf01e2601..74fd529b5d 100644 --- a/repos/os/recipes/pkg/test-init/runtime +++ b/repos/os/recipes/pkg/test-init/runtime @@ -5,6 +5,7 @@ child "test-init" exited with exit value 0 + list model not empty at destruction time diff --git a/repos/os/recipes/pkg/test-init_loop/hash b/repos/os/recipes/pkg/test-init_loop/hash index c3778a5dcd..be1b0dd9bf 100644 --- a/repos/os/recipes/pkg/test-init_loop/hash +++ b/repos/os/recipes/pkg/test-init_loop/hash @@ -1 +1 @@ -2022-05-24 b08b8290df42648e81a50900e47f36e358c8688a +2022-10-11 10de16fc39c7346d7827219b3a54469e1e9737f3 diff --git a/repos/os/recipes/pkg/test-lx_block/hash b/repos/os/recipes/pkg/test-lx_block/hash index 825d25c324..c64d4041cb 100644 --- a/repos/os/recipes/pkg/test-lx_block/hash +++ b/repos/os/recipes/pkg/test-lx_block/hash @@ -1 +1 @@ -2022-05-24 0976a9790be7a938540eadb3ef6ce73a37f796b2 +2022-10-11 90538e539505e44d772ec54b1a88444403978b5e diff --git a/repos/os/recipes/pkg/test-nic_loopback/hash b/repos/os/recipes/pkg/test-nic_loopback/hash index 2bf71a0059..3ee2e5bb69 100644 --- a/repos/os/recipes/pkg/test-nic_loopback/hash +++ b/repos/os/recipes/pkg/test-nic_loopback/hash @@ -1 +1 @@ -2022-05-24 c95057700a0425018a4283233b36bd463eda1491 +2022-10-11 63b3c5d8b3b997daa201bb7de6066390d2201acc diff --git a/repos/os/recipes/pkg/test-nic_perf/README b/repos/os/recipes/pkg/test-nic_perf/README new file mode 100644 index 0000000000..eccd77488e --- /dev/null +++ b/repos/os/recipes/pkg/test-nic_perf/README @@ -0,0 +1 @@ +Throughput test of nic session. diff --git a/repos/os/recipes/pkg/test-nic_perf/archives b/repos/os/recipes/pkg/test-nic_perf/archives new file mode 100644 index 0000000000..af4ab8951c --- /dev/null +++ b/repos/os/recipes/pkg/test-nic_perf/archives @@ -0,0 +1,2 @@ +_/src/init +_/src/nic_perf diff --git a/repos/os/recipes/pkg/test-nic_perf/hash b/repos/os/recipes/pkg/test-nic_perf/hash new file mode 100644 index 0000000000..4c37b14e11 --- /dev/null +++ b/repos/os/recipes/pkg/test-nic_perf/hash @@ -0,0 +1 @@ +2022-10-11 01ed91fe6c3a721a021ef434dbc1e414e8773227 diff --git a/repos/os/recipes/pkg/test-nic_perf/runtime b/repos/os/recipes/pkg/test-nic_perf/runtime new file mode 100644 index 0000000000..f434095992 --- /dev/null +++ b/repos/os/recipes/pkg/test-nic_perf/runtime @@ -0,0 +1,62 @@ + + + + + + + + [init] child "nic_perf_tx" exited with exit value 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/repos/os/recipes/pkg/test-nic_perf_router/README b/repos/os/recipes/pkg/test-nic_perf_router/README new file mode 100644 index 0000000000..c43fcce423 --- /dev/null +++ b/repos/os/recipes/pkg/test-nic_perf_router/README @@ -0,0 +1 @@ +Throughput test of nic router. diff --git a/repos/os/recipes/pkg/test-nic_perf_router/archives b/repos/os/recipes/pkg/test-nic_perf_router/archives new file mode 100644 index 0000000000..6d22704a6a --- /dev/null +++ b/repos/os/recipes/pkg/test-nic_perf_router/archives @@ -0,0 +1,3 @@ +_/src/init +_/src/nic_router +_/src/nic_perf diff --git a/repos/os/recipes/pkg/test-nic_perf_router/hash b/repos/os/recipes/pkg/test-nic_perf_router/hash new file mode 100644 index 0000000000..2a25f6e711 --- /dev/null +++ b/repos/os/recipes/pkg/test-nic_perf_router/hash @@ -0,0 +1 @@ +2022-10-11 a0f6af0744a81671807c2b9f7522782ae59a01a0 diff --git a/repos/os/recipes/pkg/test-nic_perf_router/runtime b/repos/os/recipes/pkg/test-nic_perf_router/runtime new file mode 100644 index 0000000000..4246f3db87 --- /dev/null +++ b/repos/os/recipes/pkg/test-nic_perf_router/runtime @@ -0,0 +1,91 @@ + + + + + + + + [init] child "nic_perf_tx" exited with exit value 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/repos/os/recipes/pkg/test-part_block_gpt/hash b/repos/os/recipes/pkg/test-part_block_gpt/hash index 6bf06058d6..480f0530aa 100644 --- a/repos/os/recipes/pkg/test-part_block_gpt/hash +++ b/repos/os/recipes/pkg/test-part_block_gpt/hash @@ -1 +1 @@ -2022-05-24 b6ddaf84ca51a9d6a2c18656fddf41577b2a4690 +2022-10-11 1e5dc67eb6cdbc0037397efa622a1fe72eb691ca diff --git a/repos/os/recipes/pkg/test-part_block_mbr/hash b/repos/os/recipes/pkg/test-part_block_mbr/hash index 203d50af21..a5d4bdb24f 100644 --- a/repos/os/recipes/pkg/test-part_block_mbr/hash +++ b/repos/os/recipes/pkg/test-part_block_mbr/hash @@ -1 +1 @@ -2022-05-24 014b04b592796d1776438a163a2ca75710b0c8ea +2022-10-11 962e458c21acd09fa355afec4bcbd029f3dc11c9 diff --git a/repos/os/recipes/pkg/test-ram_fs_chunk/hash b/repos/os/recipes/pkg/test-ram_fs_chunk/hash index 120c75d633..b8fedf70d1 100644 --- a/repos/os/recipes/pkg/test-ram_fs_chunk/hash +++ b/repos/os/recipes/pkg/test-ram_fs_chunk/hash @@ -1 +1 @@ -2022-05-24 79a6c694ecd7ef6ab961d95af24fa0a3019b9027 +2022-10-11 308bc5b21a023ebcfc7a16e2181320e7bc699a50 diff --git a/repos/os/recipes/pkg/test-read_only_rom/hash b/repos/os/recipes/pkg/test-read_only_rom/hash index aadd399b43..5f9de76ab1 100644 --- a/repos/os/recipes/pkg/test-read_only_rom/hash +++ b/repos/os/recipes/pkg/test-read_only_rom/hash @@ -1 +1 @@ -2022-05-24 a20b60fb9ffe97bcad942cbfa5413c717900de16 +2022-10-11 4970a65f723c7079a5cfc086b4c2b28f8411f1c3 diff --git a/repos/os/recipes/pkg/test-report_rom/hash b/repos/os/recipes/pkg/test-report_rom/hash index c56797cf24..8c1d4a3bf1 100644 --- a/repos/os/recipes/pkg/test-report_rom/hash +++ b/repos/os/recipes/pkg/test-report_rom/hash @@ -1 +1 @@ -2022-05-24 9791af897f0354b0fd2639d810d59417b68743c4 +2022-10-11 ce26028800223f982f34847c5f52294fb6db47e5 diff --git a/repos/os/recipes/pkg/test-resource_request/hash b/repos/os/recipes/pkg/test-resource_request/hash index 695fe5c8ae..6cb309d8dc 100644 --- a/repos/os/recipes/pkg/test-resource_request/hash +++ b/repos/os/recipes/pkg/test-resource_request/hash @@ -1 +1 @@ -2022-05-24 28246c207857b21089bb34624b62e24473f5b4c1 +2022-10-11 1d6c747b6e1eeae1d9089a1a2f24b893d8ada861 diff --git a/repos/os/recipes/pkg/test-resource_yield/hash b/repos/os/recipes/pkg/test-resource_yield/hash index 27f00a4256..f98b25a115 100644 --- a/repos/os/recipes/pkg/test-resource_yield/hash +++ b/repos/os/recipes/pkg/test-resource_yield/hash @@ -1 +1 @@ -2022-05-24 ab05a2e15d6d2973fcca3eec237c2f341c9270fd +2022-10-11 44f5ebf6e58c908ce48cbe68be5abb4503230416 diff --git a/repos/os/recipes/pkg/test-rom_filter/hash b/repos/os/recipes/pkg/test-rom_filter/hash index 4954d031b7..556fd4117e 100644 --- a/repos/os/recipes/pkg/test-rom_filter/hash +++ b/repos/os/recipes/pkg/test-rom_filter/hash @@ -1 +1 @@ -2022-05-24 f9e76fb42835686d491afbaf984d573499c7eef1 +2022-10-11 9b242f1b2c0b79909b700ee0fb134367069c87ef diff --git a/repos/os/recipes/pkg/test-rtc/hash b/repos/os/recipes/pkg/test-rtc/hash index 8e5d8a4e9d..a7522fa972 100644 --- a/repos/os/recipes/pkg/test-rtc/hash +++ b/repos/os/recipes/pkg/test-rtc/hash @@ -1 +1 @@ -2022-05-24 0a0872f33f618edd68d9ce17daa9a077afc94432 +2022-10-11 ede3254208690f9c6e690c06fc2d9c6666c932ff diff --git a/repos/os/recipes/pkg/test-sandbox/hash b/repos/os/recipes/pkg/test-sandbox/hash index 5bb7dfcad0..f185fff94e 100644 --- a/repos/os/recipes/pkg/test-sandbox/hash +++ b/repos/os/recipes/pkg/test-sandbox/hash @@ -1 +1 @@ -2022-05-24 b5009e03d29225d899ccee373c7f79ce84f4d8ad +2022-10-11 d8f87310a02150b2b5c3860568e58786d2c52247 diff --git a/repos/os/recipes/pkg/test-signal/hash b/repos/os/recipes/pkg/test-signal/hash index 4c5b838ec0..9494585d24 100644 --- a/repos/os/recipes/pkg/test-signal/hash +++ b/repos/os/recipes/pkg/test-signal/hash @@ -1 +1 @@ -2022-05-24 aeecc85485f246a36929fd3f92a79d18cab9f085 +2022-10-11 d8ce46f7a8b617c64e17f4e9ea5d1016770b3bf9 diff --git a/repos/os/recipes/pkg/test-slab/hash b/repos/os/recipes/pkg/test-slab/hash index 21e323cda9..47d412434f 100644 --- a/repos/os/recipes/pkg/test-slab/hash +++ b/repos/os/recipes/pkg/test-slab/hash @@ -1 +1 @@ -2022-05-24 a9f05d4cf34d42d31f71fad5e665a2b4f05dddb9 +2022-10-11 344566c7a689431547b8bd4cc2d4ef71940705f0 diff --git a/repos/os/recipes/pkg/test-terminal_crosslink/hash b/repos/os/recipes/pkg/test-terminal_crosslink/hash index db2fb13388..6384190faf 100644 --- a/repos/os/recipes/pkg/test-terminal_crosslink/hash +++ b/repos/os/recipes/pkg/test-terminal_crosslink/hash @@ -1 +1 @@ -2022-05-24 68521fb82896fdce581ad7d849c1771ab52c1804 +2022-10-11 609e65676bab87357ab92e5c1482cebe059bae64 diff --git a/repos/os/recipes/pkg/test-trace/hash b/repos/os/recipes/pkg/test-trace/hash index ffa8e24cb1..251f6bc3d7 100644 --- a/repos/os/recipes/pkg/test-trace/hash +++ b/repos/os/recipes/pkg/test-trace/hash @@ -1 +1 @@ -2022-05-24 78b0460c5a8cc630fbe39826fe14fbec3b521381 +2022-10-11 611b6ec956723f9a14a3f00f0b66e0bd694daf7f diff --git a/repos/os/recipes/pkg/test-trace_buffer/hash b/repos/os/recipes/pkg/test-trace_buffer/hash index 1d7ab97059..9ac5f2fc2a 100644 --- a/repos/os/recipes/pkg/test-trace_buffer/hash +++ b/repos/os/recipes/pkg/test-trace_buffer/hash @@ -1 +1 @@ -2022-05-24 e8d817157d8e555628c607dd0a77e7437631fb48 +2022-10-11 2690a52fb045138d79d679f1affbf0f8c3a27483 diff --git a/repos/os/recipes/pkg/test-trace_logger/hash b/repos/os/recipes/pkg/test-trace_logger/hash index 20f13751d7..77676b38cb 100644 --- a/repos/os/recipes/pkg/test-trace_logger/hash +++ b/repos/os/recipes/pkg/test-trace_logger/hash @@ -1 +1 @@ -2022-05-24 6d2dfdc13344308a1ad57c47a8a2b94a980995e5 +2022-10-11 2a50bc8c841f305277855a924a532e5c6909884d diff --git a/repos/os/recipes/pkg/test-trace_logger/runtime b/repos/os/recipes/pkg/test-trace_logger/runtime index ef758a2171..60bf180d25 100644 --- a/repos/os/recipes/pkg/test-trace_logger/runtime +++ b/repos/os/recipes/pkg/test-trace_logger/runtime @@ -105,7 +105,7 @@ - + @@ -115,7 +115,7 @@ - + diff --git a/repos/os/recipes/pkg/test-utf8/hash b/repos/os/recipes/pkg/test-utf8/hash index 5f8aa9f5b6..56c81bbfb0 100644 --- a/repos/os/recipes/pkg/test-utf8/hash +++ b/repos/os/recipes/pkg/test-utf8/hash @@ -1 +1 @@ -2022-05-24 10db2219509eeaa60481714f12611a3f1985ca25 +2022-10-11 d73134d210d7ca255b5588ff65a998beba123907 diff --git a/repos/os/recipes/pkg/test-vfs_block/hash b/repos/os/recipes/pkg/test-vfs_block/hash index bd6afb8c0a..ff0185c08e 100644 --- a/repos/os/recipes/pkg/test-vfs_block/hash +++ b/repos/os/recipes/pkg/test-vfs_block/hash @@ -1 +1 @@ -2022-05-24 595b668d40048892bc0eb1136e460f224fc4c570 +2022-10-11 b840034b7ec21f269070b254cea5b0c16ed90b5e diff --git a/repos/os/recipes/pkg/test-vfs_stress_fs/hash b/repos/os/recipes/pkg/test-vfs_stress_fs/hash index 3ff6d32781..3302dcaa90 100644 --- a/repos/os/recipes/pkg/test-vfs_stress_fs/hash +++ b/repos/os/recipes/pkg/test-vfs_stress_fs/hash @@ -1 +1 @@ -2022-05-24 cf494b3d96992ad5463a302ab77c583e32f761ce +2022-10-11 1a58c208669889d6d80fd9d893d3d09b1d66fdb6 diff --git a/repos/os/recipes/pkg/test-vfs_stress_ram/hash b/repos/os/recipes/pkg/test-vfs_stress_ram/hash index 04efa13044..9b77a1573d 100644 --- a/repos/os/recipes/pkg/test-vfs_stress_ram/hash +++ b/repos/os/recipes/pkg/test-vfs_stress_ram/hash @@ -1 +1 @@ -2022-05-24 e7aa2ad8a16cbf1c2978657cc269b07a54727f66 +2022-10-11 5ffa8bb13e3b081074da7812d3dfa6da759deaf1 diff --git a/repos/os/recipes/pkg/test-weak_ptr/hash b/repos/os/recipes/pkg/test-weak_ptr/hash index 805d0db9dc..9224413431 100644 --- a/repos/os/recipes/pkg/test-weak_ptr/hash +++ b/repos/os/recipes/pkg/test-weak_ptr/hash @@ -1 +1 @@ -2022-05-24 2c8e16866758863b085ee1f4a2c198282a5117d1 +2022-10-11 78e9073cdfb713063e5705c11a09faec76eb47c6 diff --git a/repos/os/recipes/pkg/trace_logger/hash b/repos/os/recipes/pkg/trace_logger/hash index 3535837b17..7326c8967a 100644 --- a/repos/os/recipes/pkg/trace_logger/hash +++ b/repos/os/recipes/pkg/trace_logger/hash @@ -1 +1 @@ -2022-05-24 b8b01abf80b985f3e929314aee5825a7136ee048 +2022-10-11 5c3376142d6635290b939319d65dbfaa55001c94 diff --git a/repos/os/recipes/pkg/vfs/hash b/repos/os/recipes/pkg/vfs/hash index fba7c12684..fa5cf31d83 100644 --- a/repos/os/recipes/pkg/vfs/hash +++ b/repos/os/recipes/pkg/vfs/hash @@ -1 +1 @@ -2022-05-24 4376719c575cecddf6b96662edf7b4d88939f767 +2022-10-11 32c161dc634a1d5a2e3c5774fba0f4133857bcad diff --git a/repos/os/recipes/pkg/vfs_block/hash b/repos/os/recipes/pkg/vfs_block/hash index 31062b6d70..6a47b0938e 100644 --- a/repos/os/recipes/pkg/vfs_block/hash +++ b/repos/os/recipes/pkg/vfs_block/hash @@ -1 +1 @@ -2022-05-24 41b1b36e4d6752cf56fd20dde36338321c7b53a2 +2022-10-11 7cab6890a30250d4e29cb239438dc53e6ad0da91 diff --git a/repos/os/recipes/raw/drivers_interactive-pc/drivers.config b/repos/os/recipes/raw/drivers_interactive-pc/drivers.config index 7edf0fac53..6e8093a435 100644 --- a/repos/os/recipes/raw/drivers_interactive-pc/drivers.config +++ b/repos/os/recipes/raw/drivers_interactive-pc/drivers.config @@ -36,7 +36,8 @@ - + + @@ -47,16 +48,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + @@ -67,11 +100,10 @@ - - - - - + + + + @@ -127,7 +159,7 @@ - + diff --git a/repos/os/recipes/raw/drivers_interactive-pc/hash b/repos/os/recipes/raw/drivers_interactive-pc/hash index ec5093a683..21c7677dfe 100644 --- a/repos/os/recipes/raw/drivers_interactive-pc/hash +++ b/repos/os/recipes/raw/drivers_interactive-pc/hash @@ -1 +1 @@ -2022-02-27 729c011725259a37fb289161f72e00640f535da9 +2022-10-11 551db516e914069b3d83b7649170c5b2bb2e5f43 diff --git a/repos/os/recipes/raw/drivers_interactive-virt_qemu/content.mk b/repos/os/recipes/raw/drivers_interactive-virt_qemu_arm/content.mk similarity index 73% rename from repos/os/recipes/raw/drivers_interactive-virt_qemu/content.mk rename to repos/os/recipes/raw/drivers_interactive-virt_qemu_arm/content.mk index 54b94f2896..c954b65ba9 100644 --- a/repos/os/recipes/raw/drivers_interactive-virt_qemu/content.mk +++ b/repos/os/recipes/raw/drivers_interactive-virt_qemu_arm/content.mk @@ -1,7 +1,7 @@ content: drivers.config event_filter.config en_us.chargen special.chargen drivers.config event_filter.config: - cp $(REP_DIR)/recipes/raw/drivers_interactive-virt_qemu/$@ $@ + cp $(REP_DIR)/recipes/raw/drivers_interactive-virt_qemu_arm/$@ $@ en_us.chargen special.chargen: cp $(REP_DIR)/src/server/event_filter/$@ $@ diff --git a/repos/os/recipes/raw/drivers_interactive-virt_qemu/drivers.config b/repos/os/recipes/raw/drivers_interactive-virt_qemu_arm/drivers.config similarity index 100% rename from repos/os/recipes/raw/drivers_interactive-virt_qemu/drivers.config rename to repos/os/recipes/raw/drivers_interactive-virt_qemu_arm/drivers.config diff --git a/repos/os/recipes/raw/drivers_interactive-virt_qemu/event_filter.config b/repos/os/recipes/raw/drivers_interactive-virt_qemu_arm/event_filter.config similarity index 100% rename from repos/os/recipes/raw/drivers_interactive-virt_qemu/event_filter.config rename to repos/os/recipes/raw/drivers_interactive-virt_qemu_arm/event_filter.config diff --git a/repos/os/recipes/raw/drivers_interactive-virt_qemu/hash b/repos/os/recipes/raw/drivers_interactive-virt_qemu_arm/hash similarity index 100% rename from repos/os/recipes/raw/drivers_interactive-virt_qemu/hash rename to repos/os/recipes/raw/drivers_interactive-virt_qemu_arm/hash diff --git a/repos/os/recipes/raw/drivers_nic-virt_qemu/content.mk b/repos/os/recipes/raw/drivers_nic-virt_qemu/content.mk deleted file mode 100644 index 78a408f9d6..0000000000 --- a/repos/os/recipes/raw/drivers_nic-virt_qemu/content.mk +++ /dev/null @@ -1,4 +0,0 @@ -content: drivers.config - -drivers.config: - cp $(REP_DIR)/recipes/raw/drivers_nic-virt_qemu/$@ $@ diff --git a/repos/os/recipes/raw/drivers_nic-virt_qemu_arm/content.mk b/repos/os/recipes/raw/drivers_nic-virt_qemu_arm/content.mk new file mode 100644 index 0000000000..0dca8b503e --- /dev/null +++ b/repos/os/recipes/raw/drivers_nic-virt_qemu_arm/content.mk @@ -0,0 +1,4 @@ +content: drivers.config + +drivers.config: + cp $(REP_DIR)/recipes/raw/drivers_nic-virt_qemu_arm/$@ $@ diff --git a/repos/os/recipes/raw/drivers_nic-virt_qemu/drivers.config b/repos/os/recipes/raw/drivers_nic-virt_qemu_arm/drivers.config similarity index 100% rename from repos/os/recipes/raw/drivers_nic-virt_qemu/drivers.config rename to repos/os/recipes/raw/drivers_nic-virt_qemu_arm/drivers.config diff --git a/repos/os/recipes/raw/drivers_nic-virt_qemu/hash b/repos/os/recipes/raw/drivers_nic-virt_qemu_arm/hash similarity index 100% rename from repos/os/recipes/raw/drivers_nic-virt_qemu/hash rename to repos/os/recipes/raw/drivers_nic-virt_qemu_arm/hash diff --git a/repos/os/recipes/src/acpi_drv/hash b/repos/os/recipes/src/acpi_drv/hash index dd478d02bd..6cd67b959d 100644 --- a/repos/os/recipes/src/acpi_drv/hash +++ b/repos/os/recipes/src/acpi_drv/hash @@ -1 +1 @@ -2022-05-24 2fbd7825132b34cd0c92951b8f89f504ad1a3a7f +2022-10-11 9805a7846e9ffc77a58bf0a66efd1ad37095df9e diff --git a/repos/os/recipes/src/ahci_drv/hash b/repos/os/recipes/src/ahci_drv/hash index ea5c1f430f..5a7216cf55 100644 --- a/repos/os/recipes/src/ahci_drv/hash +++ b/repos/os/recipes/src/ahci_drv/hash @@ -1 +1 @@ -2022-05-24 8d14d1bb16d8e6e79518981293ee29efa5076640 +2022-10-11 1cda0ef83ca9fa0dd99b085e0c79ab87166a7889 diff --git a/repos/os/recipes/src/black_hole/hash b/repos/os/recipes/src/black_hole/hash index 007cdea8e0..20a32b9961 100644 --- a/repos/os/recipes/src/black_hole/hash +++ b/repos/os/recipes/src/black_hole/hash @@ -1 +1 @@ -2022-05-24 5ac9b906376475807bffa72389a4fe88bdd30e1a +2022-10-11 1166063113ed0e24c8c6bec6827ee102240210f3 diff --git a/repos/os/recipes/src/block_tester/hash b/repos/os/recipes/src/block_tester/hash index 0f543c40e7..f7936d4f8e 100644 --- a/repos/os/recipes/src/block_tester/hash +++ b/repos/os/recipes/src/block_tester/hash @@ -1 +1 @@ -2022-05-24 449da55c27dfcaff22fdfaefd79de64934932045 +2022-10-11 3cd9023c61da5f2ae3f0d9bee913c3e37f65cb93 diff --git a/repos/os/recipes/src/boot_fb_drv/hash b/repos/os/recipes/src/boot_fb_drv/hash index 6757ebbb66..8e2b631d11 100644 --- a/repos/os/recipes/src/boot_fb_drv/hash +++ b/repos/os/recipes/src/boot_fb_drv/hash @@ -1 +1 @@ -2022-05-24 9749eea404d824a29d282aef353f9fdc6b35f610 +2022-10-11 1c4e66b4681e6efb5779f07a9c88cfe76a975fee diff --git a/repos/os/recipes/src/cached_fs_rom/hash b/repos/os/recipes/src/cached_fs_rom/hash index fec09b6061..514322fe84 100644 --- a/repos/os/recipes/src/cached_fs_rom/hash +++ b/repos/os/recipes/src/cached_fs_rom/hash @@ -1 +1 @@ -2022-05-24 d0cac4e722d774633f75c69df36295bd05ef6bbb +2022-10-11 3185b0a5480f2939a4f2493f9e1d3aaa4f8044fb diff --git a/repos/os/recipes/src/chroot/hash b/repos/os/recipes/src/chroot/hash index 8c04d2670a..5f2fc5a708 100644 --- a/repos/os/recipes/src/chroot/hash +++ b/repos/os/recipes/src/chroot/hash @@ -1 +1 @@ -2022-05-24 fa7550335c68e22c6a28fa4b542607399c312ce6 +2022-10-11 c1a23e3e04f71c1cb617260f306781cbcc7bbeac diff --git a/repos/os/recipes/src/clipboard/hash b/repos/os/recipes/src/clipboard/hash index 6741c4a7be..a156735127 100644 --- a/repos/os/recipes/src/clipboard/hash +++ b/repos/os/recipes/src/clipboard/hash @@ -1 +1 @@ -2022-05-24 6070043d80c7e58d9bcca8136c9f023794afffc4 +2022-10-11 cebcb310ae5674cac9a096bbba9f1688315ab9f2 diff --git a/repos/os/recipes/src/cpu_balancer/hash b/repos/os/recipes/src/cpu_balancer/hash index a2eba3cdf5..88222d6630 100644 --- a/repos/os/recipes/src/cpu_balancer/hash +++ b/repos/os/recipes/src/cpu_balancer/hash @@ -1 +1 @@ -2022-05-24 4996e66510f4c45f8446e1380267811c49c97b71 +2022-10-11 40e6f50ed41ff3b4aaf2a97ccd9bdcda205a4426 diff --git a/repos/os/recipes/src/cpu_burner/hash b/repos/os/recipes/src/cpu_burner/hash index e0fd5f6ff5..da5b30404a 100644 --- a/repos/os/recipes/src/cpu_burner/hash +++ b/repos/os/recipes/src/cpu_burner/hash @@ -1 +1 @@ -2022-05-24 3dc056efacfa12cea3196b43556e42d6263addf6 +2022-10-11 a9c8e0a23366e43bc54d7dca8cd54bf6cf738f77 diff --git a/repos/os/recipes/src/dummy/hash b/repos/os/recipes/src/dummy/hash index 1850138ed6..66dde21aea 100644 --- a/repos/os/recipes/src/dummy/hash +++ b/repos/os/recipes/src/dummy/hash @@ -1 +1 @@ -2022-05-24 fb79764f11e84a786bbb6d1ca5a538106b10f9b4 +2022-10-11 71455f41edc47cdb10f6dc0757c7574c9e3683fa diff --git a/repos/os/recipes/src/dummy_rtc_drv/hash b/repos/os/recipes/src/dummy_rtc_drv/hash index 0112ec6895..64ce01b3fe 100644 --- a/repos/os/recipes/src/dummy_rtc_drv/hash +++ b/repos/os/recipes/src/dummy_rtc_drv/hash @@ -1 +1 @@ -2022-05-24 5ecbf8f6a210344c9a49d4ad64c12921d80e8627 +2022-10-11 73b82e3423e8b7edf41057dabd171ece07d492e3 diff --git a/repos/os/recipes/src/dynamic_rom/hash b/repos/os/recipes/src/dynamic_rom/hash index dee56cea23..2aeb34d298 100644 --- a/repos/os/recipes/src/dynamic_rom/hash +++ b/repos/os/recipes/src/dynamic_rom/hash @@ -1 +1 @@ -2022-05-24 b6f11fe18b09b4bf8058d83f9b2076542d0b6bcb +2022-10-11 b6004adc3e1fe3ebdce593dad14801c4e22c0694 diff --git a/repos/os/recipes/src/event_filter/hash b/repos/os/recipes/src/event_filter/hash index 67cab4aae3..1753fed14a 100644 --- a/repos/os/recipes/src/event_filter/hash +++ b/repos/os/recipes/src/event_filter/hash @@ -1 +1 @@ -2022-05-24 4fe82cc55cccde30453dd6366e44fe5242892e1b +2022-10-11 b1761ae7399d467577f794d24deca5399b7915a1 diff --git a/repos/os/recipes/src/fb_sdl/hash b/repos/os/recipes/src/fb_sdl/hash index babad839fa..1fd12104b9 100644 --- a/repos/os/recipes/src/fb_sdl/hash +++ b/repos/os/recipes/src/fb_sdl/hash @@ -1 +1 @@ -2022-05-24 8dde2409fff2c91af7e1897437ef9ffe4a6b5f6d +2022-10-11 21da60c780a4cec8c2066d13fbc2685eb4b3a866 diff --git a/repos/os/recipes/src/fs_report/hash b/repos/os/recipes/src/fs_report/hash index fafe84f4ff..10c4999885 100644 --- a/repos/os/recipes/src/fs_report/hash +++ b/repos/os/recipes/src/fs_report/hash @@ -1 +1 @@ -2022-05-24 fde35eea9d1d92eb665bff3ebdc6dc9ae3ad2efb +2022-10-11 82beab5b9f03b106b9df24e8ebda58520e64ae58 diff --git a/repos/os/recipes/src/fs_rom/hash b/repos/os/recipes/src/fs_rom/hash index 90e8629c51..1bc319652d 100644 --- a/repos/os/recipes/src/fs_rom/hash +++ b/repos/os/recipes/src/fs_rom/hash @@ -1 +1 @@ -2022-05-24 138b33df108154edec48dd20206d0c8c5e9d1f78 +2022-10-11 9358d50551dabbf2eb0c2c7c32f11204f7cfc024 diff --git a/repos/os/recipes/src/global_keys_handler/hash b/repos/os/recipes/src/global_keys_handler/hash index 22f614b145..5b724175db 100644 --- a/repos/os/recipes/src/global_keys_handler/hash +++ b/repos/os/recipes/src/global_keys_handler/hash @@ -1 +1 @@ -2022-05-24 7c83e4167e1228ae7cdf2c4e0624231d1a68ad0d +2022-10-11 368fa1b3dddff106c67458cb68ab7ab552aa0618 diff --git a/repos/os/recipes/src/gui_fb/hash b/repos/os/recipes/src/gui_fb/hash index 02d2721e9f..c01a8db0f3 100644 --- a/repos/os/recipes/src/gui_fb/hash +++ b/repos/os/recipes/src/gui_fb/hash @@ -1 +1 @@ -2022-05-24 6bef2a93ea1331aeaf3551bf296234d5d67515f4 +2022-10-11 ac109767621e92a3794d715e4ca10cf6231f92ce diff --git a/repos/os/recipes/src/init/hash b/repos/os/recipes/src/init/hash index 22694b215f..7c42efbe67 100644 --- a/repos/os/recipes/src/init/hash +++ b/repos/os/recipes/src/init/hash @@ -1 +1 @@ -2022-05-24 3d8a9cd468876e1ef2098e9081e65f2a2873fc3d +2022-10-11 605688d1c4ecc12497b9a60538ff07fbfb904fc6 diff --git a/repos/os/recipes/src/input_event_bridge/hash b/repos/os/recipes/src/input_event_bridge/hash index c8cc107c91..f70a39c7bd 100644 --- a/repos/os/recipes/src/input_event_bridge/hash +++ b/repos/os/recipes/src/input_event_bridge/hash @@ -1 +1 @@ -2022-05-24 cfaff88dd24b11f5d9087c16149d2dec7f68f5bd +2022-10-11 c702cb6d81359af2ec072e77957224b9aa007c24 diff --git a/repos/os/recipes/src/intel_gpu_drv/hash b/repos/os/recipes/src/intel_gpu_drv/hash index 3b613376fd..b7f3ddf053 100644 --- a/repos/os/recipes/src/intel_gpu_drv/hash +++ b/repos/os/recipes/src/intel_gpu_drv/hash @@ -1 +1 @@ -2022-05-24 dad94e082e6a814b29cded8c09e729f30e2c3870 +2022-10-11 0dc53728a22cf380185a81bfc11881cebf1b7430 diff --git a/repos/os/recipes/src/lan9118_nic_drv/hash b/repos/os/recipes/src/lan9118_nic_drv/hash index ba6d60e7ad..2f6ba73523 100644 --- a/repos/os/recipes/src/lan9118_nic_drv/hash +++ b/repos/os/recipes/src/lan9118_nic_drv/hash @@ -1 +1 @@ -2022-05-24 e20d2bdc468c557aaee04a11850a681abc25e8e3 +2022-10-11 cf22a7cb41f15854a45c6a80ce068e13644c7133 diff --git a/repos/os/recipes/src/linux_nic_drv/hash b/repos/os/recipes/src/linux_nic_drv/hash index 26e2940729..50491f70fa 100644 --- a/repos/os/recipes/src/linux_nic_drv/hash +++ b/repos/os/recipes/src/linux_nic_drv/hash @@ -1 +1 @@ -2022-05-24 deb834207a8c64d9e60de13781dc1b4f68f286dc +2022-10-11 660b73eccbf6ca293d6b2f3162030eb3db84dc4a diff --git a/repos/os/recipes/src/linux_rtc_drv/hash b/repos/os/recipes/src/linux_rtc_drv/hash index 56e6dc6621..463cfaec12 100644 --- a/repos/os/recipes/src/linux_rtc_drv/hash +++ b/repos/os/recipes/src/linux_rtc_drv/hash @@ -1 +1 @@ -2022-05-24 21f662a4e7934c5c2d4efb05ea3118b3bea8b307 +2022-10-11 33ce5984090693c657e2561a73f25a0cc72b5432 diff --git a/repos/os/recipes/src/loader/hash b/repos/os/recipes/src/loader/hash index a2619c166f..bbe45b1ed6 100644 --- a/repos/os/recipes/src/loader/hash +++ b/repos/os/recipes/src/loader/hash @@ -1 +1 @@ -2022-05-24 351722701f3942554b0732a38478e76848ed0b38 +2022-10-11 a2daddeddff06de347a5cb6ef182f3a83d406245 diff --git a/repos/os/recipes/src/log_core/hash b/repos/os/recipes/src/log_core/hash index b272ab339d..6a8ed5774b 100644 --- a/repos/os/recipes/src/log_core/hash +++ b/repos/os/recipes/src/log_core/hash @@ -1 +1 @@ -2022-05-24 2e7a30562de2cb4d0eb8fac62a622d1e4b3b8459 +2022-10-11 cb9e12dfc72a03387476f61ed8c840673e750900 diff --git a/repos/os/recipes/src/log_terminal/hash b/repos/os/recipes/src/log_terminal/hash index 4e8f483c39..a986d7b9c1 100644 --- a/repos/os/recipes/src/log_terminal/hash +++ b/repos/os/recipes/src/log_terminal/hash @@ -1 +1 @@ -2022-05-24 fc6fd01c9060610e0aa5bec3b733ba004cd0b3a6 +2022-10-11 aa500b712f0b435cb8f42f825c407cb26d65ac0d diff --git a/repos/os/recipes/src/lx_block/hash b/repos/os/recipes/src/lx_block/hash index 9083985261..d798f6054c 100644 --- a/repos/os/recipes/src/lx_block/hash +++ b/repos/os/recipes/src/lx_block/hash @@ -1 +1 @@ -2022-05-24 0c1b84a462eed33773eeb248460642940871d694 +2022-10-11 7791c681a8b2af7b687145f0cf9203f26b54ed70 diff --git a/repos/os/recipes/src/lx_fs/hash b/repos/os/recipes/src/lx_fs/hash index 777418fc50..3817301587 100644 --- a/repos/os/recipes/src/lx_fs/hash +++ b/repos/os/recipes/src/lx_fs/hash @@ -1 +1 @@ -2022-05-24 214aabdee3bfabd37b9e393890412dcfa0781ec3 +2022-10-11 2849a6b5e48bf31f188ae7191e08d9515efc8073 diff --git a/repos/os/recipes/src/mixer/hash b/repos/os/recipes/src/mixer/hash index d179109a4d..233702b04f 100644 --- a/repos/os/recipes/src/mixer/hash +++ b/repos/os/recipes/src/mixer/hash @@ -1 +1 @@ -2022-05-24 e460af414b356460715c0641e0b719c3c5240527 +2022-10-11 c189e802f0b23452b5c952d49f518bc9e0e7637b diff --git a/repos/os/recipes/src/nic_bridge/hash b/repos/os/recipes/src/nic_bridge/hash index a72750bb7d..8fdc6e89bb 100644 --- a/repos/os/recipes/src/nic_bridge/hash +++ b/repos/os/recipes/src/nic_bridge/hash @@ -1 +1 @@ -2022-05-24 50e90b99f54a58dbde10886e3fde577112a4ff8c +2022-10-11 9e0177577eb19bef0558332d742259d710ea066b diff --git a/repos/os/recipes/src/nic_loopback/hash b/repos/os/recipes/src/nic_loopback/hash index 23ce8fa9b1..6a0013db6f 100644 --- a/repos/os/recipes/src/nic_loopback/hash +++ b/repos/os/recipes/src/nic_loopback/hash @@ -1 +1 @@ -2022-05-24 207af558d3f1a58c57e5a893ee223d77bbb5a281 +2022-10-11 257044c9db6cd651c714a79bb29072f34c764d33 diff --git a/repos/os/recipes/src/nic_perf/content.mk b/repos/os/recipes/src/nic_perf/content.mk new file mode 100644 index 0000000000..b5ad31b0d5 --- /dev/null +++ b/repos/os/recipes/src/nic_perf/content.mk @@ -0,0 +1,2 @@ +SRC_DIR = src/server/nic_perf +include $(GENODE_DIR)/repos/base/recipes/src/content.inc diff --git a/repos/os/recipes/src/nic_perf/hash b/repos/os/recipes/src/nic_perf/hash new file mode 100644 index 0000000000..6527662bd8 --- /dev/null +++ b/repos/os/recipes/src/nic_perf/hash @@ -0,0 +1 @@ +2022-10-11 757ee083a110c637ae6b82058b73d0f3bc7ac245 diff --git a/repos/os/recipes/src/nic_perf/used_apis b/repos/os/recipes/src/nic_perf/used_apis new file mode 100644 index 0000000000..e1fe665c5d --- /dev/null +++ b/repos/os/recipes/src/nic_perf/used_apis @@ -0,0 +1,6 @@ +base +os +net +nic_session +uplink_session +timer_session diff --git a/repos/os/recipes/src/nic_router/hash b/repos/os/recipes/src/nic_router/hash index e59e8b1173..154b25631d 100644 --- a/repos/os/recipes/src/nic_router/hash +++ b/repos/os/recipes/src/nic_router/hash @@ -1 +1 @@ -2022-05-24 62b001db529654caa8b5e203e443cb3d18ab5e58 +2022-10-13 3fb16b7db3e03ca4ab82ff9f6672eeb455f8c3f1 diff --git a/repos/os/recipes/src/nit_focus/hash b/repos/os/recipes/src/nit_focus/hash index eda9d6e390..d18421241b 100644 --- a/repos/os/recipes/src/nit_focus/hash +++ b/repos/os/recipes/src/nit_focus/hash @@ -1 +1 @@ -2022-05-24 5e63d56ea68219aee1fb5f8b9f99d6027247bad8 +2022-10-11 b0579dd9fae4ad62119a4800ba93c6f20928ea3e diff --git a/repos/os/recipes/src/nitpicker/hash b/repos/os/recipes/src/nitpicker/hash index e3a540a768..a5ae468ad0 100644 --- a/repos/os/recipes/src/nitpicker/hash +++ b/repos/os/recipes/src/nitpicker/hash @@ -1 +1 @@ -2022-05-24 b1ac3b7e7696ba65d4fcb0b8ec8043222c22663c +2022-10-11 8f6b75a88d34b0ff2c14510900224e5a30574edb diff --git a/repos/os/recipes/src/nvme_drv/hash b/repos/os/recipes/src/nvme_drv/hash index 571d82abdc..6e482c0dda 100644 --- a/repos/os/recipes/src/nvme_drv/hash +++ b/repos/os/recipes/src/nvme_drv/hash @@ -1 +1 @@ -2022-05-24 5602426d581e9b056eb465459b142d7b98ff41a8 +2022-10-11 1745aaed73094365ab6ec8f804d20293c3ec1856 diff --git a/repos/os/recipes/src/part_block/hash b/repos/os/recipes/src/part_block/hash index 021a6bf3be..b3976d103b 100644 --- a/repos/os/recipes/src/part_block/hash +++ b/repos/os/recipes/src/part_block/hash @@ -1 +1 @@ -2022-05-24 3804e994e70487ec972e8a206b18dfd40505b204 +2022-10-11 43dc37fb7b2a4de45d318e58cadcdf9108353f94 diff --git a/repos/os/recipes/src/pbxa9_drivers/hash b/repos/os/recipes/src/pbxa9_drivers/hash index aae6f8ed0a..dc77a5e995 100644 --- a/repos/os/recipes/src/pbxa9_drivers/hash +++ b/repos/os/recipes/src/pbxa9_drivers/hash @@ -1 +1 @@ -2022-05-24 dd886745a030e2c9b124e99884da1cd860fcc947 +2022-10-11 4de1f028c228a3baf2644c69344b6127042aa2b1 diff --git a/repos/os/recipes/src/pci_decode/content.mk b/repos/os/recipes/src/pci_decode/content.mk new file mode 100644 index 0000000000..8cc6ae3d61 --- /dev/null +++ b/repos/os/recipes/src/pci_decode/content.mk @@ -0,0 +1,2 @@ +SRC_DIR = src/app/pci_decode +include $(GENODE_DIR)/repos/base/recipes/src/content.inc diff --git a/repos/os/recipes/src/pci_decode/hash b/repos/os/recipes/src/pci_decode/hash new file mode 100644 index 0000000000..8765ce7029 --- /dev/null +++ b/repos/os/recipes/src/pci_decode/hash @@ -0,0 +1 @@ +2022-10-11 c5a093ad45d20f407fdc58bc129003216e9ea890 diff --git a/repos/os/recipes/src/pci_decode/used_apis b/repos/os/recipes/src/pci_decode/used_apis new file mode 100644 index 0000000000..69a94c6d26 --- /dev/null +++ b/repos/os/recipes/src/pci_decode/used_apis @@ -0,0 +1,3 @@ +base +os +report_session diff --git a/repos/os/recipes/src/platform_drv/content.inc b/repos/os/recipes/src/platform_drv/content.inc index bce4ea0042..23684efa08 100644 --- a/repos/os/recipes/src/platform_drv/content.inc +++ b/repos/os/recipes/src/platform_drv/content.inc @@ -1,13 +1,10 @@ include $(GENODE_DIR)/repos/base/recipes/src/content.inc GENERIC_SRC_DIR := $(GENODE_DIR)/repos/os/src/drivers/platform -GENERIC_INC_DIR := $(GENODE_DIR)/repos/os/include/pci GENERIC_SRC_FILES := $(filter-out target.mk,$(filter-out main.cc,$(notdir $(wildcard $(GENERIC_SRC_DIR)/*.*)))) -GENERIC_HDR_FILES := $(notdir $(wildcard $(GENERIC_INC_DIR)/*.h)) -MIRROR_FROM_OS_DIR := $(addprefix src/drivers/platform/,$(GENERIC_SRC_FILES)) \ - $(addprefix include/pci/,$(GENERIC_HDR_FILES)) +MIRROR_FROM_OS_DIR := $(addprefix src/drivers/platform/,$(GENERIC_SRC_FILES)) content: $(MIRROR_FROM_OS_DIR) diff --git a/repos/os/recipes/src/platform_drv/hash b/repos/os/recipes/src/platform_drv/hash index 93f96a0d04..adf10f1c19 100644 --- a/repos/os/recipes/src/platform_drv/hash +++ b/repos/os/recipes/src/platform_drv/hash @@ -1 +1 @@ -2022-05-24 d3274a7b7c60a3182b05184aed017de1399d40cc +2022-10-11 66e7c8c6b35a2b4dcd1d881568992bd8400983d8 diff --git a/repos/os/recipes/src/ps2_drv/hash b/repos/os/recipes/src/ps2_drv/hash index f54dbfc845..e93a642d76 100644 --- a/repos/os/recipes/src/ps2_drv/hash +++ b/repos/os/recipes/src/ps2_drv/hash @@ -1 +1 @@ -2022-05-24 40d9226b4bcb895f83b6b8263b980ca8b2f77430 +2022-10-11 c3ab14b58d2cfd217c360e36f9af4432b979bb7f diff --git a/repos/os/recipes/src/report_rom/hash b/repos/os/recipes/src/report_rom/hash index 5fcd080997..3e97941fd3 100644 --- a/repos/os/recipes/src/report_rom/hash +++ b/repos/os/recipes/src/report_rom/hash @@ -1 +1 @@ -2022-05-24 81b7701e7428734eb8f935d08488d235ed027e89 +2022-10-11 831a60dc7eef884a4edbb6226b3d5d6a23195e3c diff --git a/repos/os/recipes/src/rom_filter/hash b/repos/os/recipes/src/rom_filter/hash index 094dd48b1e..20b25f7c9c 100644 --- a/repos/os/recipes/src/rom_filter/hash +++ b/repos/os/recipes/src/rom_filter/hash @@ -1 +1 @@ -2022-05-24 a3393f87e0ce7cbf7c5059ee5193b8bafec5e174 +2022-10-11 4127584c22b8b59577a32fe71cab3f6e9435eba2 diff --git a/repos/os/recipes/src/rom_logger/hash b/repos/os/recipes/src/rom_logger/hash index f602b66325..7b23fa9990 100644 --- a/repos/os/recipes/src/rom_logger/hash +++ b/repos/os/recipes/src/rom_logger/hash @@ -1 +1 @@ -2022-05-24 5e7d668f08e277a38552796a35ed2162b9f7b921 +2022-10-11 b207357854c335b2c1081be7c583f04930c539ef diff --git a/repos/os/recipes/src/rom_reporter/hash b/repos/os/recipes/src/rom_reporter/hash index 201de72295..043de8c1e9 100644 --- a/repos/os/recipes/src/rom_reporter/hash +++ b/repos/os/recipes/src/rom_reporter/hash @@ -1 +1 @@ -2022-05-24 5539a3ad6197c7ea21a982de84ea01c9c5a0d3eb +2022-10-11 1c57ce6783fcafc2a8c708e7835c351e158ec055 diff --git a/repos/os/recipes/src/rom_to_file/hash b/repos/os/recipes/src/rom_to_file/hash index 70e2c1471c..6183f726b1 100644 --- a/repos/os/recipes/src/rom_to_file/hash +++ b/repos/os/recipes/src/rom_to_file/hash @@ -1 +1 @@ -2022-05-24 ffff68edf6f86d26b8897f7356f58cd91f86e1bb +2022-10-11 0f1d82e4fc126d38db9e2996b109506e5ccb72ba diff --git a/repos/os/recipes/src/rtc_drv/hash b/repos/os/recipes/src/rtc_drv/hash index 3e190d6d45..aba42aee83 100644 --- a/repos/os/recipes/src/rtc_drv/hash +++ b/repos/os/recipes/src/rtc_drv/hash @@ -1 +1 @@ -2022-05-24 efd3414279424ba9af6316da0d14eaa16c334f8a +2022-10-11 0e17ab580579fbac952fd3355931cff6e63d930a diff --git a/repos/os/recipes/src/sandbox/content.mk b/repos/os/recipes/src/sandbox/content.mk index 0bfc4af807..956e67fc9f 100644 --- a/repos/os/recipes/src/sandbox/content.mk +++ b/repos/os/recipes/src/sandbox/content.mk @@ -6,8 +6,3 @@ content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) - -content: src/lib/sandbox/target.mk - -src/lib/sandbox/target.mk: - echo "LIBS += sandbox" > $@ diff --git a/repos/os/recipes/src/sandbox/hash b/repos/os/recipes/src/sandbox/hash index 65bf7d7c86..498d0a3710 100644 --- a/repos/os/recipes/src/sandbox/hash +++ b/repos/os/recipes/src/sandbox/hash @@ -1 +1 @@ -2022-05-24 1313a7700762c9ef497c1fc15e747ba698549f8f +2022-10-11 8b913decfc5235d73021901c19b5f5ed4c5f8050 diff --git a/repos/os/recipes/src/sequence/hash b/repos/os/recipes/src/sequence/hash index 4ad5eb289c..5673e1ac47 100644 --- a/repos/os/recipes/src/sequence/hash +++ b/repos/os/recipes/src/sequence/hash @@ -1 +1 @@ -2022-05-24 419347e013764f8c6db1aba7e73b228ed51a872b +2022-10-11 7e245128c005cbde72463a0f8d9fd255e9ad7bef diff --git a/repos/os/recipes/src/shim/hash b/repos/os/recipes/src/shim/hash index a572197b34..7f7348d333 100644 --- a/repos/os/recipes/src/shim/hash +++ b/repos/os/recipes/src/shim/hash @@ -1 +1 @@ -2022-05-24 e3f0c80569c95f2ff75137dd13544fbce9b00aed +2022-10-11 c19f6134a15baf12d7c14f77ee8204a19bd1d2af diff --git a/repos/os/recipes/src/terminal_crosslink/hash b/repos/os/recipes/src/terminal_crosslink/hash index 1507cae9bb..4d44344be6 100644 --- a/repos/os/recipes/src/terminal_crosslink/hash +++ b/repos/os/recipes/src/terminal_crosslink/hash @@ -1 +1 @@ -2022-05-24 24cb2ee2919015194fa27e332beb2adbb1e321ba +2022-10-11 02d81f1159bbcc9478d7ed1c075c59a7a0ed53db diff --git a/repos/os/recipes/src/terminal_log/hash b/repos/os/recipes/src/terminal_log/hash index f07986d3f1..d82c2a5710 100644 --- a/repos/os/recipes/src/terminal_log/hash +++ b/repos/os/recipes/src/terminal_log/hash @@ -1 +1 @@ -2022-05-24 ecb26455d4aa28beca935d488490ce3af18a3c8c +2022-10-11 c440470a248b9ba3f3d311661925d66f7b2a10c7 diff --git a/repos/os/recipes/src/test-black_hole/hash b/repos/os/recipes/src/test-black_hole/hash index c3b6857810..f2b4e5f8c9 100644 --- a/repos/os/recipes/src/test-black_hole/hash +++ b/repos/os/recipes/src/test-black_hole/hash @@ -1 +1 @@ -2022-05-24 c7d6153af7c4b5c3455927b40e1f0d7058f3fc97 +2022-10-11 7c24f7278c21d5940555daf55d015686a11ad967 diff --git a/repos/os/recipes/src/test-bomb/hash b/repos/os/recipes/src/test-bomb/hash index 8aecf40367..575d7c67d3 100644 --- a/repos/os/recipes/src/test-bomb/hash +++ b/repos/os/recipes/src/test-bomb/hash @@ -1 +1 @@ -2022-05-24 7cfbf701e399ce6b2347cf1bc7d9fd324196698e +2022-10-11 e00c030976f304ea2a549a7173293061ac7d8e5b diff --git a/repos/os/recipes/src/test-capture/hash b/repos/os/recipes/src/test-capture/hash index bc88e04ca0..2472a38cb0 100644 --- a/repos/os/recipes/src/test-capture/hash +++ b/repos/os/recipes/src/test-capture/hash @@ -1 +1 @@ -2022-05-24 4c0225dc9ca6b8b219207df0ca66c0bcaa76c76a +2022-10-11 1c41dfc307702b545b26bec7970a1dd5fc9aff17 diff --git a/repos/os/recipes/src/test-clipboard/hash b/repos/os/recipes/src/test-clipboard/hash index e16370c098..a54e3b97e2 100644 --- a/repos/os/recipes/src/test-clipboard/hash +++ b/repos/os/recipes/src/test-clipboard/hash @@ -1 +1 @@ -2022-05-24 ddd723a50408577c0e72ab90ae8bd2e2dbb9f694 +2022-10-11 f19cacaaca8997bbe1709d6c682db9791938f53f diff --git a/repos/os/recipes/src/test-dynamic_config/hash b/repos/os/recipes/src/test-dynamic_config/hash index a0d22bda03..a691607f38 100644 --- a/repos/os/recipes/src/test-dynamic_config/hash +++ b/repos/os/recipes/src/test-dynamic_config/hash @@ -1 +1 @@ -2022-05-24 3dc23f172be62aa39e3dbc0074d70f16fd6fb4fe +2022-10-11 cc09b228062e72e7018d9da06ea3aa2b7269a8a3 diff --git a/repos/os/recipes/src/test-fault_detection/hash b/repos/os/recipes/src/test-fault_detection/hash index 3c20624c4b..bf7769374f 100644 --- a/repos/os/recipes/src/test-fault_detection/hash +++ b/repos/os/recipes/src/test-fault_detection/hash @@ -1 +1 @@ -2022-05-24 1a7f2ae84f720fc6c241a2fbee277b5a1de3750b +2022-10-11 4fc59ce6c20619ec9f4aee7d5ba067bd1c55021b diff --git a/repos/os/recipes/src/test-fs_packet/hash b/repos/os/recipes/src/test-fs_packet/hash index 8c08ff1d8b..4163823a7d 100644 --- a/repos/os/recipes/src/test-fs_packet/hash +++ b/repos/os/recipes/src/test-fs_packet/hash @@ -1 +1 @@ -2022-05-24 7b5edc93f53a09705bad7b2451fe8bfbed0f264a +2022-10-11 91d8adce148627b3edc97a3ac76927942947fd13 diff --git a/repos/os/recipes/src/test-fs_report/hash b/repos/os/recipes/src/test-fs_report/hash index 1b315170cb..f94b3fd718 100644 --- a/repos/os/recipes/src/test-fs_report/hash +++ b/repos/os/recipes/src/test-fs_report/hash @@ -1 +1 @@ -2022-05-24 e3cff88308acd589bf38086da31c055ceb8ce45b +2022-10-11 5036e9b14e875ac85a472c4b89b2532a681515fe diff --git a/repos/os/recipes/src/test-immutable_rom/hash b/repos/os/recipes/src/test-immutable_rom/hash index 0944d33735..28743b5ac8 100644 --- a/repos/os/recipes/src/test-immutable_rom/hash +++ b/repos/os/recipes/src/test-immutable_rom/hash @@ -1 +1 @@ -2022-05-24 1fd2ec21af5a90229a5de974207bdb00783c43a7 +2022-10-11 a34d8c8bf25e2c2b64abb737853b4c35bc85756b diff --git a/repos/os/recipes/src/test-init/hash b/repos/os/recipes/src/test-init/hash index 91328d2776..94741ff002 100644 --- a/repos/os/recipes/src/test-init/hash +++ b/repos/os/recipes/src/test-init/hash @@ -1 +1 @@ -2022-05-24 5c34bd3ea35e8fcd989ff2bb6efaef2d737155a6 +2022-10-11 ce6285b1ab01445b506024c4c32a2fe1cadac23d diff --git a/repos/os/recipes/src/test-init_loop/hash b/repos/os/recipes/src/test-init_loop/hash index d22ac34686..8da6e90a3c 100644 --- a/repos/os/recipes/src/test-init_loop/hash +++ b/repos/os/recipes/src/test-init_loop/hash @@ -1 +1 @@ -2022-05-24 3e10707de27b0339bf579f877dc5dd170cd17cad +2022-10-11 8848321913f52ed40c54cf168718c2ac5e528f8c diff --git a/repos/os/recipes/src/test-nic_loopback/hash b/repos/os/recipes/src/test-nic_loopback/hash index 4a0183c49a..10b79e1d94 100644 --- a/repos/os/recipes/src/test-nic_loopback/hash +++ b/repos/os/recipes/src/test-nic_loopback/hash @@ -1 +1 @@ -2022-05-24 21db241f20b46a4adcb1a12b9da3c5991769caba +2022-10-11 632494bcde32aa6c0b07d509d904f936a6ef9c43 diff --git a/repos/os/recipes/src/test-ram_fs_chunk/hash b/repos/os/recipes/src/test-ram_fs_chunk/hash index ca533622f2..f34022e05f 100644 --- a/repos/os/recipes/src/test-ram_fs_chunk/hash +++ b/repos/os/recipes/src/test-ram_fs_chunk/hash @@ -1 +1 @@ -2022-05-24 d812eba5b6035d0b8f4fa1fb162f2b9d2e8ad01b +2022-10-11 1b7e381425e9ec734e20ca68a8ca35c933967f2b diff --git a/repos/os/recipes/src/test-report_rom/hash b/repos/os/recipes/src/test-report_rom/hash index 98e2256f48..ed896442dd 100644 --- a/repos/os/recipes/src/test-report_rom/hash +++ b/repos/os/recipes/src/test-report_rom/hash @@ -1 +1 @@ -2022-05-24 e3acd9b4afd446c8cc8cb5be8e1ebd8504390f1b +2022-10-11 93833d0d1cf6a19e38241cb4300b29529236ca75 diff --git a/repos/os/recipes/src/test-resource_request/hash b/repos/os/recipes/src/test-resource_request/hash index 3e71e8818e..82980c626b 100644 --- a/repos/os/recipes/src/test-resource_request/hash +++ b/repos/os/recipes/src/test-resource_request/hash @@ -1 +1 @@ -2022-05-24 d5751f024c2168f8cd3402c43f51443d90a219f0 +2022-10-11 d04d83b10577aaf26043393c654fccadfb65ffb0 diff --git a/repos/os/recipes/src/test-resource_yield/hash b/repos/os/recipes/src/test-resource_yield/hash index 7ee7e0de70..9b978917d6 100644 --- a/repos/os/recipes/src/test-resource_yield/hash +++ b/repos/os/recipes/src/test-resource_yield/hash @@ -1 +1 @@ -2022-05-24 4d6a5eec7d381f95232023717d92947412270c43 +2022-10-11 a514a8d94fab7060669ced14ea2e58a244791989 diff --git a/repos/os/recipes/src/test-rtc/hash b/repos/os/recipes/src/test-rtc/hash index 9278869dc8..aac14704d0 100644 --- a/repos/os/recipes/src/test-rtc/hash +++ b/repos/os/recipes/src/test-rtc/hash @@ -1 +1 @@ -2022-05-24 3d5e95a96856089fb4c2a75ea8b7d5f6b77b597e +2022-10-11 945d51546f25976da522ced39e52452fc3a9504d diff --git a/repos/os/recipes/src/test-sandbox/hash b/repos/os/recipes/src/test-sandbox/hash index 9e2189ee7b..585d0aaa31 100644 --- a/repos/os/recipes/src/test-sandbox/hash +++ b/repos/os/recipes/src/test-sandbox/hash @@ -1 +1 @@ -2022-05-24 3ad10501025a79d86f9ee3f979a5bd823abb9f93 +2022-10-11 2a88b8be0637628801db56c141938de2b9e954b5 diff --git a/repos/os/recipes/src/test-signal/hash b/repos/os/recipes/src/test-signal/hash index 417c9509b7..6ba4b1566e 100644 --- a/repos/os/recipes/src/test-signal/hash +++ b/repos/os/recipes/src/test-signal/hash @@ -1 +1 @@ -2022-05-24 29347e1cf83d26e95e0cd1496e6d6d7b8f08cbcb +2022-10-11 eeb7e45485768e3a2d8d40e7f398cb0bbb75fc07 diff --git a/repos/os/recipes/src/test-slab/hash b/repos/os/recipes/src/test-slab/hash index 0abae5f98f..15d0971254 100644 --- a/repos/os/recipes/src/test-slab/hash +++ b/repos/os/recipes/src/test-slab/hash @@ -1 +1 @@ -2022-05-24 a89960bccd1d80a9e3c60799f1557ddc8efbc2a5 +2022-10-11 86cad05d7a49d815f0051f95a23b15d24dc90fe6 diff --git a/repos/os/recipes/src/test-terminal_crosslink/hash b/repos/os/recipes/src/test-terminal_crosslink/hash index 4eb3cdc489..33b0b225e4 100644 --- a/repos/os/recipes/src/test-terminal_crosslink/hash +++ b/repos/os/recipes/src/test-terminal_crosslink/hash @@ -1 +1 @@ -2022-05-24 5a685ea2f421a1e63fa50ba6a33433854d652295 +2022-10-11 6d50dc56306af1ef5257e60b1e774a4d80045c2f diff --git a/repos/os/recipes/src/test-trace/content.mk b/repos/os/recipes/src/test-trace/content.mk index 95d2225c4a..0cd6e68718 100644 --- a/repos/os/recipes/src/test-trace/content.mk +++ b/repos/os/recipes/src/test-trace/content.mk @@ -1,2 +1,2 @@ -SRC_DIR = src/test/trace src/lib/trace/policy include/trace +SRC_DIR = src/test/trace src/trace/policy include/trace include $(GENODE_DIR)/repos/base/recipes/src/content.inc diff --git a/repos/os/recipes/src/test-trace/hash b/repos/os/recipes/src/test-trace/hash index 2416ffd3da..78e061fb86 100644 --- a/repos/os/recipes/src/test-trace/hash +++ b/repos/os/recipes/src/test-trace/hash @@ -1 +1 @@ -2022-05-24 ee8b965ccee564b90864c1d4f402a52193fa0a96 +2022-10-11 c5be43b3072b4b0ba38b010ae408942009c18ff2 diff --git a/repos/os/recipes/src/test-trace_buffer/hash b/repos/os/recipes/src/test-trace_buffer/hash index 2dcd550005..25a132d7ac 100644 --- a/repos/os/recipes/src/test-trace_buffer/hash +++ b/repos/os/recipes/src/test-trace_buffer/hash @@ -1 +1 @@ -2022-05-24 1ffec760c0e9c1076a7d0eac0a85f6f33b1a08e2 +2022-10-11 4e12417721def36da1fd7d710c8a3edb46f32ed7 diff --git a/repos/os/recipes/src/test-trace_logger/content.mk b/repos/os/recipes/src/test-trace_logger/content.mk index f7c5989277..ad62486cae 100644 --- a/repos/os/recipes/src/test-trace_logger/content.mk +++ b/repos/os/recipes/src/test-trace_logger/content.mk @@ -1,2 +1,2 @@ -SRC_DIR = src/test/trace_logger src/lib/trace/policy include/trace +SRC_DIR = src/test/trace_logger src/trace/policy include/trace include $(GENODE_DIR)/repos/base/recipes/src/content.inc diff --git a/repos/os/recipes/src/test-trace_logger/hash b/repos/os/recipes/src/test-trace_logger/hash index 97b5214cdf..32a3db1542 100644 --- a/repos/os/recipes/src/test-trace_logger/hash +++ b/repos/os/recipes/src/test-trace_logger/hash @@ -1 +1 @@ -2022-05-24 3b2667466420ee1a82d7dd970a7e4f5460fd5240 +2022-10-11 b08b4306d9974d28f1279d5218c157311e2400f8 diff --git a/repos/os/recipes/src/test-utf8/hash b/repos/os/recipes/src/test-utf8/hash index 01dd3a72b4..80dae7d33f 100644 --- a/repos/os/recipes/src/test-utf8/hash +++ b/repos/os/recipes/src/test-utf8/hash @@ -1 +1 @@ -2022-05-24 65f524a9e571d9b3caec18a2aae2a4c318e4fd6a +2022-10-11 289dd5465cccbb92017488e556308d1662dfecff diff --git a/repos/os/recipes/src/test-vfs_capture/hash b/repos/os/recipes/src/test-vfs_capture/hash index b2bb21ba59..3cb46cd1e5 100644 --- a/repos/os/recipes/src/test-vfs_capture/hash +++ b/repos/os/recipes/src/test-vfs_capture/hash @@ -1 +1 @@ -2022-05-24 b346b457a35a8f4eaa5dac436b0dc30eac311e92 +2022-10-11 a39d9a3c730dee74a3100069badf459bd6e78328 diff --git a/repos/os/recipes/src/test-vfs_stress/hash b/repos/os/recipes/src/test-vfs_stress/hash index 5da56f6f91..8f3a15bf4c 100644 --- a/repos/os/recipes/src/test-vfs_stress/hash +++ b/repos/os/recipes/src/test-vfs_stress/hash @@ -1 +1 @@ -2022-05-24 9e35e59333d963b013968b4856df3116ee12f495 +2022-10-11 a201fde7cc23c0942431fa8d7a6d57a5501d7126 diff --git a/repos/os/recipes/src/test-weak_ptr/hash b/repos/os/recipes/src/test-weak_ptr/hash index 92207241d8..6a7cae940a 100644 --- a/repos/os/recipes/src/test-weak_ptr/hash +++ b/repos/os/recipes/src/test-weak_ptr/hash @@ -1 +1 @@ -2022-05-24 70804938f63b509f7c0a5b80204f62a55bfc46b9 +2022-10-11 ac4ba4301657310608a2ba4e6081f1a78da6a05d diff --git a/repos/os/recipes/src/top/hash b/repos/os/recipes/src/top/hash index 0dedf9e26a..a843181d6b 100644 --- a/repos/os/recipes/src/top/hash +++ b/repos/os/recipes/src/top/hash @@ -1 +1 @@ -2022-05-24 9b4b0a908f6bcb7139736d9406b404812d8738a3 +2022-10-11 7e4c13346add57c5753c9810ff7f8c7b02060751 diff --git a/repos/os/recipes/src/trace_logger/hash b/repos/os/recipes/src/trace_logger/hash index 88ab45e994..71853e4125 100644 --- a/repos/os/recipes/src/trace_logger/hash +++ b/repos/os/recipes/src/trace_logger/hash @@ -1 +1 @@ -2022-05-24 cbbd075ac91a3e11aa04075c0d646dd1dfc638af +2022-10-11 9aab8773d2ff92fae541b59a3d276b39b69fa943 diff --git a/repos/os/recipes/src/trace_policy/content.mk b/repos/os/recipes/src/trace_policy/content.mk index 78f22f88da..86757241f5 100644 --- a/repos/os/recipes/src/trace_policy/content.mk +++ b/repos/os/recipes/src/trace_policy/content.mk @@ -1,2 +1,2 @@ -SRC_DIR = src/lib/trace/policy +SRC_DIR = src/trace/policy include $(GENODE_DIR)/repos/base/recipes/src/content.inc diff --git a/repos/os/recipes/src/trace_policy/hash b/repos/os/recipes/src/trace_policy/hash index d06930e206..bb5efe9f1b 100644 --- a/repos/os/recipes/src/trace_policy/hash +++ b/repos/os/recipes/src/trace_policy/hash @@ -1 +1 @@ -2022-05-24 f0b101005ccf1fe6fab622568dc49c9e75724d82 +2022-10-11 5c4a83aeef4e52061da34644db8c3ec404214efd diff --git a/repos/os/recipes/src/trace_subject_reporter/hash b/repos/os/recipes/src/trace_subject_reporter/hash index c2061306de..57dd9a05f9 100644 --- a/repos/os/recipes/src/trace_subject_reporter/hash +++ b/repos/os/recipes/src/trace_subject_reporter/hash @@ -1 +1 @@ -2022-05-24 31313fa37d7020ef5ba6e7030e7f785ae576e8da +2022-10-11 85aad43b6815e90f12ddf1b87a902c335ef0704d diff --git a/repos/os/recipes/src/usb_block_drv/hash b/repos/os/recipes/src/usb_block_drv/hash index 578316035e..75319b2aeb 100644 --- a/repos/os/recipes/src/usb_block_drv/hash +++ b/repos/os/recipes/src/usb_block_drv/hash @@ -1 +1 @@ -2022-05-24 0f839972e4efe5b65cd15533a047531c279128e5 +2022-10-11 0af1f69552a93148bebdc36d89d4535c72abe16b diff --git a/repos/os/recipes/src/vfs/hash b/repos/os/recipes/src/vfs/hash index 39eb86e2b5..b9787897b9 100644 --- a/repos/os/recipes/src/vfs/hash +++ b/repos/os/recipes/src/vfs/hash @@ -1 +1 @@ -2022-05-24 8aba6698ed3c7ee216dfe09b514f99e9bdc402d4 +2022-10-11 e528b11dabfa358cc99c145c15036b03adcf63dd diff --git a/repos/os/recipes/src/vfs_block/hash b/repos/os/recipes/src/vfs_block/hash index 7997866bbf..106b09df89 100644 --- a/repos/os/recipes/src/vfs_block/hash +++ b/repos/os/recipes/src/vfs_block/hash @@ -1 +1 @@ -2022-05-24 591e7c2fc588c20cb64a8dbdd76beab5f8c2b630 +2022-10-11 88697e51d1a6d319caeacb435d1106086b25b6f9 diff --git a/repos/os/recipes/src/vfs_capture/hash b/repos/os/recipes/src/vfs_capture/hash index bb31b0c602..c6d73d9dbe 100644 --- a/repos/os/recipes/src/vfs_capture/hash +++ b/repos/os/recipes/src/vfs_capture/hash @@ -1 +1 @@ -2022-05-24 6cd4039ddef6ee37a57e8774a13203173eed0a4d +2022-10-11 f334596c5101f31c2c79fc6cfd1fcd8ad9acaef1 diff --git a/repos/os/recipes/src/vfs_tap/hash b/repos/os/recipes/src/vfs_tap/hash index 82e6aacb5d..77f448acb2 100644 --- a/repos/os/recipes/src/vfs_tap/hash +++ b/repos/os/recipes/src/vfs_tap/hash @@ -1 +1 @@ -2022-05-24 e4fa0b3ac8c84ed7a56b165e7d15208976d5108d +2022-10-11 e3715852e3429eb2c809dc8712d9aaffe1892e89 diff --git a/repos/os/recipes/src/virt_qemu_drivers/hash b/repos/os/recipes/src/virt_qemu_drivers/hash index d04f4564a2..26e58b7c8a 100644 --- a/repos/os/recipes/src/virt_qemu_drivers/hash +++ b/repos/os/recipes/src/virt_qemu_drivers/hash @@ -1 +1 @@ -2022-05-24 2d6d2162e1dfee635faa18dc531388533227aaf7 +2022-10-11 c63b9056079a4b29c8e30b2f716278eaafd723ce diff --git a/repos/os/recipes/src/virtdev_rom/hash b/repos/os/recipes/src/virtdev_rom/hash index 5d9c17e4ec..4dbef8d666 100644 --- a/repos/os/recipes/src/virtdev_rom/hash +++ b/repos/os/recipes/src/virtdev_rom/hash @@ -1 +1 @@ -2022-05-24 9fdcd8de052df54ff89c31c4716fb7a9ddb8f51b +2022-10-11 293794c814bca8b0f45cea1ce89c740abc08fdbf diff --git a/repos/os/recipes/src/virtio_fb_drv/hash b/repos/os/recipes/src/virtio_fb_drv/hash index 1c91158fe6..afd0a996d3 100644 --- a/repos/os/recipes/src/virtio_fb_drv/hash +++ b/repos/os/recipes/src/virtio_fb_drv/hash @@ -1 +1 @@ -2022-05-24 34ab0bce62cf310845b1ffe0d2be889a61684004 +2022-10-11 b52ead0214ef7975bc1457916682f30e70bec5b9 diff --git a/repos/os/recipes/src/virtio_input_drv/hash b/repos/os/recipes/src/virtio_input_drv/hash index 814a9fe620..086a89ddbd 100644 --- a/repos/os/recipes/src/virtio_input_drv/hash +++ b/repos/os/recipes/src/virtio_input_drv/hash @@ -1 +1 @@ -2022-05-24 8fb780053fc196545a38e778306c95f3f185055c +2022-10-11 f1ff132c2d3a406ad1fce6decff5050ac53285cd diff --git a/repos/os/recipes/src/virtio_nic_drv/hash b/repos/os/recipes/src/virtio_nic_drv/hash index eb90a71f2f..bc457314f9 100644 --- a/repos/os/recipes/src/virtio_nic_drv/hash +++ b/repos/os/recipes/src/virtio_nic_drv/hash @@ -1 +1 @@ -2022-05-24 131a3bf3a0b61debc7d895ec76ea24a60fe8d539 +2022-10-11 4398449ab003f50147fbef829766b9aa8733ed50 diff --git a/repos/os/recipes/src/vmm/hash b/repos/os/recipes/src/vmm/hash index 213e523cd0..97e17cb04b 100644 --- a/repos/os/recipes/src/vmm/hash +++ b/repos/os/recipes/src/vmm/hash @@ -1 +1 @@ -2022-05-24 f20338a3ac0c82e3601f32c59100710f3bdb987e +2022-10-11 cf2a7c3d0070df2efe04a92104e977c6725eacde diff --git a/repos/os/run/ahci_block.run b/repos/os/run/ahci_block.run index 43d6895f63..6fdb74bd8e 100644 --- a/repos/os/run/ahci_block.run +++ b/repos/os/run/ahci_block.run @@ -1,35 +1,25 @@ assert_spec x86 -set mke2fs [installed_command mke2fs] -set dd [installed_command dd] - -# -# Build -# -set build_components { +create_boot_directory +build { core init timer + drivers/platform + drivers/acpi drivers/ahci + app/pci_decode server/report_rom app/block_tester } -source ${genode_dir}/repos/base/run/platform_drv.inc -append_platform_drv_build_components - -build $build_components - # # Build EXT2-file-system image # +set mke2fs [installed_command mke2fs] +set dd [installed_command dd] catch { exec $dd if=/dev/zero of=bin/ext2.raw bs=1M count=16 } catch { exec $mke2fs -F bin/ext2.raw } -create_boot_directory - -# -# Generate config -# -set config { +install_config { @@ -45,20 +35,78 @@ set config { + - } + -append_platform_drv_config + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -append config { + @@ -72,6 +120,7 @@ append config { + @@ -86,6 +135,7 @@ append config { + @@ -101,16 +151,13 @@ append config { } -install_config $config - # # Boot modules # -set boot_modules { core ld.lib.so init timer ahci_drv report_rom block_tester } - -append_platform_drv_boot_modules - -build_boot_image $boot_modules +build_boot_image { + core ld.lib.so init timer + pci_decode platform_drv report_rom acpi_drv + ahci_drv report_rom block_tester } append qemu_args " -nographic -device ahci,id=ahci -boot d " append qemu_args " -drive id=disk,file=bin/ext2.raw,format=raw,if=none -device ide-hd,drive=disk,bus=ahci.0 " diff --git a/repos/os/run/event_filter.run b/repos/os/run/event_filter.run index a860b3278b..08872ccfdc 100644 --- a/repos/os/run/event_filter.run +++ b/repos/os/run/event_filter.run @@ -88,6 +88,7 @@ append config { + @@ -483,6 +484,7 @@ append config { + @@ -502,6 +504,7 @@ append config { + @@ -524,6 +527,7 @@ append config { + @@ -545,6 +549,29 @@ append config { + + + + + + + + + + + + + + + + + + + + + + + diff --git a/repos/os/run/fb_bench.run b/repos/os/run/fb_bench.run index f764505b0f..65a907520a 100644 --- a/repos/os/run/fb_bench.run +++ b/repos/os/run/fb_bench.run @@ -9,7 +9,7 @@ if {[have_board imx7d_sabre] || } if {[get_cmd_switch --autopilot] && ([have_spec linux] || - [have_board riscv_qemu])} { + [have_board virt_qemu_riscv])} { puts "\nAutopilot run is not supported on this platform\n" exit 0 } diff --git a/repos/os/run/input.run b/repos/os/run/input.run index fbd05ac87e..ae2cd0fe8f 100644 --- a/repos/os/run/input.run +++ b/repos/os/run/input.run @@ -6,9 +6,7 @@ assert_spec x86 set build_components { core init timer server/dynamic_rom server/event_dump } -source ${genode_dir}/repos/base/run/platform_drv.inc -append_platform_drv_build_components - +lappend_if [have_board pc] build_components drivers/platform lappend_if [have_board pc] build_components drivers/ps2 lappend_if [have_board linux] build_components drivers/framebuffer/sdl lappend_if [have_board linux] build_components server/nitpicker @@ -50,9 +48,24 @@ append config { } -append_platform_drv_config - append_if [have_board pc] config { + + + + + + + + + + + + + + + + + - + @@ -364,4 +364,4 @@ append done_string ".* DNS domain name: genode.org.*\n" } -run_genode_until $done_string 30 +run_genode_until $done_string 35 diff --git a/repos/os/run/nic_router_disable_arp.run b/repos/os/run/nic_router_disable_arp.run index 6a60925cdf..23890b73f6 100644 --- a/repos/os/run/nic_router_disable_arp.run +++ b/repos/os/run/nic_router_disable_arp.run @@ -5,7 +5,7 @@ if {![have_include power_on/qemu] || [have_spec foc] || [have_spec linux] || exit 0 } -if {[get_cmd_switch --autopilot] && [have_board riscv_qemu]} { +if {[get_cmd_switch --autopilot] && [have_board virt_qemu_riscv]} { puts "Autopilot mode is not supported on this platform." exit 0 } diff --git a/repos/os/run/nic_router_flood.run b/repos/os/run/nic_router_flood.run index b5d555710e..6f67f12247 100644 --- a/repos/os/run/nic_router_flood.run +++ b/repos/os/run/nic_router_flood.run @@ -7,7 +7,7 @@ if {![have_include power_on/qemu] || exit 0 } -if {[get_cmd_switch --autopilot] && ([have_board riscv_qemu] || +if {[get_cmd_switch --autopilot] && ([have_board virt_qemu_riscv] || [have_board zynq_qemu])} { puts "Autopilot mode is not supported on this platform." exit 0 diff --git a/repos/os/run/nvme.run b/repos/os/run/nvme.run index 28f1e0485f..e0c70e5ef1 100644 --- a/repos/os/run/nvme.run +++ b/repos/os/run/nvme.run @@ -48,13 +48,14 @@ proc writeable { } { # set build_components { core init timer + server/report_rom + app/pci_decode + drivers/acpi + drivers/platform drivers/nvme app/block_tester } -source ${genode_dir}/repos/base/run/platform_drv.inc -append_platform_drv_build_components - build $build_components @@ -89,13 +90,69 @@ append config { - } + -append_platform_drv_config + + + + + + + + -append config { - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -192,11 +249,10 @@ install_config $config set boot_modules { core init timer nvme_drv + pci_decode platform_drv report_rom acpi_drv ld.lib.so block_tester } -append_platform_drv_boot_modules - build_boot_image $boot_modules append qemu_args " -nographic " diff --git a/repos/os/run/pci.run b/repos/os/run/pci.run deleted file mode 100644 index 30d1abd36c..0000000000 --- a/repos/os/run/pci.run +++ /dev/null @@ -1,81 +0,0 @@ -# -# Build -# -set build_components { core init test/pci timer } - -set use_acpica_as_acpi_drv 0 - -source ${genode_dir}/repos/base/run/platform_drv.inc - -# override default platform driver policy -proc platform_drv_policy {} { - global use_acpica_as_acpi_drv - set policy "" - - append_if $use_acpica_as_acpi_drv policy { - } - - append policy { - } - - return $policy -} - -append_platform_drv_build_components - -build $build_components -create_boot_directory - -# -# Generate config -# - -append config { - - - - - - - - - - - - - - - - - - - - } - -append_platform_drv_config - -append config { - - - -} - -install_config $config - -# -# Boot modules -# - -# generic modules -set boot_modules { - core ld.lib.so init test-pci timer -} - -# platform-specific modules -append_platform_drv_boot_modules -build_boot_image $boot_modules - -append qemu_args "-nographic " - -run_genode_until "--- Platform test finished ---.*\n" 10 - diff --git a/repos/os/run/ping.run b/repos/os/run/ping.run index 58c57ee607..2caac903c1 100644 --- a/repos/os/run/ping.run +++ b/repos/os/run/ping.run @@ -38,7 +38,7 @@ if {[have_spec foc] || [have_board rpi3] || [have_board imx53_qsb_tz]} { } if {[get_cmd_switch --autopilot] && ([have_spec linux] || - [have_board riscv_qemu])} { + [have_board virt_qemu_riscv])} { puts "Autopilot mode is not supported on this platform." exit 0 } diff --git a/repos/os/run/ping_nic_router.run b/repos/os/run/ping_nic_router.run index 67e781abd5..b447ada897 100644 --- a/repos/os/run/ping_nic_router.run +++ b/repos/os/run/ping_nic_router.run @@ -4,7 +4,7 @@ if {[have_spec foc] || [have_spec linux] || [have_board rpi3] || exit 0 } -if {[get_cmd_switch --autopilot] && [have_board riscv_qemu]} { +if {[get_cmd_switch --autopilot] && [have_board virt_qemu_riscv]} { puts "Autopilot mode is not supported on this platform." exit 0 } diff --git a/repos/os/run/rtc.run b/repos/os/run/rtc.run index c693e4b32a..7cff2ac6f1 100644 --- a/repos/os/run/rtc.run +++ b/repos/os/run/rtc.run @@ -58,7 +58,7 @@ append config { } append_if $test_update config { - + diff --git a/repos/os/run/sd_card_bench.run b/repos/os/run/sd_card_bench.run index 9e239a5fdb..32932a7d58 100644 --- a/repos/os/run/sd_card_bench.run +++ b/repos/os/run/sd_card_bench.run @@ -1,7 +1,8 @@ # # Check for platform support # -if {[get_cmd_switch --autopilot] && [have_board riscv_qemu]} { +if {[get_cmd_switch --autopilot] && + [expr [have_board virt_qemu_riscv] || [have_board rpi]]} { puts "Autopilot mode is not supported on this platform." exit 0 } diff --git a/repos/os/run/smbios_decoder.run b/repos/os/run/smbios_decoder.run index 7672758bf0..2a7af2a374 100644 --- a/repos/os/run/smbios_decoder.run +++ b/repos/os/run/smbios_decoder.run @@ -5,17 +5,10 @@ if {![have_board pc] || [expr ![have_spec nova] && ![have_spec hw]] } { exit 0 } -set build_components { app/smbios_decoder core init timer server/report_rom } - -source ${genode_dir}/repos/base/run/platform_drv.inc - -append_platform_drv_build_components - -build $build_components - +build { app/smbios_decoder core init timer drivers/acpi server/report_rom } create_boot_directory -append config { +install_config { @@ -31,17 +24,34 @@ append config { - } + -append_platform_drv_config - -append config { - + + + + + + + + + + + + + + + + + + + + + @@ -62,18 +72,12 @@ append config { } -install_config $config - -set boot_modules { - report_rom +build_boot_image { + report_rom acpi_drv core init timer ld.lib.so smbios_decoder } -append_platform_drv_boot_modules - -build_boot_image $boot_modules - append qemu_args " -nographic" run_genode_until "report_rom] .*?report_rom] .*?\n" 20 diff --git a/repos/os/run/test.run b/repos/os/run/test.run index f9599e9132..98e649575e 100644 --- a/repos/os/run/test.run +++ b/repos/os/run/test.run @@ -229,7 +229,7 @@ foreach rom [content_rom_modules] { # handle vfs plugin shared-object targets if {[regexp "^vfs_(.+).lib.so$" $rom dummy plugin]} { - lappend build_targets lib/vfs/$plugin + lappend build_targets lib/vfs_$plugin continue } diff --git a/repos/os/run/timeout.run b/repos/os/run/timeout.run index 8a872a81fd..ad6afb56ca 100644 --- a/repos/os/run/timeout.run +++ b/repos/os/run/timeout.run @@ -10,7 +10,7 @@ proc fast_polling_buf_size { } { if {[expr [have_board pbxa9] && [have_spec foc]]} { return 40000000 } if {[expr [have_board imx53_qsb_tz] && [have_spec hw]]} { return 40000000 } if {[expr [have_board rpi] && [have_spec hw]]} { return 40000000 } - if {[expr [have_board riscv_qemu] && [have_spec hw]]} { return 15000000 } + if {[expr [have_board virt_qemu_riscv] && [have_spec hw]]} { return 15000000 } return 80000000 } diff --git a/repos/os/run/vfs_block.run b/repos/os/run/vfs_block.run index e54e061e10..55243f5a64 100644 --- a/repos/os/run/vfs_block.run +++ b/repos/os/run/vfs_block.run @@ -6,7 +6,7 @@ set build_components { server/vfs server/vfs_block app/block_tester - lib/vfs/import + lib/vfs_import } source ${genode_dir}/repos/base/run/platform_drv.inc diff --git a/repos/os/run/vmm_arm.run b/repos/os/run/vmm_arm.run index d5b5e54bbe..06a8ada3ae 100644 --- a/repos/os/run/vmm_arm.run +++ b/repos/os/run/vmm_arm.run @@ -7,7 +7,8 @@ assert_spec hw if { ![have_board imx7d_sabre] && ![have_board imx8q_evk] && - ![have_board virt_qemu]} { + ![have_board virt_qemu_arm_v7a] && + ![have_board virt_qemu_arm_v8a]} { puts "Run script is not supported on this platform" exit 0 } diff --git a/repos/os/src/app/pci_decode/main.cc b/repos/os/src/app/pci_decode/main.cc index c988c27a78..a786606a31 100644 --- a/repos/os/src/app/pci_decode/main.cc +++ b/repos/os/src/app/pci_decode/main.cc @@ -19,6 +19,7 @@ #include #include +#include #include using namespace Genode; @@ -36,21 +37,20 @@ struct Main Expanding_reporter pci_reporter { env, "devices", "devices" }; Registry bridge_registry {}; /* contains host bridges */ - unsigned msi_number { 0U }; - bool apic_capable { false }; bool msi_capable { false }; List_model irq_routing_list {}; List_model irq_override_list {}; + List_model reserved_memory_list {}; Constructible pci_config_ds {}; void parse_pci_function(Bdf bdf, Config & cfg, addr_t cfg_phys_base, - Xml_generator & generator); - void parse_pci_bus(bus_t bus, bus_t offset, addr_t base, - addr_t phys_base, Xml_generator & generator); + Xml_generator & generator, unsigned & msi); + void parse_pci_bus(bus_t bus, bus_t offset, addr_t base, addr_t phys_base, + Xml_generator & generator, unsigned & msi); void parse_irq_override_rules(Xml_node & xml); void parse_pci_config_spaces(Xml_node & xml); @@ -70,23 +70,30 @@ struct Main void Main::parse_pci_function(Bdf bdf, Config & cfg, addr_t cfg_phys_base, - Xml_generator & generator) + Xml_generator & gen, + unsigned & msi_number) { cfg.scan(); - Config::Vendor::access_t vendor = cfg.read(); - Config::Device::access_t device = cfg.read(); - Config::Header_type::Type::access_t type = - cfg.read(); - Config::Class_code_rev_id::Class_code::access_t dclass = - cfg.read(); - - if (type) { + /* check for bridges */ + if (cfg.read()) { for_bridge(bdf.bus, [&] (Bridge & parent) { Config_type1 bcfg(cfg.base()); new (heap) Bridge(parent.sub_bridges, bdf, bcfg.secondary_bus_number(), bcfg.subordinate_bus_number()); + + /* enable I/O spaces and DMA in bridges if not done already */ + using Command = Pci::Config::Command; + Command::access_t command = bcfg.read(); + if (Command::Io_space_enable::get(command) == 0 || + Command::Memory_space_enable::get(command) == 0 || + Command::Bus_master_enable::get(command) == 0) { + Command::Io_space_enable::set(command, 1); + Command::Memory_space_enable::set(command, 1); + Command::Bus_master_enable::set(command, 1); + bcfg.write(command); + } }); } @@ -94,67 +101,130 @@ void Main::parse_pci_function(Bdf bdf, bool msi_x = cfg.msi_x_cap.constructed(); irq_pin_t irq_pin = cfg.read(); - generator.node("device", [&] + gen.node("device", [&] { - generator.attribute("name", Bdf::string(bdf)); - generator.attribute("type", "pci"); + auto string = [&] (uint64_t v) { return String<16>(Hex(v)); }; - generator.node("pci-config", [&] + gen.attribute("name", Bdf::string(bdf)); + gen.attribute("type", "pci"); + + gen.node("pci-config", [&] { - generator.attribute("address", String<16>(Hex(cfg_phys_base))); - generator.attribute("bus", String<16>(Hex(bdf.bus))); - generator.attribute("device", String<16>(Hex(bdf.dev))); - generator.attribute("function", String<16>(Hex(bdf.fn))); - generator.attribute("vendor_id", String<16>(Hex(vendor))); - generator.attribute("device_id", String<16>(Hex(device))); - generator.attribute("class", String<16>(Hex(dclass))); - generator.attribute("bridge", cfg.bridge() ? "yes" : "no"); + using C = Config; + using C0 = Config_type0; + using Cc = Config::Class_code_rev_id; + + gen.attribute("address", string(cfg_phys_base)); + gen.attribute("bus", string(bdf.bus)); + gen.attribute("device", string(bdf.dev)); + gen.attribute("function", string(bdf.fn)); + gen.attribute("vendor_id", string(cfg.read())); + gen.attribute("device_id", string(cfg.read())); + gen.attribute("class", string(cfg.read())); + gen.attribute("revision", string(cfg.read())); + gen.attribute("bridge", cfg.bridge() ? "yes" : "no"); + if (!cfg.bridge()) { + C0 cfg0(cfg.base()); + gen.attribute("sub_vendor_id", + string(cfg0.read())); + gen.attribute("sub_device_id", + string(cfg0.read())); + } }); - cfg.for_each_bar([&] (uint64_t addr, size_t size) { - generator.node("io_mem", [&] + cfg.for_each_bar([&] (uint64_t addr, size_t size, + unsigned bar, bool pf) + { + gen.node("io_mem", [&] { - generator.attribute("address", String<16>(Hex(addr))); - generator.attribute("size", String<16>(Hex(size))); + gen.attribute("pci_bar", bar); + gen.attribute("address", string(addr)); + gen.attribute("size", string(size)); + if (pf) gen.attribute("prefetchable", true); }); - }, [&] (uint64_t addr, size_t size) { - generator.node("io_port_range", [&] + }, [&] (uint64_t addr, size_t size, unsigned bar) { + gen.node("io_port_range", [&] { - generator.attribute("address", String<16>(Hex(addr))); - generator.attribute("size", String<16>(Hex(size))); + gen.attribute("pci_bar", bar); + gen.attribute("address", string(addr)); + + /* on x86 I/O ports can be in range 0-64KB only */ + gen.attribute("size", string(size & 0xffff)); }); }); - - /* IRQ pins count from 1-4 (INTA-D), zero means no IRQ defined */ - if (!irq_pin) - return; - - generator.node("irq", [&] { - if (msi_capable && msi_x) { - generator.attribute("type", "msi-x"); - generator.attribute("number", msi_number++); - return; - } - - if (msi_capable && msi) { - generator.attribute("type", "msi"); - generator.attribute("number", msi_number++); - return; - } + /* Apply GSI/MSI/MSI-X quirks based on vendor/device/class */ + using Cc = Config::Class_code_rev_id; - irq_line_t irq = cfg.read(); + bool const hdaudio = cfg.read() == 0x40300; + auto const vendor_id = cfg.read(); + auto const device_id = cfg.read(); - for_bridge(bdf.bus, [&] (Bridge & b) { - irq_routing_list.for_each([&] (Irq_routing & ir) { - ir.route(b, bdf.dev, irq_pin-1, irq); }); + if (hdaudio && vendor_id == 0x1022 /* AMD */) { + /** + * see dde_bsd driver dev/pci/azalia.c + * + * PCI_PRODUCT_AMD_17_HDA + * PCI_PRODUCT_AMD_17_1X_HDA + * PCI_PRODUCT_AMD_HUDSON2_HDA + */ + if (device_id == 0x1457 || device_id == 0x15e3 || + device_id == 0x780d) + msi = msi_x = false; + } + } + + /* + * Only generate nodes if at least one of the following + * options is operational. + * + * - An IRQ pin from 1-4 (INTA-D) specifies legacy IRQ or GSI can be + * used, zero means no IRQ defined. + * - The used platform/kernel is MSI-capable and the device includes an + * MSI/MSI-X PCI capability. + * + * An node advertises (in decreasing priority) MSI-X, MSI, or + * legacy/GSI exclusively. + */ + bool const supports_irq = irq_pin != 0; + bool const supports_msi = msi_capable && (msi_x || msi); + + if (supports_irq || supports_msi) + gen.node("irq", [&] + { + if (msi_capable && msi) { + gen.attribute("type", "msi"); + gen.attribute("number", msi_number++); + return; + } + + if (msi_capable && msi_x) { + gen.attribute("type", "msi-x"); + gen.attribute("number", msi_number++); + return; + } + + irq_line_t irq = cfg.read(); + + for_bridge(bdf.bus, [&] (Bridge & b) { + irq_routing_list.for_each([&] (Irq_routing & ir) { + ir.route(b, bdf.dev, irq_pin-1, irq); }); + }); + + irq_override_list.for_each([&] (Irq_override & io) { + io.generate(gen, irq); }); + + gen.attribute("number", irq); }); - irq_override_list.for_each([&] (Irq_override & io) { - io.generate(generator, irq); }); - - generator.attribute("number", irq); + reserved_memory_list.for_each([&] (Rmrr & rmrr) { + if (rmrr.bdf == bdf) + gen.node("reserved_memory", [&] + { + gen.attribute("address", rmrr.addr); + gen.attribute("size", rmrr.size); + }); }); }); } @@ -164,7 +234,8 @@ void Main::parse_pci_bus(bus_t bus, bus_t offset, addr_t base, addr_t phys_base, - Xml_generator & generator) + Xml_generator & generator, + unsigned & msi_number) { auto per_function = [&] (addr_t config_base, addr_t config_phys_base, dev_t dev, func_t fn) { @@ -173,7 +244,7 @@ void Main::parse_pci_bus(bus_t bus, return true; parse_pci_function({(bus_t)(bus+offset), dev, fn}, cfg, - config_phys_base, generator); + config_phys_base, generator, msi_number); return !(fn == 0 && !cfg.read()); }; @@ -196,6 +267,12 @@ void Main::parse_pci_config_spaces(Xml_node & xml) { pci_reporter.generate([&] (Xml_generator & generator) { + /* + * We count beginning from 1 not 0, because some clients (Linux drivers) + * do not ignore the pseudo MSI number announced, but interpret zero as + * invalid. + */ + unsigned msi_number = 1; unsigned host_bridge_num = 0; xml.for_each_sub_node("bdf", [&] (Xml_node & xml) @@ -204,8 +281,9 @@ void Main::parse_pci_config_spaces(Xml_node & xml) addr_t const base = xml.attribute_value("base", 0UL); size_t const count = xml.attribute_value("count", 0UL); - bus_t const bus_off = (bus_t) (start / FUNCTION_PER_BUS_MAX); - bus_t const bus_count = (bus_t) (count / FUNCTION_PER_BUS_MAX); + bus_t const bus_off = (bus_t) (start / FUNCTION_PER_BUS_MAX); + bus_t const last_bus = (bus_t) + (max(1UL, (count / FUNCTION_PER_BUS_MAX)) - 1); if (host_bridge_num++) { error("We do not support multiple host bridges by now!"); @@ -213,14 +291,16 @@ void Main::parse_pci_config_spaces(Xml_node & xml) } new (heap) Bridge(bridge_registry, { bus_off, 0, 0 }, - bus_off, bus_count); + bus_off, last_bus); pci_config_ds.construct(env, base, count * FUNCTION_CONFIG_SPACE_SIZE); - for (bus_t bus = 0; bus < bus_count; bus++) + bus_t bus = 0; + do parse_pci_bus((bus_t)bus, bus_off, (addr_t)pci_config_ds->local_addr(), - base, generator); + base, generator, msi_number); + while (bus++ < last_bus); pci_config_ds.destruct(); }); @@ -232,6 +312,9 @@ void Main::sys_rom_update() { sys_rom.update(); + if (!sys_rom.valid()) + return; + Xml_node xml = sys_rom.xml(); if (apic_capable) { @@ -244,6 +327,11 @@ void Main::sys_rom_update() irq_routing_list.update_from_xml(policy, xml); } + { + Rmrr_policy policy(heap); + reserved_memory_list.update_from_xml(policy, xml); + } + parse_pci_config_spaces(xml); } @@ -251,11 +339,13 @@ void Main::sys_rom_update() Main::Main(Env & env) : env(env) { sys_rom.sigh(sys_rom_handler); - platform_info.xml().with_sub_node("kernel", [&] (Xml_node xml) + platform_info.xml().with_optional_sub_node("kernel", [&] (Xml_node xml) { apic_capable = xml.attribute_value("acpi", false); msi_capable = xml.attribute_value("msi", false); }); + + sys_rom_update(); } diff --git a/repos/os/src/app/pci_decode/rmrr.h b/repos/os/src/app/pci_decode/rmrr.h new file mode 100644 index 0000000000..2576c152f7 --- /dev/null +++ b/repos/os/src/app/pci_decode/rmrr.h @@ -0,0 +1,75 @@ +/* + * \brief Reserved memory region reporting from ACPI information in list models + * \author Stefan Kalkowski + * \date 2022-09-12 + */ + +/* + * Copyright (C) 2022 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. + */ + + +#include +#include +#include + +using namespace Genode; +using namespace Pci; + + +struct Rmrr : List_model::Element +{ + Bdf bdf; + addr_t addr; + size_t size; + + Rmrr(Bdf bdf, addr_t addr, size_t size) + : bdf(bdf), addr(addr), size(size) {} +}; + + +struct Rmrr_policy : List_model::Update_policy +{ + Heap & heap; + + void destroy_element(Rmrr & rmrr) { + destroy(heap, &rmrr); } + + Rmrr & create_element(Xml_node node) + { + bus_t bus = 0; + dev_t dev = 0; + func_t fn = 0; + addr_t start = node.attribute_value("start", 0UL); + addr_t end = node.attribute_value("end", 0UL); + + node.with_optional_sub_node("scope", [&] (Xml_node node) { + bus = node.attribute_value("bus_start", 0U); + node.with_optional_sub_node("path", [&] (Xml_node node) { + dev = node.attribute_value("dev", 0); + fn = node.attribute_value("func", 0); + }); + }); + + return *(new (heap) Rmrr({bus, dev, fn}, start, (end-start+1))); + } + + void update_element(Rmrr &, Xml_node) {} + + static bool element_matches_xml_node(Rmrr const & rmrr, + Genode::Xml_node node) + { + addr_t start = node.attribute_value("start", 0UL); + addr_t end = node.attribute_value("end", 0UL); + return rmrr.addr == start && + rmrr.size == (end-start+1); + } + + static bool node_is_element(Genode::Xml_node node) { + return node.has_type("rmrr"); } + + Rmrr_policy(Heap & heap) : heap(heap) {} +}; diff --git a/repos/os/src/app/pci_decode/target.mk b/repos/os/src/app/pci_decode/target.mk index 00aab2c32b..fa21870027 100644 --- a/repos/os/src/app/pci_decode/target.mk +++ b/repos/os/src/app/pci_decode/target.mk @@ -1,4 +1,5 @@ -TARGET = pci_decode -LIBS = base -SRC_CC = main.cc -INC_DIR = $(PRG_DIR) +TARGET = pci_decode +REQUIRES = x86 +LIBS = base +SRC_CC = main.cc +INC_DIR = $(PRG_DIR) diff --git a/repos/os/src/drivers/acpi/acpi.cc b/repos/os/src/drivers/acpi/acpi.cc index a4ff2d1dd0..41670466ad 100644 --- a/repos/os/src/drivers/acpi/acpi.cc +++ b/repos/os/src/drivers/acpi/acpi.cc @@ -11,7 +11,7 @@ */ /* - * Copyright (C) 2009-2017 Genode Labs GmbH + * Copyright (C) 2009-2022 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. @@ -28,6 +28,7 @@ #include "acpi.h" #include "memory.h" +#include "intel_opregion.h" using namespace Genode; @@ -412,6 +413,95 @@ class Pci_config_space : public List::Element static List _list; return &_list; } + + struct Config_space : Mmio + { + struct Vendor : Register<0x00, 16> { enum { INTEL = 0x8086 }; }; + struct Class : Register<0x0b, 8> { enum { DISPLAY = 0x3 }; }; + struct Asls : Register<0xfc, 32> { }; + + Config_space(addr_t mmio) : Mmio(mmio) { } + }; + + struct Opregion : Mmio + { + struct Minor : Register<0x16, 8> { }; + struct Major : Register<0x17, 8> { }; + struct MBox : Register<0x58, 32> { + struct Asle : Bitfield<2, 1> { }; + }; + struct Asle_ardy : Register<0x300, 32> { }; + struct Asle_rvda : Register<0x3ba, 64> { }; + struct Asle_rvds : Register<0x3c2, 32> { }; + + Opregion(addr_t mmio) : Mmio(mmio) { } + }; + + static void intel_opregion(Env &env) + { + for (auto *e = list()->first(); e; e = e->next()) { + if (e->_bdf_start != 0u) /* BDF 0:0.0 */ + continue; + + auto const config_offset = 8u * 2; /* BDF 0:2.0 */ + auto const config_size = 4096; + + if (e->_func_count <= config_offset) + continue; + + Attached_io_mem_dataspace pci_config(env, e->_base + + config_offset * config_size, + config_size); + Config_space device((addr_t)pci_config.local_addr()); + + if ((device.read() != Config_space::Vendor::INTEL) || + (device.read() != Config_space::Class::DISPLAY)) + continue; + + enum { + OPREGION_SIZE = 2 * 4096 + }; + + addr_t const phys_asls = device.read(); + if (!phys_asls) + continue; + + addr_t asls_size = OPREGION_SIZE; + + { + Attached_io_mem_dataspace map_asls(env, phys_asls, asls_size); + Opregion opregion((addr_t)map_asls.local_addr()); + + auto const rvda = opregion.read(); + auto const rvds = opregion.read(); + + if (opregion.read() && + opregion.read() >= 2 && rvda && rvds) { + + /* 2.0 rvda is physical, 2.1+ rvda is relative offset */ + if (opregion.read() > 2 || + opregion.read() >= 1) { + + if (rvda > asls_size) + asls_size += rvda - asls_size; + asls_size += opregion.read(); + } else { + warning("rvda/rvds unsupported case"); + } + } + } + + /* + * Intel_opregion requires access to the opregion memory later + * on used by acpica. Therefore the code must be executed here + * and finished, before the acpi report is sent. + * With a valid acpi report the acpica driver starts to run + * and would collide with Intel_opregion. + */ + static Acpi::Intel_opregion opregion_report { env, phys_asls, + asls_size }; + } + } }; @@ -1580,5 +1670,11 @@ void Acpi::generate_report(Genode::Env &env, Genode::Allocator &alloc) } } } + + /* + * Intel opregion lookup & parsing must be finished before acpi + * report is sent, therefore the invocation is placed exactly here. + */ + Pci_config_space::intel_opregion(env); }); } diff --git a/repos/os/src/drivers/acpi/intel_opregion.cc b/repos/os/src/drivers/acpi/intel_opregion.cc new file mode 100644 index 0000000000..488714b8eb --- /dev/null +++ b/repos/os/src/drivers/acpi/intel_opregion.cc @@ -0,0 +1,57 @@ +/* + * \brief Lookup Intel opregion region and report it as is (plain data) + * \author Alexander Boettcher + * \date 2022-05-25 + */ + + /* + * Copyright (C) 2022 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. + */ + +#include +#include +#include + +#include "intel_opregion.h" + +void Acpi::Intel_opregion::generate_report(Genode::Env &env, + addr_t const region_phys, + addr_t const region_size) +{ + try { + addr_t const phys_addr_offset = region_phys & 0xffful; + addr_t const memory_size = region_size + phys_addr_offset; + + /* create ram dataspace with space for io_mem address + size */ + Attached_io_mem_dataspace io_mem { env, region_phys, memory_size }; + Attached_ram_dataspace report_mem { env.ram(), env.rm(), + memory_size + sizeof(addr_t) * 2 }; + + auto mem_local = report_mem.local_addr(); + + /* copy io_mem to ram dataspace and preserve offset */ + memcpy(mem_local + phys_addr_offset, io_mem.local_addr(), + region_size); + + Dataspace_client report_ds(report_mem.cap()); + + /* report also io_mem address and io_mem size (!equal to ds size) */ + auto report_phys_ptr = (addr_t*)(mem_local + report_ds.size() - sizeof(addr_t) * 2); + auto report_phys_size = (addr_t*)(mem_local + report_ds.size() - sizeof(addr_t)); + + *report_phys_ptr = region_phys; + *report_phys_size = region_size; + + /* create report */ + _report.construct(env, "intel_opregion", "intel_opregion", + report_ds.size()); + _report->enabled(true); + _report->report(report_mem.local_addr(), report_ds.size()); + + } catch (...) { + Genode::warning("Intel opregion region copy failed"); + } +} diff --git a/repos/os/src/drivers/acpi/intel_opregion.h b/repos/os/src/drivers/acpi/intel_opregion.h new file mode 100644 index 0000000000..1023fdc89a --- /dev/null +++ b/repos/os/src/drivers/acpi/intel_opregion.h @@ -0,0 +1,41 @@ +/* + * \brief Lookup Intel opregion and report it as is (plain data) + * \author Alexander Boettcher + * \date 2022-05-25 + */ + + /* + * Copyright (C) 2022 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 _INTEL_OPREGION_REPORTER_H_ +#define _INTEL_OPREGION_REPORTER_H_ + +/* Genode includes */ +#include + +namespace Acpi { + class Intel_opregion; + using namespace Genode; +} + +class Acpi::Intel_opregion +{ + private: + + Constructible _report { }; + + void generate_report(Env &env, addr_t, addr_t); + + public: + + Intel_opregion(Env &env, addr_t phys_base, addr_t size) + { + generate_report(env, phys_base, size); + } +}; + +#endif /* _INTEL_OPREGION_REPORTER_H_ */ diff --git a/repos/os/src/drivers/acpi/spec/x86/target.mk b/repos/os/src/drivers/acpi/spec/x86/target.mk index 831a337726..e03b8e5f72 100644 --- a/repos/os/src/drivers/acpi/spec/x86/target.mk +++ b/repos/os/src/drivers/acpi/spec/x86/target.mk @@ -1,6 +1,6 @@ TARGET = acpi_drv REQUIRES = x86 -SRC_CC = main.cc acpi.cc smbios_table_reporter.cc +SRC_CC = main.cc acpi.cc smbios_table_reporter.cc intel_opregion.cc LIBS = base INC_DIR = $(PRG_DIR)/../.. @@ -8,5 +8,6 @@ INC_DIR = $(PRG_DIR)/../.. vpath main.cc $(PRG_DIR)/../.. vpath acpi.cc $(PRG_DIR)/../.. vpath smbios_table_reporter.cc $(PRG_DIR)/../.. +vpath intel_opregion.cc $(PRG_DIR)/../.. CC_CXX_WARN_STRICT_CONVERSION = diff --git a/repos/os/src/drivers/ahci/ahci.h b/repos/os/src/drivers/ahci/ahci.h index b0478ffdd9..8a11e51923 100644 --- a/repos/os/src/drivers/ahci/ahci.h +++ b/repos/os/src/drivers/ahci/ahci.h @@ -16,19 +16,18 @@ #define _AHCI__AHCI_H_ #include -#include +#include #include #include #include -#include - static bool constexpr verbose = false; namespace Ahci { + using namespace Genode; + struct Missing_controller : Exception { }; - class Platform; struct Protocol; struct Port; struct Port_base; @@ -39,47 +38,70 @@ namespace Ahci { using block_count_t = Block::block_count_t; } -class Ahci::Platform -{ - private : - - Data _data; - - protected: - - /** - * Return base address and size of HBA device registers - */ - addr_t _mmio_base() const; - - public: - - Platform(Env &env) : _data(env) { }; - - /** - * Register interrupt signal context - */ - void sigh_irq(Signal_context_capability sigh); - void ack_irq(); - - /** - * DMA - */ - Ram_dataspace_capability alloc_dma_buffer(size_t size); - void free_dma_buffer(Ram_dataspace_capability ds); - addr_t dma_addr(Ram_dataspace_capability); -}; - /** * HBA definitions */ -struct Ahci::Hba : Ahci::Platform, - Mmio +struct Ahci::Hba : private Platform::Device::Mmio { - Mmio::Delayer &_delayer; + using Platform::Device::Mmio::base; + using Index = Platform::Device::Mmio::Index; - Hba(Env &env, Mmio::Delayer &delayer) - : Platform(env), Mmio(_mmio_base()), _delayer(delayer) { } + Platform::Device::Irq _irq; + + /* + * mmio region of AHCI controller is always in BAR 5 + */ + class No_bar : Genode::Exception { }; + + Index _mmio_index(Platform::Connection &platform) + { + unsigned index = 0; + unsigned bar5 = ~0u; + + platform.update(); + + platform.with_xml([&] (Xml_node & xml) { + xml.with_optional_sub_node("device", [&] (Xml_node xml) { + xml.for_each_sub_node("io_mem", [&] (Xml_node node) { + unsigned bar = node.attribute_value("pci_bar", ~0u); + if (bar == 5) bar5 = index; + index++; + }); + }); + }); + + if (bar5 == ~0u) { + error("MMIO region of HBA (BAR 5) not found. Try adding\n" + "\n" + "to platform driver configuration."); + throw No_bar(); + } + + return { bar5 }; + } + + Hba(Platform::Device & dev, + Signal_context_capability cap, + Platform::Connection & platform) + : + Platform::Device::Mmio(dev, _mmio_index(platform)), + _irq(dev) + { + log("version: " + "major=", Hex(read()), " " + "minor=", Hex(read())); + log("command slots: ", command_slots()); + log("native command queuing: ", ncq() ? "yes" : "no"); + log("64-bit support: ", supports_64bit() ? "yes" : "no"); + + _irq.sigh(cap); + + /* enable AHCI */ + write(1); + + /* enable interrupts */ + write(1); + } /** * Host capabilites @@ -116,7 +138,7 @@ struct Ahci::Hba : Ahci::Platform, void ack_irq() { write(read()); - Platform::ack_irq(); + _irq.ack(); } /** @@ -135,16 +157,24 @@ struct Ahci::Hba : Ahci::Platform, struct Cap2 : Register<0x24, 32> { }; - void init() + bool port_implemented(unsigned port) const { - /* enable AHCI */ - write(1); - - /* enable interrupts */ - write(1); + return read() & (1u << port); } - Mmio::Delayer &delayer() { return _delayer; } + template + void handle_irq(FN const & fn) + { + unsigned port_list = read(); + while (port_list) { + unsigned port = log2(port_list); + port_list &= ~(1U << port); + fn(port); + } + + /* clear status register */ + ack_irq(); + } }; @@ -434,8 +464,10 @@ struct Ahci::Port_base : Mmio ATAPI_SIG_QEMU = 0xeb140000, /* will be fixed in Qemu */ }; - unsigned index { }; - Hba &hba; + unsigned index { }; + Platform::Connection &plat; + Hba &hba; + Mmio::Delayer &delayer; /** * Port signature @@ -445,13 +477,14 @@ struct Ahci::Port_base : Mmio static constexpr addr_t offset() { return 0x100; } static constexpr size_t size() { return 0x80; } - Port_base(unsigned index, Hba &hba) + Port_base(unsigned index, Platform::Connection &plat, Hba &hba, + Mmio::Delayer &delayer) : Mmio(hba.base() + offset() + (index * size())), - index(index), hba(hba) { } + index(index), plat(plat), hba(hba), delayer(delayer) { } bool implemented() const { - return hba.read() & (1u << index); + return hba.port_implemented(index); } bool ata() const { return read() == ATA_SIG; } @@ -488,6 +521,7 @@ struct Ahci::Port : private Port_base using Port_base::Register_set::Polling_timeout; using Port_base::index; using Port_base::hba; + using Port_base::delayer; struct Not_ready : Exception { }; @@ -507,10 +541,10 @@ struct Ahci::Port : private Port_base addr_t device_info = 0; addr_t dma_base = 0; /* physical address of DMA memory */ - Port(Protocol &protocol, Region_map &rm, Hba &hba, - unsigned index) + Port(Protocol &protocol, Region_map &rm, Platform::Connection & plat, + Hba &hba, Mmio::Delayer &delayer, unsigned index) : - Port_base(index, hba), + Port_base(index, plat, hba, delayer), protocol(protocol), rm(rm) { reset(); @@ -519,7 +553,7 @@ struct Ahci::Port : private Port_base stop(); - wait_for(hba.delayer(), Cmd::Cr::Equal(0)); + wait_for(delayer, Cmd::Cr::Equal(0)); init(); @@ -540,17 +574,17 @@ struct Ahci::Port : private Port_base { if (device_ds.valid()) { rm.detach((void *)cmd_list); - hba.free_dma_buffer(device_ds); + plat.free_dma_buffer(device_ds); } if (cmd_ds.valid()) { rm.detach((void *)cmd_table); - hba.free_dma_buffer(cmd_ds); + plat.free_dma_buffer(cmd_ds); } if (device_info_ds.valid()) { rm.detach((void*)device_info); - hba.free_dma_buffer(device_info_ds); + plat.free_dma_buffer(device_info_ds); } } @@ -679,14 +713,14 @@ struct Ahci::Port : private Port_base return; try { - wait_for(hba.delayer(), Tfd::Sts_bsy::Equal(0)); + wait_for(delayer, Tfd::Sts_bsy::Equal(0)); } catch (Polling_timeout) { error("HBA busy unable to start command processing."); return; } try { - wait_for(hba.delayer(), Tfd::Sts_drq::Equal(0)); + wait_for(delayer, Tfd::Sts_drq::Equal(0)); } catch (Polling_timeout) { error("HBA in DRQ unable to start command processing."); return; @@ -758,7 +792,7 @@ struct Ahci::Port : private Port_base throw Not_ready(); }, [&] { - hba.delayer().usleep(1000); + delayer.usleep(1000); status = read(); }, 10); } @@ -782,11 +816,11 @@ struct Ahci::Port : private Port_base warning("CMD.ST bit set during device reset --> unknown behavior"); write(1); - hba.delayer().usleep(1000); + delayer.usleep(1000); write(0); try { - wait_for(hba.delayer(), Ssts::Dec::Equal(Ssts::Dec::ESTABLISHED)); + wait_for(delayer, Ssts::Dec::Equal(Ssts::Dec::ESTABLISHED)); } catch (Polling_timeout) { warning("Port reset failed"); } @@ -846,10 +880,10 @@ struct Ahci::Port : private Port_base void setup_memory() { - device_ds = hba.alloc_dma_buffer(0x1000); + device_ds = plat.alloc_dma_buffer(0x1000, CACHED); /* command list 1K */ - addr_t phys = hba.dma_addr(device_ds); + addr_t phys = plat.dma_addr(device_ds); cmd_list = (addr_t)rm.attach(device_ds); command_list_base(phys); @@ -861,14 +895,14 @@ struct Ahci::Port : private Port_base * (FIS receive running) to clear */ write(0); - wait_for(hba.delayer(), Cmd::Fr::Equal(0)); + wait_for(delayer, Cmd::Fr::Equal(0)); fis_rcv_base(phys + 1024); /* command table */ size_t cmd_size = align_addr(cmd_slots * Command_table::size(), 12); - cmd_ds = hba.alloc_dma_buffer(cmd_size); + cmd_ds = plat.alloc_dma_buffer(cmd_size, CACHED); cmd_table = (addr_t)rm.attach(cmd_ds); - phys = hba.dma_addr(cmd_ds); + phys = plat.dma_addr(cmd_ds); /* set command table addresses in command list */ for (unsigned i = 0; i < cmd_slots; i++) { @@ -877,8 +911,8 @@ struct Ahci::Port : private Port_base } /* dataspace for device info */ - device_info_ds = hba.alloc_dma_buffer(0x1000); - device_info_dma_addr = hba.dma_addr(device_info_ds); + device_info_ds = plat.alloc_dma_buffer(0x1000, CACHED); + device_info_dma_addr = plat.dma_addr(device_info_ds); device_info = rm.attach(device_info_ds); } @@ -921,15 +955,15 @@ struct Ahci::Port : private Port_base { if (dma_base) return Ram_dataspace_capability(); - Ram_dataspace_capability dma = hba.alloc_dma_buffer(size); - dma_base = hba.dma_addr(dma); + Ram_dataspace_capability dma = plat.alloc_dma_buffer(size, CACHED); + dma_base = plat.dma_addr(dma); return dma; } void free_buffer(Ram_dataspace_capability ds) { dma_base = 0; - hba.free_dma_buffer(ds); + plat.free_dma_buffer(ds); } /********************** diff --git a/repos/os/src/drivers/ahci/ata_protocol.h b/repos/os/src/drivers/ahci/ata_protocol.h index cfd9ebc41f..88fb85424c 100644 --- a/repos/os/src/drivers/ahci/ata_protocol.h +++ b/repos/os/src/drivers/ahci/ata_protocol.h @@ -227,9 +227,9 @@ class Ata::Protocol : public Ahci::Protocol, Noncopyable table.fis.identify_device(); port.execute(0); - port.wait_for_any(port.hba.delayer(), Port::Is::Dss::Equal(1), - Port::Is::Pss::Equal(1), - Port::Is::Dhrs::Equal(1)); + port.wait_for_any(port.delayer, Port::Is::Dss::Equal(1), + Port::Is::Pss::Equal(1), + Port::Is::Dhrs::Equal(1)); _identity.construct(port.device_info); serial.construct(*_identity); diff --git a/repos/os/src/drivers/ahci/atapi_protocol.h b/repos/os/src/drivers/ahci/atapi_protocol.h index 4b0a2cbb58..e1cb346da1 100644 --- a/repos/os/src/drivers/ahci/atapi_protocol.h +++ b/repos/os/src/drivers/ahci/atapi_protocol.h @@ -93,21 +93,21 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable [&] { _start_unit(port); - port.wait_for_any(port.hba.delayer(), + port.wait_for_any(port.delayer, Port::Is::Dss::Equal(1), Port::Is::Pss::Equal(1), Port::Is::Dhrs::Equal(1)); port.ack_irq(); /* read sense */ _read_sense(port); - port.wait_for_any(port.hba.delayer(), + port.wait_for_any(port.delayer, Port::Is::Dss::Equal(1), Port::Is::Pss::Equal(1), Port::Is::Dhrs::Equal(1)); port.ack_irq(); /* test unit ready */ _test_unit_ready(port); - port.wait_for(port.hba.delayer(), Port::Is::Dhrs::Equal(1)); + port.wait_for(port.delayer, Port::Is::Dhrs::Equal(1)); port.ack_irq(); Device_fis f(port.fis_base); @@ -116,7 +116,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable throw Port::Polling_timeout(); _read_capacity(port); - port.wait_for_any(port.hba.delayer(), + port.wait_for_any(port.delayer, Port::Is::Dss::Equal(1), Port::Is::Pss::Equal(1), Port::Is::Dhrs::Equal(1)); port.ack_irq(); diff --git a/repos/os/src/drivers/ahci/main.cc b/repos/os/src/drivers/ahci/main.cc index 2b050b1939..b535e384a1 100644 --- a/repos/os/src/drivers/ahci/main.cc +++ b/repos/os/src/drivers/ahci/main.cc @@ -55,39 +55,30 @@ class Ahci::Driver : Noncopyable struct Timer_delayer : Mmio::Delayer, Timer::Connection { - Timer_delayer(Env &env) - : Timer::Connection(env) { } + using Timer::Connection::Connection; void usleep(uint64_t us) override { Timer::Connection::usleep(us); } } _delayer { _env }; - Hba _hba { _env, _delayer }; + Signal_handler _handler { _env.ep(), *this, &Driver::handle_irq }; + + Platform::Connection _plat { _env }; + Platform::Device _device { _plat }; + Hba _hba { _device, _handler, _plat }; Constructible _ata[MAX_PORTS]; Constructible _atapi[MAX_PORTS]; Constructible _ports[MAX_PORTS]; - Signal_handler _irq { _env.ep(), *this, &Driver::handle_irq }; - bool _enable_atapi; - - void _info() - { - log("version: " - "major=", Hex(_hba.read()), " " - "minor=", Hex(_hba.read())); - log("command slots: ", _hba.command_slots()); - log("native command queuing: ", _hba.ncq() ? "yes" : "no"); - log("64-bit support: ", _hba.supports_64bit() ? "yes" : "no"); - } + bool _enable_atapi; void _scan_ports(Region_map &rm) { - log("number of ports: ", _hba.port_count(), " pi: ", - Hex(_hba.read())); + log("number of ports: ", _hba.port_count()); for (unsigned index = 0; index < MAX_PORTS; index++) { - Port_base port(index, _hba); + Port_base port(index, _plat, _hba, _delayer); if (port.implemented() == false) continue; @@ -96,7 +87,8 @@ class Ahci::Driver : Noncopyable if (port.ata()) { try { _ata[index].construct(); - _ports[index].construct(*_ata[index], rm, _hba, index); + _ports[index].construct(*_ata[index], rm, _plat, + _hba, _delayer, index); enabled = true; } catch (...) { } @@ -104,7 +96,8 @@ class Ahci::Driver : Noncopyable } else if (port.atapi() && _enable_atapi) { try { _atapi[index].construct(); - _ports[index].construct(*_atapi[index], rm, _hba, index); + _ports[index].construct(*_atapi[index], rm, _plat, + _hba, _delayer, index); enabled = true; } catch (...) { } @@ -121,14 +114,6 @@ class Ahci::Driver : Noncopyable Driver(Env &env, Dispatch &dispatch, bool support_atapi) : _env(env), _dispatch(dispatch), _enable_atapi(support_atapi) { - _info(); - - /* register irq handler */ - _hba.sigh_irq(_irq); - - /* initialize HBA (IRQs, memory) */ - _hba.init(); - /* search for devices */ _scan_ports(env.rm()); } @@ -138,22 +123,15 @@ class Ahci::Driver : Noncopyable */ void handle_irq() { - unsigned port_list = _hba.read(); - while (port_list) { - unsigned port = log2(port_list); - port_list &= ~(1U << port); - - /* ack irq */ + _hba.handle_irq([&] (unsigned port) { if (_ports[port].constructed()) _ports[port]->handle_irq(); /* handle (pending) requests */ _dispatch.session(port); - } - - /* clear status register */ - _hba.ack_irq(); + }); } + Port &port(Session_label const &label, Session_policy const &policy) { /* try read device port number attribute */ diff --git a/repos/os/src/drivers/ahci/spec/x86/platform.cc b/repos/os/src/drivers/ahci/spec/x86/platform.cc deleted file mode 100644 index bc12cb560d..0000000000 --- a/repos/os/src/drivers/ahci/spec/x86/platform.cc +++ /dev/null @@ -1,93 +0,0 @@ -/* - * \brief Driver for PCI-bus platforms - * \author Sebastian Sumpf - * \date 2020-01-20 - */ - -/* - * Copyright (C) 2020 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. - */ - -#include - -Ahci::Data::Data(Env &env) - : env(env) -{ - pci_device_cap = pci.with_upgrade( - [&] () { return pci.next_device(pci_device_cap, AHCI_DEVICE, - CLASS_MASK); }); - - if (!pci_device_cap.valid()) { - throw Missing_controller(); - } - - /* construct pci client */ - pci_device.construct(pci_device_cap); - log("AHCI found (" - "vendor: ", Hex(pci_device->vendor_id()), " " - "device: ", Hex(pci_device->device_id()), " " - "class: ", Hex(pci_device->class_code()), ")"); - - /* map base address of controller */ - Io_mem_session_capability iomem_cap = pci_device->io_mem(pci_device->phys_bar_to_virt(AHCI_BASE_ID)); - iomem.construct(env.rm(), Io_mem_session_client(iomem_cap).dataspace()); - - uint16_t cmd = (uint16_t)pci_device->config_read(PCI_CMD, ::Platform::Device::ACCESS_16BIT); - cmd |= 0x2; /* respond to memory space accesses */ - cmd |= 0x4; /* enable bus master */ - _config_write(PCI_CMD, cmd, ::Platform::Device::ACCESS_16BIT); - - irq.construct(pci_device->irq(0)); -} - - -/************************ - ** Platform interface ** - ************************/ - -Genode::addr_t Ahci::Platform::_mmio_base() const -{ - return addr_t(_data.iomem->local_addr()); -} - - -void Ahci::Platform::sigh_irq(Signal_context_capability sigh) -{ - _data.irq->sigh(sigh); - ack_irq(); -} - - -void Ahci::Platform::ack_irq() { _data.irq->ack_irq(); } - - -Genode::Ram_dataspace_capability Ahci::Platform::alloc_dma_buffer(size_t size) -{ - size_t donate = size; - - return retry( - [&] () { - return retry( - [&] () { return _data.pci.alloc_dma_buffer(size, Genode::UNCACHED); }, - [&] () { _data.pci.upgrade_caps(2); }); - }, - [&] () { - _data.pci.upgrade_ram(donate); - donate = donate * 2 > size ? 4096 : donate * 2; - }); -} - - -void Ahci::Platform::free_dma_buffer(Genode::Ram_dataspace_capability ds) -{ - _data.pci.free_dma_buffer(ds); -} - - -Genode::addr_t Ahci::Platform::dma_addr(Genode::Ram_dataspace_capability ds) -{ - return _data.pci.dma_addr(ds); -} diff --git a/repos/os/src/drivers/ahci/spec/x86/platform.h b/repos/os/src/drivers/ahci/spec/x86/platform.h deleted file mode 100644 index fc5c53b110..0000000000 --- a/repos/os/src/drivers/ahci/spec/x86/platform.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef _AHCI__SPEC__X86__PLATFORM_H_ -#define _AHCI__SPEC__X86__PLATFORM_H_ -/* - * \brief Driver for PCI-bus platforms - * \author Sebastian Sumpf - * \date 2020-01-20 - */ - -/* - * Copyright (C) 2020 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. - */ - -#include -#include -#include -#include - -namespace Ahci { - struct Data; - using namespace Genode; -} - -struct Ahci::Data -{ - enum Pci_config { - CLASS_MASS_STORAGE = 0x10000u, - SUBCLASS_AHCI = 0x600u, - CLASS_MASK = 0xffff00u, - AHCI_DEVICE = CLASS_MASS_STORAGE | SUBCLASS_AHCI, - AHCI_BASE_ID = 0x5, /* resource id of ahci base addr */ - PCI_CMD = 0x4, - }; - - Genode::Env &env; - - Platform::Connection pci { env }; - Platform::Device_capability pci_device_cap { }; - Constructible pci_device { }; - Constructible irq { }; - Constructible iomem { }; - - Data(Env &env); - - void _config_write(uint8_t op, uint16_t cmd, - Platform::Device::Access_size width) - { - size_t donate = 4096; - retry( - [&] () { - retry( - [&] () { pci_device->config_write(op, cmd, width); }, - [&] () { pci.upgrade_caps(2); }); - }, - [&] () { - pci.upgrade_ram(donate); - donate *= 2; - }); - } -}; - - -#endif /* _AHCI__SPEC__X86__PLATFORM_H_ */ diff --git a/repos/os/src/drivers/ahci/spec/x86/target.mk b/repos/os/src/drivers/ahci/spec/x86/target.mk deleted file mode 100644 index fe44856e5b..0000000000 --- a/repos/os/src/drivers/ahci/spec/x86/target.mk +++ /dev/null @@ -1,7 +0,0 @@ -TARGET = ahci_drv -REQUIRES = x86 - -INC_DIR += $(REP_DIR)/src/drivers/ahci/spec/x86 - -include $(REP_DIR)/src/drivers/ahci/target.inc - diff --git a/repos/os/src/drivers/ahci/target.inc b/repos/os/src/drivers/ahci/target.inc deleted file mode 100644 index dee2052fcc..0000000000 --- a/repos/os/src/drivers/ahci/target.inc +++ /dev/null @@ -1,8 +0,0 @@ -SRC_CC += main.cc platform.cc -INC_DIR += $(REP_DIR)/src/drivers/ahci -LIBS += base - -CC_CXX_WARN_STRICT_CONVERSION = - -vpath platform.cc $(PRG_DIR) -vpath %.cc $(REP_DIR)/src/drivers/ahci diff --git a/repos/os/src/drivers/ahci/target.mk b/repos/os/src/drivers/ahci/target.mk new file mode 100644 index 0000000000..7d22e9a0dd --- /dev/null +++ b/repos/os/src/drivers/ahci/target.mk @@ -0,0 +1,8 @@ +TARGET = ahci_drv +SRC_CC += main.cc +INC_DIR += $(PRG_DIR) +LIBS += base + +CC_CXX_WARN_STRICT_CONVERSION = + +vpath %.cc $(PRG_DIR) diff --git a/repos/os/src/drivers/audio/spec/linux/main.cc b/repos/os/src/drivers/audio/spec/linux/main.cc index c560230e3c..a1ebbe915f 100644 --- a/repos/os/src/drivers/audio/spec/linux/main.cc +++ b/repos/os/src/drivers/audio/spec/linux/main.cc @@ -205,13 +205,10 @@ struct Audio_out::Root_policy { size_t ram_quota = Arg_string::find_arg(args, "ram_quota" ).ulong_value(0); - size_t session_size = - align_addr(sizeof(Audio_out::Session_component), 12); - if ((ram_quota < session_size) || - (sizeof(Stream) > ram_quota - session_size)) { + if (sizeof(Stream) > ram_quota) { Genode::error("insufficient 'ram_quota', got ", ram_quota, - " need ", sizeof(Stream) + session_size); + " need ", sizeof(Stream)); throw Genode::Insufficient_ram_quota(); } diff --git a/repos/os/src/drivers/framebuffer/boot/main.cc b/repos/os/src/drivers/framebuffer/boot/main.cc index 4551ba1e98..77d15dd28a 100644 --- a/repos/os/src/drivers/framebuffer/boot/main.cc +++ b/repos/os/src/drivers/framebuffer/boot/main.cc @@ -45,8 +45,8 @@ struct Framebuffer::Main static Info from_platform_info(Xml_node const &node) { Info result { }; - node.with_sub_node("boot", [&] (Xml_node const &boot) { - boot.with_sub_node("framebuffer", [&] (Xml_node const &fb) { + node.with_optional_sub_node("boot", [&] (Xml_node const &boot) { + boot.with_optional_sub_node("framebuffer", [&] (Xml_node const &fb) { result = { .addr = fb.attribute_value("phys", 0UL), .size = { fb.attribute_value("width", 0U), diff --git a/repos/os/src/drivers/framebuffer/virtio/component.h b/repos/os/src/drivers/framebuffer/virtio/component.h index 35d0b920dc..93194bf005 100644 --- a/repos/os/src/drivers/framebuffer/virtio/component.h +++ b/repos/os/src/drivers/framebuffer/virtio/component.h @@ -203,7 +203,7 @@ class Virtio_fb::Driver Env &_env; Platform::Connection &_platform; Virtio::Device &_device; - Control_queue _ctrl_vq { _env.rm(), _platform, 4, 512 }; + Control_queue _ctrl_vq { _platform, 4, 512 }; uint32_t const _num_scanouts; Signal_handler _irq_handler { _env.ep(), *this, &Driver::_handle_irq }; diff --git a/repos/os/src/drivers/framebuffer/virtio/spec/riscv/target.mk b/repos/os/src/drivers/framebuffer/virtio/spec/riscv/target.mk new file mode 100644 index 0000000000..a3ad102711 --- /dev/null +++ b/repos/os/src/drivers/framebuffer/virtio/spec/riscv/target.mk @@ -0,0 +1,3 @@ +REQUIRES = riscv + +include $(REP_DIR)/src/drivers/framebuffer/virtio/target_mmio.inc diff --git a/repos/os/src/drivers/gpio/imx/driver.h b/repos/os/src/drivers/gpio/imx/driver.h index 192cf328a9..f4d695e3a7 100644 --- a/repos/os/src/drivers/gpio/imx/driver.h +++ b/repos/os/src/drivers/gpio/imx/driver.h @@ -44,15 +44,15 @@ struct Platform::Device_client : Rpc_client return call(id); } - Io_mem_session_capability io_mem(unsigned id, Range &range, Cache cache) + Io_mem_session_capability io_mem(unsigned id, Range &range) { - return call(id, range, cache); + return call(id, range); } Dataspace_capability io_mem_dataspace(unsigned id = 0) { Range range { }; - return Io_mem_session_client(io_mem(id, range, UNCACHED)).dataspace(); + return Io_mem_session_client(io_mem(id, range)).dataspace(); } }; diff --git a/repos/os/src/drivers/gpu/intel/ggtt.h b/repos/os/src/drivers/gpu/intel/ggtt.h index 4b8e4ab1c8..b17a034a31 100644 --- a/repos/os/src/drivers/gpu/intel/ggtt.h +++ b/repos/os/src/drivers/gpu/intel/ggtt.h @@ -21,10 +21,7 @@ #include -namespace Igd { - - struct Ggtt; -} +namespace Igd { struct Ggtt; } /* * Global Graphics Translation Table @@ -57,6 +54,12 @@ class Igd::Ggtt private: + /* + * Noncopyable + */ + Ggtt(Ggtt const &); + Ggtt &operator = (Ggtt const &); + /* * IHD-OS-BDW-Vol 5-11.15 p. 44 */ @@ -113,7 +116,8 @@ class Igd::Ggtt uint64_t *_entries; - addr_t const _scratch_page; + Platform::Dma_buffer _scratch_page; + size_t const _aperture_size; size_t const _aperture_entries; @@ -133,6 +137,7 @@ class Igd::Ggtt /** * Constructor * + * \param platform reference to Platform::Connection object * \param mmio reference to Igd::Mmio object * \param base virtual base address of GGTT start * \param size size of GGTT in bytes @@ -140,9 +145,8 @@ class Igd::Ggtt * \param scratch_page physical address of the scratch page * \param fb_size size of the framebuffer region in the GTT in bytes */ - Ggtt(Igd::Mmio &mmio, addr_t base, size_t size, - size_t aperture_size, addr_t scratch_page, - size_t fb_size) + Ggtt(Platform::Connection & platform, Igd::Mmio &mmio, + addr_t base, size_t size, size_t aperture_size, size_t fb_size) : _mmio(mmio), _base(base), @@ -150,7 +154,7 @@ class Igd::Ggtt /* make the last entry/page unavailable */ _num_entries((_size / 8) - 1), _entries((uint64_t*)_base), - _scratch_page(scratch_page), + _scratch_page(platform, PAGE_SIZE, Genode::UNCACHED), _aperture_size(aperture_size), _aperture_entries(_aperture_size / PAGE_SIZE) { @@ -160,7 +164,7 @@ class Igd::Ggtt _space.set(i); } for (size_t i = fb_entries; i < _num_entries; i++) { - _insert_pte(_scratch_page, i); + _insert_pte(_scratch_page.dma_addr(), i); } } @@ -197,7 +201,7 @@ class Igd::Ggtt } _space.clear(offset); - _insert_pte(_scratch_page, offset); + _insert_pte(_scratch_page.dma_addr(), offset); } /** @@ -270,13 +274,6 @@ class Igd::Ggtt */ size_t entries() const { return _num_entries; } - /** - * Get scratch page address - * - * \return physical address of the scratch page - */ - addr_t scratch_page() const { return _scratch_page; } - /********************* ** Debug interface ** *********************/ @@ -290,7 +287,7 @@ class Igd::Ggtt log("GGTT"); log(" vaddr:", Hex(_base), " size:", Hex(_size), " entries:", _num_entries, " used:", _space.used(), " aperture_size:", Hex(_aperture_size)); - log(" scratch_page:", Hex(_scratch_page), " (PA)"); + log(" scratch_page:", Hex(_scratch_page.dma_addr()), " (PA)"); if (!dump_entries) { return; } diff --git a/repos/os/src/drivers/gpu/intel/main.cc b/repos/os/src/drivers/gpu/intel/main.cc index aa44806104..f0f1189553 100644 --- a/repos/os/src/drivers/gpu/intel/main.cc +++ b/repos/os/src/drivers/gpu/intel/main.cc @@ -24,10 +24,8 @@ #include #include #include -#include -#include -#include -#include +#include +#include #include #include #include @@ -42,12 +40,10 @@ #include #include #include -#include #include #include #include - using namespace Genode; @@ -78,18 +74,21 @@ struct Igd::Device struct Out_of_ram : Genode::Exception { }; struct Could_not_map_buffer : Genode::Exception { }; - Env &_env; - Allocator &_md_alloc; - enum { WATCHDOG_TIMEOUT = 1*1000*1000, }; + Env & _env; + Allocator & _md_alloc; + Platform::Connection & _platform; + Rm_connection & _rm; + Igd::Mmio & _mmio; + Platform::Device::Mmio & _gmadr; + uint8_t _gmch_ctl; + Timer::Connection _timer { _env }; + /********* ** PCI ** *********/ - Resources &_resources; - Platform::Device_client &_device { _resources.gpu_client() }; - struct Pci_backend_alloc : Utils::Backend_alloc { Platform::Connection &_pci; @@ -98,7 +97,8 @@ struct Igd::Device Ram_dataspace_capability alloc(size_t size) override { - return _pci.with_upgrade([&] () { + return _pci.retry_with_upgrade(Genode::Ram_quota{PAGE_SIZE}, + Genode::Cap_quota{8}, [&] () { return _pci.alloc_dma_buffer(size, Genode::UNCACHED); }); } @@ -117,7 +117,7 @@ struct Igd::Device return _pci.dma_addr(ds_cap); } - } _pci_backend_alloc { _resources.platform() }; + } _pci_backend_alloc { _platform }; Device_info _info { }; @@ -127,41 +127,9 @@ struct Igd::Device Gpu::Info_intel::Eu_total _eus { }; Gpu::Info_intel::Subslices _subslices { }; - void _pci_info(String<64> const &descr) const - { - using namespace Genode; - - uint16_t const vendor_id = _device.vendor_id(); - uint16_t const device_id = _device.device_id(); - - uint8_t bus = 0, dev = 0, fun = 0; - _device.bus_address(&bus, &dev, &fun); - - log("Found: '", descr, "' gen=", _info.generation, - " rev=", _revision.value, " ", - "[", Hex(vendor_id), ":", Hex(device_id), "] (", - Hex(bus, Hex::OMIT_PREFIX), ":", - Hex(dev, Hex::OMIT_PREFIX), ".", - Hex(fun, Hex::OMIT_PREFIX), ")"); - - enum { PCI_NUM_RES = 6 }; - for (int i = 0; i < PCI_NUM_RES; i++) { - - using Resource = Platform::Device::Resource; - - Resource const resource = _device.resource(i); - - if (resource.type() == Resource::INVALID) { continue; } - - log(" Resource ", i, " " - "(", resource.type() == Resource::IO ? "I/O" : "MEM", "): " - "base=", Genode::Hex(resource.base()), " " - "size=", Genode::Hex(resource.size()), " ", - (resource.prefetchable() ? "prefetchable" : "")); - } - } - - bool _supported(Xml_node &supported) + bool _supported(Xml_node & supported, + uint16_t dev_id, + uint8_t rev_id) { bool found = false; @@ -173,7 +141,7 @@ struct Igd::Device uint16_t const device = node.attribute_value("device", 0U); uint8_t const generation = node.attribute_value("generation", 0U); String<16> const platform = node.attribute_value("platform", String<16>("unknown")); - String<64> const desc = node.attribute_value("description", String<64>("unknown")); + //String<64> const desc = node.attribute_value("description", String<64>("unknown")); if (vendor != 0x8086 /* Intel */ || generation < 8) return; @@ -188,10 +156,9 @@ struct Igd::Device if (info.platform == Igd::Device_info::Platform::UNKNOWN) return; - if (info.id == _device.device_id()) { + if (info.id == dev_id) { _info = info; - _revision.value = _resources.config_read(8); - _pci_info(desc.string()); + _revision.value = rev_id; found = true; return; @@ -218,13 +185,40 @@ struct Igd::Device ** GGTT ** **********/ - Genode::Constructible _ggtt { }; - /********** - ** MMIO ** - **********/ + size_t _ggtt_size() + { + /* + * IHD-OS-BDW-Vol 2c-11.15 p. 1068 + */ + struct MGGC_0_2_0_PCI : Genode::Register<16> + { + struct Graphics_mode_select : Bitfield<8, 8> { }; + struct Gtt_graphics_memory_size : Bitfield<6, 2> { }; + struct Versatile_acceleration_mode_enable : Bitfield<3, 1> { }; + struct Igd_vga_disable : Bitfield<2, 1> { }; + struct Ggc_lock : Bitfield<0, 1> { }; + }; + enum { PCI_GMCH_CTL = 0x50, }; + MGGC_0_2_0_PCI::access_t v = _gmch_ctl; - Igd::Mmio &_mmio { _resources.mmio() }; + { + log("MGGC_0_2_0_PCI"); + log(" Graphics_mode_select: ", Hex(MGGC_0_2_0_PCI::Graphics_mode_select::get(v))); + log(" Gtt_graphics_memory_size: ", Hex(MGGC_0_2_0_PCI::Gtt_graphics_memory_size::get(v))); + log(" Versatile_acceleration_mode_enable: ", Hex(MGGC_0_2_0_PCI::Versatile_acceleration_mode_enable::get(v))); + log(" Igd_vga_disable: ", Hex(MGGC_0_2_0_PCI::Igd_vga_disable::get(v))); + log(" Ggc_lock: ", Hex(MGGC_0_2_0_PCI::Ggc_lock::get(v))); + } + + return (1u << MGGC_0_2_0_PCI::Gtt_graphics_memory_size::get(v)) << 20; + } + + addr_t _ggtt_base() const { + return _mmio.base() + (_mmio.size() / 2); } + + Igd::Ggtt _ggtt { _platform, _mmio, _ggtt_base(), + _ggtt_size(), _gmadr.size(), APERTURE_RESERVED }; /************ ** MEMORY ** @@ -250,14 +244,17 @@ struct Igd::Device struct Ggtt_mmio_mapping : Ggtt::Mapping { - Region_map_client _rm; + Region_map_client _rmc; - Ggtt_mmio_mapping(Resources &resources, Ggtt::Offset offset, size_t size) + Ggtt_mmio_mapping(Rm_connection & rm, + Dataspace_capability cap, + Ggtt::Offset offset, + size_t size) : - _rm(resources.rm().create(size)) + _rmc(rm.create(size)) { - _rm.attach_at(resources.gmadr_ds(), 0, size, offset * PAGE_SIZE); - Ggtt::Mapping::cap = _rm.dataspace(); + _rmc.attach_at(cap, 0, size, offset * PAGE_SIZE); + Ggtt::Mapping::cap = _rmc.dataspace(); Ggtt::Mapping::offset = offset; } @@ -280,10 +277,10 @@ struct Igd::Device */ Genode::Registered *mem = new (&alloc) Genode::Registered(_ggtt_mmio_mapping_registry, - _resources, offset, size); + _rm, _gmadr.cap(), offset, size); for (size_t i = 0; i < size; i += PAGE_SIZE) { addr_t const pa = phys_addr + i; - _ggtt->insert_pte(pa, offset + (i / PAGE_SIZE)); + _ggtt.insert_pte(pa, offset + (i / PAGE_SIZE)); } return *mem; @@ -296,7 +293,7 @@ struct Igd::Device auto lookup_and_free = [&] (Ggtt_mmio_mapping &m) { if (!(m.cap == cap)) { return; } - _ggtt->remove_pte_range(m.offset, num); + _ggtt.remove_pte_range(m.offset, num); Genode::destroy(&alloc, &m); }; @@ -420,7 +417,7 @@ struct Igd::Device : device(device), alloc(alloc), - offset(device._ggtt->find_free(pages, true)), + offset(device._ggtt.find_free(pages, true)), skip(skip_pages), ram_ds(device, device._alloc_dataspace(pages * PAGE_SIZE)), map(device, *this, alloc), @@ -922,7 +919,7 @@ struct Igd::Device _submit_execlist(rcs); _active_vgpu = gpu; - _resources.timer().trigger_once(WATCHDOG_TIMEOUT); + _timer.trigger_once(WATCHDOG_TIMEOUT); } /********** @@ -1030,56 +1027,28 @@ struct Igd::Device /** * Constructor */ - Device(Genode::Env &env, - Genode::Allocator &alloc, - Resources &resources, - Genode::Xml_node &supported) + Device(Genode::Env & env, + Genode::Allocator & alloc, + Platform::Connection & platform, + Rm_connection & rm, + Igd::Mmio & mmio, + Platform::Device::Mmio & gmadr, + Genode::Xml_node & supported, + uint16_t device_id, + uint8_t revision, + uint8_t gmch_ctl) : - _env(env), _md_alloc(alloc), _resources(resources) + _env(env), _md_alloc(alloc), _platform(platform), _rm(rm), + _mmio(mmio), _gmadr(gmadr), _gmch_ctl(gmch_ctl) { using namespace Genode; - if (!_supported(supported)) { throw Unsupported_device(); } + if (!_supported(supported, device_id, revision)) + throw Unsupported_device(); - /* - * IHD-OS-BDW-Vol 2c-11.15 p. 1068 - */ - struct MGGC_0_2_0_PCI : Genode::Register<16> - { - struct Graphics_mode_select : Bitfield<8, 8> { }; - struct Gtt_graphics_memory_size : Bitfield<6, 2> { }; - struct Versatile_acceleration_mode_enable : Bitfield<3, 1> { }; - struct Igd_vga_disable : Bitfield<2, 1> { }; - struct Ggc_lock : Bitfield<0, 1> { }; - }; - enum { PCI_GMCH_CTL = 0x50, }; - MGGC_0_2_0_PCI::access_t v = _resources.config_read(PCI_GMCH_CTL); + _ggtt.dump(); - { - log("MGGC_0_2_0_PCI"); - log(" Graphics_mode_select: ", Hex(MGGC_0_2_0_PCI::Graphics_mode_select::get(v))); - log(" Gtt_graphics_memory_size: ", Hex(MGGC_0_2_0_PCI::Gtt_graphics_memory_size::get(v))); - log(" Versatile_acceleration_mode_enable: ", Hex(MGGC_0_2_0_PCI::Versatile_acceleration_mode_enable::get(v))); - log(" Igd_vga_disable: ", Hex(MGGC_0_2_0_PCI::Igd_vga_disable::get(v))); - log(" Ggc_lock: ", Hex(MGGC_0_2_0_PCI::Ggc_lock::get(v))); - } - - /* map PCI resources */ - addr_t gttmmadr_base = _resources.map_gttmmadr(); - - /* GGTT */ - addr_t const scratch_page = _resources.scratch_page(); - - /* reserverd size for framebuffer */ - size_t const aperture_reserved = resources.gmadr_platform_size(); - - size_t const ggtt_size = (1u << MGGC_0_2_0_PCI::Gtt_graphics_memory_size::get(v)) << 20; - addr_t const ggtt_base = gttmmadr_base + (_resources.gttmmadr_size() / 2); - size_t const gmadr_size = _resources.gmadr_size(); - _ggtt.construct(_mmio, ggtt_base, ggtt_size, gmadr_size, scratch_page, aperture_reserved); - _ggtt->dump(); - - _vgpu_avail = (gmadr_size - aperture_reserved) / Vgpu::APERTURE_SIZE; + _vgpu_avail = (_gmadr.size() - APERTURE_RESERVED) / Vgpu::APERTURE_SIZE; _device_reset_and_init(); @@ -1121,7 +1090,7 @@ struct Igd::Device /* apply generation specific workarounds */ apply_workarounds(_mmio, _info.generation); - _resources.timer().sigh(_watchdog_timeout_sigh); + _timer.sigh(_watchdog_timeout_sigh); } void _clock_gating() @@ -1363,7 +1332,7 @@ struct Igd::Device size_t const size = Genode::Dataspace_client(cap).size(); size_t const num = size / PAGE_SIZE; - Ggtt::Offset const offset = _ggtt->find_free(num, aperture); + Ggtt::Offset const offset = _ggtt.find_free(num, aperture); return map_dataspace_ggtt(guard, cap, offset); } @@ -1464,8 +1433,6 @@ struct Igd::Device void enable_master_irq() { _mmio.enable_master_irq(); } - Resources &resources() { return _resources; } - private: /* @@ -1516,7 +1483,7 @@ class Gpu::Session_component : public Genode::Session_object { } /* worst case */ - bool avail_caps() { return _cap_quota_guard.have_avail(Cap_quota { 4 }); } + bool avail_caps() { return _cap_quota_guard.have_avail(Cap_quota { 5 }); } /* size + possible heap allocations */ bool avail_ram(size_t size = 0) { @@ -1524,8 +1491,17 @@ class Gpu::Session_component : public Genode::Session_object void withdraw(size_t caps, size_t ram) { - _cap_quota_guard.withdraw(Cap_quota { caps }); - _ram_quota_guard.withdraw(Ram_quota { ram }); + try { + _cap_quota_guard.withdraw(Cap_quota { caps }); + _ram_quota_guard.withdraw(Ram_quota { ram }); + } catch (... /* intentional catch-all */) { + /* + * At this point something in the accounting went wrong + * and as quick-fix let the client abort rather than the + * multiplexer. + */ + throw Service_denied(); + } } void replenish(size_t caps, size_t ram) @@ -2007,6 +1983,23 @@ class Gpu::Session_component : public Genode::Session_object _apply_buffer_local(id, lookup_and_unmap); } + Gpu::addr_t query_buffer_ppgtt(Gpu::Buffer_id id) override + { + Gpu::addr_t result = (Gpu::addr_t)-1; + + auto lookup_va = [&] (Buffer_local &buffer_local) { + + if (!buffer_local.ppgtt_va_valid) { + Genode::error("buffer not mapped"); + return; + } + + result = buffer_local.ppgtt_va; + }; + _apply_buffer_local(id, lookup_va); + return result; + } + bool set_tiling(Gpu::Buffer_id id, Genode::uint32_t const mode) override { @@ -2120,31 +2113,31 @@ class Gpu::Root : public Gpu::Root_component }; -struct Main +struct Initialization_failed : Genode::Exception { }; + + +struct Main : Irq_ack_handler, Gpu_reset_handler { - Genode::Env &_env; + Env & _env; + Sliced_heap _root_heap { _env.ram(), _env.rm() }; + Gpu::Root _gpu_root { _env, _root_heap }; + Attached_rom_dataspace _config_rom { _env, "config" }; + Heap _md_alloc { _env.ram(), _env.rm() }; + Platform::Connection _platform { _env }; + Platform::Device _device { _platform }; + Platform::Device::Irq _irq { _device }; + Igd::Mmio _mmio { _device, _env }; + Platform::Device::Mmio _gmadr { _device, { 1 } }; + Rm_connection _rm { _env }; + Io_signal_handler
_irq_dispatcher { _env.ep(), *this, + &Main::handle_irq }; + Signal_handler
_config_sigh { _env.ep(), *this, + &Main::_handle_config_update }; - /********* - ** Gpu ** - *********/ + Platform::Root _platform_root { _env, _md_alloc, _platform, *this, *this, + _mmio, _gmadr, _rm }; - Genode::Sliced_heap _root_heap { _env.ram(), _env.rm() }; - Gpu::Root _gpu_root { _env, _root_heap }; - Genode::Attached_rom_dataspace _config_rom { _env, "config" }; - - Genode::Heap _device_md_alloc { _env.ram(), _env.rm() }; - Genode::Constructible _device { }; - Igd::Resources _gpu_resources { _env, _device_md_alloc, - *this, &Main::ack_irq }; - - Genode::Irq_session_client _irq { _gpu_resources.gpu_client().irq(0) }; - Genode::Signal_handler
_irq_dispatcher { - _env.ep(), *this, &Main::handle_irq }; - - Constructible _platform_root { }; - - Genode::Signal_handler
_config_sigh { - _env.ep(), *this, &Main::_handle_config_update }; + Genode::Constructible _igd_device { }; Main(Genode::Env &env) : @@ -2154,29 +2147,33 @@ struct Main /* IRQ */ _irq.sigh(_irq_dispatcher); - _irq.ack_irq(); /* GPU */ _handle_config_update(); - - /* platform service */ - _platform_root.construct(_env, _device_md_alloc, _gpu_resources); } - void _handle_config_update() + void _create_device() { - _config_rom.update(); + uint16_t device_id; + uint8_t revision; + uint8_t gmch_ctl; - if (!_config_rom.valid()) { return; } - - if (_device.constructed()) { - Genode::log("gpu device already initialized - ignore"); - return; - } + _platform.update(); + _platform.with_xml([&] (Xml_node node) { + node.with_optional_sub_node("device", [&] (Xml_node node) { + node.with_optional_sub_node("pci-config", [&] (Xml_node node) { + device_id = node.attribute_value("device_id", 0U); + revision = node.attribute_value("revision", 0U); + gmch_ctl = node.attribute_value("intel_gmch_control", 0U); + }); + }); + }); try { - _device.construct(_env, _device_md_alloc, _gpu_resources, _config_rom.xml()); - _gpu_root.manage(*_device); + _igd_device.construct(_env, _md_alloc, _platform, _rm, _mmio, + _gmadr, _config_rom.xml(), device_id, + revision, gmch_ctl); + _gpu_root.manage(*_igd_device); _env.parent().announce(_env.ep().manage(_gpu_root)); } catch (Igd::Device::Unsupported_device) { Genode::warning("No supported Intel GPU detected - no GPU service"); @@ -2185,14 +2182,28 @@ struct Main } } + void _handle_config_update() + { + _config_rom.update(); + + if (!_config_rom.valid()) { return; } + + if (_igd_device.constructed()) { + Genode::log("gpu device already initialized - ignore"); + return; + } + + _create_device(); + } + void handle_irq() { unsigned master = 0; - if (_device.constructed()) - master = _device->handle_irq(); + if (_igd_device.constructed()) + master = _igd_device->handle_irq(); /* GPU not present forward all IRQs to platform client */ else { - _platform_root->handle_irq(); + _platform_root.handle_irq(); return; } @@ -2202,19 +2213,25 @@ struct Main */ using Master = Igd::Mmio::MASTER_INT_CTL; if (Master::De_interrupts_pending::get(master) && - (_platform_root->handle_irq())) + (_platform_root.handle_irq())) return; ack_irq(); } - void ack_irq() + void ack_irq() override { - if (_device.constructed()) { - _device->enable_master_irq(); + if (_igd_device.constructed()) { + _igd_device->enable_master_irq(); } - _irq.ack_irq(); + _irq.ack(); + } + + void reset() override + { + addr_t const base = _mmio.base() + (_mmio.size() / 2); + Igd::Ggtt(_platform, _mmio, base, Igd::GTT_RESERVED, 0, 0); } }; @@ -2224,7 +2241,7 @@ void Component::construct(Genode::Env &env) static Constructible
main; try { main.construct(env); - } catch (Igd::Resources::Initialization_failed) { + } catch (Initialization_failed) { Genode::warning("Intel GPU resources not found."); env.parent().exit(0); } diff --git a/repos/os/src/drivers/gpu/intel/mmio.h b/repos/os/src/drivers/gpu/intel/mmio.h index 44eea1536f..fa99778151 100644 --- a/repos/os/src/drivers/gpu/intel/mmio.h +++ b/repos/os/src/drivers/gpu/intel/mmio.h @@ -16,19 +16,17 @@ /* Genode includes */ #include -#include +#include +#include /* local includes */ #include -namespace Igd { - - class Mmio; -} +namespace Igd { class Mmio; } -class Igd::Mmio : public Genode::Mmio +class Igd::Mmio : public Platform::Device::Mmio { public: @@ -936,7 +934,13 @@ class Igd::Mmio : public Genode::Mmio private: - Mmio::Delayer &_delayer; + struct Timer_delayer : Genode::Mmio::Delayer + { + Timer::Connection _timer; + Timer_delayer(Genode::Env & env) : _timer(env) { } + + void usleep(uint64_t us) override { _timer.usleep(us); } + } _delayer; void _fw_reset_gen8() { @@ -1419,8 +1423,8 @@ class Igd::Mmio : public Genode::Mmio public: - Mmio(Mmio::Delayer &delayer, addr_t const base) - : Genode::Mmio(base), _delayer(delayer) { } + Mmio(Platform::Device & device, Genode::Env & env) + : Platform::Device::Mmio(device, {0}), _delayer(env) { } template void write_post(typename T::access_t const value) diff --git a/repos/os/src/drivers/gpu/intel/platform_session.h b/repos/os/src/drivers/gpu/intel/platform_session.h index 6c58c31fd1..2c803e2538 100644 --- a/repos/os/src/drivers/gpu/intel/platform_session.h +++ b/repos/os/src/drivers/gpu/intel/platform_session.h @@ -11,54 +11,63 @@ * under the terms of the GNU Affero General Public License version 3. */ -#include +#include +#include +#include +#include + +struct Irq_ack_handler +{ + virtual ~Irq_ack_handler() {} + virtual void ack_irq() = 0; +}; + +struct Gpu_reset_handler +{ + virtual ~Gpu_reset_handler() {} + virtual void reset() = 0; +}; namespace Platform { -class Device_component; -class Session_component; -class Io_mem_session_component; -class Io_mem_session_component_gmadr; -class Irq_session_component; -class Root; + using namespace Genode; + + class Device_component; + class Session_component; + class Io_mem_session_component; + class Irq_session_component; + class Root; } +using Range = Platform::Device_interface::Range; + +struct Main; class Platform::Irq_session_component : public Rpc_object { private: - Igd::Resources &_resources; + Irq_ack_handler & _ack_handler; Signal_context_capability _sigh { }; public: - Irq_session_component(Igd::Resources &resources) - : - _resources(resources) - { } + Irq_session_component(Irq_ack_handler & ack_handler) + : _ack_handler(ack_handler) { } - void ack_irq() override - { - _resources.ack_irq(); - } + void ack_irq() override { _ack_handler.ack_irq(); } - void sigh(Signal_context_capability sigh) override - { - _sigh = sigh; - } + void sigh(Signal_context_capability sigh) override { + _sigh = sigh; } bool handle_irq() { if (!_sigh.valid()) return false; Signal_transmitter(_sigh).submit(); - return true; } - Info info() override - { - return Info { Info::INVALID, 0, 0 }; - } + Info info() override { + return Info { Info::INVALID, 0, 0 }; } }; @@ -66,57 +75,47 @@ class Platform::Io_mem_session_component : public Rpc_object { private: - Igd::Resources &_resources; + Io_mem_dataspace_capability _ds_cap; public: - Io_mem_session_component(Igd::Resources &resources) - : - _resources(resources) { } + Io_mem_session_component(Dataspace_capability cap) + : _ds_cap(static_cap_cast(cap)) { } Io_mem_dataspace_capability dataspace() override { - return _resources.gttmmadr_platform_ds(); + return _ds_cap; } }; -class Platform::Io_mem_session_component_gmadr : public Rpc_object +class Platform::Device_component : public Rpc_object { private: - Igd::Resources &_resources; + Env & _env; + Io_mem_session_component _gttmmadr_io; + Range _gttmmadr_range; + Io_mem_session_component _gmadr_io; + Range _gmadr_range; + Irq_session_component _irq; public: - Io_mem_session_component_gmadr(Igd::Resources &resources) + Device_component(Env & env, + Irq_ack_handler & ack_handler, + Dataspace_capability gttmmadr_ds_cap, + Range gttmmadr_range, + Dataspace_capability gmadr_ds_cap, + Range gmadr_range) : - _resources(resources) { } - - Io_mem_dataspace_capability dataspace() override - { - return _resources.gmadr_platform_ds(); - } -}; - - -class Platform::Device_component : public Rpc_object -{ - private: - - Env &_env; - Igd::Resources &_resources; - Device_client &_device { _resources.gpu_client() }; - - Io_mem_session_component _gttmmadr_io { _resources }; - Io_mem_session_component_gmadr _gmadr_io { _resources }; - Irq_session_component _irq { _resources }; - - public: - - Device_component(Env &env, Igd::Resources &resources) - : - _env(env), _resources(resources) + _env(env), + _gttmmadr_io(gttmmadr_ds_cap), + _gttmmadr_range(gttmmadr_range), + _gmadr_io(gmadr_ds_cap), + _gmadr_range(gmadr_range), + _irq(ack_handler) { _env.ep().rpc_ep().manage(&_gttmmadr_io); _env.ep().rpc_ep().manage(&_gmadr_io); @@ -130,69 +129,29 @@ class Platform::Device_component : public Rpc_object _env.ep().rpc_ep().dissolve(&_irq); } - Irq_session_capability irq(uint8_t) override + Irq_session_capability irq(unsigned) { return _irq.cap(); } - Io_mem_session_capability io_mem(uint8_t v_id, Cache /* caching */, - addr_t /* offset */, - size_t /* size */) override + Io_mem_session_capability io_mem(unsigned idx, Range & range) { - if (v_id == 0) - return _gttmmadr_io.cap(); + range.start = 0; - if (v_id == 1) + if (idx == 0) { + range.size = _gttmmadr_range.size; + return _gttmmadr_io.cap(); + } + + if (idx == 1) { + range.size = _gmadr_range.size; return _gmadr_io.cap(); + } return Io_mem_session_capability(); } - void bus_address(unsigned char *bus, unsigned char *dev, - unsigned char *fn) override - { - _device.bus_address(bus, dev, fn); - } - - unsigned short vendor_id() override - { - return _device.vendor_id(); - } - - unsigned short device_id() override - { - return _device.device_id(); - } - - unsigned class_code() override - { - return _device.class_code(); - } - - Resource resource(int resource_id) override - { - /* bar 0 is io mem/gtt */ - if (resource_id == 0) - return Resource(_resources.gttmmadr_base(), _resources.gttmmadr_size()); - - /* bar 2 is GMADR (i.e., aperture) */ - if(resource_id == 2) - return Resource(_resources.gmadr_base(), _resources.gmadr_platform_size()); - - return Resource(); - } - - unsigned config_read(unsigned char address, Access_size size) override - { - return _device.config_read(address, size); - } - - void config_write(unsigned char /* address */, unsigned /* value */, - Access_size/* size */) override - { - } - - Io_port_session_capability io_port(uint8_t /* id */) override + Io_port_session_capability io_port_range(unsigned /* id */) { Genode::error(__func__, " is not supported"); return Io_port_session_capability(); @@ -206,37 +165,47 @@ class Platform::Session_component : public Rpc_object { private: - Env &_env; - Device_component _device_component; - Connection &_platform; - Device_capability _bridge; - Igd::Resources &_resources; - - struct Dma_cap - { - Ram_dataspace_capability cap; - - Dma_cap(Ram_dataspace_capability cap) - : cap(cap) { } - - virtual ~Dma_cap() { } - }; + Env & _env; + Connection & _platform; + Gpu_reset_handler & _reset_handler; + Heap _heap { _env.ram(), _env.rm() }; + Device_component _device_component; + bool _acquired { false }; /* * track DMA memory allocations so we can free them at session * destruction */ - Registry> _dma_registry { }; + struct Buffer : Dma_buffer, Registry::Element + { + Buffer(Registry & registry, + Connection & platform, + size_t size, + Cache cache) + : + Dma_buffer(platform, size, cache), + Registry::Element(registry, *this) {} + }; + Registry _dma_registry { }; public: - Session_component(Env &env, Igd::Resources &resources) + using Device_capability = Capability; + + Session_component(Env & env, + Connection & platform, + Irq_ack_handler & ack_handler, + Gpu_reset_handler & reset_handler, + Dataspace_capability gttmmadr_ds_cap, + Range gttmmadr_range, + Dataspace_capability gmadr_ds_cap, + Range gmadr_range) : _env(env), - _device_component(env, resources), - _platform(resources.platform()), - _bridge(resources.host_bridge_cap()), - _resources(resources) + _platform(platform), + _reset_handler(reset_handler), + _device_component(env, ack_handler, gttmmadr_ds_cap, gttmmadr_range, + gmadr_ds_cap, gmadr_range) { _env.ep().rpc_ep().manage(&_device_component); } @@ -246,72 +215,63 @@ class Platform::Session_component : public Rpc_object _env.ep().rpc_ep().dissolve(&_device_component); /* clear ggtt */ - _resources.gtt_platform_reset(); + _reset_handler.reset(); /* free DMA allocations */ - _dma_registry.for_each([&](Dma_cap &dma) { - _platform.free_dma_buffer(dma.cap); - destroy(&_resources.heap(), &dma); + _dma_registry.for_each([&](Buffer & dma) { + destroy(_heap, &dma); }); } - Device_capability first_device(unsigned device_class, unsigned) override + Device_capability acquire_single_device() override { - if (device_class == _resources.isa_bridge_class()) - return _resources.isa_bridge_cap(); + if (_acquired) + return Device_capability(); - return _bridge; - } - - Device_capability next_device(Device_capability prev_device, - unsigned, unsigned) override - { - if (!prev_device.valid()) - return _bridge; - - if (prev_device == _bridge) - return _device_component.cap(); - - if (prev_device == _device_component.cap()) - return _resources.isa_bridge_cap(); - - return Device_capability(); + _acquired = true; + return _device_component.cap(); } void release_device(Device_capability) override { - return; + _acquired = false; } - Device_capability device(Device_name const & /* string */) override + Device_capability acquire_device(Device_name const & /* string */) override { - Genode::error(__func__, " is not supported"); - return Device_capability(); + return acquire_single_device(); } Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache) override { - Ram_dataspace_capability cap = _platform.alloc_dma_buffer(size, cache); - new (&_resources.heap()) Registered(_dma_registry, cap); - return cap; + Buffer & db = *(new (_heap) + Buffer(_dma_registry, _platform, size, cache)); + return static_cap_cast(db.cap()); } void free_dma_buffer(Ram_dataspace_capability cap) override { if (!cap.valid()) return; - _dma_registry.for_each([&](Dma_cap &dma) { - if ((dma.cap == cap) == false) return; - _platform.free_dma_buffer(cap); - destroy(&_resources.heap(), &dma); + _dma_registry.for_each([&](Buffer & db) { + if ((db.cap() == cap) == false) return; + destroy(_heap, &db); }); } addr_t dma_addr(Ram_dataspace_capability cap) override { - return _platform.dma_addr(cap); + addr_t ret = 0UL; + _dma_registry.for_each([&](Buffer & db) { + if ((db.cap() == cap) == false) return; + ret = db.dma_addr(); + }); + return ret; } + Rom_session_capability devices_rom() override { + return _platform.devices_rom(); } + bool handle_irq() { return _device_component.handle_irq(); } }; @@ -320,23 +280,83 @@ class Platform::Root : public Root_component _session { }; - Igd::Resources &_resources; public: - Root(Env &env, Allocator &md_alloc, Igd::Resources &resources) + Root(Env & env, + Allocator & md_alloc, + Connection & platform, + Irq_ack_handler & ack_handler, + Gpu_reset_handler & reset_handler, + Igd::Mmio & mmio, + Device::Mmio & gmadr, + Rm_connection & rm) : - Root_component(&env.ep().rpc_ep(), &md_alloc), - _env(env), _resources(resources) + Root_component(&env.ep().rpc_ep(), &md_alloc), + _env(env), + _platform(platform), + _ack_handler(ack_handler), + _reset_handler(reset_handler), + _gttmmadr_rm(rm.create(mmio.size())), + _gttmmadr_range{1<<30, mmio.size()}, + _gmadr_rm(rm.create(Igd::APERTURE_RESERVED)), + _gmadr_range{1<<29, gmadr.size()} { + using namespace Igd; + + /******************************** + ** Prepare managed dataspaces ** + ********************************/ + + /* GTT starts at half of the mmio memory */ + size_t const gttm_half_size = mmio.size() / 2; + off_t const gtt_offset = gttm_half_size; + + if (gttm_half_size < GTT_RESERVED) { + Genode::error("GTTM size too small"); + return; + } + + /* attach actual iomem + reserved */ + _gttmmadr_rm.attach_at(mmio.cap(), 0, gtt_offset); + + /* attach beginning of GTT */ + _gttmmadr_rm.attach_at(mmio.cap(), gtt_offset, + GTT_RESERVED, gtt_offset); + + /* attach the rest of the GTT as dummy RAM */ + Genode::Ram_dataspace_capability dummmy_gtt_ds { + _env.ram().alloc(PAGE_SIZE) }; + size_t remainder = gttm_half_size - GTT_RESERVED; + for (off_t offset = gtt_offset + GTT_RESERVED; + remainder > 0; + offset += PAGE_SIZE, remainder -= PAGE_SIZE) { + rm.retry_with_upgrade(Genode::Ram_quota{PAGE_SIZE}, + Genode::Cap_quota{8}, [&]() { + _gttmmadr_rm.attach_at(dummmy_gtt_ds, offset, PAGE_SIZE); }); + } + + _gmadr_rm.attach_at(gmadr.cap(), 0, APERTURE_RESERVED); + env.parent().announce(env.ep().manage(*this)); } Session_component *_create_session(char const * /* args */) override { - _session.construct(_env, _resources); + _session.construct(_env, _platform, _ack_handler, _reset_handler, + _gttmmadr_rm.dataspace(), _gttmmadr_range, + _gmadr_rm.dataspace(), _gmadr_range); return &*_session; } @@ -344,8 +364,8 @@ class Platform::Root : public Root_component -#include - -namespace Igd { - class Resources; -} - -struct Main; - -class Igd::Resources : Genode::Noncopyable -{ - public: - - struct Initialization_failed : Genode::Exception { }; - - private: - - using Io_mem_connection = Genode::Io_mem_connection; - using Io_mem_dataspace_capability = Genode::Io_mem_dataspace_capability; - using Ram_dataspace_capability = Genode::Ram_dataspace_capability; - using Dataspace_capability = Genode::Dataspace_capability; - - Genode::Env &_env; - Genode::Heap &_heap; - - /* timer */ - Timer::Connection _timer { _env }; - - struct Timer_delayer : Genode::Mmio::Delayer - { - Timer::Connection &_timer; - Timer_delayer(Timer::Connection &timer) : _timer(timer) { } - - void usleep(uint64_t us) override { _timer.usleep(us); } - - } _delayer { _timer }; - - /* irq callback */ - Main &_obj; - void (Main::*_ack_irq) (); - - /* platform session */ - Platform::Connection _platform { _env }; - - Platform::Device_capability _gpu_cap { }; - Platform::Device_capability _host_bridge_cap { }; - Platform::Device_capability _isa_bridge_cap { }; - Genode::Constructible _gpu_client { }; - - /* mmio + ggtt */ - Platform::Device::Resource _gttmmadr { }; - Io_mem_dataspace_capability _gttmmadr_ds { }; - Genode::Io_mem_session_capability _gttmmadr_io { }; - addr_t _gttmmadr_local { 0 }; - - Genode::Constructible _mmio { }; - - /* scratch page for ggtt */ - Ram_dataspace_capability _scratch_page_ds { - _platform.with_upgrade([&] () { - return _platform.alloc_dma_buffer(PAGE_SIZE, Genode::UNCACHED); }) }; - - addr_t _scratch_page { - _platform.dma_addr(_scratch_page_ds) }; - - /* aperture */ - enum { - /* reserved aperture for platform service */ - APERTURE_RESERVED = 64u<<20, - /* reserved GTT for platform service, GTT entry is 8 byte */ - GTT_RESERVED = (APERTURE_RESERVED/PAGE_SIZE) * 8, - }; - - Genode::Rm_connection _rm_connection { _env }; - - Platform::Device::Resource _gmadr { }; - Io_mem_dataspace_capability _gmadr_ds { }; - Genode::Io_mem_session_capability _gmadr_io { }; - Genode::Region_map_client _gmadr_rm { _rm_connection.create(APERTURE_RESERVED) }; - - - /* managed dataspace for local platform service */ - Genode::Constructible _gttmmadr_rm { }; - - void _create_gttmmadr_rm() - { - using off_t = Genode::off_t; - - size_t const gttm_half_size = gttmmadr_size() / 2; - /* GTT starts at half of the mmio memory */ - off_t const gtt_offset = gttm_half_size; - - if (gttm_half_size < GTT_RESERVED) { - Genode::error("GTTM size too small"); - return; - } - - _gttmmadr_rm.construct(_rm_connection.create((gttmmadr_size()))); - - /* attach actual iomem + reserved */ - _gttmmadr_rm->attach_at(_gttmmadr_ds, 0, gtt_offset); - - /* attach beginning of GTT */ - _gttmmadr_rm->attach_at(_gttmmadr_ds, gtt_offset, GTT_RESERVED, gtt_offset); - - /* attach the rest of the GTT as dummy RAM */ - Genode::Ram_dataspace_capability dummmy_gtt_ds { _env.ram().alloc(PAGE_SIZE) }; - size_t remainder = gttm_half_size - GTT_RESERVED; - for (off_t offset = gtt_offset + GTT_RESERVED; - remainder > 0; - offset += PAGE_SIZE, remainder -= PAGE_SIZE) { - _rm_connection.retry_with_upgrade(Genode::Ram_quota{4096}, - Genode::Cap_quota{8}, [&]() { - _gttmmadr_rm->attach_at(dummmy_gtt_ds, offset, PAGE_SIZE); - }); - } - } - - /********* - ** Pci ** - *********/ - - void _find_devices() - { - using namespace Platform; - - auto _scan_pci = [&] (Platform::Connection &pci, - Device_capability const &prev, - bool release) { - Device_capability cap = pci.with_upgrade([&]() { - return pci.next_device(prev, 0, 0); }); - - if (prev.valid() && release) { pci.release_device(prev); } - return cap; - }; - - Device_capability cap; - bool release = false; - while ((cap = _scan_pci(_platform, cap, release)).valid()) { - Device_client device(cap); - - unsigned char bus = 0xff, dev = 0xff, func = 0xff; - device.bus_address(&bus, &dev, &func); - - /* host pci bridge */ - if (bus == 0 && dev == 0 && func == 0) { - _host_bridge_cap = cap; - release = false; - continue; - } - - /* gpu */ - if ((device.class_code() >> 8) == 0x0300) { - _gpu_cap = cap; - release = false; - continue; - } - - if (device.class_code() == isa_bridge_class()) { - _isa_bridge_cap = cap; - release = false; - continue; - } - - release = true; - } - } - - bool _mch_enabled() - { - using namespace Platform; - - if (!_host_bridge_cap.valid()) { return false; } - - Device_client device(_host_bridge_cap); - - /* - * 5th Gen Core Processor datasheet vol 2 p. 48 - */ - enum { MCHBAR_OFFSET = 0x48, }; - struct MCHBAR : Genode::Register<64> - { - struct Mchbaren : Bitfield<0, 1> { }; - }; - - MCHBAR::access_t const v = device.config_read(MCHBAR_OFFSET, - Platform::Device::ACCESS_32BIT); - return MCHBAR::Mchbaren::get(v); - } - - template - static Platform::Device::Access_size _access_size(T) - { - switch (sizeof(T)) { - case 1: return Platform::Device::ACCESS_8BIT; - case 2: return Platform::Device::ACCESS_16BIT; - default: return Platform::Device::ACCESS_32BIT; - } - } - - void _enable_pci_bus_master() - { - enum { - PCI_CMD_REG = 4, - PCI_BUS_MASTER = 1<<2, - }; - - uint16_t cmd = config_read(PCI_CMD_REG); - cmd |= PCI_BUS_MASTER; - config_write(PCI_CMD_REG, cmd); - } - - public: - - Resources(Genode::Env &env, Genode::Heap &heap, - Main &obj, void (Main::*ack_irq) ()) - : - _env(env), _heap(heap), _obj(obj), _ack_irq(ack_irq) - { - /* initial donation for device pd */ - _platform.upgrade_ram(1024*1024); - - _find_devices(); - if (!_gpu_cap.valid() || !_mch_enabled()) { - throw Initialization_failed(); - } - - _gpu_client.construct(_gpu_cap); - - /* - * The intel display driver (as client of this gpu driver) - * uses the platform.io_mem() cap interface to obtain the io_mem - * capabilities. The need for directly handling with the physical - * io_mem addresses is not desired and the legacy path. So dummy - * addresses are used here just as placeholder for implementing - * the platform.resource() RPC interface. - */ - - _gttmmadr_io = _gpu_client->io_mem(0); - _gttmmadr_ds = Genode::Io_mem_session_client(_gttmmadr_io).dataspace(); - _gttmmadr = Platform::Device::Resource(1u << 30 /* dummy */, - Genode::Dataspace_client(_gttmmadr_ds).size()); - - _gmadr_io = _gpu_client->io_mem(1, Genode::Cache::WRITE_COMBINED); - _gmadr_ds = Genode::Io_mem_session_client(_gmadr_io).dataspace(); - _gmadr_rm.attach_at(_gmadr_ds, 0, APERTURE_RESERVED); - _gmadr = Platform::Device::Resource(1u << 29 /* dummy */, - Genode::Dataspace_client(_gmadr_ds).size()); - - _enable_pci_bus_master(); - - log("Reserved beginning ", - Genode::Number_of_bytes(APERTURE_RESERVED), - " of aperture for platform service"); - } - - ~Resources() - { - _platform.release_device(_gpu_cap); - _platform.release_device(_host_bridge_cap); - } - - Genode::Rm_connection &rm() { return _rm_connection; } - - addr_t map_gttmmadr() - { - if (!_gttmmadr_ds.valid()) - throw Initialization_failed(); - - if (_gttmmadr_local) return _gttmmadr_local; - - _gttmmadr_local = (addr_t)(_env.rm().attach(_gttmmadr_ds, _gttmmadr.size())); - - log("Map res:", 0, - " base:", Genode::Hex(_gttmmadr.base()), - " size:", Genode::Hex(_gttmmadr.size()), - " vaddr:", Genode::Hex(_gttmmadr_local)); - - return _gttmmadr_local; - } - - template - T config_read(unsigned int const devfn) - { - T val = 0; - _platform.with_upgrade([&] () { - val = _gpu_client->config_read(devfn, _access_size(val)); - }); - - return val; - } - - template - void config_write(unsigned int const devfn, T val) - { - _platform.with_upgrade([&] () { - _gpu_client->config_write(devfn, val, _access_size(val)); - }); - } - - void ack_irq() { (_obj.*_ack_irq)(); } - - Genode::Heap &heap() { return _heap; } - Timer::Connection &timer() { return _timer; }; - addr_t scratch_page() const { return _scratch_page; } - - Platform::Connection &platform() { return _platform; } - Platform::Device_client &gpu_client() { return *_gpu_client; } - Platform::Device_capability host_bridge_cap() { return _host_bridge_cap; } - Platform::Device_capability isa_bridge_cap() { return _isa_bridge_cap; } - unsigned isa_bridge_class() const { return 0x601u << 8; } - - addr_t gmadr_base() const { return _gmadr.base(); } - size_t gmadr_size() const { return _gmadr.size(); } - Dataspace_capability gmadr_ds() const { return _gmadr_ds; } - - addr_t gttmmadr_base() const { return _gttmmadr.base(); } - size_t gttmmadr_size() const { return _gttmmadr.size(); } - - size_t gmadr_platform_size() const { return APERTURE_RESERVED; } - size_t gttmmadr_platform_size() const { return GTT_RESERVED; } - - Io_mem_dataspace_capability gttmmadr_platform_ds() - { - using namespace Genode; - - if (!_gttmmadr_rm.constructed()) - _create_gttmmadr_rm(); - - if (!_gttmmadr_rm.constructed()) - return { }; - - return static_cap_cast(_gttmmadr_rm->dataspace()); - } - - Io_mem_dataspace_capability gmadr_platform_ds() - { - using namespace Genode; - return static_cap_cast(_gmadr_rm.dataspace()); - } - - void gtt_platform_reset() - { - addr_t const base = map_gttmmadr() + (gttmmadr_size() / 2); - Igd::Ggtt(mmio(), base, gttmmadr_platform_size(), 0, scratch_page(), 0); - } - - Igd::Mmio &mmio() - { - if (!_mmio.constructed()) - _mmio.construct(_delayer, map_gttmmadr()); - - return *_mmio; - } -}; - diff --git a/repos/os/src/drivers/gpu/intel/types.h b/repos/os/src/drivers/gpu/intel/types.h index 4a839d818c..1c2ec0b957 100644 --- a/repos/os/src/drivers/gpu/intel/types.h +++ b/repos/os/src/drivers/gpu/intel/types.h @@ -28,7 +28,13 @@ namespace Igd { using addr_t = Genode::addr_t; using size_t = Genode::size_t; - enum { PAGE_SIZE = 4096, }; + enum { + PAGE_SIZE = 4096, + /* reserved aperture for platform service */ + APERTURE_RESERVED = 64u<<20, + /* reserved GTT for platform service, GTT entry is 8 byte */ + GTT_RESERVED = (APERTURE_RESERVED/PAGE_SIZE) * 8, + }; inline void wmb() { asm volatile ("sfence": : :"memory"); } } diff --git a/repos/os/src/drivers/input/virtio/component.h b/repos/os/src/drivers/input/virtio/component.h index 5387fc5c98..d799733d29 100644 --- a/repos/os/src/drivers/input/virtio/component.h +++ b/repos/os/src/drivers/input/virtio/component.h @@ -137,10 +137,8 @@ class Virtio_input::Driver Input::Absolute_motion _abs_motion { -1, -1 }; Abs_config _abs_config { { 0, 0 }, { 0, 0 }, 0, 0 }; Signal_handler _irq_handler {_env.ep(), *this, &Driver::_handle_irq}; - Events_virtqueue _events_vq { _env.rm(), _plat, - QUEUE_SIZE, QUEUE_ELM_SIZE }; - Status_virtqueue _status_vq { _env.rm(), _plat, - QUEUE_SIZE, QUEUE_ELM_SIZE }; + Events_virtqueue _events_vq { _plat, QUEUE_SIZE, QUEUE_ELM_SIZE }; + Status_virtqueue _status_vq { _plat, QUEUE_SIZE, QUEUE_ELM_SIZE }; void _handle_event(::Event::Session_client::Batch &batch, const Event &evt) diff --git a/repos/os/src/drivers/input/virtio/spec/riscv/target.mk b/repos/os/src/drivers/input/virtio/spec/riscv/target.mk new file mode 100644 index 0000000000..ecf75bc827 --- /dev/null +++ b/repos/os/src/drivers/input/virtio/spec/riscv/target.mk @@ -0,0 +1,3 @@ +REQUIRES = riscv + +include $(REP_DIR)/src/drivers/input/virtio/target_mmio.inc diff --git a/repos/os/src/drivers/nic/spec/linux/main.cc b/repos/os/src/drivers/nic/spec/linux/main.cc index 4b7d7296bf..db85a3db08 100644 --- a/repos/os/src/drivers/nic/spec/linux/main.cc +++ b/repos/os/src/drivers/nic/spec/linux/main.cc @@ -212,7 +212,7 @@ struct Main Main(Env &env) : _env(env) { - _config_rom.xml().with_sub_node("report", [&] (Xml_node const &xml) { + _config_rom.xml().with_optional_sub_node("report", [&] (Xml_node const &xml) { bool const report_mac_address = xml.attribute_value("mac_address", false); diff --git a/repos/os/src/drivers/nic/virtio/component.h b/repos/os/src/drivers/nic/virtio/component.h index 5a7d5300c2..003ae5dc54 100644 --- a/repos/os/src/drivers/nic/virtio/component.h +++ b/repos/os/src/drivers/nic/virtio/component.h @@ -288,18 +288,17 @@ class Virtio_nic::Device : Noncopyable public: - Device(Genode::Env &env, - Virtio::Device &device, + Device(Virtio::Device &device, Platform::Connection &plat, Genode::Xml_node const &xml) try : _verbose { xml.attribute_value("verbose", false) }, _device { device }, _hw_features { _init_hw_features(xml) }, - _rx_vq { env.rm(), plat, + _rx_vq { plat, _vq_size(RX_VQ, xml, "rx_queue_size"), _buf_size(RX_VQ, xml, "rx_buffer_size") }, - _tx_vq { env.rm(), plat, + _tx_vq { plat, _vq_size(TX_VQ, xml, "tx_queue_size"), _buf_size(TX_VQ, xml, "tx_buffer_size") } { } @@ -496,7 +495,7 @@ class Virtio_nic::Uplink_client : public Virtio_nic::Device, Platform::Connection &plat, Genode::Xml_node const &xml) : - Device { env, device, plat, xml }, + Device { device, plat, xml }, Uplink_client_base { env, alloc, read_mac_address() }, _irq_handler { env.ep(), *this, &Uplink_client::_handle_irq } { diff --git a/repos/os/src/drivers/nic/virtio/pci_device.cc b/repos/os/src/drivers/nic/virtio/pci_device.cc index 1b5aa9e4d4..561a4e5c51 100644 --- a/repos/os/src/drivers/nic/virtio/pci_device.cc +++ b/repos/os/src/drivers/nic/virtio/pci_device.cc @@ -14,7 +14,7 @@ /* Genode includes */ #include #include -#include +#include #include /* local includes */ @@ -30,29 +30,15 @@ struct Virtio_pci_nic::Main struct Device_not_found : Genode::Exception { }; Genode::Env & env; - Genode::Heap heap { env.ram(), env.rm() }; - Platform::Connection pci { env }; - Platform::Device_client platform_device; - Virtio::Device virtio_device { env, platform_device }; - Attached_rom_dataspace config_rom { env, "config" }; + Genode::Heap heap { env.ram(), env.rm() }; + Platform::Connection pci { env }; + Virtio::Device virtio_device { env, pci }; + Attached_rom_dataspace config_rom { env, "config" }; Virtio_nic::Uplink_client uplink_client { env, heap, virtio_device, pci, config_rom.xml() }; - Platform::Device_capability find_platform_device() - { - Platform::Device_capability device_cap; - pci.with_upgrade([&] () { device_cap = pci.first_device(); }); - - if (!device_cap.valid()) throw Device_not_found(); - - return device_cap; - } - - Main(Env &env) - : env(env), platform_device(find_platform_device()) - { - log("--- VirtIO PCI driver started ---"); - } + Main(Env &env) : env(env) { + log("--- VirtIO PCI driver started ---"); } }; diff --git a/repos/os/src/drivers/nic/virtio/spec/riscv/target.mk b/repos/os/src/drivers/nic/virtio/spec/riscv/target.mk new file mode 100644 index 0000000000..20569fd810 --- /dev/null +++ b/repos/os/src/drivers/nic/virtio/spec/riscv/target.mk @@ -0,0 +1,3 @@ +REQUIRES = riscv + +include $(REP_DIR)/src/drivers/nic/virtio/target_mmio.inc diff --git a/repos/os/src/drivers/nvme/main.cc b/repos/os/src/drivers/nvme/main.cc index 76050cc626..44ed8d7ffb 100644 --- a/repos/os/src/drivers/nvme/main.cc +++ b/repos/os/src/drivers/nvme/main.cc @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include #include @@ -33,7 +35,6 @@ /* local includes */ #include -#include namespace { @@ -397,14 +398,17 @@ struct Nvme::Sqe_io : Nvme::Sqe /* * Queue base structure */ -struct Nvme::Queue +struct Nvme::Queue : Platform::Dma_buffer { - Genode::Ram_dataspace_capability ds { }; - addr_t pa { 0 }; - addr_t va { 0 }; - uint32_t max_entries { 0 }; + size_t len; + uint32_t max_entries; - bool valid() const { return pa != 0ul; } + Queue(Platform::Connection & platform, + uint32_t max_entries, + size_t len) + : + Dma_buffer(platform, len * max_entries, UNCACHED), + len(len), max_entries(max_entries) {}; }; @@ -416,9 +420,11 @@ struct Nvme::Sq : Nvme::Queue uint32_t tail { 0 }; uint16_t id { 0 }; + using Queue::Queue; + addr_t next() { - addr_t a = va + (tail * SQE_LEN); + addr_t a = (addr_t)local_addr() + (tail * SQE_LEN); Genode::memset((void*)a, 0, SQE_LEN); tail = (tail + 1) % max_entries; return a; @@ -434,7 +440,9 @@ struct Nvme::Cq : Nvme::Queue uint32_t head { 0 }; uint32_t phase { 1 }; - addr_t next() { return va + (head * CQE_LEN); } + using Queue::Queue; + + addr_t next() { return (addr_t)local_addr() + (head * CQE_LEN); } void advance_head() { @@ -449,9 +457,12 @@ struct Nvme::Cq : Nvme::Queue /* * Controller */ -struct Nvme::Controller : public Genode::Attached_dataspace, - public Genode::Mmio +class Nvme::Controller : Platform::Device, + Platform::Device::Mmio, + Platform::Device::Irq { + public: + /********** ** MMIO ** **********/ @@ -641,39 +652,51 @@ struct Nvme::Controller : public Genode::Attached_dataspace, struct Cqh : Bitfield< 0, 16> { }; /* completion queue tail */ }; + struct Initialization_failed : Genode::Exception { }; + + struct Info + { + Genode::String<8> version { }; + Identify_data::Sn sn { }; + Identify_data::Mn mn { }; + Identify_data::Fr fr { }; + size_t mdts { }; + }; + + struct Nsinfo + { + Block::sector_t count { 0 }; + size_t size { 0 }; + Block::sector_t max_request_count { 0 }; + bool valid() const { return count && size; } + }; + + private: + /********** ** CODE ** **********/ - struct Mem_address - { - addr_t va { 0 }; - addr_t pa { 0 }; - }; - - struct Initialization_failed : Genode::Exception { }; - - Genode::Env &_env; - - Util::Dma_allocator &_dma_alloc; - Mmio::Delayer &_delayer; + Genode::Env &_env; + Platform::Connection &_platform; + Mmio::Delayer &_delayer; /* * There is a completion and submission queue for * every namespace and one pair for the admin queues. */ - Nvme::Cq _cq[NUM_QUEUES] { }; - Nvme::Sq _sq[NUM_QUEUES] { }; + Constructible _cq[NUM_QUEUES] { }; + Constructible _sq[NUM_QUEUES] { }; - Nvme::Cq &_admin_cq = _cq[0]; - Nvme::Sq &_admin_sq = _sq[0]; + Constructible &_admin_cq = _cq[0]; + Constructible &_admin_sq = _sq[0]; - Mem_address _nvme_identify { }; + Platform::Dma_buffer _nvme_identify { _platform, IDENTIFY_LEN, UNCACHED }; Genode::Constructible _identify_data { }; - Mem_address _nvme_nslist { }; - uint32_t _nvme_nslist_count { 0 }; + Platform::Dma_buffer _nvme_nslist { _platform, IDENTIFY_LEN, UNCACHED }; + uint32_t _nvme_nslist_count { 0 }; size_t _mdts_bytes { 0 }; @@ -696,27 +719,10 @@ struct Nvme::Controller : public Genode::Attached_dataspace, CREATE_IO_SQ_CID, }; - Mem_address _nvme_query_ns[MAX_NS] { }; - - struct Info - { - Genode::String<8> version { }; - Identify_data::Sn sn { }; - Identify_data::Mn mn { }; - Identify_data::Fr fr { }; - size_t mdts { }; - }; + Constructible _nvme_query_ns[MAX_NS] { }; Info _info { }; - struct Nsinfo - { - Block::sector_t count { 0 }; - size_t size { 0 }; - Block::sector_t max_request_count { 0 }; - bool valid() const { return count && size; } - }; - /* create larger array to use namespace id to as index */ Nsinfo _nsinfo[MAX_NS+1] { }; @@ -772,22 +778,6 @@ struct Nvme::Controller : public Genode::Attached_dataspace, write(SQE_LEN_LOG2); } - /** - * Setup queue, i.e., fill out fields - * - * \param q reference to queue - * \param num number of entries - * \param len size of one entry - */ - void _setup_queue(Queue &q, size_t const num, size_t const len) - { - size_t const size = num * len; - q.ds = _dma_alloc.alloc(size); - q.pa = _dma_alloc.dma_addr(q.ds); - q.va = (addr_t)_env.rm().attach(q.ds); - q.max_entries = num; - } - /** * Check if given queue tuple is full * @@ -806,13 +796,13 @@ struct Nvme::Controller : public Genode::Attached_dataspace, */ void _setup_admin() { - _setup_queue(_admin_cq, MAX_ADMIN_ENTRIES, CQE_LEN); + _admin_cq.construct(_platform, MAX_ADMIN_ENTRIES, CQE_LEN); write(MAX_ADMIN_ENTRIES_MASK); - write(_admin_cq.pa); + write(_admin_cq->dma_addr()); - _setup_queue(_admin_sq, MAX_ADMIN_ENTRIES, SQE_LEN); + _admin_sq.construct(_platform, MAX_ADMIN_ENTRIES, SQE_LEN); write(MAX_ADMIN_ENTRIES_MASK); - write(_admin_sq.pa); + write(_admin_sq->dma_addr()); } /** @@ -827,9 +817,9 @@ struct Nvme::Controller : public Genode::Attached_dataspace, */ addr_t _admin_command(Opcode opc, uint32_t nsid, uint32_t cid) { - if (_queue_full(_admin_sq, _admin_cq)) { return 0ul; } + if (_queue_full(*_admin_sq, *_admin_cq)) { return 0ul; } - Sqe b(_admin_sq.next()); + Sqe b(_admin_sq->next()); b.write(opc); b.write(cid); b.write(nsid); @@ -852,17 +842,17 @@ struct Nvme::Controller : public Genode::Attached_dataspace, for (uint32_t i = 0; i < num; i++) { _delayer.usleep(100 * 1000); - Cqe b(_admin_cq.next()); + Cqe b(_admin_cq->next()); if (b.read() != cid) { continue; } - _admin_cq.advance_head(); + _admin_cq->advance_head(); success = true; - write(_admin_cq.head); + write(_admin_cq->head); break; } @@ -874,14 +864,7 @@ struct Nvme::Controller : public Genode::Attached_dataspace, */ void _query_nslist() { - if (!_nvme_nslist.va) { - Ram_dataspace_capability ds = _dma_alloc.alloc(IDENTIFY_LEN); - _nvme_nslist.va = (addr_t)_env.rm().attach(ds); - _nvme_nslist.pa = _dma_alloc.dma_addr(ds); - - } - - uint32_t *nslist = (uint32_t*)_nvme_nslist.va; + uint32_t *nslist = _nvme_nslist.local_addr(); bool const nsm = _identify_data->read(); if (!nsm) { @@ -892,10 +875,10 @@ struct Nvme::Controller : public Genode::Attached_dataspace, Sqe_identify b(_admin_command(Opcode::IDENTIFY, 0, NSLIST_CID)); - b.write(_nvme_nslist.pa); + b.write(_nvme_nslist.dma_addr()); b.write(Cns::NSLIST); - write(_admin_sq.tail); + write(_admin_sq->tail); if (!_wait_for_admin_cq(10, NSLIST_CID)) { error("identify name space list failed"); @@ -923,27 +906,24 @@ struct Nvme::Controller : public Genode::Attached_dataspace, if (max > 1) { warning("only the first name space is used"); } - uint32_t const *ns = (uint32_t const*)_nvme_nslist.va; + uint32_t const *ns = _nvme_nslist.local_addr(); uint16_t const id = 0; - if (!_nvme_query_ns[id].va) { - Ram_dataspace_capability ds = _dma_alloc.alloc(IDENTIFY_LEN); - _nvme_query_ns[id].va = (addr_t)_env.rm().attach(ds); - _nvme_query_ns[id].pa = _dma_alloc.dma_addr(ds); - } + if (!_nvme_query_ns[id].constructed()) + _nvme_query_ns[id].construct(_platform, IDENTIFY, UNCACHED); Sqe_identify b(_admin_command(Opcode::IDENTIFY, ns[id], QUERYNS_CID)); - b.write(_nvme_query_ns[id].pa); + b.write(_nvme_query_ns[id]->dma_addr()); b.write(Cns::IDENTIFY_NS); - write(_admin_sq.tail); + write(_admin_sq->tail); if (!_wait_for_admin_cq(10, QUERYNS_CID)) { error("identify name space failed"); throw Initialization_failed(); } - Identify_ns_data nsdata(_nvme_query_ns[id].va); + Identify_ns_data nsdata((addr_t)_nvme_query_ns[id]->local_addr()); uint32_t const flbas = nsdata.read(); /* use array subscription, omit first entry */ @@ -959,24 +939,18 @@ struct Nvme::Controller : public Genode::Attached_dataspace, */ void _identify() { - if (!_nvme_identify.va) { - Ram_dataspace_capability ds = _dma_alloc.alloc(IDENTIFY_LEN); - _nvme_identify.va = (addr_t)_env.rm().attach(ds); - _nvme_identify.pa = _dma_alloc.dma_addr(ds); - } - Sqe_identify b(_admin_command(Opcode::IDENTIFY, 0, IDENTIFY_CID)); - b.write(_nvme_identify.pa); + b.write(_nvme_identify.dma_addr()); b.write(Cns::IDENTIFY); - write(_admin_sq.tail); + write(_admin_sq->tail); if (!_wait_for_admin_cq(10, IDENTIFY_CID)) { error("identify failed"); throw Initialization_failed(); } - _identify_data.construct(_nvme_identify.va); + _identify_data.construct((addr_t)_nvme_identify.local_addr()); /* store information */ _info.version = Genode::String<8>(read(), ".", @@ -1008,17 +982,19 @@ struct Nvme::Controller : public Genode::Attached_dataspace, */ void _setup_io_cq(uint16_t id) { - Nvme::Cq &cq = _cq[id]; - if (!cq.valid()) { _setup_queue(cq, _max_io_entries, CQE_LEN); } + if (!_cq[id].constructed()) + _cq[id].construct(_platform, _max_io_entries, CQE_LEN); + + Nvme::Cq &cq = *_cq[id]; Sqe_create_cq b(_admin_command(Opcode::CREATE_IO_CQ, 0, CREATE_IO_CQ_CID)); - b.write(cq.pa); + b.write(cq.dma_addr()); b.write(id); b.write(_max_io_entries_mask); b.write(1); b.write(1); - write(_admin_sq.tail); + write(_admin_sq->tail); if (!_wait_for_admin_cq(10, CREATE_IO_CQ_CID)) { error("create I/O cq failed"); @@ -1036,18 +1012,20 @@ struct Nvme::Controller : public Genode::Attached_dataspace, */ void _setup_io_sq(uint16_t id, uint16_t cqid) { - Nvme::Sq &sq = _sq[id]; - if (!sq.valid()) { _setup_queue(sq, _max_io_entries, SQE_LEN); } + if (!_sq[id].constructed()) + _sq[id].construct(_platform, _max_io_entries, SQE_LEN); + + Nvme::Sq &sq = *_sq[id]; Sqe_create_sq b(_admin_command(Opcode::CREATE_IO_SQ, 0, CREATE_IO_SQ_CID)); - b.write(sq.pa); + b.write(sq.dma_addr()); b.write(id); b.write(_max_io_entries_mask); b.write(1); b.write(0b00); /* urgent for now */ b.write(cqid); - write(_admin_sq.tail); + write(_admin_sq->tail); if (!_wait_for_admin_cq(10, CREATE_IO_SQ_CID)) { error("create I/O sq failed"); @@ -1055,17 +1033,23 @@ struct Nvme::Controller : public Genode::Attached_dataspace, } } + public: + /** * Constructor */ - Controller(Genode::Env &env, Util::Dma_allocator &dma_alloc, - Genode::Io_mem_dataspace_capability ds_cap, - Mmio::Delayer &delayer) + Controller(Genode::Env &env, + Platform::Connection &platform, + Mmio::Delayer &delayer, + Signal_context_capability irq_sigh) : - Genode::Attached_dataspace(env.rm(), ds_cap), - Genode::Mmio((addr_t)local_addr()), - _env(env), _dma_alloc(dma_alloc), _delayer(delayer) - { } + Platform::Device(platform), + Platform::Device::Mmio((Platform::Device&)*this), + Platform::Device::Irq((Platform::Device&)*this), + _env(env), _platform(platform), _delayer(delayer) + { + sigh(irq_sigh); + } /** * Initialize controller @@ -1086,6 +1070,8 @@ struct Nvme::Controller : public Genode::Attached_dataspace, } throw Initialization_failed(); } + + clear_intr(); } /** @@ -1096,7 +1082,11 @@ struct Nvme::Controller : public Genode::Attached_dataspace, /** * Clean interrupts */ - void clear_intr() { write(1); } + void clear_intr() + { + write(1); + ack(); + } /* * Identify NVM system @@ -1126,7 +1116,7 @@ struct Nvme::Controller : public Genode::Attached_dataspace, */ addr_t io_command(uint16_t nsid, uint16_t cid) { - Nvme::Sq &sq = _sq[nsid]; + Nvme::Sq &sq = *_sq[nsid]; Sqe e(sq.next()); e.write(cid); @@ -1143,8 +1133,8 @@ struct Nvme::Controller : public Genode::Attached_dataspace, */ bool io_queue_full(uint16_t nsid) const { - Nvme::Sq const &sq = _sq[nsid]; - Nvme::Cq const &cq = _cq[nsid]; + Nvme::Sq const &sq = *_sq[nsid]; + Nvme::Cq const &cq = *_cq[nsid]; return _queue_full(sq, cq); } @@ -1155,7 +1145,7 @@ struct Nvme::Controller : public Genode::Attached_dataspace, */ void commit_io(uint16_t nsid) { - Nvme::Sq &sq = _sq[nsid]; + Nvme::Sq &sq = *_sq[nsid]; write(sq.tail); } @@ -1168,9 +1158,10 @@ struct Nvme::Controller : public Genode::Attached_dataspace, template void handle_io_completion(uint16_t nsid, FUNC const &func) { - Nvme::Cq &cq = _cq[nsid]; + if (!_cq[nsid].constructed()) + return; - if (!cq.valid()) { return; } + Nvme::Cq &cq = *_cq[nsid]; do { Cqe e(cq.next()); @@ -1196,7 +1187,7 @@ struct Nvme::Controller : public Genode::Attached_dataspace, */ void ack_io_completions(uint16_t nsid) { - Nvme::Cq &cq = _cq[nsid]; + Nvme::Cq &cq = *_cq[nsid]; write(cq.head); } @@ -1273,7 +1264,7 @@ struct Nvme::Controller : public Genode::Attached_dataspace, void dump_nslist() { - uint32_t const *p = (uint32_t const*)_nvme_nslist.va; + uint32_t const *p = _nvme_nslist.local_addr(); if (!p) { return; } for (size_t i = 0; i < 1024; i++) { @@ -1334,8 +1325,8 @@ class Nvme::Driver : Genode::Noncopyable Driver(const Driver&) = delete; Driver& operator=(const Driver&) = delete; - Genode::Env &_env; - Genode::Allocator &_alloc; + Genode::Env &_env; + Platform::Connection _platform { _env }; Genode::Attached_rom_dataspace &_config_rom; @@ -1366,12 +1357,12 @@ class Nvme::Driver : Genode::Noncopyable { try { Genode::Reporter::Xml_generator xml(_namespace_reporter, [&]() { - Nvme::Controller::Info const &info = _nvme_ctrlr->info(); + Nvme::Controller::Info const &info = _nvme_ctrlr.info(); xml.attribute("serial", info.sn); xml.attribute("model", info.mn); - Nvme::Controller::Nsinfo ns = _nvme_ctrlr->nsinfo(Nvme::IO_NSID); + Nvme::Controller::Nsinfo ns = _nvme_ctrlr.nsinfo(Nvme::IO_NSID); xml.node("namespace", [&]() { xml.attribute("id", (uint16_t)Nvme::IO_NSID); @@ -1386,43 +1377,14 @@ class Nvme::Driver : Genode::Noncopyable ** DMA ** *********/ - addr_t _dma_base { 0 }; - - Genode::Constructible _nvme_pci { }; + Constructible _dma_buffer { }; /* * The PRP (Physical Region Pages) page is used to setup * large requests. */ - - struct Prp_list_helper - { - struct Page - { - addr_t pa; - addr_t va; - }; - - Genode::Ram_dataspace_capability _ds; - addr_t _phys_addr; - addr_t _virt_addr; - - Prp_list_helper(Genode::Ram_dataspace_capability ds, - addr_t phys, addr_t virt) - : _ds(ds), _phys_addr(phys), _virt_addr(virt) { } - - Genode::Ram_dataspace_capability dataspace() { return _ds; } - - Page page(uint16_t cid) - { - addr_t const offset = cid * Nvme::MPS; - - return Page { .pa = offset + _phys_addr, - .va = offset + _virt_addr }; - } - }; - - Genode::Constructible _prp_list_helper { }; + Platform::Dma_buffer _prp_list_helper { _platform, Nvme::PRP_DS_SIZE, + UNCACHED }; /************** ** Requests ** @@ -1473,7 +1435,7 @@ class Nvme::Driver : Genode::Noncopyable template bool _for_any_request(FUNC const &func) const { - for (uint16_t i = 0; i < _nvme_ctrlr->max_io_entries(); i++) { + for (uint16_t i = 0; i < _nvme_ctrlr.max_io_entries(); i++) { if (_command_id_allocator.used(i) && func(_requests[i])) { return true; } @@ -1497,7 +1459,8 @@ class Nvme::Driver : Genode::Noncopyable void usleep(uint64_t us) override { Timer::Connection::usleep(us); } } _delayer { _env }; - Genode::Constructible _nvme_ctrlr { }; + Signal_context_capability _irq_sigh; + Nvme::Controller _nvme_ctrlr { _env, _platform, _delayer, _irq_sigh }; /*********** ** Block ** @@ -1511,10 +1474,10 @@ class Nvme::Driver : Genode::Noncopyable * Constructor */ Driver(Genode::Env &env, - Genode::Allocator &alloc, Genode::Attached_rom_dataspace &config_rom, Genode::Signal_context_capability request_sigh) - : _env(env), _alloc(alloc), _config_rom(config_rom) + : _env(env), + _config_rom(config_rom), _irq_sigh(request_sigh) { _config_rom.sigh(_config_sigh); _handle_config_update(); @@ -1523,61 +1486,37 @@ class Nvme::Driver : Genode::Noncopyable * Setup and identify NVMe PCI controller */ - try { - _nvme_pci.construct(_env); - } catch (Nvme::Pci::Missing_controller) { - error("no NVMe PCIe controller found"); - throw; - } + if (_verbose_regs) { _nvme_ctrlr.dump_cap(); } - try { - _nvme_ctrlr.construct(_env, *_nvme_pci, _nvme_pci->io_mem_ds(), - _delayer); - } catch (...) { - error("could not access NVMe controller MMIO"); - throw; - } - - if (_verbose_regs) { _nvme_ctrlr->dump_cap(); } - - _nvme_ctrlr->init(); - _nvme_ctrlr->identify(); + _nvme_ctrlr.init(); + _nvme_ctrlr.identify(); if (_verbose_identify) { - _nvme_ctrlr->dump_identify(); - _nvme_ctrlr->dump_nslist(); + _nvme_ctrlr.dump_identify(); + _nvme_ctrlr.dump_nslist(); } /* * Setup I/O */ - { - Genode::Ram_dataspace_capability ds = _nvme_pci->alloc(Nvme::PRP_DS_SIZE); - if (!ds.valid()) { - error("could not allocate DMA backing store"); - throw Nvme::Controller::Initialization_failed(); - } - addr_t const phys_addr = _nvme_pci->dma_addr(ds); - addr_t const virt_addr = (addr_t)_env.rm().attach(ds); - _prp_list_helper.construct(ds, phys_addr, virt_addr); - - if (_verbose_mem) { - log("DMA", " virt: [", Hex(virt_addr), ",", - Hex(virt_addr + Nvme::PRP_DS_SIZE), "]", - " phys: [", Hex(phys_addr), ",", - Hex(phys_addr + Nvme::PRP_DS_SIZE), "]"); - } + if (_verbose_mem) { + addr_t virt_addr = (addr_t)_prp_list_helper.local_addr(); + addr_t phys_addr = _prp_list_helper.dma_addr(); + log("DMA", " virt: [", Hex(virt_addr), ",", + Hex(virt_addr + Nvme::PRP_DS_SIZE), "]", + " phys: [", Hex(phys_addr), ",", + Hex(phys_addr + Nvme::PRP_DS_SIZE), "]"); } - _nvme_ctrlr->setup_io(Nvme::IO_NSID, Nvme::IO_NSID); + _nvme_ctrlr.setup_io(Nvme::IO_NSID, Nvme::IO_NSID); /* * Setup Block session */ /* set Block session properties */ - Nvme::Controller::Nsinfo nsinfo = _nvme_ctrlr->nsinfo(Nvme::IO_NSID); + Nvme::Controller::Nsinfo nsinfo = _nvme_ctrlr.nsinfo(Nvme::IO_NSID); if (!nsinfo.valid()) { error("could not query namespace information"); throw Nvme::Controller::Initialization_failed(); @@ -1588,7 +1527,7 @@ class Nvme::Driver : Genode::Noncopyable .align_log2 = Nvme::MPS_LOG2, .writeable = false }; - Nvme::Controller::Info const &info = _nvme_ctrlr->info(); + Nvme::Controller::Info const &info = _nvme_ctrlr.info(); log("NVMe:", info.version.string(), " " "serial:'", info.sn.string(), "'", " " @@ -1598,7 +1537,7 @@ class Nvme::Driver : Genode::Noncopyable log("Block", " " "size: ", _info.block_size, " " "count: ", _info.block_count, " " - "I/O entries: ", _nvme_ctrlr->max_io_entries()); + "I/O entries: ", _nvme_ctrlr.max_io_entries()); /* generate Report if requested */ try { @@ -1608,29 +1547,12 @@ class Nvme::Driver : Genode::Noncopyable _report_namespaces(); } } catch (...) { } - - _nvme_pci->sigh_irq(request_sigh); - _nvme_ctrlr->clear_intr(); - _nvme_pci->ack_irq(); } ~Driver() { /* free resources */ } Block::Session::Info info() const { return _info; } - Genode::Ram_dataspace_capability dma_alloc(size_t size) - { - Genode::Ram_dataspace_capability cap = _nvme_pci->alloc(size); - _dma_base = _nvme_pci->dma_addr(cap); - return cap; - } - - void dma_free(Genode::Ram_dataspace_capability cap) - { - _dma_base = 0; - _nvme_pci->free(cap); - } - void writeable(bool writeable) { _info.writeable = writeable; } @@ -1645,7 +1567,7 @@ class Nvme::Driver : Genode::Noncopyable * MAX_IO_ENTRIES requests, so it is safe to only check the * I/O queue. */ - if (_nvme_ctrlr->io_queue_full(Nvme::IO_NSID)) { + if (_nvme_ctrlr.io_queue_full(Nvme::IO_NSID)) { return Response::RETRY; } @@ -1670,8 +1592,8 @@ class Nvme::Driver : Genode::Noncopyable case Block::Operation::Type::READ: /* limit request to what we can handle, needed for overlap check */ - if (request.operation.count > _nvme_ctrlr->max_count(Nvme::IO_NSID)) { - request.operation.count = _nvme_ctrlr->max_count(Nvme::IO_NSID); + if (request.operation.count > _nvme_ctrlr.max_count(Nvme::IO_NSID)) { + request.operation.count = _nvme_ctrlr.max_count(Nvme::IO_NSID); } } @@ -1704,12 +1626,15 @@ class Nvme::Driver : Genode::Noncopyable void _submit(Block::Request request) { + if (!_dma_buffer.constructed()) + return; + bool const write = request.operation.type == Block::Operation::Type::WRITE; /* limit request to what we can handle */ - if (request.operation.count > _nvme_ctrlr->max_count(Nvme::IO_NSID)) { - request.operation.count = _nvme_ctrlr->max_count(Nvme::IO_NSID); + if (request.operation.count > _nvme_ctrlr.max_count(Nvme::IO_NSID)) { + request.operation.count = _nvme_ctrlr.max_count(Nvme::IO_NSID); } size_t const count = request.operation.count; @@ -1717,7 +1642,7 @@ class Nvme::Driver : Genode::Noncopyable size_t const len = request.operation.count * _info.block_size; bool const need_list = len > 2 * Nvme::MPS; - addr_t const request_pa = _dma_base + request.offset; + addr_t const request_pa = _dma_buffer->dma_addr() + request.offset; if (_verbose_io) { log("Submit: ", write ? "WRITE" : "READ", @@ -1725,7 +1650,7 @@ class Nvme::Driver : Genode::Noncopyable " need_list: ", need_list, " block count: ", count, " lba: ", lba, - " dma_base: ", Hex(_dma_base), + " dma_base: ", Hex(_dma_buffer->dma_addr()), " offset: ", Hex(request.offset)); } @@ -1735,7 +1660,7 @@ class Nvme::Driver : Genode::Noncopyable r = Request { .block_request = request, .id = id }; - Nvme::Sqe_io b(_nvme_ctrlr->io_command(Nvme::IO_NSID, cid)); + Nvme::Sqe_io b(_nvme_ctrlr.io_command(Nvme::IO_NSID, cid)); Nvme::Opcode const op = write ? Nvme::Opcode::WRITE : Nvme::Opcode::READ; b.write(op); b.write(request_pa); @@ -1746,18 +1671,21 @@ class Nvme::Driver : Genode::Noncopyable } else if (need_list) { /* get page to store list of mps chunks */ - Prp_list_helper::Page page = _prp_list_helper->page(cid); + addr_t const offset = cid * Nvme::MPS; + addr_t pa = _prp_list_helper.dma_addr() + offset; + addr_t va = (addr_t)_prp_list_helper.local_addr() + + offset; /* omit first page and write remaining pages to iob */ addr_t npa = request_pa + Nvme::MPS; using Page_entry = uint64_t; - Page_entry *pe = (Page_entry*)page.va; + Page_entry *pe = (Page_entry*)va; size_t const mps_len = Genode::align_addr(len, Nvme::MPS_LOG2); size_t const num = (mps_len - Nvme::MPS) / Nvme::MPS; if (_verbose_io) { - log(" page.va: ", Hex(page.va), " page.pa: ", - Hex(page.pa), " num: ", num); + log(" page.va: ", Hex(va), " page.pa: ", + Hex(pa), " num: ", num); } for (size_t i = 0; i < num; i++) { @@ -1767,7 +1695,7 @@ class Nvme::Driver : Genode::Noncopyable pe[i] = npa; npa += Nvme::MPS; } - b.write(page.pa); + b.write(pa); } b.write(lba); @@ -1782,7 +1710,7 @@ class Nvme::Driver : Genode::Noncopyable r = Request { .block_request = request, .id = id }; - Nvme::Sqe_io b(_nvme_ctrlr->io_command(Nvme::IO_NSID, cid)); + Nvme::Sqe_io b(_nvme_ctrlr.io_command(Nvme::IO_NSID, cid)); b.write(Nvme::Opcode::FLUSH); } @@ -1797,7 +1725,7 @@ class Nvme::Driver : Genode::Noncopyable size_t const count = request.operation.count; Block::sector_t const lba = request.operation.block_number; - Nvme::Sqe_io b(_nvme_ctrlr->io_command(Nvme::IO_NSID, cid)); + Nvme::Sqe_io b(_nvme_ctrlr.io_command(Nvme::IO_NSID, cid)); b.write(Nvme::Opcode::WRITE_ZEROS); b.write(lba); @@ -1812,7 +1740,7 @@ class Nvme::Driver : Genode::Noncopyable void _get_completed_request(Block::Request &out, uint16_t &out_cid) { - _nvme_ctrlr->handle_io_completion(Nvme::IO_NSID, [&] (Nvme::Cqe const &b) { + _nvme_ctrlr.handle_io_completion(Nvme::IO_NSID, [&] (Nvme::Cqe const &b) { if (_verbose_io) { Nvme::Cqe::dump(b); } @@ -1872,20 +1800,19 @@ class Nvme::Driver : Genode::Noncopyable void mask_irq() { - _nvme_ctrlr->mask_intr(); + _nvme_ctrlr.mask_intr(); } void ack_irq() { - _nvme_ctrlr->clear_intr(); - _nvme_pci->ack_irq(); + _nvme_ctrlr.clear_intr(); } bool execute() { if (!_submits_pending) { return false; } - _nvme_ctrlr->commit_io(Nvme::IO_NSID); + _nvme_ctrlr.commit_io(Nvme::IO_NSID); _submits_pending = false; return true; } @@ -1908,9 +1835,17 @@ class Nvme::Driver : Genode::Noncopyable { if (!_completed_pending) { return; } - _nvme_ctrlr->ack_io_completions(Nvme::IO_NSID); + _nvme_ctrlr.ack_io_completions(Nvme::IO_NSID); _completed_pending = false; } + + Dataspace_capability dma_buffer_construct(size_t size) + { + _dma_buffer.construct(_platform, size, UNCACHED); + return _dma_buffer->cap(); + } + + void dma_buffer_destruct() { _dma_buffer.destruct(); } }; @@ -1920,28 +1855,28 @@ class Nvme::Driver : Genode::Noncopyable struct Nvme::Main : Rpc_object> { - Genode::Env &_env; - Genode::Heap _heap { _env.ram(), _env.rm() }; + Genode::Env &_env; Genode::Attached_rom_dataspace _config_rom { _env, "config" }; Genode::Ram_dataspace_capability _block_ds_cap { }; Constructible _block_session { }; - Constructible _driver { }; Signal_handler
_request_handler { _env.ep(), *this, &Main::_handle_requests }; Signal_handler
_irq_handler { _env.ep(), *this, &Main::_handle_irq }; + Nvme::Driver _driver { _env, _config_rom, _irq_handler }; + void _handle_irq() { - _driver->mask_irq(); + _driver.mask_irq(); _handle_requests(); - _driver->ack_irq(); + _driver.ack_irq(); } void _handle_requests() { - if (!_block_session.constructed() || !_driver.constructed()) + if (!_block_session.constructed()) return; Block_session_component &block_session = *_block_session; @@ -1953,11 +1888,11 @@ struct Nvme::Main : Rpc_object> /* import new requests */ block_session.with_requests([&] (Block::Request request) { - Response response = _driver->acceptable(request); + Response response = _driver.acceptable(request); switch (response) { case Response::ACCEPTED: - _driver->submit(request); + _driver.submit(request); [[fallthrough]]; case Response::REJECTED: progress = true; @@ -1970,12 +1905,12 @@ struct Nvme::Main : Rpc_object> }); /* process I/O */ - progress |= _driver->execute(); + progress |= _driver.execute(); /* acknowledge finished jobs */ block_session.try_acknowledge([&] (Block_session_component::Ack &ack) { - _driver->with_any_completed_job([&] (Block::Request request) { + _driver.with_any_completed_job([&] (Block::Request request) { ack.submit(request); progress = true; @@ -1983,7 +1918,7 @@ struct Nvme::Main : Rpc_object> }); /* defered acknowledge on the controller */ - _driver->acknowledge_if_completed(); + _driver.acknowledge_if_completed(); if (!progress) { break; } } @@ -2013,11 +1948,10 @@ struct Nvme::Main : Rpc_object> } bool const writeable = policy.attribute_value("writeable", false); - _driver->writeable(writeable); + _driver.writeable(writeable); - _block_ds_cap = _driver->dma_alloc(tx_buf_size); - _block_session.construct(_env, _block_ds_cap, _request_handler, - _driver->info()); + _block_session.construct(_env, _driver.dma_buffer_construct(tx_buf_size), + _request_handler, _driver.info()); return _block_session->cap(); } @@ -2030,15 +1964,11 @@ struct Nvme::Main : Rpc_object> * XXX a malicious client could submit all its requests * and close the session... */ - _driver->dma_free(_block_ds_cap); + _driver.dma_buffer_destruct(); } - Main(Genode::Env &env) : _env(env) - { - _driver.construct(_env, _heap, _config_rom, _irq_handler); - - _env.parent().announce(_env.ep().manage(*this)); - } + Main(Genode::Env &env) : _env(env) { + _env.parent().announce(_env.ep().manage(*this)); } }; diff --git a/repos/os/src/drivers/nvme/pci.h b/repos/os/src/drivers/nvme/pci.h deleted file mode 100644 index f3e2c6211c..0000000000 --- a/repos/os/src/drivers/nvme/pci.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * \brief NVMe PCIe backend - * \author Josef Soentgen - * \date 2018-03-05 - */ - -/* - * Copyright (C) 2018 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 _NVME_PCI_H_ -#define _NVME_PCI_H_ - -/* Genode includes */ -#include -#include -#include - - -namespace Nvme { - - using namespace Genode; - - struct Pci; -} - - -struct Nvme::Pci : Platform::Connection, - Util::Dma_allocator -{ - struct Missing_controller : Genode::Exception { }; - - enum { - CLASS_MASS_STORAGE = 0x010000u, - CLASS_MASK = 0xffff00u, - SUBCLASS_NVME = 0x000800u, - NVME_DEVICE = CLASS_MASS_STORAGE | SUBCLASS_NVME, - NVME_PCI = 0x02, - NVME_BASE_ID = 0, - }; - - enum Pci_config { IRQ = 0x3c, CMD = 0x4, CMD_IO = 0x1, - CMD_MEMORY = 0x2, CMD_MASTER = 0x4 }; - - Platform::Device_capability _device_cap { }; - Genode::Constructible _device { }; - - Io_mem_session_capability _io_mem_cap { }; - Genode::Constructible _irq { }; - - /** - * Constructor - */ - Pci(Genode::Env &env) : Platform::Connection(env) - { - upgrade_ram(2*4096u); - upgrade_caps(8); - - _device_cap = with_upgrade([&] () { - return next_device(_device_cap, - NVME_DEVICE, CLASS_MASK); - }); - - if (!_device_cap.valid()) { throw Missing_controller(); } - - _device.construct(_device_cap); - - uint16_t cmd = _device->config_read(Pci_config::CMD, Platform::Device::ACCESS_16BIT); - cmd |= 0x2; /* respond to memory space accesses */ - cmd |= 0x4; /* enable bus master */ - - _device->config_write(Pci_config::CMD, cmd, Platform::Device::ACCESS_16BIT); - - _io_mem_cap = _device->io_mem(_device->phys_bar_to_virt(NVME_BASE_ID)); - _irq.construct(_device->irq(0)); - - Genode::log("NVMe PCIe controller found (", - Genode::Hex(_device->vendor_id()), ":", - Genode::Hex(_device->device_id()), ")"); - } - - /** - * Return base address of controller MMIO region - */ - Io_mem_dataspace_capability io_mem_ds() const { - return Io_mem_session_client(_io_mem_cap).dataspace(); } - - /** - * Set interrupt signal handler - * - * \parm sigh signal capability - */ - void sigh_irq(Genode::Signal_context_capability sigh) - { - _irq->sigh(sigh); - _irq->ack_irq(); - } - - /** - * Acknowledge interrupt - */ - void ack_irq() { _irq->ack_irq(); } - - /***************************** - ** Dma_allocator interface ** - *****************************/ - - /** - * Allocator DMA buffer - * - * \param size size of the buffer - * - * \return Ram_dataspace_capability - */ - Genode::Ram_dataspace_capability alloc(size_t size) override - { - size_t donate = size; - return retry( - [&] () { - return retry( - [&] () { return Pci::Connection::alloc_dma_buffer(size, UNCACHED); }, - [&] () { upgrade_caps(2); }); - }, - [&] () { - upgrade_ram(donate); - donate = donate * 2 > size ? 4096 : donate * 2; - }); - } - - /** - * Free DMA buffer - * - * \param cap RAM dataspace capability - */ - void free(Genode::Ram_dataspace_capability cap) override - { - Pci::Connection::free_dma_buffer(cap); - } - - /** - * Return bus address of DMA buffer - * - * \param cap RAM dataspace capability - */ - addr_t dma_addr(Ram_dataspace_capability cap) override - { - return Pci::Connection::dma_addr(cap); - } -}; - -#endif /* _NVME_PCI_H_ */ diff --git a/repos/os/src/drivers/nvme/target.mk b/repos/os/src/drivers/nvme/target.mk index 4cb20fa13b..bdf35f06c0 100644 --- a/repos/os/src/drivers/nvme/target.mk +++ b/repos/os/src/drivers/nvme/target.mk @@ -2,6 +2,5 @@ TARGET = nvme_drv SRC_CC = main.cc INC_DIR += $(PRG_DIR) LIBS += base -REQUIRES = x86 CC_CXX_WARN_STRICT_CONVERSION = diff --git a/repos/os/src/drivers/platform/README b/repos/os/src/drivers/platform/README index 2b00642c61..bc3e8512dc 100644 --- a/repos/os/src/drivers/platform/README +++ b/repos/os/src/drivers/platform/README @@ -79,6 +79,23 @@ pair of identifiers inside a pci sub-node: ! ! +The following class names are supported which correspond to the +specified PCI base class (B), sub class (S) and programming interface +(P) combinations. ('-' matches all devices in the category) + +alias B S P + +AHCI 01 06 - +AUDIO 04 01 - +ETHERNET 02 00 - +HDAUDIO 04 03 - +ISABRIDGE 06 01 - +NVME 01 08 02 +USB 0c 03 00 10 20 30 +USB4 0c 03 40 +VGA 03 00 00 +WIFI 02 80 - + Report facilities ----------------- diff --git a/repos/os/src/drivers/platform/clock.h b/repos/os/src/drivers/platform/clock.h index 170d99fbfb..ed9296532c 100644 --- a/repos/os/src/drivers/platform/clock.h +++ b/repos/os/src/drivers/platform/clock.h @@ -60,6 +60,13 @@ class Driver::Clock : Clocks::Element, Interface void enable() { _switch.use(); } void disable() { _switch.unuse(); } + + struct Guard : Genode::Noncopyable + { + Clock &_clock; + Guard(Clock &clock) : _clock(clock) { _clock.enable(); } + ~Guard() { _clock.disable(); } + }; }; diff --git a/repos/os/src/drivers/platform/common.h b/repos/os/src/drivers/platform/common.h index 559a4de6e9..49adc6a7f4 100644 --- a/repos/os/src/drivers/platform/common.h +++ b/repos/os/src/drivers/platform/common.h @@ -24,7 +24,7 @@ class Driver::Common : Device_reporter Attached_rom_dataspace _devices_rom { _env, _rom_name.string() }; Heap _heap { _env.ram(), _env.rm() }; Sliced_heap _sliced_heap { _env.ram(), _env.rm() }; - Device_model _devices { _heap, *this }; + Device_model _devices { _env, _heap, *this }; Signal_handler _dev_handler { _env.ep(), *this, &Common::_handle_devices }; Driver::Root _root; diff --git a/repos/os/src/drivers/platform/device.cc b/repos/os/src/drivers/platform/device.cc index 27962a06cf..082d0d8a4b 100644 --- a/repos/os/src/drivers/platform/device.cc +++ b/repos/os/src/drivers/platform/device.cc @@ -11,6 +11,8 @@ * under the terms of the GNU Affero General Public License version 3. */ +#include + #include #include #include @@ -79,7 +81,7 @@ void Driver::Device::acquire(Session_component & sc) } }); - pci_enable(sc.env(), sc.device_pd(), *this); + pci_enable(_env, sc.device_pd(), *this); sc.update_devices_rom(); _model.device_status_changed(); } @@ -90,7 +92,7 @@ void Driver::Device::release(Session_component & sc) if (!(_owner == sc)) return; - pci_disable(sc.env(), *this); + pci_disable(_env, *this); _reset_domain_list.for_each([&] (Reset_domain & r) { @@ -124,6 +126,8 @@ void Driver::Device::generate(Xml_generator & xml, bool info) const xml.attribute("used", _owner.valid()); _io_mem_list.for_each([&] (Io_mem const & io_mem) { xml.node("io_mem", [&] () { + if (io_mem.bar.valid()) + xml.attribute("pci_bar", io_mem.bar.number); if (!info) return; xml.attribute("phys_addr", String<16>(Hex(io_mem.range.start))); @@ -135,14 +139,17 @@ void Driver::Device::generate(Xml_generator & xml, bool info) const if (!info) return; xml.attribute("number", irq.number); + if (irq.shared) xml.attribute("shared", true); }); }); - _io_port_range_list.for_each([&] (Io_port_range const & io_port_range) { + _io_port_range_list.for_each([&] (Io_port_range const & iop) { xml.node("io_port_range", [&] () { + if (iop.bar.valid()) + xml.attribute("pci_bar", iop.bar.number); if (!info) return; - xml.attribute("phys_addr", String<16>(Hex(io_port_range.addr))); - xml.attribute("size", String<16>(Hex(io_port_range.size))); + xml.attribute("phys_addr", String<16>(Hex(iop.range.addr))); + xml.attribute("size", String<16>(Hex(iop.range.size))); }); }); _property_list.for_each([&] (Property const & p) { @@ -164,14 +171,18 @@ void Driver::Device::generate(Xml_generator & xml, bool info) const xml.attribute("vendor_id", String<16>(Hex(pci.vendor_id))); xml.attribute("device_id", String<16>(Hex(pci.device_id))); xml.attribute("class", String<16>(Hex(pci.class_code))); + xml.attribute("revision", String<16>(Hex(pci.revision))); + xml.attribute("sub_vendor_id", String<16>(Hex(pci.sub_vendor_id))); + xml.attribute("sub_device_id", String<16>(Hex(pci.sub_device_id))); + pci_device_specific_info(*this, _env, _model, xml); }); }); }); } -Driver::Device::Device(Device_model & model, Name name, Type type) -: _model(model), _name(name), _type(type) { } +Driver::Device::Device(Env & env, Device_model & model, Name name, Type type) +: _env(env), _model(model), _name(name), _type(type) { } Driver::Device::~Device() @@ -197,4 +208,57 @@ void Driver::Device_model::generate(Xml_generator & xml) const void Driver::Device_model::update(Xml_node const & node) { _model.update_from_xml(*this, node); + + /* + * Detect all shared interrupts + */ + enum { MAX_IRQ = 1024 }; + Bit_array detected_irqs, shared_irqs; + for_each([&] (Device const & device) { + device._irq_list.for_each([&] (Device::Irq const & irq) { + + if (irq.type != Device::Irq::LEGACY) + return; + + if (detected_irqs.get(irq.number, 1)) { + if (!shared_irqs.get(irq.number, 1)) + shared_irqs.set(irq.number, 1); + } else + detected_irqs.set(irq.number, 1); + }); + }); + + /* + * Mark all shared interrupts in the devices + */ + for_each([&] (Device & device) { + device._irq_list.for_each([&] (Device::Irq & irq) { + + if (irq.type != Device::Irq::LEGACY) + return; + + if (shared_irqs.get(irq.number, 1)) + irq.shared = true; + }); + }); + + /* + * Create shared interrupt objects + */ + for (unsigned i = 0; i < MAX_IRQ; i++) { + if (!shared_irqs.get(i, 1)) + continue; + bool found = false; + _shared_irqs.for_each([&] (Shared_interrupt & sirq) { + if (sirq.number() == i) found = true; }); + if (!found) + new (_heap) Shared_interrupt(_shared_irqs, _env, i); + } + + /* + * Iterate over all devices and apply PCI quirks if necessary + */ + for_each([&] (Device const & device) { + pci_apply_quirks(_env, device); + }); } diff --git a/repos/os/src/drivers/platform/device.h b/repos/os/src/drivers/platform/device.h index 828022311b..267c1d50f6 100644 --- a/repos/os/src/drivers/platform/device.h +++ b/repos/os/src/drivers/platform/device.h @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -44,6 +45,7 @@ namespace Driver { struct Reset_domain_update_policy; struct Power_domain_update_policy; struct Pci_config_update_policy; + struct Reserved_memory_update_policy; } @@ -53,7 +55,15 @@ class Driver::Device : private List_model::Element using Name = Genode::String<64>; using Type = Genode::String<64>; - using Range = Platform::Device_interface::Range; + + struct Pci_bar + { + enum { INVALID = 255 }; + + unsigned char number { INVALID }; + + bool valid() const { return number < INVALID; } + }; struct Owner { @@ -71,9 +81,14 @@ class Driver::Device : private List_model::Element struct Io_mem : List_model::Element { - Range range; + using Range = Platform::Device_interface::Range; - Io_mem(Range range) : range(range) {} + Pci_bar bar; + Range range; + bool prefetchable; + + Io_mem(Pci_bar bar, Range range, bool pf) + : bar(bar), range(range), prefetchable(pf) {} }; struct Irq : List_model::Element @@ -84,17 +99,20 @@ class Driver::Device : private List_model::Element Type type { LEGACY }; Irq_session::Polarity polarity { Irq_session::POLARITY_UNCHANGED }; Irq_session::Trigger mode { Irq_session::TRIGGER_UNCHANGED }; + bool shared { false }; Irq(unsigned number) : number(number) {} }; struct Io_port_range : List_model::Element { - uint16_t addr; - uint16_t size; + struct Range { uint16_t addr; uint16_t size; }; - Io_port_range(uint16_t addr, uint16_t size) - : addr(addr), size(size) {} + Pci_bar bar; + Range range; + + Io_port_range(Pci_bar bar, Range range) + : bar(bar), range(range) {} }; struct Property : List_model::Element @@ -153,6 +171,9 @@ class Driver::Device : private List_model::Element Pci::vendor_t vendor_id; Pci::device_t device_id; Pci::class_t class_code; + Pci::rev_t revision; + Pci::vendor_t sub_vendor_id; + Pci::device_t sub_device_id; bool bridge; Pci_config(addr_t addr, @@ -162,6 +183,9 @@ class Driver::Device : private List_model::Element Pci::vendor_t vendor_id, Pci::device_t device_id, Pci::class_t class_code, + Pci::rev_t revision, + Pci::vendor_t sub_vendor_id, + Pci::device_t sub_device_id, bool bridge) : addr(addr), @@ -171,10 +195,22 @@ class Driver::Device : private List_model::Element vendor_id(vendor_id), device_id(device_id), class_code(class_code), + revision(revision), + sub_vendor_id(sub_vendor_id), + sub_device_id(sub_device_id), bridge(bridge) {} }; - Device(Device_model & model, Name name, Type type); + struct Reserved_memory : List_model::Element + { + using Range = Platform::Device_interface::Range; + + Range range; + + Reserved_memory(Range range) : range(range) {} + }; + + Device(Env & env, Device_model & model, Name name, Type type); virtual ~Device(); Name name() const; @@ -188,21 +224,22 @@ class Driver::Device : private List_model::Element { unsigned idx = 0; _irq_list.for_each([&] (Irq const & irq) { - fn(idx++, irq.number, irq.type, irq.polarity, irq.mode); }); + fn(idx++, irq.number, irq.type, irq.polarity, + irq.mode, irq.shared); }); } template void for_each_io_mem(FN const & fn) const { unsigned idx = 0; _io_mem_list.for_each([&] (Io_mem const & iomem) { - fn(idx++, iomem.range); }); + fn(idx++, iomem.range, iomem.bar, iomem.prefetchable); }); } template void for_each_io_port_range(FN const & fn) const { unsigned idx = 0; _io_port_range_list.for_each([&] (Io_port_range const & ipr) { - fn(idx++, ipr.addr, ipr.size); }); + fn(idx++, ipr.range, ipr.bar); }); } template void for_pci_config(FN const & fn) const @@ -222,6 +259,14 @@ class Driver::Device : private List_model::Element }); } + template + void for_each_reserved_memory(FN const & fn) const + { + unsigned idx = 0; + _reserved_mem_list.for_each([&] (Reserved_memory const & mem) { + fn(idx++, mem.range); }); + } + void generate(Xml_generator &, bool) const; protected: @@ -230,18 +275,20 @@ class Driver::Device : private List_model::Element friend class List_model; friend class List; - Device_model & _model; - Name const _name; - Type const _type; - Owner _owner {}; - List_model _io_mem_list {}; - List_model _irq_list {}; - List_model _io_port_range_list {}; - List_model _property_list {}; - List_model _clock_list {}; - List_model _power_domain_list {}; - List_model _reset_domain_list {}; - List_model _pci_config_list {}; + Env & _env; + Device_model & _model; + Name const _name; + Type const _type; + Owner _owner {}; + List_model _io_mem_list {}; + List_model _irq_list {}; + List_model _io_port_range_list {}; + List_model _property_list {}; + List_model _clock_list {}; + List_model _power_domain_list {}; + List_model _reset_domain_list {}; + List_model _pci_config_list {}; + List_model _reserved_mem_list {}; /* * Noncopyable @@ -264,12 +311,14 @@ class Driver::Device_model : { private: - Heap & _heap; - Device_reporter & _reporter; - List_model _model { }; - Clocks _clocks { }; - Resets _resets { }; - Powers _powers { }; + Env & _env; + Heap & _heap; + Device_reporter & _reporter; + List_model _model { }; + Registry _shared_irqs { }; + Clocks _clocks { }; + Resets _resets { }; + Powers _powers { }; public: @@ -277,9 +326,10 @@ class Driver::Device_model : void update(Xml_node const & node); void device_status_changed(); - Device_model(Heap & heap, + Device_model(Env & env, + Heap & heap, Device_reporter & reporter) - : _heap(heap), _reporter(reporter) { } + : _env(env), _heap(heap), _reporter(reporter) { } ~Device_model() { _model.destroy_all_elements(*this); } @@ -290,6 +340,13 @@ class Driver::Device_model : template void for_each(FN const & fn) const { _model.for_each(fn); } + template + void with_shared_irq(unsigned number, FN const & fn) + { + _shared_irqs.for_each([&] (Shared_interrupt & sirq) { + if (sirq.number() == number) fn(sirq); }); + } + /*********************** ** Update_policy API ** @@ -360,6 +417,9 @@ struct Driver::Irq_update_policy : Genode::List_model::Update_polic struct Driver::Io_mem_update_policy : Genode::List_model::Update_policy { + using Range = Device::Io_mem::Range; + using Bar = Device::Pci_bar; + Genode::Allocator & alloc; Io_mem_update_policy(Genode::Allocator & alloc) : alloc(alloc) {} @@ -369,17 +429,19 @@ struct Driver::Io_mem_update_policy : Genode::List_model::Update Element & create_element(Genode::Xml_node node) { - Device::Range range { node.attribute_value("address", 0), - node.attribute_value("size", 0) }; - return *(new (alloc) Element(range)); + Bar bar { node.attribute_value("pci_bar", Bar::INVALID) }; + Range range { node.attribute_value("address", 0), + node.attribute_value("size", 0) }; + bool pf { node.attribute_value("prefetchable", false) }; + return *(new (alloc) Element(bar, range, pf)); } void update_element(Element &, Genode::Xml_node) {} static bool element_matches_xml_node(Element const & iomem, Genode::Xml_node node) { - Device::Range range { node.attribute_value("address", 0), - node.attribute_value("size", 0) }; + Range range { node.attribute_value("address", 0), + node.attribute_value("size", 0) }; return (range.start == iomem.range.start) && (range.size == iomem.range.size); } @@ -393,6 +455,9 @@ struct Driver::Io_mem_update_policy : Genode::List_model::Update struct Driver::Io_port_update_policy : Genode::List_model::Update_policy { + using Range = Device::Io_port_range::Range; + using Bar = Device::Pci_bar; + Genode::Allocator & alloc; Io_port_update_policy(Genode::Allocator & alloc) : alloc(alloc) {} @@ -402,18 +467,19 @@ struct Driver::Io_port_update_policy Element & create_element(Genode::Xml_node node) { - uint16_t addr = node.attribute_value("address", 0); - uint16_t size = node.attribute_value("size", 0); - return *(new (alloc) Element(addr, size)); + Bar bar { node.attribute_value("pci_bar", Bar::INVALID) }; + Range range { node.attribute_value("address", 0), + node.attribute_value("size", 0) }; + return *(new (alloc) Element(bar, range)); } void update_element(Element &, Genode::Xml_node) {} static bool element_matches_xml_node(Element const & ipr, Genode::Xml_node node) { - uint16_t addr = node.attribute_value("address", 0); - uint16_t size = node.attribute_value("size", 0); - return addr == ipr.addr && size == ipr.size; + Range range { node.attribute_value("address", 0), + node.attribute_value("size", 0) }; + return range.addr == ipr.range.addr && range.size == ipr.range.size; } static bool node_is_element(Genode::Xml_node node) @@ -573,10 +639,16 @@ struct Driver::Pci_config_update_policy device_t device_id = node.attribute_value("device_id", 0xffff); class_t class_code = node.attribute_value("class", 0xff); + rev_t rev = node.attribute_value("revision", 0xff); + vendor_t sub_v_id = node.attribute_value("sub_vendor_id", + 0xffff); + device_t sub_d_id = node.attribute_value("sub_device_id", + 0xffff); bool bridge = node.attribute_value("bridge", false); return *(new (alloc) Element(addr, bus_num, dev_num, func_num, - vendor_id, device_id, class_code, bridge)); + vendor_id, device_id, class_code, + rev, sub_v_id, sub_d_id, bridge)); } void update_element(Element &, Genode::Xml_node) {} @@ -593,4 +665,39 @@ struct Driver::Pci_config_update_policy } }; + +struct Driver::Reserved_memory_update_policy +: Genode::List_model::Update_policy +{ + Genode::Allocator & alloc; + + Reserved_memory_update_policy(Genode::Allocator & alloc) : alloc(alloc) {} + + void destroy_element(Element & pd) { + Genode::destroy(alloc, &pd); } + + Element & create_element(Genode::Xml_node node) + { + using namespace Pci; + + addr_t addr = node.attribute_value("address", 0UL); + size_t size = node.attribute_value("size", 0UL); + return *(new (alloc) Element({addr, size})); + } + + void update_element(Element &, Genode::Xml_node) {} + + static bool element_matches_xml_node(Element const & e, Genode::Xml_node node) + { + addr_t addr = node.attribute_value("address", 0UL); + size_t size = node.attribute_value("size", 0UL); + return addr == e.range.start && size == e.range.size; + } + + static bool node_is_element(Genode::Xml_node node) + { + return node.has_type("reserved_memory"); + } +}; + #endif /* _SRC__DRIVERS__PLATFORM__DEVICE_H_ */ diff --git a/repos/os/src/drivers/platform/device_component.cc b/repos/os/src/drivers/platform/device_component.cc index 282278fcd9..67f8851638 100644 --- a/repos/os/src/drivers/platform/device_component.cc +++ b/repos/os/src/drivers/platform/device_component.cc @@ -15,6 +15,7 @@ #include #include #include +#include using Driver::Device_component; @@ -27,6 +28,14 @@ void Driver::Device_component::_release_resources() _irq_registry.for_each([&] (Irq & irq) { destroy(_session.heap(), &irq); }); + _io_port_range_registry.for_each([&] (Io_port_range & iop) { + destroy(_session.heap(), &iop); }); + + _reserved_mem_registry.for_each([&] (Io_mem & iomem) { + destroy(_session.heap(), &iomem); }); + + if (_pci_config.constructed()) _pci_config.destruct(); + _session.ram_quota_guard().replenish(Ram_quota{_ram_quota}); _session.cap_quota_guard().replenish(Cap_quota{_cap_quota}); } @@ -38,8 +47,17 @@ Driver::Device::Name Device_component::device() const { return _device; } Driver::Session_component & Device_component::session() { return _session; } +unsigned Device_component::io_mem_index(Device::Pci_bar bar) +{ + unsigned ret = ~0U; + _io_mem_registry.for_each([&] (Io_mem & iomem) { + if (iomem.bar.number == bar.number) ret = iomem.idx; }); + return ret; +} + + Genode::Io_mem_session_capability -Device_component::io_mem(unsigned idx, Range &range, Cache cache) +Device_component::io_mem(unsigned idx, Range &range) { Io_mem_session_capability cap; @@ -49,10 +67,10 @@ Device_component::io_mem(unsigned idx, Range &range, Cache cache) return; if (!iomem.io_mem.constructed()) - iomem.io_mem.construct(_session.env(), + iomem.io_mem.construct(_env, iomem.range.start, iomem.range.size, - cache == WRITE_COMBINED); + iomem.prefetchable); range = iomem.range; range.start &= 0xfff; @@ -72,21 +90,28 @@ Genode::Irq_session_capability Device_component::irq(unsigned idx) if (irq.idx != idx) return; - if (!irq.irq.constructed()) { + if (!irq.shared && !irq.irq.constructed()) { addr_t pci_cfg_addr = 0; if (irq.type != Device::Irq::LEGACY) { if (_pci_config.constructed()) pci_cfg_addr = _pci_config->addr; else error("MSI(-x) detected for device without pci-config!"); } - irq.irq.construct(_session.env(), irq.number, irq.mode, irq.polarity, + irq.irq.construct(_env, irq.number, irq.mode, irq.polarity, pci_cfg_addr); Irq_session::Info info = irq.irq->info(); if (info.type == Irq_session::Info::MSI) - pci_msi_enable(_session.env(), pci_cfg_addr, info); + pci_msi_enable(_env, *this, pci_cfg_addr, info, irq.type); } - cap = irq.irq->cap(); + if (irq.shared && !irq.sirq.constructed()) + _device_model.with_shared_irq(irq.number, + [&] (Shared_interrupt & sirq) { + irq.sirq.construct(sirq, irq.mode, irq.polarity); + _env.ep().rpc_ep().manage(&*irq.sirq); + }); + + cap = irq.shared ? irq.sirq->cap() : irq.irq->cap(); }); return cap; @@ -103,7 +128,8 @@ Genode::Io_port_session_capability Device_component::io_port_range(unsigned idx) return; if (!ipr.io_port_range.constructed()) - ipr.io_port_range.construct(_session.env(), ipr.addr, ipr.size); + ipr.io_port_range.construct(_env, ipr.range.addr, + ipr.range.size); cap = ipr.io_port_range->cap(); }); @@ -113,9 +139,16 @@ Genode::Io_port_session_capability Device_component::io_port_range(unsigned idx) Device_component::Device_component(Registry & registry, + Env & env, Driver::Session_component & session, + Driver::Device_model & model, Driver::Device & device) -: _session(session), _device(device.name()), _reg_elem(registry, *this) +: + _env(env), + _session(session), + _device_model(model), + _device(device.name()), + _reg_elem(registry, *this) { session.cap_quota_guard().withdraw(Cap_quota{1}); _cap_quota += 1; @@ -136,33 +169,35 @@ Device_component::Device_component(Registry & registry, unsigned nr, Device::Irq::Type type, Irq_session::Polarity polarity, - Irq_session::Trigger mode) + Irq_session::Trigger mode, + bool shared) { session.ram_quota_guard().withdraw(Ram_quota{Irq_session::RAM_QUOTA}); _ram_quota += Irq_session::RAM_QUOTA; session.cap_quota_guard().withdraw(Cap_quota{Irq_session::CAP_QUOTA}); _cap_quota += Irq_session::CAP_QUOTA; - new (session.heap()) Irq(_irq_registry, idx, nr, type, polarity, mode); + new (session.heap()) Irq(_irq_registry, idx, nr, type, polarity, + mode, shared); }); - device.for_each_io_mem([&] (unsigned idx, Range range) + device.for_each_io_mem([&] (unsigned idx, Range range, + Device::Pci_bar bar, bool pf) { session.ram_quota_guard().withdraw(Ram_quota{Io_mem_session::RAM_QUOTA}); _ram_quota += Io_mem_session::RAM_QUOTA; session.cap_quota_guard().withdraw(Cap_quota{Io_mem_session::CAP_QUOTA}); _cap_quota += Io_mem_session::CAP_QUOTA; - new (session.heap()) Io_mem(_io_mem_registry, idx, range); + new (session.heap()) Io_mem(_io_mem_registry, bar, idx, range, pf); }); - device.for_each_io_port_range([&] (unsigned idx, uint16_t addr, - uint16_t size) + device.for_each_io_port_range([&] (unsigned idx, Io_port_range::Range range, + Device::Pci_bar) { session.ram_quota_guard().withdraw(Ram_quota{Io_port_session::RAM_QUOTA}); _ram_quota += Io_port_session::RAM_QUOTA; session.cap_quota_guard().withdraw(Cap_quota{Io_port_session::CAP_QUOTA}); _cap_quota += Io_port_session::CAP_QUOTA; - new (session.heap()) Io_port_range(_io_port_range_registry, - idx, addr, size); + new (session.heap()) Io_port_range(_io_port_range_registry, idx, range); }); device.for_pci_config([&] (Device::Pci_config const & cfg) @@ -173,6 +208,20 @@ Device_component::Device_component(Registry & registry, _cap_quota += Io_mem_session::CAP_QUOTA; _pci_config.construct(cfg.addr); }); + + device.for_each_reserved_memory([&] (unsigned idx, Range range) + { + session.ram_quota_guard().withdraw(Ram_quota{Io_mem_session::RAM_QUOTA}); + _ram_quota += Io_mem_session::RAM_QUOTA; + session.cap_quota_guard().withdraw(Cap_quota{Io_mem_session::CAP_QUOTA}); + _cap_quota += Io_mem_session::CAP_QUOTA; + Io_mem & iomem = *(new (session.heap()) + Io_mem(_reserved_mem_registry, {0}, idx, range, false)); + iomem.io_mem.construct(_env, iomem.range.start, + iomem.range.size, false); + session.device_pd().attach_dma_mem(iomem.io_mem->dataspace(), + iomem.range.start); + }); } catch(...) { _release_resources(); throw; diff --git a/repos/os/src/drivers/platform/device_component.h b/repos/os/src/drivers/platform/device_component.h index c890e267d3..a736437f49 100644 --- a/repos/os/src/drivers/platform/device_component.h +++ b/repos/os/src/drivers/platform/device_component.h @@ -38,53 +38,62 @@ class Driver::Device_component : public Rpc_object::Element { - unsigned idx; - unsigned number; - Device::Irq::Type type; - Irq_session::Polarity polarity; - Irq_session::Trigger mode; - Constructible irq {}; + unsigned idx; + unsigned number; + Device::Irq::Type type; + Irq_session::Polarity polarity; + Irq_session::Trigger mode; + bool shared; + Constructible irq {}; + Constructible sirq {}; Irq(Registry & registry, unsigned idx, unsigned number, Device::Irq::Type type, Irq_session::Polarity polarity, - Irq_session::Trigger mode) + Irq_session::Trigger mode, + bool shared) : Registry::Element(registry, *this), idx(idx), number(number), type(type), - polarity(polarity), mode(mode) {} + polarity(polarity), mode(mode), shared(shared) {} }; struct Io_mem : Registry::Element { + using Pci_bar = Device::Pci_bar; + + Pci_bar bar; unsigned idx; Range range; + bool prefetchable; Constructible io_mem {}; Io_mem(Registry & registry, + Pci_bar bar, unsigned idx, - Range range) + Range range, + bool pf) : Registry::Element(registry, *this), - idx(idx), range(range) {} + bar(bar), idx(idx), range(range), prefetchable(pf) {} }; struct Io_port_range : Registry::Element { + using Range = Device::Io_port_range::Range; + unsigned idx; - uint16_t addr; - uint16_t size; + Range range; Constructible io_port_range {}; Io_port_range(Registry & registry, - unsigned idx, - uint16_t addr, - uint16_t size) + unsigned idx, + Range range) : Registry::Element(registry, *this), - idx(idx), addr(addr), size(size) {} + idx(idx), range(range) {} }; struct Pci_config @@ -95,12 +104,15 @@ class Driver::Device_component : public Rpc_object & registry, + Env & env, Session_component & session, + Device_model & model, Driver::Device & device); ~Device_component(); Driver::Device::Name device() const; Session_component & session(); + unsigned io_mem_index(Device::Pci_bar bar); /************************************ @@ -108,12 +120,14 @@ class Driver::Device_component : public Rpc_object _irq_registry {}; Registry _io_mem_registry {}; Registry _io_port_range_registry {}; + Registry _reserved_mem_registry {}; Constructible _pci_config {}; void _release_resources(); diff --git a/repos/os/src/drivers/platform/device_model_policy.cc b/repos/os/src/drivers/platform/device_model_policy.cc index 652e28eec5..45a04d8321 100644 --- a/repos/os/src/drivers/platform/device_model_policy.cc +++ b/repos/os/src/drivers/platform/device_model_policy.cc @@ -58,6 +58,11 @@ void Device_model::destroy_element(Device & device) device._pci_config_list.destroy_all_elements(policy); } + { + Reserved_memory_update_policy policy(_heap); + device._reserved_mem_list.destroy_all_elements(policy); + } + Genode::destroy(_heap, &device); } @@ -66,7 +71,7 @@ Device & Device_model::create_element(Genode::Xml_node node) { Device::Name name = node.attribute_value("name", Device::Name()); Device::Type type = node.attribute_value("type", Device::Type()); - return *(new (_heap) Device(*this, name, type)); + return *(new (_heap) Device(_env, *this, name, type)); } @@ -112,4 +117,9 @@ void Device_model::update_element(Device & device, Pci_config_update_policy policy(_heap); device._pci_config_list.update_from_xml(policy, node); } + + { + Reserved_memory_update_policy policy(_heap); + device._reserved_mem_list.update_from_xml(policy, node); + } } diff --git a/repos/os/src/drivers/platform/device_pd.cc b/repos/os/src/drivers/platform/device_pd.cc index 6b7cb0ce65..9fe5d88904 100644 --- a/repos/os/src/drivers/platform/device_pd.cc +++ b/repos/os/src/drivers/platform/device_pd.cc @@ -117,7 +117,7 @@ void Device_pd::assign_pci(Io_mem_dataspace_capability const io_mem_cap, /* try to assign pci device to this protection domain */ if (!_pd.assign_pci(addr, Pci::Bdf::rid(bdf))) - error("Assignment of PCI device ", bdf, " to device PD failed!"); + log("Assignment of PCI device ", bdf, " to device PD failed, no IOMMU?!"); /* we don't need the mapping anymore */ _address_space.detach(addr); diff --git a/repos/os/src/drivers/platform/legacy/x86/README b/repos/os/src/drivers/platform/legacy/x86/README index ff2c4837af..6391dc0346 100644 --- a/repos/os/src/drivers/platform/legacy/x86/README +++ b/repos/os/src/drivers/platform/legacy/x86/README @@ -182,3 +182,26 @@ The driver provides for the PS2 and PIT device the IO_PORT and IRQ resources. ! ! ! + +Also, known ACPI device resources can be statically configured on +startup like follows. + +! +! +! +! +! +! +! +! +! +! +! +! +! +! +! +! +! +! +! diff --git a/repos/os/src/drivers/platform/legacy/x86/acpi_devices.cc b/repos/os/src/drivers/platform/legacy/x86/acpi_devices.cc new file mode 100644 index 0000000000..ae1cf74d85 --- /dev/null +++ b/repos/os/src/drivers/platform/legacy/x86/acpi_devices.cc @@ -0,0 +1,207 @@ +/* + * \brief ACPI device information from config + * \author Christian Helmuth + * \date 2022-05-16 + */ + +/* + * Copyright (C) 2022 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. + */ + +#include "acpi_devices.h" + +namespace Platform { namespace Acpi { + struct Device_impl; + + typedef String<16> Str; +}} + + +void Platform::Acpi::Device::Resource::print(Output &o) const +{ + using Genode::print; + switch (type) { + case Type::IRQ: + print(o, "IRQ [", base); + print(o, " ", irq == Irq::EDGE ? "edge" : irq == Irq::LEVEL_LOW ? "level-low" : "level-high"); + print(o, "]"); + break; + case Type::IOMEM: + print(o, "IOMEM "); + print(o, "[", Hex(base, Hex::Prefix::OMIT_PREFIX, Hex::PAD)); + print(o, "-", Hex(base + (size - 1), Hex::Prefix::OMIT_PREFIX, Hex::PAD)); + print(o, "]"); + break; + case Type::IOPORT: + print(o, "IOPORT "); + print(o, "[", Hex((unsigned short)base, Hex::Prefix::OMIT_PREFIX, Hex::PAD)); + print(o, "-", Hex((unsigned short)(base + (size - 1)), Hex::Prefix::OMIT_PREFIX, Hex::PAD)); + print(o, "]"); + break; + } +} + + +class Platform::Acpi::Device_impl : private Registry::Element, + public Platform::Acpi::Device +{ + private: + + Hid _hid; /* ACPI Spec 6.1.5 Hardware ID */ + + struct Resource_element : Registry::Element + { + unsigned id; + Resource res; + + Resource_element(Registry ®istry, + unsigned id, + Resource res) + : + Registry::Element(registry, *this), + id(id), res(res) + { } + }; + + Registry _resource_registry { }; + + Resource_result _lookup_resource(Resource::Type type, unsigned const id) const + { + Resource const *res = nullptr; + _resource_registry.for_each([&] (Resource_element const &e) { + if (e.res.type == type && e.id == id) + res = &e.res; + }); + + if (res) + return *res; + else + return Invalid_resource { }; + } + + unsigned _max_irq_id { 0 }; + unsigned _max_iomem_id { 0 }; + unsigned _max_ioport_id { 0 }; + + public: + + Device_impl(Registry ®istry, + Allocator &heap, Xml_node config) + : + Registry::Element(registry, *this), + _hid(config.attribute_value("name", Hid("ACPI0000"))) + { + config.for_each_sub_node("irq", [&] (Xml_node node) { + auto irq = [&] (Str const &mode, Str const &polarity) { + if (mode == "level") { + if (polarity == "high") + return Resource::Irq::LEVEL_HIGH; + else + return Resource::Irq::LEVEL_LOW; + } else { + return Resource::Irq::EDGE; + } + }; + new (heap) + Resource_element { + _resource_registry, + _max_irq_id++, + Resource { + .type = Resource::Type::IRQ, + .base = node.attribute_value("number", addr_t(0)), + .irq = irq(node.attribute_value("mode", Str("unchanged")), + node.attribute_value("polarity", Str("unchanged"))) } }; + }); + config.for_each_sub_node("io_mem", [&] (Xml_node node) { + new (heap) + Resource_element { + _resource_registry, + _max_iomem_id++, + Resource { + .type = Resource::Type::IOMEM, + .base = node.attribute_value("address", addr_t(0)), + .size = node.attribute_value("size", size_t(0)) } }; + }); + config.for_each_sub_node("io_port_range", [&] (Xml_node node) { + new (heap) + Resource_element { + _resource_registry, + _max_ioport_id++, + Resource { + .type = Resource::Type::IOPORT, + .base = node.attribute_value("address", addr_t(0)), + .size = node.attribute_value("size", size_t(0)) } }; + }); + } + + ~Device_impl() { error("unexpected call of ", __func__); } + + /* Platform::Acpi::Device interface */ + + Hid hid() const override { return _hid; } + + Resource_result resource(unsigned idx) const override + { + /* + * Index of all IOMEM and IOPORT resources - no IRQ! + * + * first _max_iomem_id IOMEM, then _max_ioport_id IOPORT + */ + if (idx < _max_iomem_id) + return iomem(idx); + else if (idx < _max_iomem_id + _max_ioport_id) + return ioport(idx - _max_iomem_id); + else + return Invalid_resource { }; + } + + Resource_result irq(unsigned id) const override + { + return _lookup_resource(Resource::Type::IRQ, id); + } + + Resource_result iomem(unsigned id) const override + { + return _lookup_resource(Resource::Type::IOMEM, id); + } + + Resource_result ioport(unsigned id) const override + { + return _lookup_resource(Resource::Type::IOPORT, id); + } +}; + + +Platform::Acpi::Device_registry::Lookup_result +Platform::Acpi::Device_registry::lookup(Platform::Acpi::Device::Hid hid) const +{ + Device const *found = nullptr; + + this->for_each([&] (Device const &device) { + if (device.hid() == hid) + found = &device; + }); + + if (found) + return found; + else + return Lookup_failed { }; +} + + +void Platform::Acpi::Device_registry::init_devices(Allocator &heap, Xml_node config) +{ + /* init only once */ + if (_initialized) + return; + + config.for_each_sub_node("device", [&] (Xml_node node) { + if (node.attribute_value("type", Str()) == "acpi") + new (heap) Device_impl(*this, heap, node); + }); + + _initialized = true; +} diff --git a/repos/os/src/drivers/platform/legacy/x86/acpi_devices.h b/repos/os/src/drivers/platform/legacy/x86/acpi_devices.h new file mode 100644 index 0000000000..89e7aa98e3 --- /dev/null +++ b/repos/os/src/drivers/platform/legacy/x86/acpi_devices.h @@ -0,0 +1,71 @@ +/* + * \brief ACPI device information from config + * \author Christian Helmuth + * \date 2022-05-16 + */ + +/* + * Copyright (C) 2022 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. + */ + +#include +#include +#include +#include + + +namespace Platform { namespace Acpi { + using namespace Genode; + + class Device; + + class Device_registry; +} } + + +struct Platform::Acpi::Device : Interface +{ + typedef String<10> Hid; /* ACPI Spec 6.1.5 Hardware ID */ + + struct Resource + { + enum class Type { IRQ, IOMEM, IOPORT }; + + enum class Irq { EDGE, LEVEL_LOW, LEVEL_HIGH }; + + Type type; + addr_t base; + + union { + size_t size; + Irq irq; + }; + + void print(Output &o) const; + }; + + enum struct Invalid_resource { }; + typedef Attempt Resource_result; + + virtual Hid hid() const = 0; + virtual Resource_result resource(unsigned idx) const = 0; + virtual Resource_result irq(unsigned id) const = 0; + virtual Resource_result iomem(unsigned id) const = 0; + virtual Resource_result ioport(unsigned id) const = 0; +}; + + +struct Platform::Acpi::Device_registry : Genode::Registry +{ + bool _initialized { false }; + + void init_devices(Allocator &heap, Xml_node config); + + enum struct Lookup_failed { }; + typedef Attempt Lookup_result; + + Lookup_result lookup(Device::Hid name) const; +}; diff --git a/repos/os/src/drivers/platform/legacy/x86/irq.cc b/repos/os/src/drivers/platform/legacy/x86/irq.cc index 4de20bb2d0..609142475d 100644 --- a/repos/os/src/drivers/platform/legacy/x86/irq.cc +++ b/repos/os/src/drivers/platform/legacy/x86/irq.cc @@ -167,7 +167,7 @@ class Platform::Irq_component : public Platform::Irq_proxy void Platform::Irq_session_component::ack_irq() { if (msi()) { - _irq_conn->ack_irq(); + _msi_conn->ack_irq(); return; } @@ -186,7 +186,9 @@ void Platform::Irq_session_component::ack_irq() Platform::Irq_session_component::Irq_session_component(unsigned irq, addr_t pci_config_space, Env &env, - Allocator &heap) + Allocator &heap, + Irq_session::Trigger trigger, + Irq_session::Polarity polarity) : _gsi(irq) { @@ -197,11 +199,11 @@ Platform::Irq_session_component::Irq_session_component(unsigned irq, try { using namespace Genode; - _irq_conn.construct(env, msi, Irq_session::TRIGGER_UNCHANGED, + _msi_conn.construct(env, msi, Irq_session::TRIGGER_UNCHANGED, Irq_session::POLARITY_UNCHANGED, pci_config_space); - _msi_info = _irq_conn->info(); + _msi_info = _msi_conn->info(); if (_msi_info.type == Irq_session::Info::Type::MSI) { _gsi = msi; return; @@ -216,9 +218,6 @@ Platform::Irq_session_component::Irq_session_component(unsigned irq, if (_gsi >= INVALID_IRQ) return; - Irq_session::Trigger trigger; - Irq_session::Polarity polarity; - _gsi = Platform::Irq_override::irq_override(_gsi, trigger, polarity); if (_gsi != irq || trigger != Irq_session::TRIGGER_UNCHANGED || polarity != POLARITY_UNCHANGED) { @@ -241,7 +240,7 @@ Platform::Irq_session_component::Irq_session_component(unsigned irq, Platform::Irq_session_component::~Irq_session_component() { if (msi()) { - _irq_conn->sigh(Signal_context_capability()); + _msi_conn->sigh(Signal_context_capability()); irq_alloc.free_msi(_gsi); return; @@ -258,9 +257,9 @@ Platform::Irq_session_component::~Irq_session_component() void Platform::Irq_session_component::sigh(Signal_context_capability sigh) { - if (_irq_conn.constructed()) { + if (_msi_conn.constructed()) { /* register signal handler for msi directly at parent */ - _irq_conn->sigh(sigh); + _msi_conn->sigh(sigh); return; } diff --git a/repos/os/src/drivers/platform/legacy/x86/irq.h b/repos/os/src/drivers/platform/legacy/x86/irq.h index 1a64e3b51b..55c2402a96 100644 --- a/repos/os/src/drivers/platform/legacy/x86/irq.h +++ b/repos/os/src/drivers/platform/legacy/x86/irq.h @@ -42,18 +42,21 @@ class Platform::Irq_session_component : public Rpc_object, Platform::Irq_sigh _irq_sigh { }; Irq_session::Info _msi_info { }; - Constructible _irq_conn { }; + Constructible _msi_conn { }; public: enum { INVALID_IRQ = 0xffU }; - Irq_session_component(unsigned, addr_t, Env &, Allocator &heap); + Irq_session_component(unsigned, addr_t, Env &, Allocator &heap, + Trigger trigger = TRIGGER_UNCHANGED, + Polarity polarity = POLARITY_UNCHANGED); + ~Irq_session_component(); bool msi() { - return _irq_conn.constructed() && + return _msi_conn.constructed() && _msi_info.type == Irq_session::Info::Type::MSI; } @@ -136,9 +139,9 @@ class Platform::Irq_override : public List::Element Irq_session::Trigger trigger() const { return _trigger; } Irq_session::Polarity polarity() const { return _polarity; } - static unsigned irq_override (unsigned irq, - Irq_session::Trigger &trigger, - Irq_session::Polarity &polarity) + static unsigned irq_override(unsigned irq, + Irq_session::Trigger &trigger, + Irq_session::Polarity &polarity) { for (Irq_override *i = list()->first(); i; i = i->next()) if (i->irq() == irq) { @@ -147,8 +150,7 @@ class Platform::Irq_override : public List::Element return i->gsi(); } - trigger = Irq_session::TRIGGER_UNCHANGED; - polarity = Irq_session::POLARITY_UNCHANGED; + /* trigger and polarity not touched in this case! */ return irq; } }; diff --git a/repos/os/src/drivers/platform/legacy/x86/main.cc b/repos/os/src/drivers/platform/legacy/x86/main.cc index 5043e754d7..58c3e5e777 100644 --- a/repos/os/src/drivers/platform/legacy/x86/main.cc +++ b/repos/os/src/drivers/platform/legacy/x86/main.cc @@ -1,6 +1,7 @@ /* * \brief Platform driver for x86 * \author Norman Feske + * \author Christian Helmuth * \date 2008-01-28 */ @@ -20,17 +21,26 @@ #include "pci_session_component.h" #include "pci_device_config.h" #include "device_pd.h" +#include "acpi_devices.h" -namespace Platform { struct Main; }; +namespace Platform { + struct Main; + namespace Nonpci { void acpi_device_registry(Acpi::Device_registry &); } +}; struct Platform::Main { + Env &_env; + + Heap _heap { _env.ram(), _env.rm() }; + + Acpi::Device_registry _acpi_device_registry { }; + /* * Use sliced heap to allocate each session component at a separate * dataspace. */ - Env &_env; Sliced_heap sliced_heap { _env.ram(), _env.rm() }; Attached_rom_dataspace _config { _env, "config" }; @@ -67,13 +77,13 @@ struct Platform::Main try { Attached_rom_dataspace info { _env, "platform_info" }; - info.xml().with_sub_node("kernel", [&] (Xml_node const &node) { + info.xml().with_optional_sub_node("kernel", [&] (Xml_node const &node) { acpi_platform = node.attribute_value("acpi", acpi_platform); msi_platform = node.attribute_value("msi" , msi_platform); }); } catch (...) { } - root.construct(_env, sliced_heap, _config, + root.construct(_env, _heap, sliced_heap, _config, acpi_rom->local_addr(), acpi_platform, msi_platform); } @@ -143,6 +153,8 @@ struct Platform::Main root->generate_pci_report(); root->config_update(); } + + _acpi_device_registry.init_devices(_heap, _config.xml()); } Main(Env &env) : _env(env) @@ -165,6 +177,8 @@ struct Platform::Main config_update(); acpi_update(); system_update(); + + Nonpci::acpi_device_registry(_acpi_device_registry); } }; @@ -174,7 +188,7 @@ void Platform::Main::_attempt_acpi_reset() if (!acpi_rom.constructed()) return; - acpi_rom->xml().with_sub_node("reset", [&] (Xml_node reset) { + acpi_rom->xml().with_optional_sub_node("reset", [&] (Xml_node reset) { uint16_t const io_port = reset.attribute_value("io_port", (uint16_t)0); uint8_t const value = reset.attribute_value("value", (uint8_t)0); diff --git a/repos/os/src/drivers/platform/legacy/x86/nonpci_devices.cc b/repos/os/src/drivers/platform/legacy/x86/nonpci_devices.cc index 69e8f3fd60..550883b19b 100644 --- a/repos/os/src/drivers/platform/legacy/x86/nonpci_devices.cc +++ b/repos/os/src/drivers/platform/legacy/x86/nonpci_devices.cc @@ -1,6 +1,7 @@ /* * \brief Non PCI devices, e.g. PS2 * \author Alexander Boettcher + * \author Christian Helmuth * \date 2015-04-17 */ @@ -13,6 +14,7 @@ #include "pci_session_component.h" #include "irq.h" +#include "acpi_devices.h" namespace Platform { namespace Nonpci { class Ps2; class Pit; } } @@ -85,7 +87,7 @@ class Platform::Nonpci::Ps2 : public Device_component return Io_mem_session_capability(); } - String<5> name() const override { return "PS2"; } + Device_name_string name() const override { return "PS2"; } }; @@ -124,7 +126,166 @@ class Platform::Nonpci::Pit : public Device_component return Io_port_session_capability(); } - String<5> name() const override { return "PIT"; } + Device_name_string name() const override { return "PIT"; } +}; + + +namespace Platform { namespace Nonpci { + class Acpi; + + void acpi_device_registry(Platform::Acpi::Device_registry &); +} } + + +static Platform::Acpi::Device_registry *_acpi_device_registry; + +void Platform::Nonpci::acpi_device_registry(Platform::Acpi::Device_registry ®istry) +{ + _acpi_device_registry = ®istry; +} + + +class Platform::Nonpci::Acpi : public Device_component +{ + private: + + Env &_env; + + Allocator &_session_heap; + + Platform::Acpi::Device const &_acpi_device; + + Irq_session_component *_irq0 = nullptr; + + /* + * Noncopyable + */ + Acpi(Acpi const &) = delete; + Acpi &operator = (Acpi const &) = delete; + + public: + + Acpi(Platform::Acpi::Device const &acpi_device, + Env &env, + Attached_io_mem_dataspace &pciconf, + Session_component &session, + Allocator &session_heap, + Allocator &global_heap, + Pci::Config::Delayer &delayer, + Device_bars_pool &devices_bars) + : + Device_component(env, pciconf, session, 0, + global_heap, delayer, devices_bars), + _env(env), _session_heap(session_heap), _acpi_device(acpi_device) + { } + + Device_name_string name() const override { return _acpi_device.hid(); } + + /* Platform::Device interface */ + + void bus_address(unsigned char *bus, unsigned char *dev, + unsigned char *fn) override + { + *bus = 0; *dev = 0; *fn = 0; + } + + unsigned short vendor_id() override { return ~0; } + + unsigned short device_id() override { return ~0; } + + unsigned class_code() override { return ~0; } + + Resource resource(int resource_id) override + { + using Acpi_device = Platform::Acpi::Device; + + return _acpi_device.resource(resource_id).convert( + [&] (Acpi_device::Resource r) { + /* craft artificial BAR values from resource info */ + switch (r.type) { + case Acpi_device::Resource::Type::IOMEM: + return Resource((r.base & 0xfffffff0) | 0b0000, r.size); + + case Acpi_device::Resource::Type::IOPORT: + return Resource((r.base & 0xfffffffc) | 0b01, r.size); + + case Acpi_device::Resource::Type::IRQ: + return Resource(); + } + return Resource(); + }, + [&] (Acpi_device::Invalid_resource) { return Resource(); }); + } + + unsigned config_read(unsigned char, Access_size) override + { + warning("ignore config_read from ACPI device ", _acpi_device.hid()); + return 0; + } + + void config_write(unsigned char, unsigned, Access_size) override + { + warning("ignore config_write to ACPI device ", _acpi_device.hid()); + } + + Irq_session_capability irq(uint8_t v_id) override + { + using Acpi_device = Platform::Acpi::Device; + + /* TODO more than one IRQ */ + if (v_id != 0) { + warning("ACPI device with more than one IRQ not supported (requested id ", v_id, ")"); + return Irq_session_capability(); + } + if (_irq0) return _irq0->cap(); + + /* TODO needs try see pci_device.cc ::iomem() */ + return _acpi_device.irq(v_id).convert( + [&] (Acpi_device::Resource r) { + Platform::Irq_session_component &irq = + *new(_session_heap) + Platform::Irq_session_component(r.base, ~0UL, _env, _session_heap, + Irq_session::TRIGGER_LEVEL, + Irq_session::POLARITY_LOW); + _env.ep().manage(irq); + _irq0 = &irq; + return irq.cap(); + }, + [&] (Acpi_device::Invalid_resource) { return Irq_session_capability(); }); + } + + Io_port_session_capability io_port(uint8_t v_id) override + { + using Acpi_device = Platform::Acpi::Device; + + /* TODO needs try see pci_device.cc ::iomem() */ + + return _acpi_device.ioport(v_id).convert( + [&] (Acpi_device::Resource r) { + Io_port_connection &ioport = + *new (_session_heap) Io_port_connection(_env, r.base, r.size); + return ioport.cap(); + }, + [&] (Acpi_device::Invalid_resource) { return Io_port_session_capability(); }); + } + + Io_mem_session_capability io_mem(uint8_t v_id, + Cache /* ignored */, + addr_t /* ignored */, + size_t /* ignored */) override + { + using Acpi_device = Platform::Acpi::Device; + + /* TODO needs try see pci_device.cc ::iomem() */ + + return _acpi_device.iomem(v_id).convert( + [&] (Acpi_device::Resource r) { + Io_mem_connection &iomem = + *new (_session_heap) Io_mem_connection(_env, r.base, r.size); + return iomem.cap(); + }, + [&] (Acpi_device::Invalid_resource) { return Io_mem_session_capability(); }); + } }; @@ -136,20 +297,34 @@ Platform::Device_capability Platform::Session_component::device(Device_name cons if (!name.valid_string()) return Device_capability(); - char const * device_name = name.string(); - const char * devices [] = { "PS2", "PIT" }; - unsigned devices_i = 0; + Device_name_string const device_name { name.string() }; - for (; devices_i < sizeof(devices) / sizeof(devices[0]); devices_i++) - if (!strcmp(device_name, devices[devices_i])) - break; + enum class Type { UNKNOWN, PS2, PIT, ACPI } device_type { Type::UNKNOWN }; - if (devices_i >= sizeof(devices) / sizeof(devices[0])) { - error("unknown '", device_name, " device name"); + Platform::Acpi::Device const *acpi_device = nullptr; + + if (device_name == "PS2") + device_type = Type::PS2; + + else if (device_name == "PIT") + device_type = Type::PIT; + + else if (_acpi_device_registry) + device_type = _acpi_device_registry->lookup(device_name).convert( + [&] (Acpi::Device const *device) { + acpi_device = device; + return Type::ACPI; + }, + [&] (Acpi::Device_registry::Lookup_failed) { return Type::UNKNOWN; }); + + bool const found = device_type != Type::UNKNOWN; + + if (!found) { + error("unknown device name '", device_name, "'"); return Device_capability(); } - if (!permit_device(devices[devices_i])) { + if (!permit_device(device_name.string())) { error("denied access to device '", device_name, "' for " "session '", _label, "'"); return Device_capability(); @@ -158,17 +333,24 @@ Platform::Device_capability Platform::Session_component::device(Device_name cons try { Device_component * dev = nullptr; - switch(devices_i) { - case 0: + switch (device_type) { + case Type::PS2: dev = new (_md_alloc) Nonpci::Ps2(_env, _pciconf, *this, _global_heap, _delayer, _devices_bars); break; - case 1: + case Type::PIT: dev = new (_md_alloc) Nonpci::Pit(_env, _pciconf, *this, _global_heap, _delayer, _devices_bars); break; + case Type::ACPI: + dev = new (_md_alloc) Nonpci::Acpi(*acpi_device, + _env, _pciconf, *this, + _md_alloc, + _global_heap, _delayer, + _devices_bars); + break; default: return Device_capability(); } diff --git a/repos/os/src/drivers/platform/legacy/x86/pci_device.cc b/repos/os/src/drivers/platform/legacy/x86/pci_device.cc index ea4acb6a6a..30aa26399b 100644 --- a/repos/os/src/drivers/platform/legacy/x86/pci_device.cc +++ b/repos/os/src/drivers/platform/legacy/x86/pci_device.cc @@ -1,6 +1,8 @@ /* * \brief PCI device component implementation * \author Alexander Boettcher + * \author Christian Helmuth + * \date 2022-06-24 */ /* @@ -102,10 +104,24 @@ Genode::Io_mem_session_capability Platform::Device_component::io_mem(uint8_t con return Io_mem_session_capability(); } + +unsigned Platform::Device_component::config_read(unsigned char address, Access_size size) +{ + if (pci_device()) + return _device_config.read(_config_access, address, size, + _device_config.DONT_TRACK_ACCESS); + + return ~0; +} + + void Platform::Device_component::config_write(unsigned char address, unsigned value, Access_size size) { + if (!pci_device()) + return; + /* white list of ports which we permit to write */ switch (address) { case 0x40 ... 0xff: @@ -164,7 +180,7 @@ Genode::Irq_session_capability Platform::Device_component::irq(uint8_t id) if (_irq_session) return _irq_session->cap(); - if (!_device_config.valid()) { + if (!pci_device()) { /* Non PCI devices */ _irq_session = construct_at(_mem_irq_component, _irq_line, ~0UL, diff --git a/repos/os/src/drivers/platform/legacy/x86/pci_device_component.h b/repos/os/src/drivers/platform/legacy/x86/pci_device_component.h index b8e68de77e..db3d92da36 100644 --- a/repos/os/src/drivers/platform/legacy/x86/pci_device_component.h +++ b/repos/os/src/drivers/platform/legacy/x86/pci_device_component.h @@ -1,6 +1,7 @@ /* * \brief platform device component * \author Norman Feske + * \author Christian Helmuth * \date 2008-01-28 */ @@ -33,6 +34,8 @@ namespace Platform { class Device_component; class Session_component; + typedef String<10> Device_name_string; + typedef Registry > Device_bars_pool; } @@ -536,12 +539,15 @@ class Platform::Device_component : public Rpc_object, } } - if (!_device_config.valid()) + if (!pci_device()) return; _power_off(); } + /* distinct non-PCI and PCI devices */ + bool pci_device() const { return _device_config.valid(); } + /**************************************** ** Methods used solely by pci session ** ****************************************/ @@ -549,7 +555,7 @@ class Platform::Device_component : public Rpc_object, Device_config device_config() const { return _device_config; } addr_t config_space() const { return _config_space; } - virtual String<5> name() const { return "PCI"; } + virtual Device_name_string name() const { return "PCI"; } template void for_each_device(FUNC const &fn) const @@ -580,18 +586,14 @@ class Platform::Device_component : public Rpc_object, Resource resource(int resource_id) override { + if (pci_device()) + return _device_config.resource(resource_id).api_resource(); + /* return invalid resource if device is invalid */ - if (!_device_config.valid()) - return Resource(0, 0); - - return _device_config.resource(resource_id).api_resource(); + return Resource(0, 0); } - unsigned config_read(unsigned char address, Access_size size) override - { - return _device_config.read(_config_access, address, size, - _device_config.DONT_TRACK_ACCESS); - } + unsigned config_read(unsigned char address, Access_size size) override; void config_write(unsigned char address, unsigned value, Access_size size) override; diff --git a/repos/os/src/drivers/platform/legacy/x86/pci_device_config.h b/repos/os/src/drivers/platform/legacy/x86/pci_device_config.h index 8610f17321..0478bc988b 100644 --- a/repos/os/src/drivers/platform/legacy/x86/pci_device_config.h +++ b/repos/os/src/drivers/platform/legacy/x86/pci_device_config.h @@ -1,6 +1,7 @@ /* * \brief PCI device configuration * \author Norman Feske + * \author Christian Helmuth * \date 2008-01-29 */ @@ -292,12 +293,12 @@ namespace Platform { /** * Return true if device is a PCI bridge */ - bool pci_bridge() { return _header_type == HEADER_PCI_TO_PCI; } + bool pci_bridge() const { return _header_type == HEADER_PCI_TO_PCI; } /** * Return true if device is valid */ - bool valid() { return _vendor_id != INVALID_VENDOR; } + bool valid() const { return _vendor_id != INVALID_VENDOR; } /** * Return resource description by resource ID diff --git a/repos/os/src/drivers/platform/legacy/x86/pci_session_component.h b/repos/os/src/drivers/platform/legacy/x86/pci_session_component.h index 68a8f7ecba..ddf2828faa 100644 --- a/repos/os/src/drivers/platform/legacy/x86/pci_session_component.h +++ b/repos/os/src/drivers/platform/legacy/x86/pci_session_component.h @@ -1,6 +1,7 @@ /* * \brief Platform session component * \author Norman Feske + * \author Christian Helmuth * \date 2008-01-28 */ @@ -218,7 +219,7 @@ class Platform::Session_component : public Rpc_object Session_label const _label; List _device_list { }; Platform::Pci_buses &_pci_bus; - Heap &_global_heap; + Allocator &_global_heap; Pci::Config::Delayer &_delayer; Device_bars_pool &_devices_bars; bool const _iommu; @@ -349,8 +350,8 @@ class Platform::Session_component : public Rpc_object try { policy.for_each_sub_node("device", [&] (Xml_node dev) { - /* enforce restriction based on name name */ - if (dev.attribute_value("name", String<10>()) == name) + /* enforce restriction based on name */ + if (dev.attribute_value("name", Device_name_string()) == name) /* found identical match - permit access */ throw true; }); @@ -405,7 +406,7 @@ class Platform::Session_component : public Rpc_object return; /* if this bdf is used by some policy - deny */ - if (find_dev_in_policy(bdf)) + if (alias != "ALL" && find_dev_in_policy(bdf)) return; throw true; @@ -424,8 +425,7 @@ class Platform::Session_component : public Rpc_object _config.xml().for_each_sub_node("policy", [&] (Xml_node policy) { policy.for_each_sub_node("device", [&] (Xml_node device) { - typedef String<10> Name; - if (device.attribute_value("name", Name()) == dev_name) { + if (device.attribute_value("name", Device_name_string()) == dev_name) { if (once) throw true; @@ -474,7 +474,7 @@ class Platform::Session_component : public Rpc_object Attached_io_mem_dataspace &pciconf, addr_t pciconf_base, Platform::Pci_buses &buses, - Heap &global_heap, + Allocator &global_heap, Pci::Config::Delayer &delayer, Device_bars_pool &devices_bars, char const *args, @@ -521,8 +521,8 @@ class Platform::Session_component : public Rpc_object throw Service_denied(); } - typedef String<16> Name; - Name const name = device_node.attribute_value("name", Name()); + Device_name_string const name = + device_node.attribute_value("name", Device_name_string()); enum { DOUBLET = false }; if (find_dev_in_policy(name.string(), DOUBLET)) { @@ -610,7 +610,7 @@ class Platform::Session_component : public Rpc_object _device_list.first()->for_each_device([&](auto const &dev) { /* Non PCI devices */ - if (!dev.device_config().valid()) { + if (!dev.pci_device()) { if (!permit_device(dev.name().string())) result = false; @@ -777,7 +777,7 @@ class Platform::Session_component : public Rpc_object if (!device) return; - if (device->device_config().valid()) { + if (device->pci_device()) { if (bdf_in_use.get(device->device_config().bdf().value(), 1)) bdf_in_use.clear(device->device_config().bdf().value(), 1); } @@ -877,6 +877,7 @@ class Platform::Session_component : public Rpc_object return _env.pd().dma_addr(ram_cap); } + /* non-PCI devices */ Device_capability device(Device_name const &name) override; }; @@ -886,14 +887,13 @@ class Platform::Root : public Root_component private: Env &_env; + Allocator &_heap; Attached_rom_dataspace &_config; Constructible _pci_confspace { }; addr_t _pci_confspace_base = 0; Constructible _pci_reporter { }; - Heap _heap { _env.ram(), _env.rm() }; - Device_bars_pool _devices_bars { }; Constructible _buses { }; @@ -1123,11 +1123,12 @@ class Platform::Root : public Root_component * \param md_alloc meta-data allocator for allocating PCI-session * components and PCI-device components */ - Root(Env &env, Allocator &md_alloc, Attached_rom_dataspace &config, + Root(Env &env, Allocator &heap, Allocator &md_alloc, Attached_rom_dataspace &config, char const *acpi_rom, bool acpi_platform, bool msi_platform) : Root_component(&env.ep().rpc_ep(), &md_alloc), _env(env), + _heap(heap), _config(config), _msi_platform(msi_platform) { diff --git a/repos/os/src/drivers/platform/legacy/x86/target.mk b/repos/os/src/drivers/platform/legacy/x86/target.mk index 65a0a83892..d9ab3786c1 100644 --- a/repos/os/src/drivers/platform/legacy/x86/target.mk +++ b/repos/os/src/drivers/platform/legacy/x86/target.mk @@ -1,7 +1,7 @@ TARGET = legacy_pc_platform_drv REQUIRES = x86 SRC_CC = main.cc irq.cc pci_device.cc nonpci_devices.cc session.cc -SRC_CC += device_pd.cc +SRC_CC += device_pd.cc acpi_devices.cc LIBS = base INC_DIR = $(PRG_DIR) diff --git a/repos/os/src/drivers/platform/pci.cc b/repos/os/src/drivers/platform/pci.cc index 45df1afd52..0d4653f441 100644 --- a/repos/os/src/drivers/platform/pci.cc +++ b/repos/os/src/drivers/platform/pci.cc @@ -12,47 +12,83 @@ */ #include +#include #include #include #include #include +#include #include +#include +#include +#include +#include +#include using namespace Genode; using namespace Pci; + +static Config::Delayer & delayer(Env & env) +{ + struct Delayer : Config::Delayer, Timer::Connection + { + using Timer::Connection::Connection; + + void usleep(uint64_t us) override { + return Timer::Connection::usleep(us); } + }; + static Delayer delayer(env); + return delayer; +}; + + struct Config_helper { + Env & _env; Driver::Device const & _dev; Driver::Device::Pci_config const & _cfg; - Attached_io_mem_dataspace _io_mem; + Attached_io_mem_dataspace _io_mem { _env, _cfg.addr, 0x1000 }; Config _config { (addr_t)_io_mem.local_addr() }; Config_helper(Env & env, Driver::Device const & dev, Driver::Device::Pci_config const & cfg) - : _dev(dev), _cfg(cfg), _io_mem(env, cfg.addr, 0x1000) { } + : _env(env), _dev(dev), _cfg(cfg) { _config.scan(); } void enable(Driver::Device_pd & pd) { pd.assign_pci(_io_mem.cap(), { _cfg.bus_num, _cfg.dev_num, _cfg.func_num }); + _config.power_on(delayer(_env)); + Config::Command::access_t cmd = _config.read(); /* always allow DMA operations */ Config::Command::Bus_master_enable::set(cmd, 1); - /* enable memory space when I/O mem is defined */ - _dev.for_each_io_mem([&] (unsigned, Driver::Device::Range) { - Config::Command::Memory_space_enable::set(cmd, 1); }); + _dev.for_each_io_mem([&] (unsigned, Driver::Device::Io_mem::Range r, + Driver::Device::Pci_bar b, bool) + { + _config.set_bar_address(b.number, r.start); - /* enable i/o space when I/O ports are defined */ - _dev.for_each_io_port_range([&] (unsigned, uint16_t, uint16_t) { - Config::Command::Io_space_enable::set(cmd, 1); }); + /* enable memory space when I/O mem is defined */ + Config::Command::Memory_space_enable::set(cmd, 1); + }); + + _dev.for_each_io_port_range([&] (unsigned, + Driver::Device::Io_port_range::Range r, + Driver::Device::Pci_bar b) + { + _config.set_bar_address(b.number, r.addr); + + /* enable i/o space when I/O ports are defined */ + Config::Command::Io_space_enable::set(cmd, 1); + }); _config.write(cmd); } @@ -66,6 +102,35 @@ struct Config_helper Config::Command::Bus_master_enable::set(cmd, 0); Config::Command::Interrupt_enable::set(cmd, 0); _config.write(cmd); + + _config.power_off(); + } + + void apply_quirks() + { + Config::Command::access_t cmd = + _config.read(); + Config::Command::access_t cmd_old = cmd; + + /* enable memory space when I/O mem is defined */ + _dev.for_each_io_mem([&] (unsigned, Driver::Device::Io_mem::Range, + Driver::Device::Pci_bar, bool) { + Config::Command::Memory_space_enable::set(cmd, 1); }); + + /* enable i/o space when I/O ports are defined */ + _dev.for_each_io_port_range( + [&] (unsigned, Driver::Device::Io_port_range::Range, + Driver::Device::Pci_bar) { + Config::Command::Io_space_enable::set(cmd, 1); }); + + _config.write(cmd); + + /* apply different PCI quirks, bios handover etc. */ + Driver::pci_uhci_quirks(_env, _dev, _cfg, _config.base()); + Driver::pci_ehci_quirks(_env, _dev, _cfg, _config.base()); + Driver::pci_hd_audio_quirks(_cfg, _config); + + _config.write(cmd_old); } }; @@ -84,16 +149,61 @@ void Driver::pci_disable(Env & env, Device const & dev) } +void Driver::pci_apply_quirks(Env & env, Device const & dev) +{ + dev.for_pci_config([&] (Device::Pci_config const & pc) { + Config_helper(env, dev, pc).apply_quirks(); }); +} + + void Driver::pci_msi_enable(Env & env, + Device_component & dc, addr_t cfg_space, - Irq_session::Info const info) + Irq_session::Info const info, + Device::Irq::Type type) { Attached_io_mem_dataspace io_mem { env, cfg_space, 0x1000 }; Config config { (addr_t)io_mem.local_addr() }; config.scan(); - if (config.msi_cap.constructed()) + + if (type == Device::Irq::Type::MSIX && config.msi_x_cap.constructed()) { + try { + /* find the MSI-x table from the device's memory bars */ + Platform::Device_interface::Range range; + unsigned idx = dc.io_mem_index({config.msi_x_cap->bar()}); + Io_mem_session_client dsc(dc.io_mem(idx, range)); + Attached_dataspace msix_table_ds(env.rm(), dsc.dataspace()); + addr_t msix_table_start = (addr_t)msix_table_ds.local_addr() + + config.msi_x_cap->table_offset(); + + /* disable all msi-x table entries beside the first one */ + unsigned slots = config.msi_x_cap->slots(); + for (unsigned i = 0; i < slots; i++) { + using Entry = Config::Msi_x_capability::Table_entry; + Entry e (msix_table_start + Entry::SIZE * i); + if (!i) { + uint32_t lower = info.address & 0xfffffffc; + uint32_t upper = sizeof(info.address) > 4 ? + (uint32_t)(info.address >> 32) : 0; + e.write(lower); + e.write(upper); + e.write((uint32_t)info.value); + e.write(0); + } else + e.write(1); + } + + config.msi_x_cap->enable(); + } catch(...) { error("Failed to setup MSI-x!"); } + return; + } + + if (type == Device::Irq::Type::MSI && config.msi_cap.constructed()) { config.msi_cap->enable(info.address, (uint16_t)info.value); - else error("Device does not support MSI(-x)!"); + return; + } + + error("Device does not support MSI(-x)!"); } @@ -125,6 +235,7 @@ pci_class_code_alias(uint32_t class_code) { "USB" , 0x0c, 0x03, 0x10 }, /* OHCI */ { "USB" , 0x0c, 0x03, 0x20 }, /* EHCI */ { "USB" , 0x0c, 0x03, 0x30 }, /* XHCI */ + { "USB4" , 0x0c, 0x03, 0x40 }, { "VGA" , 0x03, 0x00, 0x00 }, { "AHCI" , 0x01, 0x06, WILDCARD }, { "AUDIO" , 0x04, 0x01, WILDCARD }, @@ -166,3 +277,16 @@ bool Driver::pci_device_matches(Session_policy const & policy, return ret; } + + +void Driver::pci_device_specific_info(Device const & dev, + Env & env, + Device_model & model, + Xml_generator & xml) +{ + dev.for_pci_config([&] (Device::Pci_config const cfg) + { + Driver::pci_intel_graphics_info(cfg, env, model, xml); + Driver::pci_virtio_info(dev, cfg, env, xml); + }); +} diff --git a/repos/os/src/drivers/platform/pci.h b/repos/os/src/drivers/platform/pci.h index c5b9290ad5..a33869da24 100644 --- a/repos/os/src/drivers/platform/pci.h +++ b/repos/os/src/drivers/platform/pci.h @@ -18,16 +18,24 @@ #include #include +#include + namespace Driver { - class Device; + class Device_component; class Device_pd; void pci_enable(Genode::Env & env, Device_pd & pd, Device const & dev); void pci_disable(Genode::Env & env, Device const & dev); - void pci_msi_enable(Genode::Env & env, addr_t cfg_space, - Genode::Irq_session::Info const info); + void pci_apply_quirks(Genode::Env & env, Device const & dev); + void pci_msi_enable(Genode::Env & env, Device_component & dc, + addr_t cfg_space, Genode::Irq_session::Info const info, + Device::Irq::Type type); bool pci_device_matches(Genode::Session_policy const & policy, Device const & dev); + void pci_device_specific_info(Device const & dev, + Env & env, + Device_model & model, + Xml_generator & xml); } #endif /* _SRC__DRIVERS__PLATFORM__PCI_H_ */ diff --git a/repos/os/src/drivers/platform/pci_ehci.h b/repos/os/src/drivers/platform/pci_ehci.h new file mode 100644 index 0000000000..49b14314cb --- /dev/null +++ b/repos/os/src/drivers/platform/pci_ehci.h @@ -0,0 +1,105 @@ +/* + * \brief Platform driver - PCI EHCI utilities + * \author Stefan Kalkowski + * \date 2022-09-28 + */ + +/* + * Copyright (C) 2022 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. + */ + +#include +#include + +namespace Driver { + static void pci_ehci_quirks(Env &, Device const &, + Device::Pci_config, addr_t); +} + + +void Driver::pci_ehci_quirks(Env & env, + Device const & dev, + Device::Pci_config cfg, + addr_t base) +{ + enum { EHCI_CLASS_CODE = 0xc0320 }; + + if (cfg.class_code != EHCI_CLASS_CODE) + return; + + /* EHCI host controller register definitions */ + struct Ehci : Mmio + { + struct Capability_parameters : Register<0x8, 32> + { + struct Extended_cap_pointer : Bitfield<8,8> {}; + }; + struct Configure_flag : Register<0x40, 32> {}; + + using Mmio::Mmio; + }; + + struct Ehci_pci : Mmio + { + struct Port_wake : Register<0x62, 16> {}; + + using Mmio::Mmio; + }; + + /* PCI extended capability for EHCI */ + struct Cap : Mmio + { + struct Pointer : Register<0x0, 16> + { + struct Id : Bitfield<0, 8> { enum { SYNC = 1 }; }; + struct Next : Bitfield<8, 8> { }; + }; + + struct Bios_semaphore : Register<0x2, 8> { }; + struct Os_semaphore : Register<0x3, 8> { }; + struct Usb_legacy_control_status : Register<0x4, 32> {}; + + using Mmio::Mmio; + }; + + /* find ehci controller registers behind PCI bar zero */ + dev.for_each_io_mem([&] (unsigned, Device::Io_mem::Range range, + Device::Pci_bar bar, bool) + { + if (!bar.valid() || bar.number != 0) + return; + + Ehci_pci pw(base); + + Attached_io_mem_dataspace iomem(env, range.start, 0x1000); + Ehci ehci((addr_t)iomem.local_addr()); + addr_t offset = + ehci.read(); + + /* iterate over EHCI extended capabilities */ + while (offset) { + Cap cap(base + offset); + if (cap.read() != Cap::Pointer::Id::SYNC) + break; + + bool bios_owned = cap.read(); + + if (bios_owned) cap.write(1); + + enum { MAX_ROUNDS = 1000000 }; + unsigned rounds = MAX_ROUNDS; + while (cap.read() && --rounds) ; + + if (!rounds) cap.write(0); + + cap.write(0); + + if (bios_owned) ehci.write(0); + + offset = cap.read(); + } + }); +} diff --git a/repos/os/src/drivers/platform/pci_hd_audio.h b/repos/os/src/drivers/platform/pci_hd_audio.h new file mode 100644 index 0000000000..616cb5f14a --- /dev/null +++ b/repos/os/src/drivers/platform/pci_hd_audio.h @@ -0,0 +1,60 @@ +/* + * \brief Platform driver - PCI HD AUDIO utilities + * \author Stefan Kalkowski + * \date 2022-09-09 + */ + +/* + * Copyright (C) 2022 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. + */ + +#include +#include + +namespace Driver { + static void pci_hd_audio_quirks(Device::Pci_config cfg, + Pci::Config & config); +} + + +void Driver::pci_hd_audio_quirks(Device::Pci_config cfg, + Pci::Config & config) +{ + enum { HDAUDIO_CLASS_CODE = 0x40300 }; + + if ((cfg.class_code & 0xffff00) != HDAUDIO_CLASS_CODE) + return; + + /* PCI configuration register for HDAUDIO */ + struct Hdaudio : Mmio + { + struct Traffic_class_select : Register<0x44, 8> {}; + + struct Intel_device_control : Register<0x78, 16> + { + struct No_snoop : Bitfield<11,1> {}; + }; + + struct Amd_device_control : Register<0x42, 8> + { + struct No_snoop : Bitfield<0, 3> {}; + }; + + using Mmio::Mmio; + }; + + config.write(1); + + Hdaudio audio(config.base()); + audio.write(0); + + if (cfg.vendor_id == 0x8086) + audio.write(0); + + if (cfg.vendor_id == 0x1002 || cfg.vendor_id == 0x1022) + audio.write(2); +} + diff --git a/repos/os/src/drivers/platform/pci_intel_graphics.h b/repos/os/src/drivers/platform/pci_intel_graphics.h new file mode 100644 index 0000000000..fffabac758 --- /dev/null +++ b/repos/os/src/drivers/platform/pci_intel_graphics.h @@ -0,0 +1,121 @@ +/* + * \brief Platform driver - PCI intel graphics utilities + * \author Stefan Kalkowski + * \date 2022-06-02 + */ + +/* + * Copyright (C) 2022 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. + */ + +#include +#include +#include + +namespace Driver { + void pci_intel_graphics_info(Device::Pci_config cfg, + Env & env, + Device_model & model, + Xml_generator & xml); +} + + +static inline unsigned pci_intel_graphics_generation(Pci::device_t id) +{ + struct Device_gen { + Pci::device_t id; + unsigned gen; + }; + + static Device_gen intel_gpu_generations[] = { + { 0x7121, 1 }, { 0x7123, 1 }, { 0x7125, 1 }, { 0x1132, 1 }, + { 0x3577, 2 }, { 0x2562, 2 }, { 0x3582, 2 }, { 0x358e, 2 }, + { 0x2572, 2 }, { 0x2582, 3 }, { 0x258a, 3 }, { 0x2592, 3 }, + { 0x2772, 3 }, { 0x27a2, 3 }, { 0x27ae, 3 }, { 0x29b2, 3 }, + { 0x29c2, 3 }, { 0x29d2, 3 }, { 0xa001, 3 }, { 0xa011, 3 }, + { 0x2972, 4 }, { 0x2982, 4 }, { 0x2992, 4 }, { 0x29a2, 4 }, + { 0x2a02, 4 }, { 0x2a12, 4 }, { 0x2a42, 4 }, { 0x2e02, 4 }, + { 0x2e12, 4 }, { 0x2e22, 4 }, { 0x2e32, 4 }, { 0x2e42, 4 }, + { 0x2e92, 4 }, { 0x0042, 5 }, { 0x0046, 5 }, { 0x0102, 6 }, + { 0x010a, 6 }, { 0x0112, 6 }, { 0x0122, 6 }, { 0x0106, 6 }, + { 0x0116, 6 }, { 0x0126, 6 }, { 0x0156, 6 }, { 0x0166, 6 }, + { 0x0152, 7 }, { 0x015a, 7 }, { 0x0162, 7 }, { 0x016a, 7 }, + { 0x0a02, 7 }, { 0x0a06, 7 }, { 0x0a0a, 7 }, { 0x0a0b, 7 }, + { 0x0a0e, 7 }, { 0x0402, 7 }, { 0x0406, 7 }, { 0x040a, 7 }, + { 0x040b, 7 }, { 0x040e, 7 }, { 0x0c02, 7 }, { 0x0c06, 7 }, + { 0x0c0a, 7 }, { 0x0c0b, 7 }, { 0x0c0e, 7 }, { 0x0d02, 7 }, + { 0x0d06, 7 }, { 0x0d0a, 7 }, { 0x0d0b, 7 }, { 0x0d0e, 7 }, + { 0x0a12, 7 }, { 0x0a16, 7 }, { 0x0a1a, 7 }, { 0x0a1b, 7 }, + { 0x0a1e, 7 }, { 0x0412, 7 }, { 0x0416, 7 }, { 0x041a, 7 }, + { 0x041b, 7 }, { 0x041e, 7 }, { 0x0c12, 7 }, { 0x0c16, 7 }, + { 0x0c1a, 7 }, { 0x0c1b, 7 }, { 0x0c1e, 7 }, { 0x0d12, 7 }, + { 0x0d16, 7 }, { 0x0d1a, 7 }, { 0x0d1b, 7 }, { 0x0d1e, 7 }, + { 0x0a22, 7 }, { 0x0a26, 7 }, { 0x0a2a, 7 }, { 0x0a2b, 7 }, + { 0x0a2e, 7 }, { 0x0422, 7 }, { 0x0426, 7 }, { 0x042a, 7 }, + { 0x042b, 7 }, { 0x042e, 7 }, { 0x0c22, 7 }, { 0x0c26, 7 }, + { 0x0c2a, 7 }, { 0x0c2b, 7 }, { 0x0c2e, 7 }, { 0x0d22, 7 }, + { 0x0d26, 7 }, { 0x0d2a, 7 }, { 0x0d2b, 7 }, { 0x0d2e, 7 }, + { 0x0f30, 7 }, { 0x0f31, 7 }, { 0x0f32, 7 }, { 0x0f33, 7 }, + }; + for (unsigned i = 0; + i < (sizeof(intel_gpu_generations)/(sizeof(Device_gen))); + i++) { + if (id == intel_gpu_generations[i].id) + return intel_gpu_generations[i].gen; + }; + + /* + * If we do not find something in the array, we assume its + * generation 8 or higher + */ + return 8; +}; + + +void Driver::pci_intel_graphics_info(Device::Pci_config cfg, + Env & env, + Device_model & model, + Xml_generator & xml) +{ + enum { + GPU_CLASS_MASK = 0xff0000, + GPU_CLASS_ID = 0x030000, + VENDOR_INTEL = 0x8086 + }; + + if (((cfg.class_code & GPU_CLASS_MASK) != GPU_CLASS_ID) || + (cfg.vendor_id != VENDOR_INTEL)) + return; + + /* PCI configuration registers of host bridge */ + struct Host_bridge : Mmio + { + struct Gen_old_gmch_control : Register<0x52, 16> {}; + struct Gen_gmch_control : Register<0x50, 16> {}; + + using Mmio::Mmio; + }; + + /* find host bridge */ + model.for_each([&] (Device const & dev) { + dev.for_pci_config([&] (Device::Pci_config const cfg) { + if (cfg.bus_num || cfg.dev_num || cfg.func_num) + return; + + Attached_io_mem_dataspace io_mem(env, cfg.addr, 0x1000); + Host_bridge config((addr_t)io_mem.local_addr()); + unsigned gen = pci_intel_graphics_generation(cfg.device_id); + uint16_t gmch = 0; + + if (gen < 6) + gmch = config.read(); + else + gmch = config.read(); + + xml.attribute("intel_gmch_control", String<16>(Hex(gmch))); + }); + }); +} diff --git a/repos/os/src/drivers/platform/pci_uhci.h b/repos/os/src/drivers/platform/pci_uhci.h new file mode 100644 index 0000000000..1a4ae82247 --- /dev/null +++ b/repos/os/src/drivers/platform/pci_uhci.h @@ -0,0 +1,119 @@ +/* + * \brief Platform driver - PCI UHCI utilities + * \author Stefan Kalkowski + * \date 2022-06-02 + */ + +/* + * Copyright (C) 2022 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. + */ + +#include +#include +#include + +namespace Driver { + static void pci_uhci_quirks(Env &, Device const &, + Device::Pci_config, addr_t); +} + + +void Driver::pci_uhci_quirks(Env & env, + Device const & dev, + Device::Pci_config cfg, + addr_t base) +{ + enum { UHCI_CLASS_CODE = 0xc0300 }; + + if (cfg.class_code != UHCI_CLASS_CODE) + return; + + /* PCI configuration register for UHCI */ + struct Uhci : Mmio + { + struct Usb_legacy_support : Register<0xc0, 16> + { + struct Trap_by_60h_read_status : Bitfield<8, 1> {}; + struct Trap_by_60h_write_status : Bitfield<9, 1> {}; + struct Trap_by_64h_read_status : Bitfield<10,1> {}; + struct Trap_by_64h_write_status : Bitfield<11,1> {}; + struct Usb_pirq_enable : Bitfield<13,1> {}; + struct End_of_a20gate_pass_through_status : Bitfield<15,1> {}; + }; + + struct Usb_resume_intel : Register<0xc4, 16> {}; + + using Mmio::Mmio; + }; + + /* find uhci controller i/o ports */ + Device::Io_port_range::Range range { 0, 0 }; + dev.for_each_io_port_range([&] (unsigned, Device::Io_port_range::Range r, + Device::Pci_bar) { + if (!range.size) range = r; }); + + Io_port_connection io_ports(env, range.addr, range.size); + Uhci config(base); + + bool have_to_reset = false; + uint16_t UHCI_CMD = range.addr; + uint16_t UHCI_INTR = range.addr + 4; + + struct Uhci_command : Register<16> + { + struct Enable : Bitfield<0,1> {}; + struct Reset : Bitfield<1,1> {}; + struct Global_suspend : Bitfield<3,1> {}; + struct Config : Bitfield<6,1> {}; + }; + + struct Uhci_irq_status : Register<16> + { + struct Resume : Bitfield<1,1> {}; + }; + + using Reg = Uhci::Usb_legacy_support; + + + /*************************** + ** BIOS handover + reset ** + ***************************/ + + Reg::access_t reg = 0; + Reg::Trap_by_60h_read_status::set(reg,1); + Reg::Trap_by_60h_write_status::set(reg,1); + Reg::Trap_by_64h_read_status::set(reg,1); + Reg::Trap_by_64h_write_status::set(reg,1); + Reg::End_of_a20gate_pass_through_status::set(reg,1); + if (config.read() & ~reg) + have_to_reset = true; + + if (!have_to_reset) { + Uhci_command::access_t cmd = io_ports.inw(UHCI_CMD); + if (Uhci_command::Enable::get(cmd) || + !Uhci_command::Config::get(cmd) || + !Uhci_command::Global_suspend::get(cmd)) + have_to_reset = true; + } + + if (!have_to_reset) { + Uhci_irq_status::access_t intr = io_ports.inw(UHCI_INTR); + if (intr & ~Uhci_irq_status::Resume::mask()) + have_to_reset = true; + } + + if (!have_to_reset) + return; + + config.write(reg); + + io_ports.outw(UHCI_CMD, Uhci_command::Reset::bits(1)); + io_ports.outw(UHCI_INTR, 0); + io_ports.outw(UHCI_CMD, 0); + + if (cfg.vendor_id == 0x8086) + config.write(0); +} diff --git a/repos/os/src/drivers/platform/pci_virtio.h b/repos/os/src/drivers/platform/pci_virtio.h new file mode 100644 index 0000000000..19d7ccff8b --- /dev/null +++ b/repos/os/src/drivers/platform/pci_virtio.h @@ -0,0 +1,119 @@ +/* + * \brief Platform driver - PCI Virtio utilities + * \author Stefan Kalkowski + * \date 2022-09-19 + */ + +/* + * Copyright (C) 2022 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. + */ + +#include +#include +#include + +namespace Driver { + void pci_virtio_info(Device const & dev, + Device::Pci_config cfg, + Env & env, + Xml_generator & xml); +} + + +void Driver::pci_virtio_info(Device const & dev, + Device::Pci_config cfg, + Env & env, + Xml_generator & xml) +{ + enum { VENDOR_RED_HAT = 0x1af4 }; + + if (cfg.vendor_id != VENDOR_RED_HAT) + return; + + struct Virtio : Pci::Config + { + struct Capability : Pci::Config::Pci_capability + { + enum { COMMON = 1, NOTIFY = 2, ISR = 3, DEVICE = 4 }; + + struct Type : Register<0x3, 8> {}; + struct Bar : Register<0x4, 8> {}; + struct Offset : Register<0x8, 32> {}; + struct Length : Register<0xc, 32> {}; + struct Offset_factor : Register<0x10, 32> {}; + + using Pci::Config::Pci_capability::Pci_capability; + + bool valid() + { + switch (read()) { + case COMMON: + case NOTIFY: + case ISR: + case DEVICE: + return true; + }; + return false; + } + + String<16> name() + { + switch (read()) { + case COMMON: return "common"; + case NOTIFY: return "notify"; + case ISR: return "irq_status"; + case DEVICE: return "device"; + }; + return "unknown"; + } + }; + + using Pci::Config::Config; + + void capability(Capability & cap, + Driver::Device const & dev, + Xml_generator & xml) + { + unsigned idx = ~0U; + dev.for_each_io_mem([&] (unsigned i, + Driver::Device::Io_mem::Range, + Driver::Device::Pci_bar bar, bool) { + if (bar.number == cap.read()) idx = i; }); + + xml.node("virtio_range", [&] () { + xml.attribute("type", cap.name()); + xml.attribute("index", idx); + xml.attribute("offset", cap.read()); + xml.attribute("size", cap.read()); + if (cap.read() == Capability::NOTIFY) + xml.attribute("factor", + cap.read()); + }); + } + + void for_each_capability(Driver::Device const & dev, + Xml_generator & xml) + { + if (!read()) + return; + + uint16_t off = read(); + while (off) { + Capability cap(base() + off); + if (cap.read() == + Pci_capability::Id::VENDOR && + cap.valid()) + capability(cap, dev, xml); + off = cap.read(); + } + } + }; + + Attached_io_mem_dataspace io_mem(env, cfg.addr, 0x1000); + Virtio config((addr_t)io_mem.local_addr()); + config.for_each_capability(dev, xml); +} + diff --git a/repos/os/src/drivers/platform/power.h b/repos/os/src/drivers/platform/power.h index 676dbd90a7..71039fd56f 100644 --- a/repos/os/src/drivers/platform/power.h +++ b/repos/os/src/drivers/platform/power.h @@ -51,6 +51,13 @@ class Driver::Power : Powers::Element, Interface void on() { _switch.use(); } void off() { _switch.unuse(); } + + struct Guard : Genode::Noncopyable + { + Power &_power; + Guard(Power &power) : _power(power) { _power.on(); } + ~Guard() { _power.off(); } + }; }; #endif /* _POWER_H_ */ diff --git a/repos/os/src/drivers/platform/reset.h b/repos/os/src/drivers/platform/reset.h index e89b6f99d6..f2b61fc389 100644 --- a/repos/os/src/drivers/platform/reset.h +++ b/repos/os/src/drivers/platform/reset.h @@ -51,6 +51,13 @@ class Driver::Reset : Resets::Element, Interface void deassert() { _switch.use(); } void assert() { _switch.unuse(); } + + struct Guard : Genode::Noncopyable + { + Reset &_reset; + Guard(Reset &reset) : _reset(reset) { _reset.deassert(); } + ~Guard() { _reset.assert(); } + }; }; #endif /* _RESET_H_ */ diff --git a/repos/os/src/drivers/platform/session_component.cc b/repos/os/src/drivers/platform/session_component.cc index cefc1ad5da..081ab14ed1 100644 --- a/repos/os/src/drivers/platform/session_component.cc +++ b/repos/os/src/drivers/platform/session_component.cc @@ -24,7 +24,7 @@ Genode::Capability Session_component::_acquire(Device & device) { Device_component * dc = new (heap()) - Device_component(_device_registry, *this, device); + Device_component(_device_registry, _env, *this, _devices, device); device.acquire(*this); return _env.ep().rpc_ep().manage(dc); }; @@ -112,9 +112,6 @@ void Session_component::produce_xml(Xml_generator &xml) } -Genode::Env & Session_component::env() { return _env; } - - Genode::Heap & Session_component::heap() { return _md_alloc; } @@ -156,7 +153,7 @@ Session_component::acquire_single_device() Capability cap; _devices.for_each([&] (Device & dev) { - if (matches(dev) && !dev.owner().valid()) + if (!cap.valid() && matches(dev) && !dev.owner().valid()) cap = _acquire(dev); }); return cap; diff --git a/repos/os/src/drivers/platform/session_component.h b/repos/os/src/drivers/platform/session_component.h index f4a0d63124..dbc91b660a 100644 --- a/repos/os/src/drivers/platform/session_component.h +++ b/repos/os/src/drivers/platform/session_component.h @@ -56,7 +56,6 @@ class Driver::Session_component ~Session_component(); - Env & env(); Heap & heap(); Device_pd & device_pd(); diff --git a/repos/os/src/drivers/platform/shared_irq.cc b/repos/os/src/drivers/platform/shared_irq.cc new file mode 100644 index 0000000000..a87587937d --- /dev/null +++ b/repos/os/src/drivers/platform/shared_irq.cc @@ -0,0 +1,65 @@ +/* + * \brief Platform driver - shared interrupts + * \author Stefan Kalkowski + * \date 2022-09-27 + */ + +/* + * Copyright (C) 2022 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. + */ + +#include + +using Driver::Shared_interrupt; +using Driver::Shared_interrupt_session; + + +void Shared_interrupt::_handle() +{ + _sessions.for_each([&] (Shared_interrupt_session & session) { + session.signal(); }); +} + + +void Shared_interrupt::enable(Irq_session::Trigger mode, + Irq_session::Polarity polarity) +{ + if (!_irq.constructed()) { + _irq.construct(_env, _number, mode, polarity); + _irq->sigh(_handler); + } +} + + +void Shared_interrupt::disable() +{ + unsigned session_count = 0; + _sessions.for_each([&] (Shared_interrupt_session &) { + session_count++; }); + + /* if it is the last session, close the upstream connection */ + if (session_count <= 1) + _irq.destruct(); +} + + +void Shared_interrupt::ack() +{ + unsigned outstanding = 0; + _sessions.for_each([&] (Shared_interrupt_session & session) { + if (session.outstanding()) outstanding++; }); + if (!outstanding) _irq->ack_irq(); +} + + +void Shared_interrupt_session::signal() +{ + if (!_cap.valid()) + return; + + _outstanding = true; + Signal_transmitter(_cap).submit(1); +} diff --git a/repos/os/src/drivers/platform/shared_irq.h b/repos/os/src/drivers/platform/shared_irq.h new file mode 100644 index 0000000000..b7198a01d7 --- /dev/null +++ b/repos/os/src/drivers/platform/shared_irq.h @@ -0,0 +1,110 @@ +/* + * \brief Platform driver - shared interrupts + * \author Stefan Kalkowski + * \date 2022-09-27 + */ + +/* + * Copyright (C) 2022 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 _SRC__DRIVERS__PLATFORM__SHARED_IRQ_H_ +#define _SRC__DRIVERS__PLATFORM__SHARED_IRQ_H_ + +#include +#include +#include + +namespace Driver { + using namespace Genode; + + class Shared_interrupt; + class Shared_interrupt_session; +} + + +class Driver::Shared_interrupt : + private Registry::Element +{ + private: + + Env & _env; + unsigned _number; + Io_signal_handler _handler; + Constructible _irq {}; + Registry _sessions {}; + + void _handle(); + + friend class Shared_interrupt_session; + + public: + + Shared_interrupt(Registry & registry, + Env & env, + unsigned number) + : + Registry::Element(registry, *this), + _env(env), + _number(number), + _handler(env.ep(), *this, &Shared_interrupt::_handle) {} + + unsigned number() const { return _number; } + + void enable(Irq_session::Trigger mode, + Irq_session::Polarity polarity); + void disable(); + void ack(); +}; + + +class Driver::Shared_interrupt_session : + public Rpc_object, + private Registry::Element +{ + private: + + Shared_interrupt & _sirq; + Signal_context_capability _cap {}; + bool _outstanding { true }; + + public: + + Shared_interrupt_session(Shared_interrupt & sirq, + Irq_session::Trigger mode, + Irq_session::Polarity polarity) + : + Registry::Element(sirq._sessions, *this), + _sirq(sirq) + { + sirq.enable(mode, polarity); + } + + ~Shared_interrupt_session() { _sirq.disable(); } + + bool outstanding() { return _outstanding; } + void signal(); + + + /*************************** + ** Irq session interface ** + ***************************/ + + void ack_irq() override + { + _outstanding = false; + _sirq.ack(); + } + + void sigh(Signal_context_capability cap) override { _cap = cap; } + + Info info() override + { + return { .type = Info::Type::INVALID, .address = 0, .value = 0 }; + } +}; + +#endif /* _SRC__DRIVERS__PLATFORM__SHARED_IRQ_H_ */ diff --git a/repos/os/src/drivers/platform/target.inc b/repos/os/src/drivers/platform/target.inc index 15fa2656b4..f6ea60c1aa 100644 --- a/repos/os/src/drivers/platform/target.inc +++ b/repos/os/src/drivers/platform/target.inc @@ -6,6 +6,7 @@ SRC_CC += main.cc SRC_CC += pci.cc SRC_CC += root.cc SRC_CC += session_component.cc +SRC_CC += shared_irq.cc GENERIC_DIR := $(dir $(call select_from_repositories,src/drivers/platform/target.inc)) diff --git a/repos/os/src/drivers/platform/types.h b/repos/os/src/drivers/platform/types.h index 788aac18ee..bc0c07069e 100644 --- a/repos/os/src/drivers/platform/types.h +++ b/repos/os/src/drivers/platform/types.h @@ -20,12 +20,6 @@ namespace Driver { using namespace Genode; - template - static inline bool operator > (String const &s1, String const &s2) - { - return strcmp(s1.string(), s2.string()) > 0; - } - /** * Utility for switching clocks/resets/powers on/off depending on the * number of users @@ -64,7 +58,7 @@ namespace Driver { _count--; - if (--_count == 0) + if (_count == 0) (_dev.*_deactivate)(); } }; diff --git a/repos/os/src/drivers/ps2/irq_handler.h b/repos/os/src/drivers/ps2/irq_handler.h index b1634bb2e5..7aedee4604 100644 --- a/repos/os/src/drivers/ps2/irq_handler.h +++ b/repos/os/src/drivers/ps2/irq_handler.h @@ -16,7 +16,7 @@ /* Genode includes */ #include -#include +#include /* local includes */ #include "input_driver.h" @@ -25,14 +25,14 @@ class Irq_handler { private: - Genode::Irq_session_client _irq; + Platform::Device::Irq _irq; Genode::Signal_handler _handler; Input_driver &_input_driver; Event::Session_client &_event_session; void _handle() { - _irq.ack_irq(); + _irq.ack(); _event_session.with_batch([&] (Event::Session_client::Batch &batch) { while (_input_driver.event_pending()) @@ -42,18 +42,18 @@ class Irq_handler public: - Irq_handler(Genode::Entrypoint &ep, - Input_driver &input_driver, - Event::Session_client &event_session, - Genode::Irq_session_capability irq_cap) + Irq_handler(Genode::Entrypoint &ep, + Input_driver &input_driver, + Event::Session_client &event_session, + Platform::Device &device, + unsigned idx) : - _irq(irq_cap), + _irq(device, {idx}), _handler(ep, *this, &Irq_handler::_handle), _input_driver(input_driver), _event_session(event_session) { _irq.sigh(_handler); - _irq.ack_irq(); } }; diff --git a/repos/os/src/drivers/ps2/x86/i8042.h b/repos/os/src/drivers/ps2/x86/i8042.h index 437004aa25..3105684d7f 100644 --- a/repos/os/src/drivers/ps2/x86/i8042.h +++ b/repos/os/src/drivers/ps2/x86/i8042.h @@ -14,7 +14,7 @@ #ifndef _DRIVERS__INPUT__SPEC__PS2__X86__I8042_H_ #define _DRIVERS__INPUT__SPEC__PS2__X86__I8042_H_ -#include +#include #include #include "serial_interface.h" @@ -179,8 +179,8 @@ class I8042 private: - Genode::Io_port_session_client _data_port; /* data port */ - Genode::Io_port_session_client _stat_port; /* status/command port */ + Platform::Device::Io_port_range _data_port; /* data port */ + Platform::Device::Io_port_range _stat_port; /* status/command port */ bool _kbd_xlate = false; /* translation mode to scan-code set 1 */ @@ -266,11 +266,10 @@ class I8042 /** * Constructor */ - I8042(Genode::Io_port_session_capability cap_data, - Genode::Io_port_session_capability cap_status) + I8042(Platform::Device & device) : - _data_port(cap_data), - _stat_port(cap_status), + _data_port(device, {0}), + _stat_port(device, {1}), _kbd_interface(*this, false), _aux_interface(*this, true) { diff --git a/repos/os/src/drivers/ps2/x86/main.cc b/repos/os/src/drivers/ps2/x86/main.cc index de195f5d9f..ee2160cfa2 100644 --- a/repos/os/src/drivers/ps2/x86/main.cc +++ b/repos/os/src/drivers/ps2/x86/main.cc @@ -18,7 +18,6 @@ /* os includes */ #include -#include #include /* local includes */ @@ -44,21 +43,11 @@ struct Ps2::Main Event::Connection _event { _env }; Platform::Connection _platform { _env }; + Platform::Device _device { _platform }; Timer::Connection _timer { _env }; - Platform::Device_capability _ps2_device_cap() - { - return _platform.with_upgrade([&] () { - return _platform.device("PS2"); }); - } - - Platform::Device_client _device_ps2 { _ps2_device_cap() }; - - enum { REG_IOPORT_DATA = 0, REG_IOPORT_STATUS = 1 }; - - I8042 _i8042 { _device_ps2.io_port(REG_IOPORT_DATA), - _device_ps2.io_port(REG_IOPORT_STATUS) }; + I8042 _i8042 { _device }; Attached_rom_dataspace _config { _env, "config" }; @@ -70,8 +59,8 @@ struct Ps2::Main Mouse _mouse { _i8042.aux_interface(), _timer, *_verbose }; - Irq_handler _keyboard_irq { _env.ep(), _keyboard, _event, _device_ps2.irq(0) }; - Irq_handler _mouse_irq { _env.ep(), _mouse, _event, _device_ps2.irq(1) }; + Irq_handler _keyboard_irq { _env.ep(), _keyboard, _event, _device, 0 }; + Irq_handler _mouse_irq { _env.ep(), _mouse, _event, _device, 1 }; Led_state _capslock { _env, "capslock" }, _numlock { _env, "numlock" }, diff --git a/repos/os/src/drivers/rtc/main.cc b/repos/os/src/drivers/rtc/main.cc index f296424a51..fdeaf71f2b 100644 --- a/repos/os/src/drivers/rtc/main.cc +++ b/repos/os/src/drivers/rtc/main.cc @@ -106,6 +106,9 @@ struct Rtc::Main bool const _set_rtc { _config_rom.xml().attribute_value("allow_setting_rtc", false) }; + bool const _verbose { + _config_rom.xml().attribute_value("verbose", false) }; + Constructible _update_rom { }; struct Invalid_timestamp_xml : Exception {}; @@ -124,7 +127,12 @@ struct Rtc::Main } try { - Rtc::set_time(env, _parse_xml(_config_rom.xml())); + Timestamp ts = _parse_xml(_config_rom.xml()); + + if (_verbose) + Genode::log("set time to ", ts); + + Rtc::set_time(env, ts); } catch (Invalid_timestamp_xml &) {} env.parent().announce(env.ep().manage(root)); @@ -189,7 +197,12 @@ void Rtc::Main::_handle_update() Genode::Xml_node node = _update_rom->xml(); try { - Rtc::set_time(env, _parse_xml(node)); + Timestamp ts = _parse_xml(node); + + if (_verbose) + Genode::log("set time to ", ts); + + Rtc::set_time(env, ts); root.notify_clients(); } catch (Invalid_timestamp_xml &) { Genode::warning("set_rtc: ignoring incomplete RTC update"); } diff --git a/repos/os/src/drivers/usb_block/README b/repos/os/src/drivers/usb_block/README index 6f0f75f5e5..056eb495a0 100644 --- a/repos/os/src/drivers/usb_block/README +++ b/repos/os/src/drivers/usb_block/README @@ -8,16 +8,13 @@ Behavior This driver only supports USB Mass Storage Bulk-Only devices that use the SCSI Block Commands set (direct-access). Devices using different command sets, e.g, SD/HC devices or some external disc drives will not work properly -if at all. The driver will query the device and tries to use the first -bulk-only interface it finds. - -The following configuration snippets demonstrates how to use the driver: +if at all. The following configuration snippets demonstrates how to use the +driver: ! ! ! -! +! ! ! ! @@ -64,8 +61,7 @@ In addition to other attributes that can be used to configure sepecific aspects of the driver. The 'writeable' attribute denotes the permission of the Block session client to write to the USB device. Independent thereof the driver will query the device and will set the Block session operations accordingly. The -'interface' specifies the USB interface the driver should use and 'alt_setting' -allows for selecting the appropriate alternate setting. If the device +'interface' specifies the USB interface the driver should use. If the device provides multiple SCSI devices the 'lun' attribute is used to select the right one. When 'reset_device' is enabled, a 'bulk-only mass storage reset' command is sent to the device at the beginning of the initialization step. This command diff --git a/repos/os/src/drivers/usb_block/main.cc b/repos/os/src/drivers/usb_block/main.cc index c1693d8992..315ffe8c62 100644 --- a/repos/os/src/drivers/usb_block/main.cc +++ b/repos/os/src/drivers/usb_block/main.cc @@ -170,9 +170,6 @@ struct Usb::Block_driver : Usb::Completion uint8_t active_interface = 0; uint8_t active_lun = 0; - enum { INVALID_ALT_SETTING = 256 }; - uint16_t active_alt_setting = 0; - uint32_t active_tag = 0; uint32_t new_tag() { return ++active_tag % 0xffffffu; } @@ -434,43 +431,6 @@ struct Usb::Block_driver : Usb::Completion IPROTO_BULK_ONLY = 80 }; - /* - * Devices following the USB Attached SCSI specification - * normally expose the bulk-only transport in interface 0 alt 0 - * and the UAS endpoints in interface 0 alt 1. - * - * The default interface and thereby 'iface.current()', however, - * might point to the interface 0 alt 1 for such devices. - * - * In case the alternate setting was not explicitly configured - * we look for the first bulk-only setting. - */ - - if (active_alt_setting == INVALID_ALT_SETTING) { - - /* cap value in case there is no bulk-only */ - active_alt_setting = 0; - - for (unsigned i = 0; i < iface.alternate_count(); i++) { - Alternate_interface &aif = iface.alternate_interface(i); - if (aif.iclass == ICLASS_MASS_STORAGE - && aif.isubclass == ISUBCLASS_SCSI - && aif.iprotocol == IPROTO_BULK_ONLY) { - - active_alt_setting = i; - - Genode::log("Use probed alternate setting ", - active_alt_setting, " for interface ", - active_interface); - break; - } - } - } - - Alternate_interface &aif = - iface.alternate_interface((uint8_t)active_alt_setting); - iface.set_alternate_interface(aif); - Alternate_interface &alt_iface = iface.current(); if (alt_iface.iclass != ICLASS_MASS_STORAGE @@ -822,10 +782,6 @@ struct Usb::Block_driver : Usb::Completion active_lun = node.attribute_value("lun", 0UL); reset_device = node.attribute_value("reset_device", false); verbose_scsi = node.attribute_value("verbose_scsi", false); - - active_alt_setting = - node.attribute_value("alt_setting", - (unsigned long)INVALID_ALT_SETTING); } /** diff --git a/repos/os/src/drivers/virtdev_rom/main.cc b/repos/os/src/drivers/virtdev_rom/main.cc index 4ffe0ca69f..bd57092028 100644 --- a/repos/os/src/drivers/virtdev_rom/main.cc +++ b/repos/os/src/drivers/virtdev_rom/main.cc @@ -21,6 +21,9 @@ #include #include +/* local includes */ +#include "platform_config.h" + namespace Virtdev_rom { using namespace Genode; class Session_component; @@ -81,16 +84,7 @@ class Virtdev_rom::Root : public Root_component struct Virtdev_rom::Main { - enum { - /* Taken from include/hw/arm/virt.h in Qemu source tree. */ - NUM_VIRTIO_TRANSPORTS = 32, - /* Taken from hw/arm/virt.c in Qemu source tree. */ - BASE_ADDRESS = 0x0A000000, - DEVICE_SIZE = 0x200, - IRQ_BASE = 48, - VIRTIO_MMIO_MAGIC = 0x74726976, - }; - + enum { VIRTIO_MMIO_MAGIC = 0x74726976 }; enum { MAX_ROM_SIZE = 4096, DEVICE_NAME_LEN = 64 }; Env &_env; @@ -147,7 +141,7 @@ struct Virtdev_rom::Main Device device { _env, BASE_ADDRESS + idx * DEVICE_SIZE, DEVICE_SIZE }; if (device.read() != VIRTIO_MMIO_MAGIC) { - warning("Found non VirtIO MMIO device @ ", addr); + warning("Found non VirtIO MMIO device @ ", Hex(addr)); continue; } diff --git a/repos/os/src/drivers/virtdev_rom/spec/arm/platform_config.h b/repos/os/src/drivers/virtdev_rom/spec/arm/platform_config.h new file mode 100644 index 0000000000..31772d9302 --- /dev/null +++ b/repos/os/src/drivers/virtdev_rom/spec/arm/platform_config.h @@ -0,0 +1,23 @@ +/* + * \brief ARM specific config for virtio device ROM. + * \author Piotr Tworek + * \date 2022-06-12 + */ + +/* + * Copyright (C) 2022 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. + */ + +namespace Virtdev_rom { + enum { + /* Taken from include/hw/arm/virt.h in Qemu source tree. */ + NUM_VIRTIO_TRANSPORTS = 32, + /* Taken from hw/arm/virt.c in Qemu source tree. */ + BASE_ADDRESS = 0x0A000000, + DEVICE_SIZE = 0x200, + IRQ_BASE = 48, + }; +} diff --git a/repos/os/src/drivers/virtdev_rom/spec/arm/target.mk b/repos/os/src/drivers/virtdev_rom/spec/arm/target.mk new file mode 100644 index 0000000000..a5b7d389b1 --- /dev/null +++ b/repos/os/src/drivers/virtdev_rom/spec/arm/target.mk @@ -0,0 +1,5 @@ +REQUIRES = arm + +INC_DIR = $(PRG_DIR) + +include $(REP_DIR)/src/drivers/virtdev_rom/target.inc diff --git a/repos/os/src/drivers/virtdev_rom/spec/arm_64/target.mk b/repos/os/src/drivers/virtdev_rom/spec/arm_64/target.mk new file mode 100644 index 0000000000..27474ca3a8 --- /dev/null +++ b/repos/os/src/drivers/virtdev_rom/spec/arm_64/target.mk @@ -0,0 +1,5 @@ +REQUIRES = arm_64 + +INC_DIR = $(PRG_DIR)/../arm + +include $(REP_DIR)/src/drivers/virtdev_rom/target.inc diff --git a/repos/os/src/drivers/virtdev_rom/spec/riscv/platform_config.h b/repos/os/src/drivers/virtdev_rom/spec/riscv/platform_config.h new file mode 100644 index 0000000000..804ba778aa --- /dev/null +++ b/repos/os/src/drivers/virtdev_rom/spec/riscv/platform_config.h @@ -0,0 +1,23 @@ +/* + * \brief RISC-V specific config for virtio device ROM. + * \author Piotr Tworek + * \date 2022-06-12 + */ + +/* + * Copyright (C) 2022 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. + */ + +namespace Virtdev_rom { + enum { + /* Taken from include/hw/riscv/virt.h in Qemu source tree. */ + NUM_VIRTIO_TRANSPORTS = 8, + IRQ_BASE = 1, + /* Taken from hw/riscv/virt.c in Qemu source tree. */ + BASE_ADDRESS = 0x10001000, + DEVICE_SIZE = 0x1000, + }; +} diff --git a/repos/os/src/drivers/virtdev_rom/spec/riscv/target.mk b/repos/os/src/drivers/virtdev_rom/spec/riscv/target.mk new file mode 100644 index 0000000000..9932022332 --- /dev/null +++ b/repos/os/src/drivers/virtdev_rom/spec/riscv/target.mk @@ -0,0 +1,5 @@ +REQUIRES = riscv + +INC_DIR = $(PRG_DIR) + +include $(REP_DIR)/src/drivers/virtdev_rom/target.inc diff --git a/repos/os/src/drivers/virtdev_rom/target.mk b/repos/os/src/drivers/virtdev_rom/target.inc similarity index 53% rename from repos/os/src/drivers/virtdev_rom/target.mk rename to repos/os/src/drivers/virtdev_rom/target.inc index b4a142362a..14bf820da2 100644 --- a/repos/os/src/drivers/virtdev_rom/target.mk +++ b/repos/os/src/drivers/virtdev_rom/target.inc @@ -1,3 +1,5 @@ TARGET = virtdev_rom SRC_CC = main.cc LIBS = base + +vpath main.cc $(REP_DIR)/src/drivers/virtdev_rom diff --git a/repos/os/src/init/main.cc b/repos/os/src/init/main.cc index a3fa95de0a..4f13681880 100644 --- a/repos/os/src/init/main.cc +++ b/repos/os/src/init/main.cc @@ -49,7 +49,7 @@ struct Init::Main : Sandbox::State_handler Xml_node const config = _config.xml(); bool reporter_enabled = false; - config.with_sub_node("report", [&] (Xml_node report) { + config.with_optional_sub_node("report", [&] (Xml_node report) { reporter_enabled = true; diff --git a/repos/os/src/lib/genode_c_api/event.cc b/repos/os/src/lib/genode_c_api/event.cc index 2be248ef39..87834ad32f 100644 --- a/repos/os/src/lib/genode_c_api/event.cc +++ b/repos/os/src/lib/genode_c_api/event.cc @@ -1,6 +1,7 @@ /* * \brief C interface to Genode's event session * \author Norman Feske + * \author Christian Helmuth * \date 2021-09-29 */ @@ -72,6 +73,24 @@ namespace { fn(static_cast(myself)->batch); } + static void _press(struct genode_event_submit *myself, unsigned keycode) + { + _with_batch(myself, [&] (Event::Session_client::Batch &batch) { + batch.submit(Input::Press { Input::Keycode(keycode) }); }); + } + + static void _release(struct genode_event_submit *myself, unsigned keycode) + { + _with_batch(myself, [&] (Event::Session_client::Batch &batch) { + batch.submit(Input::Release { Input::Keycode(keycode) }); }); + } + + static void _rel_motion(struct genode_event_submit *myself, int x, int y) + { + _with_batch(myself, [&] (Event::Session_client::Batch &batch) { + batch.submit(Input::Relative_motion { x, y }); }); + } + static void _touch(struct genode_event_submit *myself, struct genode_event_touch_args const *args) { @@ -94,6 +113,9 @@ namespace { : batch(batch) { + press = _press; + release = _release; + rel_motion = _rel_motion; touch = _touch; touch_release = _touch_release; }; diff --git a/repos/os/src/lib/genode_c_api/usb.cc b/repos/os/src/lib/genode_c_api/usb.cc index 84138e872a..a31fd05d27 100644 --- a/repos/os/src/lib/genode_c_api/usb.cc +++ b/repos/os/src/lib/genode_c_api/usb.cc @@ -46,6 +46,24 @@ struct Device { }; +class Session_id +{ + private: + + genode_usb_session_handle_t const _id; + unsigned _ref_cnt { 0 }; + + public: + + Session_id(genode_usb_session_handle_t id) : _id(id) {} + + genode_usb_session_handle_t id() { return _id; } + + void inc() { _ref_cnt++; } + void dec() { _ref_cnt--; } + bool used() { return _ref_cnt; } +}; + class Root; @@ -62,7 +80,7 @@ class genode_usb_session : public Usb::Session_rpc_object ::Root & _root; genode_shared_dataspace * _ds; Signal_context_capability _sigh_state_cap {}; - genode_usb_session_handle_t _id; + Session_id & _id; Session_label const _label; List_element _le { this }; @@ -79,8 +97,8 @@ class genode_usb_session : public Usb::Session_rpc_object genode_usb_session(::Root & root, genode_shared_dataspace * ds, Env & env, + Session_id & id, Signal_context_capability cap, - genode_usb_session_handle_t id, Session_label label); virtual ~genode_usb_session() {} @@ -143,17 +161,7 @@ class Root : public Root_component { private: - enum { MAX_DEVICES = 32 }; - - struct Id_allocator : Bit_allocator<16> - { - genode_usb_session_handle_t alloc() - { - /* we can downcast here, because we only use 16 bits */ - return (genode_usb_session_handle_t) - Bit_allocator<16>::alloc(); - } - }; + enum { MAX_DEVICES = 32, MAX_SESSIONS = MAX_DEVICES }; Env & _env; Signal_context_capability _sigh_cap; @@ -161,12 +169,13 @@ class Root : public Root_component Signal_handler _config_handler { _env.ep(), *this, &Root::_announce_service }; Reporter _config_reporter { _env, "config" }; - Reporter _device_reporter { _env, "devices" }; + Constructible _session_ids[MAX_SESSIONS]; Constructible _devices[MAX_DEVICES]; - List> _sessions {}; - Id_allocator _id_alloc {}; bool _announced { false }; + Constructible _device_reporter {}; + List> _sessions {}; + Root(const Root&); Root & operator=(const Root&); @@ -243,6 +252,8 @@ class Root : public Root_component * Acknowledge requests from sessions without device */ void handle_empty_sessions(); + + void decrement_session_id(genode_usb_session_handle_t id); }; @@ -444,42 +455,40 @@ bool genode_usb_session::request(genode_usb_request_callbacks & req, void * data void * addr = (void*)(genode_shared_dataspace_local_address(_ds) + offset); + packets[idx].construct(p); + _id.inc(); /* increment the session ids usage */ + switch (p.type) { case Packet_descriptor::STRING: - _ack(req.string_fn((genode_usb_request_string*)&p.string, - addr, p.size(), data), p); + req.string_fn((genode_usb_request_string*)&p.string, + _id.id(), idx, addr, p.size(), data); break; case Packet_descriptor::CTRL: - _ack(req.control_fn((genode_usb_request_control*)&p.control, - addr, p.size(), data), p); + req.urb_fn({ CTRL, &p.control }, _id.id(), idx, addr, p.size(), data); break; case Packet_descriptor::BULK: - packets[idx].construct(p); - req.transfer_fn((genode_usb_request_transfer*)&p.transfer, BULK, - _id, idx, addr, p.size(), data); + req.urb_fn({ BULK, &p.transfer }, _id.id(), idx, addr, p.size(), data); break; case Packet_descriptor::IRQ: - packets[idx].construct(p); - req.transfer_fn((genode_usb_request_transfer*)&p.transfer, IRQ, - _id, idx, addr, p.size(), data); + req.urb_fn({ IRQ, &p.transfer }, _id.id(), idx, addr, p.size(), data); break; case Packet_descriptor::ISOC: - packets[idx].construct(p); - req.transfer_fn((genode_usb_request_transfer*)&p.transfer, ISOC, - _id, idx, addr, p.size(), data); + req.urb_fn({ ISOC, &p.transfer }, _id.id(), idx, addr, p.size(), data); break; case Packet_descriptor::ALT_SETTING: - _ack(req.altsetting_fn(p.interface.number, - p.interface.alt_setting, data), p); + req.altsetting_fn(p.interface.number, p.interface.alt_setting, + _id.id(), idx, data); break; case Packet_descriptor::CONFIG: - _ack(req.config_fn(p.number, data), p); + req.config_fn(p.number, _id.id(), idx, data); break; case Packet_descriptor::RELEASE_IF: warning("Release interface gets ignored!"); + _id.dec(); + packets[idx].destruct(); break; case Packet_descriptor::FLUSH_TRANSFERS: - _ack(req.flush_fn(p.number, data), p); + req.flush_fn(p.number, _id.id(), idx, data); break; }; @@ -491,9 +500,25 @@ void genode_usb_session::handle_response(genode_usb_request_handle_t id, genode_usb_response_t callback, void * callback_data) { - Usb::Packet_descriptor p = *packets[id]; - _ack(callback((genode_usb_request_transfer*)&p.transfer, - callback_data), p); + using Packet_descriptor = Usb::Packet_descriptor; + + Packet_descriptor p = *packets[id]; + switch (p.type) { + case Packet_descriptor::CTRL: + _ack(callback({ CTRL, &p.control }, callback_data), p); + break; + case Packet_descriptor::BULK: + _ack(callback({ BULK, &p.transfer }, callback_data), p); + break; + case Packet_descriptor::IRQ: + _ack(callback({ IRQ, &p.transfer }, callback_data), p); + break; + case Packet_descriptor::ISOC: + _ack(callback({ ISOC, &p.transfer }, callback_data), p); + break; + default: + _ack(callback({ NONE, nullptr }, callback_data), p); + }; packets[id].destruct(); } @@ -501,8 +526,8 @@ void genode_usb_session::handle_response(genode_usb_request_handle_t id, genode_usb_session::genode_usb_session(::Root & root, genode_shared_dataspace * ds, Env & env, + Session_id & id, Signal_context_capability cap, - genode_usb_session_handle_t id, Session_label const label) : Usb::Session_rpc_object(genode_shared_dataspace_capability(ds), @@ -513,6 +538,8 @@ genode_usb_session::genode_usb_session(::Root & root, _label(label) { _tx.sigh_packet_avail(cap); + + id.inc(); } @@ -555,20 +582,24 @@ genode_usb_session * ::Root::_create_session(const char * args, if (!tx_buf_size) throw Service_denied(); - /* check session quota */ - size_t session_size = max(4096, sizeof(genode_usb_session)); - if (ram_quota < session_size) - throw Insufficient_ram_quota(); - - if (tx_buf_size > ram_quota - session_size) { + if (tx_buf_size > ram_quota) { warning("Insufficient RAM quota, got ", ram_quota, " need ", - tx_buf_size + session_size); + tx_buf_size); throw Insufficient_ram_quota(); } + unsigned i = 0; + for (; i < MAX_SESSIONS; i++) + if (!_session_ids[i]->used()) + break; + if (i >= MAX_SESSIONS) { + warning("Maximum of sessions reached!"); + throw Service_denied(); + } + genode_shared_dataspace * ds = _callbacks->alloc_fn(tx_buf_size); genode_usb_session * ret = new (md_alloc()) - genode_usb_session(*this, ds, _env, _sigh_cap, _id_alloc.alloc(), label); + genode_usb_session(*this, ds, _env, *_session_ids[i], _sigh_cap, label); _sessions.insert(&ret->_le); if (!ret) throw Service_denied(); @@ -594,11 +625,10 @@ void ::Root::_destroy_session(genode_usb_session * session) } }); - genode_usb_session_handle_t id = session->_id; + session->_id.dec(); genode_shared_dataspace * ds = session->_ds; _sessions.remove(&session->_le); Genode::destroy(md_alloc(), session); - _id_alloc.free((addr_t)id); _callbacks->free_fn(ds); } @@ -607,7 +637,10 @@ void ::Root::_report() { using Value = String<64>; - Reporter::Xml_generator xml(_device_reporter, [&] () { + if (!_device_reporter.constructed()) + return; + + _device_reporter->generate([&] (Reporter::Xml_generator &xml) { _for_each_device([&] (Device & d) { xml.node("device", [&] { xml.attribute("label", d.label()); @@ -669,8 +702,10 @@ void ::Root::_announce_service() /* * Check for report policy, and resp. con-/destruct device reporter */ - _config.xml().with_sub_node("report", [&] (Xml_node node) { - _device_reporter.enabled(node.attribute_value("devices", false)); + _config.xml().with_optional_sub_node("report", [&] (Xml_node node) { + _device_reporter.conditional(node.attribute_value("devices", false), + _env, "devices", "devices" ); + _config_reporter.enabled(node.attribute_value("config", false)); }); @@ -752,16 +787,26 @@ genode_usb_session_handle_t ::Root::session(genode_usb_bus_num_t bus, session = d.usb_session; }); - return session ? session->_id : 0; + return session ? session->_id.id() : 0; } template void ::Root::session(genode_usb_session_handle_t id, FUNC const & fn) { + genode_usb_session * session = nullptr; + _for_each_session([&] (genode_usb_session & s) { - if (s._id == id) fn(s); + if (s._id.id() == id) session = &s; }); + + /* + * We've to execute the functor outside the session iteration, + * because the functor might block and the actual session + * can be destroyed in the meantime, which will lead to + * a corrupted next() pointer. + */ + if (session) fn(*session); } @@ -793,13 +838,22 @@ void ::Root::handle_empty_sessions() } +void ::Root::decrement_session_id(genode_usb_session_handle_t id) +{ + if (id > 0 && id <= MAX_SESSIONS) + _session_ids[id-1]->dec(); +} + + ::Root::Root(Env & env, Allocator & alloc, Signal_context_capability cap) : Root_component(env.ep(), alloc), _env(env), _sigh_cap(cap) { /* Reserve id zero which is invalid */ - _id_alloc.alloc(); + for (unsigned i = 0; i < MAX_SESSIONS; i++) + _session_ids[i].construct((genode_usb_session_handle_t)(i+1)); + _config.sigh(_config_handler); } @@ -873,6 +927,8 @@ extern "C" void genode_usb_ack_request(genode_usb_session_handle_t session_id, _usb_root->session(session_id, [&] (genode_usb_session & session) { session.handle_response(request_id, callback, callback_data); }); + + _usb_root->decrement_session_id(session_id); } diff --git a/repos/os/src/lib/net/internet_checksum.cc b/repos/os/src/lib/net/internet_checksum.cc index 6d18505488..0580337e90 100644 --- a/repos/os/src/lib/net/internet_checksum.cc +++ b/repos/os/src/lib/net/internet_checksum.cc @@ -17,6 +17,11 @@ using namespace Net; using namespace Genode; + +/************************** + ** Unit-local utilities ** + **************************/ + struct Packed_uint8 { Genode::uint8_t value; @@ -24,32 +29,47 @@ struct Packed_uint8 } __attribute__((packed)); -uint16_t Net::internet_checksum(Packed_uint16 const *addr, - size_t size, - addr_t init_sum) +static void fold_checksum_to_16_bits(signed long &sum) +{ + while (addr_t const remainder = sum >> 16) { + sum = (sum & 0xffff) + remainder; + } +} + + +static uint16_t checksum_of_raw_data(Packed_uint16 const *data_ptr, + size_t data_sz, + signed long sum) { /* add up bytes in pairs */ - addr_t sum = init_sum; - for (; size > 1; size -= sizeof(Packed_uint16)) { - sum += addr->value; - addr++; + for (; data_sz > 1; data_sz -= sizeof(Packed_uint16)) { + sum += data_ptr->value; + data_ptr++; } - /* add left-over byte, if any */ - if (size > 0) - sum += ((Packed_uint8 const *)addr)->value; - - /* fold sum to 16-bit value */ - while (addr_t const sum_rsh = sum >> 16) - sum = (sum & 0xffff) + sum_rsh; + if (data_sz > 0) { + sum += ((Packed_uint8 const *)data_ptr)->value; + } + fold_checksum_to_16_bits(sum); /* return one's complement */ return (uint16_t)(~sum); } -uint16_t Net::internet_checksum_pseudo_ip(Packed_uint16 const *ip_data, - size_t ip_data_sz, +/*********************** + ** Internet_checksum ** + ***********************/ + +uint16_t Net::internet_checksum(Packed_uint16 const *data_ptr, + size_t data_sz) +{ + return checksum_of_raw_data(data_ptr, data_sz, 0); +} + + +uint16_t Net::internet_checksum_pseudo_ip(Packed_uint16 const *data_ptr, + size_t data_sz, uint16_t ip_data_sz_be, Ipv4_packet::Protocol ip_prot, Ipv4_address &ip_src, @@ -63,10 +83,41 @@ uint16_t Net::internet_checksum_pseudo_ip(Packed_uint16 const *ip_data, * | 4 bytes | 4 bytes | 1 byte | 1 byte | 2 bytes | * -------------------------------------------------------------- */ - addr_t sum = host_to_big_endian((uint16_t)ip_prot) + ip_data_sz_be; + signed long sum { host_to_big_endian((uint16_t)ip_prot) + ip_data_sz_be }; for (size_t i = 0; i < Ipv4_packet::ADDR_LEN; i += 2) sum += *(uint16_t*)&ip_src.addr[i] + *(uint16_t*)&ip_dst.addr[i]; - /* add up IP data bytes */ - return internet_checksum(ip_data, ip_data_sz, sum); + /* add up data bytes */ + return checksum_of_raw_data(data_ptr, data_sz, sum); +} + + +/**************************** + ** Internet_checksum_diff ** + ****************************/ + +void Internet_checksum_diff::add_up_diff(Packed_uint16 const *new_data_ptr, + Packed_uint16 const *old_data_ptr, + size_t data_sz) +{ + /* add up byte differences in pairs */ + signed long diff { 0 }; + for (; data_sz > 1; data_sz -= sizeof(Packed_uint16)) { + diff += old_data_ptr->value - new_data_ptr->value; + old_data_ptr++; + new_data_ptr++; + } + /* add difference of left-over byte, if any */ + if (data_sz > 0) { + diff += *(uint8_t *)old_data_ptr - *(uint8_t *)new_data_ptr; + } + _value += diff; +} + + +uint16_t Internet_checksum_diff::apply_to(signed long sum) const +{ + sum += _value; + fold_checksum_to_16_bits(sum); + return (uint16_t)sum; } diff --git a/repos/os/src/lib/net/ipv4.cc b/repos/os/src/lib/net/ipv4.cc index e4383c54c8..e2e0f1bbca 100644 --- a/repos/os/src/lib/net/ipv4.cc +++ b/repos/os/src/lib/net/ipv4.cc @@ -41,6 +41,12 @@ void Net::Ipv4_packet::print(Genode::Output &output) const } +bool Ipv4_address::is_multicast() const +{ + return (addr[0] & 0xf0) == 0b11100000; +} + + bool Ipv4_address::is_in_range(Ipv4_address const &first, Ipv4_address const &last) const { @@ -156,3 +162,23 @@ size_t Ipv4_packet::size(size_t max_size) const size_t const stated_size = total_length(); return stated_size < max_size ? stated_size : max_size; } + + +void Ipv4_packet::src(Ipv4_address v, Internet_checksum_diff &icd) +{ + icd.add_up_diff((Packed_uint16 *)&v.addr[0], (Packed_uint16 *)&_src[0], 4); + src(v); +} + + +void Ipv4_packet::dst(Ipv4_address v, Internet_checksum_diff &icd) +{ + icd.add_up_diff((Packed_uint16 *)&v.addr[0], (Packed_uint16 *)&_dst[0], 4); + dst(v); +} + + +void Ipv4_packet::update_checksum(Internet_checksum_diff const &icd) +{ + _checksum = icd.apply_to(_checksum); +} diff --git a/repos/os/src/lib/sandbox/child.cc b/repos/os/src/lib/sandbox/child.cc index 7096516fe1..b6d5cfb62c 100644 --- a/repos/os/src/lib/sandbox/child.cc +++ b/repos/os/src/lib/sandbox/child.cc @@ -66,8 +66,8 @@ Sandbox::Child::apply_config(Xml_node start_node) * The node may affect the availability or unavailability * of dependencies. */ - start_node.with_sub_node("route", [&] (Xml_node const &route) { - _start_node->xml().with_sub_node("route", [&] (Xml_node const &orig) { + start_node.with_optional_sub_node("route", [&] (Xml_node const &route) { + _start_node->xml().with_optional_sub_node("route", [&] (Xml_node const &orig) { if (route.differs_from(orig)) { _construct_route_model_from_start_node(start_node); _uncertain_dependencies = true; } }); }); diff --git a/repos/os/src/lib/sandbox/child.h b/repos/os/src/lib/sandbox/child.h index e192d9126f..b4a612624a 100644 --- a/repos/os/src/lib/sandbox/child.h +++ b/repos/os/src/lib/sandbox/child.h @@ -126,13 +126,11 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup { _route_model.destruct(); - start.with_sub_node("route", [&] (Xml_node const &route) { - _route_model.construct(_alloc, route); }); - - if (_route_model.constructed()) - return; - - _route_model.construct(_alloc, _default_route_accessor.default_route()); + start.with_sub_node("route", + [&] (Xml_node const &route) { + _route_model.construct(_alloc, route); }, + [&] () { + _route_model.construct(_alloc, _default_route_accessor.default_route()); }); } /* diff --git a/repos/os/src/lib/sandbox/config_model.h b/repos/os/src/lib/sandbox/config_model.h index 30d14a7430..5a007970fe 100644 --- a/repos/os/src/lib/sandbox/config_model.h +++ b/repos/os/src/lib/sandbox/config_model.h @@ -73,6 +73,11 @@ struct Sandbox::Parent_provides_model : Noncopyable _alloc(alloc), _verbose(verbose), _factory(factory) { } + ~Parent_provides_model() + { + update_from_xml(Xml_node("")); + } + void update_from_xml(Xml_node const &xml) { bool first_log = true; diff --git a/repos/os/src/lib/sandbox/utils.h b/repos/os/src/lib/sandbox/utils.h index 90bb177a4d..cba9ca5d2c 100644 --- a/repos/os/src/lib/sandbox/utils.h +++ b/repos/os/src/lib/sandbox/utils.h @@ -213,7 +213,7 @@ namespace Sandbox { Location result = Location(0, 0, space.width(), space.height()); - start_node.with_sub_node("affinity", [&] (Xml_node node) { + start_node.with_optional_sub_node("affinity", [&] (Xml_node node) { Location const location = Location::from_xml(space, node); diff --git a/repos/os/src/lib/vfs/capture/target.mk b/repos/os/src/lib/vfs/capture/target.mk deleted file mode 100644 index 31e9307f89..0000000000 --- a/repos/os/src/lib/vfs/capture/target.mk +++ /dev/null @@ -1,4 +0,0 @@ -TARGET = dummy-vfs_capture -LIBS = vfs_capture - -BUILD_ARTIFACTS := diff --git a/repos/os/src/lib/vfs/fs_file_system.h b/repos/os/src/lib/vfs/fs_file_system.h index 5dfdb687e9..8009ed71ae 100644 --- a/repos/os/src/lib/vfs/fs_file_system.h +++ b/repos/os/src/lib/vfs/fs_file_system.h @@ -754,13 +754,11 @@ class Vfs::Fs_file_system : public File_system path = "/"; try { - ::File_system::Node_handle node = _fs.node(path); - Fs_handle_guard node_guard(*this, _fs, node, + ::File_system::Dir_handle dir = _fs.dir(path, false); + Fs_handle_guard node_guard(*this, _fs, dir, _handle_space, _fs); - ::File_system::Status status = _fs.status(node); - - return status.size / sizeof(::File_system::Directory_entry); + return _fs.num_entries(dir); } catch (...) { } return 0; diff --git a/repos/os/src/lib/vfs/rtc_file_system.h b/repos/os/src/lib/vfs/rtc_file_system.h index 3d2449edbc..866e9fb180 100644 --- a/repos/os/src/lib/vfs/rtc_file_system.h +++ b/repos/os/src/lib/vfs/rtc_file_system.h @@ -27,8 +27,8 @@ class Vfs::Rtc_file_system : public Single_file_system { private: - /* "1970-01-01 00:00\n" */ - enum { TIMESTAMP_LEN = 17 }; + /* "1970-01-01 00:00:00\n" */ + enum { TIMESTAMP_LEN = 20 }; class Rtc_vfs_handle : public Single_vfs_handle { @@ -49,7 +49,7 @@ class Vfs::Rtc_file_system : public Single_file_system * Read the current time from the Rtc session * * On each read the current time is queried and afterwards formated - * as '%Y-%m-%d %H:%M\n'. + * as '%Y-%m-%d %H:%M:%S\n' resp. '%F %T\n'. */ Read_result read(char *dst, file_size count, file_size &out_count) override @@ -63,8 +63,8 @@ class Vfs::Rtc_file_system : public Single_file_system char buf[TIMESTAMP_LEN+1]; char *b = buf; - Genode::size_t n = Genode::snprintf(buf, sizeof(buf), "%04u-%02u-%02u %02u:%02u\n", - ts.year, ts.month, ts.day, ts.hour, ts.minute); + Genode::size_t n = Genode::snprintf(buf, sizeof(buf), "%04u-%02u-%02u %02u:%02u:%02u\n", + ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second); n -= (size_t)seek(); b += seek(); diff --git a/repos/os/src/lib/vfs/tap/README b/repos/os/src/lib/vfs/tap/README index 0f4d8d340a..86eab21515 100644 --- a/repos/os/src/lib/vfs/tap/README +++ b/repos/os/src/lib/vfs/tap/README @@ -1,4 +1,4 @@ -The VFS TAP plugin offers access to Genode's Uplink by providing +The VFS TAP plugin offers access to Genode's Uplink/Nic session by providing a special file system. It exposes a data file that reflects a _/dev/tap0_ file. The support of I/O control operations is provided in form of a structured 'info' file located in the directory named after the data file, e.g. @@ -21,12 +21,14 @@ be provided: * :label: Sets the session label of the Uplink/Nic session. If not provided, an empty label is used. * :mac: Sets the default mac address. + * :mode: If set to 'uplink_client', the plugin uses an Uplink session. + Otherwise, it will open a Nic session. The following config snippet illustrates its configuration: ! ! -! +! ! ! diff --git a/repos/os/src/lib/vfs/tap/target.mk b/repos/os/src/lib/vfs/tap/target.mk deleted file mode 100644 index 46dfa30eca..0000000000 --- a/repos/os/src/lib/vfs/tap/target.mk +++ /dev/null @@ -1,4 +0,0 @@ -TARGET = dummy-vfs_tap -LIBS = vfs_tap - -BUILD_ARTIFACTS := diff --git a/repos/os/src/server/black_hole/audio_in.h b/repos/os/src/server/black_hole/audio_in.h index d9070036dd..411528dd0a 100644 --- a/repos/os/src/server/black_hole/audio_in.h +++ b/repos/os/src/server/black_hole/audio_in.h @@ -127,12 +127,9 @@ class Audio_in::Root : public Audio_in::Root_component size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); - size_t session_size = align_addr(sizeof(Session_component), 12); - - if ((ram_quota < session_size) || - (sizeof(Stream) > ram_quota - session_size)) { + if (sizeof(Stream) > ram_quota) { Genode::error("insufficient 'ram_quota', got ", ram_quota, ", " - "need ", sizeof(Stream) + session_size); + "need ", sizeof(Stream)); throw Insufficient_ram_quota(); } diff --git a/repos/os/src/server/black_hole/audio_out.h b/repos/os/src/server/black_hole/audio_out.h index 0c105987cd..3ccf19fe92 100644 --- a/repos/os/src/server/black_hole/audio_out.h +++ b/repos/os/src/server/black_hole/audio_out.h @@ -130,12 +130,9 @@ class Audio_out::Root : public Audio_out::Root_component size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); - size_t session_size = align_addr(sizeof(Session_component), 12); - - if ((ram_quota < session_size) || - (sizeof(Stream) > ram_quota - session_size)) { + if (sizeof(Stream) > ram_quota) { Genode::error("insufficient 'ram_quota', got ", ram_quota, ", " - "need ", sizeof(Stream) + session_size); + "need ", sizeof(Stream)); throw Insufficient_ram_quota(); } diff --git a/repos/os/src/server/black_hole/capture.h b/repos/os/src/server/black_hole/capture.h index 598c24d467..474981a6e4 100644 --- a/repos/os/src/server/black_hole/capture.h +++ b/repos/os/src/server/black_hole/capture.h @@ -107,17 +107,6 @@ class Capture::Root : public Capture::Root_component { using namespace Genode; - size_t ram_quota = - Arg_string::find_arg(args, "ram_quota").ulong_value(0); - - size_t session_size = align_addr(sizeof(Session_component), 12); - - if ((ram_quota < session_size)) { - Genode::error("insufficient 'ram_quota', got ", ram_quota, ", " - "need ", session_size); - throw Insufficient_ram_quota(); - } - Session_component *session = new (md_alloc()) Session_component(_env, session_resources_from_args(args), @@ -125,7 +114,6 @@ class Capture::Root : public Capture::Root_component session_diag_from_args(args)); return session; - } void _upgrade_session(Session_component *s, const char *args) override diff --git a/repos/os/src/server/black_hole/gpu.h b/repos/os/src/server/black_hole/gpu.h index cb8c0dff37..7a624c201a 100644 --- a/repos/os/src/server/black_hole/gpu.h +++ b/repos/os/src/server/black_hole/gpu.h @@ -113,6 +113,11 @@ class Black_hole::Gpu_session : public Session_object Gpu::addr_t /* va */) override { } + Gpu::addr_t query_buffer_ppgtt(Buffer_id /* id */) override + { + return (Gpu::addr_t)-1; + } + bool set_tiling(Buffer_id /* id */, uint32_t const /* mode */) override { diff --git a/repos/os/src/server/black_hole/nic.h b/repos/os/src/server/black_hole/nic.h index 4b5e5b104b..5fe7dbff96 100644 --- a/repos/os/src/server/black_hole/nic.h +++ b/repos/os/src/server/black_hole/nic.h @@ -83,19 +83,14 @@ class Black_hole::Nic_root : public Root_component size_t tx_buf_size = Arg_string::find_arg(args, "tx_buf_size").ulong_value(0); size_t rx_buf_size = Arg_string::find_arg(args, "rx_buf_size").ulong_value(0); - /* deplete ram quota by the memory needed for the session structure */ - size_t session_size = max(4096UL, (size_t)sizeof(Nic_session)); - if (ram_quota < session_size) - throw Insufficient_ram_quota(); - /* * Check if donated ram quota suffices for both communication * buffers and check for overflow */ if (tx_buf_size + rx_buf_size < tx_buf_size || - tx_buf_size + rx_buf_size > ram_quota - session_size) { + tx_buf_size + rx_buf_size > ram_quota) { error("insufficient 'ram_quota', got ", ram_quota, ", " - "need ", tx_buf_size + rx_buf_size + session_size); + "need ", tx_buf_size + rx_buf_size); throw Insufficient_ram_quota(); } diff --git a/repos/os/src/server/black_hole/uplink.h b/repos/os/src/server/black_hole/uplink.h index 6cb65d6548..390642083f 100644 --- a/repos/os/src/server/black_hole/uplink.h +++ b/repos/os/src/server/black_hole/uplink.h @@ -138,19 +138,14 @@ class Black_hole::Uplink_root : public Root_component size_t tx_buf_size = Arg_string::find_arg(args, "tx_buf_size").ulong_value(0); size_t rx_buf_size = Arg_string::find_arg(args, "rx_buf_size").ulong_value(0); - /* deplete ram quota by the memory needed for the session structure */ - size_t session_size = max(4096UL, (size_t)sizeof(Uplink_session)); - if (ram_quota < session_size) - throw Insufficient_ram_quota(); - /* * Check if donated ram quota suffices for both communication * buffers and check for overflow */ if (tx_buf_size + rx_buf_size < tx_buf_size || - tx_buf_size + rx_buf_size > ram_quota - session_size) { + tx_buf_size + rx_buf_size > ram_quota) { error("insufficient 'ram_quota', got ", ram_quota, ", " - "need ", tx_buf_size + rx_buf_size + session_size); + "need ", tx_buf_size + rx_buf_size); throw Insufficient_ram_quota(); } diff --git a/repos/os/src/server/black_hole/usb.h b/repos/os/src/server/black_hole/usb.h index a61f688727..676e938b4f 100644 --- a/repos/os/src/server/black_hole/usb.h +++ b/repos/os/src/server/black_hole/usb.h @@ -85,10 +85,7 @@ class Black_hole::Usb_root : public Root_component size_t const tx_buf_size { Arg_string::find_arg(args, "tx_buf_size").ulong_value(0) }; - size_t const session_size { - max(4096, sizeof(Usb_session)) }; - - if (ram_quota < session_size + tx_buf_size) { + if (ram_quota < tx_buf_size) { throw Insufficient_ram_quota { }; } Ram_dataspace_capability tx_ds { _env.ram().alloc(tx_buf_size) }; diff --git a/repos/os/src/server/cached_fs_rom/main.cc b/repos/os/src/server/cached_fs_rom/main.cc index cae731c3cd..5afb7cf95e 100755 --- a/repos/os/src/server/cached_fs_rom/main.cc +++ b/repos/os/src/server/cached_fs_rom/main.cc @@ -167,7 +167,7 @@ struct Cached_fs_rom::Transfer final if (!_fs.tx()->ready_to_submit()) throw Packet_alloc_failed(); - size_t chunk_size = (size_t)min(_size, _fs.tx()->bulk_buffer_size()/4); + size_t chunk_size = (size_t)min(_size, _fs.tx()->bulk_buffer_size()/2); return _fs.tx()->alloc_packet(chunk_size); } @@ -280,7 +280,7 @@ struct Cached_fs_rom::Main final : Genode::Session_request_handler Heap heap { env.pd(), env.rm() }; Allocator_avl fs_tx_block_alloc { &heap }; - File_system::Connection fs { env, fs_tx_block_alloc }; + File_system::Connection fs { env, fs_tx_block_alloc, "", "/", false, 4*1024*1024 }; Session_requests_rom session_requests { env, *this }; diff --git a/repos/os/src/server/event_filter/README b/repos/os/src/server/event_filter/README index 134c95d1af..f01d745511 100644 --- a/repos/os/src/server/event_filter/README +++ b/repos/os/src/server/event_filter/README @@ -86,6 +86,14 @@ one of the following filters: touch input. The original touch events are preserved, enabling touch-aware applications to interpet touch gestures. +:: + + Triggers an artificial key tap (a press event followed by a release event) + when touching a preconfigured area on a touch screen. The filter node can + host any number of '' sub nodes. Each sub node must define a + rectangular area - using the attributes 'xpos', 'ypos', 'width', and + 'height' - and the name of the tapped key as 'key' attribute. + Character generator rules ------------------------- diff --git a/repos/os/src/server/event_filter/main.cc b/repos/os/src/server/event_filter/main.cc index e2fbcfda79..c9fae9fa7c 100644 --- a/repos/os/src/server/event_filter/main.cc +++ b/repos/os/src/server/event_filter/main.cc @@ -26,6 +26,7 @@ #include #include #include +#include #include namespace Event_filter { struct Main; } @@ -254,6 +255,9 @@ struct Event_filter::Main : Source::Factory, Source::Trigger if (node.type() == Touch_click_source::name()) return *new (_heap) Touch_click_source(owner, node, *this); + if (node.type() == Touch_key_source::name()) + return *new (_heap) Touch_key_source(owner, node, *this, _heap); + warning("unknown <", node.type(), "> input-source node type"); throw Source::Invalid_config(); } diff --git a/repos/os/src/server/event_filter/source.h b/repos/os/src/server/event_filter/source.h index 629ff0cc89..4ecda4c7b7 100644 --- a/repos/os/src/server/event_filter/source.h +++ b/repos/os/src/server/event_filter/source.h @@ -48,7 +48,8 @@ class Event_filter::Source || node.type() == "button-scroll" || node.type() == "accelerate" || node.type() == "log" - || node.type() == "touch-click"; + || node.type() == "touch-click" + || node.type() == "touch-key"; return false; } diff --git a/repos/os/src/server/event_filter/touch_key_source.h b/repos/os/src/server/event_filter/touch_key_source.h new file mode 100644 index 0000000000..cefca4c6df --- /dev/null +++ b/repos/os/src/server/event_filter/touch_key_source.h @@ -0,0 +1,128 @@ +/* + * \brief Input-event source that generates press/release from touch events + * \author Norman Feske + * \date 2022-08-22 + * + * This filter generates artificial key press/release event pairs when touching + * pre-defined areas on a touch screen. All events occurring while such a + * special area is touched are suppressed. + */ + +/* + * Copyright (C) 2022 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 _EVENT_FILTER__TOUCH_KEY_SOURCE_H_ +#define _EVENT_FILTER__TOUCH_KEY_SOURCE_H_ + +/* Genode includes */ +#include +#include +#include + +/* local includes */ +#include + +namespace Event_filter { class Touch_key_source; } + + +class Event_filter::Touch_key_source : public Source, Source::Filter +{ + private: + + using Rect = Genode::Rect<>; + + Owner _owner; + + Source &_source; + + Allocator &_alloc; + + bool _pressed = false; /* true during touch sequence */ + + struct Tap : Interface + { + Rect const rect; + + Input::Keycode const code; + + static Input::Keycode code_from_xml(Xml_node const &node) + { + try { + return key_code_by_name(node.attribute_value("key", Key_name())); + } + catch (Unknown_key) { } + warning("ignoring tap rule ", node); + return Input::KEY_UNKNOWN; + } + + Tap(Xml_node const &node) + : rect(Rect::from_xml(node)), code(code_from_xml(node)) { } + }; + + Registry> _tap_rules { }; + + /** + * Filter interface + */ + void filter_event(Sink &destination, Input::Event const &event) override + { + Input::Event ev = event; + + ev.handle_touch([&] (Input::Touch_id id, float x, float y) { + + /* respond to initial touch of first finger only */ + if (id.value != 0 || _pressed) + return; + + _tap_rules.for_each([&] (Tap const &tap) { + if (tap.rect.contains(Point((int)(x), (int)(y)))) { + destination.submit(Input::Press { tap.code }); + destination.submit(Input::Release { tap.code }); + _pressed = true; + } + }); + }); + + /* filter out all events during the touch sequence */ + if (!_pressed) + destination.submit(ev); + + ev.handle_touch_release([&] (Input::Touch_id id) { + if (id.value == 0) + _pressed = false; + }); + } + + public: + + static char const *name() { return "touch-key"; } + + Touch_key_source(Owner &owner, Xml_node config, + Source::Factory &factory, Allocator &alloc) + : + Source(owner), + _owner(factory), + _source(factory.create_source(_owner, input_sub_node(config))), + _alloc(alloc) + { + config.for_each_sub_node("tap", [&] (Xml_node const &node) { + new (_alloc) Registered(_tap_rules, node); }); + } + + ~Touch_key_source() + { + _tap_rules.for_each([&] (Registered &tap) { + destroy(_alloc, &tap); }); + } + + void generate(Sink &destination) override + { + Source::Filter::apply(destination, *this, _source); + } +}; + +#endif /* _EVENT_FILTER__TOUCH_KEY_SOURCE_H_*/ diff --git a/repos/os/src/server/fs_report/main.cc b/repos/os/src/server/fs_report/main.cc index 9b13545bd0..30a588992c 100644 --- a/repos/os/src/server/fs_report/main.cc +++ b/repos/os/src/server/fs_report/main.cc @@ -230,13 +230,9 @@ class Fs_report::Root : public Genode::Root_component size_t const buffer_size = Arg_string::find_arg(args, "buffer_size").aligned_size(); - size_t session_size = - max((size_t)4096, sizeof(Session_component)) + - buffer_size; - - if (session_size > ram_quota) { + if (buffer_size > ram_quota) { error("insufficient 'ram_quota' from '", label, "' " - "got ", ram_quota, ", need ", session_size); + "got ", ram_quota, ", need ", buffer_size); throw Insufficient_ram_quota(); } diff --git a/repos/os/src/server/lx_fs/directory.h b/repos/os/src/server/lx_fs/directory.h index d98bf7d9fc..acfed71e5b 100644 --- a/repos/os/src/server/lx_fs/directory.h +++ b/repos/os/src/server/lx_fs/directory.h @@ -85,7 +85,7 @@ class Lx_fs::Directory : public Node return fd; } - size_t _num_entries() const + unsigned _num_entries() const { unsigned num = 0; @@ -112,6 +112,8 @@ class Lx_fs::Directory : public Node closedir(_fd); } + bool type_directory() const override { return true; } + void update_modification_time(Timestamp const time) override { struct timespec ts[2] = { @@ -250,7 +252,7 @@ class Lx_fs::Directory : public Node st.st_mtime = 0; return { - .size = _num_entries() * sizeof(File_system::Directory_entry), + .size = 0, .type = Node_type::DIRECTORY, .rwx = { .readable = (st.st_mode & S_IRUSR) != 0, .writeable = (st.st_mode & S_IWUSR) != 0, @@ -260,6 +262,11 @@ class Lx_fs::Directory : public Node }; } + unsigned num_entries() override + { + return _num_entries(); + } + Path path() const override { return _path; diff --git a/repos/os/src/server/lx_fs/main.cc b/repos/os/src/server/lx_fs/main.cc index b0d218a027..b453f76c3e 100644 --- a/repos/os/src/server/lx_fs/main.cc +++ b/repos/os/src/server/lx_fs/main.cc @@ -91,6 +91,7 @@ class Lx_fs::Session_component : private Session_resources, private: using Open_node = File_system::Open_node; + using Dir_node = File_system::Open_node; using Signal_handler = Genode::Signal_handler; Genode::Env &_env; @@ -238,6 +239,43 @@ class Lx_fs::Session_component : private Session_resources, } } + /** + * Apply 'fn' to the open node referenced by 'node_handle' + * + * \throw Invalid_handle + */ + template + auto _with_open_node(Node_handle &node_handle, FN const &fn) + -> typename Trait::Functor::Return_type + { + using Node = File_system::Node; + try { + return _open_node_registry.apply(node_handle, [&] (Node &node) { + return fn(static_cast(node)); }); + } + catch (Id_space::Unknown_id const &) { + throw Invalid_handle(); } + } + + template + auto _with_open_dir_node(Dir_handle &dir_handle, FN const &fn) + -> typename Trait::Functor::Return_type + { + using Node = File_system::Node; + try { + return _open_node_registry.apply(dir_handle, [&] (Node &node) { + + Open_node &open_node = static_cast(node); + + if (!open_node.node().type_directory()) + throw Invalid_handle(); + + return fn(static_cast(node)); }); + } + catch (Id_space::Unknown_id const &) { + throw Invalid_handle(); } + } + /** * Watch_node::Response_handler interface */ @@ -315,6 +353,7 @@ class Lx_fs::Session_component : private Session_resources, void upgrade(Genode::Ram_quota ram) { _ram_guard.upgrade(ram); } void upgrade(Genode::Cap_quota caps) { _cap_guard.upgrade(caps); } + /*************************** ** File_system interface ** ***************************/ @@ -324,9 +363,9 @@ class Lx_fs::Session_component : private Session_resources, if (!valid_name(name.string())) throw Invalid_name(); - auto file_fn = [&] (Open_node &open_node) { + return _with_open_dir_node(dir_handle, [&] (Dir_node &dir_node) { - Node &dir = open_node.node(); + Node &dir = dir_node.node(); if (!_writeable) if (create || (mode != STAT_ONLY && mode != READ_ONLY)) @@ -337,16 +376,8 @@ class Lx_fs::Session_component : private Session_resources, Open_node *open_file = new (_alloc) Open_node(*file, _open_node_registry); - return open_file->id(); - }; - - try { - return File_handle { - _open_node_registry.apply(dir_handle, file_fn).value - }; - } catch (Id_space::Unknown_id const &) { - throw Invalid_handle(); - } + return File_handle { open_file->id().value }; + }); } Symlink_handle symlink(Dir_handle, Name const &, bool /* create */) override @@ -415,30 +446,23 @@ class Lx_fs::Session_component : private Session_resources, void close(Node_handle handle) override { - auto close_fn = [&] (Open_node &open_node) { + _with_open_node(handle, [&] (Open_node &open_node) { Node &node = open_node.node(); destroy(_alloc, &open_node); destroy(_alloc, &node); - }; - - try { - _open_node_registry.apply(handle, close_fn); - } catch (Id_space::Unknown_id const &) { - throw Invalid_handle(); - } + }); } - Status status(Node_handle node_handle) override + Status status(Node_handle handle) override { - auto status_fn = [&] (Open_node &open_node) { - return open_node.node().status(); - }; + return _with_open_node(handle, [&] (Open_node &open_node) { + return open_node.node().status(); }); + } - try { - return _open_node_registry.apply(node_handle, status_fn); - } catch (Id_space::Unknown_id const &) { - throw Invalid_handle(); - } + unsigned num_entries(Dir_handle dir_handle) override + { + return _with_open_dir_node(dir_handle, [&] (Dir_node &dir_node) { + return dir_node.node().num_entries(); }); } void control(Node_handle, Control) override @@ -454,7 +478,7 @@ class Lx_fs::Session_component : private Session_resources, if (!_writeable) throw Permission_denied(); - auto unlink_fn = [&] (Open_node &open_node) { + _with_open_node(dir_handle, [&] (Open_node &open_node) { Absolute_path absolute_path("/"); @@ -489,13 +513,7 @@ class Lx_fs::Session_component : private Session_resources, if (err == EACCES) throw Permission_denied(); } - }; - - try { - _open_node_registry.apply(dir_handle, unlink_fn); - } catch (Id_space::Unknown_id const &) { - throw Invalid_handle(); - } + }); } void truncate(File_handle file_handle, file_size_t size) override @@ -503,43 +521,20 @@ class Lx_fs::Session_component : private Session_resources, if (!_writeable) throw Permission_denied(); - auto truncate_fn = [&] (Open_node &open_node) { - open_node.node().truncate(size); - }; - - try { - _open_node_registry.apply(file_handle, truncate_fn); - } catch (Id_space::Unknown_id const &) { - throw Invalid_handle(); - } + _with_open_node(file_handle, [&] (Open_node &open_node) { + open_node.node().truncate(size); }); } void move(Dir_handle dir_from, Name const & name_from, Dir_handle dir_to, Name const & name_to) override { - typedef File_system::Open_node Dir_node; - Directory *to = 0; - auto to_fn = [&] (Dir_node &dir_node) { - to = &dir_node.node(); - }; + _with_open_dir_node(dir_to, [&] (Dir_node &dir_node) { + to = &dir_node.node(); }); - try { - _open_node_registry.apply(dir_to, to_fn); - } catch (Id_space::Unknown_id const &) { - throw Invalid_handle(); - } - - auto move_fn = [&] (Dir_node &dir_node) { - dir_node.node().rename(*to, name_from.string(), name_to.string()); - }; - - try { - _open_node_registry.apply(dir_from, move_fn); - } catch (Id_space::Unknown_id const &) { - throw Invalid_handle(); - } + _with_open_dir_node(dir_from, [&] (Dir_node &dir_node) { + dir_node.node().rename(*to, name_from.string(), name_to.string()); }); } }; @@ -618,13 +613,11 @@ class Lx_fs::Root : public Root_component } /* - * Check if donated ram quota suffices for session data, - * and communication buffer. + * Check if donated ram quota suffices for communication buffer. */ - size_t session_size = sizeof(Session_component) + tx_buf_size; - if (max((size_t)4096, session_size) > ram_quota) { + if (tx_buf_size > ram_quota) { Genode::error("insufficient 'ram_quota', " - "got ", ram_quota, ", need ", session_size); + "got ", ram_quota, ", need ", tx_buf_size); throw Insufficient_ram_quota(); } diff --git a/repos/os/src/server/lx_fs/node.h b/repos/os/src/server/lx_fs/node.h index bd8d84d5f0..d4a91917ce 100644 --- a/repos/os/src/server/lx_fs/node.h +++ b/repos/os/src/server/lx_fs/node.h @@ -60,6 +60,8 @@ class Lx_fs::Node : public File_system::Node_base uint64_t inode() const { return _inode; } char const *name() const { return _name; } + virtual bool type_directory() const { return false; } + /** * Assign name */ @@ -74,6 +76,8 @@ class Lx_fs::Node : public File_system::Node_base virtual Status status() = 0; + virtual unsigned num_entries() { return 0; } + /* * File functionality */ diff --git a/repos/os/src/server/lx_fs/open_node.h b/repos/os/src/server/lx_fs/open_node.h index 99878d3a47..66cc088667 100644 --- a/repos/os/src/server/lx_fs/open_node.h +++ b/repos/os/src/server/lx_fs/open_node.h @@ -32,7 +32,8 @@ class File_system::Open_node : public File_system::Node Genode::Id_space::Element _element; - NODE &_node; + NODE &_node; + Genode::Constructible _listener { }; Listener::Version const _version_when_opened = _node.curr_version(); diff --git a/repos/os/src/server/mixer/mixer.cc b/repos/os/src/server/mixer/mixer.cc index e354f76399..0cd276f2ab 100644 --- a/repos/os/src/server/mixer/mixer.cc +++ b/repos/os/src/server/mixer/mixer.cc @@ -706,12 +706,9 @@ class Audio_out::Root : public Audio_out::Root_component size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); - size_t session_size = align_addr(sizeof(Session_component), 12); - - if ((ram_quota < session_size) || - (sizeof(Stream) > ram_quota - session_size)) { + if (sizeof(Stream) > ram_quota) { Genode::error("insufficient 'ram_quota', got ", ram_quota, ", " - "need ", sizeof(Stream) + session_size); + "need ", sizeof(Stream)); throw Insufficient_ram_quota(); } diff --git a/repos/os/src/server/nic_dump/component.cc b/repos/os/src/server/nic_dump/component.cc index e4de127087..ee89a805d7 100644 --- a/repos/os/src/server/nic_dump/component.cc +++ b/repos/os/src/server/nic_dump/component.cc @@ -134,21 +134,15 @@ Session_component *Net::Root::_create_session(char const *args) size_t const rx_buf_size = Arg_string::find_arg(args, "rx_buf_size").ulong_value(0); - size_t const session_size = - max((size_t)4096, sizeof(Session_component)); - - if (ram_quota.value < session_size) { - throw Insufficient_ram_quota(); } - - if (tx_buf_size > ram_quota.value - session_size || - rx_buf_size > ram_quota.value - session_size || - tx_buf_size + rx_buf_size > ram_quota.value - session_size) + if (tx_buf_size > ram_quota.value || + rx_buf_size > ram_quota.value || + tx_buf_size + rx_buf_size > ram_quota.value) { error("insufficient 'ram_quota' for session creation"); throw Insufficient_ram_quota(); } return new (md_alloc()) - Session_component(Ram_quota{ram_quota.value - session_size}, + Session_component(Ram_quota{ram_quota.value}, cap_quota, tx_buf_size, rx_buf_size, _config, _timer, _curr_time, _env); } diff --git a/repos/os/src/server/nic_loopback/main.cc b/repos/os/src/server/nic_loopback/main.cc index 082fb93654..86b19fe4e4 100644 --- a/repos/os/src/server/nic_loopback/main.cc +++ b/repos/os/src/server/nic_loopback/main.cc @@ -149,19 +149,14 @@ class Nic_loopback::Root : public Root_component size_t tx_buf_size = Arg_string::find_arg(args, "tx_buf_size").ulong_value(0); size_t rx_buf_size = Arg_string::find_arg(args, "rx_buf_size").ulong_value(0); - /* deplete ram quota by the memory needed for the session structure */ - size_t session_size = max(4096UL, (size_t)sizeof(Session_component)); - if (ram_quota < session_size) - throw Insufficient_ram_quota(); - /* * Check if donated ram quota suffices for both communication * buffers and check for overflow */ if (tx_buf_size + rx_buf_size < tx_buf_size || - tx_buf_size + rx_buf_size > ram_quota - session_size) { + tx_buf_size + rx_buf_size > ram_quota) { error("insufficient 'ram_quota', got ", ram_quota, ", " - "need ", tx_buf_size + rx_buf_size + session_size); + "need ", tx_buf_size + rx_buf_size); throw Insufficient_ram_quota(); } diff --git a/repos/os/src/server/nic_perf/README b/repos/os/src/server/nic_perf/README new file mode 100644 index 0000000000..e49bf2032f --- /dev/null +++ b/repos/os/src/server/nic_perf/README @@ -0,0 +1,46 @@ +The 'nic_perf' component is a benchmark component for the Nic and Uplink +service. It can act as a Nic/Uplink server and a Nic client. The component +periodically logs the number of transmitted/received packets and the resulting +data rate. When enabled, it transmits continuous stream of UDP packets to a +predefined receiver as a test stimulus. + + +Basics +~~~~~~ + +This is an example configuration: + +! +! +! +! +! +! +! +! + +The 'period_ms' attribute specifies the logging intervall (in milliseconds). By +default, logging is disabled. The 'count' attribute defines after how may +periods the component exits. Session policies for connecting Nic/Uplink clients +are specified by '' nodes resp. a '' node. The component +opens a single Nic connection if a '' node is provided. + +All sub-nodes comprise an optional '' node and an optional '' +node. This is an overview of their attributes: + +:interface.ip: + Optional. Specifies the own IP address. If not specified, the component will + send DHCP requests to acquire an IP. + +:interface.dhcp_client_ip: + Optional. If specified, the component responds to DHCP requests with this IP + address. + +:tx.mtu: + Optional. Sets the size of the transmitted test packets. + +:tx.to: + Mandatory. Specifies the destination IP address. + +:tx.udp_port: + Mandatory. Specifies the destination port. diff --git a/repos/os/src/server/nic_perf/dhcp_client.cc b/repos/os/src/server/nic_perf/dhcp_client.cc new file mode 100644 index 0000000000..a26de4ee66 --- /dev/null +++ b/repos/os/src/server/nic_perf/dhcp_client.cc @@ -0,0 +1,245 @@ +/* + * \brief DHCP client state model + * \author Martin Stein + * \date 2016-08-24 + */ + +/* + * Copyright (C) 2016-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. + */ + +/* local includes */ +#include +#include + +/* Genode includes */ +#include + +enum { PKT_SIZE = 1024 }; + +struct Send_buffer_too_small : Genode::Exception { }; +struct Bad_send_dhcp_args : Genode::Exception { }; + +using namespace Genode; +using namespace Net; +using Message_type = Dhcp_packet::Message_type; +using Dhcp_options = Dhcp_packet::Options_aggregator; + + +/*************** + ** Utilities ** + ***************/ + +void append_param_req_list(Dhcp_options &dhcp_opts) +{ + dhcp_opts.append_param_req_list([&] (Dhcp_options::Parameter_request_list_data &data) { + data.append_param_req(); + data.append_param_req(); + data.append_param_req(); + data.append_param_req(); + data.append_param_req(); + data.append_param_req(); + }); +} + + +/***************** + ** Dhcp_client ** + *****************/ + +Dhcp_client::Dhcp_client(Timer::Connection &timer, + Nic_perf::Interface &interface) +: + _timeout(timer, *this, &Dhcp_client::_handle_timeout), + _interface(interface) +{ + _discover(); +} + + +void Dhcp_client::_discover() +{ + _set_state(State::SELECT, _discover_timeout); + _send(Message_type::DISCOVER, Ipv4_address(), Ipv4_address(), + Ipv4_address()); +} + + +void Dhcp_client::_rerequest(State next_state) +{ + _set_state(next_state, _rerequest_timeout(2)); + Ipv4_address const client_ip = _interface.ip(); + _send(Message_type::REQUEST, client_ip, Ipv4_address(), client_ip); +} + + +void Dhcp_client::_set_state(State state, Microseconds timeout) +{ + _state = state; + _timeout.schedule(timeout); +} + + +Microseconds Dhcp_client::_rerequest_timeout(unsigned lease_time_div_log2) +{ + /* FIXME limit the time because of shortcomings in timeout framework */ + enum { MAX_TIMEOUT_SEC = 3600 }; + uint64_t timeout_sec = _lease_time_sec >> lease_time_div_log2; + + if (timeout_sec > MAX_TIMEOUT_SEC) { + timeout_sec = MAX_TIMEOUT_SEC; + warning("Had to prune the state timeout of DHCP client"); + } + return Microseconds(timeout_sec * 1000 * 1000); +} + + +void Dhcp_client::_handle_timeout(Duration) +{ + switch (_state) { + case State::BOUND: _rerequest(State::RENEW); break; + case State::RENEW: _rerequest(State::REBIND); break; + default: _discover(); + } +} + + +void Dhcp_client::handle_dhcp(Dhcp_packet &dhcp, Ethernet_frame ð, Size_guard &) +{ + if (eth.dst() != _interface.mac() && + eth.dst() != Mac_address(0xff)) + { + throw Drop_packet_inform("DHCP client expects Ethernet targeting the router"); + } + + if (dhcp.client_mac() != _interface.mac()) { + throw Drop_packet_inform("DHCP client expects DHCP targeting the router"); } + + try { _handle_dhcp_reply(dhcp); } + catch (Dhcp_packet::Option_not_found) { + throw Drop_packet_inform("DHCP client misses DHCP option"); } +} + + +void Dhcp_client::_handle_dhcp_reply(Dhcp_packet &dhcp) +{ + Message_type const msg_type = + dhcp.option().value(); + + switch (_state) { + case State::SELECT: + + if (msg_type != Message_type::OFFER) { + throw Drop_packet_inform("DHCP client expects an offer"); + } + _set_state(State::REQUEST, _request_timeout); + _send(Message_type::REQUEST, Ipv4_address(), + dhcp.option().value(), + dhcp.yiaddr()); + break; + + case State::REQUEST: + { + if (msg_type != Message_type::ACK) { + throw Drop_packet_inform("DHCP client expects an acknowledgement"); + } + _lease_time_sec = dhcp.option().value(); + _set_state(State::BOUND, _rerequest_timeout(1)); + Ipv4_address dns_server; + try { dns_server = dhcp.option().value(); } + catch (Dhcp_packet::Option_not_found) { } + + _interface.ip(dhcp.yiaddr()); + log("Got IP address ", _interface.ip()); + break; + } + case State::RENEW: + case State::REBIND: + + if (msg_type != Message_type::ACK) { + throw Drop_packet_inform("DHCP client expects an acknowledgement"); + } + _set_state(State::BOUND, _rerequest_timeout(1)); + _lease_time_sec = dhcp.option().value(); + break; + + default: throw Drop_packet_inform("DHCP client doesn't expect a packet"); + } +} + + +void Dhcp_client::_send(Message_type msg_type, + Ipv4_address client_ip, + Ipv4_address server_ip, + Ipv4_address requested_ip) +{ + _interface.send(PKT_SIZE, [&] (void *pkt_base, Size_guard &size_guard) { + + /* create ETH header of the request */ + Ethernet_frame ð = Ethernet_frame::construct_at(pkt_base, size_guard); + eth.dst(Mac_address(0xff)); + eth.src(_interface.mac()); + eth.type(Ethernet_frame::Type::IPV4); + + /* create IP header of the request */ + enum { IPV4_TIME_TO_LIVE = 64 }; + size_t const ip_off = size_guard.head_size(); + Ipv4_packet &ip = eth.construct_at_data(size_guard); + ip.header_length(sizeof(Ipv4_packet) / 4); + ip.version(4); + ip.time_to_live(IPV4_TIME_TO_LIVE); + ip.protocol(Ipv4_packet::Protocol::UDP); + ip.src(client_ip); + ip.dst(Ipv4_address(0xff)); + + /* create UDP header of the request */ + size_t const udp_off = size_guard.head_size(); + Udp_packet &udp = ip.construct_at_data(size_guard); + udp.src_port(Port(Dhcp_packet::BOOTPC)); + udp.dst_port(Port(Dhcp_packet::BOOTPS)); + + /* create mandatory DHCP fields of the request */ + size_t const dhcp_off = size_guard.head_size(); + Dhcp_packet &dhcp = udp.construct_at_data(size_guard); + dhcp.op(Dhcp_packet::REQUEST); + dhcp.htype(Dhcp_packet::Htype::ETH); + dhcp.hlen(sizeof(Mac_address)); + dhcp.ciaddr(client_ip); + dhcp.client_mac(_interface.mac()); + dhcp.default_magic_cookie(); + + /* append DHCP option fields to the request */ + Dhcp_options dhcp_opts(dhcp, size_guard); + dhcp_opts.append_option(msg_type); + switch (msg_type) { + case Message_type::DISCOVER: + append_param_req_list(dhcp_opts); + dhcp_opts.append_option(_interface.mac()); + dhcp_opts.append_option(PKT_SIZE - dhcp_off); + break; + + case Message_type::REQUEST: + append_param_req_list(dhcp_opts); + dhcp_opts.append_option(_interface.mac()); + dhcp_opts.append_option(PKT_SIZE - dhcp_off); + if (_state == State::REQUEST) { + dhcp_opts.append_option(requested_ip); + dhcp_opts.append_option(server_ip); + } + break; + + default: + throw Bad_send_dhcp_args(); + } + dhcp_opts.append_option(); + + /* fill in header values that need the packet to be complete already */ + udp.length(size_guard.head_size() - udp_off); + udp.update_checksum(ip.src(), ip.dst()); + ip.total_length(size_guard.head_size() - ip_off); + ip.update_checksum(); + }); +} diff --git a/repos/os/src/server/nic_perf/dhcp_client.h b/repos/os/src/server/nic_perf/dhcp_client.h new file mode 100644 index 0000000000..0cb8a08622 --- /dev/null +++ b/repos/os/src/server/nic_perf/dhcp_client.h @@ -0,0 +1,89 @@ +/* + * \brief DHCP client state model + * \author Martin Stein + * \date 2016-08-24 + */ + +/* + * Copyright (C) 2016-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 _DHCP_CLIENT_H_ +#define _DHCP_CLIENT_H_ + +/* Genode includes */ +#include +#include + +namespace Nic_perf { class Interface; } + +namespace Net { + + /* external definition */ + class Ethernet_frame; + + /* local definition */ + class Dhcp_client; + class Drop_packet_inform; +} + + +struct Net::Drop_packet_inform : Genode::Exception +{ + char const *msg; + + Drop_packet_inform(char const *msg) : msg(msg) { } +}; + + +class Net::Dhcp_client +{ + private: + + enum class State + { + INIT = 0, SELECT = 1, REQUEST = 2, BOUND = 3, RENEW = 4, REBIND = 5 + }; + + enum { DISCOVER_TIMEOUT_SEC = 2 }; + enum { REQUEST_TIMEOUT_SEC = 2 }; + + State _state { State::INIT }; + Timer::One_shot_timeout _timeout; + unsigned long _lease_time_sec = 0; + Genode::Microseconds const _discover_timeout { (Genode::uint64_t)DISCOVER_TIMEOUT_SEC * 1000 * 1000 }; + Genode::Microseconds const _request_timeout { (Genode::uint64_t)REQUEST_TIMEOUT_SEC * 1000 * 1000 }; + Nic_perf::Interface &_interface; + + void _handle_dhcp_reply(Dhcp_packet &dhcp); + + void _handle_timeout(Genode::Duration); + + void _rerequest(State next_state); + + Genode::Microseconds _rerequest_timeout(unsigned lease_time_div_log2); + + void _set_state(State state, Genode::Microseconds timeout); + + void _send(Dhcp_packet::Message_type msg_type, + Ipv4_address client_ip, + Ipv4_address server_ip, + Ipv4_address requested_ip); + + void _discover(); + + public: + + Dhcp_client(Timer::Connection &timer, + Nic_perf::Interface &interface); + + void handle_dhcp(Dhcp_packet &dhcp, + Ethernet_frame ð, + Size_guard &size_guard); + +}; + +#endif /* _DHCP_CLIENT_H_ */ diff --git a/repos/os/src/server/nic_perf/interface.cc b/repos/os/src/server/nic_perf/interface.cc new file mode 100644 index 0000000000..3c1bab3e83 --- /dev/null +++ b/repos/os/src/server/nic_perf/interface.cc @@ -0,0 +1,254 @@ +/* + * \brief Base class for Nic/Uplink session components + * \author Johannes Schlatow + * \date 2022-06-15 + */ + +/* + * Copyright (C) 2022 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. + */ + +/* local includes */ +#include + +/* Genode includes */ +#include +#include +#include + + +void Nic_perf::Interface::_handle_eth(void * pkt_base, size_t size) +{ + try { + + Size_guard size_guard(size); + Ethernet_frame ð = Ethernet_frame::cast_from(pkt_base, size_guard); + + switch (eth.type()) { + case Ethernet_frame::Type::ARP: + _handle_arp(eth, size_guard); + break; + case Ethernet_frame::Type::IPV4: + _handle_ip(eth, size_guard); + break; + default: + ; + } + } catch (Size_guard::Exceeded) { + warning("Size guard exceeded"); + } catch (Net::Drop_packet_inform e) { + error(e.msg); + } + + _stats.rx_packet(size); +} + + +void Nic_perf::Interface::_handle_arp(Ethernet_frame & eth, Size_guard & size_guard) +{ + Arp_packet &arp = eth.data(size_guard); + if (!arp.ethernet_ipv4()) + return; + + Ipv4_address old_src_ip { }; + + switch (arp.opcode()) { + case Arp_packet::REPLY: + _generator.handle_arp_reply(arp); + + break; + + case Arp_packet::REQUEST: + /* check whether the request targets us */ + if (arp.dst_ip() != _ip) + return; + + old_src_ip = arp.src_ip(); + arp.opcode(Arp_packet::REPLY); + arp.dst_mac(arp.src_mac()); + arp.src_mac(_mac); + arp.src_ip(arp.dst_ip()); + arp.dst_ip(old_src_ip); + eth.dst(arp.dst_mac()); + eth.src(_mac); + + send(size_guard.total_size(), [&] (void * pkt_base, Size_guard & size_guard) { + memcpy(pkt_base, (void*)ð, size_guard.total_size()); + }); + break; + + default: + ; + } +} + + +void Nic_perf::Interface::_handle_ip(Ethernet_frame & eth, Size_guard & size_guard) +{ + Ipv4_packet &ip = eth.data(size_guard); + if (ip.protocol() == Ipv4_packet::Protocol::UDP) { + + Udp_packet &udp = ip.data(size_guard); + if (Dhcp_packet::is_dhcp(&udp)) { + Dhcp_packet &dhcp = udp.data(size_guard); + switch (dhcp.op()) { + case Dhcp_packet::REQUEST: + _handle_dhcp_request(eth, dhcp); + break; + case Dhcp_packet::REPLY: + if (_dhcp_client.constructed()) { + _dhcp_client->handle_dhcp(dhcp, eth, size_guard); + } + break; + } + } + } +} + + +void Nic_perf::Interface::_handle_dhcp_request(Ethernet_frame & eth, Dhcp_packet & dhcp) +{ + Dhcp_packet::Message_type const msg_type = + dhcp.option().value(); + + switch (msg_type) { + case Dhcp_packet::Message_type::DISCOVER: + _send_dhcp_reply(eth, dhcp, Dhcp_packet::Message_type::OFFER); + break; + case Dhcp_packet::Message_type::REQUEST: + _send_dhcp_reply(eth, dhcp, Dhcp_packet::Message_type::ACK); + break; + default: + ; + } +} + + +void Nic_perf::Interface::_send_dhcp_reply(Ethernet_frame const & eth_req, + Dhcp_packet const & dhcp_req, + Dhcp_packet::Message_type msg_type) +{ + if (_ip == Ipv4_address()) + return; + + if (_dhcp_client_ip == Ipv4_address()) + return; + + enum { PKT_SIZE = 512 }; + send(PKT_SIZE, [&] (void *pkt_base, Size_guard &size_guard) { + + Ethernet_frame ð = Ethernet_frame::construct_at(pkt_base, size_guard); + if (msg_type == Dhcp_packet::Message_type::OFFER) { + eth.dst(Ethernet_frame::broadcast()); } + else { + eth.dst(eth_req.src()); } + eth.src(_mac); + eth.type(Ethernet_frame::Type::IPV4); + + /* create IP header of the reply */ + size_t const ip_off = size_guard.head_size(); + Ipv4_packet &ip = eth.construct_at_data(size_guard); + ip.header_length(sizeof(Ipv4_packet) / 4); + ip.version(4); + ip.time_to_live(64); + ip.protocol(Ipv4_packet::Protocol::UDP); + ip.src(_ip); + ip.dst(_dhcp_client_ip); + + /* create UDP header of the reply */ + size_t const udp_off = size_guard.head_size(); + Udp_packet &udp = ip.construct_at_data(size_guard); + udp.src_port(Port(Dhcp_packet::BOOTPS)); + udp.dst_port(Port(Dhcp_packet::BOOTPC)); + + /* create mandatory DHCP fields of the reply */ + Dhcp_packet &dhcp = udp.construct_at_data(size_guard); + dhcp.op(Dhcp_packet::REPLY); + dhcp.htype(Dhcp_packet::Htype::ETH); + dhcp.hlen(sizeof(Mac_address)); + dhcp.xid(dhcp_req.xid()); + if (msg_type == Dhcp_packet::Message_type::INFORM) { + dhcp.ciaddr(_dhcp_client_ip); } + else { + dhcp.yiaddr(_dhcp_client_ip); } + dhcp.siaddr(_ip); + dhcp.client_mac(dhcp_req.client_mac()); + dhcp.default_magic_cookie(); + + /* append DHCP option fields to the reply */ + Dhcp_packet::Options_aggregator dhcp_opts(dhcp, size_guard); + dhcp_opts.append_option(msg_type); + dhcp_opts.append_option(_ip); + dhcp_opts.append_option(86400); + dhcp_opts.append_option(_subnet_mask()); + dhcp_opts.append_option(_ip); + + dhcp_opts.append_dns_server([&] (Dhcp_options::Dns_server_data &data) { + data.append_address(_ip); + }); + dhcp_opts.append_option(Ipv4_packet::broadcast()); + dhcp_opts.append_option(); + + /* fill in header values that need the packet to be complete already */ + udp.length(size_guard.head_size() - udp_off); + udp.update_checksum(ip.src(), ip.dst()); + ip.total_length(size_guard.head_size() - ip_off); + ip.update_checksum(); + }); +} + + +void Nic_perf::Interface::handle_packet_stream() +{ + /* handle acks from client */ + while (_source.ack_avail()) + _source.release_packet(_source.try_get_acked_packet()); + + /* loop while we can make Rx progress */ + for (;;) { + if (!_sink.ready_to_ack()) + break; + + if (!_sink.packet_avail()) + break; + + Packet_descriptor const packet_from_client = _sink.try_get_packet(); + + if (_sink.packet_valid(packet_from_client)) { + _handle_eth(_sink.packet_content(packet_from_client), packet_from_client.size()); + if (!_sink.try_ack_packet(packet_from_client)) + break; + } + } + + /* skip sending if disabled or IP address is not set */ + if (!_generator.enabled() || _ip == Ipv4_address()) { + _sink.wakeup(); + _source.wakeup(); + return; + } + + /* loop while we can make Tx progress */ + for (;;) { + /* + * The client fails to pick up the packets from the rx channel. So we + * won't try to submit new packets. + */ + if (!_source.ready_to_submit()) + break; + + bool okay = + send(_generator.size(), [&] (void * pkt_base, Size_guard & size_guard) { + _generator.generate(pkt_base, size_guard, _mac, _ip); + }); + + if (!okay) + break; + } + + _sink.wakeup(); + _source.wakeup(); +} diff --git a/repos/os/src/server/nic_perf/interface.h b/repos/os/src/server/nic_perf/interface.h new file mode 100644 index 0000000000..63032b09d9 --- /dev/null +++ b/repos/os/src/server/nic_perf/interface.h @@ -0,0 +1,155 @@ +/* + * \brief Base class for Nic/Uplink session components + * \author Johannes Schlatow + * \date 2022-06-15 + */ + +/* + * Copyright (C) 2022 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 _INTERFACE_H_ +#define _INTERFACE_H_ + +/* local includes */ +#include +#include +#include + +/* Genode includes */ +#include +#include +#include +#include +#include + +namespace Nic_perf { + using namespace Genode; + using namespace Net; + + using Dhcp_options = Dhcp_packet::Options_aggregator; + + class Interface; + + using Interface_registry = Registry; +} + +class Nic_perf::Interface +{ + protected: + + using Sink = Nic::Packet_stream_sink; + using Source = Nic::Packet_stream_source; + + Interface_registry::Element _element; + Session_label _label; + + Packet_stats _stats; + Packet_generator _generator; + + bool _mac_from_policy; + + Mac_address _mac { }; + Mac_address const _default_mac; + Ipv4_address _ip { }; + Ipv4_address _dhcp_client_ip { }; + + Source &_source; + Sink &_sink; + + Constructible _dhcp_client { }; + Timer::Connection &_timer; + + static Ipv4_address _subnet_mask() + { + uint8_t buf[] = { 0xff, 0xff, 0xff, 0 }; + return Ipv4_address((void*)buf); + } + + void _handle_eth(void *, size_t); + void _handle_ip(Ethernet_frame &, Size_guard &); + void _handle_arp(Ethernet_frame &, Size_guard &); + void _handle_dhcp_request(Ethernet_frame &, Dhcp_packet &); + void _send_dhcp_reply(Ethernet_frame const &, Dhcp_packet const &, Dhcp_packet::Message_type); + + public: + + Interface(Interface_registry ®istry, + Session_label const &label, + Xml_node const &policy, + bool mac_from_policy, + Mac_address mac, + Source &source, + Sink &sink, + Timer::Connection &timer) + : _element(registry, *this), + _label(label), + _stats(_label), + _generator(timer, *this), + _mac_from_policy(mac_from_policy), + _default_mac(mac), + _source(source), + _sink(sink), + _timer(timer) + { apply_config(policy); } + + void apply_config(Xml_node const &config) + { + _generator.apply_config(config); + + /* restore defaults when applied to empty/incomplete config */ + _mac = _default_mac; + _ip = Ipv4_address(); + _dhcp_client_ip = Ipv4_address(); + + _dhcp_client.destruct(); + + config.with_sub_node("interface", + [&] (Xml_node node) { + _ip = node.attribute_value("ip", _ip); + _dhcp_client_ip = node.attribute_value("dhcp_client_ip", _dhcp_client_ip); + + if (_mac_from_policy) + _mac = node.attribute_value("mac", _mac); + }, + + /* node does not exist */ + [&] () { _dhcp_client.construct(_timer, *this); } + ); + } + + Session_label const &label() const { return _label; } + Packet_stats &packet_stats() { return _stats; } + + Mac_address const &mac() const { return _mac; } + Ipv4_address const &ip() const { return _ip; } + void ip(Ipv4_address const &ip) { _ip = ip; } + + void handle_packet_stream(); + + template + bool send(size_t pkt_size, FUNC && write_to_pkt) + { + if (!pkt_size) + return false; + + try { + Packet_descriptor pkt = _source.alloc_packet(pkt_size); + void *pkt_base = _source.packet_content(pkt); + + Size_guard size_guard { pkt_size }; + write_to_pkt(pkt_base, size_guard); + + _source.try_submit_packet(pkt); + } catch (...) { return false; } + + _stats.tx_packet(pkt_size); + + return true; + } +}; + +#endif /* _INTERFACE_H_ */ diff --git a/repos/os/src/server/nic_perf/main.cc b/repos/os/src/server/nic_perf/main.cc new file mode 100644 index 0000000000..44373ef1f4 --- /dev/null +++ b/repos/os/src/server/nic_perf/main.cc @@ -0,0 +1,123 @@ +/* + * \brief Throughput benchmark component for Nic and Uplink sessions + * \author Johannes Schlatow + * \date 2022-06-14 + * + * This component continously sends/receives UDP packets via a Nic or Uplink + * session in order to benchmark the throughput. + */ + +/* + * Copyright (C) 2022 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. + */ + +/* local includes */ +#include +#include +#include +#include + +/* Genode includes */ +#include +#include +#include +#include +#include +#include + +namespace Nic_perf { + class Main; + + using namespace Genode; +} + + +struct Nic_perf::Main +{ + using Periodic_timeout = Timer::Periodic_timeout
; + + Env &_env; + + Heap _heap { _env.ram(), _env.rm() }; + + Timer::Connection _timer { _env }; + + Attached_rom_dataspace _config { _env, "config" }; + + unsigned _period_ms { 5000 }; + + unsigned _count { 10000 }; + + Interface_registry _registry { }; + + Nic_perf::Nic_root _nic_root { _env, _heap, _registry, _config, _timer }; + + Nic_perf::Uplink_root _uplink_root { _env, _heap, _registry, _config, _timer }; + + Constructible _nic_client { }; + + Genode::Signal_handler
_config_handler = + { _env.ep(), *this, &Main::_handle_config }; + + Constructible _timeout { }; + + void _handle_config() + { + _config.update(); + + _registry.for_each([&] (Interface &interface) { + with_matching_policy(interface.label(), _config.xml(), + [&] (Xml_node const &policy) { + interface.apply_config(policy); + }, + [&] () { /* no matches */ + interface.apply_config(Xml_node("")); + } + ); + }); + + if (_nic_client.constructed()) + _nic_client.destruct(); + + if (_config.xml().has_sub_node("nic-client")) + _nic_client.construct(_env, _heap, _config.xml().sub_node("nic-client"), _registry, _timer); + + _period_ms = _config.xml().attribute_value("period_ms", _period_ms); + _count = _config.xml().attribute_value("count", _count); + + _timeout.conditional(_count && _period_ms, + _timer, *this, &Main::_handle_timeout, Microseconds(_period_ms*1000)); + } + + void _handle_timeout(Genode::Duration) + { + _registry.for_each([&] (Interface &interface) { + Packet_stats &stats = interface.packet_stats(); + + stats.calculate_throughput(_period_ms); + log(stats); + stats.reset(); + }); + + _count--; + if (!_count) + _env.parent().exit(0); + } + + Main(Env &env) : _env(env) + { + _env.parent().announce(_env.ep().manage(_nic_root)); + _env.parent().announce(_env.ep().manage(_uplink_root)); + + _config.sigh(_config_handler); + + _handle_config(); + } +}; + + +void Component::construct(Genode::Env &env) { static Nic_perf::Main main(env); } + diff --git a/repos/os/src/server/nic_perf/nic_client.h b/repos/os/src/server/nic_perf/nic_client.h new file mode 100644 index 0000000000..c88c07b9d8 --- /dev/null +++ b/repos/os/src/server/nic_perf/nic_client.h @@ -0,0 +1,71 @@ +/* + * \brief Nic client + * \author Johannes Schlatow + * \date 2022-06-16 + */ + +/* + * Copyright (C) 2022 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 _NIC_CLIENT_H_ +#define _NIC_CLIENT_H_ + +/* local includes */ +#include + +/* Genode includes */ +#include +#include +#include + +namespace Nic_perf { + class Nic_client; + + using namespace Genode; +} + + +class Nic_perf::Nic_client +{ + private: + enum { BUF_SIZE = Nic::Session::QUEUE_SIZE * Nic::Packet_allocator::DEFAULT_PACKET_SIZE }; + + Env &_env; + Nic::Packet_allocator _pkt_alloc; + Nic::Connection _nic { _env, &_pkt_alloc, BUF_SIZE, BUF_SIZE }; + Interface _interface; + + Signal_handler _packet_stream_handler + { _env.ep(), *this, &Nic_client::_handle_packet_stream }; + + void _handle_packet_stream() { + _interface.handle_packet_stream(); } + + public: + + Nic_client(Env &env, + Genode::Allocator &alloc, + Xml_node const &policy, + Interface_registry ®istry, + Timer::Connection &timer) + : + _env(env), + _pkt_alloc(&alloc), + _interface(registry, "nic-client", policy, false, Mac_address(), + *_nic.tx(), *_nic.rx(), timer) + { + _nic.rx_channel()->sigh_ready_to_ack(_packet_stream_handler); + _nic.rx_channel()->sigh_packet_avail(_packet_stream_handler); + _nic.tx_channel()->sigh_ack_avail(_packet_stream_handler); + _nic.tx_channel()->sigh_ready_to_submit(_packet_stream_handler); + + _interface.handle_packet_stream(); + } +}; + + +#endif /* _NIC_CLIENT_H_ */ diff --git a/repos/os/src/server/nic_perf/nic_component.h b/repos/os/src/server/nic_perf/nic_component.h new file mode 100644 index 0000000000..66898cf148 --- /dev/null +++ b/repos/os/src/server/nic_perf/nic_component.h @@ -0,0 +1,142 @@ +/* + * \brief Nic root and session component + * \author Johannes Schlatow + * \date 2022-06-16 + */ + +/* + * Copyright (C) 2022 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 _NIC_ROOT_H_ +#define _NIC_ROOT_H_ + +/* local includes */ +#include + +/* Genode includes */ +#include +#include +#include +#include + +namespace Nic_perf { + class Nic_session_component; + class Nic_root; + + using namespace Genode; +} + + +class Nic_perf::Nic_session_component : public Nic::Session_component +{ + private: + + Interface _interface; + + static Mac_address _default_mac_address() + { + char buf[] = {2,3,4,5,6,7}; + Mac_address result((void*)buf); + return result; + } + + void _handle_packet_stream() override { + _interface.handle_packet_stream(); } + + public: + + Nic_session_component(size_t const tx_buf_size, + size_t const rx_buf_size, + Allocator &rx_block_md_alloc, + Env &env, + Session_label const &label, + Xml_node const &policy, + Interface_registry ®istry, + Timer::Connection &timer) + : + Nic::Session_component(tx_buf_size, rx_buf_size, CACHED, + rx_block_md_alloc, env), + _interface(registry, label, policy, true, _default_mac_address(), + *_rx.source(), *_tx.sink(), timer) + { _interface.handle_packet_stream(); } + + /***************************** + * Session_component methods * + *****************************/ + + Nic::Mac_address mac_address() override { + char buf[] = {2,3,4,5,6,8}; + Mac_address result((void*)buf); + return result; + } + + bool link_state() override + { + /* XXX always return true, for now */ + return true; + } +}; + + +class Nic_perf::Nic_root : public Root_component +{ + private: + Env &_env; + Attached_rom_dataspace &_config; + Interface_registry &_registry; + Timer::Connection &_timer; + + protected: + + Nic_session_component *_create_session(char const *args) override + { + size_t ram_quota = Arg_string::find_arg(args, "ram_quota" ).ulong_value(0); + size_t tx_buf_size = Arg_string::find_arg(args, "tx_buf_size").ulong_value(0); + size_t rx_buf_size = Arg_string::find_arg(args, "rx_buf_size").ulong_value(0); + + /* deplete ram quota by the memory needed for the session structure */ + size_t session_size = max(4096UL, (size_t)sizeof(Nic_session_component)); + if (ram_quota < session_size) + throw Insufficient_ram_quota(); + + /* + * Check if donated ram quota suffices for both communication + * buffers and check for overflow + */ + if (tx_buf_size + rx_buf_size < tx_buf_size || + tx_buf_size + rx_buf_size > ram_quota - session_size) { + error("insufficient 'ram_quota', got ", ram_quota, ", " + "need ", tx_buf_size + rx_buf_size + session_size); + throw Insufficient_ram_quota(); + } + + Session_label label = label_from_args(args); + + Session_policy policy(label, _config.xml()); + + return new (md_alloc()) Nic_session_component(tx_buf_size, rx_buf_size, + *md_alloc(), _env, label, policy, + _registry, _timer); + } + + public: + + Nic_root(Env &env, + Allocator &md_alloc, + Interface_registry ®istry, + Attached_rom_dataspace &config, + Timer::Connection &timer) + : + Root_component(&env.ep().rpc_ep(), &md_alloc), + _env(env), + _config(config), + _registry(registry), + _timer(timer) + { } +}; + +#endif /* _NIC_ROOT_H_ */ diff --git a/repos/os/src/server/nic_perf/packet_generator.cc b/repos/os/src/server/nic_perf/packet_generator.cc new file mode 100644 index 0000000000..8825f63e44 --- /dev/null +++ b/repos/os/src/server/nic_perf/packet_generator.cc @@ -0,0 +1,134 @@ +/* + * \brief Packet generator + * \author Johannes Schlatow + * \date 2022-06-14 + */ + +/* + * Copyright (C) 2022 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. + */ + +/* local includes */ +#include +#include + +void Nic_perf::Packet_generator::_handle_timeout(Genode::Duration) +{ + /* re-issue ARP request */ + if (_state == WAIT_ARP_REPLY) + _state = NEED_ARP_REQUEST; + + _interface.handle_packet_stream(); +} + +void Nic_perf::Packet_generator::handle_arp_reply(Arp_packet const & arp) +{ + if (arp.src_ip() != _dst_ip) + return; + + if (_state != WAIT_ARP_REPLY) + return; + + _timeout.discard(); + + _dst_mac = arp.src_mac(); + _state = READY; +} + + +void Nic_perf::Packet_generator::_generate_arp_request(void * pkt_base, + Size_guard & size_guard, + Mac_address const & from_mac, + Ipv4_address const & from_ip) +{ + if (from_ip == Ipv4_address()) { + error("Ip address not set"); + throw Ip_address_not_set(); + } + + Ethernet_frame ð = Ethernet_frame::construct_at(pkt_base, size_guard); + eth.dst(Mac_address(0xff)); + eth.src(from_mac); + eth.type(Ethernet_frame::Type::ARP); + + Arp_packet &arp = eth.construct_at_data(size_guard); + arp.hardware_address_type(Arp_packet::ETHERNET); + arp.protocol_address_type(Arp_packet::IPV4); + arp.hardware_address_size(sizeof(Mac_address)); + arp.protocol_address_size(sizeof(Ipv4_address)); + arp.opcode(Arp_packet::REQUEST); + arp.src_mac(from_mac); + arp.src_ip(from_ip); + arp.dst_mac(Mac_address(0xff)); + arp.dst_ip(_dst_ip); +} + + +void Nic_perf::Packet_generator::_generate_test_packet(void * pkt_base, + Size_guard & size_guard, + Mac_address const & from_mac, + Ipv4_address const & from_ip) +{ + if (from_ip == Ipv4_address()) { + error("Ip address not set"); + throw Ip_address_not_set(); + } + + if (_dst_port == Port(0)) { + error("Udp port not set"); + throw Udp_port_not_set(); + } + + Ethernet_frame ð = Ethernet_frame::construct_at(pkt_base, size_guard); + eth.dst(_dst_mac); + eth.src(from_mac); + eth.type(Ethernet_frame::Type::IPV4); + + size_t const ip_off = size_guard.head_size(); + Ipv4_packet &ip = eth.construct_at_data(size_guard); + ip.header_length(sizeof(Ipv4_packet) / 4); + ip.version(4); + ip.time_to_live(64); + ip.protocol(Ipv4_packet::Protocol::UDP); + ip.src(from_ip); + ip.dst(_dst_ip); + + size_t udp_off = size_guard.head_size(); + Udp_packet &udp = ip.construct_at_data(size_guard); + udp.src_port(Port(0)); + udp.dst_port(_dst_port); + + /* inflate packet up to _mtu */ + size_guard.consume_head(size_guard.unconsumed()); + + /* fill in length fields and checksums */ + udp.length(size_guard.head_size() - udp_off); + udp.update_checksum(ip.src(), ip.dst()); + ip.total_length(size_guard.head_size() - ip_off); + ip.update_checksum(); +} + + +void Nic_perf::Packet_generator::generate(void * pkt_base, + Size_guard & size_guard, + Mac_address const & from_mac, + Ipv4_address const & from_ip) +{ + switch (_state) { + case READY: + _generate_test_packet(pkt_base, size_guard, from_mac, from_ip); + break; + case NEED_ARP_REQUEST: + _generate_arp_request(pkt_base, size_guard, from_mac, from_ip); + _state = WAIT_ARP_REPLY; + _timeout.schedule(Microseconds { 1000 * 1000 }); + break; + case MUTED: + case WAIT_ARP_REPLY: + throw Not_ready(); + break; + } +} diff --git a/repos/os/src/server/nic_perf/packet_generator.h b/repos/os/src/server/nic_perf/packet_generator.h new file mode 100644 index 0000000000..e70a761c60 --- /dev/null +++ b/repos/os/src/server/nic_perf/packet_generator.h @@ -0,0 +1,116 @@ +/* + * \brief Packet generator + * \author Johannes Schlatow + * \date 2022-06-14 + */ + +/* + * Copyright (C) 2022 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 _PACKET_GENERATOR_H_ +#define _PACKET_GENERATOR_H_ + +/* Genode includes */ +#include +#include +#include +#include +#include +#include + +namespace Nic_perf { + using namespace Genode; + using namespace Net; + + class Interface; + class Packet_generator; +} + +class Nic_perf::Packet_generator +{ + public: + struct Not_ready : Exception { }; + struct Ip_address_not_set : Exception { }; + struct Udp_port_not_set : Exception { }; + + private: + + enum State { MUTED, NEED_ARP_REQUEST, WAIT_ARP_REPLY, READY }; + + size_t _mtu { 1024 }; + bool _enable { false }; + Ipv4_address _dst_ip { }; + Port _dst_port { 0 }; + Mac_address _dst_mac { }; + State _state { MUTED }; + + Timer::One_shot_timeout _timeout; + Nic_perf::Interface &_interface; + + void _generate_arp_request(void *, Size_guard &, Mac_address const &, Ipv4_address const &); + + void _generate_test_packet(void *, Size_guard &, Mac_address const &, Ipv4_address const &); + + void _handle_timeout(Genode::Duration); + + public: + + Packet_generator(Timer::Connection &timer, Nic_perf::Interface &interface) + : _timeout(timer, *this, &Packet_generator::_handle_timeout), + _interface(interface) + { } + + void apply_config(Xml_node const &config) + { + Ipv4_address old_ip = _dst_ip; + + /* restore defaults */ + _dst_ip = Ipv4_address(); + _dst_port = Port(0); + _enable = false; + _state = MUTED; + + config.with_optional_sub_node("tx", [&] (Xml_node node) { + _mtu = node.attribute_value("mtu", _mtu); + _dst_ip = node.attribute_value("to", _dst_ip); + _dst_port = node.attribute_value("udp_port", _dst_port); + _enable = true; + _state = READY; + }); + + /* redo ARP resolution if dst ip changed */ + if (old_ip != _dst_ip) { + _dst_mac = Mac_address(); + + if (_enable) + _state = NEED_ARP_REQUEST; + } + } + + bool enabled() const { return _enable; } + + size_t size() const + { + switch (_state) { + case READY: + return _mtu; + case NEED_ARP_REQUEST: + return Ethernet_frame::MIN_SIZE + sizeof(uint32_t); + case WAIT_ARP_REPLY: + case MUTED: + return 0; + } + + return 0; + } + + void handle_arp_reply(Arp_packet const & arp); + + void generate(void *, Size_guard &, Mac_address const &, Ipv4_address const &); +}; + +#endif /* _PACKET_GENERATOR_H_ */ diff --git a/repos/os/src/server/nic_perf/packet_stats.h b/repos/os/src/server/nic_perf/packet_stats.h new file mode 100644 index 0000000000..f61835a069 --- /dev/null +++ b/repos/os/src/server/nic_perf/packet_stats.h @@ -0,0 +1,90 @@ +/* + * \brief Packet statistics + * \author Johannes Schlatow + * \date 2022-06-14 + */ + +/* + * Copyright (C) 2022 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 _PACKET_STATS_H_ +#define _PACKET_STATS_H_ + +/* Genode includes */ +#include + +namespace Nic_perf { + using namespace Genode; + + class Packet_stats; +} + +class Nic_perf::Packet_stats +{ + private: + + Session_label const &_label; + + size_t _sent_cnt { 0 }; + size_t _recv_cnt { 0 }; + size_t _sent_bytes { 0 }; + size_t _recv_bytes { 0 }; + unsigned _period_ms { 0 }; + float _rx_mbit_sec { 0.0 }; + float _tx_mbit_sec { 0.0 }; + + public: + + Packet_stats(Session_label const & label) + : _label(label) + { } + + void reset() + { + _sent_cnt = 0; + _recv_cnt = 0; + _sent_bytes = 0; + _recv_bytes = 0; + _rx_mbit_sec = 0; + _tx_mbit_sec = 0; + } + + void rx_packet(size_t bytes) + { + _recv_cnt++; + _recv_bytes += bytes; + } + + void tx_packet(size_t bytes) + { + _sent_cnt++; + _sent_bytes += bytes; + } + + void calculate_throughput(unsigned period_ms) + { + _period_ms = period_ms; + + if (_period_ms == 0) return; + + _rx_mbit_sec = (float)(_recv_bytes * 8ULL) / (float)(period_ms*1000ULL); + _tx_mbit_sec = (float)(_sent_bytes * 8ULL) / (float)(period_ms*1000ULL); + } + + void print(Output &out) const + { + Genode::print(out, "# Stats for session ", _label, "\n"); + Genode::print(out, " Received ", _recv_cnt, " packets in ", + _period_ms, "ms at ", _rx_mbit_sec, "Mbit/s\n"); + Genode::print(out, " Sent ", _sent_cnt, " packets in ", + _period_ms, "ms at ", _tx_mbit_sec, "Mbit/s\n"); + } + +}; + + +#endif /* _PACKET_STATS_H_ */ diff --git a/repos/os/src/server/nic_perf/target.mk b/repos/os/src/server/nic_perf/target.mk new file mode 100644 index 0000000000..5445365b49 --- /dev/null +++ b/repos/os/src/server/nic_perf/target.mk @@ -0,0 +1,7 @@ +TARGET = nic_perf +SRC_CC = main.cc interface.cc packet_generator.cc dhcp_client.cc +LIBS = base net + +INC_DIR += $(PRG_DIR) + +CC_CXX_WARN_STRICT_CONVERSION = diff --git a/repos/os/src/server/nic_perf/uplink_component.h b/repos/os/src/server/nic_perf/uplink_component.h new file mode 100644 index 0000000000..48098f5eca --- /dev/null +++ b/repos/os/src/server/nic_perf/uplink_component.h @@ -0,0 +1,195 @@ +/* + * \brief Uplink root and session component + * \author Johannes Schlatow + * \date 2022-06-17 + */ + +/* + * Copyright (C) 2022 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 _UPLINK_ROOT_H_ +#define _UPLINK_ROOT_H_ + +/* local includes */ +#include + +/* Genode includes */ +#include +#include +#include +#include +#include + +namespace Nic_perf { + class Uplink_session_base; + class Uplink_session_component; + class Uplink_root; + + using namespace Genode; +} + + +class Nic_perf::Uplink_session_base +{ + friend class Uplink_session_component; + + private: + + class Buffer + { + private: + + Ram_allocator &_ram_alloc; + Ram_dataspace_capability _ram_ds; + + public: + + Buffer(Ram_allocator &ram_alloc, + size_t const size) + : + _ram_alloc { ram_alloc }, + _ram_ds { ram_alloc.alloc(size) } + { } + + ~Buffer() { _ram_alloc.free(_ram_ds); } + + Dataspace_capability ds() const { return _ram_ds; } + }; + + Env &_env; + Allocator &_alloc; + Nic::Packet_allocator _packet_alloc; + Buffer _tx_buf; + Buffer _rx_buf; + + public: + + Uplink_session_base(Env &env, + size_t tx_buf_size, + size_t rx_buf_size, + Allocator &alloc) + : + _env { env }, + _alloc { alloc }, + _packet_alloc { &_alloc }, + _tx_buf { _env.ram(), tx_buf_size }, + _rx_buf { _env.ram(), rx_buf_size } + { } +}; + + +class Nic_perf::Uplink_session_component : private Uplink_session_base, + public Uplink::Session_rpc_object +{ + private: + + Interface _interface; + Signal_handler _packet_stream_handler + { _env.ep(), *this, &Uplink_session_component::_handle_packet_stream }; + + void _handle_packet_stream() { + _interface.handle_packet_stream(); } + + public: + + Uplink_session_component(size_t const tx_buf_size, + size_t const rx_buf_size, + Allocator &alloc, + Env &env, + Session_label const &label, + Xml_node const &policy, + Interface_registry ®istry, + Mac_address mac, + Timer::Connection &timer) + : + Uplink_session_base(env, tx_buf_size, rx_buf_size, alloc), + Uplink::Session_rpc_object(env.rm(), _tx_buf.ds(), _rx_buf.ds(), + &_packet_alloc, env.ep().rpc_ep()), + _interface(registry, label, policy, false, mac, + *_rx.source(), *_tx.sink(), timer) + { + _interface.handle_packet_stream(); + + _tx.sigh_ready_to_ack (_packet_stream_handler); + _tx.sigh_packet_avail (_packet_stream_handler); + _rx.sigh_ack_avail (_packet_stream_handler); + _rx.sigh_ready_to_submit(_packet_stream_handler); + } +}; + + +class Nic_perf::Uplink_root : public Root_component +{ + private: + Env &_env; + Attached_rom_dataspace &_config; + Interface_registry &_registry; + Timer::Connection &_timer; + + protected: + + Uplink_session_component *_create_session(char const *args) override + { + size_t ram_quota = Arg_string::find_arg(args, "ram_quota" ).ulong_value(0); + size_t tx_buf_size = Arg_string::find_arg(args, "tx_buf_size").ulong_value(0); + size_t rx_buf_size = Arg_string::find_arg(args, "rx_buf_size").ulong_value(0); + + /* deplete ram quota by the memory needed for the session structure */ + size_t session_size = max(4096UL, (size_t)sizeof(Uplink_session_component)); + if (ram_quota < session_size) + throw Insufficient_ram_quota(); + + /* + * Check if donated ram quota suffices for both communication + * buffers and check for overflow + */ + if (tx_buf_size + rx_buf_size < tx_buf_size || + tx_buf_size + rx_buf_size > ram_quota - session_size) { + error("insufficient 'ram_quota', got ", ram_quota, ", " + "need ", tx_buf_size + rx_buf_size + session_size); + throw Insufficient_ram_quota(); + } + + enum { MAC_STR_LENGTH = 19 }; + char mac_str [MAC_STR_LENGTH]; + Arg mac_arg { Arg_string::find_arg(args, "mac_address") }; + + if (!mac_arg.valid()) + throw Service_denied(); + + mac_arg.string(mac_str, MAC_STR_LENGTH, ""); + Mac_address mac { }; + ascii_to(mac_str, mac); + if (mac == Mac_address { }) + throw Service_denied(); + + Session_label label = label_from_args(args); + + Session_policy policy(label, _config.xml()); + + return new (md_alloc()) Uplink_session_component(tx_buf_size, rx_buf_size, + *md_alloc(), _env, label, policy, + _registry, mac, _timer); + } + + public: + + Uplink_root(Env &env, + Allocator &md_alloc, + Interface_registry ®istry, + Attached_rom_dataspace &config, + Timer::Connection &timer) + : + Root_component(&env.ep().rpc_ep(), &md_alloc), + _env(env), + _config(config), + _registry(registry), + _timer(timer) + { } +}; + +#endif /* _UPLINK_ROOT_H_ */ diff --git a/repos/os/src/server/nic_router/README b/repos/os/src/server/nic_router/README index eae491da8c..0a1f032358 100644 --- a/repos/os/src/server/nic_router/README +++ b/repos/os/src/server/nic_router/README @@ -485,10 +485,32 @@ sub-tags. The attribute states the domain from whose IP config to take the DNS domain name and the list of DNS server addresses that shall be propagated. Note that the order of DNS server adresses is not altered thereby. This is useful in scenarios where these addresses must be obtained dynamically through the DHCP -client of another domain. An implication of the 'dns_config_from' attribute is -that the link state of all interfaces at the domain with the DHCP server -becomes bound to the validity of the IP config of the domain that is stated in -the attribute. +client of another domain. + +There is an additional feature the router implements together with the +'dns_config_from' functionality. If a domain has a DHCP server with a +'dns_config_from' value that denominates another valid domain, the link state +of all interfaces, where the router is a NIC session server, at the first +domain becomes bound to the validity of the IP config of the second domain. + +One motivation for having this feature is to optimize the network boot-up time +of application clients of the NIC router by preventing DHCP re-attempt +timeouts. Such timeouts would occur because clients attempt DHCP as soon as +their interface goes up and without the extra feature, the DHCP server would +potentially not be ready yet. + +But this feature is not only an optimization. It also implies that whenever the +domain denominated by 'dns_config_from' receives a new IP config with a new DNS +configuration, application clients are poked via a link state "down-up" +sequence to re-request DHCP and thereby update their DNS configuration. I.e. it +enables dynamic DNS config propagation. + +However, please be aware this feature is limited to applications that connect +directly and via a NIC session client to the NIC router. This is due to two +technical limitations. First, the router can't control the link state at +interfaces where he acts as NIC session client or Uplink session server. And +second, the router can't ensure that link state changes reach the client if +there are intermediate network components like a NIC bridge. The lifetime of an IP address assignment that was yet only offered to the client can be configured for all domains in the tag of the router: @@ -720,10 +742,10 @@ information on that, refer to [Behavior regarding the NIC-session link state]. 'link_state_triggers' -A boolean value that controls whether to enforce sending a report each time the -state that is controlled through the 'link_state' attribute of the tag -changes. I.e., whenever the real link state of any interface at the router has -changed. +A boolean value that controls whether to enforce sending a report whenever the +real link state (see description of the 'link_state' attribute) of any +interface at the router has changed. Note that whenever an interface is created +or destroyed this is considered a change of its real link state. 'interval_sec' @@ -743,7 +765,7 @@ Whether to log router decisions and optional hints. ! ! -! +! Whether to log most important protocol header fields of each packet that is received or sent (ETH, IPv4, ARP, UDP, TCP, DHCP, ICMP). The value @@ -751,7 +773,7 @@ affects all domains without a local value. ! ! -! +! Whether to log each packet drop and the rational behind it. The value affects all domains without a local value. @@ -762,6 +784,28 @@ Whether to log most important changes in the state of a domain (number of interfaces assigned, current IPv4 config). +Tracing +~~~~~~~ + +You can use Genode's TRACE service to capture all packets that traverse the +router. This requires a monitor component such as the trace-recorder component +that provides and activates a corresponding trace buffer and trace policy. +More precisely, packet tracing is realised via the 'trace_eth_packet()' hook +that needs to be implemented by the trace policy. Note that packet tracing must +also be enabled in the router configuration. + +This is how you can configure whether to trace packets (default values shown): + +! +! +! + +If enabled, 'trace_eth_packet()' is called for every packet received or sent by +the router. The attribute in the tag applies only for packets +received and sent by that domain. The attribute in the tag sets the +default value for all tags without a local setting. + + Other configuration attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -793,7 +837,7 @@ this can lead to starvation of the other interfaces. Thus, the maximum number of packets handled per signal is limited by default. This limit can be configured as follows (default value shown): -! +! When set to zero, the limit is deactivated, meaning that the router always handles all available packets of an interface. diff --git a/repos/os/src/server/nic_router/arp_cache.cc b/repos/os/src/server/nic_router/arp_cache.cc index 500e858f6e..6493abf6af 100644 --- a/repos/os/src/server/nic_router/arp_cache.cc +++ b/repos/os/src/server/nic_router/arp_cache.cc @@ -37,19 +37,6 @@ bool Arp_cache_entry::_higher(Ipv4_address const &ip) const } -Arp_cache_entry const & -Arp_cache_entry::find_by_ip(Ipv4_address const &ip) const -{ - if (ip == _ip) { - return *this; } - - Arp_cache_entry const *const entry = child(_higher(ip)); - if (!entry) { - throw Arp_cache::No_match(); } - - return entry->find_by_ip(ip); -} - void Arp_cache_entry::print(Output &output) const { Genode::print(output, _ip, " > ", _mac); @@ -79,15 +66,6 @@ void Arp_cache::new_entry(Ipv4_address const &ip, Mac_address const &mac) } -Arp_cache_entry const &Arp_cache::find_by_ip(Ipv4_address const &ip) const -{ - if (!first()) { - throw No_match(); } - - return first()->find_by_ip(ip); -} - - void Arp_cache::destroy_entries_with_mac(Mac_address const &mac) { for (unsigned curr = 0; curr < NR_OF_ENTRIES; curr++) { @@ -105,3 +83,17 @@ void Arp_cache::destroy_entries_with_mac(Mac_address const &mac) } catch (Arp_cache_entry_slot::Deref_unconstructed_object) { } } } + + +void Arp_cache::destroy_all_entries() +{ + if (_domain.config().verbose()) { + log("[", _domain, "] destroy all ARP entries"); + } + while (Arp_cache_entry *entry = first()) { + remove(entry); + } + for (unsigned curr = 0; curr < NR_OF_ENTRIES; curr++) { + _entries[curr].destruct(); + } +} diff --git a/repos/os/src/server/nic_router/arp_cache.h b/repos/os/src/server/nic_router/arp_cache.h index 8844f576bf..18a5042f76 100644 --- a/repos/os/src/server/nic_router/arp_cache.h +++ b/repos/os/src/server/nic_router/arp_cache.h @@ -42,7 +42,33 @@ class Net::Arp_cache_entry : public Genode::Avl_node Arp_cache_entry(Ipv4_address const &ip, Mac_address const &mac); - Arp_cache_entry const &find_by_ip(Ipv4_address const &ip) const; + template + + void find_by_ip(Ipv4_address const &ip, + HANDLE_MATCH_FN && handle_match, + HANDLE_NO_MATCH_FN && handle_no_match) const + { + if (ip != _ip) { + + Arp_cache_entry *const entry_ptr { + Avl_node::child( + _higher(ip)) }; + + if (entry_ptr != nullptr) { + + entry_ptr->find_by_ip( + ip, handle_match, handle_no_match); + + } else { + + handle_no_match(); + } + } else { + + handle_match(*this); + } + } /************** @@ -83,15 +109,30 @@ class Net::Arp_cache : public Genode::Avl_tree public: - struct No_match : Genode::Exception { }; - Arp_cache(Domain const &domain) : _domain(domain) { } void new_entry(Ipv4_address const &ip, Mac_address const &mac); void destroy_entries_with_mac(Mac_address const &mac); - Arp_cache_entry const &find_by_ip(Ipv4_address const &ip) const; + template + + void find_by_ip(Ipv4_address const &ip, + HANDLE_MATCH_FN && handle_match, + HANDLE_NO_MATCH_FN && handle_no_match) const + { + if (first() != nullptr) { + + first()->find_by_ip(ip, handle_match, handle_no_match); + + } else { + + handle_no_match(); + } + } + + void destroy_all_entries(); }; #endif /* _ARP_CACHE_H_ */ diff --git a/repos/os/src/server/nic_router/avl_string_tree.h b/repos/os/src/server/nic_router/avl_string_tree.h deleted file mode 100644 index 31a4e956b8..0000000000 --- a/repos/os/src/server/nic_router/avl_string_tree.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * \brief AVL tree of strings with additional functions needed by NIC router - * \author Martin Stein - * \date 2016-08-19 - */ - -/* - * Copyright (C) 2016-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 _AVL_STRING_TREE_H_ -#define _AVL_STRING_TREE_H_ - -/* local includes */ -#include - -/* Genode includes */ -#include -#include - -namespace Net { template class Avl_string_tree; } - - -template -class Net::Avl_string_tree : public Genode::Avl_tree -{ - private: - - using Node = Genode::Avl_string_base; - using Tree = Genode::Avl_tree; - - OBJECT &_find_by_name(char const *name) - { - if (!first()) { - throw No_match(); } - - Node *node = first()->find_by_name(name); - if (!node) { - throw No_match(); } - - return *static_cast(node); - } - - public: - - struct No_match : Genode::Exception { }; - struct Name_not_unique : Genode::Exception - { - OBJECT &object; - - Name_not_unique(OBJECT &object) : object(object) { } - }; - - OBJECT &find_by_name(NAME const &name) { return _find_by_name(name.string()); } - - template - void for_each(FUNCTOR && functor) const { - Tree::for_each([&] (Node const &node) { - - /* - * FIXME This constness cast sneaked in with an older - * implementation where it was done implicitely and - * therefore not that obvious. Now the router relies on - * it and we should either get rid of the dependency to - * const Avl_tree::for_each or of the the need for - * mutable objects in Avl_string_tree::for_each. - */ - functor(*const_cast(static_cast(&node))); - }); - } - - void destroy_each(Genode::Deallocator &dealloc) - { - while (Node *node = first()) { - Tree::remove(node); - Genode::destroy(dealloc, static_cast(node)); - } - } - - void insert(OBJECT &object) - { - try { throw Name_not_unique(_find_by_name(static_cast(&object)->name())); } - catch (No_match) { Tree::insert(&object); } - } - - void remove(OBJECT &object) { Tree::remove(&object); } -}; - - - -#endif /* _AVL_STRING_TREE_H_ */ diff --git a/repos/os/src/server/nic_router/cached_timer.h b/repos/os/src/server/nic_router/cached_timer.h new file mode 100644 index 0000000000..0e7b4e2c12 --- /dev/null +++ b/repos/os/src/server/nic_router/cached_timer.h @@ -0,0 +1,74 @@ +/* + * \brief A wrapper for Timer::Connection that caches time values + * \author Johannes Schlatow + * \date 2022-07-07 + * + * This implementation aims for reducing the number of + * Timer::Connection::curr_time() that was found to be relatively + * expensive on base-hw (implies a syscall on each call) by assuming that + * a certain caching is fine with the accuracy requirements of the NIC router. + */ + +/* + * Copyright (C) 2022 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 _CACHED_TIMER_H_ +#define _CACHED_TIMER_H_ + +/* Genode includes */ +#include + +namespace Net { + + class Cached_timer; +} + + +class Net::Cached_timer : public ::Timer::Connection +{ + private: + + using Duration = Genode::Duration; + using Microseconds = Genode::Microseconds; + + Duration _cached_time { Microseconds { 0 } }; + + public: + + Cached_timer (Genode::Env &env) + : + Timer::Connection { env } + { } + + /** + * Update cached time with current timer + */ + void update_cached_time() + { + _cached_time = Timer::Connection::curr_time(); + } + + /** + * Update cached time and return it + */ + Duration curr_time() override + { + update_cached_time(); + return cached_time(); + } + + + /*************** + ** Accessors ** + ***************/ + + Duration cached_time() const { return _cached_time; } + + void cached_time(Duration time) { _cached_time = time; } +}; + +#endif /* _CACHED_TIMER_H_ */ diff --git a/repos/os/src/server/nic_router/config.xsd b/repos/os/src/server/nic_router/config.xsd index 35fc2975bb..3b46a1d104 100644 --- a/repos/os/src/server/nic_router/config.xsd +++ b/repos/os/src/server/nic_router/config.xsd @@ -171,6 +171,7 @@ + @@ -182,6 +183,7 @@ + diff --git a/repos/os/src/server/nic_router/configuration.cc b/repos/os/src/server/nic_router/configuration.cc index 09efbbf57d..4549bd8877 100644 --- a/repos/os/src/server/nic_router/configuration.cc +++ b/repos/os/src/server/nic_router/configuration.cc @@ -36,6 +36,7 @@ Configuration::Configuration(Xml_node const node, _verbose_packets { false }, _verbose_packet_drop { false }, _verbose_domain_state { false }, + _trace_packets { false }, _icmp_echo_server { false }, _icmp_type_3_code_on_fragm_ipv4 { 0 }, _dhcp_discover_timeout { 0 }, @@ -49,24 +50,12 @@ Configuration::Configuration(Xml_node const node, { } -void Configuration::_invalid_nic_client(Nic_client &nic_client, - char const *reason) -{ - if (_verbose) { - log("[", nic_client.domain(), "] invalid NIC client: ", nic_client, " (", reason, ")"); } - - _nic_clients.remove(nic_client); - destroy(_alloc, &nic_client); -} - - void Configuration::_invalid_domain(Domain &domain, char const *reason) { if (_verbose) { log("[", domain, "] invalid domain (", reason, ") "); } - _domains.remove(domain); destroy(_alloc, &domain); } @@ -102,20 +91,22 @@ Configuration::_init_icmp_type_3_code_on_fragm_ipv4(Xml_node const &node) const } -Configuration::Configuration(Env &env, - Xml_node const node, - Allocator &alloc, - Timer::Connection &timer, - Configuration &old_config, - Quota const &shared_quota, - Interface_list &interfaces) +Configuration::Configuration(Env &env, + Xml_node const node, + Allocator &alloc, + Signal_context_capability const &report_signal_cap, + Cached_timer &timer, + Configuration &old_config, + Quota const &shared_quota, + Interface_list &interfaces) : _alloc { alloc }, - _max_packets_per_signal { node.attribute_value("max_packets_per_signal", (unsigned long)32) }, + _max_packets_per_signal { node.attribute_value("max_packets_per_signal", (unsigned long)150) }, _verbose { node.attribute_value("verbose", false) }, _verbose_packets { node.attribute_value("verbose_packets", false) }, _verbose_packet_drop { node.attribute_value("verbose_packet_drop", false) }, _verbose_domain_state { node.attribute_value("verbose_domain_state", false) }, + _trace_packets { node.attribute_value("trace_packets", false) }, _icmp_echo_server { node.attribute_value("icmp_echo_server", true) }, _icmp_type_3_code_on_fragm_ipv4 { _init_icmp_type_3_code_on_fragm_ipv4(node) }, _dhcp_discover_timeout { read_sec_attr(node, "dhcp_discover_timeout_sec", 10) }, @@ -130,12 +121,29 @@ Configuration::Configuration(Env &env, /* do parts of domain initialization that do not lookup other domains */ node.for_each_sub_node("domain", [&] (Xml_node const node) { try { - Domain &domain = *new (_alloc) Domain(*this, node, _alloc); - try { _domains.insert(domain); } - catch (Domain_tree::Name_not_unique exception) { - _invalid_domain(domain, "name not unique"); - _invalid_domain(exception.object, "name not unique"); - } + Domain_name const name { + node.attribute_value("name", Domain_name { }) }; + + _domains.with_element( + name, + [&] /* match_fn */ (Domain &other_domain) + { + if (_verbose) { + + log("[", name, + "] invalid domain (name not unique) "); + + log("[", other_domain, + "] invalid domain (name not unique) "); + } + destroy(_alloc, &other_domain); + }, + [&] /* no_match_fn */ () + { + new (_alloc) Domain { + *this, node, name, _alloc, _domains }; + } + ); } catch (Domain::Invalid) { } }); @@ -159,7 +167,6 @@ Configuration::Configuration(Env &env, catch (Retry_without_domain exception) { /* destroy domain that became invalid during initialization */ - _domains.remove(exception.domain); destroy(_alloc, &exception.domain); /* deinitialize the remaining domains again */ @@ -188,52 +195,53 @@ Configuration::Configuration(Env &env, } /* create report generator */ _report = *new (_alloc) - Report(_verbose, report_node, timer, _domains, shared_quota, - env.pd(), _reporter()); + Report { + _verbose, report_node, timer, _domains, shared_quota, env.pd(), + _reporter(), report_signal_cap }; } catch (Genode::Xml_node::Nonexistent_sub_node) { } /* initialize NIC clients */ _node.for_each_sub_node("nic-client", [&] (Xml_node const node) { try { - Nic_client &nic_client = *new (_alloc) - Nic_client { node, alloc, old_config._nic_clients, env, timer, - interfaces, *this }; + Session_label const label { + node.attribute_value("label", Session_label::String { }) }; - try { _nic_clients.insert(nic_client); } - catch (Nic_client_tree::Name_not_unique exception) { - _invalid_nic_client(nic_client, "label not unique"); - _invalid_nic_client(exception.object, "label not unique"); - } + Domain_name const domain { + node.attribute_value("domain", Domain_name { }) }; + + _nic_clients.with_element( + label, + [&] /* match */ (Nic_client &nic_client) + { + if (_verbose) { + + log("[", domain, "] invalid NIC client: ", + label, " (label not unique)"); + + log("[", nic_client.domain(), "] invalid NIC client: ", + nic_client.label(), " (label not unique)"); + } + destroy(_alloc, &nic_client); + }, + [&] /* no_match */ () + { + new (_alloc) Nic_client { + label, domain, alloc, old_config._nic_clients, + _nic_clients, env, timer, interfaces, *this }; + } + ); } catch (Nic_client::Invalid) { } }); /* - * Destroy old NIC clients to ensure that NIC client interfaces that were not - * re-used are not re-attached to the new domains. + * Destroy old NIC clients to ensure that NIC client interfaces that were + * not re-used are not re-attached to the new domains. */ old_config._nic_clients.destroy_each(_alloc); } -void Configuration::stop_reporting() -{ - if (!_reporter.valid()) { - return; - } - _reporter().enabled(false); -} - - -void Configuration::start_reporting() -{ - if (!_reporter.valid()) { - return; - } - _reporter().enabled(true); -} - - Configuration::~Configuration() { /* destroy NIC clients */ diff --git a/repos/os/src/server/nic_router/configuration.h b/repos/os/src/server/nic_router/configuration.h index 8eb0c1eb09..a6c4fca841 100644 --- a/repos/os/src/server/nic_router/configuration.h +++ b/repos/os/src/server/nic_router/configuration.h @@ -39,6 +39,7 @@ class Net::Configuration bool const _verbose_packets; bool const _verbose_packet_drop; bool const _verbose_domain_state; + bool const _trace_packets; bool const _icmp_echo_server; Icmp_packet::Code const _icmp_type_3_code_on_fragm_ipv4; Genode::Microseconds const _dhcp_discover_timeout; @@ -50,38 +51,32 @@ class Net::Configuration Genode::Microseconds const _tcp_max_segm_lifetime; Pointer _report { }; Pointer _reporter { }; - Domain_tree _domains { }; - Nic_client_tree _nic_clients { }; + Domain_dict _domains { }; + Nic_client_dict _nic_clients { }; Genode::Xml_node const _node; Icmp_packet::Code _init_icmp_type_3_code_on_fragm_ipv4(Genode::Xml_node const &node) const; - void _invalid_nic_client(Nic_client &nic_client, - char const *reason); - void _invalid_domain(Domain &domain, char const *reason); public: - Configuration(Genode::Xml_node const node, - Genode::Allocator &alloc); + Configuration(Genode::Xml_node const node, + Genode::Allocator &alloc); - Configuration(Genode::Env &env, - Genode::Xml_node const node, - Genode::Allocator &alloc, - Timer::Connection &timer, - Configuration &old_config, - Quota const &shared_quota, - Interface_list &interfaces); + Configuration(Genode::Env &env, + Genode::Xml_node const node, + Genode::Allocator &alloc, + Genode::Signal_context_capability const &report_signal_cap, + Cached_timer &timer, + Configuration &old_config, + Quota const &shared_quota, + Interface_list &interfaces); ~Configuration(); - void stop_reporting(); - - void start_reporting(); - /*************** ** Accessors ** @@ -92,6 +87,7 @@ class Net::Configuration bool verbose_packets() const { return _verbose_packets; } bool verbose_packet_drop() const { return _verbose_packet_drop; } bool verbose_domain_state() const { return _verbose_domain_state; } + bool trace_packets() const { return _trace_packets; } bool icmp_echo_server() const { return _icmp_echo_server; } Icmp_packet::Code icmp_type_3_code_on_fragm_ipv4() const { return _icmp_type_3_code_on_fragm_ipv4; } Genode::Microseconds dhcp_discover_timeout() const { return _dhcp_discover_timeout; } @@ -101,7 +97,7 @@ class Net::Configuration Genode::Microseconds udp_idle_timeout() const { return _udp_idle_timeout; } Genode::Microseconds tcp_idle_timeout() const { return _tcp_idle_timeout; } Genode::Microseconds tcp_max_segm_lifetime() const { return _tcp_max_segm_lifetime; } - Domain_tree &domains() { return _domains; } + Domain_dict &domains() { return _domains; } Report &report() { return _report(); } Genode::Xml_node node() const { return _node; } }; diff --git a/repos/os/src/server/nic_router/dhcp_client.cc b/repos/os/src/server/nic_router/dhcp_client.cc index 4440e3c22a..99e499a7c6 100644 --- a/repos/os/src/server/nic_router/dhcp_client.cc +++ b/repos/os/src/server/nic_router/dhcp_client.cc @@ -17,8 +17,6 @@ #include #include -enum { PKT_SIZE = 1024 }; - using namespace Genode; using namespace Net; using Message_type = Dhcp_packet::Message_type; @@ -54,7 +52,7 @@ Configuration &Dhcp_client::_config() { return _domain().config(); }; Domain &Dhcp_client::_domain() { return _interface.domain(); } -Dhcp_client::Dhcp_client(Timer::Connection &timer, +Dhcp_client::Dhcp_client(Cached_timer &timer, Interface &interface) : _interface(interface), @@ -64,17 +62,20 @@ Dhcp_client::Dhcp_client(Timer::Connection &timer, void Dhcp_client::discover() { + enum { DISCOVER_PKT_SIZE = 309 }; _set_state(State::SELECT, _config().dhcp_discover_timeout()); _send(Message_type::DISCOVER, Ipv4_address(), Ipv4_address(), - Ipv4_address()); + Ipv4_address(), DISCOVER_PKT_SIZE); } void Dhcp_client::_rerequest(State next_state) { + enum { REREQUEST_PKT_SIZE = 309 }; _set_state(next_state, _rerequest_timeout(2)); Ipv4_address const client_ip = _domain().ip_config().interface().address; - _send(Message_type::REQUEST, client_ip, Ipv4_address(), client_ip); + _send(Message_type::REQUEST, client_ip, Ipv4_address(), client_ip, + REREQUEST_PKT_SIZE); } @@ -129,10 +130,11 @@ void Dhcp_client::handle_dhcp_reply(Dhcp_packet &dhcp) if (msg_type != Message_type::OFFER) { throw Drop_packet("DHCP client expects an offer"); } + enum { REQUEST_PKT_SIZE = 321 }; _set_state(State::REQUEST, _config().dhcp_request_timeout()); _send(Message_type::REQUEST, Ipv4_address(), dhcp.option().value(), - dhcp.yiaddr()); + dhcp.yiaddr(), REQUEST_PKT_SIZE); break; case State::REQUEST: @@ -159,10 +161,11 @@ void Dhcp_client::handle_dhcp_reply(Dhcp_packet &dhcp) void Dhcp_client::_send(Message_type msg_type, Ipv4_address client_ip, Ipv4_address server_ip, - Ipv4_address requested_ip) + Ipv4_address requested_ip, + size_t pkt_size) { Mac_address client_mac = _interface.router_mac(); - _interface.send(PKT_SIZE, [&] (void *pkt_base, Size_guard &size_guard) { + _interface.send(pkt_size, [&] (void *pkt_base, Size_guard &size_guard) { /* create ETH header of the request */ Ethernet_frame ð = Ethernet_frame::construct_at(pkt_base, size_guard); @@ -198,19 +201,20 @@ void Dhcp_client::_send(Message_type msg_type, dhcp.default_magic_cookie(); /* append DHCP option fields to the request */ + enum { MAX_PKT_SIZE = 1024 }; Dhcp_options dhcp_opts(dhcp, size_guard); dhcp_opts.append_option(msg_type); switch (msg_type) { case Message_type::DISCOVER: append_param_req_list(dhcp_opts); dhcp_opts.append_option(client_mac); - dhcp_opts.append_option(PKT_SIZE - dhcp_off); + dhcp_opts.append_option(MAX_PKT_SIZE - dhcp_off); break; case Message_type::REQUEST: append_param_req_list(dhcp_opts); dhcp_opts.append_option(client_mac); - dhcp_opts.append_option(PKT_SIZE - dhcp_off); + dhcp_opts.append_option(MAX_PKT_SIZE - dhcp_off); if (_state == State::REQUEST) { dhcp_opts.append_option(requested_ip); dhcp_opts.append_option(server_ip); @@ -228,4 +232,6 @@ void Dhcp_client::_send(Message_type msg_type, ip.total_length(size_guard.head_size() - ip_off); ip.update_checksum(); }); + + _interface.wakeup_source(); } diff --git a/repos/os/src/server/nic_router/dhcp_client.h b/repos/os/src/server/nic_router/dhcp_client.h index f56e5e5ad4..066cdc726a 100644 --- a/repos/os/src/server/nic_router/dhcp_client.h +++ b/repos/os/src/server/nic_router/dhcp_client.h @@ -14,8 +14,10 @@ #ifndef _DHCP_CLIENT_H_ #define _DHCP_CLIENT_H_ +/* local includes */ +#include + /* Genode includes */ -#include #include namespace Net { @@ -52,7 +54,8 @@ class Net::Dhcp_client void _send(Dhcp_packet::Message_type msg_type, Ipv4_address client_ip, Ipv4_address server_ip, - Ipv4_address requested_ip); + Ipv4_address requested_ip, + Genode::size_t pkt_size); Configuration &_config(); @@ -60,7 +63,7 @@ class Net::Dhcp_client public: - Dhcp_client(Timer::Connection &timer, + Dhcp_client(Cached_timer &timer, Interface &interface); void handle_dhcp_reply(Dhcp_packet &dhcp); diff --git a/repos/os/src/server/nic_router/dhcp_server.cc b/repos/os/src/server/nic_router/dhcp_server.cc index 1637a7655f..756c22cb0e 100644 --- a/repos/os/src/server/nic_router/dhcp_server.cc +++ b/repos/os/src/server/nic_router/dhcp_server.cc @@ -34,16 +34,19 @@ Dhcp_server_base::Dhcp_server_base(Xml_node const &node, { node.for_each_sub_node("dns-server", [&] (Xml_node const &sub_node) { - try { - _dns_servers.insert_as_tail(*new (alloc) - Dns_server(sub_node.attribute_value("ip", Ipv4_address()))); - - } catch (Dns_server::Invalid) { - - _invalid(domain, "invalid DNS server entry"); - } + Dns_server::construct( + alloc, sub_node.attribute_value("ip", Ipv4_address { }), + [&] /* handle_success */ (Dns_server &server) + { + _dns_servers.insert_as_tail(server); + }, + [&] /* handle_failure */ () + { + _invalid(domain, "invalid DNS server entry"); + } + ); }); - node.with_sub_node("dns-domain", [&] (Xml_node const &sub_node) { + node.with_optional_sub_node("dns-domain", [&] (Xml_node const &sub_node) { xml_node_with_attribute(sub_node, "name", [&] (Xml_attribute const &attr) { _dns_domain_name.set_to(attr); @@ -78,11 +81,21 @@ void Dhcp_server_base::_invalid(Domain const &domain, ** Dhcp_server ** *****************/ +bool Dhcp_server::dns_servers_empty() const +{ + if (_dns_config_from.valid()) { + + return _resolve_dns_config_from().dns_servers_empty(); + } + return _dns_servers.empty(); +} + + Dhcp_server::Dhcp_server(Xml_node const node, Domain &domain, Allocator &alloc, Ipv4_address_prefix const &interface, - Domain_tree &domains) + Domain_dict &domains) : Dhcp_server_base(node, domain, alloc), _dns_config_from(_init_dns_config_from(node, domains)), @@ -193,7 +206,7 @@ void Dhcp_server::free_ip(Domain const &domain, Pointer Dhcp_server::_init_dns_config_from(Genode::Xml_node const node, - Domain_tree &domains) + Domain_dict &domains) { if (!_dns_servers.empty() || _dns_domain_name.valid()) { @@ -206,19 +219,16 @@ Pointer Dhcp_server::_init_dns_config_from(Genode::Xml_node const node, if (dns_config_from == Domain_name()) { return Pointer(); } - try { return domains.find_by_name(dns_config_from); } - catch (Domain_tree::No_match) { throw Invalid(); } + return domains.deprecated_find_by_name(dns_config_from); } -bool Dhcp_server::ready() const +bool Dhcp_server::has_invalid_remote_dns_cfg() const { - if (!_dns_servers.empty()) { - return true; + if (_dns_config_from.valid()) { + return !_dns_config_from().ip_config().valid(); } - try { return _dns_config_from().ip_config().valid(); } - catch (Pointer::Invalid) { } - return true; + return false; } @@ -229,7 +239,7 @@ bool Dhcp_server::ready() const Dhcp_allocation::Dhcp_allocation(Interface &interface, Ipv4_address const &ip, Mac_address const &mac, - Timer::Connection &timer, + Cached_timer &timer, Microseconds lifetime) : _interface(interface), _ip(ip), _mac(mac), diff --git a/repos/os/src/server/nic_router/dhcp_server.h b/repos/os/src/server/nic_router/dhcp_server.h index e903e8f02e..6022272797 100644 --- a/repos/os/src/server/nic_router/dhcp_server.h +++ b/repos/os/src/server/nic_router/dhcp_server.h @@ -20,6 +20,7 @@ #include #include #include +#include /* Genode includes */ #include @@ -39,7 +40,7 @@ namespace Net { /* forward declarations */ class Interface; class Domain; - class Domain_tree; + class Domain_dict; } @@ -80,7 +81,7 @@ class Net::Dhcp_server : private Genode::Noncopyable, Genode::Microseconds _init_ip_lease_time(Genode::Xml_node const node); Pointer _init_dns_config_from(Genode::Xml_node const node, - Domain_tree &domains); + Domain_dict &domains); Ipv4_config const &_resolve_dns_config_from() const; @@ -95,7 +96,7 @@ class Net::Dhcp_server : private Genode::Noncopyable, Domain &domain, Genode::Allocator &alloc, Ipv4_address_prefix const &interface, - Domain_tree &domains); + Domain_dict &domains); Ipv4_address alloc_ip(); @@ -104,7 +105,7 @@ class Net::Dhcp_server : private Genode::Noncopyable, void free_ip(Domain const &domain, Ipv4_address const &ip); - bool ready() const; + bool has_invalid_remote_dns_cfg() const; template void for_each_dns_server_ip(FUNC && functor) const @@ -124,6 +125,8 @@ class Net::Dhcp_server : private Genode::Noncopyable, } } + bool dns_servers_empty() const; + Dns_domain_name const &dns_domain_name() const { if (_dns_config_from.valid()) { @@ -171,7 +174,7 @@ class Net::Dhcp_allocation : public Genode::Avl_node, Dhcp_allocation(Interface &interface, Ipv4_address const &ip, Mac_address const &mac, - Timer::Connection &timer, + Cached_timer &timer, Genode::Microseconds lifetime); ~Dhcp_allocation(); diff --git a/repos/os/src/server/nic_router/dictionary.h b/repos/os/src/server/nic_router/dictionary.h new file mode 100644 index 0000000000..635c5f88e8 --- /dev/null +++ b/repos/os/src/server/nic_router/dictionary.h @@ -0,0 +1,55 @@ +/* + * \brief Local convenience wrapper for the Genode dictionary + * \author Martin Stein + * \date 2022-09-16 + */ + +/* + * Copyright (C) 2022 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 _DICTIONARY_H_ +#define _DICTIONARY_H_ + +/* Genode includes */ +#include +#include + +namespace Net { template class Dictionary; } + + +template + +class Net::Dictionary : public Genode::Dictionary +{ + private: + + using Dict = Genode::Dictionary; + + public: + + template + void for_each(FUNCTION_T const &function) const + { + Dict::for_each( + [&] (OBJECT_T const &obj) + { + function(*const_cast(&obj)); + } + ); + } + + void destroy_each(Genode::Deallocator &dealloc) + { + auto destroy_element { [&] (OBJECT_T &obj) { + destroy(dealloc, &obj); + } }; + while (this->with_any_element(destroy_element)) { } + } +}; + +#endif /* _DICTIONARY_H_ */ diff --git a/repos/os/src/server/nic_router/direct_rule.h b/repos/os/src/server/nic_router/direct_rule.h index e4ccfe93e2..a33bb69590 100644 --- a/repos/os/src/server/nic_router/direct_rule.h +++ b/repos/os/src/server/nic_router/direct_rule.h @@ -73,21 +73,36 @@ struct Net::Direct_rule_list : List { using Base = List; - struct No_match : Genode::Exception { }; - - T const &longest_prefix_match(Ipv4_address const &ip) const + template + void + find_longest_prefix_match(Ipv4_address const &ip, + HANDLE_MATCH_FN && handle_match, + HANDLE_NO_MATCH_FN && handle_no_match) const { - /* first match is sufficient as the list is prefix-size-sorted */ - for (T const *curr = Base::first(); curr; curr = curr->next()) { - if (curr->dst().prefix_matches(ip)) { - return *curr; } + /* + * Simply handling the first match is sufficient as the list is + * sorted by the prefix size in descending order. + */ + for (T const *rule_ptr = Base::first(); + rule_ptr != nullptr; + rule_ptr = rule_ptr->next()) { + + if (rule_ptr->dst().prefix_matches(ip)) { + + handle_match(*rule_ptr); + return; + } } - throw No_match(); + handle_no_match(); } void insert(T &rule) { - /* ensure that the list stays prefix-size-sorted (descending) */ + /* + * Ensure that the list stays sorted by the prefix size in descending + * order. + */ T *behind = nullptr; for (T *curr = Base::first(); curr; curr = curr->next()) { if (rule.dst().prefix >= curr->dst().prefix) { diff --git a/repos/os/src/server/nic_router/dns.cc b/repos/os/src/server/nic_router/dns.cc index fae3892868..d4cbe71f83 100644 --- a/repos/os/src/server/nic_router/dns.cc +++ b/repos/os/src/server/nic_router/dns.cc @@ -30,11 +30,7 @@ using namespace Genode; Dns_server::Dns_server(Ipv4_address const &ip) : _ip { ip } -{ - if (!_ip.valid()) { - throw Invalid { }; - } -} +{ } bool Dns_server::equal_to(Dns_server const &server) const diff --git a/repos/os/src/server/nic_router/dns.h b/repos/os/src/server/nic_router/dns.h index 6d747e56a9..2f8fb6e2a8 100644 --- a/repos/os/src/server/nic_router/dns.h +++ b/repos/os/src/server/nic_router/dns.h @@ -43,11 +43,23 @@ class Net::Dns_server : private Genode::Noncopyable, Net::Ipv4_address const _ip; + Dns_server(Net::Ipv4_address const &ip); + public: - struct Invalid : Genode::Exception { }; + template - Dns_server(Net::Ipv4_address const &ip); + static void construct(Genode::Allocator &alloc, + Net::Ipv4_address const &ip, + HANDLE_SUCCESS_FN && handle_success, + HANDLE_FAILURE_FN && handle_failure) + { + if (!ip.valid()) { + handle_failure(); + } + handle_success(*new (alloc) Dns_server(ip)); + } bool equal_to(Dns_server const &server) const; diff --git a/repos/os/src/server/nic_router/domain.cc b/repos/os/src/server/nic_router/domain.cc index 11af946ab7..25b5001c90 100644 --- a/repos/os/src/server/nic_router/domain.cc +++ b/repos/os/src/server/nic_router/domain.cc @@ -26,16 +26,6 @@ using namespace Net; using namespace Genode; -/***************** - ** Domain_base ** - *****************/ - -Domain_base::Domain_base(Xml_node const node) -: - _name(node.attribute_value("name", Domain_name())) -{ } - - /************ ** Domain ** ************/ @@ -49,6 +39,26 @@ void Domain::_log_ip_config() const } +bool Domain::ready() const +{ + if (_dhcp_server.valid()) { + if (_dhcp_server().has_invalid_remote_dns_cfg()) { + return false; + } + } + return true; +} + + +void Domain::update_ready_state() +{ + bool const rdy { ready() }; + _interfaces.for_each([&] (Interface &interface) { + interface.handle_domain_ready_state(rdy); + }); +} + + void Domain::_prepare_reconstructing_ip_config() { if (!_ip_config_dynamic) { @@ -65,9 +75,7 @@ void Domain::_prepare_reconstructing_ip_config() interface.detach_from_ip_config(*this); }); _ip_config_dependents.for_each([&] (Domain &domain) { - domain._interfaces.for_each([&] (Interface &interface) { - interface.detach_from_remote_ip_config(); - }); + domain.update_ready_state(); }); /* dissolve foreign ARP waiters */ while (_foreign_arp_waiters.first()) { @@ -88,9 +96,7 @@ void Domain::_finish_reconstructing_ip_config() interface.attach_to_ip_config(*this, ip_config()); }); _ip_config_dependents.for_each([&] (Domain &domain) { - domain._interfaces.for_each([&] (Interface &interface) { - interface.attach_to_remote_ip_config(); - }); + domain.update_ready_state(); }); } else { _interfaces.for_each([&] (Interface &interface) { @@ -132,7 +138,7 @@ void Domain::try_reuse_ip_config(Domain const &domain) void Domain::_read_forward_rules(Cstring const &protocol, - Domain_tree &domains, + Domain_dict &domains, Xml_node const node, char const *type, Forward_rule_tree &rules) @@ -158,7 +164,7 @@ void Domain::_invalid(char const *reason) const void Domain::_read_transport_rules(Cstring const &protocol, - Domain_tree &domains, + Domain_dict &domains, Xml_node const node, char const *type, Transport_rule_list &rules) @@ -177,17 +183,20 @@ void Domain::_read_transport_rules(Cstring const &protocol, void Domain::print(Output &output) const { - if (_name == Domain_name()) { + if (name() == Domain_name()) { Genode::print(output, "?"); } else { - Genode::print(output, _name); } + Genode::print(output, name()); } } -Domain::Domain(Configuration &config, Xml_node const node, Allocator &alloc) +Domain::Domain(Configuration &config, + Xml_node const &node, + Domain_name const &name, + Allocator &alloc, + Domain_dict &domains) : - Domain_base { node }, - Avl_string_base { Domain_base::_name.string() }, + Domain_dict::Element { domains, name }, _config { config }, _node { node }, _alloc { alloc }, @@ -196,6 +205,8 @@ Domain::Domain(Configuration &config, Xml_node const node, Allocator &alloc) config.verbose_packets()) }, _verbose_packet_drop { node.attribute_value("verbose_packet_drop", config.verbose_packet_drop()) }, + _trace_packets { node.attribute_value("trace_packets", + config.trace_packets()) }, _icmp_echo_server { node.attribute_value("icmp_echo_server", config.icmp_echo_server()) }, _use_arp { _node.attribute_value("use_arp", true) }, @@ -204,7 +215,7 @@ Domain::Domain(Configuration &config, Xml_node const node, Allocator &alloc) { _log_ip_config(); - if (_name == Domain_name()) { + if (Domain::name() == Domain_name()) { _invalid("missing name attribute"); } if (_config.verbose_domain_state()) { @@ -232,14 +243,14 @@ Domain::~Domain() Dhcp_server &Domain::dhcp_server() { Dhcp_server &dhcp_server = _dhcp_server(); - if (!dhcp_server.ready()) { + if (dhcp_server.has_invalid_remote_dns_cfg()) { throw Pointer::Invalid(); } return dhcp_server; } -void Domain::init(Domain_tree &domains) +void Domain::init(Domain_dict &domains) { /* read DHCP server configuration */ try { @@ -364,8 +375,11 @@ void Domain::detach_interface(Interface &interface) { _interfaces.remove(&interface); _interface_cnt--; - if (!_interface_cnt && _ip_config_dynamic) { - discard_ip_config(); + if (!_interface_cnt) { + _arp_cache.destroy_all_entries(); + if (_ip_config_dynamic) { + discard_ip_config(); + } } if (_config.verbose_domain_state()) { log("[", *this, "] NIC sessions: ", _interface_cnt); @@ -383,7 +397,7 @@ void Domain::report(Xml_generator &xml) { xml.node("domain", [&] () { bool empty = true; - xml.attribute("name", _name); + xml.attribute("name", name()); if (_config.report().bytes()) { xml.attribute("rx_bytes", _tx_bytes); xml.attribute("tx_bytes", _rx_bytes); diff --git a/repos/os/src/server/nic_router/domain.h b/repos/os/src/server/nic_router/domain.h index f92e6d7d9d..fb8ce11403 100644 --- a/repos/os/src/server/nic_router/domain.h +++ b/repos/os/src/server/nic_router/domain.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include /* Genode includes */ #include @@ -40,10 +40,9 @@ namespace Net { class Interface; class Configuration; - class Domain_base; class Domain; using Domain_name = Genode::String<160>; - class Domain_tree; + class Domain_dict; class Domain_link_stats; class Domain_object_stats; } @@ -71,22 +70,35 @@ struct Net::Domain_link_stats : Domain_object_stats }; -class Net::Domain_tree : public Avl_string_tree { }; - - -class Net::Domain_base +class Net::Domain_dict : public Dictionary { - protected: + public: - Domain_name const _name; + template + Domain &deprecated_find_by_name(Domain_name const &domain_name) + { + Domain *dom_ptr { nullptr }; + with_element( + domain_name, + [&] /* match_fn */ (Domain &dom) { dom_ptr = &dom; }, + [&] /* no_match_fn */ () { throw NO_MATCH_EXCEPTION { }; } + ); + return *dom_ptr; + } - Domain_base(Genode::Xml_node const node); + template + Domain &deprecated_find_by_domain_attr(Genode::Xml_node const &node) + { + Domain_name const domain_name { + node.attribute_value("domain", Domain_name { }) }; + + return deprecated_find_by_name(domain_name); + } }; -class Net::Domain : public Domain_base, - public List::Element, - public Genode::Avl_string_base +class Net::Domain : public List::Element, + public Domain_dict::Element { private: @@ -118,6 +130,7 @@ class Net::Domain : public Domain_base, Genode::size_t _rx_bytes { 0 }; bool const _verbose_packets; bool const _verbose_packet_drop; + bool const _trace_packets; bool const _icmp_echo_server; bool const _use_arp; Genode::Session_label const _label; @@ -129,13 +142,13 @@ class Net::Domain : public Domain_base, unsigned long _dropped_fragm_ipv4 { 0 }; void _read_forward_rules(Genode::Cstring const &protocol, - Domain_tree &domains, + Domain_dict &domains, Genode::Xml_node const node, char const *type, Forward_rule_tree &rules); void _read_transport_rules(Genode::Cstring const &protocol, - Domain_tree &domains, + Domain_dict &domains, Genode::Xml_node const node, char const *type, Transport_rule_list &rules); @@ -165,12 +178,14 @@ class Net::Domain : public Domain_base, struct No_next_hop : Genode::Exception { }; Domain(Configuration &config, - Genode::Xml_node const node, - Genode::Allocator &alloc); + Genode::Xml_node const &node, + Domain_name const &name, + Genode::Allocator &alloc, + Domain_dict &domain_dict); ~Domain(); - void init(Domain_tree &domains); + void init(Domain_dict &domains); void deinit(); @@ -198,6 +213,10 @@ class Net::Domain : public Domain_base, void add_dropped_fragm_ipv4(unsigned long dropped_fragm_ipv4); + bool ready() const; + + void update_ready_state(); + /********* ** log ** @@ -212,12 +231,13 @@ class Net::Domain : public Domain_base, bool verbose_packets() const { return _verbose_packets; } bool verbose_packet_drop() const { return _verbose_packet_drop; } + bool trace_packets() const { return _trace_packets; } bool icmp_echo_server() const { return _icmp_echo_server; } bool use_arp() const { return _use_arp; } Genode::Session_label const &label() const { return _label; } Ipv4_config const &ip_config() const { return *_ip_config; } List &ip_config_dependents() { return _ip_config_dependents; } - Domain_name const &name() const { return _name; } + Domain_name const &name() const { return Domain_dict::Element::name; } Ip_rule_list &ip_rules() { return _ip_rules; } Forward_rule_tree &tcp_forward_rules() { return _tcp_forward_rules; } Forward_rule_tree &udp_forward_rules() { return _udp_forward_rules; } diff --git a/repos/os/src/server/nic_router/forward_rule.cc b/repos/os/src/server/nic_router/forward_rule.cc index 30d8c6592e..24bfc8d751 100644 --- a/repos/os/src/server/nic_router/forward_rule.cc +++ b/repos/os/src/server/nic_router/forward_rule.cc @@ -26,18 +26,6 @@ using namespace Genode; ** Forward_rule ** ******************/ - -Domain &Forward_rule::_find_domain(Domain_tree &domains, - Xml_node const node) -{ - try { - Domain_name const domain_name = node.attribute_value("domain", Domain_name()); - return domains.find_by_name(domain_name); - } - catch (Domain_tree::No_match) { throw Invalid(); } -} - - void Forward_rule::print(Output &output) const { Genode::print(output, "port ", _port, " domain ", _domain, " to ip ", @@ -45,41 +33,13 @@ void Forward_rule::print(Output &output) const } -Forward_rule::Forward_rule(Domain_tree &domains, Xml_node const node) +Forward_rule::Forward_rule(Domain_dict &domains, Xml_node const node) : _port { node.attribute_value("port", Port(0)) }, _to_ip { node.attribute_value("to", Ipv4_address()) }, _to_port { node.attribute_value("to_port", Port(0)) }, - _domain { _find_domain(domains, node) } + _domain { domains.deprecated_find_by_domain_attr(node) } { if (_port == Port(0) || !_to_ip.valid() || dynamic_port(_port)) { throw Invalid(); } } - - -Forward_rule const &Forward_rule::find_by_port(Port const port) const -{ - if (port == _port) { - return *this; } - - Forward_rule *const rule = - Avl_node::child(port.value > _port.value); - - if (!rule) { - throw Forward_rule_tree::No_match(); } - - return rule->find_by_port(port); -} - - -/*********************** - ** Forward_rule_tree ** - ***********************/ - -Forward_rule const &Forward_rule_tree::find_by_port(Port const port) const -{ - if (!first()) { - throw No_match(); } - - return first()->find_by_port(port); -} diff --git a/repos/os/src/server/nic_router/forward_rule.h b/repos/os/src/server/nic_router/forward_rule.h index c9b1a6477b..fde85bdb19 100644 --- a/repos/os/src/server/nic_router/forward_rule.h +++ b/repos/os/src/server/nic_router/forward_rule.h @@ -27,7 +27,7 @@ namespace Genode { class Xml_node; } namespace Net { class Domain; - class Domain_tree; + class Domain_dict; class Forward_rule; class Forward_rule_tree; @@ -45,16 +45,38 @@ class Net::Forward_rule : public Genode::Avl_node Port const _to_port; Domain &_domain; - static Domain &_find_domain(Domain_tree &domains, - Genode::Xml_node const node); - public: struct Invalid : Genode::Exception { }; - Forward_rule(Domain_tree &domains, Genode::Xml_node const node); + Forward_rule(Domain_dict &domains, Genode::Xml_node const node); - Forward_rule const &find_by_port(Port const port) const; + template + + void find_by_port(Port const port, + HANDLE_MATCH_FN && handle_match, + HANDLE_NO_MATCH_FN && handle_no_match) const + { + if (port.value != _port.value) { + + Forward_rule *const rule_ptr { + Avl_node::child(port.value > _port.value) }; + + if (rule_ptr != nullptr) { + + rule_ptr->find_by_port( + port, handle_match, handle_no_match); + + } else { + + handle_no_match(); + } + } else { + + handle_match(*this); + } + } /********* @@ -84,9 +106,22 @@ class Net::Forward_rule : public Genode::Avl_node struct Net::Forward_rule_tree : Avl_tree { - struct No_match : Genode::Exception { }; + template - Forward_rule const &find_by_port(Port const port) const; + void find_by_port(Port const port, + HANDLE_MATCH_FN && handle_match, + HANDLE_NO_MATCH_FN && handle_no_match) const + { + if (first() != nullptr) { + + first()->find_by_port(port, handle_match, handle_no_match); + + } else { + + handle_no_match(); + } + } }; #endif /* _FORWARD_RULE_H_ */ diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index d609e27c1c..3ba439ee81 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include /* local includes */ @@ -293,28 +294,27 @@ void Interface::_destroy_link(Link &link) } -void Interface::_pass_prot(Ethernet_frame ð, - Size_guard &size_guard, - Ipv4_packet &ip, - L3_protocol const prot, - void *const prot_base, - size_t const prot_size) +void Interface::_pass_prot_to_domain(Domain &domain, + Ethernet_frame ð, + Size_guard &size_guard, + Ipv4_packet &ip, + Internet_checksum_diff const &ip_icd, + L3_protocol const prot, + void *const prot_base, + size_t const prot_size) { - eth.src(_router_mac); - if (!_domain().use_arp()) { - eth.dst(_router_mac); - } - _update_checksum(prot, prot_base, prot_size, ip.src(), ip.dst(), ip.total_length()); - _pass_ip(eth, size_guard, ip); -} + _update_checksum( + prot, prot_base, prot_size, ip.src(), ip.dst(), ip.total_length()); - -void Interface::_pass_ip(Ethernet_frame ð, - Size_guard &size_guard, - Ipv4_packet &ip) -{ - ip.update_checksum(); - send(eth, size_guard); + ip.update_checksum(ip_icd); + domain.interfaces().for_each([&] (Interface &interface) + { + eth.src(interface._router_mac); + if (!domain.use_arp()) { + eth.dst(interface._router_mac); + } + interface.send(eth, size_guard); + }); } @@ -341,7 +341,7 @@ Interface::_transport_rules(Domain &local_domain, L3_protocol const prot) const void Interface::_attach_to_domain_raw(Domain &domain) { _domain = domain; - _policy.interface_ready(); + _refetch_domain_ready_state(); _interfaces.remove(this); domain.attach_interface(*this); } @@ -353,7 +353,7 @@ void Interface::_detach_from_domain_raw() domain.detach_interface(*this); _interfaces.insert(this); _domain = Pointer(); - _policy.interface_unready(); + _refetch_domain_ready_state(); domain.add_dropped_fragm_ipv4(_dropped_fragm_ipv4); domain.tcp_stats().dissolve_interface(_tcp_stats); @@ -371,7 +371,7 @@ void Interface::_update_domain_object(Domain &new_domain) { old_domain.interface_updates_domain_object(*this); _interfaces.insert(this); _domain = Pointer(); - _policy.interface_unready(); + _refetch_domain_ready_state(); old_domain.add_dropped_fragm_ipv4(_dropped_fragm_ipv4); old_domain.tcp_stats().dissolve_interface(_tcp_stats); @@ -382,7 +382,7 @@ void Interface::_update_domain_object(Domain &new_domain) { /* attach raw */ _domain = new_domain; - _policy.interface_ready(); + _refetch_domain_ready_state(); _interfaces.remove(this); new_domain.attach_interface(*this); } @@ -390,19 +390,20 @@ void Interface::_update_domain_object(Domain &new_domain) { void Interface::attach_to_domain() { - try { - Domain &domain = - _config().domains().find_by_name(_policy.determine_domain_name()); + _config().domains().with_element( + _policy.determine_domain_name(), + [&] /* match_fn */ (Domain &domain) + { + _attach_to_domain_raw(domain); - _attach_to_domain_raw(domain); - - /* construct DHCP client if the new domain needs it */ - if (domain.ip_config_dynamic()) { - _dhcp_client.construct(_timer, *this); - } - attach_to_domain_finish(); - } - catch (Domain_tree::No_match) { } + /* construct DHCP client if the new domain needs it */ + if (domain.ip_config_dynamic()) { + _dhcp_client.construct(_timer, *this); + } + attach_to_domain_finish(); + }, + [&] /* no_match_fn */ () { } + ); } @@ -455,18 +456,26 @@ void Interface::detach_from_ip_config(Domain &domain) } -void Interface::detach_from_remote_ip_config() +void Interface::handle_domain_ready_state(bool state) { - /* only the DNS server address of the local DHCP server can be remote */ - _policy.interface_unready(); - + _policy.handle_domain_ready_state(state); } -void Interface::attach_to_remote_ip_config() +void Interface::_refetch_domain_ready_state() { - /* only the DNS server address of the local DHCP server can be remote */ - _policy.interface_ready(); + if (_domain.valid()) { + handle_domain_ready_state(_domain().ready()); + } else { + handle_domain_ready_state(false); + } +} + + +void Interface::_reset_and_refetch_domain_ready_state() +{ + _policy.handle_domain_ready_state(false); + _refetch_domain_ready_state(); } @@ -561,50 +570,62 @@ void Interface::_adapt_eth(Ethernet_frame ð, if (remote_domain.use_arp()) { Ipv4_address const &hop_ip = remote_domain.next_hop(dst_ip); - try { eth.dst(remote_domain.arp_cache().find_by_ip(hop_ip).mac()); } - catch (Arp_cache::No_match) { - remote_domain.interfaces().for_each([&] (Interface &interface) { - interface._broadcast_arp_request(remote_ip_cfg.interface().address, - hop_ip); - }); - try { new (_alloc) Arp_waiter { *this, remote_domain, hop_ip, pkt }; } - catch (Out_of_ram) { throw Free_resources_and_retry_handle_eth(); } - catch (Out_of_caps) { throw Free_resources_and_retry_handle_eth(); } - throw Packet_postponed(); - } - + remote_domain.arp_cache().find_by_ip( + hop_ip, + [&] /* handle_match */ (Arp_cache_entry const &entry) + { + eth.dst(entry.mac()); + }, + [&] /* handle_no_match */ () + { + remote_domain.interfaces().for_each([&] (Interface &interface) + { + interface._broadcast_arp_request( + remote_ip_cfg.interface().address, hop_ip); + }); + try { new (_alloc) Arp_waiter { *this, remote_domain, hop_ip, pkt }; } + catch (Out_of_ram) { throw Free_resources_and_retry_handle_eth(); } + catch (Out_of_caps) { throw Free_resources_and_retry_handle_eth(); } + throw Packet_postponed(); + } + ); } } -void Interface::_nat_link_and_pass(Ethernet_frame ð, - Size_guard &size_guard, - Ipv4_packet &ip, - L3_protocol const prot, - void *const prot_base, - size_t const prot_size, - Link_side_id const &local_id, - Domain &local_domain, - Domain &remote_domain) +void Interface::_nat_link_and_pass(Ethernet_frame ð, + Size_guard &size_guard, + Ipv4_packet &ip, + Internet_checksum_diff &ip_icd, + L3_protocol const prot, + void *const prot_base, + size_t const prot_size, + Link_side_id const &local_id, + Domain &local_domain, + Domain &remote_domain) { try { Pointer remote_port_alloc; - try { - Nat_rule &nat = remote_domain.nat_rules().find_by_domain(local_domain); - if(_config().verbose()) { - log("[", local_domain, "] using NAT rule: ", nat); } + remote_domain.nat_rules().find_by_domain( + local_domain, + [&] /* handle_match */ (Nat_rule &nat) + { + if(_config().verbose()) { + log("[", local_domain, "] using NAT rule: ", nat); } - _src_port(prot, prot_base, nat.port_alloc(prot).alloc()); - ip.src(remote_domain.ip_config().interface().address); - remote_port_alloc = nat.port_alloc(prot); - } - catch (Nat_rule_tree::No_match) { } + _src_port(prot, prot_base, nat.port_alloc(prot).alloc()); + ip.src(remote_domain.ip_config().interface().address, ip_icd); + remote_port_alloc = nat.port_alloc(prot); + }, + [&] /* no_match */ () { } + ); Link_side_id const remote_id = { ip.dst(), _dst_port(prot, prot_base), ip.src(), _src_port(prot, prot_base) }; _new_link(prot, local_id, remote_port_alloc, remote_domain, remote_id); - remote_domain.interfaces().for_each([&] (Interface &interface) { - interface._pass_prot(eth, size_guard, ip, prot, prot_base, prot_size); - }); + _pass_prot_to_domain( + remote_domain, eth, size_guard, ip, ip_icd, prot, prot_base, + prot_size); + } catch (Port_allocator_guard::Out_of_indices) { switch (prot) { case L3_protocol::TCP: _tcp_stats.refused_for_ports++; break; @@ -673,11 +694,18 @@ void Interface::_send_dhcp_reply(Dhcp_server const &dhcp_srv, dhcp_opts.append_option(local_intf.subnet_mask()); dhcp_opts.append_option(local_intf.address); - dhcp_opts.append_dns_server([&] (Dhcp_options::Dns_server_data &data) { - dhcp_srv.for_each_dns_server_ip([&] (Ipv4_address const &addr) { - data.append_address(addr); - }); - }); + if (not dhcp_srv.dns_servers_empty()) { + + dhcp_opts.append_dns_server( + [&] (Dhcp_options::Dns_server_data &data) + { + dhcp_srv.for_each_dns_server_ip( + [&] (Ipv4_address const &addr) + { + data.append_address(addr); + }); + }); + } dhcp_srv.dns_domain_name().with_string( [&] (Dns_domain_name::String const &str) { @@ -730,9 +758,10 @@ void Interface::_new_dhcp_allocation(Ethernet_frame ð, } -void Interface::_handle_dhcp_request(Ethernet_frame ð, - Dhcp_packet &dhcp, - Domain &local_domain) +void Interface::_handle_dhcp_request(Ethernet_frame ð, + Dhcp_packet &dhcp, + Domain &local_domain, + Ipv4_address_prefix const &local_intf) { try { /* try to get the DHCP server config of this interface */ @@ -747,9 +776,6 @@ void Interface::_handle_dhcp_request(Ethernet_frame ð, Dhcp_allocation &allocation = _dhcp_allocations.find_by_mac(dhcp.client_mac()); - Ipv4_address_prefix const &local_intf = - local_domain.ip_config().interface(); - switch (msg_type) { case Dhcp_packet::Message_type::DISCOVER: @@ -832,7 +858,14 @@ void Interface::_handle_dhcp_request(Ethernet_frame ð, _new_dhcp_allocation(eth, dhcp, dhcp_srv, local_domain); return; - case Dhcp_packet::Message_type::REQUEST: throw Drop_packet("DHCP REQUEST from client without offered/acked IP"); + case Dhcp_packet::Message_type::REQUEST: + + _send_dhcp_reply(dhcp_srv, eth.src(), dhcp.client_mac(), + Ipv4_address { }, + Dhcp_packet::Message_type::NAK, + dhcp.xid(), local_intf); + return; + case Dhcp_packet::Message_type::DECLINE: throw Drop_packet("DHCP DECLINE from client without offered/acked IP"); case Dhcp_packet::Message_type::RELEASE: throw Drop_packet("DHCP RELEASE from client without offered/acked IP"); case Dhcp_packet::Message_type::NAK: throw Drop_packet("DHCP NAK from client"); @@ -926,6 +959,7 @@ void Interface::handle_interface_link_state() throw Keep_ip_config(); } }); domain_.discard_ip_config(); + domain_.arp_cache().destroy_all_entries(); } } catch (Pointer::Invalid) { } @@ -958,9 +992,13 @@ void Interface::_send_icmp_echo_reply(Ethernet_frame ð, icmp.type(Icmp_packet::Type::ECHO_REPLY); icmp.code(Icmp_packet::Code::ECHO_REPLY); - /* update checksums and send */ + /* + * Update checksums and send + * + * Skip updating the IPv4 checksum because we have only swapped SRC and + * DST and these changes cancel each other out in checksum calculation. + */ icmp.update_checksum(icmp_sz - sizeof(Icmp_packet)); - ip.update_checksum(); send(eth, size_guard); } @@ -968,6 +1006,7 @@ void Interface::_send_icmp_echo_reply(Ethernet_frame ð, void Interface::_handle_icmp_query(Ethernet_frame ð, Size_guard &size_guard, Ipv4_packet &ip, + Internet_checksum_diff &ip_icd, Packet_descriptor const &pkt, L3_protocol prot, void *prot_base, @@ -978,46 +1017,58 @@ void Interface::_handle_icmp_query(Ethernet_frame ð, ip.dst(), _dst_port(prot, prot_base) }; /* try to route via existing ICMP links */ - try { - Link_side const &local_side = local_domain.links(prot).find_by_id(local_id); - Link &link = local_side.link(); - bool const client = local_side.is_client(); - Link_side &remote_side = client ? link.server() : link.client(); - Domain &remote_domain = remote_side.domain(); - if (_config().verbose()) { - log("[", local_domain, "] using ", l3_protocol_name(prot), - " link: ", link); - } - _adapt_eth(eth, remote_side.src_ip(), pkt, remote_domain); - ip.src(remote_side.dst_ip()); - ip.dst(remote_side.src_ip()); - _src_port(prot, prot_base, remote_side.dst_port()); - _dst_port(prot, prot_base, remote_side.src_port()); + bool done { false }; + local_domain.links(prot).find_by_id( + local_id, + [&] /* handle_match */ (Link_side const &local_side) + { + Link &link = local_side.link(); + bool const client = local_side.is_client(); + Link_side &remote_side = client ? link.server() : link.client(); + Domain &remote_domain = remote_side.domain(); + if (_config().verbose()) { + log("[", local_domain, "] using ", l3_protocol_name(prot), + " link: ", link); + } + _adapt_eth(eth, remote_side.src_ip(), pkt, remote_domain); + ip.src(remote_side.dst_ip(), ip_icd); + ip.dst(remote_side.src_ip(), ip_icd); + _src_port(prot, prot_base, remote_side.dst_port()); + _dst_port(prot, prot_base, remote_side.src_port()); + _pass_prot_to_domain( + remote_domain, eth, size_guard, ip, ip_icd, prot, + prot_base, prot_size); - remote_domain.interfaces().for_each([&] (Interface &interface) { - interface._pass_prot(eth, size_guard, ip, prot, prot_base, prot_size); - }); - _link_packet(prot, prot_base, link, client); + _link_packet(prot, prot_base, link, client); + done = true; + }, + [&] /* handle_no_match */ () { } + ); + if (done) { return; } - catch (Link_side_tree::No_match) { } /* try to route via ICMP rules */ - try { - Ip_rule const &rule = - local_domain.icmp_rules().longest_prefix_match(ip.dst()); + local_domain.icmp_rules().find_longest_prefix_match( + ip.dst(), + [&] /* handle_match */ (Ip_rule const &rule) + { + if(_config().verbose()) { + log("[", local_domain, "] using ICMP rule: ", rule); } - if(_config().verbose()) { - log("[", local_domain, "] using ICMP rule: ", rule); } - - Domain &remote_domain = rule.domain(); - _adapt_eth(eth, local_id.dst_ip, pkt, remote_domain); - _nat_link_and_pass(eth, size_guard, ip, prot, prot_base, prot_size, - local_id, local_domain, remote_domain); + Domain &remote_domain = rule.domain(); + _adapt_eth(eth, local_id.dst_ip, pkt, remote_domain); + _nat_link_and_pass(eth, size_guard, ip, ip_icd, prot, prot_base, + prot_size, local_id, local_domain, + remote_domain); + done = true; + }, + [&] /* handle_no_match */ () { } + ); + if (done) { return; } - catch (Ip_rule_list::No_match) { } throw Bad_transport_protocol(); } @@ -1026,13 +1077,16 @@ void Interface::_handle_icmp_query(Ethernet_frame ð, void Interface::_handle_icmp_error(Ethernet_frame ð, Size_guard &size_guard, Ipv4_packet &ip, + Internet_checksum_diff &ip_icd, Packet_descriptor const &pkt, Domain &local_domain, Icmp_packet &icmp, size_t icmp_sz) { + Ipv4_packet &embed_ip { icmp.data(size_guard) }; + Internet_checksum_diff embed_ip_icd { }; + /* drop packet if embedded IP checksum invalid */ - Ipv4_packet &embed_ip = icmp.data(size_guard); if (embed_ip.checksum_error()) { throw Drop_packet("bad checksum in IP packet embedded in ICMP error"); } @@ -1041,54 +1095,61 @@ void Interface::_handle_icmp_error(Ethernet_frame ð, void *const embed_prot_base = _prot_base(embed_prot, size_guard, embed_ip); Link_side_id const local_id = { embed_ip.dst(), _dst_port(embed_prot, embed_prot_base), embed_ip.src(), _src_port(embed_prot, embed_prot_base) }; - try { - /* lookup a link state that matches the embedded transport packet */ - Link_side const &local_side = local_domain.links(embed_prot).find_by_id(local_id); - Link &link = local_side.link(); - bool const client = local_side.is_client(); - Link_side &remote_side = client ? link.server() : link.client(); - Domain &remote_domain = remote_side.domain(); - /* print out that the link is used */ - if (_config().verbose()) { - log("[", local_domain, "] using ", l3_protocol_name(embed_prot), - " link: ", link); + /* lookup a link state that matches the embedded transport packet */ + local_domain.links(embed_prot).find_by_id( + local_id, + [&] /* handle_match */ (Link_side const &local_side) + { + Link &link = local_side.link(); + bool const client = local_side.is_client(); + Link_side &remote_side = client ? link.server() : link.client(); + Domain &remote_domain = remote_side.domain(); + + /* print out that the link is used */ + if (_config().verbose()) { + log("[", local_domain, "] using ", + l3_protocol_name(embed_prot), " link: ", link); + } + /* adapt source and destination of Ethernet frame and IP packet */ + _adapt_eth(eth, remote_side.src_ip(), pkt, remote_domain); + if (remote_side.dst_ip() == remote_domain.ip_config().interface().address) { + ip.src(remote_side.dst_ip(), ip_icd); + } + ip.dst(remote_side.src_ip(), ip_icd); + + /* adapt source and destination of embedded IP and transport packet */ + embed_ip.src(remote_side.src_ip(), embed_ip_icd); + embed_ip.dst(remote_side.dst_ip(), embed_ip_icd); + _src_port(embed_prot, embed_prot_base, remote_side.src_port()); + _dst_port(embed_prot, embed_prot_base, remote_side.dst_port()); + + /* update checksum of both IP headers and the ICMP header */ + embed_ip.update_checksum(embed_ip_icd); + icmp.update_checksum(icmp_sz - sizeof(Icmp_packet)); + ip.update_checksum(ip_icd); + + /* send adapted packet to all interfaces of remote domain */ + remote_domain.interfaces().for_each([&] (Interface &interface) { + interface.send(eth, size_guard); + }); + /* refresh link only if the error is not about an ICMP query */ + if (embed_prot != L3_protocol::ICMP) { + _link_packet(embed_prot, embed_prot_base, link, client); } + }, + [&] /* handle_no_match */ () + { + throw Drop_packet("no link that matches packet embedded in " + "ICMP error"); } - /* adapt source and destination of Ethernet frame and IP packet */ - _adapt_eth(eth, remote_side.src_ip(), pkt, remote_domain); - if (remote_side.dst_ip() == remote_domain.ip_config().interface().address) { - ip.src(remote_side.dst_ip()); - } - ip.dst(remote_side.src_ip()); - - /* adapt source and destination of embedded IP and transport packet */ - embed_ip.src(remote_side.src_ip()); - embed_ip.dst(remote_side.dst_ip()); - _src_port(embed_prot, embed_prot_base, remote_side.src_port()); - _dst_port(embed_prot, embed_prot_base, remote_side.dst_port()); - - /* update checksum of both IP headers and the ICMP header */ - embed_ip.update_checksum(); - icmp.update_checksum(icmp_sz - sizeof(Icmp_packet)); - ip.update_checksum(); - - /* send adapted packet to all interfaces of remote domain */ - remote_domain.interfaces().for_each([&] (Interface &interface) { - interface.send(eth, size_guard); - }); - /* refresh link only if the error is not about an ICMP query */ - if (embed_prot != L3_protocol::ICMP) { - _link_packet(embed_prot, embed_prot_base, link, client); } - } - /* drop packet if there is no matching link */ - catch (Link_side_tree::No_match) { - throw Drop_packet("no link that matches packet embedded in ICMP error"); } + ); } void Interface::_handle_icmp(Ethernet_frame ð, Size_guard &size_guard, Ipv4_packet &ip, + Internet_checksum_diff &ip_icd, Packet_descriptor const &pkt, L3_protocol prot, void *prot_base, @@ -1115,8 +1176,8 @@ void Interface::_handle_icmp(Ethernet_frame ð, /* try to act as ICMP router */ switch (icmp.type()) { case Icmp_packet::Type::ECHO_REPLY: - case Icmp_packet::Type::ECHO_REQUEST: _handle_icmp_query(eth, size_guard, ip, pkt, prot, prot_base, prot_size, local_domain); break; - case Icmp_packet::Type::DST_UNREACHABLE: _handle_icmp_error(eth, size_guard, ip, pkt, local_domain, icmp, prot_size); break; + case Icmp_packet::Type::ECHO_REQUEST: _handle_icmp_query(eth, size_guard, ip, ip_icd, pkt, prot, prot_base, prot_size, local_domain); break; + case Icmp_packet::Type::DST_UNREACHABLE: _handle_icmp_error(eth, size_guard, ip, ip_icd, pkt, local_domain, icmp, prot_size); break; default: Drop_packet("unhandled type in ICMP"); } } @@ -1126,8 +1187,10 @@ void Interface::_handle_ip(Ethernet_frame ð, Packet_descriptor const &pkt, Domain &local_domain) { + Ipv4_packet &ip { eth.data(size_guard) }; + Internet_checksum_diff ip_icd { }; + /* drop fragmented IPv4 as it isn't supported */ - Ipv4_packet &ip = eth.data(size_guard); Ipv4_address_prefix const &local_intf = local_domain.ip_config().interface(); if (ip.more_fragments() || ip.fragment_offset() != 0) { @@ -1152,6 +1215,7 @@ void Interface::_handle_ip(Ethernet_frame ð, } /* try to route via transport layer rules */ + bool done { false }; try { L3_protocol const prot = ip.protocol(); size_t const prot_size = size_guard.unconsumed(); @@ -1168,7 +1232,10 @@ void Interface::_handle_ip(Ethernet_frame ð, switch (dhcp.op()) { case Dhcp_packet::REQUEST: - try { _handle_dhcp_request(eth, dhcp, local_domain); } + try { + _handle_dhcp_request( + eth, dhcp, local_domain, local_intf); + } catch (Pointer::Invalid) { throw Drop_packet("DHCP request while DHCP server inactive"); } @@ -1197,8 +1264,8 @@ void Interface::_handle_ip(Ethernet_frame ð, } } else if (prot == L3_protocol::ICMP) { - _handle_icmp(eth, size_guard, ip, pkt, prot, prot_base, prot_size, - local_domain, local_intf); + _handle_icmp(eth, size_guard, ip, ip_icd, pkt, prot, prot_base, + prot_size, local_domain, local_intf); return; } @@ -1206,96 +1273,131 @@ void Interface::_handle_ip(Ethernet_frame ð, ip.dst(), _dst_port(prot, prot_base) }; /* try to route via existing UDP/TCP links */ - try { - Link_side const &local_side = local_domain.links(prot).find_by_id(local_id); - Link &link = local_side.link(); - bool const client = local_side.is_client(); - Link_side &remote_side = client ? link.server() : link.client(); - Domain &remote_domain = remote_side.domain(); - if (_config().verbose()) { - log("[", local_domain, "] using ", l3_protocol_name(prot), - " link: ", link); - } - _adapt_eth(eth, remote_side.src_ip(), pkt, remote_domain); - ip.src(remote_side.dst_ip()); - ip.dst(remote_side.src_ip()); - _src_port(prot, prot_base, remote_side.dst_port()); - _dst_port(prot, prot_base, remote_side.src_port()); + local_domain.links(prot).find_by_id( + local_id, + [&] /* handle_match */ (Link_side const &local_side) + { + Link &link = local_side.link(); + bool const client = local_side.is_client(); + Link_side &remote_side = + client ? link.server() : link.client(); - remote_domain.interfaces().for_each([&] (Interface &interface) { - interface._pass_prot(eth, size_guard, ip, prot, prot_base, prot_size); - }); - _link_packet(prot, prot_base, link, client); + Domain &remote_domain = remote_side.domain(); + if (_config().verbose()) { + log("[", local_domain, "] using ", l3_protocol_name(prot), + " link: ", link); + } + _adapt_eth(eth, remote_side.src_ip(), pkt, remote_domain); + ip.src(remote_side.dst_ip(), ip_icd); + ip.dst(remote_side.src_ip(), ip_icd); + _src_port(prot, prot_base, remote_side.dst_port()); + _dst_port(prot, prot_base, remote_side.src_port()); + _pass_prot_to_domain( + remote_domain, eth, size_guard, ip, ip_icd, prot, + prot_base, prot_size); + + _link_packet(prot, prot_base, link, client); + done = true; + }, + [&] /* handle_no_match */ () { } + ); + if (done) { return; } - catch (Link_side_tree::No_match) { } /* try to route via forward rules */ if (local_id.dst_ip == local_intf.address) { - try { - Forward_rule const &rule = - _forward_rules(local_domain, prot).find_by_port(local_id.dst_port); - if(_config().verbose()) { - log("[", local_domain, "] using forward rule: ", - l3_protocol_name(prot), " ", rule); - } - Domain &remote_domain = rule.domain(); - _adapt_eth(eth, rule.to_ip(), pkt, remote_domain); - ip.dst(rule.to_ip()); - if (!(rule.to_port() == Port(0))) { - _dst_port(prot, prot_base, rule.to_port()); - } - _nat_link_and_pass(eth, size_guard, ip, prot, prot_base, - prot_size, local_id, local_domain, remote_domain); + _forward_rules(local_domain, prot).find_by_port( + local_id.dst_port, + [&] /* handle_match */ (Forward_rule const &rule) + { + if(_config().verbose()) { + log("[", local_domain, "] using forward rule: ", + l3_protocol_name(prot), " ", rule); + } + Domain &remote_domain = rule.domain(); + _adapt_eth(eth, rule.to_ip(), pkt, remote_domain); + ip.dst(rule.to_ip(), ip_icd); + if (!(rule.to_port() == Port(0))) { + _dst_port(prot, prot_base, rule.to_port()); + } + _nat_link_and_pass( + eth, size_guard, ip, ip_icd, prot, prot_base, + prot_size, local_id, local_domain, remote_domain); + + done = true; + }, + [&] /* handle_no_match */ () { } + ); + if (done) { return; } - catch (Forward_rule_tree::No_match) { } } /* try to route via transport and permit rules */ - try { - Transport_rule const &transport_rule = - _transport_rules(local_domain, prot).longest_prefix_match(local_id.dst_ip); + _transport_rules(local_domain, prot).find_best_match( + local_id.dst_ip, + local_id.dst_port, + [&] /* handle_match */ (Transport_rule const &transport_rule, + Permit_rule const &permit_rule) + { + if(_config().verbose()) { + log("[", local_domain, "] using ", + l3_protocol_name(prot), " rule: ", + transport_rule, " ", permit_rule); + } + Domain &remote_domain = permit_rule.domain(); + _adapt_eth(eth, local_id.dst_ip, pkt, remote_domain); + _nat_link_and_pass( + eth, size_guard, ip, ip_icd, prot, prot_base, prot_size, + local_id, local_domain, remote_domain); - Permit_rule const &permit_rule = - transport_rule.permit_rule(local_id.dst_port); - - if(_config().verbose()) { - log("[", local_domain, "] using ", l3_protocol_name(prot), - " rule: ", transport_rule, " ", permit_rule); - } - Domain &remote_domain = permit_rule.domain(); - _adapt_eth(eth, local_id.dst_ip, pkt, remote_domain); - _nat_link_and_pass(eth, size_guard, ip, prot, prot_base, prot_size, - local_id, local_domain, remote_domain); + done = true; + }, + [&] /* handle_no_match */ () { } + ); + if (done) { return; } - catch (Transport_rule_list::No_match) { } - catch (Permit_single_rule_tree::No_match) { } } catch (Interface::Bad_transport_protocol) { } /* try to route via IP rules */ - try { - Ip_rule const &rule = - local_domain.ip_rules().longest_prefix_match(ip.dst()); - - if(_config().verbose()) { - log("[", local_domain, "] using IP rule: ", rule); } - - Domain &remote_domain = rule.domain(); - _adapt_eth(eth, ip.dst(), pkt, remote_domain); - remote_domain.interfaces().for_each([&] (Interface &interface) { - interface._pass_ip(eth, size_guard, ip); - }); + local_domain.ip_rules().find_longest_prefix_match( + ip.dst(), + [&] /* handle_match */ (Ip_rule const &rule) + { + if(_config().verbose()) { + log("[", local_domain, "] using IP rule: ", rule); } + Domain &remote_domain = rule.domain(); + _adapt_eth(eth, ip.dst(), pkt, remote_domain); + remote_domain.interfaces().for_each([&] (Interface &interface) { + interface.send(eth, size_guard); + }); + done = true; + }, + [&] /* handle_no_match */ () { } + ); + if (done) { return; } - catch (Ip_rule_list::No_match) { } - /* give up and drop packet */ - _send_icmp_dst_unreachable(local_intf, eth, ip, - Icmp_packet::Code::DST_NET_UNREACHABLE); + /* + * Give up and drop packet. According to RFC 1812 section 4.3.2.7, an ICMP + * "Destination Unreachable" is sent as response only if the dropped + * packet fullfills certain properties. + * + * FIXME + * + * There are some properties required by the RFC that are not yet checked + * at this point. + */ + if(not ip.dst().is_multicast()) { + + _send_icmp_dst_unreachable(local_intf, eth, ip, + Icmp_packet::Code::DST_NET_UNREACHABLE); + } if (_config().verbose()) { log("[", local_domain, "] unroutable packet"); } } @@ -1332,29 +1434,32 @@ void Interface::_handle_arp_reply(Ethernet_frame ð, Arp_packet &arp, Domain &local_domain) { - try { - /* check wether a matching ARP cache entry already exists */ - local_domain.arp_cache().find_by_ip(arp.src_ip()); - if (_config().verbose()) { - log("[", local_domain, "] ARP entry already exists"); } - } - catch (Arp_cache::No_match) { - - /* by now, no matching ARP cache entry exists, so create one */ - Ipv4_address const ip = arp.src_ip(); - local_domain.arp_cache().new_entry(ip, arp.src_mac()); - - /* continue handling of packets that waited for the entry */ - for (Arp_waiter_list_element *waiter_le = local_domain.foreign_arp_waiters().first(); - waiter_le; ) + local_domain.arp_cache().find_by_ip( + arp.src_ip(), + [&] /* handle_match */ (Arp_cache_entry const &) { - Arp_waiter &waiter = *waiter_le->object(); - waiter_le = waiter_le->next(); - if (ip != waiter.ip()) { continue; } - waiter.src()._continue_handle_eth(local_domain, waiter.packet()); - destroy(waiter.src()._alloc, &waiter); + /* check wether a matching ARP cache entry already exists */ + if (_config().verbose()) { + log("[", local_domain, "] ARP entry already exists"); } + }, + [&] /* handle_no_match */ () + { + /* by now, no matching ARP cache entry exists, so create one */ + Ipv4_address const ip = arp.src_ip(); + local_domain.arp_cache().new_entry(ip, arp.src_mac()); + + /* continue handling of packets that waited for the entry */ + for (Arp_waiter_list_element *waiter_le = local_domain.foreign_arp_waiters().first(); + waiter_le; ) + { + Arp_waiter &waiter = *waiter_le->object(); + waiter_le = waiter_le->next(); + if (ip != waiter.ip()) { continue; } + waiter.src()._continue_handle_eth(local_domain, waiter.packet()); + destroy(waiter.src()._alloc, &waiter); + } } - } + ); Ipv4_address_prefix const &local_intf = local_domain.ip_config().interface(); if (local_intf.prefix_matches(arp.dst_ip()) && arp.dst_ip() != local_intf.address) @@ -1482,13 +1587,15 @@ void Interface::_handle_pkt() void Interface::_handle_pkt_stream_signal() { + _timer.update_cached_time(); + /* * Release all sent packets that were already acknowledged by the counter * side. Doing this first frees packet-stream memory which facilitates * sending new packets in the subsequent steps of this handler. */ while (_source.ack_avail()) { - _source.release_packet(_source.get_acked_packet()); + _source.release_packet(_source.try_get_acked_packet()); } /* @@ -1517,6 +1624,23 @@ void Interface::_handle_pkt_stream_signal() _handle_pkt(); } } + + /* + * Since we use the try_*() variants of the packet-stream API, we + * haven't emitted any packet_avail, ack_avail, ready_to_submit or + * ready_to_ack signal up to now. We've removed packets from our sink's + * submit queue and might have forwarded it to any interface. We may have + * also removed acks from our sink's ack queue. + * + * We therefore wakeup all sources and our sink. Note that the packet-stream + * API takes care of emitting only the signals that are actually needed. + */ + _config().domains().for_each([&] (Domain &domain) { + domain.interfaces().for_each([&] (Interface &interface) { + interface.wakeup_source(); + }); + }); + wakeup_sink(); } @@ -1636,6 +1760,12 @@ void Interface::_handle_eth(void *const eth_base, if (local_domain.verbose_packets()) { log("[", local_domain, "] rcv ", eth); } + if (local_domain.trace_packets()) + Genode::Trace::Ethernet_packet(local_domain.name().string(), + Genode::Trace::Ethernet_packet::Direction::RECV, + eth_base, + size_guard.total_size()); + /* try to handle ethernet frame */ try { _handle_eth(eth, size_guard, pkt, local_domain); } catch (Free_resources_and_retry_handle_eth) { @@ -1737,15 +1867,6 @@ void Interface::send(Ethernet_frame ð, } -void Interface::_send_alloc_pkt(Packet_descriptor &pkt, - void * &pkt_base, - size_t pkt_size) -{ - pkt = _source.alloc_packet(pkt_size); - pkt_base = _source.packet_content(pkt); -} - - void Interface::_send_submit_pkt(Packet_descriptor &pkt, void * &pkt_base, size_t pkt_size) @@ -1760,12 +1881,19 @@ void Interface::_send_submit_pkt(Packet_descriptor &pkt, } catch (Size_guard::Exceeded) { log("[", local_domain, "] snd ?"); } } - _source.submit_packet(pkt); + + if (local_domain.trace_packets()) + Genode::Trace::Ethernet_packet(local_domain.name().string(), + Genode::Trace::Ethernet_packet::Direction::SENT, + pkt_base, + pkt_size); + + _source.try_submit_packet(pkt); } Interface::Interface(Genode::Entrypoint &ep, - Timer::Connection &timer, + Cached_timer &timer, Mac_address const router_mac, Genode::Allocator &alloc, Mac_address const mac, @@ -1787,6 +1915,8 @@ Interface::Interface(Genode::Entrypoint &ep, _interfaces { interfaces } { _interfaces.insert(this); + try { _config().report().handle_interface_link_state(); } + catch (Pointer::Invalid) { } } @@ -1824,14 +1954,28 @@ void Interface::_update_link_check_nat(Link &link, _dismiss_link_log(link, "NAT IP"); throw Dismiss_link(); } - Nat_rule &nat = new_srv_dom.nat_rules().find_by_domain(cln_dom); - Port_allocator_guard &remote_port_alloc = nat.port_alloc(prot); - remote_port_alloc.alloc(link.server().dst_port()); - remote_port_alloc_ptr = remote_port_alloc; - link.handle_config(cln_dom, new_srv_dom, remote_port_alloc_ptr, _config()); - return; + bool done { false }; + new_srv_dom.nat_rules().find_by_domain( + cln_dom, + [&] /* handle_match */ (Nat_rule &nat) + { + Port_allocator_guard &remote_port_alloc = nat.port_alloc(prot); + remote_port_alloc.alloc(link.server().dst_port()); + remote_port_alloc_ptr = remote_port_alloc; + link.handle_config( + cln_dom, new_srv_dom, remote_port_alloc_ptr, _config()); + + done = true; + }, + [&] /* handle_no_match */ () + { + _dismiss_link_log(link, "no NAT rule"); + } + ); + if (done) { + return; + } } - catch (Nat_rule_tree::No_match) { _dismiss_link_log(link, "no NAT rule"); } catch (Port_allocator::Allocation_conflict) { _dismiss_link_log(link, "no NAT-port"); } catch (Port_allocator_guard::Out_of_indices) { _dismiss_link_log(link, "no NAT-port quota"); } throw Dismiss_link(); @@ -1842,59 +1986,68 @@ void Interface::_update_udp_tcp_links(L3_protocol prot, Domain &cln_dom) { links(prot).for_each([&] (Link &link) { + try { /* try to find forward rule that matches the server port */ - Forward_rule const &rule = - _forward_rules(cln_dom, prot). - find_by_port(link.client().dst_port()); - - /* if destination IP of forwarding changed, dismiss link */ - if (rule.to_ip() != link.server().src_ip()) { - _dismiss_link_log(link, "other forward-rule to"); - throw Dismiss_link(); - } - /* - * If destination port of forwarding was set and then was - * modified or unset, dismiss link - */ - if (!(link.server().src_port() == link.client().dst_port())) { - if (!(rule.to_port() == link.server().src_port())) { - _dismiss_link_log(link, "other forward-rule to_port"); - throw Dismiss_link(); - } - } - /* - * If destination port of forwarding was not set and then was - * set, dismiss link - */ - else { - if (!(rule.to_port() == link.server().src_port()) && - !(rule.to_port() == Port(0))) + _forward_rules(cln_dom, prot).find_by_port( + link.client().dst_port(), + [&] /* handle_match */ (Forward_rule const &rule) { - _dismiss_link_log(link, "new forward-rule to_port"); - throw Dismiss_link(); + /* if destination IP of forwarding changed, dismiss link */ + if (rule.to_ip() != link.server().src_ip()) { + _dismiss_link_log(link, "other forward-rule to"); + throw Dismiss_link(); + } + /* + * If destination port of forwarding was set and then was + * modified or unset, dismiss link + */ + if (!(link.server().src_port() == link.client().dst_port())) { + if (!(rule.to_port() == link.server().src_port())) { + _dismiss_link_log(link, "other forward-rule to_port"); + throw Dismiss_link(); + } + } + /* + * If destination port of forwarding was not set and then was + * set, dismiss link + */ + else { + if (!(rule.to_port() == link.server().src_port()) && + !(rule.to_port() == Port(0))) + { + _dismiss_link_log(link, "new forward-rule to_port"); + throw Dismiss_link(); + } + } + _update_link_check_nat(link, rule.domain(), prot, cln_dom); + return; + }, + [&] /* handle_no_match */ () { + try { + /* try to find transport rule that matches the server IP */ + bool done { false }; + _transport_rules(cln_dom, prot).find_best_match( + link.client().dst_ip(), + link.client().dst_port(), + [&] /* handle_match */ (Transport_rule const &, + Permit_rule const &permit_rule) + { + _update_link_check_nat(link, permit_rule.domain(), prot, cln_dom); + done = true; + }, + [&] /* handle_no_match */ () + { + _dismiss_link_log(link, "no matching transport/permit/forward rule"); + } + ); + if (done) { + return; + } + } + catch (Dismiss_link) { } } - } - _update_link_check_nat(link, rule.domain(), prot, cln_dom); - return; - } - catch (Forward_rule_tree::No_match) { - try { - /* try to find transport rule that matches the server IP */ - Transport_rule const &transport_rule = - _transport_rules(cln_dom, prot). - longest_prefix_match(link.client().dst_ip()); - - /* try to find permit rule that matches the server port */ - Permit_rule const &permit_rule = - transport_rule.permit_rule(link.client().dst_port()); - - _update_link_check_nat(link, permit_rule.domain(), prot, cln_dom); - return; - } - catch (Transport_rule_list::No_match) { _dismiss_link_log(link, "no transport/forward rule"); } - catch (Permit_single_rule_tree::No_match) { _dismiss_link_log(link, "no permit rule"); } - catch (Dismiss_link) { } + ); } catch (Dismiss_link) { } _destroy_link(link); @@ -1907,13 +2060,23 @@ void Interface::_update_icmp_links(Domain &cln_dom) L3_protocol const prot = L3_protocol::ICMP; links(prot).for_each([&] (Link &link) { try { - Ip_rule const &rule = cln_dom.icmp_rules(). - longest_prefix_match(link.client().dst_ip()); - - _update_link_check_nat(link, rule.domain(), prot, cln_dom); - return; + bool done { false }; + cln_dom.icmp_rules().find_longest_prefix_match( + link.client().dst_ip(), + [&] /* handle_match */ (Ip_rule const &rule) + { + _update_link_check_nat(link, rule.domain(), prot, cln_dom); + done = true; + }, + [&] /* handle_no_match */ () + { + _dismiss_link_log(link, "no ICMP rule"); + } + ); + if (done) { + return; + } } - catch (Ip_rule_list::No_match) { _dismiss_link_log(link, "no ICMP rule"); } catch (Dismiss_link) { } _destroy_link(link); }); @@ -1967,42 +2130,44 @@ void Interface::_update_dhcp_allocations(Domain &old_domain, } } if (dhcp_clients_outdated) { - _policy.interface_unready(); - _policy.interface_ready(); + _reset_and_refetch_domain_ready_state(); } } void Interface::_update_own_arp_waiters(Domain &domain) { - bool const verbose = _config().verbose(); - _own_arp_waiters.for_each([&] (Arp_waiter_list_element &le) { - Arp_waiter &arp_waiter = *le.object(); - try { - Domain &dst = _config().domains().find_by_name(arp_waiter.dst().name()); - if (dst.ip_config() != arp_waiter.dst().ip_config()) { - if (verbose) { - log("[", domain, "] dismiss ARP waiter: ", arp_waiter, - " (IP config changed)"); + bool const verbose { _config().verbose() }; + _own_arp_waiters.for_each([&] (Arp_waiter_list_element &le) + { + Arp_waiter &arp_waiter { *le.object() }; + bool dismiss_arp_waiter { true }; + _config().domains().with_element( + arp_waiter.dst().name(), + [&] /* match_fn */ (Domain &dst) + { + /* dismiss ARP waiter if IP config of target domain changed */ + if (dst.ip_config() != arp_waiter.dst().ip_config()) { + return; } - throw Dismiss_arp_waiter(); + /* keep ARP waiter */ + arp_waiter.handle_config(dst); + if (verbose) { + log("[", domain, "] update ARP waiter: ", arp_waiter); + } + dismiss_arp_waiter = false; + }, + [&] /* no_match_fn */ () + { + /* dismiss ARP waiter as the target domain disappeared */ } - /* keep ARP waiter */ - arp_waiter.handle_config(dst); + ); + if (dismiss_arp_waiter) { if (verbose) { - log("[", domain, "] update ARP waiter: ", arp_waiter); + log("[", domain, "] dismiss ARP waiter: ", arp_waiter); } - return; + cancel_arp_waiting(*_own_arp_waiters.first()->object()); } - /* dismiss ARP waiter */ - catch (Domain_tree::No_match) { - if (verbose) { - log("[", domain, "] dismiss ARP waiter: ", arp_waiter, - " (domain disappeared)"); - } - } - catch (Dismiss_arp_waiter) { } - cancel_arp_waiting(*_own_arp_waiters.first()->object()); }); } @@ -2026,11 +2191,15 @@ void Interface::handle_config_1(Configuration &config) return; } /* interface stays with its domain, so, try to reuse IP config */ - Domain &new_domain = config.domains().find_by_name(new_domain_name); - new_domain.try_reuse_ip_config(old_domain); - return; + config.domains().with_element( + new_domain_name, + [&] /* match_fn */ (Domain &new_domain) + { + new_domain.try_reuse_ip_config(old_domain); + }, + [&] /* no_match_fn */ () { } + ); } - catch (Domain_tree::No_match) { } catch (Pointer::Invalid) { } } @@ -2042,6 +2211,13 @@ void Interface::_failed_to_send_packet_link() } +void Interface::_failed_to_send_packet_submit() +{ + if (_config().verbose()) { + log("[", _domain(), "] failed to send packet (queue full)"); } +} + + void Interface::_failed_to_send_packet_alloc() { if (_config().verbose()) { @@ -2054,66 +2230,70 @@ void Interface::handle_config_2() Domain_name const &new_domain_name = _policy.determine_domain_name(); try { Domain &old_domain = domain(); - try { - Domain &new_domain = _config().domains().find_by_name(new_domain_name); + _config().domains().with_element( + new_domain_name, + [&] /* match_fn */ (Domain &new_domain) + { + /* if the domains differ, detach completely from the domain */ + if (old_domain.name() != new_domain_name) { - /* if the domains differ, detach completely from the domain */ - if (old_domain.name() != new_domain_name) { + _detach_from_domain(); + _attach_to_domain_raw(new_domain); + /* destruct and construct DHCP client if required */ + if (old_domain.ip_config_dynamic()) { + _dhcp_client.destruct(); + } + if (new_domain.ip_config_dynamic()) { + _dhcp_client.construct(_timer, *this); + } + return; + } + _update_domain_object(new_domain); + + /* destruct or construct DHCP client if IP-config type changes */ + if (old_domain.ip_config_dynamic() && + !new_domain.ip_config_dynamic()) + { + _dhcp_client.destruct(); + } + if (!old_domain.ip_config_dynamic() && + new_domain.ip_config_dynamic()) + { + _dhcp_client.construct(_timer, *this); + } + + /* remember that the interface stays attached to the same domain */ + _update_domain.construct(old_domain, new_domain); + }, + [&] /* no_match_fn */ () + { + /* the interface no longer has a domain */ _detach_from_domain(); - _attach_to_domain_raw(new_domain); - /* destruct and construct DHCP client if required */ + /* destruct DHCP client if it was constructed */ if (old_domain.ip_config_dynamic()) { _dhcp_client.destruct(); } - if (new_domain.ip_config_dynamic()) { - _dhcp_client.construct(_timer, *this); - } - return; } - _update_domain_object(new_domain); - - /* destruct or construct DHCP client if IP-config type changes */ - if (old_domain.ip_config_dynamic() && - !new_domain.ip_config_dynamic()) - { - _dhcp_client.destruct(); - } - if (!old_domain.ip_config_dynamic() && - new_domain.ip_config_dynamic()) - { - _dhcp_client.construct(_timer, *this); - } - - /* remember that the interface stays attached to the same domain */ - _update_domain.construct(old_domain, new_domain); - return; - } - catch (Domain_tree::No_match) { - - /* the interface no longer has a domain */ - _detach_from_domain(); - - /* destruct DHCP client if it was constructed */ - if (old_domain.ip_config_dynamic()) { - _dhcp_client.destruct(); - } - } + ); } catch (Pointer::Invalid) { /* the interface had no domain but now it may get one */ - try { - Domain &new_domain = _config().domains().find_by_name(new_domain_name); - _attach_to_domain_raw(new_domain); + _config().domains().with_element( + new_domain_name, + [&] /* match_fn */ (Domain &new_domain) + { + _attach_to_domain_raw(new_domain); - /* construct DHCP client if the new domain needs it */ - if (new_domain.ip_config_dynamic()) { - _dhcp_client.construct(_timer, *this); - } - } - catch (Domain_tree::No_match) { } + /* construct DHCP client if the new domain needs it */ + if (new_domain.ip_config_dynamic()) { + _dhcp_client.construct(_timer, *this); + } + }, + [&] /* no_match_fn */ () { } + ); } } @@ -2160,14 +2340,13 @@ void Interface::handle_config_3() void Interface::_ack_packet(Packet_descriptor const &pkt) { - if (!_sink.ready_to_ack()) { + if (!_sink.try_ack_packet(pkt)) { if (_config().verbose()) { log("[", _domain(), "] leak packet (sink not ready to " "acknowledge)"); } return; } - _sink.acknowledge_packet(pkt); } @@ -2189,6 +2368,8 @@ void Interface::cancel_arp_waiting(Arp_waiter &waiter) Interface::~Interface() { + try { _config().report().handle_interface_link_state(); } + catch (Pointer::Invalid) { } _detach_from_domain(); _interfaces.remove(this); } diff --git a/repos/os/src/server/nic_router/interface.h b/repos/os/src/server/nic_router/interface.h index 6ac3caf146..d55f9af618 100644 --- a/repos/os/src/server/nic_router/interface.h +++ b/repos/os/src/server/nic_router/interface.h @@ -24,7 +24,6 @@ #include /* Genode includes */ -#include #include #include @@ -32,10 +31,22 @@ namespace Genode { class Xml_generator; } namespace Net { - using Packet_descriptor = ::Nic::Packet_descriptor; - using Packet_stream_sink = ::Nic::Packet_stream_sink< ::Nic::Session::Policy>; - using Packet_stream_source = ::Nic::Packet_stream_source< ::Nic::Session::Policy>; - using Domain_name = Genode::String<160>; + enum { PKT_STREAM_QUEUE_SIZE = 1024 }; + + /* + * In order to be compliant to both the Uplink and the Nic packet stream + * types, we use the more base types from the Genode namespace here and + * combine them with the same parameters as in the Uplink and Nic + * namespaces. I.e., we assume the Uplink and Nic packet stream types to + * be factually the same although they are logically independent from each + * other. + */ + using Packet_descriptor = Genode::Packet_descriptor; + using Packet_stream_policy = Genode::Packet_stream_policy; + using Packet_stream_sink = Genode::Packet_stream_sink; + using Packet_stream_source = Genode::Packet_stream_source; + + using Domain_name = Genode::String<160>; class Ipv4_config; class Forward_rule_tree; class Transport_rule_list; @@ -92,9 +103,7 @@ struct Net::Interface_policy virtual Genode::Session_label const &label() const = 0; - virtual void interface_ready() = 0; - - virtual void interface_unready() = 0; + virtual void handle_domain_ready_state(bool) = 0; virtual bool interface_link_state() const = 0; @@ -140,7 +149,7 @@ class Net::Interface : private Interface_list::Element Mac_address const _mac; Reference _config; Interface_policy &_policy; - Timer::Connection &_timer; + Cached_timer &_timer; Genode::Allocator &_alloc; Pointer _domain { }; Arp_waiter_list _own_arp_waiters { }; @@ -218,9 +227,10 @@ class Net::Interface : private Interface_list::Element void _send_arp_reply(Ethernet_frame &request_eth, Arp_packet &request_arp); - void _handle_dhcp_request(Ethernet_frame ð, - Dhcp_packet &dhcp, - Domain &local_domain); + void _handle_dhcp_request(Ethernet_frame ð, + Dhcp_packet &dhcp, + Domain &local_domain, + Ipv4_address_prefix const &local_intf); void _handle_ip(Ethernet_frame ð, Size_guard &size_guard, @@ -230,6 +240,7 @@ class Net::Interface : private Interface_list::Element void _handle_icmp_query(Ethernet_frame ð, Size_guard &size_guard, Ipv4_packet &ip, + Internet_checksum_diff &ip_icd, Packet_descriptor const &pkt, L3_protocol prot, void *prot_base, @@ -239,6 +250,7 @@ class Net::Interface : private Interface_list::Element void _handle_icmp_error(Ethernet_frame ð, Size_guard &size_guard, Ipv4_packet &ip, + Internet_checksum_diff &ip_icd, Packet_descriptor const &pkt, Domain &local_domain, Icmp_packet &icmp, @@ -247,6 +259,7 @@ class Net::Interface : private Interface_list::Element void _handle_icmp(Ethernet_frame ð, Size_guard &size_guard, Ipv4_packet &ip, + Internet_checksum_diff &ip_icd, Packet_descriptor const &pkt, L3_protocol prot, void *prot_base, @@ -262,6 +275,7 @@ class Net::Interface : private Interface_list::Element void _nat_link_and_pass(Ethernet_frame ð, Size_guard &size_guard, Ipv4_packet &ip, + Internet_checksum_diff &ip_icd, L3_protocol const prot, void *const prot_base, Genode::size_t const prot_size, @@ -276,16 +290,14 @@ class Net::Interface : private Interface_list::Element Size_guard &size_guard, Domain &local_domain); - void _pass_prot(Ethernet_frame ð, - Size_guard &size_guard, - Ipv4_packet &ip, - L3_protocol const prot, - void *const prot_base, - Genode::size_t const prot_size); - - void _pass_ip(Ethernet_frame ð, - Size_guard &size_guard, - Ipv4_packet &ip); + void _pass_prot_to_domain(Domain &domain, + Ethernet_frame ð, + Size_guard &size_guard, + Ipv4_packet &ip, + Internet_checksum_diff const &ip_icd, + L3_protocol const prot, + void *const prot_base, + Genode::size_t const prot_size); void _handle_pkt(); @@ -305,10 +317,6 @@ class Net::Interface : private Interface_list::Element void _ack_packet(Packet_descriptor const &pkt); - void _send_alloc_pkt(Genode::Packet_descriptor &pkt, - void * &pkt_base, - Genode::size_t pkt_size); - void _send_submit_pkt(Genode::Packet_descriptor &pkt, void * &pkt_base, Genode::size_t pkt_size); @@ -345,6 +353,8 @@ class Net::Interface : private Interface_list::Element void _failed_to_send_packet_link(); + void _failed_to_send_packet_submit(); + void _failed_to_send_packet_alloc(); void _send_icmp_dst_unreachable(Ipv4_address_prefix const &local_intf, @@ -356,6 +366,10 @@ class Net::Interface : private Interface_list::Element void _handle_pkt_stream_signal(); + void _reset_and_refetch_domain_ready_state(); + + void _refetch_domain_ready_state(); + public: struct Free_resources_and_retry_handle_eth : Genode::Exception { L3_protocol prot; Free_resources_and_retry_handle_eth(L3_protocol prot = (L3_protocol)0) : prot(prot) { } }; @@ -373,7 +387,7 @@ class Net::Interface : private Interface_list::Element }; Interface(Genode::Entrypoint &ep, - Timer::Connection &timer, + Cached_timer &timer, Mac_address const router_mac, Genode::Allocator &alloc, Mac_address const mac, @@ -394,18 +408,23 @@ class Net::Interface : private Interface_list::Element _failed_to_send_packet_link(); return; } - try { - Packet_descriptor pkt; - void *pkt_base; - - _send_alloc_pkt(pkt, pkt_base, pkt_size); - Size_guard size_guard(pkt_size); - write_to_pkt(pkt_base, size_guard); - _send_submit_pkt(pkt, pkt_base, pkt_size); - } - catch (Packet_stream_source::Packet_alloc_failed) { - _failed_to_send_packet_alloc(); + if (!_source.ready_to_submit()) { + _failed_to_send_packet_submit(); + return; } + _source.alloc_packet_attempt(pkt_size).with_result( + [&] (Packet_descriptor pkt) + { + void *pkt_base { _source.packet_content(pkt) }; + Size_guard size_guard(pkt_size); + write_to_pkt(pkt_base, size_guard); + _send_submit_pkt(pkt, pkt_base, pkt_size); + }, + [&] (Packet_stream_source::Alloc_packet_error) + { + _failed_to_send_packet_alloc(); + } + ); } void send(Ethernet_frame ð, @@ -440,6 +459,8 @@ class Net::Interface : private Interface_list::Element void report(Genode::Xml_generator &xml); + void handle_domain_ready_state(bool state); + /*************** ** Accessors ** @@ -456,6 +477,8 @@ class Net::Interface : private Interface_list::Element Interface_link_stats &icmp_stats() { return _icmp_stats; } Interface_object_stats &arp_stats() { return _arp_stats; } Interface_object_stats &dhcp_stats() { return _dhcp_stats; } + void wakeup_source() { _source.wakeup(); } + void wakeup_sink() { _sink.wakeup(); } }; #endif /* _INTERFACE_H_ */ diff --git a/repos/os/src/server/nic_router/ip_rule.cc b/repos/os/src/server/nic_router/ip_rule.cc index dc39199a67..b808afee32 100644 --- a/repos/os/src/server/nic_router/ip_rule.cc +++ b/repos/os/src/server/nic_router/ip_rule.cc @@ -19,19 +19,8 @@ using namespace Net; using namespace Genode; -Domain &Ip_rule::_find_domain(Domain_tree &domains, - Xml_node const node) -{ - try { - return domains.find_by_name( - node.attribute_value("domain", Domain_name())); - } - catch (Domain_tree::No_match) { throw Invalid(); } -} - - -Ip_rule::Ip_rule(Domain_tree &domains, Xml_node const node) +Ip_rule::Ip_rule(Domain_dict &domains, Xml_node const node) : - Direct_rule(node), - _domain(_find_domain(domains, node)) + Direct_rule { node }, + _domain { domains.deprecated_find_by_domain_attr(node) } { } diff --git a/repos/os/src/server/nic_router/ip_rule.h b/repos/os/src/server/nic_router/ip_rule.h index ca8de1886d..8340231155 100644 --- a/repos/os/src/server/nic_router/ip_rule.h +++ b/repos/os/src/server/nic_router/ip_rule.h @@ -20,7 +20,7 @@ namespace Net { class Domain; - class Domain_tree; + class Domain_dict; class Ip_rule; struct Ip_rule_list : Direct_rule_list { }; @@ -33,12 +33,9 @@ class Net::Ip_rule : public Direct_rule Domain &_domain; - static Domain &_find_domain(Domain_tree &domains, - Genode::Xml_node const node); - public: - Ip_rule(Domain_tree &domains, Genode::Xml_node const node); + Ip_rule(Domain_dict &domains, Genode::Xml_node const node); /*************** diff --git a/repos/os/src/server/nic_router/ipv4_config.cc b/repos/os/src/server/nic_router/ipv4_config.cc index 22ef3ebf8e..8234e3ebff 100644 --- a/repos/os/src/server/nic_router/ipv4_config.cc +++ b/repos/os/src/server/nic_router/ipv4_config.cc @@ -48,8 +48,14 @@ Ipv4_config::Ipv4_config(Ipv4_config const &ip_config, _gateway { ip_config._gateway } { ip_config.for_each_dns_server([&] (Dns_server const &dns_server) { - _dns_servers.insert_as_tail( - *new (alloc) Dns_server(dns_server.ip())); + Dns_server::construct( + alloc, dns_server.ip(), + [&] /* handle_success */ (Dns_server &server) + { + _dns_servers.insert_as_tail(server); + }, + [&] /* handle_failure */ () { } + ); }); _dns_domain_name.set_to(ip_config.dns_domain_name()); } @@ -69,7 +75,14 @@ Ipv4_config::Ipv4_config(Dhcp_packet &dhcp_ack, dhcp_ack.option() }; dns_server.for_each_address([&] (Ipv4_address const &addr) { - _dns_servers.insert_as_tail(*new (alloc) Dns_server(addr)); + Dns_server::construct( + alloc, addr, + [&] /* handle_success */ (Dns_server &server) + { + _dns_servers.insert_as_tail(server); + }, + [&] /* handle_failure */ () { } + ); }); } catch (Dhcp_packet::Option_not_found) { } diff --git a/repos/os/src/server/nic_router/ipv4_config.h b/repos/os/src/server/nic_router/ipv4_config.h index af9602a744..a505b11356 100644 --- a/repos/os/src/server/nic_router/ipv4_config.h +++ b/repos/os/src/server/nic_router/ipv4_config.h @@ -91,11 +91,12 @@ class Net::Ipv4_config ** Accessors ** ***************/ - bool valid() const { return _valid; } - Ipv4_address_prefix const &interface() const { return _interface; } - Ipv4_address const &gateway() const { return _gateway; } - bool gateway_valid() const { return _gateway_valid; } - Dns_domain_name const &dns_domain_name() const { return _dns_domain_name; } + bool valid() const { return _valid; } + Ipv4_address_prefix const &interface() const { return _interface; } + Ipv4_address const &gateway() const { return _gateway; } + bool gateway_valid() const { return _gateway_valid; } + Dns_domain_name const &dns_domain_name() const { return _dns_domain_name; } + bool dns_servers_empty() const { return _dns_servers.empty(); } }; #endif /* _IPV4_CONFIG_H_ */ diff --git a/repos/os/src/server/nic_router/lazy_one_shot_timeout.h b/repos/os/src/server/nic_router/lazy_one_shot_timeout.h new file mode 100644 index 0000000000..16ebed173e --- /dev/null +++ b/repos/os/src/server/nic_router/lazy_one_shot_timeout.h @@ -0,0 +1,156 @@ +/* + * \brief A wrapper for Timer::One_shot_timeout with lazy re-scheduling + * \author Johannes Schlatow + * \date 2022-07-01 + * + * NOTE: This implementation is not thread safe and should only be used in + * single-threaded components. + * + * This implementation prevents re-scheduling when a timeout is frequently + * updated with only marginal changes. Timeouts within a certain accuracy + * threshold of the existing timeout will be ignored. Otherwise, earlier + * timeouts will always be re-scheduled whereas later timeouts are never + * applied immediately but only when the scheduled timeout occured. + */ + +/* + * Copyright (C) 2022 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 _LAZY_ONE_SHOT_TIMEOUT_H_ +#define _LAZY_ONE_SHOT_TIMEOUT_H_ + +/* local includes */ +#include + +namespace Net { + + template class Lazy_one_shot_timeout; +} + + +template +class Net::Lazy_one_shot_timeout +: + private Timer::One_shot_timeout> +{ + private: + + using One_shot_timeout = Timer::One_shot_timeout>; + using Microseconds = Genode::Microseconds; + using Duration = Genode::Duration; + using uint64_t = Genode::uint64_t; + using Handler_method = void (HANDLER::*)(Duration); + + Cached_timer &_timer; + HANDLER &_object; + Handler_method const _method; + uint64_t const _tolerance_us; + uint64_t _postponed_deadline_us { 0 }; + + void _handle_timeout(Duration curr_time) + { + _timer.cached_time(curr_time); + + /* + * If the postponed deadline is set and more than tolerance + * microseconds in the future, skip calling the user handler and + * re-schedule with the postponed deadline instead. + */ + if (_postponed_deadline_us > 0) { + + uint64_t const curr_time_us { + curr_time.trunc_to_plain_us().value }; + + if (curr_time_us + _tolerance_us < _postponed_deadline_us) { + + One_shot_timeout::schedule( + Microseconds { _postponed_deadline_us - curr_time_us }); + + _postponed_deadline_us = 0; + return; + } + } + /* + * If not, call the user handler. + */ + (_object.*_method)(curr_time); + } + + public: + + using One_shot_timeout::discard; + using One_shot_timeout::scheduled; + + Lazy_one_shot_timeout(Cached_timer &timer, + HANDLER &object, + Handler_method method, + Microseconds tolerance) + : + One_shot_timeout { timer, *this, + &Lazy_one_shot_timeout::_handle_timeout }, + _timer { timer }, + _object { object }, + _method { method }, + _tolerance_us { tolerance.value } + { } + + /** + * In contrast to the original 'schedule' method, this wrapper evalutes + * whether scheduling must be done immediately, can be postponed to + * '_handle_timeout', or can even be skipped. + * + * Scheduling is done immediately if + * the timeout is not active OR + * new deadline < old deadline - tolerance + * + * Scheduling is postponed to '_handle_timeout' if + * new deadline > old deadline + tolerance + * + * Scheduling is skipped if + * new deadline >= old deadline - tolerance AND + * new deadline <= old deadline + tolerance + */ + void schedule(Microseconds duration) + { + /* remove old postponed deadline */ + _postponed_deadline_us = 0; + + /* no special treatment if timeout is not scheduled */ + if (!scheduled()) { + One_shot_timeout::schedule(duration); + return; + } + uint64_t const curr_time_us { + _timer.cached_time().trunc_to_plain_us().value }; + + uint64_t const new_deadline_us { + duration.value <= ~(uint64_t)0 - curr_time_us ? + curr_time_us + duration.value : ~(uint64_t)0 }; + + uint64_t const old_deadline_us { One_shot_timeout::deadline().value }; + + if (new_deadline_us < old_deadline_us) { + /* + * The new deadline is earlier. If the old deadline is not + * accurate enough, re-schedule. Else, drop the new deadline. + */ + if (new_deadline_us < old_deadline_us - _tolerance_us) + One_shot_timeout::schedule(duration); + + } else { + /* + * The new deadline is later. If the old deadline is not + * accurate enough, remember the new deadline and apply it in + * '_handle_timeout'. Else, drop the new deadline. + */ + if (new_deadline_us > old_deadline_us + _tolerance_us) + _postponed_deadline_us = new_deadline_us; + } + } +}; + +#endif /* _LAZY_ONE_SHOT_TIMEOUT_H_ */ diff --git a/repos/os/src/server/nic_router/link.cc b/repos/os/src/server/nic_router/link.cc index 33636d5546..0d287ceb7e 100644 --- a/repos/os/src/server/nic_router/link.cc +++ b/repos/os/src/server/nic_router/link.cc @@ -33,9 +33,9 @@ constexpr size_t Link_side_id::data_size() } -bool Link_side_id::operator == (Link_side_id const &id) const +bool Link_side_id::operator != (Link_side_id const &id) const { - return memcmp(id.data_base(), data_base(), data_size()) == 0; + return memcmp(id.data_base(), data_base(), data_size()) != 0; } @@ -62,20 +62,6 @@ Link_side::Link_side(Domain &domain, } -Link_side const &Link_side::find_by_id(Link_side_id const &id) const -{ - if (id == _id) { - return *this; } - - bool const side = id > _id; - Link_side *const link_side = Avl_node::child(side); - if (!link_side) { - throw Link_side_tree::No_match(); } - - return link_side->find_by_id(id); -} - - void Link_side::print(Output &output) const { Genode::print(output, "src ", src_ip(), ":", src_port(), @@ -89,20 +75,6 @@ bool Link_side::is_client() const } -/******************** - ** Link_side_tree ** - ********************/ - -Link_side const &Link_side_tree::find_by_id(Link_side_id const &id) const -{ - Link_side *const link_side = first(); - if (!link_side) { - throw No_match(); } - - return link_side->find_by_id(id); -} - - /********** ** Link ** **********/ @@ -118,7 +90,7 @@ Link::Link(Interface &cln_interface, Pointer srv_port_alloc, Domain &srv_domain, Link_side_id const &srv_id, - Timer::Connection &timer, + Cached_timer &timer, Configuration &config, L3_protocol const protocol, Microseconds const dissolve_timeout, @@ -127,7 +99,8 @@ Link::Link(Interface &cln_interface, _config(config), _client_interface(cln_interface), _server_port_alloc(srv_port_alloc), - _dissolve_timeout(timer, *this, &Link::_handle_dissolve_timeout), + _dissolve_timeout(timer, *this, &Link::_handle_dissolve_timeout, + Microseconds { 100 * 1000 }), _dissolve_timeout_us(dissolve_timeout), _protocol(protocol), _client(cln_interface.domain(), cln_id, *this), @@ -228,7 +201,7 @@ Tcp_link::Tcp_link(Interface &cln_interface, Pointer srv_port_alloc, Domain &srv_domain, Link_side_id const &srv_id, - Timer::Connection &timer, + Cached_timer &timer, Configuration &config, L3_protocol const protocol, Interface_link_stats &stats) @@ -309,7 +282,7 @@ Udp_link::Udp_link(Interface &cln_interface, Pointer srv_port_alloc, Domain &srv_domain, Link_side_id const &srv_id, - Timer::Connection &timer, + Cached_timer &timer, Configuration &config, L3_protocol const protocol, Interface_link_stats &stats) @@ -340,7 +313,7 @@ Icmp_link::Icmp_link(Interface &cln_interface, Pointer srv_port_alloc, Domain &srv_domain, Link_side_id const &srv_id, - Timer::Connection &timer, + Cached_timer &timer, Configuration &config, L3_protocol const protocol, Interface_link_stats &stats) diff --git a/repos/os/src/server/nic_router/link.h b/repos/os/src/server/nic_router/link.h index f46d3509cb..ba5f9cb944 100644 --- a/repos/os/src/server/nic_router/link.h +++ b/repos/os/src/server/nic_router/link.h @@ -42,6 +42,7 @@ #include #include #include +#include namespace Net { @@ -78,7 +79,7 @@ struct Net::Link_side_id ** Standard operators ** ************************/ - bool operator == (Link_side_id const &id) const; + bool operator != (Link_side_id const &id) const; bool operator > (Link_side_id const &id) const; } @@ -101,7 +102,33 @@ class Net::Link_side : public Genode::Avl_node Link_side_id const &id, Link &link); - Link_side const &find_by_id(Link_side_id const &id) const; + template + + void find_by_id(Link_side_id const &id, + HANDLE_MATCH_FN && handle_match, + HANDLE_NO_MATCH_FN && handle_no_match) const + { + if (id != _id) { + + Link_side *const link_side_ptr { + Avl_node::child(id > _id) }; + + if (link_side_ptr != nullptr) { + + link_side_ptr->find_by_id( + id, handle_match, handle_no_match); + + } else { + + handle_no_match(); + } + + } else { + + handle_match(*this); + } + } bool is_client() const; @@ -135,9 +162,22 @@ class Net::Link_side : public Genode::Avl_node struct Net::Link_side_tree : Genode::Avl_tree { - struct No_match : Genode::Exception { }; + template - Link_side const &find_by_id(Link_side_id const &id) const; + void find_by_id(Link_side_id const &id, + HANDLE_MATCH_FN && handle_match, + HANDLE_NO_MATCH_FN && handle_no_match) const + { + if (first() != nullptr) { + + first()->find_by_id(id, handle_match, handle_no_match); + + } else { + + handle_no_match(); + } + } }; @@ -148,7 +188,7 @@ class Net::Link : public Link_list::Element Reference _config; Interface &_client_interface; Pointer _server_port_alloc; - Timer::One_shot_timeout _dissolve_timeout; + Lazy_one_shot_timeout _dissolve_timeout; Genode::Microseconds _dissolve_timeout_us; L3_protocol const _protocol; Link_side _client; @@ -170,7 +210,7 @@ class Net::Link : public Link_list::Element Pointer srv_port_alloc, Domain &srv_domain, Link_side_id const &srv_id, - Timer::Connection &timer, + Cached_timer &timer, Configuration &config, L3_protocol const protocol, Genode::Microseconds const dissolve_timeout, @@ -234,7 +274,7 @@ class Net::Tcp_link : public Link Pointer srv_port_alloc, Domain &srv_domain, Link_side_id const &srv_id, - Timer::Connection &timer, + Cached_timer &timer, Configuration &config, L3_protocol const protocol, Interface_link_stats &stats); @@ -252,7 +292,7 @@ struct Net::Udp_link : Link Pointer srv_port_alloc, Domain &srv_domain, Link_side_id const &srv_id, - Timer::Connection &timer, + Cached_timer &timer, Configuration &config, L3_protocol const protocol, Interface_link_stats &stats); @@ -270,7 +310,7 @@ struct Net::Icmp_link : Link Pointer srv_port_alloc, Domain &srv_domain, Link_side_id const &srv_id, - Timer::Connection &timer, + Cached_timer &timer, Configuration &config, L3_protocol const protocol, Interface_link_stats &stats); diff --git a/repos/os/src/server/nic_router/main.cc b/repos/os/src/server/nic_router/main.cc index adc205dc59..179fd75567 100644 --- a/repos/os/src/server/nic_router/main.cc +++ b/repos/os/src/server/nic_router/main.cc @@ -21,6 +21,7 @@ #include #include #include +#include using namespace Net; using namespace Genode; @@ -35,14 +36,17 @@ class Net::Main Genode::Env &_env; Quota _shared_quota { }; Interface_list _interfaces { }; - Timer::Connection _timer { _env }; + Cached_timer _timer { _env }; Genode::Heap _heap { &_env.ram(), &_env.rm() }; + Signal_handler
_report_handler { _env.ep(), *this, &Main::_handle_report }; Genode::Attached_rom_dataspace _config_rom { _env, "config" }; Reference _config { *new (_heap) Configuration { _config_rom.xml(), _heap } }; Signal_handler
_config_handler { _env.ep(), *this, &Main::_handle_config }; Nic_session_root _nic_session_root { _env, _timer, _heap, _config(), _shared_quota, _interfaces }; Uplink_session_root _uplink_session_root { _env, _timer, _heap, _config(), _shared_quota, _interfaces }; + void _handle_report(); + void _handle_config(); template @@ -64,6 +68,14 @@ class Net::Main }; +void Main::_handle_report() +{ + try { _config().report().generate(); } + catch (Pointer::Invalid) { } + +} + + Net::Main::Main(Env &env) : _env(env) { _config_rom.sigh(_config_handler); @@ -75,13 +87,12 @@ Net::Main::Main(Env &env) : _env(env) void Net::Main::_handle_config() { - _config().stop_reporting(); - _config_rom.update(); Configuration &old_config = _config(); Configuration &new_config = *new (_heap) - Configuration(_env, _config_rom.xml(), _heap, _timer, old_config, - _shared_quota, _interfaces); + Configuration { + _env, _config_rom.xml(), _heap, _report_handler, _timer, + old_config, _shared_quota, _interfaces }; _nic_session_root.handle_config(new_config); _uplink_session_root.handle_config(new_config); @@ -91,8 +102,6 @@ void Net::Main::_handle_config() _for_each_interface([&] (Interface &intf) { intf.handle_config_3(); }); destroy(_heap, &old_config); - - _config().start_reporting(); } diff --git a/repos/os/src/server/nic_router/nat_rule.cc b/repos/os/src/server/nic_router/nat_rule.cc index 1839b8ce22..b7a3ff445b 100644 --- a/repos/os/src/server/nic_router/nat_rule.cc +++ b/repos/os/src/server/nic_router/nat_rule.cc @@ -26,61 +26,26 @@ using namespace Net; using namespace Genode; -Domain &Nat_rule::_find_domain(Domain_tree &domains, - Xml_node const node) -{ - try { - return domains.find_by_name( - node.attribute_value("domain", Domain_name())); - } - catch (Domain_tree::No_match) { throw Invalid(); } -} - - bool Nat_rule::higher(Nat_rule *rule) { return (addr_t)&rule->domain() > (addr_t)&_domain; } -Nat_rule::Nat_rule(Domain_tree &domains, +Nat_rule::Nat_rule(Domain_dict &domains, Port_allocator &tcp_port_alloc, Port_allocator &udp_port_alloc, Port_allocator &icmp_port_alloc, Xml_node const node, bool const verbose) : - _domain(_find_domain(domains, node)), - _tcp_port_alloc (tcp_port_alloc, node.attribute_value("tcp-ports", 0UL), verbose), - _udp_port_alloc (udp_port_alloc, node.attribute_value("udp-ports", 0UL), verbose), - _icmp_port_alloc(icmp_port_alloc, node.attribute_value("icmp-ids", 0UL), verbose) + _domain { domains.deprecated_find_by_domain_attr(node) }, + _tcp_port_alloc { tcp_port_alloc, node.attribute_value("tcp-ports", 0U), verbose }, + _udp_port_alloc { udp_port_alloc, node.attribute_value("udp-ports", 0U), verbose }, + _icmp_port_alloc { icmp_port_alloc, node.attribute_value("icmp-ids", 0U), verbose } { } -Nat_rule &Nat_rule::find_by_domain(Domain &domain) -{ - if (&domain == &_domain) { - return *this; } - - bool const side = (addr_t)&domain > (addr_t)&_domain; - Nat_rule *const rule = Avl_node::child(side); - if (!rule) { - throw Nat_rule_tree::No_match(); } - - return rule->find_by_domain(domain); -} - - -Nat_rule &Nat_rule_tree::find_by_domain(Domain &domain) -{ - Nat_rule *const rule = first(); - if (!rule) { - throw No_match(); } - - return rule->find_by_domain(domain); -} - - void Nat_rule::print(Output &output) const { Genode::print(output, "domain ", _domain, diff --git a/repos/os/src/server/nic_router/nat_rule.h b/repos/os/src/server/nic_router/nat_rule.h index 500d444106..be1be378f5 100644 --- a/repos/os/src/server/nic_router/nat_rule.h +++ b/repos/os/src/server/nic_router/nat_rule.h @@ -25,7 +25,7 @@ namespace Net { class Domain; - class Domain_tree; + class Domain_dict; class Port_allocator; class Nat_rule_base; @@ -43,14 +43,11 @@ class Net::Nat_rule : public Genode::Avl_node Port_allocator_guard _udp_port_alloc; Port_allocator_guard _icmp_port_alloc; - static Domain &_find_domain(Domain_tree &domains, - Genode::Xml_node const node); - public: struct Invalid : Genode::Exception { }; - Nat_rule(Domain_tree &domains, + Nat_rule(Domain_dict &domains, Port_allocator &tcp_port_alloc, Port_allocator &udp_port_alloc, Port_allocator &icmp_port_alloc, @@ -59,6 +56,35 @@ class Net::Nat_rule : public Genode::Avl_node Nat_rule &find_by_domain(Domain &domain); + template + + void find_by_domain(Domain &domain, + HANDLE_MATCH_FN && handle_match, + HANDLE_NO_MATCH_FN && handle_no_match) + { + if (&domain != &_domain) { + + Nat_rule *const rule_ptr { + Avl_node::child( + (Genode::addr_t)&domain > (Genode::addr_t)&_domain) }; + + if (rule_ptr != nullptr) { + + rule_ptr->find_by_domain( + domain, handle_match, handle_no_match); + + } else { + + handle_no_match(); + } + + } else { + + handle_match(*this); + } + } + Port_allocator_guard &port_alloc(L3_protocol const prot); @@ -89,9 +115,22 @@ class Net::Nat_rule : public Genode::Avl_node struct Net::Nat_rule_tree : Avl_tree { - struct No_match : Genode::Exception { }; + template - Nat_rule &find_by_domain(Domain &domain); + void find_by_domain(Domain &domain, + HANDLE_MATCH_FN && handle_match, + HANDLE_NO_MATCH_FN && handle_no_match) + { + if (first() != nullptr) { + + first()->find_by_domain(domain, handle_match, handle_no_match); + + } else { + + handle_no_match(); + } + } }; #endif /* _NAT_RULE_H_ */ diff --git a/repos/os/src/server/nic_router/nic_client.cc b/repos/os/src/server/nic_router/nic_client.cc index f3fad8b0fe..e289318cc1 100644 --- a/repos/os/src/server/nic_router/nic_client.cc +++ b/repos/os/src/server/nic_router/nic_client.cc @@ -22,17 +22,6 @@ using namespace Net; using namespace Genode; -/********************* - ** Nic_client_base ** - *********************/ - -Net::Nic_client_base::Nic_client_base(Xml_node const &node) -: - _label { node.attribute_value("label", Session_label::String()) }, - _domain { node.attribute_value("domain", Domain_name()) } -{ } - - /**************** ** Nic_client ** ****************/ @@ -40,47 +29,55 @@ Net::Nic_client_base::Nic_client_base(Xml_node const &node) void Nic_client::_invalid(char const *reason) const { if (_config.verbose()) { - log("[", domain(), "] invalid NIC client: ", *this, " (", reason, ")"); } - + log("[", domain(), "] invalid NIC client: ", label(), + " (", reason, ")"); + } throw Invalid(); } -Net::Nic_client::Nic_client(Xml_node const &node, - Allocator &alloc, - Nic_client_tree &old_nic_clients, - Env &env, - Timer::Connection &timer, - Interface_list &interfaces, - Configuration &config) +Net::Nic_client::Nic_client(Session_label const &label_arg, + Domain_name const &domain_arg, + Allocator &alloc, + Nic_client_dict &old_nic_clients, + Nic_client_dict &new_nic_clients, + Env &env, + Cached_timer &timer, + Interface_list &interfaces, + Configuration &config) : - Nic_client_base { node }, - Avl_string_base { label().string() }, - _alloc { alloc }, - _config { config } + Nic_client_dict::Element { new_nic_clients, label_arg }, + _alloc { alloc }, + _config { config }, + _domain { domain_arg } { - /* if an interface with this label already exists, reuse it */ - try { - Nic_client &old_nic_client = old_nic_clients.find_by_name(label()); - Nic_client_interface &interface = old_nic_client._interface(); - old_nic_client._interface = Pointer(); - interface.domain_name(domain()); - _interface = interface; - } - /* if not, create a new one */ - catch (Nic_client_tree::No_match) { - if (config.verbose()) { - log("[", domain(), "] create NIC client: ", *this); } + old_nic_clients.with_element( + label(), + [&] /* handle_match */ (Nic_client &old_nic_client) + { + /* reuse existing interface */ + Nic_client_interface &interface = old_nic_client._interface(); + old_nic_client._interface = Pointer(); + interface.domain_name(domain()); + _interface = interface; + }, + [&] /* handle_no_match */ () + { + /* create a new interface */ + if (config.verbose()) { + log("[", domain(), "] create NIC client: ", label()); } - try { - _interface = *new (_alloc) - Nic_client_interface { env, timer, alloc, interfaces, config, - domain(), label() }; + try { + _interface = *new (_alloc) + Nic_client_interface { + env, timer, alloc, interfaces, config, domain(), + label() }; + } + catch (Insufficient_ram_quota) { _invalid("NIC session RAM quota"); } + catch (Insufficient_cap_quota) { _invalid("NIC session CAP quota"); } + catch (Service_denied) { _invalid("NIC session denied"); } } - catch (Insufficient_ram_quota) { _invalid("NIC session RAM quota"); } - catch (Insufficient_cap_quota) { _invalid("NIC session CAP quota"); } - catch (Service_denied) { _invalid("NIC session denied"); } - } + ); } @@ -90,7 +87,7 @@ Net::Nic_client::~Nic_client() try { Nic_client_interface &interface = _interface(); if (_config.verbose()) { - log("[", domain(), "] destroy NIC client: ", *this); } + log("[", domain(), "] destroy NIC client: ", label()); } destroy(_alloc, &interface); } @@ -98,15 +95,6 @@ Net::Nic_client::~Nic_client() } -void Net::Nic_client::print(Output &output) const -{ - if (label() == Session_label()) { - Genode::print(output, "?"); } - else { - Genode::print(output, label()); } -} - - /******************************* ** Nic_client_interface_base ** *******************************/ @@ -122,21 +110,15 @@ Net::Nic_client_interface_base:: { } -void Net::Nic_client_interface_base::interface_unready() +void Net::Nic_client_interface_base::handle_domain_ready_state(bool state) { - _interface_ready = false; -}; - - -void Net::Nic_client_interface_base::interface_ready() -{ - _interface_ready = true; -}; + _domain_ready = state; +} bool Net::Nic_client_interface_base::interface_link_state() const { - return _interface_ready && _session_link_state; + return _domain_ready && _session_link_state; } @@ -145,7 +127,7 @@ bool Net::Nic_client_interface_base::interface_link_state() const **************************/ Net::Nic_client_interface::Nic_client_interface(Env &env, - Timer::Connection &timer, + Cached_timer &timer, Genode::Allocator &alloc, Interface_list &interfaces, Configuration &config, @@ -165,6 +147,12 @@ Net::Nic_client_interface::Nic_client_interface(Env &env, rx_channel()->sigh_packet_avail(_interface.pkt_stream_signal_handler()); tx_channel()->sigh_ack_avail (_interface.pkt_stream_signal_handler()); + /* + * We do not install ready_to_submit because submission is only triggered + * by incoming packets (and dropped if the submit queue is full). + * The ack queue should never be full otherwise we'll be leaking packets. + */ + /* initialize link state handling */ Nic::Connection::link_state_sigh(_session_link_state_handler); _session_link_state = Nic::Connection::link_state(); diff --git a/repos/os/src/server/nic_router/nic_client.h b/repos/os/src/server/nic_router/nic_client.h index 06c193eeab..6e7b650315 100644 --- a/repos/os/src/server/nic_router/nic_client.h +++ b/repos/os/src/server/nic_router/nic_client.h @@ -19,60 +19,31 @@ #include /* local includes */ -#include +#include #include #include namespace Net { using Domain_name = Genode::String<160>; - class Nic_client_base; class Nic_client; - class Nic_client_tree; + using Nic_client_dict = Dictionary; class Nic_client_interface_base; class Nic_client_interface; } -class Net::Nic_client_tree -: - public Avl_string_tree -{ }; - - -class Net::Nic_client_base +class Net::Nic_client : private Nic_client_dict::Element { - private: - - Genode::Session_label const _label; - Domain_name const _domain; - - public: - - Nic_client_base(Genode::Xml_node const &node); - - virtual ~Nic_client_base() { } - - - /************** - ** Acessors ** - **************/ - - Genode::Session_label const &label() const { return _label; } - Domain_name const &domain() const { return _domain; } -}; - - -class Net::Nic_client : public Nic_client_base, - private Genode::Avl_string_base -{ - friend class Avl_string_tree; - friend class Genode::List; + friend class Genode::Avl_tree; + friend class Genode::Avl_node; + friend class Genode::Dictionary; private: Genode::Allocator &_alloc; Configuration const &_config; + Domain_name const _domain; Pointer _interface { }; void _invalid(char const *reason) const; @@ -81,22 +52,25 @@ class Net::Nic_client : public Nic_client_base, struct Invalid : Genode::Exception { }; - Nic_client(Genode::Xml_node const &node, - Genode::Allocator &alloc, - Nic_client_tree &old_nic_clients, - Genode::Env &env, - Timer::Connection &timer, - Interface_list &interfaces, - Configuration &config); + Nic_client(Genode::Session_label const &label_arg, + Domain_name const &domain_arg, + Genode::Allocator &alloc, + Nic_client_dict &old_nic_clients, + Nic_client_dict &new_nic_clients, + Genode::Env &env, + Cached_timer &timer, + Interface_list &interfaces, + Configuration &config); ~Nic_client(); - /********* - ** log ** - *********/ + /************** + ** Acessors ** + **************/ - void print(Genode::Output &output) const; + Domain_name const &domain() const { return _domain; } + Genode::Session_label const &label() const { return Nic_client_dict::Element::name; } }; @@ -107,7 +81,7 @@ class Net::Nic_client_interface_base : public Interface_policy Const_reference _domain_name; Genode::Session_label const _label; bool const &_session_link_state; - bool _interface_ready { false }; + bool _domain_ready { false }; /*************************** @@ -117,8 +91,7 @@ class Net::Nic_client_interface_base : public Interface_policy Domain_name determine_domain_name() const override { return _domain_name(); }; void handle_config(Configuration const &) override { } Genode::Session_label const &label() const override { return _label; } - void interface_unready() override; - void interface_ready() override; + void handle_domain_ready_state(bool state) override; bool interface_link_state() const override; public: @@ -160,7 +133,7 @@ class Net::Nic_client_interface : public Nic_client_interface_base, public: Nic_client_interface(Genode::Env &env, - Timer::Connection &timer, + Cached_timer &timer, Genode::Allocator &alloc, Interface_list &interfaces, Configuration &config, diff --git a/repos/os/src/server/nic_router/nic_session_root.cc b/repos/os/src/server/nic_router/nic_session_root.cc index 3efa739f42..1b5e98019d 100644 --- a/repos/os/src/server/nic_router/nic_session_root.cc +++ b/repos/os/src/server/nic_router/nic_session_root.cc @@ -52,7 +52,7 @@ Interface_policy::Interface_policy(Genode::Session_label const &label, _config { config }, _session_env { session_env } { - _session_link_state_transition(UP); + _session_link_state_transition(DOWN); } @@ -86,70 +86,72 @@ Interface_policy::_session_link_state_transition(Transient_link_state tls) } -void Net::Nic_session_component::Interface_policy::interface_unready() +void Net:: +Nic_session_component::Interface_policy::handle_domain_ready_state(bool state) { - switch (_transient_link_state) { - case UP_ACKNOWLEDGED: + if (state) { - _session_link_state_transition(DOWN); - break; + switch (_transient_link_state) { + case DOWN_ACKNOWLEDGED: - case UP: + _session_link_state_transition(UP); + break; - _transient_link_state = UP_DOWN; - break; + case DOWN: - case DOWN_UP: + _transient_link_state = DOWN_UP; + break; - _transient_link_state = DOWN_UP_DOWN; - break; + case UP_DOWN: - case UP_DOWN: + _transient_link_state = UP_DOWN_UP; + break; - break; + case DOWN_UP: - case UP_DOWN_UP: + break; - _transient_link_state = UP_DOWN; - break; + case DOWN_UP_DOWN: - case DOWN_ACKNOWLEDGED: break; - case DOWN: break; - case DOWN_UP_DOWN: break; - } -} + _transient_link_state = DOWN_UP; + break; + case UP_ACKNOWLEDGED: break; + case UP: break; + case UP_DOWN_UP: break; + } -void Net::Nic_session_component::Interface_policy::interface_ready() -{ - switch (_transient_link_state) { - case DOWN_ACKNOWLEDGED: + } else { - _session_link_state_transition(UP); - break; + switch (_transient_link_state) { + case UP_ACKNOWLEDGED: - case DOWN: + _session_link_state_transition(DOWN); + break; - _transient_link_state = DOWN_UP; - break; + case UP: - case UP_DOWN: + _transient_link_state = UP_DOWN; + break; - _transient_link_state = UP_DOWN_UP; - break; + case DOWN_UP: - case DOWN_UP: + _transient_link_state = DOWN_UP_DOWN; + break; - break; + case UP_DOWN: - case DOWN_UP_DOWN: + break; - _transient_link_state = DOWN_UP; - break; + case UP_DOWN_UP: - case UP_ACKNOWLEDGED: break; - case UP: break; - case UP_DOWN_UP: break; + _transient_link_state = UP_DOWN; + break; + + case DOWN_ACKNOWLEDGED: break; + case DOWN: break; + case DOWN_UP_DOWN: break; + } } } @@ -234,7 +236,7 @@ Nic_session_component:: Nic_session_component(Session_env &session_env, size_t const tx_buf_size, size_t const rx_buf_size, - Timer::Connection &timer, + Cached_timer &timer, Mac_address const mac, Mac_address const &router_mac, Session_label const &label, @@ -256,6 +258,12 @@ Nic_session_component(Session_env &session_env, /* install packet stream signal handlers */ _tx.sigh_packet_avail(_interface.pkt_stream_signal_handler()); _rx.sigh_ack_avail (_interface.pkt_stream_signal_handler()); + + /* + * We do not install ready_to_submit because submission is only triggered by + * incoming packets (and dropped if the submit queue is full). + * The ack queue should never be full otherwise we'll be leaking packets. + */ } @@ -277,7 +285,7 @@ Nic_session_component::link_state_sigh(Signal_context_capability sigh) **********************/ Net::Nic_session_root::Nic_session_root(Env &env, - Timer::Connection &timer, + Cached_timer &timer, Allocator &alloc, Configuration &config, Quota &shared_quota, diff --git a/repos/os/src/server/nic_router/nic_session_root.h b/repos/os/src/server/nic_router/nic_session_root.h index 31926d6162..81d45c5b90 100644 --- a/repos/os/src/server/nic_router/nic_session_root.h +++ b/repos/os/src/server/nic_router/nic_session_root.h @@ -118,8 +118,7 @@ class Net::Nic_session_component : private Nic_session_component_base, void handle_config(Configuration const &config) override { _config = config; } Genode::Session_label const &label() const override { return _label; } void report(Genode::Xml_generator &xml) const override { _session_env.report(xml); }; - void interface_unready() override; - void interface_ready() override; + void handle_domain_ready_state(bool state) override; bool interface_link_state() const override; }; @@ -132,7 +131,7 @@ class Net::Nic_session_component : private Nic_session_component_base, Nic_session_component(Genode::Session_env &session_env, Genode::size_t const tx_buf_size, Genode::size_t const rx_buf_size, - Timer::Connection &timer, + Cached_timer &timer, Mac_address const mac, Mac_address const &router_mac, Genode::Session_label const &label, @@ -169,7 +168,7 @@ class Net::Nic_session_root enum { MAC_ALLOC_BASE = 0x02 }; Genode::Env &_env; - Timer::Connection &_timer; + Cached_timer &_timer; Mac_allocator _mac_alloc; Mac_address const _router_mac; Reference _config; @@ -189,7 +188,7 @@ class Net::Nic_session_root public: Nic_session_root(Genode::Env &env, - Timer::Connection &timer, + Cached_timer &timer, Genode::Allocator &alloc, Configuration &config, Quota &shared_quota, diff --git a/repos/os/src/server/nic_router/permit_rule.cc b/repos/os/src/server/nic_router/permit_rule.cc index 4bfc88779c..fe5a73b830 100644 --- a/repos/os/src/server/nic_router/permit_rule.cc +++ b/repos/os/src/server/nic_router/permit_rule.cc @@ -26,26 +26,15 @@ using namespace Genode; ** Permit_any_rule ** *********************/ -Domain &Permit_any_rule::_find_domain(Domain_tree &domains, - Xml_node const node) -{ - try { - return domains.find_by_name( - node.attribute_value("domain", Domain_name())); - } - catch (Domain_tree::No_match) { throw Invalid(); } -} - - void Permit_any_rule::print(Output &output) const { Genode::print(output, "domain ", domain()); } -Permit_any_rule::Permit_any_rule(Domain_tree &domains, Xml_node const node) +Permit_any_rule::Permit_any_rule(Domain_dict &domains, Xml_node const node) : - Permit_rule(_find_domain(domains, node)) + Permit_rule { domains.deprecated_find_by_domain_attr(node) } { } @@ -53,16 +42,6 @@ Permit_any_rule::Permit_any_rule(Domain_tree &domains, Xml_node const node) ** Permit_single_rule ** ************************/ -Domain &Permit_single_rule::_find_domain(Domain_tree &domains, - Xml_node const node) -{ - try { - return domains.find_by_name( - node.attribute_value("domain", Domain_name())); - } - catch (Domain_tree::No_match) { throw Invalid(); } -} - bool Permit_single_rule::higher(Permit_single_rule *rule) { @@ -76,43 +55,12 @@ void Permit_single_rule::print(Output &output) const } -Permit_single_rule::Permit_single_rule(Domain_tree &domains, +Permit_single_rule::Permit_single_rule(Domain_dict &domains, Xml_node const node) : - Permit_rule(_find_domain(domains, node)), - _port(node.attribute_value("port", Port(0))) + Permit_rule { domains.deprecated_find_by_domain_attr(node) }, + _port { node.attribute_value("port", Port(0)) } { if (_port == Port(0) || dynamic_port(_port)) { throw Invalid(); } } - - -Permit_single_rule const & -Permit_single_rule::find_by_port(Port const port) const -{ - if (port == _port) { - return *this; } - - bool const side = port.value > _port.value; - Permit_single_rule *const rule = Avl_node::child(side); - if (!rule) { - throw Permit_single_rule_tree::No_match(); } - - return rule->find_by_port(port); -} - - - -/***************************** - ** Permit_single_rule_tree ** - *****************************/ - -Permit_single_rule const & -Permit_single_rule_tree::find_by_port(Port const port) const -{ - Permit_single_rule *const rule = first(); - if (!rule) { - throw No_match(); } - - return rule->find_by_port(port); -} diff --git a/repos/os/src/server/nic_router/permit_rule.h b/repos/os/src/server/nic_router/permit_rule.h index e75f41c91f..db2cbb49a0 100644 --- a/repos/os/src/server/nic_router/permit_rule.h +++ b/repos/os/src/server/nic_router/permit_rule.h @@ -31,7 +31,7 @@ namespace Net { class Interface; class Domain; - class Domain_tree; + class Domain_dict; class Permit_rule; class Permit_any_rule; @@ -70,16 +70,11 @@ struct Net::Permit_rule : public Genode::Interface struct Net::Permit_any_rule : Permit_rule { - private: - - static Domain &_find_domain(Domain_tree &domains, - Genode::Xml_node const node); - public: struct Invalid : Genode::Exception { }; - Permit_any_rule(Domain_tree &domains, Genode::Xml_node const node); + Permit_any_rule(Domain_dict &domains, Genode::Xml_node const node); /********* @@ -102,17 +97,40 @@ class Net::Permit_single_rule : public Permit_rule, Port const _port; - static Domain &_find_domain(Domain_tree &domains, - Genode::Xml_node const node); - public: struct Invalid : Genode::Exception { }; - Permit_single_rule(Domain_tree &domains, + Permit_single_rule(Domain_dict &domains, Genode::Xml_node const node); - Permit_single_rule const &find_by_port(Port const port) const; + template + + void find_by_port(Port const port, + HANDLE_MATCH_FN && handle_match, + HANDLE_NO_MATCH_FN && handle_no_match) const + { + if (port.value != _port.value) { + + Permit_single_rule *const rule_ptr { + Avl_node::child( + port.value > _port.value) }; + + if (rule_ptr != nullptr) { + + rule_ptr->find_by_port( + port, handle_match, handle_no_match); + + } else { + + handle_no_match(); + } + } else { + + handle_match(*this); + } + } /********* @@ -141,8 +159,6 @@ struct Net::Permit_single_rule_tree : private Avl_tree { friend class Transport_rule; - struct No_match : Genode::Exception { }; - void insert(Permit_single_rule *rule) { Genode::Avl_tree::insert(rule); @@ -150,7 +166,22 @@ struct Net::Permit_single_rule_tree : private Avl_tree using Genode::Avl_tree::first; - Permit_single_rule const &find_by_port(Port const port) const; + template + + void find_by_port(Port const port, + HANDLE_MATCH_FN && handle_match, + HANDLE_NO_MATCH_FN && handle_no_match) const + { + if (first() != nullptr) { + + first()->find_by_port(port, handle_match, handle_no_match); + + } else { + + handle_no_match(); + } + } }; #endif /* _PERMIT_RULE_H_ */ diff --git a/repos/os/src/server/nic_router/report.cc b/repos/os/src/server/nic_router/report.cc index 3299c1fd3c..e5d93a8835 100644 --- a/repos/os/src/server/nic_router/report.cc +++ b/repos/os/src/server/nic_router/report.cc @@ -20,13 +20,14 @@ using namespace Net; using namespace Genode; -Net::Report::Report(bool const &verbose, - Xml_node const node, - Timer::Connection &timer, - Domain_tree &domains, - Quota const &shared_quota, - Pd_session &pd, - Reporter &reporter) +Net::Report::Report(bool const &verbose, + Xml_node const node, + Cached_timer &timer, + Domain_dict &domains, + Quota const &shared_quota, + Pd_session &pd, + Reporter &reporter, + Signal_context_capability const &signal_cap) : _verbose { verbose }, _config { node.attribute_value("config", true) }, @@ -42,15 +43,15 @@ Net::Report::Report(bool const &verbose, _reporter { reporter }, _domains { domains }, _timeout { timer, *this, &Report::_handle_report_timeout, - read_sec_attr(node, "interval_sec", 5) } -{ } - - -void Net::Report::_report() + read_sec_attr(node, "interval_sec", 5) }, + _signal_transmitter { signal_cap } +{ + _reporter.enabled(true); +} + + +void Net::Report::generate() { - if (!_reporter.enabled()) { - return; - } try { Reporter::Xml_generator xml(_reporter, [&] () { if (_quota) { @@ -79,22 +80,23 @@ void Net::Report::_report() void Net::Report::_handle_report_timeout(Duration) { - _report(); + generate(); } void Net::Report::handle_config() { if (!_config_triggers) { - return; } - - _report(); + return; + } + _signal_transmitter.submit(); } + void Net::Report::handle_interface_link_state() { if (!_link_state_triggers) { - return; } - - _report(); + return; + } + _signal_transmitter.submit(); } diff --git a/repos/os/src/server/nic_router/report.h b/repos/os/src/server/nic_router/report.h index 8255ccde5f..407f511356 100644 --- a/repos/os/src/server/nic_router/report.h +++ b/repos/os/src/server/nic_router/report.h @@ -14,8 +14,10 @@ #ifndef _REPORT_H_ #define _REPORT_H_ +/* local includes */ +#include + /* Genode */ -#include #include namespace Genode { @@ -26,7 +28,7 @@ namespace Genode { namespace Net { - class Domain_tree; + class Domain_dict; class Report; class Quota; } @@ -55,29 +57,31 @@ class Net::Report Quota const &_shared_quota; Genode::Pd_session &_pd; Genode::Reporter &_reporter; - Domain_tree &_domains; + Domain_dict &_domains; Timer::Periodic_timeout _timeout; + Genode::Signal_transmitter _signal_transmitter; void _handle_report_timeout(Genode::Duration); - void _report(); - public: struct Empty : Genode::Exception { }; - Report(bool const &verbose, - Genode::Xml_node const node, - Timer::Connection &timer, - Domain_tree &domains, - Quota const &shared_quota, - Genode::Pd_session &pd, - Genode::Reporter &reporter); + Report(bool const &verbose, + Genode::Xml_node const node, + Cached_timer &timer, + Domain_dict &domains, + Quota const &shared_quota, + Genode::Pd_session &pd, + Genode::Reporter &reporter, + Genode::Signal_context_capability const &signal_cap); void handle_config(); void handle_interface_link_state(); + void generate(); + /*************** ** Accessors ** diff --git a/repos/os/src/server/nic_router/transport_rule.cc b/repos/os/src/server/nic_router/transport_rule.cc index 3baf4ea863..70721cf01a 100644 --- a/repos/os/src/server/nic_router/transport_rule.cc +++ b/repos/os/src/server/nic_router/transport_rule.cc @@ -25,7 +25,7 @@ using namespace Genode; Pointer -Transport_rule::_read_permit_any_rule(Domain_tree &domains, +Transport_rule::_read_permit_any_rule(Domain_dict &domains, Xml_node const node, Allocator &alloc) { @@ -39,7 +39,7 @@ Transport_rule::_read_permit_any_rule(Domain_tree &domains, } -Transport_rule::Transport_rule(Domain_tree &domains, +Transport_rule::Transport_rule(Domain_dict &domains, Xml_node const node, Allocator &alloc, Cstring const &protocol, @@ -84,11 +84,3 @@ Transport_rule::~Transport_rule() try { destroy(_alloc, &_permit_any_rule()); } catch (Pointer::Invalid) { } } - - -Permit_rule const &Transport_rule::permit_rule(Port const port) const -{ - try { return _permit_any_rule(); } - catch (Pointer::Invalid) { } - return _permit_single_rules.find_by_port(port); -} diff --git a/repos/os/src/server/nic_router/transport_rule.h b/repos/os/src/server/nic_router/transport_rule.h index 061885628d..abc34b8ac2 100644 --- a/repos/os/src/server/nic_router/transport_rule.h +++ b/repos/os/src/server/nic_router/transport_rule.h @@ -23,9 +23,9 @@ namespace Genode { class Allocator; } namespace Net { - class Configuration; - class Transport_rule; - struct Transport_rule_list : Direct_rule_list { }; + class Configuration; + class Transport_rule; + class Transport_rule_list; } @@ -38,13 +38,13 @@ class Net::Transport_rule : public Direct_rule Permit_single_rule_tree _permit_single_rules { }; static Pointer - _read_permit_any_rule(Domain_tree &domains, + _read_permit_any_rule(Domain_dict &domains, Genode::Xml_node const node, Genode::Allocator &alloc); public: - Transport_rule(Domain_tree &domains, + Transport_rule(Domain_dict &domains, Genode::Xml_node const node, Genode::Allocator &alloc, Genode::Cstring const &protocol, @@ -53,7 +53,53 @@ class Net::Transport_rule : public Direct_rule ~Transport_rule(); - Permit_rule const &permit_rule(Port const port) const; + template + void + find_permit_rule_by_port(Port const port, + HANDLE_MATCH_FN && handle_match, + HANDLE_NO_MATCH_FN && handle_no_match) const + { + if (_permit_any_rule.valid()) { + + handle_match(_permit_any_rule()); + + } else { + + _permit_single_rules.find_by_port( + port, handle_match, handle_no_match); + } + } +}; + + +class Net::Transport_rule_list : public Direct_rule_list +{ + public: + + template + + void find_best_match(Ipv4_address const &ip, + Port const port, + HANDLE_MATCH_FN && handle_match, + HANDLE_NO_MATCH_FN && handle_no_match) const + { + find_longest_prefix_match( + ip, + [&] /* handle_match */ (Transport_rule const &transport_rule) + { + transport_rule.find_permit_rule_by_port( + port, + [&] /* handle_match */ (Permit_rule const &permit_rule) + { + handle_match(transport_rule, permit_rule); + }, + handle_no_match); + }, + handle_no_match + ); + } }; #endif /* _TRANSPORT_RULE_H_ */ diff --git a/repos/os/src/server/nic_router/uplink_session_root.cc b/repos/os/src/server/nic_router/uplink_session_root.cc index fb3beaf4de..28ee10e798 100644 --- a/repos/os/src/server/nic_router/uplink_session_root.cc +++ b/repos/os/src/server/nic_router/uplink_session_root.cc @@ -83,7 +83,7 @@ Net::Uplink_session_component::Interface_policy::determine_domain_name() const Net::Uplink_session_component::Uplink_session_component(Session_env &session_env, size_t const tx_buf_size, size_t const rx_buf_size, - Timer::Connection &timer, + Cached_timer &timer, Mac_address const mac, Session_label const &label, Interface_list &interfaces, @@ -104,6 +104,12 @@ Net::Uplink_session_component::Uplink_session_component(Session_env /* install packet stream signal handlers */ _tx.sigh_packet_avail(_interface.pkt_stream_signal_handler()); _rx.sigh_ack_avail (_interface.pkt_stream_signal_handler()); + + /* + * We do not install ready_to_submit because submission is only triggered + * by incoming packets (and dropped if the submit queue is full). + * The ack queue should never be full otherwise we'll be leaking packets. + */ } @@ -112,7 +118,7 @@ Net::Uplink_session_component::Uplink_session_component(Session_env *************************/ Net::Uplink_session_root::Uplink_session_root(Env &env, - Timer::Connection &timer, + Cached_timer &timer, Allocator &alloc, Configuration &config, Quota &shared_quota, diff --git a/repos/os/src/server/nic_router/uplink_session_root.h b/repos/os/src/server/nic_router/uplink_session_root.h index d42bc532d3..a43142496b 100644 --- a/repos/os/src/server/nic_router/uplink_session_root.h +++ b/repos/os/src/server/nic_router/uplink_session_root.h @@ -82,8 +82,7 @@ class Net::Uplink_session_component : private Uplink_session_component_base, void handle_config(Configuration const &config) override { _config = config; } Genode::Session_label const &label() const override { return _label; } void report(Genode::Xml_generator &xml) const override { _session_env.report(xml); }; - void interface_unready() override { } - void interface_ready() override { } + void handle_domain_ready_state(bool /* state */) override { } bool interface_link_state() const override { return true; } }; @@ -96,7 +95,7 @@ class Net::Uplink_session_component : private Uplink_session_component_base, Uplink_session_component(Genode::Session_env &session_env, Genode::size_t const tx_buf_size, Genode::size_t const rx_buf_size, - Timer::Connection &timer, + Cached_timer &timer, Mac_address const mac, Genode::Session_label const &label, Interface_list &interfaces, @@ -123,7 +122,7 @@ class Net::Uplink_session_root enum { MAC_ALLOC_BASE = 0x02 }; Genode::Env &_env; - Timer::Connection &_timer; + Cached_timer &_timer; Reference _config; Quota &_shared_quota; Interface_list &_interfaces; @@ -141,7 +140,7 @@ class Net::Uplink_session_root public: Uplink_session_root(Genode::Env &env, - Timer::Connection &timer, + Cached_timer &timer, Genode::Allocator &alloc, Configuration &config, Quota &shared_quota, diff --git a/repos/os/src/server/part_block/main.cc b/repos/os/src/server/part_block/main.cc index 8b059750ab..d5eca0ad5a 100644 --- a/repos/os/src/server/part_block/main.cc +++ b/repos/os/src/server/part_block/main.cc @@ -347,20 +347,14 @@ class Block::Main : Rpc_object>, if (!tx_buf_size) throw Service_denied(); - /* delete ram quota by the memory needed for the session */ - size_t session_size = max((size_t)4096, - sizeof(Session_component)); - if (ram_quota.value < session_size) - throw Insufficient_ram_quota(); - /* * Check if donated ram quota suffices for both * communication buffers. Also check both sizes separately * to handle a possible overflow of the sum of both sizes. */ - if (tx_buf_size > ram_quota.value - session_size) { + if (tx_buf_size > ram_quota.value) { error("insufficient 'ram_quota', got ", ram_quota, ", need ", - tx_buf_size + session_size); + tx_buf_size); throw Insufficient_ram_quota(); } diff --git a/repos/os/src/server/rom_filter/README b/repos/os/src/server/rom_filter/README index cfb64aee3e..c81d52e6b3 100644 --- a/repos/os/src/server/rom_filter/README +++ b/repos/os/src/server/rom_filter/README @@ -48,6 +48,10 @@ The '' node can contain the following sub nodes: has an 'input' attribute, the content of the specified input is taken as attribute value. +:'': + Adds a sub node with the specified 'type'. The content of is evaluated + to generate the content of the added sub node. + Conditions ---------- diff --git a/repos/os/src/server/rom_filter/main.cc b/repos/os/src/server/rom_filter/main.cc index c0cfdad1ef..922136b04e 100644 --- a/repos/os/src/server/rom_filter/main.cc +++ b/repos/os/src/server/rom_filter/main.cc @@ -321,6 +321,12 @@ void Rom_filter::Main::_evaluate_node(Xml_node node, Xml_generator &xml) } } else + if (node.has_type("node")) { + xml.node(node.attribute_value("type", Genode::String<128>()).string(), [&]() { + _evaluate_node(node, xml); + }); + } else + if (node.has_type("inline")) { node.with_raw_content([&] (char const *src, size_t len) { diff --git a/repos/os/src/server/vfs/main.cc b/repos/os/src/server/vfs/main.cc index 665a2a520f..623bf7a588 100644 --- a/repos/os/src/server/vfs/main.cc +++ b/repos/os/src/server/vfs/main.cc @@ -660,8 +660,6 @@ class Vfs_server::Session_component : private Session_resources, { switch (vfs_stat.type) { case Vfs::Node_type::DIRECTORY: - return _vfs.num_dirent(node.path()) * sizeof(Directory_entry); - case Vfs::Node_type::SYMLINK: return 0ULL; @@ -688,6 +686,12 @@ class Vfs_server::Session_component : private Session_resources, return fs_stat; } + unsigned num_entries(Dir_handle dir_handle) override + { + return _apply(dir_handle, [&] (Directory &dir) { + return (unsigned)_vfs.num_dirent(dir.path()); }); + } + void unlink(Dir_handle dir_handle, Name const &name) override { if (!_writeable) throw Permission_denied(); @@ -876,13 +880,9 @@ class Vfs_server::Root : public Genode::Root_component, if (!tx_buf_size) throw Service_denied(); - size_t session_size = - max((size_t)4096, sizeof(Session_component)) + - tx_buf_size; - - if (session_size > ram_quota) { + if (tx_buf_size > ram_quota) { error("insufficient 'ram_quota' from '", label, "' " - "got ", ram_quota, ", need ", session_size); + "got ", ram_quota, ", need ", tx_buf_size); throw Insufficient_ram_quota(); } diff --git a/repos/os/src/test/event_filter/main.cc b/repos/os/src/test/event_filter/main.cc index 86787787a3..c6e46caeff 100644 --- a/repos/os/src/test/event_filter/main.cc +++ b/repos/os/src/test/event_filter/main.cc @@ -259,6 +259,13 @@ class Test::Input_to_filter if (motion && rel) batch.submit(Input::Relative_motion{(int)node.attribute_value("rx", 0L), (int)node.attribute_value("ry", 0L)}); + + if (node.has_type("touch")) + batch.submit(Input::Touch{ { 0 }, (float)node.attribute_value("x", 0.0), + (float)node.attribute_value("y", 0.0)}); + + if (node.has_type("touch-release")) + batch.submit(Input::Touch_release { { 0 } } ); }); }); } @@ -337,6 +344,8 @@ struct Test::Main : Input_from_filter::Event_handler step.type() == "expect_release" || step.type() == "not_expect_press" || step.type() == "not_expect_release" || + step.type() == "expect_touch" || + step.type() == "expect_touch_release" || step.type() == "expect_char" || step.type() == "expect_motion" || step.type() == "expect_wheel"); @@ -399,6 +408,7 @@ struct Test::Main : Input_from_filter::Event_handler if (step.type() == "expect_press" || step.type() == "expect_release" || step.type() == "not_expect_press" || step.type() == "not_expect_release" + || step.type() == "expect_touch" || step.type() == "expect_touch_release" || step.type() == "expect_char" || step.type() == "expect_motion" || step.type() == "expect_wheel") return; @@ -485,6 +495,18 @@ struct Test::Main : Input_from_filter::Event_handler && (!step.has_attribute("ay") || step.attribute_value("ay", 0L) == y)) step_succeeded = true; }); + ev.handle_touch([&] (Input::Touch_id, float x, float y) { + if (step.type() == "expect_touch" + && ((float)step.attribute_value("x", 0.0) == x) + && ((float)step.attribute_value("y", 0.0) == y)) + step_succeeded = true; + }); + + ev.handle_touch_release([&] (Input::Touch_id) { + if (step.type() == "expect_touch_release") + step_succeeded = true; + }); + if (step_failed) { error("got unexpected event: ", step); throw Exception(); diff --git a/repos/os/src/test/nic_router_dhcp/client/nic.cc b/repos/os/src/test/nic_router_dhcp/client/nic.cc index dd835d63e3..87e2a9952b 100644 --- a/repos/os/src/test/nic_router_dhcp/client/nic.cc +++ b/repos/os/src/test/nic_router_dhcp/client/nic.cc @@ -18,14 +18,14 @@ using namespace Net; using namespace Genode; -void Net::Nic::_ready_to_ack() +void Net::Nic::_handle_source() { while (_source().ack_avail()) { _source().release_packet(_source().get_acked_packet()); } } -void Net::Nic::_ready_to_submit() +void Net::Nic::_handle_sink() { while (_sink().packet_avail()) { diff --git a/repos/os/src/test/nic_router_dhcp/client/nic.h b/repos/os/src/test/nic_router_dhcp/client/nic.h index b874c7f808..5005cd5360 100644 --- a/repos/os/src/test/nic_router_dhcp/client/nic.h +++ b/repos/os/src/test/nic_router_dhcp/client/nic.h @@ -61,10 +61,8 @@ class Net::Nic bool const &_verbose; ::Nic::Packet_allocator _pkt_alloc { &_alloc }; ::Nic::Connection _nic { _env, &_pkt_alloc, BUF_SIZE, BUF_SIZE }; - Signal_handler _sink_ack { _env.ep(), *this, &Nic::_ack_avail }; - Signal_handler _sink_submit { _env.ep(), *this, &Nic::_ready_to_submit }; - Signal_handler _source_ack { _env.ep(), *this, &Nic::_ready_to_ack }; - Signal_handler _source_submit { _env.ep(), *this, &Nic::_packet_avail }; + Signal_handler _sink_handler { _env.ep(), *this, &Nic::_handle_sink }; + Signal_handler _source_handler { _env.ep(), *this, &Nic::_handle_source }; Signal_handler _link_state_handler { _env.ep(), *this, &Nic::handle_link_state }; Mac_address const _mac { _nic.mac_address() }; @@ -76,10 +74,8 @@ class Net::Nic ** Packet-stream signal handlers ** ***********************************/ - void _ready_to_submit(); - void _ack_avail() { } - void _ready_to_ack(); - void _packet_avail() { } + void _handle_sink(); + void _handle_source(); public: @@ -93,10 +89,10 @@ class Net::Nic _handler (handler), _verbose (verbose) { - _nic.rx_channel()->sigh_ready_to_ack(_sink_ack); - _nic.rx_channel()->sigh_packet_avail(_sink_submit); - _nic.tx_channel()->sigh_ack_avail(_source_ack); - _nic.tx_channel()->sigh_ready_to_submit(_source_submit); + _nic.rx_channel()->sigh_ready_to_ack(_sink_handler); + _nic.rx_channel()->sigh_packet_avail(_sink_handler); + _nic.tx_channel()->sigh_ack_avail(_source_handler); + _nic.tx_channel()->sigh_ready_to_submit(_source_handler); _nic.link_state_sigh(_link_state_handler); } diff --git a/repos/os/src/test/nic_router_dhcp/manager/main.cc b/repos/os/src/test/nic_router_dhcp/manager/main.cc index 5ddbb3434f..da36bce4f5 100644 --- a/repos/os/src/test/nic_router_dhcp/manager/main.cc +++ b/repos/os/src/test/nic_router_dhcp/manager/main.cc @@ -107,11 +107,17 @@ void Local::Main::_handle_router_state() domain_node.for_each_sub_node( "dns", [&] (Xml_node const &dns_node) - { - - dns_servers.insert_as_tail( - *new (_heap) Dns_server(dns_node.attribute_value("ip", Ipv4_address { }))); - }); + { + Dns_server::construct( + _heap, dns_node.attribute_value("ip", Ipv4_address { }), + [&] /* handle_success */ (Dns_server &server) + { + dns_servers.insert_as_tail(server); + }, + [&] /* handle_failure */ () { } + ); + } + ); /* * If the new list of DNS servers differs from the stored list, @@ -122,8 +128,14 @@ void Local::Main::_handle_router_state() _dns_servers.destroy_each(_heap); dns_servers.for_each([&] (Dns_server const &dns_server) { - _dns_servers.insert_as_tail( - *new (_heap) Dns_server(dns_server.ip())); + Dns_server::construct( + _heap, dns_server.ip(), + [&] /* handle_success */ (Dns_server &server) + { + _dns_servers.insert_as_tail(server); + }, + [&] /* handle_failure */ () { } + ); }); _router_config_outdated = true; } @@ -131,7 +143,7 @@ void Local::Main::_handle_router_state() /* read out new DNS domain name */ Dns_domain_name dns_domain_name { _heap }; - domain_node.with_sub_node("dns-domain", [&] (Xml_node const &sub_node) { + domain_node.with_optional_sub_node("dns-domain", [&] (Xml_node const &sub_node) { xml_node_with_attribute(sub_node, "name", [&] (Xml_attribute const &attr) { dns_domain_name.set_to(attr); }); diff --git a/repos/os/src/test/pci/target.mk b/repos/os/src/test/pci/target.mk deleted file mode 100644 index eaf0a717f7..0000000000 --- a/repos/os/src/test/pci/target.mk +++ /dev/null @@ -1,6 +0,0 @@ -TARGET = test-pci -SRC_CC = test.cc -LIBS = base -REQUIRES = x86 - -CC_CXX_WARN_STRICT_CONVERSION = diff --git a/repos/os/src/test/pci/test.cc b/repos/os/src/test/pci/test.cc deleted file mode 100644 index ab9f788177..0000000000 --- a/repos/os/src/test/pci/test.cc +++ /dev/null @@ -1,239 +0,0 @@ -/* - * \brief Test for PCI bus driver - * \author Norman Feske - * \date 2008-01-18 - */ - -/* - * Copyright (C) 2008-2020 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. - */ - -#include -#include -#include -#include -#include - -using namespace Genode; - -enum { AMD_VENDOR_ID = 0x1022, INTEL_VENDOR_ID = 0x8086 }; -enum { - CLASS_CODE_SATA = 0x106, - CLASS_CODE_ETHERNET = 0x200, - CLASS_CODE_VGA = 0x300, - CLASS_CODE_HOST_BRIDGE = 0x600, - CLASS_CODE_HOST_ISA = 0x601, - CLASS_CODE_PCI_PCI_BRIDGE = 0x604, - CLASS_CODE_IOMMU = 0x806, - CLASS_CODE_USB = 0xc03, - CLASS_CODE_SMBUS = 0xc05, -}; - -enum { - USB_UHCI = 0x00, - USB_OHCI = 0x10, - USB_EHCI = 0x20, - USB_XHCI = 0x30 -}; - -enum { - DEVICE_AMD_HUDSON2_SMBUS = 0x780b, -}; - -enum { - CAP_PWRM = 0x01, - CAP_MSI = 0x05, - CAP_HT = 0x08, - CAP_SECDEV = 0x0f, - CAP_PCI_E = 0x10, - CAP_MSIX = 0x11 -}; - -enum { - EXT_CAP_ERRREP = 0x01, /* advanced error reporting */ - EXT_CAP_DEVSNR = 0x03, /* device serial number */ - EXT_CAP_VENDOR = 0x0b, /* vendor specific */ - EXT_CAP_ACSERV = 0x0d, /* access control service */ -}; - -typedef Platform::Device::Access_size Size; - -static void dump_extended_pci_caps(Platform::Device_client &device) -{ - unsigned cap = 0x100; - unsigned max_caps = (0x1000 - cap) / 8; - - String<128> cap_string { }; - while (max_caps) { - unsigned const val = device.config_read(cap, Size::ACCESS_32BIT); - switch (val & 0xffff) { - case 0: - break; - case EXT_CAP_ERRREP: - cap_string = String<128>(cap_string, " ERR_REP"); - break; - case EXT_CAP_DEVSNR: - cap_string = String<128>(cap_string, " DEV_SNR"); - break; - case EXT_CAP_VENDOR: - cap_string = String<128>(cap_string, " VENDOR"); - break; - case EXT_CAP_ACSERV: - cap_string = String<128>(cap_string, " ACS"); - break; - default: - cap_string = String<128>(cap_string, " ", Hex(val & 0xffff)); - }; - - max_caps --; - cap = (val >> 20) & 0xffc; - if (cap <= 0x100 || cap >= 0x1000 - 4 /* size of 32Bit */) - break; - } - - if (cap_string.valid()) - log(" ECAP:", cap_string); -} - -/** - * Print device information - */ -static void print_device_info(Platform::Device_capability device_cap) -{ - if (!device_cap.valid()) { - error("invalid device capability"); - return; - } - - Platform::Device_client device(device_cap); - - unsigned char bus = 0, dev = 0, fun = 0; - device.bus_address(&bus, &dev, &fun); - unsigned short const vendor_id = device.vendor_id(); - unsigned short const device_id = device.device_id(); - unsigned const class_code = device.class_code() >> 8; - unsigned char const revision = device.config_read(0x8, Size::ACCESS_8BIT); - unsigned char const prog_if = device.config_read(0x9, Size::ACCESS_8BIT); - unsigned const pci_cmd = device.config_read(0x4, Size::ACCESS_16BIT); - - - log(Hex(bus, Hex::OMIT_PREFIX), ":", - Hex(dev, Hex::OMIT_PREFIX), ".", - Hex(fun, Hex::OMIT_PREFIX), " " - "class=", Hex(class_code), " ", - (class_code == CLASS_CODE_VGA) ? "(VGA)" : - (class_code == CLASS_CODE_HOST_BRIDGE) ? "(bridge host)" : - (class_code == CLASS_CODE_HOST_ISA) ? "(bridge ISA)" : - (class_code == CLASS_CODE_PCI_PCI_BRIDGE) ? "(bridge PCI)" : - (class_code == CLASS_CODE_IOMMU) ? "(IOMMU)" : - (class_code == CLASS_CODE_USB) ? "(USB)" : - (class_code == CLASS_CODE_SMBUS) ? "(SMBUS)" : - (class_code == CLASS_CODE_SATA) ? "(SATA)" : "", - (class_code == CLASS_CODE_ETHERNET) ? "(Ethernet)" : "", - " vendor=", Hex(vendor_id), " ", - ((vendor_id == INTEL_VENDOR_ID) ? "(Intel)" : - (vendor_id == AMD_VENDOR_ID) ? "(AMD)" : "(unknown)"), - " device=", Hex(device_id), - " prog_if=", Genode::Hex(prog_if), - (class_code != CLASS_CODE_USB) ? "" : - (prog_if == USB_UHCI) ? "(UHCI)" : - (prog_if == USB_OHCI) ? "(OHCI)" : - (prog_if == USB_EHCI) ? "(EHCI)" : - (prog_if == USB_XHCI) ? "(XHCI)" : "", - " revision=", Genode::Hex(revision), - " pci_cmd=", Genode::Hex(pci_cmd)); - - if (vendor_id == AMD_VENDOR_ID && device_id == DEVICE_AMD_HUDSON2_SMBUS) { - if (revision >= 0x11 && revision <= 0x14) - log("chipset: AMD HUDSON2"); - else if (revision >= 0x15 && revision <= 0x18) - log("chipset: AMD BOLTON"); - else if (revision >= 0x39 && revision <= 0x3a) - log("chipset: AMD ANGTZE"); - } - - for (int resource_id = 0; resource_id < 6; resource_id++) { - - typedef Platform::Device::Resource Resource; - - Resource const resource = device.resource(resource_id); - - if (resource.type() != Resource::INVALID) { - log(" Resource ", resource_id, " " - "(", (resource.type() == Resource::IO ? "I/O" : "MEM"), "): " - "base=", Genode::Hex(resource.base()), " " - "size=", Genode::Hex(resource.size()), " ", - (resource.prefetchable() ? "prefetchable" : "") - ); - } - } - - unsigned cap = device.config_read(0x34, Size::ACCESS_8BIT); - if (cap) { - String<128> cap_string { }; - for (Genode::uint32_t val = 0; cap; cap = (val >> 8) & 0xff) { - val = device.config_read(cap, Size::ACCESS_32BIT); - unsigned const type = val & 0xff; - switch (type) { - case CAP_MSI: { - uint16_t msi_val = device.config_read(cap + 2, Size::ACCESS_16BIT); - if (msi_val & 0x80) - cap_string = String<128>(cap_string, " MSI-64"); - else - cap_string = String<128>(cap_string, " MSI"); - break; - } - case CAP_HT: cap_string = String<128>(cap_string, " HYPERTRANSPORT"); break; - case CAP_MSIX: cap_string = String<128>(cap_string, " MSI-X"); break; - case CAP_PCI_E: cap_string = String<128>(cap_string, " PCI-E"); break; - case CAP_SECDEV: cap_string = String<128>(cap_string, " SECURE-DEVICE"); break; - case CAP_PWRM: cap_string = String<128>(cap_string, " PWRM"); break; - default: - cap_string = String<128>(cap_string, " ", Hex(type)); - } - - if (type == CAP_PCI_E) { - uint16_t flags = device.config_read(cap + 2, Size::ACCESS_16BIT); - uint8_t type = (flags >> 4) & 0xf; - cap_string = String<128>(cap_string, "(T", Hex(type, Hex::OMIT_PREFIX), ")"); - } - } - log(" CAP:", cap_string); - } - - dump_extended_pci_caps(device); -} - - -void Component::construct(Genode::Env &env) -{ - log("--- Platform test started ---"); - - /* open session to pci service */ - static Platform::Connection pci(env); - - Platform::Device_capability prev_device_cap, device_cap; - - pci.with_upgrade([&] () { device_cap = pci.first_device(); }); - - /* - * Iterate through all installed devices - * and print the available device information. - */ - while (device_cap.valid()) { - print_device_info(device_cap); - - pci.release_device(prev_device_cap); - prev_device_cap = device_cap; - - pci.with_upgrade([&] () { device_cap = pci.next_device(device_cap); }); - } - - /* release last device */ - pci.release_device(prev_device_cap); - - log("--- Platform test finished ---"); -} diff --git a/repos/os/src/test/resource_request/main.cc b/repos/os/src/test/resource_request/main.cc index 7c69f7c885..979ce86f75 100644 --- a/repos/os/src/test/resource_request/main.cc +++ b/repos/os/src/test/resource_request/main.cc @@ -87,8 +87,8 @@ struct Test::Monitor { size_t result = 0; - _init_state.xml().with_sub_node("child", [&] (Xml_node const &child) { - child.with_sub_node("ram", [&] (Xml_node const &ram) { + _init_state.xml().with_optional_sub_node("child", [&] (Xml_node const &child) { + child.with_optional_sub_node("ram", [&] (Xml_node const &ram) { result = ram.attribute_value(attr, Number_of_bytes(0)); }); }); return result; diff --git a/repos/os/src/test/trace_buffer/main.cc b/repos/os/src/test/trace_buffer/main.cc index 325d506ca7..990d13c0d1 100644 --- a/repos/os/src/test/trace_buffer/main.cc +++ b/repos/os/src/test/trace_buffer/main.cc @@ -168,7 +168,7 @@ struct Test_thread : Thread } Test_thread(Env &env, Trace::Buffer &buffer, unsigned delay) - : Thread(env, "producer", 1024 * sizeof(addr_t)), + : Thread(env, "producer", 8*1024), env(env), buffer(buffer), delay(delay) diff --git a/repos/os/src/lib/trace/policy/div_zero/policy.cc b/repos/os/src/trace/policy/div_zero/policy.cc similarity index 82% rename from repos/os/src/lib/trace/policy/div_zero/policy.cc rename to repos/os/src/trace/policy/div_zero/policy.cc index ce34e53a22..acc6eeb183 100644 --- a/repos/os/src/lib/trace/policy/div_zero/policy.cc +++ b/repos/os/src/trace/policy/div_zero/policy.cc @@ -18,6 +18,16 @@ size_t max_event_size() return MAX_EVENT_SIZE; } +size_t trace_eth_packet(char *, char const *, bool, char *, size_t) +{ + return 0; +} + +size_t checkpoint(char *dst, char const *, unsigned long, void *, unsigned char) +{ + return div_zero(); +} + size_t log_output(char *dst, char const *log_message, size_t len) { return div_zero(); diff --git a/repos/os/src/lib/trace/policy/div_zero/target.mk b/repos/os/src/trace/policy/div_zero/target.mk similarity index 100% rename from repos/os/src/lib/trace/policy/div_zero/target.mk rename to repos/os/src/trace/policy/div_zero/target.mk diff --git a/repos/os/src/lib/trace/policy/log_output/policy.cc b/repos/os/src/trace/policy/log_output/policy.cc similarity index 81% rename from repos/os/src/lib/trace/policy/log_output/policy.cc rename to repos/os/src/trace/policy/log_output/policy.cc index a0a825f99e..7684adef22 100644 --- a/repos/os/src/lib/trace/policy/log_output/policy.cc +++ b/repos/os/src/trace/policy/log_output/policy.cc @@ -10,6 +10,16 @@ size_t max_event_size() return MAX_EVENT_SIZE; } +size_t trace_eth_packet(char *, char const *, bool, char *, size_t) +{ + return 0; +} + +size_t checkpoint(char *dst, char const *, unsigned long, void *, unsigned char) +{ + return 0; +} + size_t log_output(char *dst, char const *log_message, size_t len) { len = min(len, MAX_EVENT_SIZE); diff --git a/repos/os/src/lib/trace/policy/log_output/target.mk b/repos/os/src/trace/policy/log_output/target.mk similarity index 100% rename from repos/os/src/lib/trace/policy/log_output/target.mk rename to repos/os/src/trace/policy/log_output/target.mk diff --git a/repos/os/src/lib/trace/policy/null/policy.cc b/repos/os/src/trace/policy/null/policy.cc similarity index 77% rename from repos/os/src/lib/trace/policy/null/policy.cc rename to repos/os/src/trace/policy/null/policy.cc index d65c5de9d1..76fb18c9f6 100644 --- a/repos/os/src/lib/trace/policy/null/policy.cc +++ b/repos/os/src/trace/policy/null/policy.cc @@ -7,6 +7,16 @@ size_t max_event_size() return 0; } +size_t trace_eth_packet(char *, char const *, bool, char *, size_t) +{ + return 0; +} + +size_t checkpoint(char *dst, char const *, unsigned long, void *, unsigned char) +{ + return 0; +} + size_t log_output(char *dst, char const *log_message, size_t len) { return 0; diff --git a/repos/os/src/lib/trace/policy/null/target.mk b/repos/os/src/trace/policy/null/target.mk similarity index 100% rename from repos/os/src/lib/trace/policy/null/target.mk rename to repos/os/src/trace/policy/null/target.mk diff --git a/repos/os/src/lib/trace/policy/policy.inc b/repos/os/src/trace/policy/policy.inc similarity index 95% rename from repos/os/src/lib/trace/policy/policy.inc rename to repos/os/src/trace/policy/policy.inc index b10ab253b3..ce8169e47a 100644 --- a/repos/os/src/lib/trace/policy/policy.inc +++ b/repos/os/src/trace/policy/policy.inc @@ -38,4 +38,4 @@ clean_policy: $(VERBOSE)$(RM) ../*.o ../*.d *.o *.d $(TARGET_POLICY).elf \ $(BUILD_BASE_DIR)/bin/$(TARGET_POLICY) -vpath table.cc $(REP_DIR)/src/lib/trace/policy +vpath table.cc $(REP_DIR)/src/trace/policy diff --git a/repos/os/src/trace/policy/policy.ld b/repos/os/src/trace/policy/policy.ld new file mode 100644 index 0000000000..4a5e7bbdbb --- /dev/null +++ b/repos/os/src/trace/policy/policy.ld @@ -0,0 +1,15 @@ +PHDRS { rw PT_LOAD; } +SECTIONS { + + .text : { + *(.data.rel) /* must be first because it contains policy module header */ + *(.data) + *(.rodata .rodata.*) + *(.text .text.*) + *(.bss) + *(.got.plt) + *(.got) + } : rw + + /DISCARD/ : { *(.*) } +} diff --git a/repos/os/src/lib/trace/policy/rpc_name/policy.cc b/repos/os/src/trace/policy/rpc_name/policy.cc similarity index 84% rename from repos/os/src/lib/trace/policy/rpc_name/policy.cc rename to repos/os/src/trace/policy/rpc_name/policy.cc index 0521d92b4c..a1293f43a4 100644 --- a/repos/os/src/lib/trace/policy/rpc_name/policy.cc +++ b/repos/os/src/trace/policy/rpc_name/policy.cc @@ -10,6 +10,16 @@ size_t max_event_size() return MAX_EVENT_SIZE; } +size_t trace_eth_packet(char *, char const *, bool, char *, size_t) +{ + return 0; +} + +size_t checkpoint(char *, char const *, unsigned long, void *, unsigned char) +{ + return 0; +} + size_t log_output(char *dst, char const *log_message, size_t len) { return 0; diff --git a/repos/os/src/lib/trace/policy/rpc_name/target.mk b/repos/os/src/trace/policy/rpc_name/target.mk similarity index 100% rename from repos/os/src/lib/trace/policy/rpc_name/target.mk rename to repos/os/src/trace/policy/rpc_name/target.mk diff --git a/repos/os/src/trace/policy/table.cc b/repos/os/src/trace/policy/table.cc new file mode 100644 index 0000000000..e92331d297 --- /dev/null +++ b/repos/os/src/trace/policy/table.cc @@ -0,0 +1,32 @@ +/* + * \brief Header of tracing policy module + * \author Norman Feske + * \date 2013-08-15 + */ + +/* + * 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. + */ + +#include +#include + +extern "C" { + + Genode::Trace::Policy_module policy_jump_table = + { + max_event_size, + trace_eth_packet, + checkpoint, + log_output, + rpc_call, + rpc_returned, + rpc_dispatch, + rpc_reply, + signal_submit, + signal_receive + }; +} diff --git a/repos/pc/lib/import/import-pc_lx_emul.mk b/repos/pc/lib/import/import-pc_lx_emul.mk index 73bb3d90a5..55ab8d47ea 100644 --- a/repos/pc/lib/import/import-pc_lx_emul.mk +++ b/repos/pc/lib/import/import-pc_lx_emul.mk @@ -18,19 +18,23 @@ SRC_CC += lx_emul/clock.cc SRC_CC += lx_emul/io_mem.cc SRC_CC += lx_emul/io_port.cc SRC_CC += lx_emul/irq.cc +SRC_CC += lx_emul/random.cc SRC_C += lx_emul/shadow/kernel/dma/mapping.c SRC_C += lx_emul/shadow/kernel/irq/spurious.c -SRC_C += lx_emul/shadow/kernel/rcu/tree.c -SRC_C += lx_emul/shadow/kernel/sched/sched.c SRC_C += lx_emul/shadow/lib/devres.c SRC_C += lx_emul/shadow/lib/smp_processor_id.c SRC_C += lx_emul/shadow/mm/memblock.c SRC_C += lx_emul/shadow/mm/page_alloc.c -SRC_CC += lx_emul/pci_config_space.cc -SRC_CC += lx_emul/pci_init.cc +SRC_C += lx_emul/shadow/drivers/pci/host-bridge.c +SRC_C += lx_emul/shadow/drivers/pci/pci.c +SRC_C += lx_emul/shadow/drivers/pci/pci-sysfs.c +SRC_C += lx_emul/shadow/drivers/pci/search.c +SRC_C += lx_emul/shadow/drivers/pci/setup-irq.c +SRC_C += lx_emul/shadow/drivers/pci/setup-res.c +SRC_CC += lx_emul/pci.cc +SRC_CC += lx_emul/pci_bus.c SRC_CC += lx_kit/device.cc SRC_CC += lx_kit/memory_dma.cc -SRC_CC += lx_kit/spec/x86/platform.cc SRC_C += lx_emul/shadow/fs/sysfs/dir.c SRC_C += lx_emul/shadow/fs/sysfs/file.c @@ -44,13 +48,13 @@ SRC_C += lx_emul/mapping.c SRC_C += lx_emul/page_alloc.c SRC_C += lx_emul/sched_core.c SRC_C += lx_emul/slab_common.c -SRC_C += lx_emul/softirq.c SRC_C += lx_emul/vmalloc.c +SRC_C += lx_emul/delay.c SRC_C += lx_emul/shadow/fs/libfs.c -SRC_C += lx_emul/shadow/kernel/rcu/tiny.c SRC_C += lx_emul/shadow/lib/logic_iomem.c +SRC_C += lx_emul/shadow/drivers/char/random.c SRC_C += lx_emul/shadow/drivers/acpi/bus.c SRC_C += lx_emul/shadow/drivers/acpi/device_sysfs.c SRC_C += lx_emul/shadow/drivers/acpi/glue.c diff --git a/repos/pc/lib/mk/spec/x86_32/wifi.mk b/repos/pc/lib/mk/spec/x86_32/wifi.mk index 6160802395..f136e992a4 100644 --- a/repos/pc/lib/mk/spec/x86_32/wifi.mk +++ b/repos/pc/lib/mk/spec/x86_32/wifi.mk @@ -3,3 +3,4 @@ include $(REP_DIR)/lib/mk/wifi.inc REQUIRES += 32bit SRC_C += lx_emul/spec/x86_32/atomic64_32.c +SRC_C += lx_emul/shadow/arch/x86/kernel/irq_32.c diff --git a/repos/pc/lib/mk/wifi.inc b/repos/pc/lib/mk/wifi.inc index 2115410fd8..54583be571 100644 --- a/repos/pc/lib/mk/wifi.inc +++ b/repos/pc/lib/mk/wifi.inc @@ -25,7 +25,6 @@ SRC_C += lx_socket_call.c SRC_C += $(notdir $(wildcard $(TARGET_LIB_DIR)/generated_dummies.c)) SRC_C += lx_emul/common_dummies.c -SRC_C += lx_emul/spec/x86/pci.c CC_C_OPT += -I$(LX_SRC_DIR)/drivers/net/wireless/intel/iwlwifi CC_C_OPT += -I$(LX_SRC_DIR)/include/linux @@ -47,7 +46,7 @@ vpath %.cc $(REP_DIR)/src/lib/pc vpath %.c $(TARGET_LIB_DIR) vpath %.cc $(TARGET_LIB_DIR) -CUSTOM_TARGET_DEPS += $(TARGET_LIB_DIR)/symbol.map +$(LIB).lib.so: $(TARGET_LIB_DIR)/symbol.map # # Genode C-API backends diff --git a/repos/pc/recipes/api/pc_linux/content.mk b/repos/pc/recipes/api/pc_linux/content.mk index 8da1762ab4..3f5fd64d3a 100644 --- a/repos/pc/recipes/api/pc_linux/content.mk +++ b/repos/pc/recipes/api/pc_linux/content.mk @@ -141,7 +141,10 @@ LX_FILES += arch/x86/include/asm/boot.h \ arch/x86/include/asm/pgtable_64.h \ arch/x86/include/asm/pgtable-invert.h \ arch/x86/include/asm/pkru.h \ + arch/x86/include/asm/qrwlock.h \ + arch/x86/include/asm/qspinlock.h \ arch/x86/include/asm/sigframe.h \ + arch/x86/include/asm/spinlock.h \ arch/x86/include/asm/suspend.h \ arch/x86/include/asm/suspend_32.h \ arch/x86/include/asm/suspend_64.h \ @@ -159,6 +162,7 @@ LX_FILES += arch/x86/include/asm/boot.h \ include/asm-generic/pgtable_uffd.h \ include/asm-generic/pgtable-nopmd.h \ include/asm-generic/pgtable-nopud.h \ + include/asm-generic/qrwlock.h \ include/asm-generic/qspinlock.h \ include/linux/arm-smccc.h \ include/linux/arm_sdei.h \ diff --git a/repos/pc/recipes/api/pc_linux/hash b/repos/pc/recipes/api/pc_linux/hash index 58e85838ab..ee68de47ec 100644 --- a/repos/pc/recipes/api/pc_linux/hash +++ b/repos/pc/recipes/api/pc_linux/hash @@ -1 +1 @@ -2022-05-30 5e0d68e3d29f06f6318e23d127cffd21f8f6c3fa +2022-10-11 3e36ba37ccdbaba16ac81203f7cd9ff64770e5c2 diff --git a/repos/pc/recipes/pkg/test_usb_host_drv-pc/archives b/repos/pc/recipes/pkg/test_usb_host_drv-pc/archives index 77ea7d26a7..373005556b 100644 --- a/repos/pc/recipes/pkg/test_usb_host_drv-pc/archives +++ b/repos/pc/recipes/pkg/test_usb_host_drv-pc/archives @@ -1,5 +1,6 @@ _/raw/test_usb_host_drv-pc _/src/acpi_drv +_/src/pci_decode _/src/pc_usb_host_drv _/src/platform_drv _/src/report_rom diff --git a/repos/pc/recipes/pkg/test_usb_host_drv-pc/hash b/repos/pc/recipes/pkg/test_usb_host_drv-pc/hash index 4048e63f58..11b6c37586 100644 --- a/repos/pc/recipes/pkg/test_usb_host_drv-pc/hash +++ b/repos/pc/recipes/pkg/test_usb_host_drv-pc/hash @@ -1 +1 @@ -2022-05-30 b3adffbb3d026013ff73ae6c9701cc603bb9b2ac +2022-10-11 dab06b4f474d2ed85bdc6a63fd2890f3fea1d91f diff --git a/repos/pc/recipes/pkg/wifi/hash b/repos/pc/recipes/pkg/wifi/hash index 062b821cfb..b88d034ef9 100644 --- a/repos/pc/recipes/pkg/wifi/hash +++ b/repos/pc/recipes/pkg/wifi/hash @@ -1 +1 @@ -2022-05-30 4a735e4205e73763c4f7e87f79a39d4152495381 +2022-10-13 5ab7d538e658982e2c7d3eea4ff89d9ded806c59 diff --git a/repos/pc/recipes/raw/pc-devices/content.mk b/repos/pc/recipes/raw/pc-devices/content.mk new file mode 100644 index 0000000000..b9b79df7c4 --- /dev/null +++ b/repos/pc/recipes/raw/pc-devices/content.mk @@ -0,0 +1,4 @@ +content: devices + +devices: + cp $(GENODE_DIR)/repos/base/board/pc/$@ $@ diff --git a/repos/pc/recipes/raw/pc-devices/hash b/repos/pc/recipes/raw/pc-devices/hash new file mode 100644 index 0000000000..b744230dec --- /dev/null +++ b/repos/pc/recipes/raw/pc-devices/hash @@ -0,0 +1 @@ +2022-09-15 184a930a9bf6fa8dc67582adbd3f940bf815a767 diff --git a/repos/pc/recipes/raw/test_usb_host_drv-pc/drivers.config b/repos/pc/recipes/raw/test_usb_host_drv-pc/drivers.config index 44e481bd46..08b2fbe9b4 100644 --- a/repos/pc/recipes/raw/test_usb_host_drv-pc/drivers.config +++ b/repos/pc/recipes/raw/test_usb_host_drv-pc/drivers.config @@ -15,6 +15,24 @@ + + + + + + + + + + + + + + + + + + @@ -28,33 +46,27 @@ - + - - - - - - - - - - - + + + + + + + + + + - - - - - - - + + + - - + @@ -65,11 +77,11 @@ - + - + diff --git a/repos/pc/recipes/raw/test_usb_host_drv-pc/hash b/repos/pc/recipes/raw/test_usb_host_drv-pc/hash index 3a86159890..71bfa06df1 100644 --- a/repos/pc/recipes/raw/test_usb_host_drv-pc/hash +++ b/repos/pc/recipes/raw/test_usb_host_drv-pc/hash @@ -1 +1 @@ -2022-05-17-y 1dc9c450d12b1e44606ae1c4f6d30b9824f3f2ac +2022-10-11 7c76567c99f9500da5f48e212a0ade1ba264804c diff --git a/repos/pc/recipes/src/pc_intel_fb_drv/hash b/repos/pc/recipes/src/pc_intel_fb_drv/hash index a00b09ac4e..8484bb4d1d 100644 --- a/repos/pc/recipes/src/pc_intel_fb_drv/hash +++ b/repos/pc/recipes/src/pc_intel_fb_drv/hash @@ -1 +1 @@ -2022-05-30 81c39be156bfd4d01786cfb01fa00efc0f7efa72 +2022-10-11 88ac1a413e845d81586d82d292a83131f5e93c23 diff --git a/repos/pc/recipes/src/pc_intel_fb_drv/used_apis b/repos/pc/recipes/src/pc_intel_fb_drv/used_apis index ba755919c7..ee690e84de 100644 --- a/repos/pc/recipes/src/pc_intel_fb_drv/used_apis +++ b/repos/pc/recipes/src/pc_intel_fb_drv/used_apis @@ -1,9 +1,10 @@ base -os -platform_session -timer_session -report_session -capture_session blit +capture_session genode_c_api +jitterentropy +os pc_linux +platform_session +report_session +timer_session diff --git a/repos/pc/recipes/src/pc_platform_drv/content.mk b/repos/pc/recipes/src/pc_platform_drv/content.mk new file mode 100644 index 0000000000..a7f7992f97 --- /dev/null +++ b/repos/pc/recipes/src/pc_platform_drv/content.mk @@ -0,0 +1,2 @@ +SRC_DIR = src/drivers/platform/pc +include $(GENODE_DIR)/repos/os/recipes/src/platform_drv/content.inc diff --git a/repos/pc/recipes/src/pc_platform_drv/hash b/repos/pc/recipes/src/pc_platform_drv/hash new file mode 100644 index 0000000000..877b0e7f62 --- /dev/null +++ b/repos/pc/recipes/src/pc_platform_drv/hash @@ -0,0 +1 @@ +2022-10-11 5644ac6c90238da37942ce92b228b168dd32f373 diff --git a/repos/pc/recipes/src/pc_platform_drv/used_apis b/repos/pc/recipes/src/pc_platform_drv/used_apis new file mode 100644 index 0000000000..dbf0f2d7f7 --- /dev/null +++ b/repos/pc/recipes/src/pc_platform_drv/used_apis @@ -0,0 +1,4 @@ +base +os +platform_session +report_session diff --git a/repos/pc/recipes/src/pc_usb_host_drv/hash b/repos/pc/recipes/src/pc_usb_host_drv/hash index 047c88d400..56d3fa4489 100644 --- a/repos/pc/recipes/src/pc_usb_host_drv/hash +++ b/repos/pc/recipes/src/pc_usb_host_drv/hash @@ -1 +1 @@ -2022-05-30 1b02394376c97cdaf7532fb0a647466990cc11c9 +2022-10-11 99faca67ba2fce667cc5bfe61d45e9903b2fa786 diff --git a/repos/pc/recipes/src/pc_usb_host_drv/used_apis b/repos/pc/recipes/src/pc_usb_host_drv/used_apis index afb8da2145..eb4df41388 100644 --- a/repos/pc/recipes/src/pc_usb_host_drv/used_apis +++ b/repos/pc/recipes/src/pc_usb_host_drv/used_apis @@ -1,8 +1,9 @@ base +genode_c_api +jitterentropy os +pc_linux platform_session +report_session timer_session usb_session -report_session -genode_c_api -pc_linux diff --git a/repos/pc/recipes/src/pc_wifi_drv/hash b/repos/pc/recipes/src/pc_wifi_drv/hash index 06c5c0906a..33b26ea5f5 100644 --- a/repos/pc/recipes/src/pc_wifi_drv/hash +++ b/repos/pc/recipes/src/pc_wifi_drv/hash @@ -1 +1 @@ -2022-05-30 d9567624fa329add1edfabe49178f5d44f183fcf +2022-10-11 ce28302f496619ac0db3345f83ce1db27a2558de diff --git a/repos/pc/run/driver_time.run b/repos/pc/run/driver_time.run new file mode 100644 index 0000000000..f3b439615c --- /dev/null +++ b/repos/pc/run/driver_time.run @@ -0,0 +1,87 @@ +# +# Build +# + +if {[expr ![have_spec x86_64]]} { + puts "Run script is not supported on this platform." + exit 0 +} + +set use_top 0 + +set build_components { + core init timer + drivers/platform + test/driver_time +} + + +append_if $use_top build_components { app/top } +build $build_components + +create_boot_directory + +append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + +append_if $use_top config { + + + + } + +append config { +} + +install_config $config + +# +# Boot modules +# + +file copy [select_from_repositories board/[board]/devices] [run_dir]/genode/devices + +# generic modules +set boot_modules { + core ld.lib.so init timer platform_drv + test-driver_time +} + +append_if $use_top boot_modules { top } +build_boot_image $boot_modules + +append qemu_args "-nographic " + +run_genode_until forever diff --git a/repos/pc/run/intel_fb.run b/repos/pc/run/intel_fb.run index 0ae21947d4..4689dc1d61 100644 --- a/repos/pc/run/intel_fb.run +++ b/repos/pc/run/intel_fb.run @@ -1,3 +1,15 @@ +assert_spec x86_64 + +if {[get_cmd_switch --autopilot] && [have_include "power_on/qemu"]} { + puts "Run script does not support autopilot mode on Qemu" + exit 0 +} + +if {[get_cmd_switch --autopilot] && [have_board linux]} { + puts "Autopilot mode is not supported on this platform." + exit 0 +} + # # Build # @@ -7,21 +19,21 @@ set use_top 0 set build_components { core init timer + drivers/acpi + drivers/platform + app/pci_decode drivers/framebuffer/intel/pc test/framebuffer server/report_rom server/vfs server/fs_rom - lib/vfs/import + lib/vfs_import } append_if $use_gpu build_components { drivers/gpu/intel } append_if $use_top build_components { app/top } -source ${genode_dir}/repos/base/run/platform_drv.inc -append_platform_drv_build_components - build $build_components create_boot_directory @@ -46,28 +58,96 @@ append config { - } + -append_platform_drv_config + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -append config { - - - - - - + + + @@ -206,13 +286,16 @@ install_config $config set boot_modules { core ld.lib.so init timer pc_intel_fb_drv intel_fb_controller test-framebuffer report_rom fs_rom vfs vfs.lib.so vfs_import.lib.so + platform_drv acpi_drv pci_decode } append_if $use_gpu boot_modules { intel_gpu_drv } append_if $use_top boot_modules { top } -append_platform_drv_boot_modules - build_boot_image $boot_modules -run_genode_until forever +if { [get_cmd_switch --autopilot] } { + run_genode_until {\[init -\> init_dynamic -\> intel_fb_drv\] HDMI-A-2: enable.*} 30 +} else { + run_genode_until forever +} diff --git a/repos/pc/run/wifi.run b/repos/pc/run/wifi.run index 2955fce6cf..939416b98d 100644 --- a/repos/pc/run/wifi.run +++ b/repos/pc/run/wifi.run @@ -65,20 +65,20 @@ assert_spec x86 set build_components { core init timer + app/pci_decode + drivers/acpi + drivers/platform drivers/rtc drivers/wifi/pc server/report_rom server/dynamic_rom server/nic_router test/lwip/http_srv - lib/vfs/wifi - lib/vfs/jitterentropy - lib/vfs/lwip + lib/vfs_wifi + lib/vfs_jitterentropy + lib/vfs_lwip } -source ${genode_dir}/repos/base/run/platform_drv.inc -append_platform_drv_build_components - build $build_components create_boot_directory @@ -108,6 +108,74 @@ append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -227,11 +295,6 @@ append config { -} - -append_platform_drv_config - -append config { } @@ -267,15 +330,13 @@ set boot_modules { wpa_driver_nl80211.lib.so wpa_supplicant.lib.so pc_wifi_drv wifi.lib.so vfs_wifi.lib.so nic_router - + platform_drv acpi_drv pci_decode test-lwip_httpsrv vfs_lwip.lib.so } append boot_modules $firmware_modules -append_platform_drv_boot_modules - build_boot_image $boot_modules run_genode_until forever diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/README b/repos/pc/src/drivers/framebuffer/intel/pc/README index 0a6212b01f..cad8de7123 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/README +++ b/repos/pc/src/drivers/framebuffer/intel/pc/README @@ -4,14 +4,17 @@ Default behaviour ~~~~~~~~~~~~~~~~~ When no configuration is provided to the driver, it will switch on all devices -connected to the graphics card. It will use the best resolution as +connected to the graphics card. It will use the highest resolution as provided by the BIOS or EDID information from the display devices for each connector. The virtual resolution delivered to the client is the maximum in -width and height of the different connectors. The framebuffer memory is -directly exported to the client of the driver. When newly connected devices are -detected by the hardware, the new connectors are enabled, probed, and again the -'best' resolution will be chosen for the device. Nevertheless, it won't have an -effect on the virtual resolution. +width and height of the active connectors. + +When newly connected devices are detected by the hardware, the new connectors +are enabled, probed, and again the highest resolution across all active +connectors will be chosen. By default, the current config of the driver will +be re-read and re-applied. This behaviour can be disabled by + +! Configuration ~~~~~~~~~~~~~ @@ -20,9 +23,14 @@ Each of the connectors can be configured explicitly in terms of resolution and whether it should be enabled or not. This looks like the following: ! -! +! +! ! +The resolution can be configured exactly by the reported mode_id or by +the width/height/hz attributes. In the latter case the driver will take the +first matching mode out of multiple matching modes potentially. + When the configuration changes during runtime, the driver will adapt to it. In this case, it will also change the current virtual resolution to the maximum of the configured resolutions in width and height, and it will inform its client @@ -47,12 +55,18 @@ in the configuration as follows: The exported report has the following format: ! -! -! +! +! +! ... +! +! +! +! +! +! ! ... ! ! -! ! The brightness attribute is reported only if the hardware supports it. diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/dummies.c b/repos/pc/src/drivers/framebuffer/intel/pc/dummies.c index 30081dc76d..2dcdda40a9 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/dummies.c +++ b/repos/pc/src/drivers/framebuffer/intel/pc/dummies.c @@ -40,7 +40,6 @@ const guid_t pci_acpi_dsm_guid = void register_syscore_ops(struct syscore_ops * ops) { - wait_bit_init(); lx_emul_trace(__func__); } @@ -527,3 +526,54 @@ void intel_dsb_commit(const struct intel_crtc_state *crtc_state) { lx_emul_trace(__func__); } + + +#include + +struct smp_ops smp_ops = { }; +EXPORT_SYMBOL_GPL(smp_ops); + + +#include + +u32 prandom_u32(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +int wbinvd_on_all_cpus(void) +{ + lx_emul_trace(__func__); + return 0; +} + + +void srcu_drive_gp(struct work_struct *wp); +void srcu_drive_gp(struct work_struct *wp) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn, + int where, u8 *val) +{ + lx_emul_trace_and_stop(__func__); +} + + +int pci_bus_read_config_word(struct pci_bus *bus, unsigned int devfn, + int where, u16 *val) +{ + lx_emul_trace_and_stop(__func__); +} + + +int pci_bus_write_config_byte(struct pci_bus *bus, unsigned int devfn, + int where, u8 val) +{ + lx_emul_trace_and_stop(__func__); +} diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc b/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc index 243f0a6501..0baedcea44 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc +++ b/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc @@ -29,3 +29,22 @@ void emul_free_shmem_file_buffer(void *addr) { Lx_kit::env().memory.free_buffer(addr); } + + +unsigned short emul_intel_gmch_control_reg() +{ + using namespace Genode; + + unsigned short ret = 0; + Lx_kit::env().devices.with_xml([&] (Xml_node node) { + node.for_each_sub_node("device", [&] (Xml_node node) { + node.for_each_sub_node("pci-config", [&] (Xml_node node) { + unsigned short gmch = + node.attribute_value("intel_gmch_control", 0U); + if (gmch) ret = gmch; + }); + }); + }); + + return ret; +} diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/generated_dummies.c b/repos/pc/src/drivers/framebuffer/intel/pc/generated_dummies.c index 888c36eb27..3b7ca3eadb 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/generated_dummies.c +++ b/repos/pc/src/drivers/framebuffer/intel/pc/generated_dummies.c @@ -1,7 +1,7 @@ /* * \brief Dummy definitions of Linux Kernel functions * \author Automatically generated file - do no edit - * \date 2022-05-06 + * \date 2022-07-28 */ #include @@ -468,30 +468,6 @@ int drm_noop(struct drm_device * dev,void * data,struct drm_file * file_priv) } -#include - -ssize_t drm_scdc_read(struct i2c_adapter * adapter,u8 offset,void * buffer,size_t size) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -bool drm_scdc_set_high_tmds_clock_ratio(struct i2c_adapter * adapter,bool set) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -bool drm_scdc_set_scrambling(struct i2c_adapter * adapter,bool enable) -{ - lx_emul_trace_and_stop(__func__); -} - - #include void drm_writeback_cleanup_job(struct drm_writeback_job * job) @@ -620,22 +596,6 @@ int get_option(char ** str,int * pint) } -#include - -u32 get_random_u32(void) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -u64 get_random_u64(void) -{ - lx_emul_trace_and_stop(__func__); -} - - #include s32 i2c_smbus_read_block_data(const struct i2c_client * client,u8 command,u8 * values) @@ -1533,14 +1493,6 @@ void mark_page_accessed(struct page * page) } -#include - -unsigned long long memparse(const char * ptr,char ** retptr) -{ - lx_emul_trace_and_stop(__func__); -} - - #include void memunmap(void * addr) @@ -1654,7 +1606,7 @@ enum reboot_mode panic_reboot_mode; #include -void pci_assign_unassigned_bridge_resources(struct pci_dev * bridge) +int pci_dev_present(const struct pci_device_id * ids) { lx_emul_trace_and_stop(__func__); } @@ -1662,14 +1614,7 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev * bridge) #include -void pci_assign_unassigned_bus_resources(struct pci_bus * bus) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern unsigned long pci_cardbus_resource_alignment(struct resource * res); -unsigned long pci_cardbus_resource_alignment(struct resource * res) +void pci_disable_device(struct pci_dev * dev) { lx_emul_trace_and_stop(__func__); } @@ -1677,11 +1622,7 @@ unsigned long pci_cardbus_resource_alignment(struct resource * res) #include -unsigned int pci_flags; - - -extern int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout); -int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout) +int pci_read_config_byte(const struct pci_dev * dev,int where,u8 * val) { lx_emul_trace_and_stop(__func__); } @@ -1689,28 +1630,7 @@ int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout) #include -int pci_mmap_resource_range(struct pci_dev * pdev,int bar,struct vm_area_struct * vma,enum pci_mmap_state mmap_state,int write_combine) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void __init pci_realloc_get_opt(char * str); -void __init pci_realloc_get_opt(char * str) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pci_restore_vc_state(struct pci_dev * dev); -void pci_restore_vc_state(struct pci_dev * dev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern int pci_save_vc_state(struct pci_dev * dev); -int pci_save_vc_state(struct pci_dev * dev) +int pci_save_state(struct pci_dev * dev) { lx_emul_trace_and_stop(__func__); } @@ -1718,42 +1638,23 @@ int pci_save_vc_state(struct pci_dev * dev) #include -void pci_stop_and_remove_bus_device_locked(struct pci_dev * dev) +int pci_set_power_state(struct pci_dev * dev,pci_power_t state) { lx_emul_trace_and_stop(__func__); } -extern void pci_vpd_release(struct pci_dev * dev); -void pci_vpd_release(struct pci_dev * dev) +#include + +void pci_unmap_rom(struct pci_dev * pdev,void __iomem * rom) { lx_emul_trace_and_stop(__func__); } -extern unsigned int pcibios_assign_all_busses(void); -unsigned int pcibios_assign_all_busses(void) -{ - lx_emul_trace_and_stop(__func__); -} +#include - -extern void pcie_aspm_init_link_state(struct pci_dev * pdev); -void pcie_aspm_init_link_state(struct pci_dev * pdev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pcie_aspm_pm_state_change(struct pci_dev * pdev); -void pcie_aspm_pm_state_change(struct pci_dev * pdev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pcie_aspm_powersave_config_link(struct pci_dev * pdev); -void pcie_aspm_powersave_config_link(struct pci_dev * pdev) +int pci_write_config_byte(const struct pci_dev * dev,int where,u8 val) { lx_emul_trace_and_stop(__func__); } @@ -1797,14 +1698,6 @@ void put_pid(struct pid * pid) } -#include - -int raw_pci_read(unsigned int domain,unsigned int bus,unsigned int devfn,int reg,int len,u32 * val) -{ - lx_emul_trace_and_stop(__func__); -} - - #include enum reboot_mode reboot_mode; @@ -1907,15 +1800,7 @@ void * skb_put(struct sk_buff * skb,unsigned int len) #include -int smp_call_function_single(int cpu,void (* func)(void * info),void * info,int wait) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -void srcu_drive_gp(struct work_struct * wp) +int smp_call_function_single(int cpu,smp_call_func_t func,void * info,int wait) { lx_emul_trace_and_stop(__func__); } @@ -1947,14 +1832,6 @@ void synchronize_rcu(void) } -#include - -void synchronize_srcu(struct srcu_struct * ssp) -{ - lx_emul_trace_and_stop(__func__); -} - - #include int task_work_add(struct task_struct * task,struct callback_head * work,enum task_work_notify_mode notify) diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.c b/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.c index afb1f8ec99..56b6b89c96 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.c +++ b/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.c @@ -36,7 +36,6 @@ int acpi_disabled = 0; void intel_wopcm_init_early(struct intel_wopcm * wopcm) { - wait_bit_init(); lx_emul_trace(__func__); } @@ -215,6 +214,9 @@ void intel_gt_init_early(struct intel_gt * gt, struct drm_i915_private * i915) init_llist_head(>->watchdog.list); lx_emul_trace(__func__); + + /* disable panel self refresh (required for FUJITSU S937/S938) */ + i915->params.enable_psr = 0; } @@ -242,7 +244,7 @@ void * memremap(resource_size_t offset, size_t size, unsigned long flags) { lx_emul_trace(__func__); - return NULL; + return intel_io_mem_map(offset, size); } @@ -259,3 +261,14 @@ void intel_vgpu_detect(struct drm_i915_private * dev_priv) printk("disabling PPGTT to avoid GPU code paths\n"); } + + +/* + * taken from src/lib/wifi/lx_emul.c + */ +void kvfree_call_rcu(struct rcu_head * head,rcu_callback_t func) +{ + void *ptr = (void *) head - (unsigned long) func; + kvfree(ptr); +} + diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.h b/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.h index b6444c51c0..aa6eb2c74e 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.h +++ b/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.h @@ -28,20 +28,16 @@ struct dma_fence_work_ops; void lx_emul_time_udelay(unsigned long usec); -/* shadow/asm/io.h */ -void lx_emul_io_port_outb(unsigned char value, unsigned short port); -void lx_emul_io_port_outw(unsigned short value, unsigned short port); -void lx_emul_io_port_outl(unsigned int value, unsigned short port); - -unsigned char lx_emul_io_port_inb(unsigned short port); -unsigned short lx_emul_io_port_inw(unsigned short port); -unsigned int lx_emul_io_port_inl(unsigned short port); - void *emul_alloc_shmem_file_buffer(unsigned long); +void * intel_io_mem_map(unsigned long offset, unsigned long size); #include "lx_i915.h" +unsigned short emul_intel_gmch_control_reg(void); + +enum { OPREGION_PSEUDO_PHYS_ADDR = 0xffffefff }; + #ifdef __cplusplus } #endif diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/lx_user.c b/repos/pc/src/drivers/framebuffer/intel/pc/lx_user.c index 9799e7e1bb..ab8864a6a5 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/lx_user.c +++ b/repos/pc/src/drivers/framebuffer/intel/pc/lx_user.c @@ -50,7 +50,25 @@ static void preferred_mode(struct drm_display_mode *prefer) /* check for connector configuration on Genode side */ lx_emul_i915_connector_config(connector->name, &conf_mode); - if (!conf_mode.enabled || !conf_mode.width || !conf_mode.height) + if (!conf_mode.enabled) + continue; + + if (conf_mode.id) { + unsigned mode_id = 0; + list_for_each_entry(mode, &connector->modes, head) { + mode_id ++; + + if (!mode || conf_mode.id != mode_id) + continue; + + conf_mode.width = mode->hdisplay; + conf_mode.height = mode->vdisplay; + + break; + } + } + + if (!conf_mode.width || !conf_mode.height) continue; if (conf_mode.width * conf_mode.height > prefer->hdisplay * prefer->vdisplay) { @@ -154,6 +172,10 @@ static bool reconfigure(void * data) /* data is adjusted if virtual resolution is not same size as physical fb */ report_fb_info = *i915_fb()->fbdev; + if (mode_preferred.hdisplay && mode_preferred.vdisplay) { + report_fb_info.var.xres_virtual = mode_preferred.hdisplay; + report_fb_info.var.yres_virtual = mode_preferred.vdisplay; + } drm_client_for_each_modeset(mode_set, &(i915_fb()->client)) { struct drm_display_mode *mode_match = NULL; @@ -182,7 +204,10 @@ static bool reconfigure(void * data) continue; /* use mode id if configured and matches exactly */ - if (conf_mode.id && (conf_mode.id == mode_id)) { + if (conf_mode.id) { + if (conf_mode.id != mode_id) + continue; + mode_match = mode; break; } @@ -225,16 +250,9 @@ static bool reconfigure(void * data) if (!mode_match) { /* use first mode */ mode_match = mode; - /* set up preferred resolution as virtual, if nothing is enforced */ - if (!conf_mode.preferred && - mode_preferred.hdisplay && - mode_preferred.vdisplay) { - conf_mode.preferred = 1; - conf_mode.width = mode_preferred.hdisplay; - conf_mode.height = mode_preferred.vdisplay; - } - no_match = mode->hdisplay != conf_mode.width || - mode->vdisplay != conf_mode.height; + + if (conf_mode.enabled) + no_match = true; } if (mode_match != mode) @@ -267,12 +285,6 @@ static bool reconfigure(void * data) retry = true; else { report_fb = true; - - /* report forced resolution */ - if (conf_mode.preferred) { - report_fb_info.var.xres_virtual = conf_mode.width; - report_fb_info.var.yres_virtual = conf_mode.height; - } } } diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/main.cc b/repos/pc/src/drivers/framebuffer/intel/pc/main.cc index 02f427390e..3bbc4f0482 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/main.cc +++ b/repos/pc/src/drivers/framebuffer/intel/pc/main.cc @@ -123,6 +123,18 @@ struct Framebuffer::Driver timer.sigh(timer_handler); timer.trigger_periodic(20*1000); } + + void report_updated() + { + bool apply_config = true; + + if (config.valid()) + apply_config = config.xml().attribute_value("apply_on_hotplug", apply_config); + + /* trigger re-read config on connector change */ + if (apply_config) + Genode::Signal_transmitter(config_handler).submit(); + } }; @@ -270,8 +282,7 @@ void lx_emul_i915_report_connector(void * lx_data, void * genode_xml, lx_emul_i915_iterate_modes(lx_data, &xml); }); - /* re-read config on connector change */ - Genode::Signal_transmitter(driver(Lx_kit::env().env).config_handler).submit(); + driver(Lx_kit::env().env).report_updated(); } diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/misc.cc b/repos/pc/src/drivers/framebuffer/intel/pc/misc.cc deleted file mode 100644 index 73f6e67174..0000000000 --- a/repos/pc/src/drivers/framebuffer/intel/pc/misc.cc +++ /dev/null @@ -1,20 +0,0 @@ -/* - * \brief Misc - * \author Josef Soentgen - * \date 2022-01-20 - */ - -/* - * Copyright (C) 2022 Genode Labs GmbH - * - * This file is distributed under the terms of the GNU General Public License - * version 2. - */ - -/* Genode includes */ -#include - -extern "C" void lx_backtrace(void) -{ - Genode::backtrace(); -} diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/opregion_io_mem.cc b/repos/pc/src/drivers/framebuffer/intel/pc/opregion_io_mem.cc new file mode 100644 index 0000000000..3271d51f16 --- /dev/null +++ b/repos/pc/src/drivers/framebuffer/intel/pc/opregion_io_mem.cc @@ -0,0 +1,75 @@ +/* + * \brief Linux emulation environment specific to this driver - Intel opregion + * \author Alexander Boettcher + * \date 2022-01-21 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + + +#include +#include +#include +#include + +#include +#include +#include + +#include + +extern "C" void * intel_io_mem_map(unsigned long const phys, + unsigned long const size) +{ + using namespace Genode; + + static Constructible rom_opregion { }; + static addr_t opregion_start = 0; + static addr_t opregion_size = 0; + + if (!rom_opregion.constructed()) { + try { + rom_opregion.construct(Lx_kit::env().env, "intel_opregion"); + + Dataspace_client ds_client(rom_opregion->cap()); + + auto mem_local = rom_opregion->local_addr(); + opregion_start = *(addr_t*)(mem_local + ds_client.size() - sizeof(addr_t) * 2); + opregion_size = *(addr_t*)(mem_local + ds_client.size() - sizeof(addr_t)); + + if (opregion_size > ds_client.size()) + opregion_size = ds_client.size(); + } catch (...) { + error("Intel opregion ROM lookup failed"); + if (rom_opregion.constructed()) + rom_opregion.destruct(); + return nullptr; + } + } + + /* + * we have to substract the pseudo physical address + * we returned when reading the ASLS from config space + */ + addr_t offset = phys - OPREGION_PSEUDO_PHYS_ADDR; + if ((offset + size) <= opregion_size) { + + try { + auto ptr = ((addr_t)rom_opregion->local_addr()) + + offset + (opregion_start & 0xffful); + return (void *)ptr; + } catch (...) { + error("Intel opregion lookup failed"); + return nullptr; + } + } + + warning("Unknown memremap range ", Hex_range(phys, size)); + + return nullptr; +} diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/pci.c b/repos/pc/src/drivers/framebuffer/intel/pc/pci.c new file mode 100644 index 0000000000..883e1c0795 --- /dev/null +++ b/repos/pc/src/drivers/framebuffer/intel/pc/pci.c @@ -0,0 +1,140 @@ +/* + * \brief Additional PCI functions needed by Intel graphics driver + * \author Stefan Kalkowski + * \author Josef Soentgen + * \date 2022-07-27 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include +#include + +#include +#include +#include <../drivers/gpu/drm/i915/i915_reg.h> +#undef GFX_FLSH_CNTL /* suppress warning of double define */ +#include <../drivers/char/agp/intel-agp.h> + + +unsigned long pci_mem_start = 0xaeedbabe; + + +int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, + resource_size_t size, resource_size_t align, + resource_size_t min, unsigned long type_mask, + resource_size_t (*alignf)(void *, + const struct resource *, + resource_size_t, + resource_size_t), + void *alignf_data) +{ + return -1; +} + + +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) +{ + struct resource *r; + unsigned long phys_addr; + unsigned long size; + + if (!dev || bar > 5) { + printk("%s:%d: invalid request for dev: %p bar: %d\n", + __func__, __LINE__, dev, bar); + return NULL; + } + + printk("pci_iomap: request for dev: %s bar: %d\n", dev_name(&dev->dev), bar); + + r = &dev->resource[bar]; + + phys_addr = r->start; + size = r->end - r->start; + + if (!phys_addr || !size) + return NULL; + + return lx_emul_io_mem_map(phys_addr, size); +} + + +void __iomem * pci_map_rom(struct pci_dev * pdev,size_t * size) +{ + /* + * Needed for VBT access which we do not allow + */ + return NULL; +} + + +int pci_read_config_word(const struct pci_dev * dev, int where, u16 *val) +{ + switch (where) { + /* Intel graphics and memory controller hub control register */ + /* I830_GMCH_CTRL is identical to INTEL_GMCH_CTRL */ + case SNB_GMCH_CTRL: + case INTEL_GMCH_CTRL: + *val = emul_intel_gmch_control_reg(); + return 0; + case SWSCI: /* intel_fb: software smi sci */ + *val = 0; + return 0; + }; + + printk("%s: %s %d %d\n", __func__, dev_name(&dev->dev), dev->devfn, where); + lx_emul_trace_and_stop(__func__); +} + + +int pci_read_config_dword(const struct pci_dev * dev, int where, u32 *val) +{ + switch (where) { + case MCHBAR_I915: + case MCHBAR_I965: + *val = 0x1; /* return ENABLE bit being set */ + return 0; + case I965_IFPADDR: /* intel host bridge flush page (lower) */ + case I965_IFPADDR + 4: /* intel host bridge flush page (higher) */ + *val = 0; + return 0; + case ASLS: + /* + * we just use a physical address as token here, + * hopefully it never crashes with other I/O memory addresses + */ + *val = OPREGION_PSEUDO_PHYS_ADDR; + return 0; + }; + + lx_emul_trace_and_stop(__func__); +} + + +int pci_write_config_word(const struct pci_dev * dev, int where, u16 val) +{ + switch (where) { + case SWSCI: /* intel_fb: software smi sci */ + /* just ignore */ + return 0; + }; + lx_emul_trace_and_stop(__func__); +} + + +int pci_write_config_dword(const struct pci_dev * dev, int where, u32 val) +{ + switch (where) { + case I965_IFPADDR: /* intel host bridge flush page (lower) */ + case I965_IFPADDR + 4: /* intel host bridge flush page (higher) */ + /* just ignore */ + return 0; + }; + lx_emul_trace_and_stop(__func__); +} diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/shadow/asm/vdso/processor.h b/repos/pc/src/drivers/framebuffer/intel/pc/shadow/asm/vdso/processor.h index db54ee6637..08414f0c1a 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/shadow/asm/vdso/processor.h +++ b/repos/pc/src/drivers/framebuffer/intel/pc/shadow/asm/vdso/processor.h @@ -19,9 +19,6 @@ #ifndef __ASSEMBLY__ #include -#include - -extern u64 jiffies_64; static __always_inline void rep_nop(void) @@ -33,8 +30,7 @@ static __always_inline void rep_nop(void) static __always_inline void cpu_relax(void) { /* break busy loop of slchi() in drivers/i2c/algos/i2c-algo-bit.c */ - u64 const us = jiffies_to_usecs(1); - usleep_range(us, us); + __udelay(100); } #endif /* __ASSEMBLY__ */ diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_32/source.list b/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_32/source.list index eb5631008a..c600d394ae 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_32/source.list +++ b/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_32/source.list @@ -1,6 +1,4 @@ -arch/x86/lib/delay.c arch/x86/lib/hweight.S -arch/x86/pci/legacy.c arch/x86/platform/intel/iosf_mbi.c drivers/base/bus.c drivers/base/class.c @@ -61,6 +59,7 @@ drivers/gpu/drm/drm_print.c drivers/gpu/drm/drm_probe_helper.c drivers/gpu/drm/drm_property.c drivers/gpu/drm/drm_rect.c +drivers/gpu/drm/drm_scdc_helper.c drivers/gpu/drm/drm_syncobj.c drivers/gpu/drm/drm_sysfs.c drivers/gpu/drm/drm_vblank.c @@ -184,19 +183,7 @@ drivers/i2c/algos/i2c-algo-bit.c drivers/i2c/i2c-boardinfo.c drivers/i2c/i2c-core-acpi.c drivers/i2c/i2c-core-base.c -drivers/pci/access.c -drivers/pci/bus.c -drivers/pci/host-bridge.c -drivers/pci/msi.c drivers/pci/pci-driver.c -drivers/pci/pci-label.c -drivers/pci/pci-sysfs.c -drivers/pci/pci.c -drivers/pci/probe.c -drivers/pci/rom.c -drivers/pci/search.c -drivers/pci/setup-res.c -drivers/pci/slot.c drivers/video/backlight/backlight.c drivers/video/fbdev/core/fb_notify.c drivers/video/fbdev/core/fbcmap.c @@ -223,12 +210,16 @@ kernel/sched/swait.c kernel/sched/wait.c kernel/sched/wait_bit.c kernel/smpboot.c +kernel/softirq.c kernel/time/clockevents.c kernel/time/clocksource.c kernel/time/hrtimer.c kernel/time/jiffies.c kernel/time/ntp.c +kernel/time/tick-broadcast.c kernel/time/tick-common.c +kernel/time/tick-oneshot.c +kernel/time/tick-sched.c kernel/time/time.c kernel/time/timeconv.c kernel/time/timecounter.c @@ -254,7 +245,6 @@ lib/kstrtox.c lib/list_sort.c lib/llist.c lib/math/div64.c -lib/pci_iomap.c lib/radix-tree.c lib/rbtree.c lib/refcount.c diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_32/target.mk b/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_32/target.mk index 6b20840600..d74c56df41 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_32/target.mk +++ b/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_32/target.mk @@ -2,3 +2,4 @@ include $(REP_DIR)/src/drivers/framebuffer/intel/pc/target.inc REQUIRES += 32bit SRC_C += lx_emul/spec/x86_32/atomic64_32.c +SRC_C += lx_emul/shadow/arch/x86/kernel/irq_32.c diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_64/source.list b/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_64/source.list index 2d40e8f3a7..c3f15819b9 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_64/source.list +++ b/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_64/source.list @@ -1,9 +1,7 @@ -arch/x86/lib/delay.c arch/x86/lib/hweight.S arch/x86/lib/memcpy_64.S arch/x86/lib/memmove_64.S arch/x86/lib/memset_64.S -arch/x86/pci/legacy.c arch/x86/platform/intel/iosf_mbi.c drivers/base/bus.c drivers/base/class.c @@ -64,6 +62,7 @@ drivers/gpu/drm/drm_print.c drivers/gpu/drm/drm_probe_helper.c drivers/gpu/drm/drm_property.c drivers/gpu/drm/drm_rect.c +drivers/gpu/drm/drm_scdc_helper.c drivers/gpu/drm/drm_syncobj.c drivers/gpu/drm/drm_sysfs.c drivers/gpu/drm/drm_vblank.c @@ -187,19 +186,7 @@ drivers/i2c/algos/i2c-algo-bit.c drivers/i2c/i2c-boardinfo.c drivers/i2c/i2c-core-acpi.c drivers/i2c/i2c-core-base.c -drivers/pci/access.c -drivers/pci/bus.c -drivers/pci/host-bridge.c -drivers/pci/msi.c drivers/pci/pci-driver.c -drivers/pci/pci-label.c -drivers/pci/pci-sysfs.c -drivers/pci/pci.c -drivers/pci/probe.c -drivers/pci/rom.c -drivers/pci/search.c -drivers/pci/setup-res.c -drivers/pci/slot.c drivers/video/backlight/backlight.c drivers/video/fbdev/core/fb_notify.c drivers/video/fbdev/core/fbcmap.c @@ -226,6 +213,7 @@ kernel/sched/swait.c kernel/sched/wait.c kernel/sched/wait_bit.c kernel/smpboot.c +kernel/softirq.c kernel/time/clockevents.c kernel/time/clocksource.c kernel/time/hrtimer.c @@ -233,6 +221,8 @@ kernel/time/jiffies.c kernel/time/ntp.c kernel/time/tick-broadcast.c kernel/time/tick-common.c +kernel/time/tick-oneshot.c +kernel/time/tick-sched.c kernel/time/time.c kernel/time/timeconv.c kernel/time/timecounter.c @@ -257,7 +247,6 @@ lib/kobject_uevent.c lib/kstrtox.c lib/list_sort.c lib/llist.c -lib/pci_iomap.c lib/radix-tree.c lib/rbtree.c lib/refcount.c diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/target.inc b/repos/pc/src/drivers/framebuffer/intel/pc/target.inc index ef119180c2..e9d62979af 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/target.inc +++ b/repos/pc/src/drivers/framebuffer/intel/pc/target.inc @@ -3,27 +3,27 @@ REQUIRES := x86 REL_PRG_DIR := $(PRG_DIR)/../.. TARGET := pc_intel_fb_drv -LIBS := base pc_lx_emul blit +LIBS := base pc_lx_emul blit jitterentropy INC_DIR += $(REL_PRG_DIR) INC_DIR += $(REL_PRG_DIR)/shadow SRC_CC += main.cc -SRC_CC += misc.cc SRC_CC += emul.cc +SRC_CC += time.cc +SRC_CC += opregion_io_mem.cc SRC_C += dummies.c +SRC_C += pci.c SRC_C += lx_emul.c SRC_C += $(notdir $(wildcard $(REL_PRG_DIR)/generated_dummies.c)) SRC_C += fb.c SRC_C += lx_user.c SRC_C += gem.c -SRC_C += timeout.c SRC_C += lx_emul/common_dummies.c -SRC_C += lx_emul/spec/x86/pci.c SRC_C += lx_emul/shadow/mm/page_alloc.c SRC_C += lx_emul/shadow/drivers/char/random.c -vpath %.c $(REL_PRG_DIR) +vpath %.c $(REL_PRG_DIR) vpath %.cc $(REL_PRG_DIR) vpath %.c $(REP_DIR)/src/lib/pc @@ -48,12 +48,6 @@ CC_OPT_generated_dummies += -include $(LX_SRC_DIR)/drivers/gpu/drm/i915/i915_drv CC_C_OPT += -Wno-unused-label -# -# Original symbol is renamed to __real_* and references to original symbol -# are replaced by __wrap_*. Used to shadow schedule_timeout, see timeout.c -# -LD_OPT += --wrap=schedule_timeout - # # Genode C-API backends # diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/time.cc b/repos/pc/src/drivers/framebuffer/intel/pc/time.cc new file mode 100644 index 0000000000..0f8f40ad69 --- /dev/null +++ b/repos/pc/src/drivers/framebuffer/intel/pc/time.cc @@ -0,0 +1,25 @@ +/* + * \brief Lx_emul udelay function for very short delays + * \author Stefan Kalkowski + * \date 2021-07-10 + */ + +/* + * Copyright (C) 2021 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include + +extern "C" void lx_emul_time_udelay(unsigned long usec); +extern "C" void lx_emul_time_udelay(unsigned long usec) +{ + if (usec > 100) + Genode::error("Cannot delay that long ", usec, " microseconds"); + + unsigned long long start = Lx_kit::env().timer.curr_time().trunc_to_plain_us().value; + while (Lx_kit::env().timer.curr_time().trunc_to_plain_us().value < (start + usec)) { ; } +} diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/timeout.c b/repos/pc/src/drivers/framebuffer/intel/pc/timeout.c deleted file mode 100644 index dec42f6995..0000000000 --- a/repos/pc/src/drivers/framebuffer/intel/pc/timeout.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * \brief Wrapper to update jiffies before invoking schedule_timeout(). - * Schedule_timeout() expects that the jiffie value is current, - * in order to setup the timeouts. Without current jiffies, - * the programmed timeouts are too short, which leads to timeouts - * firing too early. The Intel driver uses this mechanism frequently - * by utilizing wait_queue_timeout*() in order to wait for hardware - * state changes, e.g. connectors hotplug. The schedule_timeout is - * shadowed by the Linker feature '--wrap'. This code can be removed - * as soon as the timeout handling is implemented by lx_emul/lx_kit - * instead of using the original Linux sources of kernel/time/timer.c. - * \author Alexander Boettcher - * \date 2022-04-04 - */ - -/* - * Copyright (C) 2022 Genode Labs GmbH - * - * This file is distributed under the terms of the GNU General Public License - * version 2. - */ - -#include - - -signed long __real_schedule_timeout(signed long timeout); - - -signed long __wrap_schedule_timeout(signed long timeout) -{ - lx_emul_force_jiffies_update(); - return __real_schedule_timeout(timeout); -} diff --git a/repos/pc/src/drivers/platform/pc/main.cc b/repos/pc/src/drivers/platform/pc/main.cc new file mode 100644 index 0000000000..33b8afc3a6 --- /dev/null +++ b/repos/pc/src/drivers/platform/pc/main.cc @@ -0,0 +1,84 @@ +/* + * \brief Platform driver for PC + * \author Stefan Kalkowski + * \date 2022-10-05 + */ + +/* + * Copyright (C) 2022 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. + */ + +#include + +#include + +namespace Driver { struct Main; }; + +struct Driver::Main +{ + Env & _env; + Attached_rom_dataspace _config_rom { _env, "config" }; + Attached_rom_dataspace _acpi_rom { _env, "acpi" }; + Attached_rom_dataspace _system_rom { _env, "system" }; + Common _common { _env, _config_rom }; + Signal_handler
_config_handler { _env.ep(), *this, + &Main::_handle_config }; + Signal_handler
_system_handler { _env.ep(), *this, + &Main::_system_update }; + + void _handle_config(); + void _reset(); + void _system_update(); + + Main(Genode::Env & e) + : _env(e) + { + _config_rom.sigh(_config_handler); + _acpi_rom.sigh(_system_handler); + _system_rom.sigh(_system_handler); + _handle_config(); + _system_update(); + _common.announce_service(); + } +}; + + +void Driver::Main::_handle_config() +{ + _config_rom.update(); + _common.handle_config(_config_rom.xml()); +} + + +void Driver::Main::_reset() +{ + _acpi_rom.update(); + _acpi_rom.xml().with_optional_sub_node("reset", [&] (Xml_node reset) + { + uint16_t const io_port = reset.attribute_value("io_port", 0); + uint8_t const value = reset.attribute_value("value", 0); + + log("trigger reset by writing value ", value, " to I/O port ", Hex(io_port)); + + try { + Io_port_connection reset_port { _env, io_port, 1 }; + reset_port.outb(io_port, value); + } catch (...) { + error("unable to access reset I/O port ", Hex(io_port)); } + }); +} + + +void Driver::Main::_system_update() +{ + _system_rom.update(); + if (_system_rom.xml().attribute_value("state", String<16>()) == "reset") + _reset(); +} + + +void Component::construct(Genode::Env &env) { + static Driver::Main main(env); } diff --git a/repos/pc/src/drivers/platform/pc/target.mk b/repos/pc/src/drivers/platform/pc/target.mk new file mode 100644 index 0000000000..ccc6087f2c --- /dev/null +++ b/repos/pc/src/drivers/platform/pc/target.mk @@ -0,0 +1,4 @@ +TARGET = pc_platform_drv +REQUIRES = x86 + +include $(call select_from_repositories,src/drivers/platform/target.inc) diff --git a/repos/pc/src/drivers/usb_host/pc/dummies.c b/repos/pc/src/drivers/usb_host/pc/dummies.c index 81f7e7dcce..6b4d44448d 100644 --- a/repos/pc/src/drivers/usb_host/pc/dummies.c +++ b/repos/pc/src/drivers/usb_host/pc/dummies.c @@ -82,3 +82,19 @@ int __printk_ratelimit(const char * func) /* suppress */ return 0; } + + +#include + +u32 prandom_u32(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void pci_disable_device(struct pci_dev * dev) +{ + lx_emul_trace(__func__); +} diff --git a/repos/pc/src/drivers/usb_host/pc/generated_dummies.c b/repos/pc/src/drivers/usb_host/pc/generated_dummies.c index aa37090621..c26547801b 100644 --- a/repos/pc/src/drivers/usb_host/pc/generated_dummies.c +++ b/repos/pc/src/drivers/usb_host/pc/generated_dummies.c @@ -1,7 +1,7 @@ /* * \brief Dummy definitions of Linux Kernel functions * \author Automatically generated file - do no edit - * \date 2022-05-06 + * \date 2022-07-29 */ #include @@ -301,14 +301,6 @@ int kobject_uevent_env(struct kobject * kobj,enum kobject_action action,char * e } -#include - -unsigned long long memparse(const char * ptr,char ** retptr) -{ - lx_emul_trace_and_stop(__func__); -} - - #include struct irq_chip no_irq_chip; @@ -348,7 +340,7 @@ int param_set_copystring(const char * val,const struct kernel_param * kp) #include -void pci_assign_unassigned_bridge_resources(struct pci_dev * bridge) +void pci_clear_mwi(struct pci_dev * dev) { lx_emul_trace_and_stop(__func__); } @@ -356,14 +348,7 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev * bridge) #include -void pci_assign_unassigned_bus_resources(struct pci_bus * bus) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern unsigned long pci_cardbus_resource_alignment(struct resource * res); -unsigned long pci_cardbus_resource_alignment(struct resource * res) +struct pci_dev * pci_get_slot(struct pci_bus * bus,unsigned int devfn) { lx_emul_trace_and_stop(__func__); } @@ -371,11 +356,7 @@ unsigned long pci_cardbus_resource_alignment(struct resource * res) #include -unsigned int pci_flags; - - -extern int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout); -int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout) +int pci_set_power_state(struct pci_dev * dev,pci_power_t state) { lx_emul_trace_and_stop(__func__); } @@ -383,71 +364,7 @@ int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout) #include -int pci_mmap_resource_range(struct pci_dev * pdev,int bar,struct vm_area_struct * vma,enum pci_mmap_state mmap_state,int write_combine) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void __init pci_realloc_get_opt(char * str); -void __init pci_realloc_get_opt(char * str) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pci_restore_vc_state(struct pci_dev * dev); -void pci_restore_vc_state(struct pci_dev * dev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern int pci_save_vc_state(struct pci_dev * dev); -int pci_save_vc_state(struct pci_dev * dev) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -void pci_stop_and_remove_bus_device_locked(struct pci_dev * dev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pci_vpd_release(struct pci_dev * dev); -void pci_vpd_release(struct pci_dev * dev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern unsigned int pcibios_assign_all_busses(void); -unsigned int pcibios_assign_all_busses(void) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pcie_aspm_init_link_state(struct pci_dev * pdev); -void pcie_aspm_init_link_state(struct pci_dev * pdev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pcie_aspm_pm_state_change(struct pci_dev * pdev); -void pcie_aspm_pm_state_change(struct pci_dev * pdev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pcie_aspm_powersave_config_link(struct pci_dev * pdev); -void pcie_aspm_powersave_config_link(struct pci_dev * pdev) +int pci_write_config_dword(const struct pci_dev * dev,int where,u32 val) { lx_emul_trace_and_stop(__func__); } @@ -469,14 +386,6 @@ void put_pid(struct pid * pid) } -#include - -int raw_pci_read(unsigned int domain,unsigned int bus,unsigned int devfn,int reg,int len,u32 * val) -{ - lx_emul_trace_and_stop(__func__); -} - - #include bool refcount_dec_not_one(refcount_t * r) @@ -511,15 +420,7 @@ void seq_printf(struct seq_file * m,const char * f,...) #include -int smp_call_function_single(int cpu,void (* func)(void * info),void * info,int wait) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -void srcu_drive_gp(struct work_struct * wp) +int smp_call_function_single(int cpu,smp_call_func_t func,void * info,int wait) { lx_emul_trace_and_stop(__func__); } @@ -538,14 +439,6 @@ int string_escape_mem(const char * src,size_t isz,char * dst,size_t osz,unsigned } -#include - -void synchronize_srcu(struct srcu_struct * ssp) -{ - lx_emul_trace_and_stop(__func__); -} - - #include int task_work_add(struct task_struct * task,struct callback_head * work,enum task_work_notify_mode notify) diff --git a/repos/pc/src/drivers/usb_host/pc/lx_emul.c b/repos/pc/src/drivers/usb_host/pc/lx_emul.c index a9b63c84ac..63c49b4c63 100644 --- a/repos/pc/src/drivers/usb_host/pc/lx_emul.c +++ b/repos/pc/src/drivers/usb_host/pc/lx_emul.c @@ -12,3 +12,76 @@ */ #include +#include + +void __iomem * pci_ioremap_bar(struct pci_dev * pdev, int bar) +{ + struct resource *res = &pdev->resource[bar]; + return ioremap(res->start, resource_size(res)); +} + + +enum { + UHCI_USBLEGSUP = 0xc0, + UHCI_USBRES_INTEL = 0xc4, + EHCI_SERIAL_BUS_RELEASE = 0x60, + EHCI_PORT_WAKE = 0x62, +}; + + +int pci_read_config_byte(const struct pci_dev * dev,int where,u8 * val) +{ + switch (where) { + case EHCI_SERIAL_BUS_RELEASE: + *val = 0x20; + return 0; + }; + lx_emul_trace_and_stop(__func__); +} + + +int pci_read_config_word(const struct pci_dev * dev,int where,u16 * val) +{ + switch (where) { + case PCI_COMMAND: + *val = 0x7; + return 0; + case EHCI_PORT_WAKE: + *val = 0; + return 0; + case UHCI_USBLEGSUP: + /* force the driver to do a full_reset */ + *val = 0xffff; + return 0; + }; + lx_emul_trace_and_stop(__func__); +} + + +int pci_read_config_dword(const struct pci_dev * dev,int where,u32 * val) +{ + *val = 0; + return 0; +} + + +int pci_write_config_byte(const struct pci_dev * dev,int where,u8 val) +{ + switch (where) { + case UHCI_USBRES_INTEL: + /* do nothing */ + return 0; + } + lx_emul_trace_and_stop(__func__); +} + + +int pci_write_config_word(const struct pci_dev * dev,int where,u16 val) +{ + switch (where) { + case UHCI_USBLEGSUP: + /* do nothing */ + return 0; + } + lx_emul_trace_and_stop(__func__); +} diff --git a/repos/pc/src/drivers/usb_host/pc/lx_emul.h b/repos/pc/src/drivers/usb_host/pc/lx_emul.h index fc240b2d77..2b25b75d96 100644 --- a/repos/pc/src/drivers/usb_host/pc/lx_emul.h +++ b/repos/pc/src/drivers/usb_host/pc/lx_emul.h @@ -24,8 +24,6 @@ extern "C" { #endif -void lx_backtrace(void); - void lx_emul_time_udelay(unsigned long usec); #ifdef __cplusplus diff --git a/repos/pc/src/drivers/usb_host/pc/spec/x86_32/source.list b/repos/pc/src/drivers/usb_host/pc/spec/x86_32/source.list index 007dd15d22..510dc028d8 100644 --- a/repos/pc/src/drivers/usb_host/pc/spec/x86_32/source.list +++ b/repos/pc/src/drivers/usb_host/pc/spec/x86_32/source.list @@ -1,6 +1,4 @@ -arch/x86/lib/delay.c arch/x86/lib/hweight.S -arch/x86/pci/legacy.c drivers/base/bus.c drivers/base/class.c drivers/base/component.c @@ -11,18 +9,7 @@ drivers/base/driver.c drivers/base/platform.c drivers/base/property.c drivers/clk/clk-devres.c -drivers/pci/access.c -drivers/pci/bus.c -drivers/pci/host-bridge.c -drivers/pci/msi.c drivers/pci/pci-driver.c -drivers/pci/pci-sysfs.c -drivers/pci/pci.c -drivers/pci/probe.c -drivers/pci/rom.c -drivers/pci/search.c -drivers/pci/setup-res.c -drivers/pci/slot.c drivers/usb/common/common.c drivers/usb/common/debug.c drivers/usb/core/buffer.c @@ -63,6 +50,7 @@ kernel/irq/chip.c kernel/irq/devres.c kernel/irq/handle.c kernel/irq/irqdesc.c +kernel/irq/irqdomain.c kernel/irq/manage.c kernel/irq/resend.c kernel/kthread.c @@ -76,13 +64,18 @@ kernel/sched/clock.c kernel/sched/completion.c kernel/sched/swait.c kernel/sched/wait.c +kernel/sched/wait_bit.c kernel/smpboot.c +kernel/softirq.c kernel/time/clockevents.c kernel/time/clocksource.c kernel/time/hrtimer.c kernel/time/jiffies.c kernel/time/ntp.c +kernel/time/tick-broadcast.c kernel/time/tick-common.c +kernel/time/tick-oneshot.c +kernel/time/tick-sched.c kernel/time/time.c kernel/time/timeconv.c kernel/time/timecounter.c @@ -105,7 +98,6 @@ lib/kobject.c lib/kstrtox.c lib/list_sort.c lib/math/div64.c -lib/pci_iomap.c lib/radix-tree.c lib/rbtree.c lib/scatterlist.c diff --git a/repos/pc/src/drivers/usb_host/pc/spec/x86_32/target.mk b/repos/pc/src/drivers/usb_host/pc/spec/x86_32/target.mk index 998cd5af96..571119e8fb 100644 --- a/repos/pc/src/drivers/usb_host/pc/spec/x86_32/target.mk +++ b/repos/pc/src/drivers/usb_host/pc/spec/x86_32/target.mk @@ -3,3 +3,4 @@ include $(REP_DIR)/src/drivers/usb_host/pc/target.inc REQUIRES += 32bit SRC_C += lx_emul/spec/x86_32/atomic64_32.c +SRC_C += lx_emul/shadow/arch/x86/kernel/irq_32.c diff --git a/repos/pc/src/drivers/usb_host/pc/spec/x86_64/source.list b/repos/pc/src/drivers/usb_host/pc/spec/x86_64/source.list index a8c2cf6b33..bf4158e88b 100644 --- a/repos/pc/src/drivers/usb_host/pc/spec/x86_64/source.list +++ b/repos/pc/src/drivers/usb_host/pc/spec/x86_64/source.list @@ -1,6 +1,4 @@ -arch/x86/lib/delay.c arch/x86/lib/hweight.S -arch/x86/pci/legacy.c drivers/base/bus.c drivers/base/class.c drivers/base/component.c @@ -11,18 +9,7 @@ drivers/base/driver.c drivers/base/platform.c drivers/base/property.c drivers/clk/clk-devres.c -drivers/pci/access.c -drivers/pci/bus.c -drivers/pci/host-bridge.c -drivers/pci/msi.c drivers/pci/pci-driver.c -drivers/pci/pci-sysfs.c -drivers/pci/pci.c -drivers/pci/probe.c -drivers/pci/rom.c -drivers/pci/search.c -drivers/pci/setup-res.c -drivers/pci/slot.c drivers/usb/common/common.c drivers/usb/common/debug.c drivers/usb/core/buffer.c @@ -77,7 +64,9 @@ kernel/sched/clock.c kernel/sched/completion.c kernel/sched/swait.c kernel/sched/wait.c +kernel/sched/wait_bit.c kernel/smpboot.c +kernel/softirq.c kernel/time/clockevents.c kernel/time/clocksource.c kernel/time/hrtimer.c @@ -85,6 +74,8 @@ kernel/time/jiffies.c kernel/time/ntp.c kernel/time/tick-broadcast.c kernel/time/tick-common.c +kernel/time/tick-oneshot.c +kernel/time/tick-sched.c kernel/time/time.c kernel/time/timeconv.c kernel/time/timecounter.c @@ -106,7 +97,6 @@ lib/klist.c lib/kobject.c lib/kstrtox.c lib/list_sort.c -lib/pci_iomap.c lib/radix-tree.c lib/rbtree.c lib/scatterlist.c diff --git a/repos/pc/src/drivers/usb_host/pc/target.inc b/repos/pc/src/drivers/usb_host/pc/target.inc index bdee0a8fb2..d9c11ce49e 100644 --- a/repos/pc/src/drivers/usb_host/pc/target.inc +++ b/repos/pc/src/drivers/usb_host/pc/target.inc @@ -3,19 +3,17 @@ REQUIRES := x86 REL_PRG_DIR := $(PRG_DIR)/../.. TARGET := pc_usb_host_drv -LIBS := base pc_lx_emul +LIBS := base pc_lx_emul jitterentropy INC_DIR += $(REL_PRG_DIR) SRC_CC += main.cc -SRC_CC += misc.cc +SRC_CC += time.cc SRC_CC += lx_emul/shared_dma_buffer.cc SRC_C += dummies.c SRC_C += lx_emul.c SRC_C += $(notdir $(wildcard $(REL_PRG_DIR)/generated_dummies.c)) SRC_C += common_dummies.c -SRC_C += lx_emul/spec/x86/pci.c SRC_C += lx_emul/usb.c -SRC_C += lx_emul/shadow/drivers/char/random.c SRC_C += lx_emul/shadow/lib/kobject_uevent.c vpath %.c $(REP_DIR)/src/lib/pc diff --git a/repos/pc/src/drivers/usb_host/pc/time.cc b/repos/pc/src/drivers/usb_host/pc/time.cc new file mode 100644 index 0000000000..0f8f40ad69 --- /dev/null +++ b/repos/pc/src/drivers/usb_host/pc/time.cc @@ -0,0 +1,25 @@ +/* + * \brief Lx_emul udelay function for very short delays + * \author Stefan Kalkowski + * \date 2021-07-10 + */ + +/* + * Copyright (C) 2021 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include + +extern "C" void lx_emul_time_udelay(unsigned long usec); +extern "C" void lx_emul_time_udelay(unsigned long usec) +{ + if (usec > 100) + Genode::error("Cannot delay that long ", usec, " microseconds"); + + unsigned long long start = Lx_kit::env().timer.curr_time().trunc_to_plain_us().value; + while (Lx_kit::env().timer.curr_time().trunc_to_plain_us().value < (start + usec)) { ; } +} diff --git a/repos/pc/src/drivers/wifi/pc/frontend.h b/repos/pc/src/drivers/wifi/pc/frontend.h index 643b609588..f7d786c91a 100644 --- a/repos/pc/src/drivers/wifi/pc/frontend.h +++ b/repos/pc/src/drivers/wifi/pc/frontend.h @@ -62,6 +62,9 @@ /* declare manually as it is a internal hack^Winterface */ extern void wifi_kick_socketcall(); +extern bool _wifi_get_rfkill(void); +extern bool _wifi_set_rfkill(bool); + namespace Wifi { struct Frontend; @@ -330,7 +333,7 @@ struct Wifi::Frontend /* remaining stuff */ - Msg_buffer _msg { }; + Msg_buffer &_msg; Genode::Blockade _notify_blockade { }; @@ -343,7 +346,7 @@ struct Wifi::Frontend void _handle_rfkill() { - _rfkilled = wifi_get_rfkill(); + _rfkilled = _wifi_get_rfkill(); /* re-enable scan timer */ if (!_rfkilled) { @@ -407,7 +410,7 @@ struct Wifi::Frontend */ if (config.has_attribute("rfkill")) { bool const blocked = config.attribute_value("rfkill", false); - wifi_set_rfkill(blocked); + _wifi_set_rfkill(blocked); /* * In case we get blocked set rfkilled immediately to prevent @@ -1534,9 +1537,10 @@ struct Wifi::Frontend /** * Constructor */ - Frontend(Genode::Env &env) + Frontend(Genode::Env &env, Msg_buffer &msg_buffer) : _ap_allocator(env.ram(), env.rm()), + _msg(msg_buffer), _rfkill_handler(env.ep(), *this, &Wifi::Frontend::_handle_rfkill), _config_rom(env, "wifi_config"), _config_sigh(env.ep(), *this, &Wifi::Frontend::_handle_config_update), @@ -1577,6 +1581,9 @@ struct Wifi::Frontend /* read in list of APs */ _config_update(false); + /* get initial RFKILL state */ + _handle_rfkill(); + /* kick-off initial scanning */ _handle_scan_timer(); } @@ -1619,13 +1626,6 @@ struct Wifi::Frontend * Used by the wpa_supplicant to wait for the front end. */ void block_for_processing() { _notify_lock_lock(); } - - /** - * Return shared memory message buffer - * - * Used for communication between front end and wpa_supplicant. - */ - Msg_buffer &msg_buffer() { return _msg; } }; #endif /* _WIFI_FRONTEND_H_ */ diff --git a/repos/pc/src/drivers/wifi/pc/main.cc b/repos/pc/src/drivers/wifi/pc/main.cc index 75089e190f..4485a5c2dc 100644 --- a/repos/pc/src/drivers/wifi/pc/main.cc +++ b/repos/pc/src/drivers/wifi/pc/main.cc @@ -28,7 +28,7 @@ using namespace Genode; - +static Msg_buffer _wifi_msg_buffer; static Wifi::Frontend *_wifi_frontend = nullptr; @@ -100,14 +100,16 @@ struct Main Main(Genode::Env &env) : env(env) { + _frontend.construct(env, _wifi_msg_buffer); + _wifi_frontend = &*_frontend; + wifi_set_rfkill_sigh(_wifi_frontend->rfkill_sigh()); + _wpa.construct(env, _wpa_startup_blockade); wifi_init(env, _wpa_startup_blockade); } }; -static Main *_main; - /** * Return shared-memory message buffer @@ -116,31 +118,11 @@ static Main *_main; */ void *wifi_get_buffer(void) { - /* - * XXX creating the front end at this point is merely a hack - * to post-pone its creation - */ - if (_wifi_frontend) - return &_wifi_frontend->msg_buffer(); - - Libc::with_libc([&] () { - - if (_main->_frontend.constructed()) - return; - - _main->_frontend.construct(_main->env); - _wifi_frontend = &*_main->_frontend; - wifi_set_rfkill_sigh(_wifi_frontend->rfkill_sigh()); - }); - - return &_wifi_frontend->msg_buffer(); + return &_wifi_msg_buffer; } void Libc::Component::construct(Libc::Env &env) { - Libc::with_libc([&] () { - static Main server(env); - _main = &server; - }); + static Main server(env); } diff --git a/repos/pc/src/include/lx_emul/pci_fixups.h b/repos/pc/src/include/lx_emul/pci_fixups.h deleted file mode 100644 index 860d419eec..0000000000 --- a/repos/pc/src/include/lx_emul/pci_fixups.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * \brief PCI fixup calls to execute - * \author Josef Soentgen - * \date 2022-02-07 - */ - -/* - * Copyright (C) 2022 Genode Labs GmbH - * - * This file is distributed under the terms of the GNU General Public License - * version 2. - */ - -#ifndef _LX_EMUL__PCI_FIXUPS_H_ -#define _LX_EMUL__PCI_FIXUPS_H_ - -static const char * lx_emul_pci_final_fixups[] = { - "__pci_fixup_final_quirk_usb_early_handoff", - "END_OF_PCI_FIXUPS" -}; - -#endif /* _LX_EMUL__PCI_FIXUPS_H_ */ diff --git a/repos/pc/src/lib/pc/lx_emul/common_dummies.c b/repos/pc/src/lib/pc/lx_emul/common_dummies.c index 2d842b2439..d2c0189ffa 100644 --- a/repos/pc/src/lib/pc/lx_emul/common_dummies.c +++ b/repos/pc/src/lib/pc/lx_emul/common_dummies.c @@ -43,16 +43,6 @@ const struct trace_print_flags vmaflag_names[] = { {0,NULL}}; const struct trace_print_flags pageflag_names[] = { {0,NULL}}; -#include - -struct kernel_stat kstat; - -#include - -/* support for arch/x86/lib/delay.c, normally defined in init/main.c */ -unsigned long loops_per_jiffy = (1<<12); - - #include /* @@ -70,11 +60,6 @@ struct cpuinfo_x86 boot_cpu_data = unsigned long init_stack[THREAD_SIZE / sizeof(unsigned long)]; -#include - -unsigned long lpj_fine = 0; - - /* * Generate_dummies.c will otherwise pull in * that clashes with rcutiny.h. @@ -379,3 +364,48 @@ bool pat_enabled(void) lx_emul_trace(__func__); return true; } + + +struct srcu_struct; +extern int __srcu_read_lock(struct srcu_struct * ssp); +int __srcu_read_lock(struct srcu_struct * ssp) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void cpu_hotplug_disable(void) +{ + lx_emul_trace(__func__); +} + + +#include + +void cpu_hotplug_enable(void) +{ + lx_emul_trace(__func__); +} + + +extern void synchronize_srcu(struct srcu_struct * ssp); +void synchronize_srcu(struct srcu_struct * ssp) +{ + lx_emul_trace_and_stop(__func__); +} + + +#ifdef CONFIG_X86_64 +DEFINE_PER_CPU(void *, hardirq_stack_ptr); +#endif +DEFINE_PER_CPU(bool, hardirq_stack_inuse); + + +#include + +DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info); +EXPORT_PER_CPU_SYMBOL(cpu_info); + + diff --git a/repos/pc/src/lib/pc/lx_emul/delay.c b/repos/pc/src/lib/pc/lx_emul/delay.c new file mode 100644 index 0000000000..febbbd9a1e --- /dev/null +++ b/repos/pc/src/lib/pc/lx_emul/delay.c @@ -0,0 +1,68 @@ +/* + * \brief Supplement for emulation for linux/include/asm-generic/delay.h + * \author Josef Soentgen + * \author Alexander Boettcher + * \date 2022-05-05 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + + +#include +#include +#include + +#include + + +void __const_udelay(unsigned long xloops) +{ + unsigned long const usecs = xloops / 0x10C7UL; + __udelay(usecs); +} + + +void __udelay(unsigned long usecs) +{ + /* + * Account for delays summing up to equivalent of 1 jiffie during + * jiffies_64 stays same. When 1 jiffie is reached in sum, + * increase jiffie_64 to break endless loops, seen in + * * intel_fb - cpu_relax(void) emulation used by + * busy loop of slchi() in drivers/i2c/algos/i2c-algo-bit.c + * * wifi_drv - net/wireless/intel/iwlwif* code during error code handling + */ + static uint64_t last_jiffie = 0; + static unsigned long delayed_sum = 0; + + if (jiffies_64 == last_jiffie) { + delayed_sum += usecs; + } else { + last_jiffie = jiffies_64; + delayed_sum = usecs; + } + + if (usecs < 100) + lx_emul_time_udelay(usecs); + else { + unsigned long slept = 0; + while (slept < usecs) { + lx_emul_time_udelay(100); + slept += 100; + } + } + + /* + * When delays sum up to the equivalent of 1 jiffie, + * increase it to break endless loops. + */ + if (delayed_sum >= jiffies_to_usecs(1)) { + jiffies_64 ++; + delayed_sum = 0; + } +} diff --git a/repos/pc/src/lib/pc/lx_emul/dep.list b/repos/pc/src/lib/pc/lx_emul/dep.list index af3a269135..0d4aea3f98 100644 --- a/repos/pc/src/lib/pc/lx_emul/dep.list +++ b/repos/pc/src/lib/pc/lx_emul/dep.list @@ -1,6 +1,7 @@ arch/x86/include/asm/acenv.h arch/x86/include/asm/acpi.h arch/x86/include/asm/alternative.h +arch/x86/include/asm/apic.h arch/x86/include/asm/apicdef.h arch/x86/include/asm/arch_hweight.h arch/x86/include/asm/asm.h @@ -16,6 +17,7 @@ arch/x86/include/asm/cmpxchg.h arch/x86/include/asm/compat.h arch/x86/include/asm/cpu_entry_area.h arch/x86/include/asm/cpufeatures.h +arch/x86/include/asm/cpu.h arch/x86/include/asm/cpumask.h arch/x86/include/asm/delay.h arch/x86/include/asm/desc.h @@ -39,6 +41,7 @@ arch/x86/include/asm/hw_irq.h arch/x86/include/asm/intel_ds.h arch/x86/include/asm/invpcid.h arch/x86/include/asm/irq.h +arch/x86/include/asm/irq_stack.h arch/x86/include/asm/irq_vectors.h arch/x86/include/asm/irq_work.h arch/x86/include/asm/irqdomain.h @@ -91,6 +94,8 @@ arch/x86/include/asm/shmparam.h arch/x86/include/asm/signal.h arch/x86/include/asm/smap.h arch/x86/include/asm/smp.h +arch/x86/include/asm/softirq_stack.h +arch/x86/include/asm/spinlock_types.h arch/x86/include/asm/stacktrace.h arch/x86/include/asm/static_call.h arch/x86/include/asm/string.h @@ -140,6 +145,7 @@ arch/x86/include/uapi/asm/signal.h arch/x86/include/uapi/asm/stat.h arch/x86/include/uapi/asm/swab.h arch/x86/include/uapi/asm/unistd.h +arch/x86/include/uapi/asm/vsyscall.h drivers/base/base.h drivers/base/power/power.h drivers/base/trace.h @@ -186,6 +192,7 @@ include/asm-generic/bug.h include/asm-generic/cacheflush.h include/asm-generic/compat.h include/asm-generic/delay.h +include/asm-generic/div64.h include/asm-generic/early_ioremap.h include/asm-generic/error-injection.h include/asm-generic/fixmap.h @@ -207,10 +214,13 @@ include/asm-generic/pci.h include/asm-generic/pci_iomap.h include/asm-generic/percpu.h include/asm-generic/pgtable-nop4d.h +include/asm-generic/qrwlock_types.h +include/asm-generic/qspinlock_types.h include/asm-generic/resource.h include/asm-generic/rwonce.h include/asm-generic/sections.h include/asm-generic/set_memory.h +include/asm-generic/softirq_stack.h include/asm-generic/termios.h include/asm-generic/tlb.h include/asm-generic/topology.h @@ -230,6 +240,7 @@ include/linux/atomic.h include/linux/audit.h include/linux/auxvec.h include/linux/backing-dev-defs.h +include/linux/bcd.h include/linux/binfmts.h include/linux/bio.h include/linux/bit_spinlock.h @@ -560,6 +571,7 @@ include/linux/ratelimit_types.h include/linux/rbtree.h include/linux/rbtree_augmented.h include/linux/rbtree_latch.h +include/linux/rcu_node_tree.h include/linux/rcu_segcblist.h include/linux/rcu_sync.h include/linux/rculist.h @@ -567,7 +579,7 @@ include/linux/rculist_bl.h include/linux/rculist_nulls.h include/linux/rcupdate.h include/linux/rcupdate_wait.h -include/linux/rcutiny.h +include/linux/rcutree.h include/linux/rcuwait.h include/linux/reboot.h include/linux/refcount.h @@ -579,6 +591,7 @@ include/linux/ring_buffer.h include/linux/rtc.h include/linux/rtnetlink.h include/linux/rwlock.h +include/linux/rwlock_api_smp.h include/linux/rwlock_types.h include/linux/rwsem.h include/linux/sbitmap.h @@ -602,6 +615,7 @@ include/linux/sched/nohz.h include/linux/sched/numa_balancing.h include/linux/sched/prio.h include/linux/sched/rt.h +include/linux/sched/sd_flags.h include/linux/sched/signal.h include/linux/sched/smt.h include/linux/sched/stat.h @@ -640,13 +654,11 @@ include/linux/socket.h include/linux/sockptr.h include/linux/sort.h include/linux/spinlock.h -include/linux/spinlock_api_up.h +include/linux/spinlock_api_smp.h include/linux/spinlock_types.h -include/linux/spinlock_types_up.h -include/linux/spinlock_up.h include/linux/splice.h include/linux/srcu.h -include/linux/srcutiny.h +include/linux/srcutree.h include/linux/stackdepot.h include/linux/stacktrace.h include/linux/stat.h diff --git a/repos/pc/src/lib/pc/lx_emul/shadow/drivers/char/random.c b/repos/pc/src/lib/pc/lx_emul/shadow/drivers/char/random.c index e1e6d9d818..4ba978e2dc 100644 --- a/repos/pc/src/lib/pc/lx_emul/shadow/drivers/char/random.c +++ b/repos/pc/src/lib/pc/lx_emul/shadow/drivers/char/random.c @@ -1,6 +1,7 @@ /* * \brief Replaces drivers/char/random.c * \author Josef Soentgen + * \author Christian Helmuth * \date 2022-04-05 */ @@ -12,17 +13,40 @@ */ #include +#include #include -void get_random_bytes(void * buf,int nbytes) + +void add_input_randomness(unsigned int type,unsigned int code,unsigned int value) { - lx_emul_trace(__func__); + lx_emul_trace(__func__); } -int __must_check get_random_bytes_arch(void * buf,int nbytes) +u32 get_random_u32(void) { - lx_emul_trace(__func__); - return 0; + return lx_emul_random_gen_u32(); +} + + +u64 get_random_u64(void) +{ + return lx_emul_random_gen_u64(); +} + + +int __must_check get_random_bytes_arch(void *buf, int nbytes) +{ + if (nbytes < 0) + return -1; + + lx_emul_random_gen_bytes(buf, nbytes); + return nbytes; +} + + +void get_random_bytes(void *buf, int nbytes) +{ + nbytes = get_random_bytes_arch(buf, nbytes); } diff --git a/repos/pc/src/lib/pc/lx_emul/shadow/kernel/rcu/tiny.c b/repos/pc/src/lib/pc/lx_emul/shadow/kernel/rcu/tiny.c deleted file mode 100644 index 4f8298cf0d..0000000000 --- a/repos/pc/src/lib/pc/lx_emul/shadow/kernel/rcu/tiny.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * \brief Replaces kernel/rcu/tiny.c - * \author Josef Soentgen - * \date 2022-04-05 - */ - -/* - * Copyright (C) 2022 Genode Labs GmbH - * - * This file is distributed under the terms of the GNU General Public License - * version 2. - */ - - -#include - -void call_rcu(struct rcu_head * head,rcu_callback_t func) -{ - /* - * In case func is a small offset kvfree should be - * called directly, see 'rcu_reclaim_tiny'. - */ - enum { KVFREE_RCU_OFFSET = 4096, }; - if (func < (rcu_callback_t)KVFREE_RCU_OFFSET) { - kvfree((void*)head - (unsigned long)func); - return; - } - - func(head); -} diff --git a/repos/pc/src/lib/pc/lx_emul/softirq.c b/repos/pc/src/lib/pc/lx_emul/softirq.c deleted file mode 100644 index 81c1440d98..0000000000 --- a/repos/pc/src/lib/pc/lx_emul/softirq.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * \brief Supplement for emulation of kernel/softirq.c - * \author Josef Soentgen - * \date 2022-04-05 - */ - -/* - * Copyright (C) 2022 Genode Labs GmbH - * - * This file is distributed under the terms of the GNU General Public License - * version 2. - */ - - -#include - -void tasklet_setup(struct tasklet_struct * t, - void (* callback)(struct tasklet_struct *)) -{ - t->next = NULL; - t->state = 0; - atomic_set(&t->count, 0); - t->callback = callback; - t->use_callback = true; - t->data = 0; -} - - -void __tasklet_schedule(struct tasklet_struct * t) -{ - if (test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) - t->callback(t); -} - - -void __tasklet_hi_schedule(struct tasklet_struct * t) -{ - if (test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) - t->callback(t); -} diff --git a/repos/pc/src/lib/vfs/wifi/target.mk b/repos/pc/src/lib/vfs/wifi/target.mk deleted file mode 100644 index b469808922..0000000000 --- a/repos/pc/src/lib/vfs/wifi/target.mk +++ /dev/null @@ -1,3 +0,0 @@ -LIBS := vfs_wifi - -BUILD_ARTIFACTS := diff --git a/repos/pc/src/lib/wifi/dummies.c b/repos/pc/src/lib/wifi/dummies.c index b6907437ae..c77659d25d 100644 --- a/repos/pc/src/lib/wifi/dummies.c +++ b/repos/pc/src/lib/wifi/dummies.c @@ -244,6 +244,39 @@ bool pciehp_is_native(struct pci_dev *bridge) } +void pci_lock_rescan_remove(void) +{ + lx_emul_trace(__func__); +} + + +void pci_unlock_rescan_remove(void) +{ + lx_emul_trace(__func__); +} + + +bool pci_pme_capable(struct pci_dev *dev, pci_power_t state) +{ + lx_emul_trace(__func__); + return false; +} + + +int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val) +{ + lx_emul_trace(__func__); + return -1; +} + + +u16 pci_find_ext_capability(struct pci_dev *dev, int cap) +{ + lx_emul_trace(__func__); + return 0; +} + + #include struct thermal_cooling_device *thermal_cooling_device_register(const char *s, @@ -294,3 +327,15 @@ int net_ratelimit(void) /* suppress */ return 0; } + + +#include + +struct smp_ops smp_ops = { }; +EXPORT_SYMBOL_GPL(smp_ops); + + +void synchronize_rcu_expedited(void) +{ + lx_emul_trace(__func__); +} diff --git a/repos/pc/src/lib/wifi/firmware.cc b/repos/pc/src/lib/wifi/firmware.cc index e454ff7f54..99d0feb098 100644 --- a/repos/pc/src/lib/wifi/firmware.cc +++ b/repos/pc/src/lib/wifi/firmware.cc @@ -45,6 +45,7 @@ Firmware_list fw_list[] = { { "iwlwifi-QuZ-a0-hr-b0-63.ucode", 1334804, nullptr }, { "iwlwifi-QuZ-a0-hr-b0-64.ucode", 1334804, "iwlwifi-QuZ-a0-hr-b0-63.ucode" }, + { "iwlwifi-so-a0-hr-b0-64.ucode", 1427384, nullptr }, }; diff --git a/repos/pc/src/lib/wifi/generated_dummies.c b/repos/pc/src/lib/wifi/generated_dummies.c index ae11f79aed..384f9637a7 100644 --- a/repos/pc/src/lib/wifi/generated_dummies.c +++ b/repos/pc/src/lib/wifi/generated_dummies.c @@ -1,7 +1,7 @@ /* * \brief Dummy definitions of Linux Kernel functions * \author Automatically generated file - do no edit - * \date 2022-05-06 + * \date 2022-07-29 */ #include @@ -283,14 +283,6 @@ int dev_ioctl(struct net * net,unsigned int cmd,struct ifreq * ifr,bool * need_c } -#include - -asmlinkage __visible void do_softirq(void) -{ - lx_emul_trace_and_stop(__func__); -} - - #include void dst_release(struct dst_entry * dst) @@ -562,14 +554,6 @@ void iov_iter_revert(struct iov_iter * i,size_t unroll) } -#include - -void iput(struct inode * inode) -{ - lx_emul_trace_and_stop(__func__); -} - - #include void irq_work_tick(void) @@ -586,11 +570,6 @@ bool is_software_node(const struct fwnode_handle * fwnode) } -#include - -unsigned long volatile __cacheline_aligned_in_smp __jiffy_arch_data jiffies; - - #include struct kobject *kernel_kobj; @@ -660,9 +639,17 @@ int kobject_synth_uevent(struct kobject * kobj,const char * buf,size_t count) } -#include +#include -unsigned long long memparse(const char * ptr,char ** retptr) +void migrate_disable(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void migrate_enable(void) { lx_emul_trace_and_stop(__func__); } @@ -717,63 +704,7 @@ enum reboot_mode panic_reboot_mode; #include -void pci_assign_unassigned_bridge_resources(struct pci_dev * bridge) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -void pci_assign_unassigned_bus_resources(struct pci_bus * bus) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern unsigned long pci_cardbus_resource_alignment(struct resource * res); -unsigned long pci_cardbus_resource_alignment(struct resource * res) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -unsigned int pci_flags; - - -extern int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout); -int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -int pci_mmap_resource_range(struct pci_dev * pdev,int bar,struct vm_area_struct * vma,enum pci_mmap_state mmap_state,int write_combine) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void __init pci_realloc_get_opt(char * str); -void __init pci_realloc_get_opt(char * str) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pci_restore_vc_state(struct pci_dev * dev); -void pci_restore_vc_state(struct pci_dev * dev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern int pci_save_vc_state(struct pci_dev * dev); -int pci_save_vc_state(struct pci_dev * dev) +int pci_read_config_dword(const struct pci_dev * dev,int where,u32 * val) { lx_emul_trace_and_stop(__func__); } @@ -789,42 +720,7 @@ void pci_stop_and_remove_bus_device(struct pci_dev * dev) #include -void pci_stop_and_remove_bus_device_locked(struct pci_dev * dev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pci_vpd_release(struct pci_dev * dev); -void pci_vpd_release(struct pci_dev * dev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern unsigned int pcibios_assign_all_busses(void); -unsigned int pcibios_assign_all_busses(void) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pcie_aspm_init_link_state(struct pci_dev * pdev); -void pcie_aspm_init_link_state(struct pci_dev * pdev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pcie_aspm_pm_state_change(struct pci_dev * pdev); -void pcie_aspm_pm_state_change(struct pci_dev * pdev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pcie_aspm_powersave_config_link(struct pci_dev * pdev); -void pcie_aspm_powersave_config_link(struct pci_dev * pdev) +int pci_write_config_word(const struct pci_dev * dev,int where,u16 val) { lx_emul_trace_and_stop(__func__); } @@ -894,14 +790,6 @@ void put_unused_fd(unsigned int fd) } -#include - -int raw_pci_read(unsigned int domain,unsigned int bus,unsigned int devfn,int reg,int len,u32 * val) -{ - lx_emul_trace_and_stop(__func__); -} - - #include enum reboot_mode reboot_mode; @@ -1117,7 +1005,15 @@ int sk_reuseport_attach_filter(struct sock_fprog * fprog,struct sock * sk) #include -int smp_call_function_single(int cpu,void (* func)(void * info),void * info,int wait) +int smp_call_function_single(int cpu,smp_call_func_t func,void * info,int wait) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int smp_call_function_single_async(int cpu,struct __call_single_data * csd) { lx_emul_trace_and_stop(__func__); } @@ -1131,14 +1027,6 @@ void sock_diag_broadcast_destroy(struct sock * sk) } -#include - -void srcu_drive_gp(struct work_struct * wp) -{ - lx_emul_trace_and_stop(__func__); -} - - #include bool static_key_initialized; @@ -1165,14 +1053,6 @@ int string_escape_mem(const char * src,size_t isz,char * dst,size_t osz,unsigned int suppress_printk; -#include - -void synchronize_srcu(struct srcu_struct * ssp) -{ - lx_emul_trace_and_stop(__func__); -} - - #include int sysfs_rename_dir_ns(struct kobject * kobj,const char * new_name,const void * new_ns) @@ -1197,14 +1077,6 @@ struct callback_head * task_work_cancel(struct task_struct * task,task_work_func } -#include - -void tasklet_kill(struct tasklet_struct * t) -{ - lx_emul_trace_and_stop(__func__); -} - - #include void unblank_screen(void) diff --git a/repos/pc/src/lib/wifi/lx_emul.c b/repos/pc/src/lib/wifi/lx_emul.c index f950e464e1..2f307ae823 100644 --- a/repos/pc/src/lib/wifi/lx_emul.c +++ b/repos/pc/src/lib/wifi/lx_emul.c @@ -18,20 +18,6 @@ #include #include - -#include -#include - -void __const_udelay(unsigned long xloops) -{ - unsigned long usecs = xloops / 0x10C7UL; - if (usecs < 100) - lx_emul_time_udelay(usecs); - else - usleep_range(usecs, usecs * 10); -} - - #include struct kmem_cache * kmem_cache_create_usercopy(const char * name, @@ -118,20 +104,36 @@ struct vfsmount * kern_mount(struct file_system_type * type) struct inode * new_inode_pseudo(struct super_block * sb) { - const struct super_operations *ops = sb->s_op; - struct inode *inode; + const struct super_operations *ops = sb->s_op; + struct inode *inode; - if (ops->alloc_inode) { - inode = ops->alloc_inode(sb); - } + if (ops->alloc_inode) + inode = ops->alloc_inode(sb); if (!inode) return (struct inode*)ERR_PTR(-ENOMEM); + if (!inode->free_inode) + inode->free_inode = ops->free_inode; + return inode; } +void iput(struct inode * inode) +{ + if (!inode) + return; + + if (atomic_read(&inode->i_count) + && !atomic_dec_and_test(&inode->i_count)) + return; + + if (inode->free_inode) + inode->free_inode(inode); +} + + #include #if 0 @@ -300,14 +302,6 @@ int task_work_add(struct task_struct * task,struct callback_head * work,enum tas } -#include - -void __raise_softirq_irqoff(unsigned int nr) -{ - raise_softirq(nr); -} - - #include void kfree_sensitive(const void *p) @@ -439,42 +433,17 @@ void __put_page(struct page * page) } -#include - -u32 get_random_u32(void) -{ - return lx_emul_gen_random_uint(); -} - - -int __must_check get_random_bytes_arch(void *buf, int nbytes) -{ - if (nbytes < 0) - return -1; - - lx_emul_gen_random_bytes(buf, (unsigned long)nbytes); - return 0; -} - - -void get_random_bytes(void *buf, int nbytes) -{ - int const err = get_random_bytes_arch(buf, nbytes); - (void)err; -} - - #include void prandom_bytes(void *buf, size_t bytes) { - lx_emul_gen_random_bytes(buf, bytes); + lx_emul_random_gen_bytes(buf, bytes); } u32 prandom_u32(void) { - return lx_emul_gen_random_uint(); + return lx_emul_random_gen_u32(); } @@ -492,7 +461,7 @@ void *page_frag_alloc_align(struct page_frag_cache *nc, /* see page_frag_free */ if (order > 0) - printk("%s: alloc might leak memory: fragsz: %u PAGE_SIZE: %u " + printk("%s: alloc might leak memory: fragsz: %u PAGE_SIZE: %lu " "order: %u page: %p addr: %p\n", __func__, fragsz, PAGE_SIZE, order, page, page->virtual); return page->virtual; @@ -547,6 +516,10 @@ struct task_struct *rfkill_task_struct_ptr; int lx_emul_rfkill_get_any(void) { + /* + * Since this function may also be called from non EPs + * _do not_ execute _any_ kernel code. + */ return _rfkill_state.rfkilled; } @@ -585,3 +558,49 @@ void rfkill_init(void) rfkill_task_struct_ptr = find_task_by_pid_ns(pid, NULL); } + + +#ifdef CONFIG_X86_32 +s64 arch_atomic64_add_return(s64 i, atomic64_t *v) +{ + v->counter += i; + return v->counter; +} +#endif + + +void kvfree_call_rcu(struct rcu_head * head,rcu_callback_t func) +{ + void *ptr = (void *) head - (unsigned long) func; + kvfree(ptr); +} + + +#include +#include + +int pci_write_config_byte(const struct pci_dev * dev,int where,u8 val) +{ + enum { PCI_CFG_RETRY_TIMEOUT = 0x41 }; + + switch (where) { + /* + * iwlwifi: "We disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state" + */ + case PCI_CFG_RETRY_TIMEOUT: + return 0; + }; + lx_emul_trace_and_stop(__func__); +} + + +int pci_read_config_word(const struct pci_dev * dev,int where,u16 * val) +{ + switch (where) { + case PCI_COMMAND: + *val = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO; + return 0; + }; + lx_emul_trace_and_stop(__func__); +} diff --git a/repos/pc/src/lib/wifi/socket_call.cc b/repos/pc/src/lib/wifi/socket_call.cc index 63eb435763..ae7023af59 100644 --- a/repos/pc/src/lib/wifi/socket_call.cc +++ b/repos/pc/src/lib/wifi/socket_call.cc @@ -237,6 +237,8 @@ class Lx::Socket Genode::Signal_transmitter _sender { }; Genode::Signal_handler _dispatcher; + Genode::Signal_handler _dispatcher_blockade; + struct socket *_sock_poll_table[Wifi::MAX_POLL_SOCKETS] { }; struct socket *_call_socket() @@ -411,11 +413,17 @@ class Lx::Socket Lx_kit::env().scheduler.schedule(); } + void _handle_blockade() + { + _block.up(); + } + public: Socket(Genode::Entrypoint &ep) : - _dispatcher(ep, *this, &Lx::Socket::_handle) + _dispatcher(ep, *this, &Lx::Socket::_handle), + _dispatcher_blockade(ep, *this, &Lx::Socket::_handle_blockade) { _sender.context(_dispatcher); } @@ -448,7 +456,7 @@ class Lx::Socket _call.opcode = Call::NONE; - if (old != Call::NONE) { _block.up(); } + if (old != Call::NONE) { _dispatcher_blockade.local_submit(); } } void submit_and_block() diff --git a/repos/pc/src/lib/wifi/spec/x86_32/source.list b/repos/pc/src/lib/wifi/spec/x86_32/source.list index 04118d7ac1..35f22c35b1 100644 --- a/repos/pc/src/lib/wifi/spec/x86_32/source.list +++ b/repos/pc/src/lib/wifi/spec/x86_32/source.list @@ -1,5 +1,4 @@ arch/x86/lib/hweight.S -arch/x86/pci/legacy.c certs/common.c crypto/acompress.c crypto/aead.c @@ -117,18 +116,7 @@ drivers/net/wireless/intel/iwlwifi/pcie/trans.c drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c drivers/net/wireless/intel/iwlwifi/pcie/tx.c drivers/net/wireless/intel/iwlwifi/queue/tx.c -drivers/pci/access.c -drivers/pci/bus.c -drivers/pci/host-bridge.c -drivers/pci/msi.c drivers/pci/pci-driver.c -drivers/pci/pci-sysfs.c -drivers/pci/pci.c -drivers/pci/probe.c -drivers/pci/rom.c -drivers/pci/search.c -drivers/pci/setup-res.c -drivers/pci/slot.c fs/nls/nls_base.c kernel/irq/chip.c kernel/irq/devres.c @@ -148,13 +136,18 @@ kernel/sched/clock.c kernel/sched/completion.c kernel/sched/swait.c kernel/sched/wait.c +kernel/sched/wait_bit.c kernel/smpboot.c +kernel/softirq.c kernel/time/clockevents.c kernel/time/clocksource.c kernel/time/hrtimer.c kernel/time/jiffies.c kernel/time/ntp.c +kernel/time/tick-broadcast.c kernel/time/tick-common.c +kernel/time/tick-oneshot.c +kernel/time/tick-sched.c kernel/time/time.c kernel/time/timeconv.c kernel/time/timecounter.c @@ -182,7 +175,6 @@ lib/kstrtox.c lib/list_sort.c lib/math/div64.c lib/nlattr.c -lib/pci_iomap.c lib/radix-tree.c lib/rbtree.c lib/refcount.c diff --git a/repos/pc/src/lib/wifi/spec/x86_64/source.list b/repos/pc/src/lib/wifi/spec/x86_64/source.list index 48f993bb68..40f2646615 100644 --- a/repos/pc/src/lib/wifi/spec/x86_64/source.list +++ b/repos/pc/src/lib/wifi/spec/x86_64/source.list @@ -1,5 +1,4 @@ arch/x86/lib/hweight.S -arch/x86/pci/legacy.c certs/common.c crypto/acompress.c crypto/aead.c @@ -117,18 +116,7 @@ drivers/net/wireless/intel/iwlwifi/pcie/trans.c drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c drivers/net/wireless/intel/iwlwifi/pcie/tx.c drivers/net/wireless/intel/iwlwifi/queue/tx.c -drivers/pci/access.c -drivers/pci/bus.c -drivers/pci/host-bridge.c -drivers/pci/msi.c drivers/pci/pci-driver.c -drivers/pci/pci-sysfs.c -drivers/pci/pci.c -drivers/pci/probe.c -drivers/pci/rom.c -drivers/pci/search.c -drivers/pci/setup-res.c -drivers/pci/slot.c fs/nls/nls_base.c kernel/irq/chip.c kernel/irq/devres.c @@ -148,7 +136,9 @@ kernel/sched/clock.c kernel/sched/completion.c kernel/sched/swait.c kernel/sched/wait.c +kernel/sched/wait_bit.c kernel/smpboot.c +kernel/softirq.c kernel/time/clockevents.c kernel/time/clocksource.c kernel/time/hrtimer.c @@ -156,6 +146,8 @@ kernel/time/jiffies.c kernel/time/ntp.c kernel/time/tick-broadcast.c kernel/time/tick-common.c +kernel/time/tick-oneshot.c +kernel/time/tick-sched.c kernel/time/time.c kernel/time/timeconv.c kernel/time/timecounter.c @@ -182,7 +174,6 @@ lib/kobject.c lib/kstrtox.c lib/list_sort.c lib/nlattr.c -lib/pci_iomap.c lib/radix-tree.c lib/rbtree.c lib/refcount.c diff --git a/repos/pc/src/lib/wifi/uplink.c b/repos/pc/src/lib/wifi/uplink.c index 3317c50b63..11434c2b10 100644 --- a/repos/pc/src/lib/wifi/uplink.c +++ b/repos/pc/src/lib/wifi/uplink.c @@ -205,16 +205,24 @@ struct netdev_event_notification }; +/* needed for RFKILL state update */ +extern struct task_struct *rfkill_task_struct_ptr; + + static int uplink_netdev_event(struct notifier_block *this, unsigned long event, void *ptr) { /* * For now we ignore what kind of event occurred and simply - * unblock the uplink task. + * unblock the uplink and rfkill task. */ + if (uplink_task_struct_ptr) lx_emul_task_unblock(uplink_task_struct_ptr); + if (rfkill_task_struct_ptr) + lx_emul_task_unblock(rfkill_task_struct_ptr); + return NOTIFY_DONE; } diff --git a/repos/pc/src/lib/wifi/wlan.cc b/repos/pc/src/lib/wifi/wlan.cc index 0532e15307..bac9c19ae7 100644 --- a/repos/pc/src/lib/wifi/wlan.cc +++ b/repos/pc/src/lib/wifi/wlan.cc @@ -36,19 +36,18 @@ extern "C" void lx_emul_rfkill_switch_all(int blocked); static Genode::Signal_context_capability _rfkill_sigh_cap; -bool wifi_get_rfkill(void) + +bool _wifi_get_rfkill(void) { - if (!rfkill_task_struct_ptr) - return false; - - lx_emul_task_unblock(rfkill_task_struct_ptr); - Lx_kit::env().scheduler.schedule(); - + /* + * It is safe to call this from non EP threads as we + * only query a variable. + */ return lx_emul_rfkill_get_any(); } -void wifi_set_rfkill(bool blocked) +void _wifi_set_rfkill(bool blocked) { if (!rfkill_task_struct_ptr) return; @@ -71,6 +70,12 @@ void wifi_set_rfkill(bool blocked) } +bool wifi_get_rfkill(void) +{ + return _wifi_get_rfkill(); +} + + extern "C" unsigned int wifi_ifindex(void) { /* TODO replace with actual qyery */ diff --git a/repos/pc/src/pc_linux/target.inc b/repos/pc/src/pc_linux/target.inc index 2851bf457b..ea452d107f 100644 --- a/repos/pc/src/pc_linux/target.inc +++ b/repos/pc/src/pc_linux/target.inc @@ -3,7 +3,10 @@ # # kernel fundamentals -LX_ENABLE += TTY SERIAL_EARLYCON SERIAL_OF_PLATFORM PRINTK HAS_IOMEM +LX_ENABLE += TTY SERIAL_EARLYCON SERIAL_OF_PLATFORM PRINTK HAS_IOMEM SMP + +# support disabling ticking during idle +LX_ENABLE += NO_HZ_IDLE # initrd support LX_ENABLE += BINFMT_ELF BINFMT_SCRIPT BLK_DEV_INITRD diff --git a/repos/pc/src/test/driver_time/dummies.c b/repos/pc/src/test/driver_time/dummies.c new file mode 100644 index 0000000000..efb54bd300 --- /dev/null +++ b/repos/pc/src/test/driver_time/dummies.c @@ -0,0 +1,63 @@ +/* + * \brief Dummy definitions of Linux Kernel functions - handled manually + * \author Alexander Boettcher + * \date 2022-07-01 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int ___ratelimit(struct ratelimit_state * rs, const char * func) +{ + /* + * from lib/ratelimit.c: + * " 0 means callbacks will be suppressed. + * 1 means go ahead and do it. " + */ + lx_emul_trace(__func__); + return 1; +} + + +#include + +long io_schedule_timeout(long timeout) +{ + lx_emul_trace_and_stop(__func__); +} + + +void register_syscore_ops(struct syscore_ops * ops) +{ + lx_emul_trace(__func__); +} + + +#include + +u32 prandom_u32(void) +{ + lx_emul_trace_and_stop(__func__); +} diff --git a/repos/pc/src/test/driver_time/generated_dummies.c b/repos/pc/src/test/driver_time/generated_dummies.c new file mode 100644 index 0000000000..04b188f12e --- /dev/null +++ b/repos/pc/src/test/driver_time/generated_dummies.c @@ -0,0 +1,219 @@ +/* + * \brief Dummy definitions of Linux Kernel functions + * \author Automatically generated file - do no edit + * \date 2022-09-27 + */ + +#include + + +#include + +void * PDE_DATA(const struct inode * inode) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const char * __clk_get_name(const struct clk * clk) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void __put_task_struct(struct task_struct * tsk) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void __srcu_read_unlock(struct srcu_struct * ssp,int idx) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +unsigned long _copy_to_user(void __user * to,const void * from,unsigned long n) +{ + lx_emul_trace_and_stop(__func__); +} + + +extern void ack_bad_irq(unsigned int irq); +void ack_bad_irq(unsigned int irq) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int add_uevent_var(struct kobj_uevent_env * env,const char * format,...) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +asmlinkage __visible void dump_stack(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +bool file_ns_capable(const struct file * file,struct user_namespace * ns,int cap) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void fwnode_remove_software_node(struct fwnode_handle * fwnode) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int get_option(char ** str,int * pint) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct pseudo_fs_context * init_pseudo(struct fs_context * fc,unsigned long magic) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +bool initcall_debug; + + +#include + +void io_schedule_finish(int token) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int io_schedule_prepare(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void irq_work_tick(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +bool is_software_node(const struct fwnode_handle * fwnode) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct kobject *kernel_kobj; + + +#include + +void kill_anon_super(struct super_block * sb) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int kobject_synth_uevent(struct kobject * kobj,const char * buf,size_t count) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct irq_chip no_irq_chip; + + +#include + +void note_interrupt(struct irq_desc * desc,irqreturn_t action_ret) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int printk_deferred(const char * fmt,...) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void seq_printf(struct seq_file * m,const char * f,...) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int smp_call_function_single(int cpu,smp_call_func_t func,void * info,int wait) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +bool static_key_initialized; + + +#include + +int string_escape_mem(const char * src,size_t isz,char * dst,size_t osz,unsigned int flags,const char * only) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void wake_q_add_safe(struct wake_q_head * head,struct task_struct * task) +{ + lx_emul_trace_and_stop(__func__); +} + diff --git a/repos/pc/src/test/driver_time/lx_emul.h b/repos/pc/src/test/driver_time/lx_emul.h new file mode 100644 index 0000000000..acee561257 --- /dev/null +++ b/repos/pc/src/test/driver_time/lx_emul.h @@ -0,0 +1,23 @@ +/** + * \brief Dummy definitions of Linux Kernel functions + * \author Alexander Boettcher + * \date 2022-07-01 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +void lx_emul_time_udelay(unsigned long usec); + +#ifdef __cplusplus +} +#endif diff --git a/repos/pc/src/test/driver_time/lx_user.c b/repos/pc/src/test/driver_time/lx_user.c new file mode 100644 index 0000000000..8f69ca0b3a --- /dev/null +++ b/repos/pc/src/test/driver_time/lx_user.c @@ -0,0 +1,270 @@ +/* + * \brief Post kernel activity + * \author Alexander Boettcher + * \date 2022-07-01 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + + +#include + +#include + +#include "i915_drv.h" /* test wait_for() macro */ + +#include + + +extern uint64_t tsc_freq_khz; + + +static int timing_tests(void *); + + +void lx_user_init(void) +{ + kernel_thread(timing_tests, NULL, CLONE_FS | CLONE_FILES); +} + + +struct measure { + uint64_t start; + uint64_t end; + uint64_t diff; +}; + +#define test_timing(fn_test, fn_evaluation) \ +{ \ + struct measure m_lxemul, m_jiffies, m_rdtsc; \ + uint64_t jiffies_in_us; \ +\ + m_lxemul.start = lx_emul_time_counter(); \ + m_jiffies.start = jiffies_64; \ + m_rdtsc.start = rdtsc(); \ +\ + { \ + fn_test \ + } \ +\ + m_rdtsc.end = rdtsc(); \ + m_jiffies.end = jiffies_64; \ + m_lxemul.end = lx_emul_time_counter(); \ +\ + m_rdtsc.diff = m_rdtsc.end - m_rdtsc.start; \ + m_lxemul.diff = m_lxemul.end - m_lxemul.start; \ + m_jiffies.diff = m_jiffies.end - m_jiffies.start; \ +\ + jiffies_in_us = (m_jiffies.diff) * (1000ull * 1000 / CONFIG_HZ); \ +\ + { \ + fn_evaluation \ + } \ +\ +} + +#define test_timing_no_ret(text, fn_test) \ +{ \ + test_timing( \ + fn_test \ + , \ + if (rdtsc_freq_mhz) \ + printk(text \ + " %6llu:%10llu:%10llu:%10llu:%8lld\n", \ + m_jiffies.diff, jiffies_in_us, m_lxemul.diff, \ + m_rdtsc.diff / rdtsc_freq_mhz, \ + jiffies_in_us - m_lxemul.diff); \ + else \ + printk(text \ + " %6llu:%10llu:%10llu:%8lld\n", \ + m_jiffies.diff, jiffies_in_us, m_lxemul.diff, \ + jiffies_in_us - m_lxemul.diff); \ + ); \ + /* trigger to update jiffies to avoid printk time part of next test */ \ + msleep(1); \ +} + + +#define test_timing_with_ret(text, fn_test) \ +{ \ + test_timing( \ + fn_test \ + , \ + if (rdtsc_freq_mhz) \ + printk(text \ + " %6llu:%10llu:%10llu:%10llu:%8lld " \ + "ret=%d%s\n", \ + m_jiffies.diff, jiffies_in_us, m_lxemul.diff, \ + m_rdtsc.diff / rdtsc_freq_mhz, \ + jiffies_in_us - m_lxemul.diff, \ + ret, ret == -ETIMEDOUT ? " (ETIMEDOUT)" : ""); \ + else \ + printk(text \ + " %6llu:%10llu:%10llu:%8lld " \ + "ret=%d%s\n", \ + m_jiffies.diff, jiffies_in_us, m_lxemul.diff, \ + jiffies_in_us - m_lxemul.diff, \ + ret, ret == -ETIMEDOUT ? " (ETIMEDOUT)" : ""); \ + ); \ + /* trigger to update jiffies to avoid printk time part of next test */ \ + msleep(1); \ +} + + +static int timing_tests(void * data) +{ + DEFINE_WAIT(wait); + wait_queue_head_t wq; + int ret; + uint64_t const rdtsc_freq_mhz = tsc_freq_khz / 1000; + + init_waitqueue_head(&wq); + + while (true) { + if (rdtsc_freq_mhz) + printk("test(parameters) -> " + "jiffies:jiff_us:lx_time_us:rdtsc_us:diff_jiff_lx_time " + "tsc=%lluMhz\n", rdtsc_freq_mhz); + else + printk("test(parameters) -> " + "jiffies:jiff_us:lx_time_us:diff_jiff_lx_time\n"); + + test_timing_no_ret ("udelay(40) ->", + udelay(40); + ); + + test_timing_no_ret ("ndelay(4000) ->", + ndelay(4000); + ); + + test_timing_no_ret ("msleep(5000) ->", + msleep(5000); + ); + + test_timing_with_ret("wait_for(cond,10ms) A ->", + add_wait_queue(&wq, &wait); + ret = wait_for((0), 10); + remove_wait_queue(&wq, &wait); + ); + + test_timing_with_ret("wait_for(cond,5ms) B ->", + add_wait_queue(&wq, &wait); + ret = wait_for((0), 5); + remove_wait_queue(&wq, &wait); + ); + + test_timing_with_ret("wait_for(cond,2ms) C ->", + add_wait_queue(&wq, &wait); + ret = wait_for((0), 2); + remove_wait_queue(&wq, &wait); + ); + + test_timing_with_ret("wait_for(cond,10ms) D ->", + add_wait_queue(&wq, &wait); + ret = wait_for((0), 10); + remove_wait_queue(&wq, &wait); + ); + + /* do some work, so that jiffies becomes a bit outdated */ + { + unsigned long long i = 0; + printk("cause some long running load in task ...\n"); + for (i = 0; i < (1ull << 24); i++) { + asm volatile("pause":::"memory"); + } + } + + /* display driver test case -> waking up too early before irq triggered */ + test_timing_with_ret("wait_for(cond,10ms) E ->", + add_wait_queue(&wq, &wait); + ret = wait_for((0), 10); + remove_wait_queue(&wq, &wait); + ); + + test_timing_with_ret("wait_for(cond,5ms) F ->", + add_wait_queue(&wq, &wait); + ret = wait_for((0), 5); + remove_wait_queue(&wq, &wait); + ); + + test_timing_with_ret("wait_for(cond,2ms) G ->", + add_wait_queue(&wq, &wait); + ret = wait_for((0), 2); + remove_wait_queue(&wq, &wait); + ); + + test_timing_with_ret("wait_for(cond,10ms) H ->", + add_wait_queue(&wq, &wait); + ret = wait_for((0), 10); + remove_wait_queue(&wq, &wait); + ); + + test_timing_with_ret("wait_for(cond,5000ms) ->", + add_wait_queue(&wq, &wait); + ret = wait_for((0), 5000); + remove_wait_queue(&wq, &wait); + ); + + test_timing_with_ret("wait_for(cond,4000ms) ->", + add_wait_queue(&wq, &wait); + ret = wait_for((0), 4000); + remove_wait_queue(&wq, &wait); + ); + + test_timing_with_ret("wait_for(cond,3000ms) ->", + add_wait_queue(&wq, &wait); + ret = wait_for((0), 3000); + remove_wait_queue(&wq, &wait); + ); + + test_timing_with_ret("wait_for(cond,2000ms) ->", + add_wait_queue(&wq, &wait); + ret = wait_for((0), 2000); + remove_wait_queue(&wq, &wait); + ); + + test_timing_with_ret("wait_for(cond,500ms) ->", + add_wait_queue(&wq, &wait); + ret = wait_for((0), 500); + remove_wait_queue(&wq, &wait); + ); + + test_timing_with_ret("wait_for(cond,200ms) ->", + add_wait_queue(&wq, &wait); + ret = wait_for((0), 200); + remove_wait_queue(&wq, &wait); + ); + + test_timing_with_ret("wait_for(cond,100ms) ->", + add_wait_queue(&wq, &wait); + ret = wait_for((0), 100); + remove_wait_queue(&wq, &wait); + ); + + test_timing_with_ret("wait_for(cond,50ms) ->", + add_wait_queue(&wq, &wait); + ret = wait_for((0), 50); + remove_wait_queue(&wq, &wait); + ); + + /* audio driver test case -> sleeping too short or long is bad */ + test_timing_no_ret ("usleep_range(20,21) ->", + usleep_range(20, 21); + ); + + test_timing_no_ret ("usleep_range(40,41) ->", + usleep_range(40, 41); + ); + + test_timing_no_ret ("usleep_range(400,410) ->", + usleep_range(400, 410); + ); + } + + return 0; +} diff --git a/repos/pc/src/test/driver_time/main.cc b/repos/pc/src/test/driver_time/main.cc new file mode 100644 index 0000000000..3bcbee4c0b --- /dev/null +++ b/repos/pc/src/test/driver_time/main.cc @@ -0,0 +1,67 @@ +/* + * \brief Linux test driver + * \author Alexander Boettcher + * \date 2022-07-01 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include + +/* emulation includes */ +#include +#include + + +namespace Test { + using namespace Genode; + struct Driver; +} + + +unsigned long long tsc_freq_khz; + + +struct Test::Driver +{ + Env &env; + + Driver(Env &env) : env(env) + { + Lx_kit::initialize(env); + + env.exec_static_constructors(); + + try { + Attached_rom_dataspace info(env, "platform_info"); + tsc_freq_khz = info.xml().sub_node("hardware").sub_node("tsc") + .attribute_value("freq_khz", 0ULL); + } catch (...) { }; + } + + void start() + { + log("--- Test driver started ---"); + + lx_emul_start_kernel(nullptr); + } +}; + + +static Test::Driver &driver(Genode::Env & env) +{ + static Test::Driver driver(env); + return driver; +} + + +void Component::construct(Genode::Env &env) +{ + driver(env).start(); +} diff --git a/repos/pc/src/test/driver_time/source.list b/repos/pc/src/test/driver_time/source.list new file mode 100644 index 0000000000..ef8f09d03b --- /dev/null +++ b/repos/pc/src/test/driver_time/source.list @@ -0,0 +1,79 @@ +drivers/base/bus.c +drivers/base/class.c +drivers/base/component.c +drivers/base/core.c +drivers/base/dd.c +drivers/base/devres.c +drivers/base/driver.c +drivers/base/platform.c +drivers/base/property.c +drivers/pci/pci-driver.c +kernel/async.c +kernel/irq/chip.c +kernel/irq/devres.c +kernel/irq/handle.c +kernel/irq/irqdesc.c +kernel/irq/irqdomain.c +kernel/irq/manage.c +kernel/irq/resend.c +kernel/kthread.c +kernel/locking/mutex.c +kernel/locking/osq_lock.c +kernel/locking/rtmutex.c +kernel/locking/rwsem.c +kernel/notifier.c +kernel/panic.c +kernel/resource.c +kernel/sched/clock.c +kernel/sched/completion.c +kernel/sched/swait.c +kernel/sched/wait.c +kernel/sched/wait_bit.c +kernel/smpboot.c +kernel/softirq.c +kernel/time/clockevents.c +kernel/time/clocksource.c +kernel/time/hrtimer.c +kernel/time/jiffies.c +kernel/time/ntp.c +kernel/time/tick-broadcast.c +kernel/time/tick-common.c +kernel/time/tick-oneshot.c +kernel/time/tick-sched.c +kernel/time/time.c +kernel/time/timeconv.c +kernel/time/timecounter.c +kernel/time/timekeeping.c +kernel/time/timer.c +kernel/time/timer_list.c +kernel/workqueue.c +lib/bitmap.c +lib/crc32.c +lib/ctype.c +lib/debug_locks.c +lib/dec_and_lock.c +lib/find_bit.c +lib/hexdump.c +lib/hweight.c +lib/idr.c +lib/iomap.c +lib/irq_regs.c +lib/kasprintf.c +lib/klist.c +lib/kobject.c +lib/kstrtox.c +lib/list_sort.c +lib/llist.c +lib/radix-tree.c +lib/rbtree.c +lib/refcount.c +lib/scatterlist.c +lib/siphash.c +lib/sort.c +lib/string.c +lib/timerqueue.c +lib/uuid.c +lib/vsprintf.c +lib/xarray.c +mm/mempool.c +mm/util.c diff --git a/repos/pc/src/test/driver_time/target.mk b/repos/pc/src/test/driver_time/target.mk new file mode 100644 index 0000000000..ba7f8e5769 --- /dev/null +++ b/repos/pc/src/test/driver_time/target.mk @@ -0,0 +1,27 @@ +REQUIRES := x86_64 + +TARGET := test-driver_time +LIBS := base pc_lx_emul jitterentropy + +SRC_CC += main.cc time.cc +SRC_C += lx_user.c +SRC_C += dummies.c +SRC_C += generated_dummies.c + +SRC_C += lx_emul/common_dummies.c +SRC_C += lx_emul/shadow/lib/kobject_uevent.c +SRC_C += lx_emul/shadow/drivers/char/random.c + +vpath %.c $(REP_DIR)/src/lib/pc +vpath %.cc $(REP_DIR)/src/lib/pc + +LX_SRC_DIR := $(call select_from_ports,linux)/src/linux +ifeq ($(wildcard $(LX_SRC_DIR)),) +LX_SRC_DIR := $(call select_from_repositories,src/linux) +endif +ifeq ($(wildcard $(LX_SRC_DIR)),) +fail +endif + +INC_DIR += $(PRG_DIR) +INC_DIR += $(LX_SRC_DIR)/drivers/gpu/drm/i915 diff --git a/repos/pc/src/test/driver_time/time.cc b/repos/pc/src/test/driver_time/time.cc new file mode 100644 index 0000000000..0f8f40ad69 --- /dev/null +++ b/repos/pc/src/test/driver_time/time.cc @@ -0,0 +1,25 @@ +/* + * \brief Lx_emul udelay function for very short delays + * \author Stefan Kalkowski + * \date 2021-07-10 + */ + +/* + * Copyright (C) 2021 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include + +extern "C" void lx_emul_time_udelay(unsigned long usec); +extern "C" void lx_emul_time_udelay(unsigned long usec) +{ + if (usec > 100) + Genode::error("Cannot delay that long ", usec, " microseconds"); + + unsigned long long start = Lx_kit::env().timer.curr_time().trunc_to_plain_us().value; + while (Lx_kit::env().timer.curr_time().trunc_to_plain_us().value < (start + usec)) { ; } +} diff --git a/repos/pc/src/test/framebuffer/intel/main.cc b/repos/pc/src/test/framebuffer/intel/main.cc index e50fe5cb14..b0cd2371df 100644 --- a/repos/pc/src/test/framebuffer/intel/main.cc +++ b/repos/pc/src/test/framebuffer/intel/main.cc @@ -79,7 +79,7 @@ void Framebuffer_controller::_update_connector_config(Xml_generator & xml, w = mode.attribute_value("width", 0); h = mode.attribute_value("height", 0); z = mode.attribute_value("hz", 0); - if (w >= width) { + if (w * h >= width * height) { width = w; height = h; if (z > hz) @@ -103,7 +103,7 @@ void Framebuffer_controller::_update_fb_config(Xml_node const &report) static char buf[4096]; Xml_generator xml(buf, sizeof(buf), "config", [&] { -// xml.attribute("poll", "5000"); + xml.attribute("apply_on_hotplug", "no"); xml.node("report", [&] { xml.attribute("connectors", "yes"); }); diff --git a/repos/ports/ports/binutils.hash b/repos/ports/ports/binutils.hash index 8e6254ac25..54307fa8f8 100644 --- a/repos/ports/ports/binutils.hash +++ b/repos/ports/ports/binutils.hash @@ -1 +1 @@ -6c84c45b94d27bedf4b79d37f4703594e74458eb +0f8a39117a2b19a5706726ab31e5b3e9b5bd9c8c diff --git a/repos/ports/ports/binutils.port b/repos/ports/ports/binutils.port index 30c1105a8f..88d26b177f 100644 --- a/repos/ports/ports/binutils.port +++ b/repos/ports/ports/binutils.port @@ -13,14 +13,3 @@ PATCHES := $(addprefix ${DIR(binutils)}/patches/, \ PATCH_OPT := -p1 -d ${DIR(binutils)} HASH_INPUT += $(REP_DIR)/${DIR(binutils)}/patches/series - -AUTOCONF := autoconf - -$(call check_tool,$(AUTOCONF)) - -default: _patch - @# - @# Re-generate configure scripts - @# - $(VERBOSE)cd ${DIR(binutils)}/bfd; $(AUTOCONF) - $(VERBOSE)touch $@ diff --git a/repos/ports/ports/gcc.hash b/repos/ports/ports/gcc.hash index 0bd58d8ebc..373400f650 100644 --- a/repos/ports/ports/gcc.hash +++ b/repos/ports/ports/gcc.hash @@ -1 +1 @@ -bc8a730adbf377de2c449d222a0df0ba7096a4b8 +1c4e056fb1955d8e2ad3a696a169deedae8c8f64 diff --git a/repos/ports/ports/gcc.port b/repos/ports/ports/gcc.port index f569312ad8..6570ee6c08 100644 --- a/repos/ports/ports/gcc.port +++ b/repos/ports/ports/gcc.port @@ -14,11 +14,23 @@ PATCH_OPT := -p1 -d ${DIR(gcc)} HASH_INPUT += $(REP_DIR)/${DIR(gcc)}/patches/series -# Required version is 2.69, but there is no versioned binary name on -# Ubuntu right now like there has been for version 2.64. -AUTOCONF := autoconf +AUTOCONF_VERSION = 2.69 + +AUTOCONF_VERSION_STRING = "autoconf (GNU Autoconf) $(AUTOCONF_VERSION)" +ifneq ($(shell autoconf -V | grep $(AUTOCONF_VERSION_STRING)),) + AUTOCONF = autoconf +else + ifneq ($(shell which autoconf$(AUTOCONF_VERSION)),) + AUTOCONF = autoconf$(AUTOCONF_VERSION) + else + ifneq ($(shell which autoconf-$(AUTOCONF_VERSION)),) + AUTOCONF = autoconf-$(AUTOCONF_VERSION) + else + $(error Need to have 'autoconf' version $(AUTOCONF_VERSION) installed) + endif + endif +endif -$(call check_tool,$(AUTOCONF)) $(call check_tool,autogen) default: _patch diff --git a/repos/ports/ports/gnupg.hash b/repos/ports/ports/gnupg.hash index f9aac8e89b..2a2b07510b 100644 --- a/repos/ports/ports/gnupg.hash +++ b/repos/ports/ports/gnupg.hash @@ -1 +1 @@ -c784d4658f87704035f17c0e182aa0e9de931acf +8357d87e27946e6148aec9bc472ffacd0b98cdf8 diff --git a/repos/ports/ports/virtualbox6.hash b/repos/ports/ports/virtualbox6.hash index d2c1ce40bc..9fe7342901 100644 --- a/repos/ports/ports/virtualbox6.hash +++ b/repos/ports/ports/virtualbox6.hash @@ -1 +1 @@ -db7d6d9b9ab32c34fcfb371dfc9e100b208ee982 +b59f4f8ca00b96a40a93f736676f5b4e830cbd01 diff --git a/repos/ports/recipes/pkg/report_dump/hash b/repos/ports/recipes/pkg/report_dump/hash index b8e332ad0d..66f8aea133 100644 --- a/repos/ports/recipes/pkg/report_dump/hash +++ b/repos/ports/recipes/pkg/report_dump/hash @@ -1 +1 @@ -2022-05-24 816a53aa1aabc533efcdf851afe3c385638c8582 +2022-10-13 b21600b1d04c15bac05fef3c0c85b461434af654 diff --git a/repos/ports/recipes/pkg/system_shell/hash b/repos/ports/recipes/pkg/system_shell/hash index 2345089e70..3a3a6ff11a 100644 --- a/repos/ports/recipes/pkg/system_shell/hash +++ b/repos/ports/recipes/pkg/system_shell/hash @@ -1 +1 @@ -2022-05-24 69231685d5cdc6b0a0d7b35a5c8932a28d0b0eeb +2022-10-13 d5a6a38faf1a189e344e20315d7e3b5ff3c655b9 diff --git a/repos/ports/recipes/pkg/vbox5-nova-capture/hash b/repos/ports/recipes/pkg/vbox5-nova-capture/hash index 706825237b..273664f308 100644 --- a/repos/ports/recipes/pkg/vbox5-nova-capture/hash +++ b/repos/ports/recipes/pkg/vbox5-nova-capture/hash @@ -1 +1 @@ -2022-05-24 aacbfffccaa495c66e7a6ed7eaad4d084dea4d55 +2022-10-11 e8bc59a090a8ecbbf42d722ff0281638ffb163fe diff --git a/repos/ports/recipes/pkg/vbox5-nova-sculpt/hash b/repos/ports/recipes/pkg/vbox5-nova-sculpt/hash index b429a1e3c0..06fdf892ad 100644 --- a/repos/ports/recipes/pkg/vbox5-nova-sculpt/hash +++ b/repos/ports/recipes/pkg/vbox5-nova-sculpt/hash @@ -1 +1 @@ -2022-05-24 aeac291a990e794495eb33d4f87260412b6129d8 +2022-10-11 86aecdf04bd865d5437baf7d6938b772f410bfc5 diff --git a/repos/ports/recipes/pkg/vbox5/hash b/repos/ports/recipes/pkg/vbox5/hash index dae23de503..be8ef78173 100644 --- a/repos/ports/recipes/pkg/vbox5/hash +++ b/repos/ports/recipes/pkg/vbox5/hash @@ -1 +1 @@ -2022-05-24 69b7ff98e1b485e62bd92c713cca31c1f3812b2e +2022-10-11 573ef802db888376637cc80d18193fd60c044ef6 diff --git a/repos/ports/recipes/pkg/vbox6-capture/archives b/repos/ports/recipes/pkg/vbox6-capture/archives index 55569f514a..fd5314ece3 100644 --- a/repos/ports/recipes/pkg/vbox6-capture/archives +++ b/repos/ports/recipes/pkg/vbox6-capture/archives @@ -1,13 +1,17 @@ _/raw/vbox6 +_/src/expat _/src/init _/src/jpeg _/src/libc +_/src/libdrm _/src/libiconv _/src/libyuv +_/src/mesa _/src/posix _/src/stdcxx _/src/vbox6 _/src/vfs +_/src/vfs_gpu _/src/vfs_oss _/src/vfs_pipe _/src/zlib diff --git a/repos/ports/recipes/pkg/vbox6-capture/hash b/repos/ports/recipes/pkg/vbox6-capture/hash index cfc5a3b6fe..2d4949c76e 100644 --- a/repos/ports/recipes/pkg/vbox6-capture/hash +++ b/repos/ports/recipes/pkg/vbox6-capture/hash @@ -1 +1 @@ -2022-05-24 8b57b7ae6ede57d71a9a92391ee3ec5bbe115150 +2022-10-13 5ee9b1fe8cba2b4de594a86536d1715fa1f19f60 diff --git a/repos/ports/recipes/pkg/vbox6-capture/runtime b/repos/ports/recipes/pkg/vbox6-capture/runtime index 204ffef6a1..ca4433c8c2 100644 --- a/repos/ports/recipes/pkg/vbox6-capture/runtime +++ b/repos/ports/recipes/pkg/vbox6-capture/runtime @@ -1,11 +1,11 @@ - + - + @@ -14,11 +14,13 @@ + + @@ -31,11 +33,11 @@ + - @@ -47,19 +49,19 @@ - + - - + + @@ -69,7 +71,7 @@ - + @@ -79,12 +81,15 @@ - + + + + @@ -96,20 +101,29 @@ + + + + + + + + + diff --git a/repos/ports/recipes/pkg/vbox6/hash b/repos/ports/recipes/pkg/vbox6/hash index 5ba2f352ba..5fd62b4ce6 100644 --- a/repos/ports/recipes/pkg/vbox6/hash +++ b/repos/ports/recipes/pkg/vbox6/hash @@ -1 +1 @@ -2022-05-24 c9d4f7d47d92ac717d61d5683d31b85d9d043817 +2022-10-13 e4ebeaebba14936f204f7a26c14c237f9a44d636 diff --git a/repos/ports/recipes/src/bash-minimal/hash b/repos/ports/recipes/src/bash-minimal/hash index d0845dc009..0a1f7575f8 100644 --- a/repos/ports/recipes/src/bash-minimal/hash +++ b/repos/ports/recipes/src/bash-minimal/hash @@ -1 +1 @@ -2022-05-24 619590515b345ac4a329afa0db5e607451849fa6 +2022-08-30 4e01ba599b1e81d6f383a2fe391c248db5b9e91c diff --git a/repos/ports/recipes/src/bash/hash b/repos/ports/recipes/src/bash/hash index cb2c439861..7d600c7970 100644 --- a/repos/ports/recipes/src/bash/hash +++ b/repos/ports/recipes/src/bash/hash @@ -1 +1 @@ -2022-05-24 0dd89e1831eb3d202afec3006b864cfd564e2d50 +2022-08-30 eca698181c3c952580d72e5a52f7e4785e54559b diff --git a/repos/ports/recipes/src/binutils_x86/hash b/repos/ports/recipes/src/binutils_x86/hash index a662bec58a..9c0c55530c 100644 --- a/repos/ports/recipes/src/binutils_x86/hash +++ b/repos/ports/recipes/src/binutils_x86/hash @@ -1 +1 @@ -2022-05-24 a727e4cb4a620a7ad0e7aa0fa7e94c7d3a05e7f4 +2022-10-11 55f7c886de2811792d996fe4a31f7e3f9ff5fb63 diff --git a/repos/ports/recipes/src/coreutils-minimal/hash b/repos/ports/recipes/src/coreutils-minimal/hash index ffe223ed95..a4d435e825 100644 --- a/repos/ports/recipes/src/coreutils-minimal/hash +++ b/repos/ports/recipes/src/coreutils-minimal/hash @@ -1 +1 @@ -2022-05-24 67102233488577194b762fad15c6dac342abd1f7 +2022-08-30 5ca3aaf8787681887803a0874e3c0b3739b0c4a9 diff --git a/repos/ports/recipes/src/coreutils/hash b/repos/ports/recipes/src/coreutils/hash index 2754e6b205..f07e65c05c 100644 --- a/repos/ports/recipes/src/coreutils/hash +++ b/repos/ports/recipes/src/coreutils/hash @@ -1 +1 @@ -2022-05-24 31a5e0c2accdf58a8cfafb89fca452ef9b5fadc0 +2022-08-30 cb5f3326adf4b009b24bfa18b2bf18448dc88dac diff --git a/repos/ports/recipes/src/diffutils/hash b/repos/ports/recipes/src/diffutils/hash index 358974e0e6..08024486d4 100644 --- a/repos/ports/recipes/src/diffutils/hash +++ b/repos/ports/recipes/src/diffutils/hash @@ -1 +1 @@ -2022-05-24 5d313b0f3fbfa64cff78120fe57f1c21f5dfb6cf +2022-08-30 c685681a37ed3d64f8206df76bfa575d114a92b9 diff --git a/repos/ports/recipes/src/e2fsprogs-minimal/hash b/repos/ports/recipes/src/e2fsprogs-minimal/hash index 7018cc9ba0..b694d897e4 100644 --- a/repos/ports/recipes/src/e2fsprogs-minimal/hash +++ b/repos/ports/recipes/src/e2fsprogs-minimal/hash @@ -1 +1 @@ -2022-02-27 046fa1c9940906ca5ed20952f2eefa8146a64e63 +2022-08-30 143e7e64f872e51785d58255ec76f91523dc741d diff --git a/repos/ports/recipes/src/e2fsprogs/hash b/repos/ports/recipes/src/e2fsprogs/hash index 88f80bbaec..bc49e921fa 100644 --- a/repos/ports/recipes/src/e2fsprogs/hash +++ b/repos/ports/recipes/src/e2fsprogs/hash @@ -1 +1 @@ -2022-02-27 4d279fe7fcbc2bf1e80865be9d690fa940506bd0 +2022-08-30 371c401e4c97b0f9696eda87e2f40967c2899f1e diff --git a/repos/ports/recipes/src/findutils/hash b/repos/ports/recipes/src/findutils/hash index 297fafb553..ed91dfad77 100644 --- a/repos/ports/recipes/src/findutils/hash +++ b/repos/ports/recipes/src/findutils/hash @@ -1 +1 @@ -2022-05-24 e073e070381e4ab140d28840ccb8f3df63ec9988 +2022-08-30 1ec546375092620ce72fbccfb2c22e92b478e525 diff --git a/repos/ports/recipes/src/gcc_x86/hash b/repos/ports/recipes/src/gcc_x86/hash index db401ba227..1ea0f2a4af 100644 --- a/repos/ports/recipes/src/gcc_x86/hash +++ b/repos/ports/recipes/src/gcc_x86/hash @@ -1 +1 @@ -2022-05-24 21ff01afd7840b4f6c254f4dcf13b9fd3d745058 +2022-10-11 40ae61731f6aa03b3769c8adaecd69220abef743 diff --git a/repos/ports/recipes/src/gnumake/hash b/repos/ports/recipes/src/gnumake/hash index 44bca691ae..b5a7abd65a 100644 --- a/repos/ports/recipes/src/gnumake/hash +++ b/repos/ports/recipes/src/gnumake/hash @@ -1 +1 @@ -2022-05-24 6a503d5b6e3f8f67838fb940c9d1f8acf70544dd +2022-08-30 cf84399c1d84934101de86facc16c3c4f729c24e diff --git a/repos/ports/recipes/src/grep/hash b/repos/ports/recipes/src/grep/hash index 49ba0df8ba..70b0960360 100644 --- a/repos/ports/recipes/src/grep/hash +++ b/repos/ports/recipes/src/grep/hash @@ -1 +1 @@ -2022-05-24 91d0df4c916462460e75016b2e7a879f55ecd798 +2022-08-30 36fb5dbc8605aebf91e1a2b650748c6ca93ecae2 diff --git a/repos/ports/recipes/src/less/hash b/repos/ports/recipes/src/less/hash index f7842e665e..c7a41200dc 100644 --- a/repos/ports/recipes/src/less/hash +++ b/repos/ports/recipes/src/less/hash @@ -1 +1 @@ -2022-02-27 dfcb7e80e71ab7c36c8d6a2a2339ed8d44624c4b +2022-08-30 ec1c540b0e235f06c523c36a8484517903662a02 diff --git a/repos/ports/recipes/src/lighttpd/hash b/repos/ports/recipes/src/lighttpd/hash index df3f4db3aa..55e962551b 100644 --- a/repos/ports/recipes/src/lighttpd/hash +++ b/repos/ports/recipes/src/lighttpd/hash @@ -1 +1 @@ -2022-05-24 712c3df1e840d4daf957ff8421672ea8a9fb8541 +2022-08-30 e1ec2a914a651dafd2d6a66e6d14eeb5fdd714a2 diff --git a/repos/ports/recipes/src/sed/hash b/repos/ports/recipes/src/sed/hash index ce43fd2576..7294bbadcc 100644 --- a/repos/ports/recipes/src/sed/hash +++ b/repos/ports/recipes/src/sed/hash @@ -1 +1 @@ -2022-05-24 d17a596ab7ecd394fc4864cf9a79849ebe646666 +2022-08-30 57c0bca0dad88dbb4cab95d7d324b4b5f6a3dec8 diff --git a/repos/ports/recipes/src/tar/hash b/repos/ports/recipes/src/tar/hash index dd2420deb4..4b78c4a7ab 100644 --- a/repos/ports/recipes/src/tar/hash +++ b/repos/ports/recipes/src/tar/hash @@ -1 +1 @@ -2022-05-24 8defda321f0f9859a075bc7c522e3de088c3e304 +2022-08-30 eee4bdb8fc6c646fadaa77291a85accc314fe60f diff --git a/repos/ports/recipes/src/tclsh/hash b/repos/ports/recipes/src/tclsh/hash index 8c1f36db4f..830fd45ad6 100644 --- a/repos/ports/recipes/src/tclsh/hash +++ b/repos/ports/recipes/src/tclsh/hash @@ -1 +1 @@ -2022-02-27 51b1a519dc0fb7e4574cdf3489a7af63f5a72ee0 +2022-08-30 24f71a064a8b11d0eb81cd3c9b1e6fe8df089b59 diff --git a/repos/ports/recipes/src/vbox5-nova/hash b/repos/ports/recipes/src/vbox5-nova/hash index df96ebb3e0..eb83062bb1 100644 --- a/repos/ports/recipes/src/vbox5-nova/hash +++ b/repos/ports/recipes/src/vbox5-nova/hash @@ -1 +1 @@ -2022-05-24 0dbe102f38659039e6af7e0f93de3975f4432484 +2022-10-11 70396f6e3d594fc40501f10c464d992a4d20a00c diff --git a/repos/ports/recipes/src/vbox5/hash b/repos/ports/recipes/src/vbox5/hash index c968fedc2b..c50b6d6f07 100644 --- a/repos/ports/recipes/src/vbox5/hash +++ b/repos/ports/recipes/src/vbox5/hash @@ -1 +1 @@ -2022-05-24 55c2594e7a2ebb80fdbf5f7c9faa5d23bb022ed3 +2022-10-11 67b26c708d462ac6989edd77660bf0b16bde013c diff --git a/repos/ports/recipes/src/vbox6/hash b/repos/ports/recipes/src/vbox6/hash index 320645d56d..63dc853b4a 100644 --- a/repos/ports/recipes/src/vbox6/hash +++ b/repos/ports/recipes/src/vbox6/hash @@ -1 +1 @@ -2022-05-24 fc407384ceb313b03b5f02af0753b82afa0922d0 +2022-10-11 ed6b31b0a54a9950aa97b0b801ef151f69b52f74 diff --git a/repos/ports/recipes/src/verify/hash b/repos/ports/recipes/src/verify/hash index 30b927763b..e1966b15c5 100644 --- a/repos/ports/recipes/src/verify/hash +++ b/repos/ports/recipes/src/verify/hash @@ -1 +1 @@ -2022-05-24 1b0552e8dc4146b541c6325b4713c695367d02b6 +2022-10-11 d615fad468fd99978be7ceb2ddaab29cd619de5e diff --git a/repos/ports/recipes/src/vim-minimal/hash b/repos/ports/recipes/src/vim-minimal/hash index 1b4af1eb66..e210efd9dc 100644 --- a/repos/ports/recipes/src/vim-minimal/hash +++ b/repos/ports/recipes/src/vim-minimal/hash @@ -1 +1 @@ -2022-02-27 791a0fa187019a0e78e2b296a2d98ba1431898ba +2022-08-30 30e5c88017752ae7ab7132326a1dc64f2bbe3247 diff --git a/repos/ports/recipes/src/vim/hash b/repos/ports/recipes/src/vim/hash index d3a3014c9e..573b0bf1ff 100644 --- a/repos/ports/recipes/src/vim/hash +++ b/repos/ports/recipes/src/vim/hash @@ -1 +1 @@ -2022-02-27 7e10043b21613b0d7af374c658d087361ff1f099 +2022-08-30 ff4a2182cf2f71fbb3fb3f7832ffc71bdfc471d2 diff --git a/repos/ports/recipes/src/which/hash b/repos/ports/recipes/src/which/hash index d921ebeb18..a2bd68950e 100644 --- a/repos/ports/recipes/src/which/hash +++ b/repos/ports/recipes/src/which/hash @@ -1 +1 @@ -2022-05-24 3a608208a4eb46947fa2086f99dc8b4fe8c81380 +2022-08-30 ddbb4e412291e26c26d235ebfc6203fc9e313dd2 diff --git a/repos/ports/run/gdb_monitor.run b/repos/ports/run/gdb_monitor.run index 28686f7b33..f09bffcb5c 100644 --- a/repos/ports/run/gdb_monitor.run +++ b/repos/ports/run/gdb_monitor.run @@ -23,7 +23,7 @@ set build_components { drivers/uart app/gdb_monitor test/gdb_monitor - lib/vfs/pipe + lib/vfs_pipe } lappend build_components "lib/gdbserver_platform-$::env(KERNEL)" diff --git a/repos/ports/run/gdb_monitor_interactive.run b/repos/ports/run/gdb_monitor_interactive.run index 8b608b80ad..bc1c2f624d 100644 --- a/repos/ports/run/gdb_monitor_interactive.run +++ b/repos/ports/run/gdb_monitor_interactive.run @@ -19,7 +19,7 @@ set build_components { drivers/uart app/gdb_monitor test/gdb_monitor - lib/vfs/pipe + lib/vfs_pipe } lappend build_components "lib/gdbserver_platform-$::env(KERNEL)" diff --git a/repos/ports/run/gdb_monitor_target_config.run b/repos/ports/run/gdb_monitor_target_config.run index 2bff522aac..4040dc609d 100644 --- a/repos/ports/run/gdb_monitor_target_config.run +++ b/repos/ports/run/gdb_monitor_target_config.run @@ -18,7 +18,7 @@ set build_components { drivers/uart app/gdb_monitor test/gdb_monitor_target_config - lib/vfs/pipe + lib/vfs_pipe } lappend build_components "lib/gdbserver_platform-$::env(KERNEL)" diff --git a/repos/ports/run/netperf.inc b/repos/ports/run/netperf.inc index c91cdc93b5..b131110fe3 100644 --- a/repos/ports/run/netperf.inc +++ b/repos/ports/run/netperf.inc @@ -140,34 +140,30 @@ create_boot_directory set packages " [depot_user]/src/[base_src] - [depot_user]/pkg/[drivers_nic_pkg] [depot_user]/src/init [depot_user]/src/libc [depot_user]/src/posix + [depot_user]/src/report_rom [depot_user]/src/vfs [depot_user]/src/nic_router " - -append_if [expr !$use_lxip] packages " [depot_user]/src/vfs_lwip " -append_if $use_lxip packages " [depot_user]/src/vfs_lxip " -append_if $use_nic_bridge packages " [depot_user]/src/nic_bridge " -append_if $use_usb_driver packages " [depot_user]/src/platform_drv " -append_if $use_wifi_driver packages " [depot_user]/src/fs_rom " -append_if $use_wifi_driver packages " [depot_user]/src/vfs_import " -append_if $use_wifi_driver packages " [depot_user]/src/report_rom " -append_if $use_wifi_driver packages " [depot_user]/src/pc_wifi_drv " -append_if $use_wifi_driver packages " [depot_user]/src/openssl " -append_if $use_wifi_driver packages " [depot_user]/src/vfs_jitterentropy " -append_if $use_wifi_driver packages " [depot_user]/raw/wifi_firmware " +set use_nic_drv [expr !$use_usb_driver && !$use_wifi_driver] +append_if $use_nic_drv packages " [depot_user]/pkg/[drivers_nic_pkg] " +append_if [expr !$use_lxip] packages " [depot_user]/src/vfs_lwip " +append_if $use_lxip packages " [depot_user]/src/vfs_lxip " +append_if $use_nic_bridge packages " [depot_user]/src/nic_bridge " +append_if $use_usb_driver packages " [depot_user]/pkg/test_usb_host_drv-[board] " +append_if $use_usb_driver packages " [depot_user]/src/usb_net_drv " +append_if $use_wifi_driver packages " [depot_user]/src/fs_rom " +append_if $use_wifi_driver packages " [depot_user]/src/vfs_import " +append_if $use_wifi_driver packages " [depot_user]/pkg/wifi " +append_if $use_wifi_driver packages " [depot_user]/src/acpi_drv " +append_if $use_wifi_driver packages " [depot_user]/src/pci_decode " +append_if $use_wifi_driver packages " [depot_user]/src/platform_drv " import_from_depot $packages -set build_components { app/netperf } - -append_if $use_usb_driver build_components " drivers/usb_host " -append_if $use_usb_driver build_components " drivers/usb_net " - -build $build_components +build { app/netperf } # # Generate config @@ -175,14 +171,6 @@ build $build_components set lx_ip_addr "10.0.2.55" -source ${genode_dir}/repos/base/run/platform_drv.inc -proc platform_drv_policy {} { - global use_wifi_driver - if { $use_wifi_driver } { - return { }} - return { } -} - set config { @@ -206,12 +194,41 @@ set config { } if { $use_wifi_driver } { - append_platform_drv_config append config { - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -269,36 +286,18 @@ append config { } elseif { $use_usb_driver } { - append_platform_drv_config append config { - } - - append config "" - append config { - - + + + - } - - append_if [have_board arndale] config { - - } - - append_if [have_board rpi] config { - - } - - append_if [have_spec x86] config { - - } - - append config { - - + + - + + @@ -431,11 +430,22 @@ append config { install_config $config +# +# Define USB host controller config +# +if { $use_usb_driver } { + set fd [open [run_dir]/genode/usb_host_drv.config w] + append usb_config {} + append_if [have_board rpi] usb_config { + } + append_if [have_spec x86] usb_config { + } + append usb_config {} + puts $fd $usb_config + close $fd +} + set boot_modules { netserver } - -append_if $use_usb_driver boot_modules " [usb_host_drv_binary] " -append_if $use_usb_driver boot_modules " usb_net_drv " - build_boot_image $boot_modules # diff --git a/repos/ports/run/tool_chain_auto.run b/repos/ports/run/tool_chain_auto.run index 2e9df0dabb..47d55537ac 100644 --- a/repos/ports/run/tool_chain_auto.run +++ b/repos/ports/run/tool_chain_auto.run @@ -4,6 +4,8 @@ if {[get_cmd_switch --autopilot] && [have_include "power_on/qemu"]} { } if {[have_spec pistachio] || [have_spec sel4] || + [have_board imx53_qsb_tz] || [have_board rpi] || + [expr [have_spec foc] && [have_board imx6q_sabrelite]] || [expr [have_spec foc] && [have_board imx7d_sabre]] } { puts "Platform is unsupported." exit 0 @@ -78,7 +80,7 @@ set pkgs "$binutils $gcc" foreach pkg $pkgs { lappend_if [expr ![file exists bin/$pkg]] build_components noux-pkg/$pkg } -lappend build_components "lib/vfs/pipe" +lappend build_components "lib/vfs_pipe" lappend build_components "server/vfs" build $build_components diff --git a/repos/ports/run/vbox5_genode_usb_hid_raw.run b/repos/ports/run/vbox5_genode_usb_hid_raw.run index aeed73f926..11deac5b93 100644 --- a/repos/ports/run/vbox5_genode_usb_hid_raw.run +++ b/repos/ports/run/vbox5_genode_usb_hid_raw.run @@ -13,37 +13,34 @@ if { [have_include "power_on/qemu"] || ![have_spec nova] || ![have_spec x86_64]} exit 0 } -set build_components { - drivers/framebuffer - drivers/ps2 - drivers/usb_host - server/log_terminal - server/fs_rom - server/vfs lib/vfs/import - server/report_rom - app/usb_report_filter - virtualbox5 -} - -source ${genode_dir}/repos/base/run/platform_drv.inc - -# override defaults of platform_drv.inc -proc platform_drv_priority {} { return { priority="-1"} } - -append_platform_drv_build_components - -build $build_components +build { app/usb_report_filter } create_boot_directory - import_from_depot [depot_user]/src/[base_src] \ + [depot_user]/src/acpi_drv \ + [depot_user]/src/fs_rom \ [depot_user]/src/init \ + [depot_user]/src/jpeg \ + [depot_user]/src/libc \ + [depot_user]/src/libiconv \ + [depot_user]/src/libyuv \ + [depot_user]/src/log_terminal \ [depot_user]/src/nitpicker \ + [depot_user]/src/pc_usb_host_drv \ + [depot_user]/src/pci_decode \ + [depot_user]/src/platform_drv \ + [depot_user]/src/posix \ + [depot_user]/src/ps2_drv \ + [depot_user]/src/report_rom \ + [depot_user]/src/stdcxx \ + [depot_user]/src/vbox5-nova \ + [depot_user]/src/vesa_drv \ + [depot_user]/src/vfs \ + [depot_user]/src/vfs_import \ [depot_user]/src/vfs_pipe \ - [depot_user]/src/jpeg + [depot_user]/src/zlib - -set config { +install_config { @@ -58,22 +55,59 @@ set config { - } + -append_platform_drv_config + + + + + + + + + + + + + -append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - @@ -134,9 +168,8 @@ append config { - } -append config "" -append config { + + @@ -148,12 +181,6 @@ append config { - - - - - - @@ -196,29 +223,20 @@ append config { - - - - - - - - - - - - - + + + 2022-08-10 00:01 + - + @@ -229,13 +247,16 @@ append config { } -install_config $config - puts "--- executing the 'usb_hid_raw' run script to generate the 'usb_hid_raw.iso' image ---" global specs global repositories +set depot_auto_update "" +if {[get_cmd_switch --depot-auto-update]} { + set depot_auto_update "--depot-auto-update" +} + exec -ignorestderr \ $::argv0 \ --genode-dir [genode_dir] \ @@ -245,6 +266,7 @@ exec -ignorestderr \ --repositories "$repositories" \ --depot-dir [depot_dir] \ --depot-user [depot_user] \ + $depot_auto_update \ --cross-dev-prefix "[cross_dev_prefix]" \ --include boot_dir/nova \ --include image/iso \ @@ -253,32 +275,7 @@ exec -ignorestderr \ exec ln -sf ${genode_dir}/repos/ports/run/vm_genode_usb_hid_raw.vbox bin/ exec ln -sf ../../usb_hid_raw.iso bin/ -set boot_modules { - core - init - timer - vesa_fb_drv - ps2_drv - log_terminal - usb_report_filter - fs_rom - vfs vfs.lib.so vfs_import.lib.so - report_rom - virtualbox5-nova - usb_hid_raw.iso - vm_genode_usb_hid_raw.vbox - ld.lib.so libc.lib.so libm.lib.so - libiconv.lib.so stdcxx.lib.so - qemu-usb.lib.so - libyuv.lib.so jpeg.lib.so -} - -append boot_modules " [usb_host_drv_binary] " - -append_platform_drv_boot_modules - - -build_boot_image $boot_modules +build_boot_image { usb_report_filter usb_hid_raw.iso vm_genode_usb_hid_raw.vbox } if { ![get_cmd_switch --autopilot] } { run_genode_until forever } @@ -313,10 +310,10 @@ compare_output_to { [init -> log_terminal] [init -> event_dump] Input event #4 REL_MOTION +0+1 key count: 1 [init -> log_terminal] [init -> event_dump] Input event #5 RELEASE BTN_LEFT key count: 0 [init -> usb_drv] USB disconnect, device -[init -> log_terminal] [init -> usb_drv] USB disconnect, device +[init -> log_terminal] [init -> usb_drv -> usb_drv] USB disconnect, device [init -> usb_drv] new full-speed USB device -[init -> virtualbox] Attach USB device (vendor=3eb, product=204d) -[init -> log_terminal] [init -> usb_drv] new full-speed USB device +[init -> virtualbox] Attach USB device usb-2-8 +[init -> log_terminal] [init -> usb_drv -> usb_drv] new full-speed USB device [init -> log_terminal] [init -> usb_hid_drv] input: USB HID v1.11 Keyboard [HID 03eb:204d] [init -> log_terminal] [init -> usb_hid_drv] input: USB HID v1.11 Mouse [HID 03eb:204d] [init -> log_terminal] [init -> event_dump] Input event #6 PRESS KEY_X 65534 key count: 1 diff --git a/repos/ports/run/vbox_share.inc b/repos/ports/run/vbox_share.inc index 6fd75276bf..cc8e536207 100644 --- a/repos/ports/run/vbox_share.inc +++ b/repos/ports/run/vbox_share.inc @@ -104,7 +104,7 @@ set build_components { server/event_filter server/report_rom server/fs_rom server/vfs server/tcp_terminal drivers/nic - lib/vfs/lwip lib/vfs/pipe lib/vfs/import + lib/vfs_lwip lib/vfs_pipe lib/vfs_import server/nic_router } diff --git a/repos/ports/run/verify.run b/repos/ports/run/verify.run index 6d145b8213..7d69ee1bb0 100644 --- a/repos/ports/run/verify.run +++ b/repos/ports/run/verify.run @@ -1,4 +1,4 @@ -if {[get_cmd_switch --autopilot] && [have_board riscv_qemu]} { +if {[get_cmd_switch --autopilot] && [have_board virt_qemu_riscv]} { puts "Autopilot mode is not supported on this platform." exit 0 } diff --git a/repos/ports/run/virtualbox_auto.inc b/repos/ports/run/virtualbox_auto.inc index 6e50e9da21..da923eba6d 100644 --- a/repos/ports/run/virtualbox_auto.inc +++ b/repos/ports/run/virtualbox_auto.inc @@ -28,6 +28,10 @@ import_from_depot [depot_user]/src/[base_src] \ [depot_user]/src/libiconv \ [depot_user]/src/nitpicker \ [depot_user]/src/part_block \ + [depot_user]/src/platform_drv \ + [depot_user]/src/acpi_drv \ + [depot_user]/src/pci_decode \ + [depot_user]/src/report_rom \ [depot_user]/src/stdcxx \ [depot_user]/src/vfs \ [depot_user]/src/vfs_pipe \ @@ -50,25 +54,19 @@ if {$use_rumpfs} { append build_components { drivers/ahci drivers/framebuffer + drivers/rtc + drivers/ps2 + virtualbox5 } lappend_if [expr $use_serial] build_components server/log_terminal -lappend_if [expr $use_vbox5] build_components virtualbox5 -lappend_if [expr $use_ps2] build_components drivers/ps2 lappend_if [expr $use_usb] build_components app/usb_report_filter -lappend_if [have_spec x86] build_components drivers/rtc -lappend_if [expr $use_ram_fs || $use_usb] build_components lib/vfs/import +lappend_if [expr $use_ram_fs || $use_usb] build_components lib/vfs_import lappend_if [expr $use_cpu_load] build_components app/trace_subject_reporter lappend_if [expr $use_cpu_load] build_components app/cpu_load_display lappend_if [expr $use_cpu_load] build_components app/top lappend_if [have_spec nova] build_components app/log_core -source ${genode_dir}/repos/base/run/platform_drv.inc -# override defaults of platform_drv.inc -proc platform_drv_priority {} { return { priority="-1"} } - -append_platform_drv_build_components - build $build_components if {$use_rumpfs && !$use_ram_fs} { @@ -111,6 +109,57 @@ append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -118,6 +167,29 @@ append config { + + + + + + + + + + + + + + + + + + + + + + + @@ -152,11 +224,11 @@ append_if [have_spec nova] config { append_if [expr $use_rumpfs] config { - + - + } append_if [expr $use_rumpfs && $use_ram_fs && $use_overlay_from_disk] config { @@ -219,18 +291,6 @@ append_if [expr $use_ram_fs && $use_overlay_from_disk] config { } -append_platform_drv_config - -append_if [expr $use_ps2] config { - - - - - - - - } - append_if [expr $use_cpu_load] config { @@ -373,21 +433,6 @@ append_if [expr $use_usb] config { } -append_if [have_board pc] config { - - - - - } - -append_if [have_spec x86] config { - - - - - - } - append_if [expr $use_serial] config { @@ -406,12 +451,15 @@ install_config $config append boot_modules { ahci_drv + ps2_drv + rtc_drv + vesa_fb_drv qemu-usb.lib.so libyuv.lib.so } +append boot_modules $virtualbox5_binary lappend_if [expr $use_serial] boot_modules log_terminal -lappend_if [expr $use_vbox5] boot_modules $virtualbox5_binary lappend_if [expr $use_ram_fs && !$use_overlay_from_disk] boot_modules $overlay_image lappend_if [expr $use_cpu_load] boot_modules trace_subject_reporter lappend_if [expr $use_cpu_load] boot_modules cpu_load_display @@ -419,9 +467,4 @@ lappend_if [expr $use_cpu_load] boot_modules top lappend_if [have_spec nova] boot_modules log_core # platform-specific modules -lappend_if [expr $use_ps2] boot_modules ps2_drv lappend_if [expr $use_usb] boot_modules usb_report_filter -lappend_if [have_board pc] boot_modules vesa_fb_drv -lappend_if [have_spec x86] boot_modules rtc_drv - -append_platform_drv_boot_modules diff --git a/repos/ports/src/app/verify/patches/verify.patch b/repos/ports/src/app/verify/patches/verify.patch index e03ad3b76a..3ea4004198 100644 --- a/repos/ports/src/app/verify/patches/verify.patch +++ b/repos/ports/src/app/verify/patches/verify.patch @@ -9,3 +9,14 @@ } leave: +--- src/app/gnupg/common/iobuf.c.orig ++++ src/app/gnupg/common/iobuf.c +@@ -62,7 +62,7 @@ + /* The size of the internal buffers. + NOTE: If you change this value you MUST also adjust the regression + test "armored_key_8192" in armor.test! */ +-#define IOBUF_BUFFER_SIZE 8192 ++#define IOBUF_BUFFER_SIZE 65536 + + /* To avoid a potential DoS with compression packets we better limit + the number of filters in a chain. */ diff --git a/repos/ports/src/lib/gdbserver_platform-nova/target.mk b/repos/ports/src/lib/gdbserver_platform-nova/target.mk deleted file mode 100644 index 383999edd5..0000000000 --- a/repos/ports/src/lib/gdbserver_platform-nova/target.mk +++ /dev/null @@ -1,4 +0,0 @@ -TARGET = gdbserver_platform-nova -LIBS = gdbserver_platform-nova - -CC_CXX_WARN_STRICT = diff --git a/repos/ports/src/virtualbox5/generic/sup_vmm.cc b/repos/ports/src/virtualbox5/generic/sup_vmm.cc index d394bd7903..d7033318a9 100644 --- a/repos/ports/src/virtualbox5/generic/sup_vmm.cc +++ b/repos/ports/src/virtualbox5/generic/sup_vmm.cc @@ -722,7 +722,7 @@ uint64_t genode_cpu_hz() if (!cpu_freq) { try { - platform_rom().with_sub_node("tsc", [&] (Genode::Xml_node const &tsc) { + platform_rom().with_optional_sub_node("tsc", [&] (Genode::Xml_node const &tsc) { cpu_freq = tsc.attribute_value("freq_khz", cpu_freq); }); cpu_freq *= 1000ULL; } catch (...) { } diff --git a/repos/ports/src/virtualbox5/network.cpp b/repos/ports/src/virtualbox5/network.cpp index efbee88777..12b4d1e2e5 100644 --- a/repos/ports/src/virtualbox5/network.cpp +++ b/repos/ports/src/virtualbox5/network.cpp @@ -225,8 +225,8 @@ class Nic_client _nic.rx_channel()->sigh_packet_avail(_rx_packet_avail_dispatcher); _nic.rx_channel()->sigh_ready_to_ack(_rx_ready_to_ack_dispatcher); - /* set initial link-state */ - _handle_link_state(); + /* inform signal handler ep */ + _link_state_dispatcher.local_submit(); } Genode::Signal_context_capability dispatcher() { return _destruct_dispatcher; } diff --git a/repos/ports/src/virtualbox5/spec/nova/sup.cc b/repos/ports/src/virtualbox5/spec/nova/sup.cc index 79ea8be036..0d68c3af52 100644 --- a/repos/ports/src/virtualbox5/spec/nova/sup.cc +++ b/repos/ports/src/virtualbox5/spec/nova/sup.cc @@ -690,7 +690,7 @@ uint64_t genode_cpu_hz() if (!cpu_freq) { try { - platform_rom().with_sub_node("tsc", [&] (Genode::Xml_node const &tsc) { + platform_rom().with_optional_sub_node("tsc", [&] (Genode::Xml_node const &tsc) { cpu_freq = tsc.attribute_value("freq_khz", cpu_freq); }); cpu_freq *= 1000ULL; } catch (...) { } diff --git a/repos/ports/src/virtualbox6/network.cc b/repos/ports/src/virtualbox6/network.cc index 91c81f4008..e58bd17485 100644 --- a/repos/ports/src/virtualbox6/network.cc +++ b/repos/ports/src/virtualbox6/network.cc @@ -240,8 +240,8 @@ class Nic_client _nic.rx_channel()->sigh_packet_avail(_rx_packet_avail_dispatcher); _nic.rx_channel()->sigh_ready_to_ack(_rx_ready_to_ack_dispatcher); - /* set initial link-state */ - _handle_link_state(); + /* inform signal handler ep */ + _link_state_dispatcher.local_submit(); } Genode::Signal_context_capability dispatcher() { return _destruct_dispatcher; } diff --git a/repos/ports/src/virtualbox6/patches/audio.patch b/repos/ports/src/virtualbox6/patches/audio.patch new file mode 100644 index 0000000000..e9bb749269 --- /dev/null +++ b/repos/ports/src/virtualbox6/patches/audio.patch @@ -0,0 +1,27 @@ +diff --git a/src/virtualbox6/src/VBox/Devices/Audio/DrvHostAudioOss.cpp b/src/virtualbox6/src/VBox/Devices/Audio/DrvHostAudioOss.cpp +index d67f2bb..ea99bee 100644 +--- a/src/virtualbox6/src/VBox/Devices/Audio/DrvHostAudioOss.cpp ++++ b/src/virtualbox6/src/VBox/Devices/Audio/DrvHostAudioOss.cpp +@@ -836,6 +836,13 @@ static DECLCALLBACK(uint32_t) drvHstAudOssHA_StreamGetReadable(PPDMIHOSTAUDIO pI + AssertMsgStmt(cbRet <= cbBuf, ("fragsize*fragments: %d, cbBuf=%#x\n", cbRet, cbBuf), 0); + } + ++ /* ++ * On Genode the 'SNDCTL_DSP_SETTRIGGER' command should have started ++ * the recording. If no recording data arrives because of some error ++ * on the path (for example a crashed driver), the 'read()' call in ++ * the following section would block the VM, which is not desired. ++ */ ++#if 0 + /* + * HACK ALERT! To force the stream to start recording, we read a frame + * here if we get back that there are zero bytes available +@@ -854,7 +861,7 @@ static DECLCALLBACK(uint32_t) drvHstAudOssHA_StreamGetReadable(PPDMIHOSTAUDIO pI + RT_NOREF(cbRead); + LogFunc(("Dummy read for '%s' returns %zd (errno=%d)\n", pStreamOSS->Cfg.szName, cbRead, errno)); + } +- ++#endif + Log4Func(("returns %#x (%u) [cbBuf=%#x]\n", cbRet, cbRet, cbBuf)); + return cbRet; + } diff --git a/repos/ports/src/virtualbox6/patches/series b/repos/ports/src/virtualbox6/patches/series index 5534551873..01f24ee894 100644 --- a/repos/ports/src/virtualbox6/patches/series +++ b/repos/ports/src/virtualbox6/patches/series @@ -9,3 +9,4 @@ rttimer.patch devsvga.patch shaderlib.patch svga.patch +audio.patch diff --git a/repos/ports/src/virtualbox6/sup_drv.cc b/repos/ports/src/virtualbox6/sup_drv.cc index 8f509d0bd6..60fc557133 100644 --- a/repos/ports/src/virtualbox6/sup_drv.cc +++ b/repos/ports/src/virtualbox6/sup_drv.cc @@ -24,8 +24,8 @@ Sup::Cpu_freq_khz Sup::Drv::_cpu_freq_khz_from_rom() { unsigned khz = 0; - _platform_info_rom.xml().with_sub_node("hardware", [&] (Xml_node const &node) { - node.with_sub_node("tsc", [&] (Xml_node const &node) { + _platform_info_rom.xml().with_optional_sub_node("hardware", [&] (Xml_node const &node) { + node.with_optional_sub_node("tsc", [&] (Xml_node const &node) { khz = node.attribute_value("freq_khz", khz); }); }); @@ -42,8 +42,8 @@ Sup::Drv::Cpu_virt Sup::Drv::_cpu_virt_from_rom() { Cpu_virt virt = Cpu_virt::NONE; - _platform_info_rom.xml().with_sub_node("hardware", [&] (Xml_node const &node) { - node.with_sub_node("features", [&] (Xml_node const &node) { + _platform_info_rom.xml().with_optional_sub_node("hardware", [&] (Xml_node const &node) { + node.with_optional_sub_node("features", [&] (Xml_node const &node) { if (node.attribute_value("vmx", false)) virt = Cpu_virt::VMX; else if (node.attribute_value("svm", false)) diff --git a/repos/ports/src/virtualbox6/sup_vcpu.cc b/repos/ports/src/virtualbox6/sup_vcpu.cc index ec221099ce..e7f782d648 100644 --- a/repos/ports/src/virtualbox6/sup_vcpu.cc +++ b/repos/ports/src/virtualbox6/sup_vcpu.cc @@ -275,6 +275,40 @@ template void Sup::Vcpu_impl::_transfer_state_to_vcpu(CPUM } +/* + * Based on hmR0VmxImportGuestIntrState() + */ +static void handle_intr_state(PVMCPUCC pVCpu, CPUMCTX &ctx, Vcpu_state &state) +{ + auto const interrupt_state = state.intr_state.value(); + + if (!interrupt_state /* VMX_VMCS_GUEST_INT_STATE_NONE */) { + if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)) + VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS); + CPUMSetGuestNmiBlocking(pVCpu, false); + } else { + if (interrupt_state & (VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS | + VMX_VMCS_GUEST_INT_STATE_BLOCK_STI)) + EMSetInhibitInterruptsPC(pVCpu, ctx.rip); + else if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)) + VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS); + + bool const block_nmi = RT_BOOL(interrupt_state & + VMX_VMCS_GUEST_INT_STATE_BLOCK_NMI); + CPUMSetGuestNmiBlocking(pVCpu, block_nmi); + } + + /* prepare clearing blocking MOV SS or STI bits for next VM-entry */ + if (interrupt_state & (VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS | + VMX_VMCS_GUEST_INT_STATE_BLOCK_STI)) { + state.intr_state.charge(state.intr_state.value() & + ~unsigned(VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS | + VMX_VMCS_GUEST_INT_STATE_BLOCK_STI)); + state.actv_state.charge(VMX_VMCS_GUEST_ACTIVITY_ACTIVE); + } +} + + template void Sup::Vcpu_impl::_transfer_state_to_vbox(CPUMCTX &ctx) { Vcpu_state const &state { _vcpu.state() }; @@ -359,24 +393,13 @@ template void Sup::Vcpu_impl::_transfer_state_to_vbox(CPUM _cached_state.ctrl_primary = state.ctrl_primary.value(); _cached_state.ctrl_secondary = state.ctrl_secondary.value(); - /* clear blocking by MOV SS or STI bits */ - if (_vcpu.state().intr_state.value() & 3) { - _vcpu.state().intr_state.charge(state.intr_state.value() & ~3U); - _vcpu.state().actv_state.charge(VMX_VMCS_GUEST_ACTIVITY_ACTIVE); - } + /* handle guest interrupt state */ + handle_intr_state(pVCpu, ctx, _vcpu.state()); VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3); _vmcpu.cpum.s.fUseFlags |= CPUM_USED_FPU_GUEST; - if (state.intr_state.value() != VMX_VMCS_GUEST_INT_STATE_NONE) { - Assert(state.intr_state.value() == VMX_VMCS_GUEST_INT_STATE_BLOCK_STI || - state.intr_state.value() == VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS); - EMSetInhibitInterruptsPC(pVCpu, ctx.rip); - } else { - VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS); - } - APICSetTpr(pVCpu, tpr); /* import FPU state */ @@ -500,12 +523,6 @@ typename Sup::Vcpu_impl::Current_state Sup::Vcpu_impl::_handle_paused() Assert(state.flags.value() & X86_EFL_IF); - if (state.intr_state.value() != VMX_VMCS_GUEST_INT_STATE_NONE) - Genode::log("intr state ", Genode::Hex(state.intr_state.value()), - " ", Genode::Hex(state.intr_state.value() & 0xf)); - - Assert(state.intr_state.value() == VMX_VMCS_GUEST_INT_STATE_NONE); - /* * We got a pause exit during IRQ injection and the guest is ready for * IRQ injection. So, just continue running the vCPU. @@ -544,7 +561,6 @@ typename Sup::Vcpu_impl::Current_state Sup::Vcpu_impl::_handle_irq_window( PVMCPU pVCpu = &_vmcpu; - Assert(state.intr_state.value() == VMX_VMCS_GUEST_INT_STATE_NONE); Assert(state.flags.value() & X86_EFL_IF); Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)); Assert(!VMX_EXIT_INT_INFO_IS_VALID(state.inj_info.value())); @@ -588,34 +604,68 @@ typename Sup::Vcpu_impl::Current_state Sup::Vcpu_impl::_handle_irq_window( Assert(TRPMHasTrap(pVCpu)); /* interrupt can be dispatched */ - uint8_t u8Vector; - TRPMEVENT enmType; - SVMEVENT Event; - uint32_t u32ErrorCode; - RTGCUINT cr2; - - Event.u = 0; + uint8_t u8Vector { }; + TRPMEVENT event_type { TRPM_HARDWARE_INT }; + SVMEVENT event { }; + uint32_t errorcode { }; + RTGCUINT cr2 { }; /* If a new event is pending, then dispatch it now. */ - int rc = TRPMQueryTrapAll(pVCpu, &u8Vector, &enmType, &u32ErrorCode, &cr2, 0, 0); + int rc = TRPMQueryTrapAll(pVCpu, &u8Vector, &event_type, &errorcode, &cr2, 0, 0); AssertRC(rc); - Assert(enmType == TRPM_HARDWARE_INT); - Assert(u8Vector != X86_XCPT_NMI); + if (rc != VINF_SUCCESS) { + Genode::warning("no trap available"); + return RUNNING; + } + + /* based upon hmR0SvmTrpmTrapToPendingEvent */ + switch (event_type) { + case TRPM_TRAP: + event.n.u1Valid = 1; + event.n.u8Vector = u8Vector; + + switch (u8Vector) { + case X86_XCPT_NMI: + event.n.u3Type = SVM_EVENT_NMI; + + static_assert(SVM_EVENT_NMI == VMX_ENTRY_INT_INFO_TYPE_NMI, + "SVM vs VMX mismatch"); + break; + default: + Genode::error("unsupported injection case - " + "TRPM_TRAP, vector=", u8Vector); + Assert(!"unsupported injection case"); + return PAUSED; + } + break; + case TRPM_HARDWARE_INT: + event.n.u1Valid = 1; + event.n.u8Vector = u8Vector; + event.n.u3Type = SVM_EVENT_EXTERNAL_IRQ; + + static_assert(VMX_ENTRY_INT_INFO_TYPE_EXT_INT == SVM_EVENT_EXTERNAL_IRQ, + "SVM vs VMX mismatch"); + + break; + case TRPM_SOFTWARE_INT: + event.n.u1Valid = 1; + event.n.u8Vector = u8Vector; + event.n.u3Type = SVM_EVENT_SOFTWARE_INT; + + static_assert(VMX_ENTRY_INT_INFO_TYPE_SW_INT == SVM_EVENT_SOFTWARE_INT, + "SVM vs VMX mismatch"); + default: + Genode::error("unsupported injection case"); + Assert(!"unsupported injection case"); + return PAUSED; + } /* Clear the pending trap. */ rc = TRPMResetTrap(pVCpu); AssertRC(rc); - Event.n.u8Vector = u8Vector; - Event.n.u1Valid = 1; - Event.n.u32ErrorCode = u32ErrorCode; - - Assert(VMX_ENTRY_INT_INFO_TYPE_EXT_INT == SVM_EVENT_EXTERNAL_IRQ); - - Event.n.u3Type = VMX_ENTRY_INT_INFO_TYPE_EXT_INT; - - state.inj_info.charge(Event.u); - state.inj_error.charge(Event.n.u32ErrorCode); + state.inj_info.charge(event.u); + state.inj_error.charge(errorcode); return RUNNING; } @@ -749,6 +799,10 @@ template VBOXSTRICTRC Sup::Vcpu_impl::run() /* track guest mode changes - see VMM/VMMAll/IEMAllCImpl.cpp.h */ PGMChangeMode(pVCpu, ctx.cr0, ctx.cr4, ctx.msrEFER); + /* avoid assertion in EMHandleRCTmpl.h, normally set by SVMRO/VMXR0 */ + if (TRPMHasTrap(pVCpu)) + return VINF_EM_RAW_INJECT_TRPM_EVENT; + /* evaluated in VMM/include/EMHandleRCTmpl.h */ return rc; } diff --git a/tool/autopilot.list b/tool/autopilot.list index 13728a833b..559e9d6954 100644 --- a/tool/autopilot.list +++ b/tool/autopilot.list @@ -19,6 +19,7 @@ gdb_monitor hello ieee754 init_smp +intel_fb libc_integration libc_vfs_fs_ext2 libc_vfs_fs_fat diff --git a/tool/boot/README b/tool/boot/README index 5c778dd6a9..1a5e037e28 100644 --- a/tool/boot/README +++ b/tool/boot/README @@ -18,14 +18,14 @@ code respectively the download source of binaries are described below. configured via commandline. The changes are available from - https://github.com/alex-ab/morbo.git. + https://github.com/m-stein/morbo.git. - git branch intel_hwp - git commit 84be1183b066e9ba78c874713db4e68a5c3393fa + git branch genode_bender + git commit 3645d67dc0643b8aab008eb76a8e056636e5edee :'pulsar': - The 'pulsar' tool was obtained in binary form from + The 'pulsar' tool was obtained in binary form from http://os.inf.tu-dresden.de/~us15/pulsar. :'unzip' diff --git a/tool/boot/bender b/tool/boot/bender index 2acaeecbd9..d365444b24 100755 Binary files a/tool/boot/bender and b/tool/boot/bender differ diff --git a/tool/builddir/build.conf/run_arm_v7 b/tool/builddir/build.conf/run_arm_v7 index 722bae3f91..8b399f2b85 100644 --- a/tool/builddir/build.conf/run_arm_v7 +++ b/tool/builddir/build.conf/run_arm_v7 @@ -5,13 +5,13 @@ QEMU_RUN_OPT := --include power_on/qemu --include log/qemu #KERNEL ?= hw # board to use (imx53_qsb, imx53_qsb_tz, imx6q_sabrelite, imx7d_sabre, -# nit6_solox, pbxa9, usb_armory, virt_qemu, wand_quad, +# nit6_solox, pbxa9, usb_armory, virt_qemu_arm_v7a, wand_quad, # or zynq_qemu) #BOARD ?= pbxa9 # local variable for run-tool arguments that depend on the used board -BOARD_RUN_OPT(pbxa9) = $(QEMU_RUN_OPT) -BOARD_RUN_OPT(virt_qemu) = $(QEMU_RUN_OPT) +BOARD_RUN_OPT(pbxa9) = $(QEMU_RUN_OPT) +BOARD_RUN_OPT(virt_qemu_arm_v7a) = $(QEMU_RUN_OPT) ## ## Qemu arguments, effective when using the run tool's 'power_on/qemu' back end diff --git a/tool/builddir/build.conf/run_arm_v8 b/tool/builddir/build.conf/run_arm_v8 index 976840ef17..192eea86f6 100644 --- a/tool/builddir/build.conf/run_arm_v8 +++ b/tool/builddir/build.conf/run_arm_v8 @@ -8,9 +8,9 @@ QEMU_RUN_OPT := --include power_on/qemu --include log/qemu #BOARD ?= rpi3 # local variable for run-tool arguments that depend on the used board -BOARD_RUN_OPT(linux) := --include power_on/linux --include log/linux -BOARD_RUN_OPT(rpi3) := $(QEMU_RUN_OPT) -BOARD_RUN_OPT(virt_qemu) := $(QEMU_RUN_OPT) +BOARD_RUN_OPT(linux) := --include power_on/linux --include log/linux +BOARD_RUN_OPT(rpi3) := $(QEMU_RUN_OPT) +BOARD_RUN_OPT(virt_qemu_arm_v8a) := $(QEMU_RUN_OPT) ## ## Qemu arguments, effective when using the run tool's 'power_on/qemu' back end diff --git a/tool/builddir/build.conf/run_riscv b/tool/builddir/build.conf/run_riscv index 9ae807a2e1..eaf00f0105 100644 --- a/tool/builddir/build.conf/run_riscv +++ b/tool/builddir/build.conf/run_riscv @@ -5,7 +5,7 @@ QEMU_RUN_OPT := --include power_on/qemu --include log/qemu KERNEL ?= hw # board to use (riscv_qemu) -BOARD ?= riscv_qemu +BOARD ?= virt_qemu_riscv # local variable for run-tool arguments that depend on the used board -BOARD_RUN_OPT(riscv_qemu) = $(QEMU_RUN_OPT) +BOARD_RUN_OPT(virt_qemu_riscv) = $(QEMU_RUN_OPT) diff --git a/tool/builddir/build.mk b/tool/builddir/build.mk index a0fe37bae2..ed31c74654 100644 --- a/tool/builddir/build.mk +++ b/tool/builddir/build.mk @@ -154,12 +154,35 @@ export LIBGCC_INC_DIR := $(shell dirname `$(CUSTOM_CXX_LIB) -print-libgcc-file-n # # Find out about the target directories to build # -DST_DIRS := $(filter-out clean cleanall again run/%,$(MAKECMDGOALS)) +# Arguments starting with 'run/' and 'lib/' are special. The former triggers +# the execution of a run script. The latter issues the build of a library. +# +DST_DIRS := $(filter-out clean cleanall again run/% lib/%,$(MAKECMDGOALS)) ifeq ($(MAKECMDGOALS),) DST_DIRS := * endif +# +# Detect use of obsoleted LIB= option +# +ifneq ($(LIB),) +$(error the 'LIB=$(LIB)' option is no longer supported, use 'make lib/$(LIB)') +endif + +# +# Determine library targets specified as lib/ at the command line +# +LIBS := $(notdir $(filter lib/%,$(MAKECMDGOALS))) + +ifeq ($(MAKECMDGOALS),) +ALL_LIB_MK_DIRS := $(wildcard \ + $(foreach R,$(REPOSITORIES),\ + $R/lib/mk $(foreach S,$(SPECS),$R/lib/mk/spec/$S))) +ALL_LIB_MK_FILES := $(wildcard $(addsuffix /*.mk,$(ALL_LIB_MK_DIRS))) +LIBS := $(sort $(notdir $(ALL_LIB_MK_FILES:.mk=))) +endif + # # Helper function to check if a needed tool is installed # @@ -187,7 +210,7 @@ endif # # Default rule: build all directories specified as make arguments # -_all $(DST_DIRS): gen_deps_and_build_targets +_all $(DST_DIRS) $(addprefix lib/,$(LIBS)) : gen_deps_and_build_targets @true ## @@ -275,8 +298,15 @@ endif # we would need to spawn one additional shell per target, which would take # 10-20 percent more time. # -traverse_target_dependencies: $(dir $(LIB_DEP_FILE)) init_libdep_file init_progress_log +traverse_dependencies: $(dir $(LIB_DEP_FILE)) init_libdep_file init_progress_log $(VERBOSE_MK) \ + for lib in $(LIBS); do \ + $(MAKE) $(VERBOSE_DIR) -f $(BASE_DIR)/mk/dep_lib.mk \ + REP_DIR=$$rep LIB=$$lib \ + BUILD_BASE_DIR=$(BUILD_BASE_DIR) \ + DARK_COL="$(DARK_COL)" DEFAULT_COL="$(DEFAULT_COL)"; \ + echo "all: $$lib.lib" >> $(LIB_DEP_FILE); \ + done; \ for target in $(TARGETS_TO_VISIT); do \ for rep in $(REPOSITORIES); do \ test -f $$rep/src/$$target || continue; \ @@ -288,29 +318,9 @@ traverse_target_dependencies: $(dir $(LIB_DEP_FILE)) init_libdep_file init_progr done; \ done; $$result; -# -# Generate content of libdep file if manually building a single library -# specified via the 'LIB' argument. -# -traverse_lib_dependencies: $(dir $(LIB_DEP_FILE)) init_libdep_file init_progress_log - $(VERBOSE_MK) \ - $(MAKE) $(VERBOSE_DIR) -f $(BASE_DIR)/mk/dep_lib.mk \ - REP_DIR=$$rep LIB=$(LIB) \ - BUILD_BASE_DIR=$(BUILD_BASE_DIR) \ - DARK_COL="$(DARK_COL)" DEFAULT_COL="$(DEFAULT_COL)"; \ - echo "all: $(LIB).lib" >> $(LIB_DEP_FILE); \ - .PHONY: $(LIB_DEP_FILE) -# -# Depending on whether the top-level target is a list of targets or a -# single library, we populate the LIB_DEP_FILE differently. -# -ifeq ($(LIB),) -$(LIB_DEP_FILE): traverse_target_dependencies -else -$(LIB_DEP_FILE): traverse_lib_dependencies -endif +$(LIB_DEP_FILE): traverse_dependencies ## diff --git a/tool/run/boot_dir/fiasco b/tool/run/boot_dir/fiasco index 6696655bab..e3f29af063 100644 --- a/tool/run/boot_dir/fiasco +++ b/tool/run/boot_dir/fiasco @@ -21,7 +21,7 @@ proc run_boot_dir {binaries} { set kernel_arg "" set ld_arg "" if {![file exists [run_dir]/genode/fiasco]} { set kernel_arg "kernel/fiasco" } - if {![file exists [run_dir]/genode/ld.lib.so]} { set ld_arg "lib/ld/fiasco" } + if {![file exists [run_dir]/genode/ld.lib.so]} { set ld_arg "lib/ld-fiasco" } set targets "$kernel_arg $ld_arg" if {[llength $targets]} { build $targets } @@ -99,7 +99,7 @@ proc run_boot_dir {binaries} { } if {[have_include "load/ipxe"]} { - create_ipxe_iso_config + create_ipxe_config update_ipxe_boot_dir create_symlink_for_iso } diff --git a/tool/run/boot_dir/foc b/tool/run/boot_dir/foc index 196a8f385d..e8a7673b59 100644 --- a/tool/run/boot_dir/foc +++ b/tool/run/boot_dir/foc @@ -65,7 +65,7 @@ proc run_boot_dir_x86 {binaries} { set kernel_arg "" set ld_arg "" if {![file exists [run_dir]/genode/foc]} { set kernel_arg "kernel/foc" } - if {![file exists [run_dir]/genode/ld.lib.so]} { set ld_arg "lib/ld/foc" } + if {![file exists [run_dir]/genode/ld.lib.so]} { set ld_arg "lib/ld-foc" } set targets "$kernel_arg $ld_arg" if {[llength $targets]} { build $targets } @@ -146,7 +146,7 @@ proc run_boot_dir_x86 {binaries} { } if {[have_include "load/ipxe"]} { - create_ipxe_iso_config + create_ipxe_config update_ipxe_boot_dir create_symlink_for_iso } @@ -157,7 +157,7 @@ proc run_boot_dir_arm { binaries } { global run_target - build { lib/ld/foc kernel/foc } + build { lib/ld-foc kernel/foc } build_core_image $binaries diff --git a/tool/run/boot_dir/linux b/tool/run/boot_dir/linux index d79fd23c54..6d29be5c45 100644 --- a/tool/run/boot_dir/linux +++ b/tool/run/boot_dir/linux @@ -10,11 +10,18 @@ proc run_boot_dir {binaries} { set missing_boot_modules { } foreach binary $binaries { + set src_binary_path "[pwd]/bin/[kernel_specific_binary $binary]" + + set dst_binary "[kernel_specific_binary $binary]" + if {$dst_binary == "core-linux"} { set dst_binary "core" } + if {$dst_binary == "ld-linux.lib.so"} { set dst_binary "ld.lib.so" } + if {$dst_binary == "linux_timer_drv"} { set dst_binary "timer" } + if {[file exists $src_binary_path]} { - exec ln -sf $src_binary_path [run_dir]/genode/$binary + exec ln -sf $src_binary_path [run_dir]/genode/$dst_binary } else { - lappend missing_boot_modules [kernel_specific_binary $binary] + lappend missing_boot_modules $binary } } if {[llength $missing_boot_modules]} { diff --git a/tool/run/boot_dir/nova b/tool/run/boot_dir/nova index 8ca43dba19..93707a099d 100644 --- a/tool/run/boot_dir/nova +++ b/tool/run/boot_dir/nova @@ -1,3 +1,31 @@ +# +# Return Bender option that configures Bender's Intel HWP plugin +# +# \param --bender-intel-hwp-mode Run the Intel HWP plugin of Bender in the +# given mode. Valid argument values are +# "off", +# "performance", +# "balanced", and +# "power_saving" +# The argument value defaults to +# "performance". +# +proc bender_intel_hwp_mode_option { } { + + set opt [get_cmd_arg_first --bender-intel-hwp-mode "performance"] + if {$opt == "off"} { + return "intel_hwp_off" + } elseif {$opt == "performance"} { + return "intel_hwp_performance" + } elseif {$opt == "balanced"} { + return "intel_hwp_balanced" + } elseif {$opt == "power_saving"} { + return "intel_hwp_power_saving" + } else { + return "intel_hwp_performance" + } +} + proc binary_name_ld_lib_so { } { return "ld-nova.lib.so" } proc binary_name_core_a { } { return "core-nova.a" } proc binary_name_timer { } { return "nova_timer_drv" } @@ -37,7 +65,7 @@ proc run_boot_dir {binaries} { set ld_arg "" if {![file exists [run_dir]/genode/hypervisor]} { set kernel_arg kernel } if {![file exists [run_dir]/genode/core-nova.a]} { set core_arg core/nova } - if {![file exists [run_dir]/genode/ld.lib.so]} { set ld_arg lib/ld/nova } + if {![file exists [run_dir]/genode/ld.lib.so]} { set ld_arg lib/ld-nova } set targets "$kernel_arg $core_arg $ld_arg" if {[llength $targets]} { build $targets } @@ -47,7 +75,7 @@ proc run_boot_dir {binaries} { if {$ld_arg != ""} { copy_file bin/ld-nova.lib.so [run_dir]/genode/ld.lib.so } # - # Collect contents of the ISO image + # Collect contents of the boot image # build_core_image $binaries @@ -65,9 +93,9 @@ proc run_boot_dir {binaries} { set options_bender "" # - # Enable Intel HWP unconditionally + # Apply Intel HWP mode # - append options_bender " intel_hwp" + append options_bender " [bender_intel_hwp_mode_option]" if {[apply_microcode]} { exec cp bin/micro.code [run_dir]/boot/ @@ -177,7 +205,7 @@ proc run_boot_dir {binaries} { } if {[have_include "load/ipxe"]} { - create_ipxe_iso_config + create_ipxe_config update_ipxe_boot_dir create_symlink_for_iso } diff --git a/tool/run/boot_dir/okl4 b/tool/run/boot_dir/okl4 index 30d60f2620..fd430acafb 100644 --- a/tool/run/boot_dir/okl4 +++ b/tool/run/boot_dir/okl4 @@ -99,7 +99,7 @@ proc core_link_address { } { return "0x03000000" } proc elfweaver {} { - if { ![file exists tool/okl4/elfweaver] } { build LIB=tools } + if { ![file exists tool/okl4/elfweaver] } { build lib/tools } return tool/okl4/elfweaver } diff --git a/tool/run/boot_dir/pistachio b/tool/run/boot_dir/pistachio index db2d2afc80..f6f5004c5b 100644 --- a/tool/run/boot_dir/pistachio +++ b/tool/run/boot_dir/pistachio @@ -20,7 +20,7 @@ proc run_boot_dir {binaries} { set kernel_arg "" set ld_arg "" if {![file exists [run_dir]/genode/pistachio]} { set kernel_arg "kernel/pistachio" } - if {![file exists [run_dir]/genode/ld.lib.so]} { set ld_arg "lib/ld/pistachio" } + if {![file exists [run_dir]/genode/ld.lib.so]} { set ld_arg "lib/ld-pistachio" } set targets "$kernel_arg $ld_arg" if {[llength $targets]} { build $targets } diff --git a/tool/run/boot_dir/sel4 b/tool/run/boot_dir/sel4 index 1d169368ef..2787eeb701 100644 --- a/tool/run/boot_dir/sel4 +++ b/tool/run/boot_dir/sel4 @@ -33,7 +33,7 @@ proc run_boot_dir {binaries} { set kernel_arg "" set ld_arg "" if {![file exists [run_dir]/genode/sel4]} { set kernel_arg "kernel/sel4" } - if {![file exists [run_dir]/genode/ld.lib.so]} { set ld_arg "lib/ld/sel4" } + if {![file exists [run_dir]/genode/ld.lib.so]} { set ld_arg "lib/ld-sel4" } set targets "$kernel_arg $ld_arg" if {[llength $targets]} { build $targets } @@ -147,7 +147,7 @@ proc run_boot_dir {binaries} { } if {[have_spec x86] && [have_include "load/ipxe"]} { - create_ipxe_iso_config + create_ipxe_config update_ipxe_boot_dir create_symlink_for_iso } diff --git a/tool/run/iso.inc b/tool/run/iso.inc index af2f771964..9170c84f67 100644 --- a/tool/run/iso.inc +++ b/tool/run/iso.inc @@ -13,9 +13,6 @@ proc install_iso_bootloader_to_run_dir { } { exec mkdir -p [run_dir]/boot/grub/i386-pc exec cp $grub2_path/boot/grub2/eltorito.img [run_dir]/boot/grub/i386-pc/. - foreach file [glob -nocomplain $grub2_path/boot/grub2/\*.mod] { - exec cp $file [run_dir]/boot/grub/i386-pc/[file tail $file] - } exec cp [genode_dir]/tool/boot/bender [run_dir]/boot/bender } diff --git a/tool/run/load/ipxe b/tool/run/load/ipxe index 7c71ceed5c..4cf895320e 100644 --- a/tool/run/load/ipxe +++ b/tool/run/load/ipxe @@ -1,8 +1,10 @@ ## # Load files needed by the scenario via iPXE/HTTP # -# \param --load-ipxe-base-dir base directory of iPXE/HTTP server -# \param --load-ipxe-boot-dir boot directory relative to HTTP base +# \param --load-ipxe-base-dir base directory of iPXE/HTTP server +# \param --load-ipxe-boot-dir boot directory relative to HTTP base +# \param --load-ipxe-lighttpd run lighttpd automatically +# \param --load-ipxe-lighttpd-port TCP port to run lighttpd on # source [genode_dir]/tool/run/load.inc @@ -25,6 +27,24 @@ proc load_ipxe_base_dir { } { return [get_cmd_arg --load-ipxe-base-dir ""] } proc load_ipxe_boot_dir { } { return [get_cmd_arg --load-ipxe-boot-dir ""] } +proc load_ipxe_lighttpd { } { return [get_cmd_switch --load-ipxe-lighttpd] } + + +proc load_ipxe_lighttpd_port { } { return [get_cmd_arg --load-ipxe-lighttpd-port 8080] } + + +proc image_extension { } { + if {[have_include "image/iso"]} { + return "iso" + } elseif {[have_include "image/uefi"]} { + return "img" + } else { + puts "Warning, iPXE requires ISO or UEFI image." + exit -1 + } +} + + ## # Install files needed to boot via iPXE # @@ -38,7 +58,7 @@ proc install_bender_to_run_dir { } { # Create symlink for ISO image in current run directory. # proc create_symlink_for_iso { } { - exec ln -sfn [pwd]/[run_dir].iso [pwd]/[run_dir]/[run_name].iso + exec ln -sfn [pwd]/[run_dir].[image_extension] [pwd]/[run_dir]/[run_name].[image_extension] } ## @@ -49,21 +69,45 @@ proc update_ipxe_boot_dir { } { } ## -# Create iPXE config file which directly boots an ISO file. +# Create iPXE config file which directly boots an image file. # -proc create_ipxe_iso_config { } { - if {[have_include "image/iso"]} { - set fh [open "[run_dir]/boot.cfg" "WRONLY CREAT TRUNC"] - puts $fh "#!ipxe" - puts $fh "sanboot [run_name].iso || goto failed" - puts $fh "" - puts $fh ":failed" - puts $fh "echo Booting failed, dropping to shell" - puts $fh "shell" - puts $fh "boot" - close $fh - } else { - puts "Warning, iPXE requires ISO image." - exit -1 - } +# Note, the sanboot URI works relative to the script path and honors the former +# protocol too (which must be http:// not tftp://) +# +proc create_ipxe_config { } { + set fh [open "[run_dir]/boot.cfg" "WRONLY CREAT TRUNC"] + puts $fh "#!ipxe" + puts $fh "sanboot [run_name].[image_extension] || goto failed" + puts $fh "" + puts $fh ":failed" + puts $fh "echo Booting failed, dropping to shell" + puts $fh "shell" + puts $fh "boot" + close $fh + + if {![load_ipxe_lighttpd]} { return } + + set conf_file [file normalize [run_dir]/lighttpd.conf] + + set fh [open "$conf_file" "WRONLY CREAT TRUNC"] + puts $fh "server.port = [load_ipxe_lighttpd_port]" + puts $fh "server.document-root = \"[file normalize [run_dir]]\"" + puts $fh "server.errorlog = \"/dev/null\"" + close $fh + + global lighttpd_spawn_id + spawn lighttpd -f $conf_file -D + set lighttpd_spawn_id $spawn_id +} + + +# Override the exit procedure +rename exit load_ipxe_real_exit +proc exit {{status 0}} { + if {[load_ipxe_lighttpd]} { + global lighttpd_spawn_id + kill_spawned $lighttpd_spawn_id + } + + load_ipxe_real_exit $status } diff --git a/tool/run/power_on/qemu b/tool/run/power_on/qemu index 06ebc518fd..d1cf7437a2 100644 --- a/tool/run/power_on/qemu +++ b/tool/run/power_on/qemu @@ -54,18 +54,11 @@ proc board_qemu_args { } { ## # Each line is appended to qemu_args. - # Arguments might be general or restricted to a particular spec as follows: - # general arguments - # arm_v7a: arguments for arm_v7a # set qemu_args "" foreach line [split $file_content "\n"] { - if {[regexp {^([\w]+):(.*)$} $line dummy spec arg]} { - if {[have_spec $spec]} { append qemu_args " $arg" } - } else { # general arguments append qemu_args " $line" - } } return $qemu_args diff --git a/tool/run/run b/tool/run/run index b7cada39d6..93a4e81690 100755 --- a/tool/run/run +++ b/tool/run/run @@ -749,6 +749,16 @@ proc copy_file {src dst} { proc copy_genode_binaries_to_run_dir { binaries } { foreach binary $binaries { + + # + # Normalize kernel-specific file names, needed when a run script passes + # [build_artifacts] to the build_boot_image command. The build artfact + # fetched from the progress.log has the kernel-specific name. + # + foreach name { "timer" "core" "ld.lib.so" } { + if {$binary == [kernel_specific_binary $name silent]} { + set binary $name } } + copy_file bin/[kernel_specific_binary $binary] [run_dir]/genode/$binary } } diff --git a/tool/tool_chain b/tool/tool_chain index 0faba209c7..ac0ad50f7d 100755 --- a/tool/tool_chain +++ b/tool/tool_chain @@ -93,28 +93,22 @@ VERBOSE ?= @ SUDO ?= sudo # -# Check if 'autoconf' is installed +# Check if 'flex' is installed # -# Required version is 2.69, but there is no versioned binary name on Ubuntu -# right now like there has been for version 2.64. +FLEX_OK = $(call check_nonempty_f,$(shell which flex),\ + Need to have 'flex' installed.) + # -AUTOCONF_VERSION = +# Check if 'bison' is installed +# +BISON_OK = $(call check_nonempty_f,$(shell which bison),\ + Need to have 'bison' installed.) -AUTOCONF_VERSION_STRING = "autoconf (GNU Autoconf) $(AUTOCONF_VERSION)" -ifeq ($(shell autoconf -V | grep $(AUTOCONF_VERSION_STRING)),) - ifeq ($(shell which autoconf$(AUTOCONF_VERSION)),) - ifneq ($(shell which autoconf-$(AUTOCONF_VERSION)),) - AUTOCONF = autoconf-$(AUTOCONF_VERSION) - endif - else - AUTOCONF = autoconf$(AUTOCONF_VERSION) - endif -else - AUTOCONF = autoconf -endif - -AUTOCONFINST_OK = $(call check_nonempty_f,$(AUTOCONF),\ - Need to have 'autoconf-$(AUTOCONF_VERSION)' installed.) +# +# Check if 'g++' is installed +# +GXX_OK = $(call check_nonempty_f,$(shell which g++),\ + Need to have 'g++' installed.) # # Check if 'pkg-config' is installed @@ -135,24 +129,6 @@ CURSES_OK = $(call check_equal_f,\ TEXINFO_OK = $(call check_nonempty_f,$(shell which texi2pdf),\ Need to have 'texinfo' installed.) -# -# Check if 'wget' is installed -# -WGET_OK = $(call check_nonempty_f,$(shell which wget),\ - Need to have 'wget' installed.) - -# -# Check if 'autogen' is installed -# -AUTOGEN_OK = $(call check_nonempty_f,$(shell which autogen),\ - Need to have 'autogen' installed.) - -# -# Check if 'gpg' is installed -# -GPG_OK = $(call check_nonempty_f,$(shell which gpg),\ - Need to have 'gpg' installed.) - # # Check if 'libexpat' is installed # @@ -170,8 +146,8 @@ HOST_GCC_VERSION := $(shell gcc -dumpfullversion -dumpversion) GNAT_OK = $(call check_equal_f,$(shell gnatmake --version | sed -n -e 's/GNATMAKE //p'),$(HOST_GCC_VERSION),\ Need to have GNAT installed and the GNAT version must match the GCC version (found GCC $(HOST_GCC_VERSION)).) -TOOLS_OK = $(AUTOCONF_OK) $(AUTOCONFINST_OK) $(PKG_CONFIG_OK) $(CURSES_OK) \ - $(TEXINFO_OK) $(WGET_OK) $(AUTOGEN_OK) $(GPG_OK) $(EXPAT_OK) +TOOLS_OK = $(FLEX_OK) $(BISON_OK) $(GXX_OK) $(PKG_CONFIG_OK) $(CURSES_OK) \ + $(TEXINFO_OK) $(EXPAT_OK) ifneq ($(filter ada,$(ENABLE_FEATURES)),) TOOLS_OK += $(GNAT_OK) $(GPRBUILD_OK) @@ -338,11 +314,7 @@ ALI2DEP_INSTALLED_BINARY ?= $(LOCAL_INSTALL_LOCATION)/bin/genode-$(PLATFORM)-a build_all: $(GCC_INSTALLED_BINARIES) $(GDB_INSTALLED_BINARIES) $(ALI2DEP_INSTALLED_BINARY) -GCC_CONTRIB_DIR = $(shell $(GENODE_DIR)/tool/ports/current gcc)/src/noux-pkg/gcc - -$(GCC_CONTRIB_DIR)/configure: - $(ECHO) "$(BRIGHT_COL)preparing gcc...$(DEFAULT_COL)" - $(VERBOSE)$(GENODE_DIR)/tool/ports/prepare_port gcc +# prepare all ports first to detect more missing tools early BINUTILS_CONTRIB_DIR = $(shell $(GENODE_DIR)/tool/ports/current binutils)/src/noux-pkg/binutils @@ -350,7 +322,29 @@ $(BINUTILS_CONTRIB_DIR)/configure: $(ECHO) "$(BRIGHT_COL)preparing binutils...$(DEFAULT_COL)" $(VERBOSE)$(GENODE_DIR)/tool/ports/prepare_port binutils -$(BUILD_LOCATION)/bootstrap/binutils/Makefile: $(BINUTILS_CONTRIB_DIR)/configure +PREPARED_BINUTILS = $(BINUTILS_CONTRIB_DIR)/configure + +GCC_CONTRIB_DIR = $(shell $(GENODE_DIR)/tool/ports/current gcc)/src/noux-pkg/gcc + +$(GCC_CONTRIB_DIR)/configure: + $(ECHO) "$(BRIGHT_COL)preparing gcc...$(DEFAULT_COL)" + $(VERBOSE)$(GENODE_DIR)/tool/ports/prepare_port gcc + +PREPARED_GCC = $(GCC_CONTRIB_DIR)/configure + +GDB_CONTRIB_DIR = $(shell $(GENODE_DIR)/tool/ports/current gdb)/src/noux-pkg/gdb + +$(GDB_CONTRIB_DIR)/configure: + $(ECHO) "$(BRIGHT_COL)preparing gdb...$(DEFAULT_COL)" + $(VERBOSE)$(GENODE_DIR)/tool/ports/prepare_port gdb + +PREPARED_GDB = $(GDB_CONTRIB_DIR)/configure + +PREPARED_PORTS = $(PREPARED_BINUTILS) $(PREPARED_GCC) $(PREPARED_GDB) + +# bootstrap binutils + +$(BUILD_LOCATION)/bootstrap/binutils/Makefile: $(BINUTILS_CONTRIB_DIR)/configure $(PREPARED_PORTS) $(ECHO) "$(BRIGHT_COL)configuring bootstrap binutils...$(DEFAULT_COL)" $(VERBOSE)mkdir -p $(dir $@) $(VERBOSE)cd $(dir $@); $(BINUTILS_CONTRIB_DIR)/configure $(BINUTILS_BOOTSTRAP_CONFIG) @@ -365,21 +359,7 @@ $(BINUTILS_BOOTSTRAP_INSTALLED_BINARIES): $(BINUTILS_BOOTSTRAP_BINARIES) $(MAKE) -C $(BUILD_LOCATION)/bootstrap/binutils/$$i install-strip; done $(VERBOSE)$(MAKE) -C $(BUILD_LOCATION)/bootstrap/binutils/libiberty install -$(BUILD_LOCATION)/$(PLATFORM)/binutils/Makefile: $(BINUTILS_CONTRIB_DIR)/configure \ - $(GCC_BOOTSTRAP_INSTALLED_BINARIES) - $(ECHO) "$(BRIGHT_COL)configuring binutils...$(DEFAULT_COL)" - $(VERBOSE)mkdir -p $(dir $@) - $(VERBOSE)cd $(dir $@); $(BINUTILS_CONTRIB_DIR)/configure $(BINUTILS_CONFIG) - -$(BINUTILS_BINARIES): $(BUILD_LOCATION)/$(PLATFORM)/binutils/Makefile - $(ECHO) "$(BRIGHT_COL)building binutils...$(DEFAULT_COL)" - $(VERBOSE)$(MAKE) -C $(dir $<) $(MAKE_OPT) -j$(MAKE_JOBS) - -$(BINUTILS_INSTALLED_BINARIES): $(BINUTILS_BINARIES) - $(ECHO) "$(BRIGHT_COL)installing binutils...$(DEFAULT_COL)" - $(VERBOSE)for i in binutils gas ld intl opcodes; do \ - $(MAKE) -C $(BUILD_LOCATION)/$(PLATFORM)/binutils/$$i install-strip $(MAKE_OPT); done - $(VERBOSE)$(MAKE) -C $(BUILD_LOCATION)/$(PLATFORM)/binutils/libiberty install $(MAKE_OPT) +# bootstrap gcc $(BUILD_LOCATION)/bootstrap/gcc/Makefile: $(GCC_CONTRIB_DIR)/configure \ $(BINUTILS_BOOTSTRAP_INSTALLED_BINARIES) @@ -397,6 +377,26 @@ $(GCC_BOOTSTRAP_INSTALLED_BINARIES): $(GCC_BOOTSTRAP_BINARIES) $(ECHO) "$(BRIGHT_COL)installing bootstrap gcc...$(DEFAULT_COL)" $(VERBOSE)$(MAKE) -C $(BUILD_LOCATION)/bootstrap/gcc $(GCC_INSTALL_RULE) +# binutils + +$(BUILD_LOCATION)/$(PLATFORM)/binutils/Makefile: $(BINUTILS_CONTRIB_DIR)/configure \ + $(GCC_BOOTSTRAP_INSTALLED_BINARIES) + $(ECHO) "$(BRIGHT_COL)configuring binutils...$(DEFAULT_COL)" + $(VERBOSE)mkdir -p $(dir $@) + $(VERBOSE)cd $(dir $@); $(BINUTILS_CONTRIB_DIR)/configure $(BINUTILS_CONFIG) + +$(BINUTILS_BINARIES): $(BUILD_LOCATION)/$(PLATFORM)/binutils/Makefile + $(ECHO) "$(BRIGHT_COL)building binutils...$(DEFAULT_COL)" + $(VERBOSE)$(MAKE) -C $(dir $<) $(MAKE_OPT) -j$(MAKE_JOBS) + +$(BINUTILS_INSTALLED_BINARIES): $(BINUTILS_BINARIES) + $(ECHO) "$(BRIGHT_COL)installing binutils...$(DEFAULT_COL)" + $(VERBOSE)for i in binutils gas ld intl opcodes; do \ + $(MAKE) -C $(BUILD_LOCATION)/$(PLATFORM)/binutils/$$i install-strip $(MAKE_OPT); done + $(VERBOSE)$(MAKE) -C $(BUILD_LOCATION)/$(PLATFORM)/binutils/libiberty install $(MAKE_OPT) + +# gcc + $(BUILD_LOCATION)/$(PLATFORM)/gcc/Makefile: $(GCC_CONTRIB_DIR)/configure \ $(BINUTILS_INSTALLED_BINARIES) @@ -418,11 +418,7 @@ $(GCC_INSTALLED_BINARIES): $(GCC_BINARIES) $(ECHO) "$(BRIGHT_COL)installing gcc...$(DEFAULT_COL)" $(VERBOSE)$(MAKE) -C $(BUILD_LOCATION)/$(PLATFORM)/gcc $(GCC_INSTALL_RULE) $(GCC_MAKE_OPT) -GDB_CONTRIB_DIR = $(shell $(GENODE_DIR)/tool/ports/current gdb)/src/noux-pkg/gdb - -$(GDB_CONTRIB_DIR)/configure: - $(ECHO) "$(BRIGHT_COL)preparing gdb...$(DEFAULT_COL)" - $(VERBOSE)$(GENODE_DIR)/tool/ports/prepare_port gdb +# gdb $(BUILD_LOCATION)/$(PLATFORM)/gdb/Makefile: $(GDB_CONTRIB_DIR)/configure $(ECHO) "$(BRIGHT_COL)configuring gdb...$(DEFAULT_COL)" @@ -439,6 +435,7 @@ $(GDB_INSTALLED_BINARIES): $(GDB_BINARIES) $(VERBOSE)$(MAKE) -C $(BUILD_LOCATION)/$(PLATFORM)/gdb install $(MAKE_OPT) MAKEINFO=true $(VEBOSE)strip $@ +# gprbuild $(BUILD_LOCATION)/bootstrap/gprbuild/Makefile: $(ECHO) "$(BRIGHT_COL)preparing bootstrap gprbuild...$(DEFAULT_COL)" @@ -453,6 +450,7 @@ $(GPRBUILD_BOOTSTRAP_INSTALLED_BINARIES): $(BUILD_LOCATION)/bootstrap/gprbuild/M $(VERBOSE)cd $(dir $<); CC=$(LOCAL_BOOTSTRAP_INSTALL_LOCATION)/bin/gcc ./bootstrap.sh \ --with-xmlada=./xmlada --with-kb=./gprconfig_kb --prefix=$(LOCAL_BOOTSTRAP_INSTALL_LOCATION) +# ali2dep $(BUILD_LOCATION)/ali2dep/build/build.gpr: $(ECHO) "$(BRIGHT_COL)preparing ali2dep...$(DEFAULT_COL)" diff --git a/tool/tool_chain_qt5 b/tool/tool_chain_qt5 index 70a87ff9c0..f4331210f0 100755 --- a/tool/tool_chain_qt5 +++ b/tool/tool_chain_qt5 @@ -37,8 +37,9 @@ MAKE_JOBS ?= 4 GENODE_DIR ?= $(realpath $(dir $(firstword $(MAKEFILE_LIST)))/..) CONTRIB_DIR = $(shell $(GENODE_DIR)/tool/ports/current qt5-host) QTBASE_DIR = $(CONTRIB_DIR)/src/lib/qtbase +QTDECLARATIVE_DIR = $(CONTRIB_DIR)/src/lib/qtdeclarative QTTOOLS_DIR = $(CONTRIB_DIR)/src/lib/qttools -TOOL_VERSION = 20.08 +TOOL_VERSION = 22.08 BUILD_DIR = $(GENODE_DIR)/build/tool/qt5/$(TOOL_VERSION) DEFAULT_INSTALL_LOCATION = /usr/local/genode/qt5/$(TOOL_VERSION) INSTALL_LOCATION ?= $(DEFAULT_INSTALL_LOCATION) @@ -79,12 +80,16 @@ $(BUILD_DIR)/qtbase/bin/uic: $(BUILD_DIR)/qtbase/src/Makefile $(BUILD_DIR)/qtbase/bin/qlalr: $(BUILD_DIR)/qtbase/src/Makefile $(VERBOSE)make -C $(BUILD_DIR)/qtbase/src -j$(MAKE_JOBS) sub-qlalr -$(BUILD_DIR)/qtbase/bin/qfloat16-tables: $(BUILD_DIR)/qtbase/src/Makefile - $(VERBOSE)make -C $(BUILD_DIR)/qtbase/src -j$(MAKE_JOBS) sub-qfloat16-tables - $(BUILD_DIR)/qtbase/lib/libQt5Xml.so.5: $(BUILD_DIR)/qtbase/src/Makefile $(VERBOSE)make -C $(BUILD_DIR)/qtbase/src -j$(MAKE_JOBS) sub-xml +$(BUILD_DIR)/qtdeclarative/src/qmltyperegistrar/Makefile: $(QTDECLARATIVE_DIR)/src/qmltyperegistrar/qmltyperegistrar.pro + $(VERBOSE)mkdir -p $(dir $@) + $(VERBOSE)cd $(dir $@) && $(BUILD_DIR)/qtbase/bin/qmake $< + +$(BUILD_DIR)/qtdeclarative/bin/qmltyperegistrar: $(BUILD_DIR)/qtdeclarative/src/qmltyperegistrar/Makefile + $(VERBOSE)make -C $(dir $<) -j$(MAKE_JOBS) + $(BUILD_DIR)/qttools/Makefile: $(QTTOOLS_DIR)/qttools.pro $(BUILD_DIR)/qtbase/lib/libQt5Xml.so.5 $(VERBOSE)mkdir -p $(dir $@) $(VERBOSE)cd $(dir $@) && $(BUILD_DIR)/qtbase/bin/qmake $< @@ -109,7 +114,7 @@ build: $(BUILD_DIR)/qtbase/bin/moc \ $(BUILD_DIR)/qtbase/bin/rcc \ $(BUILD_DIR)/qtbase/bin/uic \ $(BUILD_DIR)/qtbase/bin/qlalr \ - $(BUILD_DIR)/qtbase/bin/qfloat16-tables \ + $(BUILD_DIR)/qtdeclarative/bin/qmltyperegistrar \ $(BUILD_DIR)/qttools/bin/lupdate \ $(BUILD_DIR)/qttools/bin/lrelease @@ -141,8 +146,9 @@ $(INSTALL_LOCATION)/bin/qlalr: $(BUILD_DIR)/qtbase/bin/qlalr $(INSTALL_LOCATION) $(VERBOSE)cd $(BUILD_DIR)/qtbase/src && \ $(SUDO) strip $< -o $@ -$(INSTALL_LOCATION)/bin/qfloat16-tables: $(BUILD_DIR)/qtbase/bin/qfloat16-tables $(INSTALL_LOCATION)/bin - $(VERBOSE)$(SUDO) strip $< -o $@ +$(INSTALL_LOCATION)/bin/qmltyperegistrar: $(BUILD_DIR)/qtdeclarative/bin/qmltyperegistrar $(INSTALL_LOCATION)/bin + $(VERBOSE)cd $(BUILD_DIR)/qtdeclarative/src && \ + $(SUDO) strip $< -o $@ $(INSTALL_LOCATION)/bin/qmake: $(BUILD_DIR)/qtbase/bin/qmake $(INSTALL_LOCATION)/bin $(VERBOSE)$(SUDO) strip $< -o $@ @@ -160,9 +166,9 @@ install: $(INSTALL_LOCATION)/bin/moc \ $(INSTALL_LOCATION)/bin/rcc \ $(INSTALL_LOCATION)/bin/uic \ $(INSTALL_LOCATION)/bin/qlalr \ - $(INSTALL_LOCATION)/bin/qfloat16-tables \ $(INSTALL_LOCATION)/bin/qmake \ $(INSTALL_LOCATION)/bin/syncqt.pl \ + $(INSTALL_LOCATION)/bin/qmltyperegistrar \ $(INSTALL_LOCATION)/bin/lupdate \ $(INSTALL_LOCATION)/bin/lrelease ifeq ($(INSTALL_LOCATION),$(DEFAULT_INSTALL_LOCATION))