ReactOS 0.4.17-dev-1190-g4c812f4
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 // There's nothing to read from a buffer field that's empty
118 if (uacpi_unlikely(field->bit_length == 0))
119 return;
120
121 if (!(field->bit_index & 7)) {
122 uacpi_u8 *src = field->backing->data;
124
126 uacpi_memcpy(dst, src + (field->bit_index / 8), count);
127 cut_misaligned_tail(dst, count - 1, field->bit_length);
128 return;
129 }
130
132}
133
136 const void *src, uacpi_size size
137)
138{
139 struct bit_span src_span = { 0 };
140 struct bit_span dst_span = { 0 };
141
142 src_span.length = size * 8;
143 src_span.const_data = src;
144
145 dst_span.index = field->bit_index;
146 dst_span.length = field->bit_length;
147 dst_span.data = field->backing->data;
148
149 bit_copy(&dst_span, &src_span);
150}
151
154 const void *src, uacpi_size size
155)
156{
157 // There's nothing to write to a buffer field that's empty
158 if (uacpi_unlikely(field->bit_length == 0))
159 return;
160
161 if (!(field->bit_index & 7)) {
162 uacpi_u8 *dst, last_byte, tail_shift;
164
165 dst = field->backing->data;
166 dst += field->bit_index / 8;
168
169 last_byte = dst[count - 1];
170 tail_shift = field->bit_length & 7;
171
173 if (tail_shift) {
174 uacpi_u8 last_shift = 8 - tail_shift;
175 dst[count - 1] = dst[count - 1] << last_shift;
176 dst[count - 1] >>= last_shift;
177 dst[count - 1] |= (last_byte >> tail_shift) << tail_shift;
178 }
179
180 return;
181 }
182
184}
185
187{
188 if (field->lock_rule)
189 return UACPI_TRUE;
190
191 /*
192 * The global lock must be acquired before the opregion lock, however,
193 * the subfields of an index/bank field are only accessed once the
194 * opregion lock is already held, so their lock rules have to be
195 * considered upfront to keep the ordering consistent.
196 */
197 switch (field->kind) {
199 return field_unit_needs_global_lock(field->index) ||
202 return field_unit_needs_global_lock(field->bank_selection);
203 default:
204 return UACPI_FALSE;
205 }
206}
207
208/*
209 * Both the global lock and the opregion lock are held for the duration of
210 * an entire field transaction (that is, across every hardware access it
211 * decomposes into) instead of individual data accesses:
212 * - The global lock protects fields shared with firmware (e.g. SMM), which
213 * expects multi-datum accesses and read-modify-writes to be atomic.
214 * - The opregion lock makes the index/bank selection register writes atomic
215 * with respect to the data accesses that rely on them, which could
216 * otherwise interleave with IO done by other threads, as every other lock
217 * is dropped around address space handler invocations.
218 */
220{
222
223 /*
224 * The namespace is unlocked more than once before we're done: while we
225 * wait for the locks below, and around every invocation of the address
226 * space handler. This makes it possible for someone else to get rid of
227 * the field in the meantime, e.g. by overwriting it via CopyObject. All
228 * of the references that our caller has to it are gone if that happens,
229 * so take one that is ours alone.
230 */
232
235 g_uacpi_rt_ctx.global_lock_mutex, 0xFFFF
236 );
238 goto out_unref;
239 }
240
244 uacpi_release_aml_mutex(g_uacpi_rt_ctx.global_lock_mutex);
245
246 goto out_unref;
247 }
248
249 return ret;
250
251out_unref:
253 return ret;
254}
255
257{
259
261 uacpi_release_aml_mutex(g_uacpi_rt_ctx.global_lock_mutex);
262
264}
265
267{
268 if (field->bit_length >= 64)
269 return UACPI_TRUE;
270
271 return value < ((uacpi_u64)1 << field->bit_length);
272}
273
277)
278{
280
281 switch (field->kind) {
283 if (uacpi_unlikely(!field_fits(field->bank_selection,
284 field->bank_value))) {
286 "bank value 0x%"UACPI_PRIX64" doesn't fit in the %u-bit "
287 "bank register", UACPI_FMT64(field->bank_value),
288 field->bank_selection->bit_length
289 );
291 }
292
294 field->bank_selection, &field->bank_value, sizeof(field->bank_value),
296 );
297 break;
299 break;
301 if (uacpi_unlikely(!field_fits(field->index, offset))) {
303 "offset 0x%X doesn't fit in the %u-bit index register",
304 offset, field->index->bit_length
305 );
307 }
308
310 field->index, &offset, sizeof(offset),
312 );
314 return ret;
315
316 switch (op) {
319 field->data, data.integer, field->access_width_bytes,
321 );
324 field->data, data.integer, field->access_width_bytes,
326 );
327 default:
329 }
330
331 default:
332 uacpi_error("invalid field unit kind %d", field->kind);
334 }
335
337 return ret;
338
340}
341
342#define SERIAL_HEADER_SIZE 2
343#define IPMI_DATA_SIZE 64
344
348)
349{
350 switch (space) {
353 break;
355 *out_size = 26;
356 break;
358 *out_size = 256;
359 break;
362 uacpi_size size_for_protocol = SERIAL_HEADER_SIZE;
363
364 switch (field->attributes) {
366 break; // + 0
369 size_for_protocol += 1;
370 break;
371
374 size_for_protocol += 2;
375 break;
376
378 size_for_protocol += field->access_length;
379 break;
380
385 size_for_protocol += 255;
386 break;
387
388 default:
390 "unsupported field@%p access attribute %d",
391 field, field->attributes
392 );
394 }
395
396 *out_size = size_for_protocol;
397 break;
398 }
399 default:
401 }
402
403 return UACPI_STATUS_OK;
404}
405
408 uacpi_region_op op, uacpi_data_view *wtr_response,
409 uacpi_bool *did_handle
410)
411{
415 uacpi_u64 in_out;
416 uacpi_data_view wtr_buffer;
418
419 *did_handle = UACPI_FALSE;
420
422 return ret;
423
426 );
427 if (uacpi_unlikely(obj == UACPI_NULL)) {
430 field->region, "attempted access to deleted", ret
431 );
432 goto out_handled;
433 }
434 region = obj->op_region;
435
436 switch (region->space) {
438 if (op == UACPI_REGION_OP_WRITE) {
440 &in_out, buf.const_data, sizeof(in_out), buf.length
441 );
442 }
443
444 data.integer = &in_out;
447 goto out_handled;
448
450 uacpi_memcpy_zerout(buf.data, &in_out, buf.length, sizeof(in_out));
451 goto out_handled;
457 field->region, "attempted to read from a write-only", ret
458 );
459 goto out_handled;
460 }
465 goto do_wtr;
466 default:
467 return ret;
468 }
469
470do_wtr:
471 ret = wtr_buffer_size(field, region->space, &wtr_buffer.length);
473 goto out_handled;
474
475 wtr_buffer.data = uacpi_kernel_alloc(wtr_buffer.length);
476 if (uacpi_unlikely(wtr_buffer.data == UACPI_NULL)) {
478 goto out_handled;
479 }
480
482 wtr_buffer.data, buf.const_data, wtr_buffer.length, buf.length
483 );
484 data.buffer = wtr_buffer;
486 field, field->byte_offset,
487 op, data
488 );
490 uacpi_free(wtr_buffer.data, wtr_buffer.length);
491 goto out_handled;
492 }
493
494 if (wtr_response != UACPI_NULL)
495 *wtr_response = wtr_buffer;
496 else
497 uacpi_free(wtr_buffer.data, wtr_buffer.length);
498
499out_handled:
500 *did_handle = UACPI_TRUE;
501 return ret;
502}
503
506)
507{
509 uacpi_size reads_to_do;
511 uacpi_u32 byte_offset = field->byte_offset;
512 uacpi_u32 bits_left = field->bit_length;
513 uacpi_u8 width_access_bits = field->access_width_bytes * 8;
514
515 struct bit_span src_span = { 0 };
516 struct bit_span dst_span = { 0 };
517
518 src_span.data = (uacpi_u8*)&out;
519 src_span.index = field->bit_offset_within_first_byte;
520
521 dst_span.data = dst;
522 dst_span.index = 0;
523 dst_span.length = size * 8;
524
525 reads_to_do = UACPI_ALIGN_UP(
526 field->bit_offset_within_first_byte + field->bit_length,
527 width_access_bits,
529 );
530 reads_to_do /= width_access_bits;
531
532 while (reads_to_do-- > 0) {
534
535 src_span.length = UACPI_MIN(
536 bits_left, width_access_bits - src_span.index
537 );
538
539 data.integer = &out;
541 field, byte_offset, UACPI_REGION_OP_READ,
542 data
543 );
545 return ret;
546
547 bit_copy(&dst_span, &src_span);
548 bits_left -= src_span.length;
549 src_span.index = 0;
550
551 bit_span_offset(&dst_span, src_span.length);
552 byte_offset += field->access_width_bytes;
553 }
554
555 return UACPI_STATUS_OK;
556}
557
560 uacpi_data_view *wtr_response
561)
562{
564 uacpi_u32 field_byte_length;
565 uacpi_bool did_handle;
566 uacpi_data_view data_view = { 0 };
567
568 data_view.data = dst;
569 data_view.length = size;
570
573 return ret;
574
576 field, data_view, UACPI_REGION_OP_READ,
577 wtr_response, &did_handle
578 );
579 if (did_handle)
580 goto out;
581
582 // There's nothing to read from a field that the AML declared as empty
583 if (uacpi_unlikely(field->bit_length == 0)) {
585 goto out;
586 }
587
588 field_byte_length = uacpi_round_up_bits_to_bytes(field->bit_length);
589
590 /*
591 * Very simple fast case:
592 * - Bit offset within first byte is 0
593 * AND
594 * - Field size is <= access width
595 */
596 if (field->bit_offset_within_first_byte == 0 &&
597 field_byte_length <= field->access_width_bytes)
598 {
601
602 data.integer = &out;
604 field, field->byte_offset, UACPI_REGION_OP_READ,
605 data
606 );
608 goto out;
609
610 uacpi_memcpy_zerout(dst, &out, size, field_byte_length);
611 if (size >= field_byte_length)
612 cut_misaligned_tail(dst, field_byte_length - 1, field->bit_length);
613
614 goto out;
615 }
616
617 // Slow case
619
620out:
622 return ret;
623}
624
627)
628{
630 uacpi_u32 bits_left, byte_offset = field->byte_offset;
631 uacpi_u8 width_access_bits = field->access_width_bytes * 8;
633 struct bit_span src_span = { 0 };
634 struct bit_span dst_span = { 0 };
635
636 src_span.const_data = src;
637 src_span.index = 0;
638 src_span.length = size * 8;
639
640 dst_span.data = (uacpi_u8 *)&in;
641 dst_span.index = field->bit_offset_within_first_byte;
642
643 bits_left = field->bit_length;
644
645 while (bits_left) {
647
648 in = 0;
649 dst_span.length = UACPI_MIN(
650 width_access_bits - dst_span.index, bits_left
651 );
652
653 if (dst_span.index != 0 || dst_span.length < width_access_bits) {
654 switch (field->update_rule) {
656 data.integer = &in;
658 field, byte_offset, UACPI_REGION_OP_READ,
659 data
660 );
662 return ret;
663 break;
665 in = ~in;
666 break;
668 break;
669 default:
670 uacpi_error("invalid field@%p update rule %d",
671 field, field->update_rule);
673 }
674 }
675
676 bit_copy(&dst_span, &src_span);
677 bit_span_offset(&src_span, dst_span.length);
678
679 data.integer = &in;
680
682 field, byte_offset, UACPI_REGION_OP_WRITE,
683 data
684 );
686 return ret;
687
688 bits_left -= dst_span.length;
689 dst_span.index = 0;
690 byte_offset += field->access_width_bytes;
691 }
692
693 return UACPI_STATUS_OK;
694}
695
698 uacpi_size chunk_size, uacpi_data_view *wtr_response
699)
700{
702 uacpi_bool did_handle;
703 uacpi_data_view data_view = { 0 };
704 const uacpi_u8 *bytes = src;
706
707 data_view.const_data = src;
708 data_view.length = size;
709
712 return ret;
713
715 field, data_view, UACPI_REGION_OP_WRITE,
716 wtr_response, &did_handle
717 );
718 if (did_handle)
719 goto out;
720
721 // There's nothing to write to a field that the AML declared as empty
722 if (uacpi_unlikely(field->bit_length == 0))
723 goto out;
724
725 for (offset = 0; offset < size; offset += chunk_size) {
727 field, bytes + offset, UACPI_MIN(chunk_size, size - offset)
728 );
730 break;
731 }
732
733out:
735 return ret;
736}
737
740 uacpi_data_view *wtr_response
741)
742{
743 return write_field_unit(field, src, size, size, wtr_response);
744}
745
748 uacpi_data_view *wtr_response
749)
750{
751 return write_field_unit(
753 wtr_response
754 );
755}
756
758 struct uacpi_field_unit *field, uacpi_object_type *out_type
759)
760{
762
764 goto out_basic_field;
765
768 );
771
772 if (uacpi_is_buffer_access_address_space(obj->op_region->space)) {
773 *out_type = UACPI_OBJECT_BUFFER;
774 return UACPI_STATUS_OK;
775 }
776
777out_basic_field:
778 if (field->bit_length > (g_uacpi_rt_ctx.is_rev1 ? 32u : 64u))
779 *out_type = UACPI_OBJECT_BUFFER;
780 else
781 *out_type = UACPI_OBJECT_INTEGER;
782
783 return UACPI_STATUS_OK;
784}
785
787 struct uacpi_field_unit *field, uacpi_size *out_length
788)
789{
791
793 goto out_basic_field;
794
797 );
800
801 if (uacpi_is_buffer_access_address_space(obj->op_region->space)) {
802 /*
803 * Bit length is protocol specific, the data will be returned
804 * via the write-then-read response buffer.
805 */
806 *out_length = 0;
807 return UACPI_STATUS_OK;
808 }
809
810out_basic_field:
811 *out_length = field->bit_length;
812 return UACPI_STATUS_OK;
813}
814
815static uacpi_u8 gas_get_access_bit_width(const struct acpi_gas *gas)
816{
817 /*
818 * Same algorithm as ACPICA.
819 *
820 * The reason we do this is apparently GAS bit offset being non-zero means
821 * that it's an APEI register, as opposed to FADT, which needs special
822 * handling. In the case of a FADT register we want to ignore the specified
823 * access size.
824 */
825 uacpi_u8 access_bit_width;
826
827 if (gas->register_bit_offset == 0 &&
828 UACPI_IS_POWER_OF_TWO(gas->register_bit_width, uacpi_u8) &&
829 UACPI_IS_ALIGNED(gas->register_bit_width, 8, uacpi_u8)) {
830 access_bit_width = gas->register_bit_width;
831 } else if (gas->access_size) {
832 access_bit_width = gas->access_size * 8;
833 } else {
834 uacpi_u8 msb;
835
837 (gas->register_bit_offset + gas->register_bit_width) - 1
838 );
839 access_bit_width = 1 << msb;
840
841 if (access_bit_width <= 8) {
842 access_bit_width = 8;
843 } else {
844 /*
845 * Keep backing off to previous power of two until we find one
846 * that is aligned to the address specified in GAS.
847 */
848 while (!UACPI_IS_ALIGNED(
849 gas->address, access_bit_width / 8, uacpi_u64
850 ))
851 access_bit_width /= 2;
852 }
853 }
854
855 return UACPI_MIN(
856 access_bit_width,
857 gas->address_space_id == UACPI_ADDRESS_SPACE_SYSTEM_IO ? 32 : 64
858 );
859}
860
862 const struct acpi_gas *gas, uacpi_u8 *access_bit_width,
863 uacpi_u8 *bit_width
864)
865{
866 uacpi_size total_width, aligned_width;
867
868 if (uacpi_unlikely(gas == UACPI_NULL))
870
871 if (!gas->address)
873
874 if (gas->address_space_id != UACPI_ADDRESS_SPACE_SYSTEM_IO &&
875 gas->address_space_id != UACPI_ADDRESS_SPACE_SYSTEM_MEMORY) {
876 uacpi_warn("unsupported GAS address space '%s' (%d)",
877 uacpi_address_space_to_string(gas->address_space_id),
878 gas->address_space_id);
880 }
881
882 if (gas->access_size > 4) {
883 uacpi_warn("unsupported GAS access size %d",
884 gas->access_size);
886 }
887
888 *access_bit_width = gas_get_access_bit_width(gas);
889
890 total_width = gas->register_bit_offset + gas->register_bit_width;
891 aligned_width = UACPI_ALIGN_UP(total_width, *access_bit_width, uacpi_size);
892
893 if (uacpi_unlikely(aligned_width > 64)) {
895 "GAS register total width is too large: %zu", total_width
896 );
898 }
899
900 *bit_width = total_width;
901 return UACPI_STATUS_OK;
902}
903
904/*
905 * Apparently both reading and writing GAS works differently from operation
906 * region in that bit offsets are not respected when writing the data.
907 *
908 * Let's follow ACPICA's approach here so that we don't accidentally
909 * break any quirky hardware.
910 */
912 const uacpi_mapped_gas *gas, uacpi_u64 *out_value
913)
914{
916 uacpi_u8 access_byte_width;
917 uacpi_u8 bit_offset, bits_left, index = 0;
918 uacpi_u64 data, mask = 0xFFFFFFFFFFFFFFFF;
919 uacpi_size offset = 0;
920
921 bit_offset = gas->bit_offset;
922 bits_left = gas->total_bit_width;
923
924 access_byte_width = gas->access_bit_width / 8;
925
926 if (access_byte_width < 8)
927 mask = ~(mask << gas->access_bit_width);
928
929 *out_value = 0;
930
931 while (bits_left) {
932 if (bit_offset >= gas->access_bit_width) {
933 data = 0;
934 bit_offset -= gas->access_bit_width;
935 } else {
936 ret = gas->read(gas->mapping, offset, access_byte_width, &data);
938 return ret;
939 }
940
941 *out_value |= (data & mask) << (index * gas->access_bit_width);
942 bits_left -= UACPI_MIN(bits_left, gas->access_bit_width);
943 ++index;
944 offset += access_byte_width;
945 }
946
947 return UACPI_STATUS_OK;
948}
949
951 const uacpi_mapped_gas *gas, uacpi_u64 in_value
952)
953{
955 uacpi_u8 access_byte_width;
956 uacpi_u8 bit_offset, bits_left, index = 0;
957 uacpi_u64 data, mask = 0xFFFFFFFFFFFFFFFF;
958 uacpi_size offset = 0;
959
960 bit_offset = gas->bit_offset;
961 bits_left = gas->total_bit_width;
962 access_byte_width = gas->access_bit_width / 8;
963
964 if (access_byte_width < 8)
965 mask = ~(mask << gas->access_bit_width);
966
967 while (bits_left) {
968 data = (in_value >> (index * gas->access_bit_width)) & mask;
969
970 if (bit_offset >= gas->access_bit_width) {
971 bit_offset -= gas->access_bit_width;
972 } else {
973 ret = gas->write(gas->mapping, offset, access_byte_width, data);
975 return ret;
976 }
977
978 bits_left -= UACPI_MIN(bits_left, gas->access_bit_width);
979 ++index;
980 offset += access_byte_width;
981 }
982
983 return UACPI_STATUS_OK;
984}
985
987{
989 uacpi_kernel_io_unmap(io_handle);
990}
991
993 const struct acpi_gas *gas, uacpi_mapped_gas *out_mapped
994)
995{
997 uacpi_u8 access_bit_width, total_width;
998
999 ret = gas_validate(gas, &access_bit_width, &total_width);
1000 if (ret != UACPI_STATUS_OK)
1001 return ret;
1002
1003 if (gas->address_space_id == UACPI_ADDRESS_SPACE_SYSTEM_MEMORY) {
1004 out_mapped->mapping = uacpi_kernel_map(gas->address, total_width / 8);
1005 if (uacpi_unlikely(out_mapped->mapping == UACPI_MAP_FAILED))
1007
1008 out_mapped->read = uacpi_system_memory_read;
1009 out_mapped->write = uacpi_system_memory_write;
1010 out_mapped->unmap = uacpi_kernel_unmap;
1011 } else { // IO, validated by gas_validate above
1012 ret = uacpi_kernel_io_map(gas->address, total_width / 8, &out_mapped->mapping);
1014 return ret;
1015
1016 out_mapped->read = uacpi_system_io_read;
1017 out_mapped->write = uacpi_system_io_write;
1018 out_mapped->unmap = unmap_gas_io;
1019 }
1020
1021 out_mapped->access_bit_width = access_bit_width;
1022 out_mapped->total_bit_width = total_width;
1023 out_mapped->bit_offset = gas->register_bit_offset;
1024
1025 return UACPI_STATUS_OK;
1026}
1027
1029 const struct acpi_gas *gas, uacpi_mapped_gas **out_mapped
1030)
1031{
1034
1038
1041 uacpi_free(mapping, sizeof(*mapping));
1042 return ret;
1043 }
1044
1045 *out_mapped = mapping;
1046 return ret;
1047}
1048
1050{
1051 gas->unmap(gas->mapping, gas->access_bit_width / 8);
1052}
1053
1055{
1057 uacpi_free(gas, sizeof(*gas));
1058}
1059
1060uacpi_status uacpi_gas_read(const struct acpi_gas *gas, uacpi_u64 *out_value)
1061{
1064
1067 return ret;
1068
1069 ret = uacpi_gas_read_mapped(&mapping, out_value);
1071
1072 return ret;
1073}
1074
1075uacpi_status uacpi_gas_write(const struct acpi_gas *gas, uacpi_u64 in_value)
1076{
1079
1082 return ret;
1083
1084 ret = uacpi_gas_write_mapped(&mapping, in_value);
1086
1087 return ret;
1088}
1089
1090#ifndef UACPI_NATIVE_MMIO
1092{
1093 return *(volatile uacpi_u8*)ptr;
1094}
1095
1097{
1098 return *(volatile uacpi_u16*)ptr;
1099}
1100
1102{
1103 return *(volatile uacpi_u32*)ptr;
1104}
1105
1107{
1108 return *(volatile uacpi_u64*)ptr;
1109}
1110
1112{
1113 *(volatile uacpi_u8*)ptr = data;
1114}
1115
1117{
1118 *(volatile uacpi_u16*)ptr = data;
1119}
1120
1122{
1123 *(volatile uacpi_u32*)ptr = data;
1124}
1125
1127{
1128 *(volatile uacpi_u64*)ptr = data;
1129}
1130#endif
1131
1134)
1135{
1137
1138 switch (width) {
1139 case 1:
1141 break;
1142 case 2:
1144 break;
1145 case 4:
1147 break;
1148 case 8:
1150 break;
1151 default:
1153 }
1154
1155 return UACPI_STATUS_OK;
1156}
1157
1160)
1161{
1163
1164 switch (width) {
1165 case 1:
1167 break;
1168 case 2:
1170 break;
1171 case 4:
1173 break;
1174 case 8:
1176 break;
1177 default:
1179 }
1180
1181 return UACPI_STATUS_OK;
1182}
1183
1189};
1190
1193)
1194{
1196 union integer_data data = {
1197 .qword = 0,
1198 };
1199
1200 switch (width) {
1201 case 1:
1203 break;
1204 case 2:
1206 break;
1207 case 4:
1209 break;
1210 default:
1212 "invalid SystemIO read %p@%zu width=%d",
1214 );
1216 }
1217
1219 *out = data.qword;
1220 return ret;
1221}
1222
1225)
1226{
1228
1229 switch (width) {
1230 case 1:
1232 break;
1233 case 2:
1235 break;
1236 case 4:
1238 break;
1239 default:
1241 "invalid SystemIO write %p@%zu width=%d",
1243 );
1245 }
1246
1247 return ret;
1248}
1249
1252)
1253{
1255 union integer_data data = {
1256 .qword = 0,
1257 };
1258
1259 switch (width) {
1260 case 1:
1262 break;
1263 case 2:
1265 break;
1266 case 4:
1268 break;
1269 default:
1271 "invalid PCI_Config read %p@%zu width=%d",
1273 );
1275 }
1276
1278 *out = data.qword;
1279 return ret;
1280}
1281
1284)
1285{
1287
1288 switch (width) {
1289 case 1:
1291 break;
1292 case 2:
1294 break;
1295 case 4:
1297 break;
1298 default:
1300 "invalid PCI_Config write %p@%zu width=%d",
1302 );
1304 }
1305
1306 return ret;
1307}
1308
1309#endif // !UACPI_BAREBONES_MODE
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define index(s, c)
Definition: various.h:29
uacpi_status uacpi_acquire_aml_mutex(uacpi_mutex *, uacpi_u16 timeout)
Definition: mutex.c:199
uacpi_status uacpi_release_aml_mutex(uacpi_mutex *)
Definition: mutex.c:239
UINT op
Definition: effect.c:235
_ACRTIMP double __cdecl remainder(double, double)
Definition: remainder.c:75
struct uacpi_runtime_context g_uacpi_rt_ctx
Definition: uacpi.c:18
#define UACPI_UNUSED(x)
Definition: helpers.h:7
#define uacpi_mmio_read8
Definition: io.h:88
#define uacpi_mmio_read16
Definition: io.h:89
#define uacpi_mmio_read64
Definition: io.h:91
#define uacpi_mmio_write16
Definition: io.h:94
#define uacpi_mmio_write64
Definition: io.h:96
#define uacpi_mmio_read32
Definition: io.h:90
#define uacpi_mmio_write32
Definition: io.h:95
#define uacpi_mmio_write8
Definition: io.h:93
#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:661
#define uacpi_memzero(ptr, size)
Definition: stdlib.h:99
#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
void uacpi_field_unit_unref(uacpi_field_unit *)
Definition: types.c:655
@ UACPI_UPDATE_RULE_PRESERVE
Definition: types.h:201
@ UACPI_UPDATE_RULE_WRITE_AS_ZEROES
Definition: types.h:203
@ UACPI_UPDATE_RULE_WRITE_AS_ONES
Definition: types.h:202
@ UACPI_FIELD_UNIT_KIND_NORMAL
Definition: types.h:207
@ UACPI_FIELD_UNIT_KIND_BANK
Definition: types.h:209
@ UACPI_FIELD_UNIT_KIND_INDEX
Definition: types.h:208
#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:54
#define uacpi_unlikely_error(expr)
Definition: status.h:50
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:12
@ UACPI_OBJECT_OPERATION_REGION_BIT
Definition: types.h:144
@ UACPI_ACCESS_ATTRIBUTE_WORD
Definition: types.h:488
@ UACPI_ACCESS_ATTRIBUTE_PROCESS_CALL
Definition: types.h:491
@ UACPI_ACCESS_ATTRIBUTE_BLOCK_PROCESS_CALL
Definition: types.h:492
@ UACPI_ACCESS_ATTRIBUTE_BYTE
Definition: types.h:487
@ UACPI_ACCESS_ATTRIBUTE_QUICK
Definition: types.h:485
@ UACPI_ACCESS_ATTRIBUTE_SEND_RECEIVE
Definition: types.h:486
@ UACPI_ACCESS_ATTRIBUTE_RAW_BYTES
Definition: types.h:493
@ UACPI_ACCESS_ATTRIBUTE_BLOCK
Definition: types.h:489
@ UACPI_ACCESS_ATTRIBUTE_RAW_PROCESS_BYTES
Definition: types.h:494
@ UACPI_ACCESS_ATTRIBUTE_BYTES
Definition: types.h:490
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:266
#define IPMI_DATA_SIZE
Definition: io.c:343
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:1126
uacpi_status uacpi_pci_write(uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in)
Definition: io.c:1282
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:274
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:1028
uacpi_status uacpi_pci_read(uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out)
Definition: io.c:1250
uacpi_u8 uacpi_builtin_mmio_read8(void *ptr)
Definition: io.c:1091
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:345
static uacpi_bool field_unit_needs_global_lock(uacpi_field_unit *field)
Definition: io.c:186
#define SERIAL_HEADER_SIZE
Definition: io.c:342
void uacpi_write_buffer_field(uacpi_buffer_field *field, const void *src, uacpi_size size)
Definition: io.c:152
uacpi_status uacpi_field_unit_get_bit_length(struct uacpi_field_unit *field, uacpi_size *out_length)
Definition: io.c:786
void uacpi_unmap_gas(uacpi_mapped_gas *gas)
Definition: io.c:1054
uacpi_u64 uacpi_builtin_mmio_read64(void *ptr)
Definition: io.c:1106
void uacpi_builtin_mmio_write32(void *ptr, uacpi_u32 data)
Definition: io.c:1121
static uacpi_status write_generic_field_unit(uacpi_field_unit *field, const void *src, uacpi_size size)
Definition: io.c:625
static void cut_misaligned_tail(uacpi_u8 *data, uacpi_size offset, uacpi_u32 bit_length)
Definition: io.c:16
uacpi_status uacpi_write_field_unit_in_chunks(uacpi_field_unit *field, const void *src, uacpi_size size, uacpi_data_view *wtr_response)
Definition: io.c:746
uacpi_status uacpi_system_io_write(uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in)
Definition: io.c:1223
static uacpi_status do_read_misaligned_field_unit(uacpi_field_unit *field, uacpi_u8 *dst, uacpi_size size)
Definition: io.c:504
void uacpi_builtin_mmio_write16(void *ptr, uacpi_u16 data)
Definition: io.c:1116
uacpi_status uacpi_gas_write_mapped(const uacpi_mapped_gas *gas, uacpi_u64 in_value)
Definition: io.c:950
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:134
uacpi_status uacpi_system_memory_read(void *ptr, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out)
Definition: io.c:1132
void uacpi_unmap_gas_nofree(uacpi_mapped_gas *gas)
Definition: io.c:1049
static uacpi_status write_field_unit(uacpi_field_unit *field, const void *src, uacpi_size size, uacpi_size chunk_size, uacpi_data_view *wtr_response)
Definition: io.c:696
uacpi_status uacpi_field_unit_get_read_type(struct uacpi_field_unit *field, uacpi_object_type *out_type)
Definition: io.c:757
uacpi_status uacpi_system_io_read(uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out)
Definition: io.c:1191
uacpi_status uacpi_gas_write(const struct acpi_gas *gas, uacpi_u64 in_value)
Definition: io.c:1075
static uacpi_status lock_field_unit_transaction(uacpi_field_unit *field)
Definition: io.c:219
static void unlock_field_unit_transaction(uacpi_field_unit *field)
Definition: io.c:256
uacpi_status uacpi_map_gas_noalloc(const struct acpi_gas *gas, uacpi_mapped_gas *out_mapped)
Definition: io.c:992
static void unmap_gas_io(uacpi_handle io_handle, uacpi_size size)
Definition: io.c:986
uacpi_u32 uacpi_builtin_mmio_read32(void *ptr)
Definition: io.c:1101
uacpi_status uacpi_system_memory_write(void *ptr, uacpi_size offset, uacpi_u8 width, uacpi_u64 in)
Definition: io.c:1158
uacpi_status uacpi_read_field_unit(uacpi_field_unit *field, void *dst, uacpi_size size, uacpi_data_view *wtr_response)
Definition: io.c:558
static uacpi_u8 gas_get_access_bit_width(const struct acpi_gas *gas)
Definition: io.c:815
uacpi_status uacpi_gas_read(const struct acpi_gas *gas, uacpi_u64 *out_value)
Definition: io.c:1060
static uacpi_status gas_validate(const struct acpi_gas *gas, uacpi_u8 *access_bit_width, uacpi_u8 *bit_width)
Definition: io.c:861
uacpi_status uacpi_gas_read_mapped(const uacpi_mapped_gas *gas, uacpi_u64 *out_value)
Definition: io.c:911
uacpi_u16 uacpi_builtin_mmio_read16(void *ptr)
Definition: io.c:1096
void uacpi_builtin_mmio_write8(void *ptr, uacpi_u8 data)
Definition: io.c:1111
uacpi_status uacpi_write_field_unit(uacpi_field_unit *field, const void *src, uacpi_size size, uacpi_data_view *wtr_response)
Definition: io.c:738
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:406
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:487
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:472
uacpi_bool uacpi_is_buffer_access_address_space(uacpi_address_space space)
Definition: opregion.c:1111
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:1162
#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
static uacpi_u32 uacpi_shareable_ref(uacpi_handle handle)
Definition: shareable.h:40
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_u32 dword
Definition: io.c:1187
uacpi_u8 byte
Definition: io.c:1185
uacpi_u64 qword
Definition: io.c:1188
uacpi_u16 word
Definition: io.c:1186
uacpi_u64 * integer
Definition: opregion.h:47
Definition: pdh_main.c:64
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383