ReactOS 0.4.17-dev-683-g0dafdc5
io.c
Go to the documentation of this file.
1#include <uacpi/internal/io.h>
8
9#ifndef UACPI_BAREBONES_MODE
10
12{
13 return UACPI_ALIGN_UP(bit_length, 8, uacpi_size) / 8;
14}
15
18)
19{
20 uacpi_u8 remainder = bit_length & 7;
21
22 if (remainder == 0)
23 return;
24
25 data[offset] &= ((1ull << remainder) - 1);
26}
27
29{
30 union {
33 };
36};
37
39{
40 uacpi_size delta = UACPI_MIN(span->length, bits);
41
42 span->index += delta;
43 span->length -= delta;
44
45 return delta;
46}
47
48static void bit_copy(struct bit_span *dst, struct bit_span *src)
49{
50 uacpi_u8 src_shift, dst_shift, bits = 0;
51 uacpi_u16 dst_mask;
52 uacpi_u8 *dst_ptr, *src_ptr;
53 uacpi_u64 dst_count, src_count;
54
55 dst_ptr = dst->data + (dst->index / 8);
56 src_ptr = src->data + (src->index / 8);
57
58 dst_count = dst->length;
59 dst_shift = dst->index & 7;
60
61 src_count = src->length;
62 src_shift = src->index & 7;
63
64 while (dst_count)
65 {
66 bits = 0;
67
68 if (src_count) {
69 bits = *src_ptr >> src_shift;
70
71 if (src_shift && src_count > (uacpi_u32)(8 - src_shift))
72 bits |= *(src_ptr + 1) << (8 - src_shift);
73
74 if (src_count < 8) {
75 bits &= (1 << src_count) - 1;
76 src_count = 0;
77 } else {
78 src_count -= 8;
79 src_ptr++;
80 }
81 }
82
83 dst_mask = (dst_count < 8 ? (1 << dst_count) - 1 : 0xFF) << dst_shift;
84 *dst_ptr = (*dst_ptr & ~dst_mask) | ((bits << dst_shift) & dst_mask);
85
86 if (dst_shift && dst_count > (uacpi_u32)(8 - dst_shift)) {
87 dst_mask >>= 8;
88 *(dst_ptr + 1) &= ~dst_mask;
89 *(dst_ptr + 1) |= (bits >> (8 - dst_shift)) & dst_mask;
90 }
91
92 dst_count = dst_count > 8 ? dst_count - 8 : 0;
93 ++dst_ptr;
94 }
95}
96
99)
100{
101 struct bit_span src_span = { 0 };
102 struct bit_span dst_span = { 0 };
103
104 src_span.index = field->bit_index;
105 src_span.length = field->bit_length;
106 src_span.const_data = field->backing->data;
107
108 dst_span.data = dst;
109 dst_span.length = uacpi_round_up_bits_to_bytes(field->bit_length) * 8;
110 bit_copy(&dst_span, &src_span);
111}
112
114 const uacpi_buffer_field *field, void *dst
115)
116{
117 if (!(field->bit_index & 7)) {
118 uacpi_u8 *src = field->backing->data;
120
122 uacpi_memcpy(dst, src + (field->bit_index / 8), count);
123 cut_misaligned_tail(dst, count - 1, field->bit_length);
124 return;
125 }
126
128}
129
132 const void *src, uacpi_size size
133)
134{
135 struct bit_span src_span = { 0 };
136 struct bit_span dst_span = { 0 };
137
138 src_span.length = size * 8;
139 src_span.const_data = src;
140
141 dst_span.index = field->bit_index;
142 dst_span.length = field->bit_length;
143 dst_span.data = field->backing->data;
144
145 bit_copy(&dst_span, &src_span);
146}
147
150 const void *src, uacpi_size size
151)
152{
153 if (!(field->bit_index & 7)) {
154 uacpi_u8 *dst, last_byte, tail_shift;
156
157 dst = field->backing->data;
158 dst += field->bit_index / 8;
160
161 last_byte = dst[count - 1];
162 tail_shift = field->bit_length & 7;
163
165 if (tail_shift) {
166 uacpi_u8 last_shift = 8 - tail_shift;
167 dst[count - 1] = dst[count - 1] << last_shift;
168 dst[count - 1] >>= last_shift;
169 dst[count - 1] |= (last_byte >> tail_shift) << tail_shift;
170 }
171
172 return;
173 }
174
176}
177
179{
180 if (field->lock_rule)
181 return UACPI_TRUE;
182
183 /*
184 * The global lock must be acquired before the opregion lock, however,
185 * the subfields of an index/bank field are only accessed once the
186 * opregion lock is already held, so their lock rules have to be
187 * considered upfront to keep the ordering consistent.
188 */
189 switch (field->kind) {
191 return field_unit_needs_global_lock(field->index) ||
194 return field_unit_needs_global_lock(field->bank_selection);
195 default:
196 return UACPI_FALSE;
197 }
198}
199
200/*
201 * Both the global lock and the opregion lock are held for the duration of
202 * an entire field transaction (that is, across every hardware access it
203 * decomposes into) instead of individual data accesses:
204 * - The global lock protects fields shared with firmware (e.g. SMM), which
205 * expects multi-datum accesses and read-modify-writes to be atomic.
206 * - The opregion lock makes the index/bank selection register writes atomic
207 * with respect to the data accesses that rely on them, which could
208 * otherwise interleave with IO done by other threads, as every other lock
209 * is dropped around address space handler invocations.
210 */
212{
214
217 g_uacpi_rt_ctx.global_lock_mutex, 0xFFFF
218 );
220 return ret;
221 }
222
225 uacpi_release_aml_mutex(g_uacpi_rt_ctx.global_lock_mutex);
226
227 return ret;
228}
229
231{
233
235 uacpi_release_aml_mutex(g_uacpi_rt_ctx.global_lock_mutex);
236}
237
239{
240 if (field->bit_length >= 64)
241 return UACPI_TRUE;
242
243 return value < ((uacpi_u64)1 << field->bit_length);
244}
245
249)
250{
252
253 switch (field->kind) {
255 if (uacpi_unlikely(!field_fits(field->bank_selection,
256 field->bank_value))) {
258 "bank value 0x%"UACPI_PRIX64" doesn't fit in the %u-bit "
259 "bank register", UACPI_FMT64(field->bank_value),
260 field->bank_selection->bit_length
261 );
263 }
264
266 field->bank_selection, &field->bank_value, sizeof(field->bank_value),
268 );
269 break;
271 break;
273 if (uacpi_unlikely(!field_fits(field->index, offset))) {
275 "offset 0x%X doesn't fit in the %u-bit index register",
276 offset, field->index->bit_length
277 );
279 }
280
282 field->index, &offset, sizeof(offset),
284 );
286 return ret;
287
288 switch (op) {
291 field->data, data.integer, field->access_width_bytes,
293 );
296 field->data, data.integer, field->access_width_bytes,
298 );
299 default:
301 }
302
303 default:
304 uacpi_error("invalid field unit kind %d", field->kind);
306 }
307
309 return ret;
310
312}
313
314#define SERIAL_HEADER_SIZE 2
315#define IPMI_DATA_SIZE 64
316
320)
321{
322 switch (space) {
325 break;
327 *out_size = 26;
328 break;
330 *out_size = 256;
331 break;
334 uacpi_size size_for_protocol = SERIAL_HEADER_SIZE;
335
336 switch (field->attributes) {
338 break; // + 0
341 size_for_protocol += 1;
342 break;
343
346 size_for_protocol += 2;
347 break;
348
350 size_for_protocol += field->access_length;
351 break;
352
357 size_for_protocol += 255;
358 break;
359
360 default:
362 "unsupported field@%p access attribute %d",
363 field, field->attributes
364 );
366 }
367
368 *out_size = size_for_protocol;
369 break;
370 }
371 default:
373 }
374
375 return UACPI_STATUS_OK;
376}
377
380 uacpi_region_op op, uacpi_data_view *wtr_response,
381 uacpi_bool *did_handle
382)
383{
387 uacpi_u64 in_out;
388 uacpi_data_view wtr_buffer;
390
391 *did_handle = UACPI_FALSE;
392
394 return ret;
395
398 );
399 if (uacpi_unlikely(obj == UACPI_NULL)) {
402 field->region, "attempted access to deleted", ret
403 );
404 goto out_handled;
405 }
406 region = obj->op_region;
407
408 switch (region->space) {
410 if (op == UACPI_REGION_OP_WRITE) {
412 &in_out, buf.const_data, sizeof(in_out), buf.length
413 );
414 }
415
416 data.integer = &in_out;
419 goto out_handled;
420
422 uacpi_memcpy_zerout(buf.data, &in_out, buf.length, sizeof(in_out));
423 goto out_handled;
429 field->region, "attempted to read from a write-only", ret
430 );
431 goto out_handled;
432 }
437 goto do_wtr;
438 default:
439 return ret;
440 }
441
442do_wtr:
443 ret = wtr_buffer_size(field, region->space, &wtr_buffer.length);
445 goto out_handled;
446
447 wtr_buffer.data = uacpi_kernel_alloc(wtr_buffer.length);
448 if (uacpi_unlikely(wtr_buffer.data == UACPI_NULL)) {
450 goto out_handled;
451 }
452
454 wtr_buffer.data, buf.const_data, wtr_buffer.length, buf.length
455 );
456 data.buffer = wtr_buffer;
458 field, field->byte_offset,
459 op, data
460 );
462 uacpi_free(wtr_buffer.data, wtr_buffer.length);
463 goto out_handled;
464 }
465
466 if (wtr_response != UACPI_NULL)
467 *wtr_response = wtr_buffer;
468 else
469 uacpi_free(wtr_buffer.data, wtr_buffer.length);
470
471out_handled:
472 *did_handle = UACPI_TRUE;
473 return ret;
474}
475
478)
479{
481 uacpi_size reads_to_do;
483 uacpi_u32 byte_offset = field->byte_offset;
484 uacpi_u32 bits_left = field->bit_length;
485 uacpi_u8 width_access_bits = field->access_width_bytes * 8;
486
487 struct bit_span src_span = { 0 };
488 struct bit_span dst_span = { 0 };
489
490 src_span.data = (uacpi_u8*)&out;
491 src_span.index = field->bit_offset_within_first_byte;
492
493 dst_span.data = dst;
494 dst_span.index = 0;
495 dst_span.length = size * 8;
496
497 reads_to_do = UACPI_ALIGN_UP(
498 field->bit_offset_within_first_byte + field->bit_length,
499 width_access_bits,
501 );
502 reads_to_do /= width_access_bits;
503
504 while (reads_to_do-- > 0) {
506
507 src_span.length = UACPI_MIN(
508 bits_left, width_access_bits - src_span.index
509 );
510
511 data.integer = &out;
513 field, byte_offset, UACPI_REGION_OP_READ,
514 data
515 );
517 return ret;
518
519 bit_copy(&dst_span, &src_span);
520 bits_left -= src_span.length;
521 src_span.index = 0;
522
523 bit_span_offset(&dst_span, src_span.length);
524 byte_offset += field->access_width_bytes;
525 }
526
527 return UACPI_STATUS_OK;
528}
529
532 uacpi_data_view *wtr_response
533)
534{
536 uacpi_u32 field_byte_length;
537 uacpi_bool did_handle;
538 uacpi_data_view data_view = { 0 };
539
540 data_view.data = dst;
541 data_view.length = size;
542
545 return ret;
546
548 field, data_view, UACPI_REGION_OP_READ,
549 wtr_response, &did_handle
550 );
551 if (did_handle)
552 goto out;
553
554 field_byte_length = uacpi_round_up_bits_to_bytes(field->bit_length);
555
556 /*
557 * Very simple fast case:
558 * - Bit offset within first byte is 0
559 * AND
560 * - Field size is <= access width
561 */
562 if (field->bit_offset_within_first_byte == 0 &&
563 field_byte_length <= field->access_width_bytes)
564 {
567
568 data.integer = &out;
570 field, field->byte_offset, UACPI_REGION_OP_READ,
571 data
572 );
574 goto out;
575
576 uacpi_memcpy_zerout(dst, &out, size, field_byte_length);
577 if (size >= field_byte_length)
578 cut_misaligned_tail(dst, field_byte_length - 1, field->bit_length);
579
580 goto out;
581 }
582
583 // Slow case
585
586out:
588 return ret;
589}
590
593)
594{
596 uacpi_u32 bits_left, byte_offset = field->byte_offset;
597 uacpi_u8 width_access_bits = field->access_width_bytes * 8;
599 struct bit_span src_span = { 0 };
600 struct bit_span dst_span = { 0 };
601
602 src_span.const_data = src;
603 src_span.index = 0;
604 src_span.length = size * 8;
605
606 dst_span.data = (uacpi_u8 *)&in;
607 dst_span.index = field->bit_offset_within_first_byte;
608
609 bits_left = field->bit_length;
610
611 while (bits_left) {
613
614 in = 0;
615 dst_span.length = UACPI_MIN(
616 width_access_bits - dst_span.index, bits_left
617 );
618
619 if (dst_span.index != 0 || dst_span.length < width_access_bits) {
620 switch (field->update_rule) {
622 data.integer = &in;
624 field, byte_offset, UACPI_REGION_OP_READ,
625 data
626 );
628 return ret;
629 break;
631 in = ~in;
632 break;
634 break;
635 default:
636 uacpi_error("invalid field@%p update rule %d",
637 field, field->update_rule);
639 }
640 }
641
642 bit_copy(&dst_span, &src_span);
643 bit_span_offset(&src_span, dst_span.length);
644
645 data.integer = &in;
646
648 field, byte_offset, UACPI_REGION_OP_WRITE,
649 data
650 );
652 return ret;
653
654 bits_left -= dst_span.length;
655 dst_span.index = 0;
656 byte_offset += field->access_width_bytes;
657 }
658
659 return UACPI_STATUS_OK;
660}
661
664 uacpi_data_view *wtr_response
665)
666{
668 uacpi_bool did_handle;
669 uacpi_data_view data_view = { 0 };
670
671 data_view.const_data = src;
672 data_view.length = size;
673
676 return ret;
677
679 field, data_view, UACPI_REGION_OP_WRITE,
680 wtr_response, &did_handle
681 );
682 if (did_handle)
683 goto out;
684
686
687out:
689 return ret;
690}
691
693 struct uacpi_field_unit *field, uacpi_object_type *out_type
694)
695{
697
699 goto out_basic_field;
700
703 );
706
707 if (uacpi_is_buffer_access_address_space(obj->op_region->space)) {
708 *out_type = UACPI_OBJECT_BUFFER;
709 return UACPI_STATUS_OK;
710 }
711
712out_basic_field:
713 if (field->bit_length > (g_uacpi_rt_ctx.is_rev1 ? 32u : 64u))
714 *out_type = UACPI_OBJECT_BUFFER;
715 else
716 *out_type = UACPI_OBJECT_INTEGER;
717
718 return UACPI_STATUS_OK;
719}
720
722 struct uacpi_field_unit *field, uacpi_size *out_length
723)
724{
726
728 goto out_basic_field;
729
732 );
735
736 if (uacpi_is_buffer_access_address_space(obj->op_region->space)) {
737 /*
738 * Bit length is protocol specific, the data will be returned
739 * via the write-then-read response buffer.
740 */
741 *out_length = 0;
742 return UACPI_STATUS_OK;
743 }
744
745out_basic_field:
746 *out_length = field->bit_length;
747 return UACPI_STATUS_OK;
748}
749
750static uacpi_u8 gas_get_access_bit_width(const struct acpi_gas *gas)
751{
752 /*
753 * Same algorithm as ACPICA.
754 *
755 * The reason we do this is apparently GAS bit offset being non-zero means
756 * that it's an APEI register, as opposed to FADT, which needs special
757 * handling. In the case of a FADT register we want to ignore the specified
758 * access size.
759 */
760 uacpi_u8 access_bit_width;
761
762 if (gas->register_bit_offset == 0 &&
763 UACPI_IS_POWER_OF_TWO(gas->register_bit_width, uacpi_u8) &&
764 UACPI_IS_ALIGNED(gas->register_bit_width, 8, uacpi_u8)) {
765 access_bit_width = gas->register_bit_width;
766 } else if (gas->access_size) {
767 access_bit_width = gas->access_size * 8;
768 } else {
769 uacpi_u8 msb;
770
772 (gas->register_bit_offset + gas->register_bit_width) - 1
773 );
774 access_bit_width = 1 << msb;
775
776 if (access_bit_width <= 8) {
777 access_bit_width = 8;
778 } else {
779 /*
780 * Keep backing off to previous power of two until we find one
781 * that is aligned to the address specified in GAS.
782 */
783 while (!UACPI_IS_ALIGNED(
784 gas->address, access_bit_width / 8, uacpi_u64
785 ))
786 access_bit_width /= 2;
787 }
788 }
789
790 return UACPI_MIN(
791 access_bit_width,
792 gas->address_space_id == UACPI_ADDRESS_SPACE_SYSTEM_IO ? 32 : 64
793 );
794}
795
797 const struct acpi_gas *gas, uacpi_u8 *access_bit_width,
798 uacpi_u8 *bit_width
799)
800{
801 uacpi_size total_width, aligned_width;
802
803 if (uacpi_unlikely(gas == UACPI_NULL))
805
806 if (!gas->address)
808
809 if (gas->address_space_id != UACPI_ADDRESS_SPACE_SYSTEM_IO &&
810 gas->address_space_id != UACPI_ADDRESS_SPACE_SYSTEM_MEMORY) {
811 uacpi_warn("unsupported GAS address space '%s' (%d)",
812 uacpi_address_space_to_string(gas->address_space_id),
813 gas->address_space_id);
815 }
816
817 if (gas->access_size > 4) {
818 uacpi_warn("unsupported GAS access size %d",
819 gas->access_size);
821 }
822
823 *access_bit_width = gas_get_access_bit_width(gas);
824
825 total_width = gas->register_bit_offset + gas->register_bit_width;
826 aligned_width = UACPI_ALIGN_UP(total_width, *access_bit_width, uacpi_size);
827
828 if (uacpi_unlikely(aligned_width > 64)) {
830 "GAS register total width is too large: %zu", total_width
831 );
833 }
834
835 *bit_width = total_width;
836 return UACPI_STATUS_OK;
837}
838
839/*
840 * Apparently both reading and writing GAS works differently from operation
841 * region in that bit offsets are not respected when writing the data.
842 *
843 * Let's follow ACPICA's approach here so that we don't accidentally
844 * break any quirky hardware.
845 */
847 const uacpi_mapped_gas *gas, uacpi_u64 *out_value
848)
849{
851 uacpi_u8 access_byte_width;
852 uacpi_u8 bit_offset, bits_left, index = 0;
853 uacpi_u64 data, mask = 0xFFFFFFFFFFFFFFFF;
854 uacpi_size offset = 0;
855
856 bit_offset = gas->bit_offset;
857 bits_left = gas->total_bit_width;
858
859 access_byte_width = gas->access_bit_width / 8;
860
861 if (access_byte_width < 8)
862 mask = ~(mask << gas->access_bit_width);
863
864 *out_value = 0;
865
866 while (bits_left) {
867 if (bit_offset >= gas->access_bit_width) {
868 data = 0;
869 bit_offset -= gas->access_bit_width;
870 } else {
871 ret = gas->read(gas->mapping, offset, access_byte_width, &data);
873 return ret;
874 }
875
876 *out_value |= (data & mask) << (index * gas->access_bit_width);
877 bits_left -= UACPI_MIN(bits_left, gas->access_bit_width);
878 ++index;
879 offset += access_byte_width;
880 }
881
882 return UACPI_STATUS_OK;
883}
884
886 const uacpi_mapped_gas *gas, uacpi_u64 in_value
887)
888{
890 uacpi_u8 access_byte_width;
891 uacpi_u8 bit_offset, bits_left, index = 0;
892 uacpi_u64 data, mask = 0xFFFFFFFFFFFFFFFF;
893 uacpi_size offset = 0;
894
895 bit_offset = gas->bit_offset;
896 bits_left = gas->total_bit_width;
897 access_byte_width = gas->access_bit_width / 8;
898
899 if (access_byte_width < 8)
900 mask = ~(mask << gas->access_bit_width);
901
902 while (bits_left) {
903 data = (in_value >> (index * gas->access_bit_width)) & mask;
904
905 if (bit_offset >= gas->access_bit_width) {
906 bit_offset -= gas->access_bit_width;
907 } else {
908 ret = gas->write(gas->mapping, offset, access_byte_width, data);
910 return ret;
911 }
912
913 bits_left -= UACPI_MIN(bits_left, gas->access_bit_width);
914 ++index;
915 offset += access_byte_width;
916 }
917
918 return UACPI_STATUS_OK;
919}
920
922{
924 uacpi_kernel_io_unmap(io_handle);
925}
926
928 const struct acpi_gas *gas, uacpi_mapped_gas *out_mapped
929)
930{
932 uacpi_u8 access_bit_width, total_width;
933
934 ret = gas_validate(gas, &access_bit_width, &total_width);
935 if (ret != UACPI_STATUS_OK)
936 return ret;
937
938 if (gas->address_space_id == UACPI_ADDRESS_SPACE_SYSTEM_MEMORY) {
939 out_mapped->mapping = uacpi_kernel_map(gas->address, total_width / 8);
940 if (uacpi_unlikely(out_mapped->mapping == UACPI_MAP_FAILED))
942
943 out_mapped->read = uacpi_system_memory_read;
944 out_mapped->write = uacpi_system_memory_write;
945 out_mapped->unmap = uacpi_kernel_unmap;
946 } else { // IO, validated by gas_validate above
947 ret = uacpi_kernel_io_map(gas->address, total_width / 8, &out_mapped->mapping);
949 return ret;
950
951 out_mapped->read = uacpi_system_io_read;
952 out_mapped->write = uacpi_system_io_write;
953 out_mapped->unmap = unmap_gas_io;
954 }
955
956 out_mapped->access_bit_width = access_bit_width;
957 out_mapped->total_bit_width = total_width;
958 out_mapped->bit_offset = gas->register_bit_offset;
959
960 return UACPI_STATUS_OK;
961}
962
964 const struct acpi_gas *gas, uacpi_mapped_gas **out_mapped
965)
966{
969
973
976 uacpi_free(mapping, sizeof(*mapping));
977 return ret;
978 }
979
980 *out_mapped = mapping;
981 return ret;
982}
983
985{
986 gas->unmap(gas->mapping, gas->access_bit_width / 8);
987}
988
990{
992 uacpi_free(gas, sizeof(*gas));
993}
994
995uacpi_status uacpi_gas_read(const struct acpi_gas *gas, uacpi_u64 *out_value)
996{
999
1002 return ret;
1003
1004 ret = uacpi_gas_read_mapped(&mapping, out_value);
1006
1007 return ret;
1008}
1009
1010uacpi_status uacpi_gas_write(const struct acpi_gas *gas, uacpi_u64 in_value)
1011{
1014
1017 return ret;
1018
1019 ret = uacpi_gas_write_mapped(&mapping, in_value);
1021
1022 return ret;
1023}
1024
1025#ifndef UACPI_NATIVE_MMIO
1027{
1028 return *(volatile uacpi_u8*)ptr;
1029}
1030
1032{
1033 return *(volatile uacpi_u16*)ptr;
1034}
1035
1037{
1038 return *(volatile uacpi_u32*)ptr;
1039}
1040
1042{
1043 return *(volatile uacpi_u64*)ptr;
1044}
1045
1047{
1048 *(volatile uacpi_u8*)ptr = data;
1049}
1050
1052{
1053 *(volatile uacpi_u16*)ptr = data;
1054}
1055
1057{
1058 *(volatile uacpi_u32*)ptr = data;
1059}
1060
1062{
1063 *(volatile uacpi_u64*)ptr = data;
1064}
1065#endif
1066
1069)
1070{
1072
1073 switch (width) {
1074 case 1:
1076 break;
1077 case 2:
1079 break;
1080 case 4:
1082 break;
1083 case 8:
1085 break;
1086 default:
1088 }
1089
1090 return UACPI_STATUS_OK;
1091}
1092
1095)
1096{
1098
1099 switch (width) {
1100 case 1:
1102 break;
1103 case 2:
1105 break;
1106 case 4:
1108 break;
1109 case 8:
1111 break;
1112 default:
1114 }
1115
1116 return UACPI_STATUS_OK;
1117}
1118
1124};
1125
1128)
1129{
1131 union integer_data data = {
1132 .qword = 0,
1133 };
1134
1135 switch (width) {
1136 case 1:
1138 break;
1139 case 2:
1141 break;
1142 case 4:
1144 break;
1145 default:
1147 "invalid SystemIO read %p@%zu width=%d",
1149 );
1151 }
1152
1154 *out = data.qword;
1155 return ret;
1156}
1157
1160)
1161{
1163
1164 switch (width) {
1165 case 1:
1167 break;
1168 case 2:
1170 break;
1171 case 4:
1173 break;
1174 default:
1176 "invalid SystemIO write %p@%zu width=%d",
1178 );
1180 }
1181
1182 return ret;
1183}
1184
1187)
1188{
1190 union integer_data data = {
1191 .qword = 0,
1192 };
1193
1194 switch (width) {
1195 case 1:
1197 break;
1198 case 2:
1200 break;
1201 case 4:
1203 break;
1204 default:
1206 "invalid PCI_Config read %p@%zu width=%d",
1208 );
1210 }
1211
1213 *out = data.qword;
1214 return ret;
1215}
1216
1219)
1220{
1222
1223 switch (width) {
1224 case 1:
1226 break;
1227 case 2:
1229 break;
1230 case 4:
1232 break;
1233 default:
1235 "invalid PCI_Config write %p@%zu width=%d",
1237 );
1239 }
1240
1241 return ret;
1242}
1243
1244#endif // !UACPI_BAREBONES_MODE
#define index(s, c)
Definition: various.h:29
uacpi_status uacpi_acquire_aml_mutex(uacpi_mutex *, uacpi_u16 timeout)
Definition: mutex.c:202
uacpi_status uacpi_release_aml_mutex(uacpi_mutex *)
Definition: mutex.c:242
UINT op
Definition: effect.c:236
_ACRTIMP double __cdecl remainder(double, double)
Definition: remainder.c:75
struct uacpi_runtime_context g_uacpi_rt_ctx
Definition: uacpi.c:17
#define UACPI_UNUSED(x)
Definition: helpers.h:7
#define uacpi_mmio_read8
Definition: io.h:77
#define uacpi_mmio_read16
Definition: io.h:78
#define uacpi_mmio_read64
Definition: io.h:80
#define uacpi_mmio_write16
Definition: io.h:83
#define uacpi_mmio_write64
Definition: io.h:85
#define uacpi_mmio_read32
Definition: io.h:79
#define uacpi_mmio_write32
Definition: io.h:84
#define uacpi_mmio_write8
Definition: io.h:82
#define uacpi_error(...)
Definition: log.h:36
#define uacpi_warn(...)
Definition: log.h:35
uacpi_object * uacpi_namespace_node_get_object_typed(const uacpi_namespace_node *node, uacpi_object_type_bits type_mask)
Definition: namespace.c:654
#define UACPI_ALIGN_UP(x, val, type)
Definition: stdlib.h:106
#define UACPI_IS_POWER_OF_TWO(x, type)
Definition: stdlib.h:114
#define UACPI_IS_ALIGNED(x, val, type)
Definition: stdlib.h:112
#define uacpi_memcpy
Definition: stdlib.h:34
#define uacpi_free(mem, _)
Definition: stdlib.h:96
uacpi_u8 uacpi_bit_scan_backward(uacpi_u64)
Definition: stdlib.c:166
void uacpi_memcpy_zerout(void *dst, const void *src, uacpi_size dst_size, uacpi_size src_size)
Definition: stdlib.c:112
#define UACPI_MIN(x, y)
Definition: stdlib.h:102
@ UACPI_UPDATE_RULE_PRESERVE
Definition: types.h:198
@ UACPI_UPDATE_RULE_WRITE_AS_ZEROES
Definition: types.h:200
@ UACPI_UPDATE_RULE_WRITE_AS_ONES
Definition: types.h:199
@ UACPI_FIELD_UNIT_KIND_NORMAL
Definition: types.h:204
@ UACPI_FIELD_UNIT_KIND_BANK
Definition: types.h:206
@ UACPI_FIELD_UNIT_KIND_INDEX
Definition: types.h:205
#define UACPI_FALLTHROUGH
Definition: compiler.h:100
#define uacpi_unlikely(expr)
Definition: compiler.h:88
#define UACPI_PRIX64
Definition: types.h:61
size_t uacpi_size
Definition: types.h:37
uint32_t uacpi_u32
Definition: types.h:21
bool uacpi_bool
Definition: types.h:31
#define UACPI_FALSE
Definition: types.h:30
uint64_t uacpi_u64
Definition: types.h:22
uint16_t uacpi_u16
Definition: types.h:20
#define UACPI_NULL
Definition: types.h:33
uint8_t uacpi_u8
Definition: types.h:19
#define UACPI_FMT64(val)
Definition: types.h:62
#define UACPI_TRUE
Definition: types.h:29
#define uacpi_likely_success(expr)
Definition: status.h:53
#define uacpi_unlikely_error(expr)
Definition: status.h:49
uacpi_status
Definition: status.h:10
@ UACPI_STATUS_INVALID_ARGUMENT
Definition: status.h:18
@ UACPI_STATUS_AML_OUT_OF_BOUNDS_INDEX
Definition: status.h:40
@ UACPI_STATUS_NOT_FOUND
Definition: status.h:17
@ UACPI_STATUS_UNIMPLEMENTED
Definition: status.h:19
@ UACPI_STATUS_OUT_OF_MEMORY
Definition: status.h:13
@ UACPI_STATUS_AML_INCOMPATIBLE_OBJECT_TYPE
Definition: status.h:38
@ UACPI_STATUS_MAPPING_FAILED
Definition: status.h:12
@ UACPI_STATUS_OK
Definition: status.h:11
const uacpi_char * uacpi_address_space_to_string(uacpi_address_space space)
Definition: types.c:11
@ UACPI_OBJECT_OPERATION_REGION_BIT
Definition: types.h:144
@ UACPI_ACCESS_ATTRIBUTE_WORD
Definition: types.h:478
@ UACPI_ACCESS_ATTRIBUTE_PROCESS_CALL
Definition: types.h:481
@ UACPI_ACCESS_ATTRIBUTE_BLOCK_PROCESS_CALL
Definition: types.h:482
@ UACPI_ACCESS_ATTRIBUTE_BYTE
Definition: types.h:477
@ UACPI_ACCESS_ATTRIBUTE_QUICK
Definition: types.h:475
@ UACPI_ACCESS_ATTRIBUTE_SEND_RECEIVE
Definition: types.h:476
@ UACPI_ACCESS_ATTRIBUTE_RAW_BYTES
Definition: types.h:483
@ UACPI_ACCESS_ATTRIBUTE_BLOCK
Definition: types.h:479
@ UACPI_ACCESS_ATTRIBUTE_RAW_PROCESS_BYTES
Definition: types.h:484
@ UACPI_ACCESS_ATTRIBUTE_BYTES
Definition: types.h:480
uacpi_object_type
Definition: types.h:110
@ UACPI_OBJECT_BUFFER
Definition: types.h:114
@ UACPI_OBJECT_INTEGER
Definition: types.h:112
uacpi_region_op
Definition: types.h:373
@ UACPI_REGION_OP_WRITE
Definition: types.h:381
@ UACPI_REGION_OP_READ
Definition: types.h:380
uacpi_address_space
Definition: types.h:42
@ UACPI_ADDRESS_SPACE_IPMI
Definition: types.h:50
@ UACPI_ADDRESS_SPACE_PRM
Definition: types.h:54
@ UACPI_ADDRESS_SPACE_SYSTEM_MEMORY
Definition: types.h:43
@ UACPI_ADDRESS_SPACE_GENERAL_PURPOSE_IO
Definition: types.h:51
@ UACPI_ADDRESS_SPACE_FFIXEDHW
Definition: types.h:55
@ UACPI_ADDRESS_SPACE_GENERIC_SERIAL_BUS
Definition: types.h:52
@ UACPI_ADDRESS_SPACE_SYSTEM_IO
Definition: types.h:44
@ UACPI_ADDRESS_SPACE_SMBUS
Definition: types.h:47
static uacpi_size bit_span_offset(struct bit_span *span, uacpi_size bits)
Definition: io.c:38
static uacpi_bool field_fits(uacpi_field_unit *field, uacpi_u64 value)
Definition: io.c:238
#define IPMI_DATA_SIZE
Definition: io.c:315
static void bit_copy(struct bit_span *dst, struct bit_span *src)
Definition: io.c:48
void uacpi_builtin_mmio_write64(void *ptr, uacpi_u64 data)
Definition: io.c:1061
uacpi_status uacpi_pci_write(uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in)
Definition: io.c:1217
static uacpi_status access_field_unit(uacpi_field_unit *field, uacpi_u32 offset, uacpi_region_op op, union uacpi_opregion_io_data data)
Definition: io.c:246
uacpi_size uacpi_round_up_bits_to_bytes(uacpi_size bit_length)
Definition: io.c:11
uacpi_status uacpi_map_gas(const struct acpi_gas *gas, uacpi_mapped_gas **out_mapped)
Definition: io.c:963
uacpi_status uacpi_pci_read(uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out)
Definition: io.c:1185
uacpi_u8 uacpi_builtin_mmio_read8(void *ptr)
Definition: io.c:1026
static void do_misaligned_buffer_read(const uacpi_buffer_field *field, uacpi_u8 *dst)
Definition: io.c:97
static uacpi_status wtr_buffer_size(uacpi_field_unit *field, uacpi_address_space space, uacpi_size *out_size)
Definition: io.c:317
static uacpi_bool field_unit_needs_global_lock(uacpi_field_unit *field)
Definition: io.c:178
#define SERIAL_HEADER_SIZE
Definition: io.c:314
void uacpi_write_buffer_field(uacpi_buffer_field *field, const void *src, uacpi_size size)
Definition: io.c:148
uacpi_status uacpi_field_unit_get_bit_length(struct uacpi_field_unit *field, uacpi_size *out_length)
Definition: io.c:721
void uacpi_unmap_gas(uacpi_mapped_gas *gas)
Definition: io.c:989
uacpi_u64 uacpi_builtin_mmio_read64(void *ptr)
Definition: io.c:1041
void uacpi_builtin_mmio_write32(void *ptr, uacpi_u32 data)
Definition: io.c:1056
static uacpi_status write_generic_field_unit(uacpi_field_unit *field, const void *src, uacpi_size size)
Definition: io.c:591
static void cut_misaligned_tail(uacpi_u8 *data, uacpi_size offset, uacpi_u32 bit_length)
Definition: io.c:16
uacpi_status uacpi_system_io_write(uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in)
Definition: io.c:1158
static uacpi_status do_read_misaligned_field_unit(uacpi_field_unit *field, uacpi_u8 *dst, uacpi_size size)
Definition: io.c:476
void uacpi_builtin_mmio_write16(void *ptr, uacpi_u16 data)
Definition: io.c:1051
uacpi_status uacpi_gas_write_mapped(const uacpi_mapped_gas *gas, uacpi_u64 in_value)
Definition: io.c:885
void uacpi_read_buffer_field(const uacpi_buffer_field *field, void *dst)
Definition: io.c:113
static void do_write_misaligned_buffer_field(uacpi_buffer_field *field, const void *src, uacpi_size size)
Definition: io.c:130
uacpi_status uacpi_system_memory_read(void *ptr, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out)
Definition: io.c:1067
void uacpi_unmap_gas_nofree(uacpi_mapped_gas *gas)
Definition: io.c:984
uacpi_status uacpi_field_unit_get_read_type(struct uacpi_field_unit *field, uacpi_object_type *out_type)
Definition: io.c:692
uacpi_status uacpi_system_io_read(uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out)
Definition: io.c:1126
uacpi_status uacpi_gas_write(const struct acpi_gas *gas, uacpi_u64 in_value)
Definition: io.c:1010
static uacpi_status lock_field_unit_transaction(uacpi_field_unit *field)
Definition: io.c:211
static void unlock_field_unit_transaction(uacpi_field_unit *field)
Definition: io.c:230
uacpi_status uacpi_map_gas_noalloc(const struct acpi_gas *gas, uacpi_mapped_gas *out_mapped)
Definition: io.c:927
static void unmap_gas_io(uacpi_handle io_handle, uacpi_size size)
Definition: io.c:921
uacpi_u32 uacpi_builtin_mmio_read32(void *ptr)
Definition: io.c:1036
uacpi_status uacpi_system_memory_write(void *ptr, uacpi_size offset, uacpi_u8 width, uacpi_u64 in)
Definition: io.c:1093
uacpi_status uacpi_read_field_unit(uacpi_field_unit *field, void *dst, uacpi_size size, uacpi_data_view *wtr_response)
Definition: io.c:530
static uacpi_u8 gas_get_access_bit_width(const struct acpi_gas *gas)
Definition: io.c:750
uacpi_status uacpi_gas_read(const struct acpi_gas *gas, uacpi_u64 *out_value)
Definition: io.c:995
static uacpi_status gas_validate(const struct acpi_gas *gas, uacpi_u8 *access_bit_width, uacpi_u8 *bit_width)
Definition: io.c:796
uacpi_status uacpi_gas_read_mapped(const uacpi_mapped_gas *gas, uacpi_u64 *out_value)
Definition: io.c:846
uacpi_u16 uacpi_builtin_mmio_read16(void *ptr)
Definition: io.c:1031
void uacpi_builtin_mmio_write8(void *ptr, uacpi_u8 data)
Definition: io.c:1046
uacpi_status uacpi_write_field_unit(uacpi_field_unit *field, const void *src, uacpi_size size, uacpi_data_view *wtr_response)
Definition: io.c:662
static uacpi_status handle_special_field(uacpi_field_unit *field, uacpi_data_view buf, uacpi_region_op op, uacpi_data_view *wtr_response, uacpi_bool *did_handle)
Definition: io.c:378
return ret
Definition: mutex.c:147
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei width
Definition: gl.h:1546
GLenum src
Definition: glext.h:6340
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLuint index
Definition: glext.h:6031
GLenum GLint GLuint mask
Definition: glext.h:6028
GLenum GLenum GLvoid GLvoid GLvoid * span
Definition: glext.h:5664
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint in
Definition: glext.h:9616
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLenum GLenum dst
Definition: glext.h:6340
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
void uacpi_release_opregion_lock(void)
Definition: opregion.c:398
void uacpi_trace_region_error(uacpi_namespace_node *node, uacpi_char *message, uacpi_status ret)
Definition: opregion.c:25
uacpi_status uacpi_upgrade_to_opregion_lock(void)
Definition: opregion.c:383
uacpi_bool uacpi_is_buffer_access_address_space(uacpi_address_space space)
Definition: opregion.c:833
uacpi_status uacpi_dispatch_opregion_io(uacpi_field_unit *field, uacpi_u32 offset, uacpi_region_op op, union uacpi_opregion_io_data data)
Definition: opregion.c:853
#define UACPI_PTR_ADD(ptr, value)
Definition: utilities.h:23
uacpi_status uacpi_kernel_io_map(uacpi_io_addr base, uacpi_size len, uacpi_handle *out_handle)
Definition: uacpiosl.c:165
uacpi_status uacpi_kernel_pci_write16(uacpi_handle device, uacpi_size offset, uacpi_u16 value)
Definition: uacpiosl.c:285
uacpi_status uacpi_kernel_pci_read8(uacpi_handle device, uacpi_size offset, uacpi_u8 *value)
Definition: uacpiosl.c:257
void * uacpi_kernel_alloc(uacpi_size size)
Definition: uacpiosl.c:111
uacpi_status uacpi_kernel_io_write8(uacpi_handle, uacpi_size offset, uacpi_u8 in_value)
Definition: uacpiosl.c:320
uacpi_status uacpi_kernel_pci_read16(uacpi_handle device, uacpi_size offset, uacpi_u16 *value)
Definition: uacpiosl.c:264
uacpi_status uacpi_kernel_io_read32(uacpi_handle, uacpi_size offset, uacpi_u32 *out_value)
Definition: uacpiosl.c:313
uacpi_status uacpi_kernel_pci_read32(uacpi_handle device, uacpi_size offset, uacpi_u32 *value)
Definition: uacpiosl.c:271
uacpi_status uacpi_kernel_io_write32(uacpi_handle, uacpi_size offset, uacpi_u32 in_value)
Definition: uacpiosl.c:334
uacpi_status uacpi_kernel_io_read8(uacpi_handle, uacpi_size offset, uacpi_u8 *out_value)
Definition: uacpiosl.c:299
#define UACPI_MAP_FAILED
Definition: kernel_api.h:13
uacpi_status uacpi_kernel_pci_write8(uacpi_handle device, uacpi_size offset, uacpi_u8 value)
Definition: uacpiosl.c:278
void uacpi_kernel_unmap(void *addr, uacpi_size len)
Definition: uacpiosl.c:198
uacpi_status uacpi_kernel_io_write16(uacpi_handle, uacpi_size offset, uacpi_u16 in_value)
Definition: uacpiosl.c:327
uacpi_status uacpi_kernel_io_read16(uacpi_handle, uacpi_size offset, uacpi_u16 *out_value)
Definition: uacpiosl.c:306
void * uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len)
Definition: uacpiosl.c:191
void uacpi_kernel_io_unmap(uacpi_handle handle)
Definition: uacpiosl.c:171
uacpi_status uacpi_kernel_pci_write32(uacpi_handle device, uacpi_size offset, uacpi_u32 value)
Definition: uacpiosl.c:292
static PVOID ptr
Definition: dispmode.c:27
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID ULONG out_size
Definition: file.c:72
Definition: io.c:29
uacpi_u64 index
Definition: io.c:34
uacpi_u64 length
Definition: io.c:35
uacpi_u8 * data
Definition: io.c:31
const uacpi_u8 * const_data
Definition: io.c:32
Definition: parser.c:44
uacpi_size length
Definition: types.h:105
const void * const_data
Definition: types.h:103
void * data
Definition: types.h:102
uacpi_u8 access_bit_width
Definition: io.h:11
uacpi_u8 total_bit_width
Definition: io.h:12
uacpi_handle mapping
Definition: io.h:10
void(* unmap)(uacpi_handle, uacpi_size)
Definition: io.h:22
uacpi_status(* write)(uacpi_handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in)
Definition: io.h:18
uacpi_u8 bit_offset
Definition: io.h:13
uacpi_status(* read)(uacpi_handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out)
Definition: io.h:15
uacpi_u16 space
Definition: types.h:120
uacpi_u32 dword
Definition: io.c:1122
uacpi_u8 byte
Definition: io.c:1120
uacpi_u64 qword
Definition: io.c:1123
uacpi_u16 word
Definition: io.c:1121
uacpi_u64 * integer
Definition: opregion.h:47
Definition: pdh_main.c:96
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383