L4Re Operating System Framework
Interface and Usage Documentation
Loading...
Searching...
No Matches
virtio-scmi-device
1// vi:ft=cpp
2/* SPDX-License-Identifier: MIT */
3/*
4 * Copyright (C) 2024 Kernkonzept GmbH.
5 * Author(s): Christian Pötzsch <christian.poetzsch@kernkonzept.com>
6 *
7 * License: see LICENSE.spdx (in this directory or the directories above)
8 */
9#pragma once
10
11#include <l4/cxx/bitmap>
12#include <l4/l4virtio/l4virtio>
13#include <l4/l4virtio/server/l4virtio>
14#include <l4/l4virtio/server/virtio>
15#include <l4/re/util/object_registry>
16
17#include <map>
18#include <vector>
19
20namespace L4virtio { namespace Svr { namespace Scmi {
21
23enum
24{
25 Version = 0x20000
26};
27
29enum
30{
31 Success = 0,
32 Not_supported = -1,
33 Invalid_parameters = -2,
34 Denied = -3,
35 Not_found = -4,
36 Out_of_range = -5,
37 Busy = -6,
38 Comms_error = -7,
39 Generic_error = -8,
40 Hardware_error = -9,
41 Protocol_error = -10
42};
43
46{
47 l4_uint32_t hdr_raw = 0;
48 CXX_BITFIELD_MEMBER(18, 27, token, hdr_raw);
49 CXX_BITFIELD_MEMBER(10, 17, protocol_id, hdr_raw);
50 CXX_BITFIELD_MEMBER( 8, 9, message_type, hdr_raw);
51 CXX_BITFIELD_MEMBER( 0, 7, message_id, hdr_raw);
52};
53
55enum
56{
57 Base_protocol = 0x10,
58 Power_domain_management_protocol = 0x11,
59 System_power_management_protocol = 0x12,
60 Performance_domain_management_protocol = 0x13,
61 Clock_management_protocol = 0x14,
62 Sensor_management_protocol = 0x15,
63 Reset_domain_management_protocol = 0x16,
64 Voltage_domain_management_protocol = 0x17
65};
66
68enum
69{
70 Protocol_version = 0x0,
71 Protocol_attributes = 0x1,
72 Protocol_message_attributes = 0x2,
73};
74
76enum
77{
78 Base_discover_vendor = 0x3,
79 Base_discover_sub_vendor = 0x4,
80 Base_discover_implementation_version = 0x5,
81 Base_discover_list_protocols = 0x6,
82 Base_discover_agent = 0x7,
83 Base_notify_errors = 0x8,
84 Base_set_device_permissions = 0x9,
85 Base_set_protocol_permissions = 0xa,
86 Base_reset_agent_configuration = 0xb
87};
88
91{
92 l4_uint32_t attr_raw = 0;
93 CXX_BITFIELD_MEMBER(8, 15, nagents, attr_raw);
94 CXX_BITFIELD_MEMBER(0, 7, nprots, attr_raw);
95};
96
98enum
99{
100 Performance_domain_attributes = 0x3,
101 Performance_describe_levels = 0x4,
102 Performance_limits_set = 0x5,
103 Performance_limits_get = 0x6,
104 Performance_level_set = 0x7,
105 Performance_level_get = 0x8,
106 Performance_notify_limits = 0x9,
107 Performance_notify_level = 0xa,
108 Performance_describe_fastchannel = 0xb,
109};
110
113{
114 l4_uint32_t attr_raw = 0;
115 CXX_BITFIELD_MEMBER(16, 16, power, attr_raw);
116 CXX_BITFIELD_MEMBER( 0, 15, domains, attr_raw);
117
118 l4_uint32_t stat_addr_low = 0;
119 l4_uint32_t stat_addr_high = 0;
120 l4_uint32_t stat_len = 0;
121};
122
125{
126 l4_uint32_t attr_raw = 0;
127 CXX_BITFIELD_MEMBER(31, 31, set_limits, attr_raw);
128 CXX_BITFIELD_MEMBER(30, 30, set_perf_level, attr_raw);
129 CXX_BITFIELD_MEMBER(29, 29, perf_limits_change_notify, attr_raw);
130 CXX_BITFIELD_MEMBER(28, 28, perf_level_change_notify, attr_raw);
131 CXX_BITFIELD_MEMBER(27, 27, fast_channel, attr_raw);
132
133 l4_uint32_t rate_limit_raw = 0;
134 CXX_BITFIELD_MEMBER( 0, 19, rate_limit, rate_limit_raw);
135
136 l4_uint32_t sustained_freq = 0;
137 l4_uint32_t sustained_perf_level = 0;
138 char name[16] = { 0 };
139};
140
143{
144 l4_uint32_t num_levels_raw = 0;
145 CXX_BITFIELD_MEMBER(16, 31, nremain_perf_levels, num_levels_raw);
146 CXX_BITFIELD_MEMBER( 0, 11, nperf_levels, num_levels_raw);
147};
148
151{
152 l4_uint32_t perf_level = 0;
153 l4_uint32_t power_cost = 0;
154 l4_uint16_t trans_latency = 0;
155 l4_uint16_t res0 = 0;
156};
157
158template<typename OBSERV>
159struct Queue_worker : Request_processor
160{
161 Queue_worker(OBSERV *o, Virtqueue *queue)
162 : o(o), q(queue)
163 {}
164
165 bool init_queue()
166 {
167 auto r = q->next_avail();
168
169 if (L4_UNLIKELY(!r))
170 return false;
171
172 head = start(o->mem_info(), r, &req);
173
174 return true;
175 }
176
177 bool next()
178 { return Request_processor::next(o->mem_info(), &req); }
179
180 void finish(l4_uint32_t total)
181 { q->finish(head, o, total); }
182
183 template<typename T>
184 l4_ssize_t read(Data_buffer *buf, T *data, l4_size_t s = sizeof(T))
185 {
186 buf->pos = reinterpret_cast<char *>(data);
187 buf->left = s;
188 l4_size_t chunk = 0;
189 for (;;)
190 {
191 chunk += req.copy_to(buf);
192 if (req.done())
193 next();
194 if (!buf->left)
195 break;
196 }
197 if (chunk != s)
198 return -1;
199 return chunk;
200 }
201
202 template<typename T>
203 l4_ssize_t write(Data_buffer *buf, T *data, l4_size_t s = sizeof(T))
204 {
205 buf->pos = reinterpret_cast<char *>(data);
206 buf->left = s;
207 l4_size_t chunk = 0;
208 for (;;)
209 {
210 chunk += buf->copy_to(&req);
211 if (req.done())
212 next();
213 if (!buf->left)
214 break;
215 }
216 if (chunk != s)
217 return -1;
218 return chunk;
219 }
220
221 l4_ssize_t handle_request()
222 {
223 try
224 {
225 if (!head && L4_UNLIKELY(!init_queue()))
226 return 0;
227
228 for (;;)
229 {
230 l4_ssize_t total = 0;
231 l4_ssize_t res = 0;
232 Scmi_hdr_t hdr;
233 Data_buffer buf = Data_buffer(&hdr);
234 if ((res = read(&buf, &hdr)) < 0)
235 return res;
236
237 // Search/execute handler for given protocol
238 auto proto = o->proto(hdr.protocol_id());
239 if (proto)
240 {
241 if ((res = proto->handle_request(hdr, buf, this)) < 0)
242 return res;
243 total += res;
244 }
245 else
246 {
247 if ((res = write(&buf, &hdr)) < 0)
248 return res;
249 total += res;
250
251 l4_int32_t status = Not_supported;
252 if ((res = write(&buf, &status)) < 0)
253 return res;
254 total += res;
255 }
256
257 finish(total);
258
259 head = Virtqueue::Head_desc();
260 if (L4_UNLIKELY(!init_queue()))
261 return 0;
262 }
263 }
264 catch (L4virtio::Svr::Bad_descriptor const &e)
265 {
266 return e.error;
267 }
268 return 0;
269 }
270
271private:
272 struct Buffer : Data_buffer
273 {
274 Buffer() = default;
275 Buffer(L4virtio::Svr::Driver_mem_region const *r,
276 Virtqueue::Desc const &d, Request_processor const *)
277 {
278 pos = static_cast<char *>(r->local(d.addr));
279 left = d.len;
280 }
281 };
282
284 Virtqueue::Head_desc head;
285 Buffer req;
286
288 OBSERV *o;
289 Virtqueue *q;
290};
291
298template<typename OBSERV>
299struct Proto
300{
301 virtual l4_ssize_t handle_request(Scmi_hdr_t &hdr,
302 Data_buffer &buf,
303 Queue_worker<OBSERV> *qw) = 0;
304};
305
337{
339 {
340 Features() = default;
342 };
343
344 struct Host_irq : public L4::Irqep_t<Host_irq>
345 {
346 Scmi_dev *c;
347 explicit Host_irq(Scmi_dev *c) : c(c) {}
348 void handle_irq() { c->kick(); }
349 };
350
351 enum
352 {
353 Queue_size = 0x10
354 };
355
356public:
358 : L4virtio::Svr::Device(&_dev_config),
359 _dev_config(L4VIRTIO_VENDOR_KK, L4VIRTIO_ID_SCMI, 1),
360 _host_irq(this),
361 _request_worker(this, &_q[0])
362 {
363 init_mem_info(2);
364
365 L4Re::chkcap(registry->register_irq_obj(&_host_irq),
366 "Register irq object");
367
368 Features hf(0);
369 hf.ring_indirect_desc() = true;
370
371 _dev_config.host_features(0) = hf.raw;
372
373 _dev_config.set_host_feature(L4VIRTIO_FEATURE_VERSION_1);
374 _dev_config.reset_hdr();
375
376 reset();
377 }
378
381 { _protos.insert({id, proto}); }
382
383 Proto<Scmi_dev> *proto(l4_uint32_t id) const
384 {
385 if (_protos.find(id) != _protos.end())
386 return _protos.at(id);
387 return nullptr;
388 }
389
390 void notify_queue(L4virtio::Virtqueue *queue)
391 {
392 if (queue->no_notify_guest())
393 return;
394
395 _dev_config.add_irq_status(L4VIRTIO_IRQ_STATUS_VRING);
396 _kick_guest_irq->trigger();
397 }
398
399private:
400 L4::Cap<L4::Irq> device_notify_irq() const override
401 { return L4::cap_cast<L4::Irq>(_host_irq.obj_cap()); }
402
403 void register_single_driver_irq() override
404 {
405 _kick_guest_irq = L4Re::Util::Unique_cap<L4::Irq>(
406 L4Re::chkcap(server_iface()->template rcv_cap<L4::Irq>(0)));
407
408 L4Re::chksys(server_iface()->realloc_rcv_cap(0));
409 }
410
411 void kick()
412 {
413 if (_request_worker.handle_request() < 0)
414 device_error();
415 }
416
417 void reset() override
418 {
419 for (Virtqueue &q : _q)
420 q.disable();
421
422 for (l4_uint32_t i = 0; i < _dev_config.num_queues(); i++)
423 reset_queue_config(i, Queue_size);
424 }
425
426 bool check_queues() override
427 {
428 return true;
429 }
430
431 int reconfig_queue(unsigned idx) override
432 {
433 if (idx >= sizeof(_q) / sizeof(_q[0]))
434 return -L4_ERANGE;
435
436 return setup_queue(_q + idx, idx, Queue_size);
437 }
438
439 void trigger_driver_config_irq() override
440 {
441 _dev_config.add_irq_status(L4VIRTIO_IRQ_STATUS_CONFIG);
442 _kick_guest_irq->trigger();
443 }
444
445 L4virtio::Svr::Dev_config_t<L4virtio::Svr::No_custom_data> _dev_config;
446 Host_irq _host_irq;
447 L4Re::Util::Unique_cap<L4::Irq> _kick_guest_irq;
448 Virtqueue _q[1];
449 Queue_worker<Scmi_dev> _request_worker;
450 std::map<l4_uint32_t, Proto<Scmi_dev> *> _protos;
451};
452
458class Base_proto : public Proto<Scmi_dev>
459{
462 virtual l4_int32_t fill_attr(Base_attr_t *attr) const = 0;
463
465 virtual std::vector<l4_uint32_t> prots() const = 0;
466
467 l4_ssize_t handle_request(Scmi_hdr_t &hdr, Data_buffer &buf,
468 Queue_worker<Scmi_dev> *qw) override
469 {
470 l4_ssize_t total = 0;
471 l4_ssize_t res = 0;
472 switch (hdr.message_id())
473 {
474 case Protocol_version:
475 {
476 if ((res = qw->write(&buf, &hdr)) < 0)
477 return res;
478 total += res;
479
480 struct
481 {
482 l4_int32_t status = Success;
483 l4_uint32_t version = Version;
484 } version;
485 if ((res = qw->write(&buf, &version)) < 0)
486 return res;
487 total += res;
488 break;
489 }
490 case Protocol_attributes:
491 {
492 if ((res = qw->write(&buf, &hdr)) < 0)
493 return res;
494 total += res;
495
496 Base_attr_t ba;
497 l4_int32_t status = fill_attr(&ba);
498 if ((res = qw->write(&buf, &status)) < 0)
499 return res;
500 total += res;
501 if (status == Success)
502 {
503 if ((res = qw->write(&buf, &ba)) < 0)
504 return res;
505 total += res;
506 }
507 break;
508 }
509 case Protocol_message_attributes:
510 {
511 l4_uint32_t msg_id = 0;
512 if ((res = qw->read(&buf, &msg_id)) < 0)
513 return res;
514
515 if ((res = qw->write(&buf, &hdr)) < 0)
516 return res;
517 total += res;
518
519 struct
520 {
521 l4_int32_t status = Not_found;
522 l4_uint32_t attr = 0;
523 } attr;
524 if (msg_id >= Protocol_version &&
525 msg_id <= Base_discover_list_protocols)
526 attr.status = Success;
527
528 if ((res = qw->write(&buf, &attr)) < 0)
529 return res;
530 total += res;
531 break;
532 }
533 case Base_discover_vendor:
534 {
535 if ((res = qw->write(&buf, &hdr)) < 0)
536 return res;
537 total += res;
538
539 struct
540 {
541 l4_int32_t status = Success;
542 l4_uint8_t vendor_identifier[16] = { "L4Re" };
543 } vendor;
544 if ((res = qw->write(&buf, &vendor)) < 0)
545 return res;
546 total += res;
547 break;
548 }
549 case Base_discover_sub_vendor:
550 {
551 if ((res = qw->write(&buf, &hdr)) < 0)
552 return res;
553 total += res;
554
555 struct
556 {
557 l4_int32_t status = Success;
558 l4_uint8_t vendor_identifier[16] = { "Scmi" };
559 } vendor;
560 if ((res = qw->write(&buf, &vendor)) < 0)
561 return res;
562 total += res;
563 break;
564 }
565 case Base_discover_implementation_version:
566 {
567 if ((res = qw->write(&buf, &hdr)) < 0)
568 return res;
569 total += res;
570
571 struct
572 {
573 l4_int32_t status = Success;
574 l4_uint32_t version = 1;
575 } version;
576 if ((res = qw->write(&buf, &version)) < 0)
577 return res;
578 total += res;
579 break;
580 }
581 case Base_discover_list_protocols:
582 {
583 l4_uint32_t skip = 0;
584 if ((res = qw->read(&buf, &skip)) < 0)
585 return res;
586
587 if ((res = qw->write(&buf, &hdr)) < 0)
588 return res;
589 total += res;
590
591 auto p = prots();
592 struct
593 {
594 l4_int32_t status = Success;
595 l4_uint32_t num;
596 } proto;
597 proto.num = p.size();
598 if ((res = qw->write(&buf, &proto)) < 0)
599 return res;
600 total += res;
601
602 // Array of uint32 where 4 protos are packed into one uint32. So
603 // round up to 4 bytes and fill the array byte by byte.
604 l4_uint8_t parr[(p.size() + 3) / 4 * 4] = { 0 };
605 for (l4_size_t i = 0; i < p.size(); i++)
606 parr[i] = p.at(i);
607
608 if ((res = qw->write(&buf, parr, sizeof(parr))) < 0)
609 return res;
610 total += res;
611 break;
612 }
613 default:
614 {
615 if ((res = qw->write(&buf, &hdr)) < 0)
616 return res;
617 total += res;
618
619 l4_int32_t status = Not_supported;
620 if ((res = qw->write(&buf, &status)) < 0)
621 return res;
622 total += res;
623 break;
624 }
625 }
626
627 return total;
628 }
629};
630
662class Perf_proto : public Proto<Scmi_dev>
663{
666 virtual l4_int32_t fill_attr(Performance_attr_t *attr) const = 0;
667
670 virtual l4_int32_t fill_domain_attr(l4_uint32_t domain_id,
671 Performance_domain_attr_t *attr) const = 0;
672
674 virtual l4_int32_t fill_describe_levels_n(l4_uint32_t domain_id,
675 l4_uint32_t level_idx,
676 Performance_describe_levels_n_t *attr) const = 0;
677
680 virtual l4_int32_t fill_describe_levels(l4_uint32_t domain_id,
681 l4_uint32_t level_idx,
682 l4_uint32_t num,
683 Performance_describe_level_t *attr) const = 0;
684
686 virtual l4_int32_t level_set(l4_uint32_t domain_id,
687 l4_uint32_t perf_level) = 0;
688
690 virtual l4_int32_t level_get(l4_uint32_t domain_id,
691 l4_uint32_t *perf_level) const = 0;
692
693 l4_ssize_t handle_request(Scmi_hdr_t &hdr, Data_buffer &buf,
694 Queue_worker<Scmi_dev> *qw) override
695 {
696 l4_ssize_t total = 0;
697 l4_ssize_t res = 0;
698 switch (hdr.message_id())
699 {
700 case Protocol_version:
701 {
702 if ((res = qw->write(&buf, &hdr)) < 0)
703 return res;
704 total += res;
705
706 struct
707 {
708 l4_int32_t status = Success;
709 l4_uint32_t version = Version;
710 } version;
711 if ((res = qw->write(&buf, &version)) < 0)
712 return res;
713 total += res;
714 break;
715 }
716 case Protocol_attributes:
717 {
718 if ((res = qw->write(&buf, &hdr)) < 0)
719 return res;
720 total += res;
721
723 l4_int32_t status = fill_attr(&pa);
724 if ((res = qw->write(&buf, &status)) < 0)
725 return res;
726 total += res;
727 if (status == Success)
728 {
729 if ((res = qw->write(&buf, &pa)) < 0)
730 return res;
731 total += res;
732 }
733 break;
734 }
735 case Protocol_message_attributes:
736 {
737 l4_uint32_t msg_id = 0;
738 if ((res = qw->read(&buf, &msg_id)) < 0)
739 return res;
740
741 if ((res = qw->write(&buf, &hdr)) < 0)
742 return res;
743 total += res;
744
745 struct
746 {
747 l4_int32_t status = Not_found;
748
749 l4_uint32_t attr_raw = 0;
750 CXX_BITFIELD_MEMBER(0, 0, fast_channel, attr_raw); // ignored
751 } attr;
752 if ((msg_id >= Protocol_version &&
753 msg_id <= Performance_describe_levels) ||
754 (msg_id >= Performance_level_set &&
755 msg_id <= Performance_level_get))
756 attr.status = Success;
757
758 if ((res = qw->write(&buf, &attr)) < 0)
759 return res;
760 total += res;
761 break;
762 }
763 case Performance_domain_attributes:
764 {
765 l4_uint32_t domain_id = 0;
766 if ((res = qw->read(&buf, &domain_id)) < 0)
767 return res;
768
769 if ((res = qw->write(&buf, &hdr)) < 0)
770 return res;
771 total += res;
772
774 l4_int32_t status = fill_domain_attr(domain_id, &attr);
775 if ((res = qw->write(&buf, &status)) < 0)
776 return res;
777 total += res;
778 if (status == Success)
779 {
780 if ((res = qw->write(&buf, &attr)) < 0)
781 return res;
782 total += res;
783 }
784 break;
785 }
786 case Performance_describe_levels:
787 {
788 struct
789 {
790 l4_uint32_t domain_id = 0;
791 l4_uint32_t level_idx = 0;
792 } param;
793 if ((res = qw->read(&buf, &param)) < 0)
794 return res;
795
796 if ((res = qw->write(&buf, &hdr)) < 0)
797 return res;
798 total += res;
799
800 // First figure out how many levels we support
802 l4_int32_t status = fill_describe_levels_n(param.domain_id, param.level_idx,
803 &attr);
804 if (status != Success)
805 {
806 // On error bail out early
807 if ((res = qw->write(&buf, &status)) < 0)
808 return res;
809 total += res;
810 break;
811 }
812
813 // Now fetch the actual levels
814 Performance_describe_level_t attr1[attr.nperf_levels().get()];
815 status = fill_describe_levels(param.domain_id, param.level_idx,
816 attr.nperf_levels(), attr1);
817 if ((res = qw->write(&buf, &status)) < 0)
818 return res;
819 total += res;
820 if (status == Success)
821 {
822 // Write both answers to the client
823 if ((res = qw->write(&buf, &attr)) < 0)
824 return res;
825 total += res;
826 if ((res = qw->write(&buf, attr1, sizeof(attr1))) < 0)
827 return res;
828 total += res;
829 }
830 break;
831 }
832 case Performance_level_set:
833 {
834 struct
835 {
836 l4_uint32_t domain_id;
837 l4_uint32_t perf_level;
838 } param;
839 if ((res = qw->read(&buf, &param)) < 0)
840 return res;
841
842 if ((res = qw->write(&buf, &hdr)) < 0)
843 return res;
844 total += res;
845
846 l4_int32_t status = level_set(param.domain_id, param.perf_level);
847 if ((res = qw->write(&buf, &status)) < 0)
848 return res;
849 total += res;
850 break;
851 }
852 case Performance_level_get:
853 {
854 l4_uint32_t domain_id = 0;
855 if ((res = qw->read(&buf, &domain_id)) < 0)
856 return res;
857
858 if ((res = qw->write(&buf, &hdr)) < 0)
859 return res;
860 total += res;
861
862 l4_uint32_t perf_level;
863 l4_int32_t status = level_get(domain_id, &perf_level);
864 if ((res = qw->write(&buf, &status)) < 0)
865 return res;
866 total += res;
867 if (status == Success)
868 {
869 if ((res = qw->write(&buf, &perf_level)) < 0)
870 return res;
871 total += res;
872 }
873 break;
874 }
875 default:
876 {
877 if ((res = qw->write(&buf, &hdr)) < 0)
878 return res;
879 total += res;
880
881 l4_int32_t status = Not_supported;
882 if ((res = qw->write(&buf, &status)) < 0)
883 return res;
884 total += res;
885 break;
886 }
887 }
888 return total;
889 }
890};
891
892} /* Scmi */ } /* Svr */ } /* L4virtio */
A registry that manages server objects and their attached IPC gates for a single server loop for a sp...
L4::Cap< L4::Irq > register_irq_obj(L4::Epiface *o) override
Register a handler for an interrupt.
C++ interface for capabilities.
Definition capability.h:219
Server-side L4-VIRTIO device stub.
Definition l4virtio:796
void device_error()
Transition device into DEVICE_NEEDS_RESET state.
Definition l4virtio:1018
bool setup_queue(Virtqueue *q, unsigned qn, unsigned num_max)
Enable/disable the specified queue.
Definition l4virtio:1041
void init_mem_info(unsigned num)
Initialize the memory region list to the given maximum.
Definition l4virtio:1006
void reset_queue_config(unsigned idx, unsigned num_max, bool inc_generation=false)
Trigger reset for the configuration space for queue idx.
Definition l4virtio:996
Encapsulate the state for processing a VIRTIO request.
Definition virtio:454
bool next(DESC_MAN *dm, ARGS... args)
Switch to the next descriptor in a descriptor chain.
Definition virtio:551
void start(DESC_MAN *dm, Virtqueue *ring, Virtqueue::Head_desc const &request, ARGS... args)
Start processing a new request.
Definition virtio:482
Base class for the SCMI base protocol.
Base class for the SCMI performance protocol.
A server implementation of the virtio-scmi protocol.
void add_proto(l4_uint32_t id, Proto< Scmi_dev > *proto)
Add an actual protocol implementation with the given id to the server.
Virtqueue implementation for the device.
Definition virtio:88
Low-level Virtqueue.
Definition virtqueue:88
bool no_notify_guest() const
Get the no IRQ flag of this queue.
Definition virtqueue:420
unsigned int l4_size_t
Unsigned size type.
Definition l4int.h:35
signed int l4_int32_t
Signed 32bit value.
Definition l4int.h:39
unsigned char l4_uint8_t
Unsigned 8bit value.
Definition l4int.h:36
signed int l4_ssize_t
Signed size type.
Definition l4int.h:36
unsigned int l4_uint32_t
Unsigned 32bit value.
Definition l4int.h:40
unsigned short int l4_uint16_t
Unsigned 16bit value.
Definition l4int.h:38
@ L4_ERANGE
Range error.
Definition err.h:59
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
Definition compiler.h:296
@ L4VIRTIO_FEATURE_VERSION_1
Virtio protocol version 1 supported. Must be 1 for L4virtio.
Definition virtio.h:98
@ L4VIRTIO_ID_SCMI
Scmi device.
Definition virtio.h:78
@ L4VIRTIO_IRQ_STATUS_VRING
VRING IRQ pending flag.
Definition virtio.h:109
@ L4VIRTIO_IRQ_STATUS_CONFIG
CONFIG IRQ pending flag.
Definition virtio.h:110
L4::Detail::Unique_cap_impl< T, Smart_cap_auto< L4_FP_ALL_SPACES > > Unique_cap
Unique capability that implements automatic free and unmap of the capability selector.
Definition unique_cap:54
long chksys(long err, char const *extra="", long ret=0)
Generate C++ exception on error.
Definition error_helper:68
T chkcap(T &&cap, char const *extra="", long err=-L4_ENOMEM)
Check for valid capability or raise C++ exception.
Definition error_helper:145
L4-VIRTIO Transport C++ API.
Definition l4virtio:26
Epiface implementation for interrupt handlers.
Definition ipc_epiface:294
Exception used by Queue to indicate descriptor errors.
Definition virtio:379
Abstract data buffer.
Definition virtio:288
l4_uint32_t left
Bytes left in buffer.
Definition virtio:290
char * pos
Current buffer position.
Definition virtio:289
Type for device feature bitmap.
Definition virtio:67
l4_uint32_t raw
The raw value of the features bitmap.
Definition virtio:68
SCMI base protocol attributes.
constexpr nagents_bfm_t::Val nagents() const
Get the nagents bits ( 8 to 15 ) of attr_raw.
constexpr nprots_bfm_t::Val nprots() const
Get the nprots bits ( 0 to 7 ) of attr_raw.
SCMI performance protocol attributes.
constexpr power_bfm_t::Val power() const
Get the power bits ( 16 to 16 ) of attr_raw.
constexpr domains_bfm_t::Val domains() const
Get the domains bits ( 0 to 15 ) of attr_raw.
SCMI performance describe levels numbers.
constexpr nperf_levels_bfm_t::Val nperf_levels() const
Get the nperf_levels bits ( 0 to 11 ) of num_levels_raw.
constexpr nremain_perf_levels_bfm_t::Val nremain_perf_levels() const
Get the nremain_perf_levels bits ( 16 to 31 ) of num_levels_raw.
SCMI performance domain protocol attributes.
constexpr perf_limits_change_notify_bfm_t::Val perf_limits_change_notify() const
Get the perf_limits_change_notify bits ( 29 to 29 ) of attr_raw.
constexpr set_perf_level_bfm_t::Val set_perf_level() const
Get the set_perf_level bits ( 30 to 30 ) of attr_raw.
constexpr fast_channel_bfm_t::Val fast_channel() const
Get the fast_channel bits ( 27 to 27 ) of attr_raw.
constexpr rate_limit_bfm_t::Val rate_limit() const
Get the rate_limit bits ( 0 to 19 ) of rate_limit_raw.
constexpr perf_level_change_notify_bfm_t::Val perf_level_change_notify() const
Get the perf_level_change_notify bits ( 28 to 28 ) of attr_raw.
constexpr set_limits_bfm_t::Val set_limits() const
Get the set_limits bits ( 31 to 31 ) of attr_raw.
Base class for all protocols.
constexpr token_bfm_t::Val token() const
Get the token bits ( 18 to 27 ) of hdr_raw.
constexpr message_type_bfm_t::Val message_type() const
Get the message_type bits ( 8 to 9 ) of hdr_raw.
constexpr message_id_bfm_t::Val message_id() const
Get the message_id bits ( 0 to 7 ) of hdr_raw.
constexpr protocol_id_bfm_t::Val protocol_id() const
Get the protocol_id bits ( 10 to 17 ) of hdr_raw.