ReactOS 0.4.17-dev-1190-g4c812f4
io.c File Reference
Include dependency graph for io.c:

Go to the source code of this file.

Classes

struct  bit_span
 
union  integer_data
 

Macros

#define SERIAL_HEADER_SIZE   2
 
#define IPMI_DATA_SIZE   64
 

Functions

uacpi_size uacpi_round_up_bits_to_bytes (uacpi_size bit_length)
 
static void cut_misaligned_tail (uacpi_u8 *data, uacpi_size offset, uacpi_u32 bit_length)
 
static uacpi_size bit_span_offset (struct bit_span *span, uacpi_size bits)
 
static void bit_copy (struct bit_span *dst, struct bit_span *src)
 
static void do_misaligned_buffer_read (const uacpi_buffer_field *field, uacpi_u8 *dst)
 
void uacpi_read_buffer_field (const uacpi_buffer_field *field, void *dst)
 
static void do_write_misaligned_buffer_field (uacpi_buffer_field *field, const void *src, uacpi_size size)
 
void uacpi_write_buffer_field (uacpi_buffer_field *field, const void *src, uacpi_size size)
 
static uacpi_bool field_unit_needs_global_lock (uacpi_field_unit *field)
 
static uacpi_status lock_field_unit_transaction (uacpi_field_unit *field)
 
static void unlock_field_unit_transaction (uacpi_field_unit *field)
 
static uacpi_bool field_fits (uacpi_field_unit *field, uacpi_u64 value)
 
static uacpi_status access_field_unit (uacpi_field_unit *field, uacpi_u32 offset, uacpi_region_op op, union uacpi_opregion_io_data data)
 
static uacpi_status wtr_buffer_size (uacpi_field_unit *field, uacpi_address_space space, uacpi_size *out_size)
 
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)
 
static uacpi_status do_read_misaligned_field_unit (uacpi_field_unit *field, uacpi_u8 *dst, uacpi_size size)
 
uacpi_status uacpi_read_field_unit (uacpi_field_unit *field, void *dst, uacpi_size size, uacpi_data_view *wtr_response)
 
static uacpi_status write_generic_field_unit (uacpi_field_unit *field, const void *src, uacpi_size size)
 
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)
 
uacpi_status uacpi_write_field_unit (uacpi_field_unit *field, const void *src, uacpi_size size, uacpi_data_view *wtr_response)
 
uacpi_status uacpi_write_field_unit_in_chunks (uacpi_field_unit *field, const void *src, uacpi_size size, uacpi_data_view *wtr_response)
 
uacpi_status uacpi_field_unit_get_read_type (struct uacpi_field_unit *field, uacpi_object_type *out_type)
 
uacpi_status uacpi_field_unit_get_bit_length (struct uacpi_field_unit *field, uacpi_size *out_length)
 
static uacpi_u8 gas_get_access_bit_width (const struct acpi_gas *gas)
 
static uacpi_status gas_validate (const struct acpi_gas *gas, uacpi_u8 *access_bit_width, uacpi_u8 *bit_width)
 
uacpi_status uacpi_gas_read_mapped (const uacpi_mapped_gas *gas, uacpi_u64 *out_value)
 
uacpi_status uacpi_gas_write_mapped (const uacpi_mapped_gas *gas, uacpi_u64 in_value)
 
static void unmap_gas_io (uacpi_handle io_handle, uacpi_size size)
 
uacpi_status uacpi_map_gas_noalloc (const struct acpi_gas *gas, uacpi_mapped_gas *out_mapped)
 
uacpi_status uacpi_map_gas (const struct acpi_gas *gas, uacpi_mapped_gas **out_mapped)
 
void uacpi_unmap_gas_nofree (uacpi_mapped_gas *gas)
 
void uacpi_unmap_gas (uacpi_mapped_gas *gas)
 
uacpi_status uacpi_gas_read (const struct acpi_gas *gas, uacpi_u64 *out_value)
 
uacpi_status uacpi_gas_write (const struct acpi_gas *gas, uacpi_u64 in_value)
 
uacpi_u8 uacpi_builtin_mmio_read8 (void *ptr)
 
uacpi_u16 uacpi_builtin_mmio_read16 (void *ptr)
 
uacpi_u32 uacpi_builtin_mmio_read32 (void *ptr)
 
uacpi_u64 uacpi_builtin_mmio_read64 (void *ptr)
 
void uacpi_builtin_mmio_write8 (void *ptr, uacpi_u8 data)
 
void uacpi_builtin_mmio_write16 (void *ptr, uacpi_u16 data)
 
void uacpi_builtin_mmio_write32 (void *ptr, uacpi_u32 data)
 
void uacpi_builtin_mmio_write64 (void *ptr, uacpi_u64 data)
 
uacpi_status uacpi_system_memory_read (void *ptr, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out)
 
uacpi_status uacpi_system_memory_write (void *ptr, uacpi_size offset, uacpi_u8 width, uacpi_u64 in)
 
uacpi_status uacpi_system_io_read (uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out)
 
uacpi_status uacpi_system_io_write (uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in)
 
uacpi_status uacpi_pci_read (uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out)
 
uacpi_status uacpi_pci_write (uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in)
 

Macro Definition Documentation

◆ IPMI_DATA_SIZE

#define IPMI_DATA_SIZE   64

Definition at line 343 of file io.c.

◆ SERIAL_HEADER_SIZE

#define SERIAL_HEADER_SIZE   2

Definition at line 342 of file io.c.

Function Documentation

◆ access_field_unit()

static uacpi_status access_field_unit ( uacpi_field_unit *  field,
uacpi_u32  offset,
uacpi_region_op  op,
union uacpi_opregion_io_data  data 
)
static

Definition at line 274 of file io.c.

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}
UINT op
Definition: effect.c:235
#define uacpi_error(...)
Definition: log.h:36
@ 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_unlikely(expr)
Definition: compiler.h:88
#define UACPI_PRIX64
Definition: types.h:61
#define UACPI_NULL
Definition: types.h:33
#define UACPI_FMT64(val)
Definition: types.h:62
#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_OK
Definition: status.h:11
@ UACPI_REGION_OP_WRITE
Definition: types.h:381
@ UACPI_REGION_OP_READ
Definition: types.h:380
static uacpi_bool field_fits(uacpi_field_unit *field, uacpi_u64 value)
Definition: io.c:266
uacpi_status uacpi_read_field_unit(uacpi_field_unit *field, void *dst, uacpi_size size, uacpi_data_view *wtr_response)
Definition: io.c:558
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
return ret
Definition: mutex.c:147
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLintptr offset
Definition: glext.h:5920
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
Definition: parser.c:44

Referenced by do_read_misaligned_field_unit(), handle_special_field(), uacpi_read_field_unit(), and write_generic_field_unit().

◆ bit_copy()

static void bit_copy ( struct bit_span *  dst,
struct bit_span *  src 
)
static

Definition at line 48 of file io.c.

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}
uint32_t uacpi_u32
Definition: types.h:21
uint64_t uacpi_u64
Definition: types.h:22
uint16_t uacpi_u16
Definition: types.h:20
uint8_t uacpi_u8
Definition: types.h:19
GLenum src
Definition: glext.h:6340
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLenum GLenum dst
Definition: glext.h:6340

Referenced by do_misaligned_buffer_read(), do_read_misaligned_field_unit(), do_write_misaligned_buffer_field(), and write_generic_field_unit().

◆ bit_span_offset()

static uacpi_size bit_span_offset ( struct bit_span *  span,
uacpi_size  bits 
)
static

Definition at line 38 of file io.c.

39{
40 uacpi_size delta = UACPI_MIN(span->length, bits);
41
42 span->index += delta;
43 span->length -= delta;
44
45 return delta;
46}
#define UACPI_MIN(x, y)
Definition: stdlib.h:102
size_t uacpi_size
Definition: types.h:37
GLenum GLenum GLvoid GLvoid GLvoid * span
Definition: glext.h:5664

Referenced by do_read_misaligned_field_unit(), and write_generic_field_unit().

◆ cut_misaligned_tail()

static void cut_misaligned_tail ( uacpi_u8 *  data,
uacpi_size  offset,
uacpi_u32  bit_length 
)
static

Definition at line 16 of file io.c.

19{
20 uacpi_u8 remainder = bit_length & 7;
21
22 if (remainder == 0)
23 return;
24
25 data[offset] &= ((1ull << remainder) - 1);
26}
_ACRTIMP double __cdecl remainder(double, double)
Definition: remainder.c:75

Referenced by uacpi_read_buffer_field(), and uacpi_read_field_unit().

◆ do_misaligned_buffer_read()

static void do_misaligned_buffer_read ( const uacpi_buffer_field *  field,
uacpi_u8 *  dst 
)
static

Definition at line 97 of file io.c.

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}
static void bit_copy(struct bit_span *dst, struct bit_span *src)
Definition: io.c:48
uacpi_size uacpi_round_up_bits_to_bytes(uacpi_size bit_length)
Definition: io.c:11
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

Referenced by uacpi_read_buffer_field().

◆ do_read_misaligned_field_unit()

static uacpi_status do_read_misaligned_field_unit ( uacpi_field_unit *  field,
uacpi_u8 *  dst,
uacpi_size  size 
)
static

Definition at line 504 of file io.c.

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}
#define UACPI_ALIGN_UP(x, val, type)
Definition: stdlib.h:106
static uacpi_size bit_span_offset(struct bit_span *span, uacpi_size bits)
Definition: io.c:38
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
GLsizeiptr size
Definition: glext.h:5919
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383

Referenced by uacpi_read_field_unit().

◆ do_write_misaligned_buffer_field()

static void do_write_misaligned_buffer_field ( uacpi_buffer_field *  field,
const void *  src,
uacpi_size  size 
)
static

Definition at line 134 of file io.c.

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}

Referenced by uacpi_write_buffer_field().

◆ field_fits()

static uacpi_bool field_fits ( uacpi_field_unit *  field,
uacpi_u64  value 
)
static

Definition at line 266 of file io.c.

267{
268 if (field->bit_length >= 64)
269 return UACPI_TRUE;
270
271 return value < ((uacpi_u64)1 << field->bit_length);
272}
#define UACPI_TRUE
Definition: types.h:29
Definition: pdh_main.c:64

Referenced by access_field_unit().

◆ field_unit_needs_global_lock()

static uacpi_bool field_unit_needs_global_lock ( uacpi_field_unit *  field)
static

Definition at line 186 of file io.c.

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}
#define UACPI_FALSE
Definition: types.h:30
static uacpi_bool field_unit_needs_global_lock(uacpi_field_unit *field)
Definition: io.c:186

Referenced by field_unit_needs_global_lock(), lock_field_unit_transaction(), and unlock_field_unit_transaction().

◆ gas_get_access_bit_width()

static uacpi_u8 gas_get_access_bit_width ( const struct acpi_gas *  gas)
static

Definition at line 815 of file io.c.

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}
#define UACPI_IS_POWER_OF_TWO(x, type)
Definition: stdlib.h:114
#define UACPI_IS_ALIGNED(x, val, type)
Definition: stdlib.h:112
uacpi_u8 uacpi_bit_scan_backward(uacpi_u64)
Definition: stdlib.c:166
@ UACPI_ADDRESS_SPACE_SYSTEM_IO
Definition: types.h:44

Referenced by gas_validate().

◆ gas_validate()

static uacpi_status gas_validate ( const struct acpi_gas *  gas,
uacpi_u8 *  access_bit_width,
uacpi_u8 *  bit_width 
)
static

Definition at line 861 of file io.c.

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}
#define uacpi_warn(...)
Definition: log.h:35
@ UACPI_STATUS_NOT_FOUND
Definition: status.h:17
@ UACPI_STATUS_UNIMPLEMENTED
Definition: status.h:19
const uacpi_char * uacpi_address_space_to_string(uacpi_address_space space)
Definition: types.c:12
@ UACPI_ADDRESS_SPACE_SYSTEM_MEMORY
Definition: types.h:43
static uacpi_u8 gas_get_access_bit_width(const struct acpi_gas *gas)
Definition: io.c:815

Referenced by uacpi_map_gas_noalloc().

◆ handle_special_field()

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 
)
static

Definition at line 406 of file io.c.

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}
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_free(mem, _)
Definition: stdlib.h:96
void uacpi_memcpy_zerout(void *dst, const void *src, uacpi_size dst_size, uacpi_size src_size)
Definition: stdlib.c:112
#define UACPI_FALLTHROUGH
Definition: compiler.h:100
@ UACPI_STATUS_OUT_OF_MEMORY
Definition: status.h:13
@ UACPI_STATUS_AML_INCOMPATIBLE_OBJECT_TYPE
Definition: status.h:38
@ UACPI_OBJECT_OPERATION_REGION_BIT
Definition: types.h:144
@ UACPI_ADDRESS_SPACE_IPMI
Definition: types.h:50
@ UACPI_ADDRESS_SPACE_PRM
Definition: types.h:54
@ 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_SMBUS
Definition: types.h:47
static uacpi_status wtr_buffer_size(uacpi_field_unit *field, uacpi_address_space space, uacpi_size *out_size)
Definition: io.c:345
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
void uacpi_trace_region_error(uacpi_namespace_node *node, uacpi_char *message, uacpi_status ret)
Definition: opregion.c:25
void * uacpi_kernel_alloc(uacpi_size size)
Definition: uacpiosl.c:111
uacpi_size length
Definition: types.h:105
void * data
Definition: types.h:102

Referenced by uacpi_read_field_unit(), and write_field_unit().

◆ lock_field_unit_transaction()

static uacpi_status lock_field_unit_transaction ( uacpi_field_unit *  field)
static

Definition at line 219 of file io.c.

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}
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
struct uacpi_runtime_context g_uacpi_rt_ctx
Definition: uacpi.c:18
void uacpi_field_unit_unref(uacpi_field_unit *)
Definition: types.c:655
uacpi_status uacpi_upgrade_to_opregion_lock(void)
Definition: opregion.c:472
static uacpi_u32 uacpi_shareable_ref(uacpi_handle handle)
Definition: shareable.h:40

Referenced by uacpi_read_field_unit(), and write_field_unit().

◆ uacpi_builtin_mmio_read16()

uacpi_u16 uacpi_builtin_mmio_read16 ( void *  ptr)

Definition at line 1096 of file io.c.

1097{
1098 return *(volatile uacpi_u16*)ptr;
1099}
static PVOID ptr
Definition: dispmode.c:27

◆ uacpi_builtin_mmio_read32()

uacpi_u32 uacpi_builtin_mmio_read32 ( void *  ptr)

Definition at line 1101 of file io.c.

1102{
1103 return *(volatile uacpi_u32*)ptr;
1104}

◆ uacpi_builtin_mmio_read64()

uacpi_u64 uacpi_builtin_mmio_read64 ( void *  ptr)

Definition at line 1106 of file io.c.

1107{
1108 return *(volatile uacpi_u64*)ptr;
1109}

◆ uacpi_builtin_mmio_read8()

uacpi_u8 uacpi_builtin_mmio_read8 ( void *  ptr)

Definition at line 1091 of file io.c.

1092{
1093 return *(volatile uacpi_u8*)ptr;
1094}

◆ uacpi_builtin_mmio_write16()

void uacpi_builtin_mmio_write16 ( void *  ptr,
uacpi_u16  data 
)

Definition at line 1116 of file io.c.

1117{
1118 *(volatile uacpi_u16*)ptr = data;
1119}

◆ uacpi_builtin_mmio_write32()

void uacpi_builtin_mmio_write32 ( void *  ptr,
uacpi_u32  data 
)

Definition at line 1121 of file io.c.

1122{
1123 *(volatile uacpi_u32*)ptr = data;
1124}

◆ uacpi_builtin_mmio_write64()

void uacpi_builtin_mmio_write64 ( void *  ptr,
uacpi_u64  data 
)

Definition at line 1126 of file io.c.

1127{
1128 *(volatile uacpi_u64*)ptr = data;
1129}

◆ uacpi_builtin_mmio_write8()

void uacpi_builtin_mmio_write8 ( void *  ptr,
uacpi_u8  data 
)

Definition at line 1111 of file io.c.

1112{
1113 *(volatile uacpi_u8*)ptr = data;
1114}

◆ uacpi_field_unit_get_bit_length()

uacpi_status uacpi_field_unit_get_bit_length ( struct uacpi_field_unit *  field,
uacpi_size *  out_length 
)

Definition at line 786 of file io.c.

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}
uacpi_bool uacpi_is_buffer_access_address_space(uacpi_address_space space)
Definition: opregion.c:1111

Referenced by field_byte_size().

◆ uacpi_field_unit_get_read_type()

uacpi_status uacpi_field_unit_get_read_type ( struct uacpi_field_unit *  field,
uacpi_object_type *  out_type 
)

Definition at line 757 of file io.c.

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}
@ UACPI_OBJECT_BUFFER
Definition: types.h:114
@ UACPI_OBJECT_INTEGER
Definition: types.h:112

Referenced by field_get_read_type().

◆ uacpi_gas_read()

uacpi_status uacpi_gas_read ( const struct acpi_gas *  gas,
uacpi_u64 *  out_value 
)

Definition at line 1060 of file io.c.

1061{
1064
1067 return ret;
1068
1069 ret = uacpi_gas_read_mapped(&mapping, out_value);
1071
1072 return ret;
1073}
void uacpi_unmap_gas_nofree(uacpi_mapped_gas *gas)
Definition: io.c:1049
uacpi_status uacpi_map_gas_noalloc(const struct acpi_gas *gas, uacpi_mapped_gas *out_mapped)
Definition: io.c:992
uacpi_status uacpi_gas_read_mapped(const uacpi_mapped_gas *gas, uacpi_u64 *out_value)
Definition: io.c:911
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031

◆ uacpi_gas_read_mapped()

uacpi_status uacpi_gas_read_mapped ( const uacpi_mapped_gas *  gas,
uacpi_u64 *  value 
)

Same as uacpi_gas_{read,write} but operates on a pre-mapped handle for faster access and/or ability to use in critical sections/irq contexts.

Definition at line 911 of file io.c.

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}
#define index(s, c)
Definition: various.h:29
GLuint index
Definition: glext.h:6031
GLenum GLint GLuint mask
Definition: glext.h:6028
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
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

Referenced by detect_gpes(), do_read_one(), gpe_try_claim(), maybe_dispatch_gpe(), set_gpe_state_unlocked(), uacpi_gas_read(), and uacpi_gpe_info().

◆ uacpi_gas_write()

uacpi_status uacpi_gas_write ( const struct acpi_gas *  gas,
uacpi_u64  in_value 
)

Definition at line 1075 of file io.c.

1076{
1079
1082 return ret;
1083
1084 ret = uacpi_gas_write_mapped(&mapping, in_value);
1086
1087 return ret;
1088}
uacpi_status uacpi_gas_write_mapped(const uacpi_mapped_gas *gas, uacpi_u64 in_value)
Definition: io.c:950

◆ uacpi_gas_write_mapped()

uacpi_status uacpi_gas_write_mapped ( const uacpi_mapped_gas *  gas,
uacpi_u64  in_value 
)

Definition at line 950 of file io.c.

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}
uacpi_status(* write)(uacpi_handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in)
Definition: io.h:18

Referenced by clear_gpe(), create_gpe_block(), do_write_one(), gpe_block_apply_action(), gpe_try_claim(), set_gpe_state_unlocked(), uacpi_gas_write(), and uninstall_gpe_block().

◆ uacpi_map_gas()

uacpi_status uacpi_map_gas ( const struct acpi_gas *  gas,
uacpi_mapped_gas **  out_mapped 
)

Map a GAS for faster access in the future. The handle returned via 'out_mapped' must be freed & unmapped using uacpi_unmap_gas() when no longer needed.

Definition at line 1028 of file io.c.

1031{
1034
1038
1041 uacpi_free(mapping, sizeof(*mapping));
1042 return ret;
1043 }
1044
1045 *out_mapped = mapping;
1046 return ret;
1047}

◆ uacpi_map_gas_noalloc()

uacpi_status uacpi_map_gas_noalloc ( const struct acpi_gas *  gas,
uacpi_mapped_gas *  out_mapped 
)

Definition at line 992 of file io.c.

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}
@ UACPI_STATUS_MAPPING_FAILED
Definition: status.h:12
uacpi_status uacpi_system_io_write(uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in)
Definition: io.c:1223
uacpi_status uacpi_system_memory_read(void *ptr, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out)
Definition: io.c:1132
uacpi_status uacpi_system_io_read(uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out)
Definition: io.c:1191
static void unmap_gas_io(uacpi_handle io_handle, uacpi_size size)
Definition: io.c:986
uacpi_status uacpi_system_memory_write(void *ptr, uacpi_size offset, uacpi_u8 width, uacpi_u64 in)
Definition: io.c:1158
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_kernel_io_map(uacpi_io_addr base, uacpi_size len, uacpi_handle *out_handle)
Definition: uacpiosl.c:165
#define UACPI_MAP_FAILED
Definition: kernel_api.h:13
void uacpi_kernel_unmap(void *addr, uacpi_size len)
Definition: uacpiosl.c:198
void * uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len)
Definition: uacpiosl.c:191
void(* unmap)(uacpi_handle, uacpi_size)
Definition: io.h:22

Referenced by create_gpe_block(), map_one(), uacpi_gas_read(), uacpi_gas_write(), and uacpi_map_gas().

◆ uacpi_pci_read()

uacpi_status uacpi_pci_read ( uacpi_handle  handle,
uacpi_size  offset,
uacpi_u8  width,
uacpi_u64 *  out 
)

Definition at line 1250 of file io.c.

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}
#define uacpi_likely_success(expr)
Definition: status.h:54
GLint GLint GLsizei width
Definition: gl.h:1546
uacpi_status uacpi_kernel_pci_read8(uacpi_handle device, uacpi_size offset, uacpi_u8 *value)
Definition: uacpiosl.c:257
uacpi_status uacpi_kernel_pci_read16(uacpi_handle device, uacpi_size offset, uacpi_u16 *value)
Definition: uacpiosl.c:264
uacpi_status uacpi_kernel_pci_read32(uacpi_handle device, uacpi_size offset, uacpi_u32 *value)
Definition: uacpiosl.c:271
uacpi_u64 qword
Definition: io.c:1188

Referenced by pci_region_do_rw().

◆ uacpi_pci_write()

uacpi_status uacpi_pci_write ( uacpi_handle  handle,
uacpi_size  offset,
uacpi_u8  width,
uacpi_u64  in 
)

Definition at line 1282 of file io.c.

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}
GLuint in
Definition: glext.h:9616
uacpi_status uacpi_kernel_pci_write16(uacpi_handle device, uacpi_size offset, uacpi_u16 value)
Definition: uacpiosl.c:285
uacpi_status uacpi_kernel_pci_write8(uacpi_handle device, uacpi_size offset, uacpi_u8 value)
Definition: uacpiosl.c:278
uacpi_status uacpi_kernel_pci_write32(uacpi_handle device, uacpi_size offset, uacpi_u32 value)
Definition: uacpiosl.c:292

Referenced by pci_region_do_rw().

◆ uacpi_read_buffer_field()

void uacpi_read_buffer_field ( const uacpi_buffer_field *  field,
void *  dst 
)

Definition at line 113 of file io.c.

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}
#define uacpi_memcpy
Definition: stdlib.h:34
static void do_misaligned_buffer_read(const uacpi_buffer_field *field, uacpi_u8 *dst)
Definition: io.c:97
static void cut_misaligned_tail(uacpi_u8 *data, uacpi_size offset, uacpi_u32 bit_length)
Definition: io.c:16
GLuint GLuint GLsizei count
Definition: gl.h:1545

Referenced by handle_field_read(), and handle_inc_dec().

◆ uacpi_read_field_unit()

uacpi_status uacpi_read_field_unit ( uacpi_field_unit *  field,
void *  dst,
uacpi_size  size,
uacpi_data_view *  wtr_response 
)

Definition at line 558 of file io.c.

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}
#define uacpi_memzero(ptr, size)
Definition: stdlib.h:99
bool uacpi_bool
Definition: types.h:31
static uacpi_status do_read_misaligned_field_unit(uacpi_field_unit *field, uacpi_u8 *dst, uacpi_size size)
Definition: io.c:504
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
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
uacpi_u64 * integer
Definition: opregion.h:47

Referenced by access_field_unit(), handle_field_read(), and handle_inc_dec().

◆ uacpi_round_up_bits_to_bytes()

◆ uacpi_system_io_read()

uacpi_status uacpi_system_io_read ( uacpi_handle  handle,
uacpi_size  offset,
uacpi_u8  width,
uacpi_u64 *  out 
)

Definition at line 1191 of file io.c.

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}
uacpi_status uacpi_kernel_io_read32(uacpi_handle, uacpi_size offset, uacpi_u32 *out_value)
Definition: uacpiosl.c:313
uacpi_status uacpi_kernel_io_read8(uacpi_handle, uacpi_size offset, uacpi_u8 *out_value)
Definition: uacpiosl.c:299
uacpi_status uacpi_kernel_io_read16(uacpi_handle, uacpi_size offset, uacpi_u16 *out_value)
Definition: uacpiosl.c:306

Referenced by io_region_do_rw(), and uacpi_map_gas_noalloc().

◆ uacpi_system_io_write()

uacpi_status uacpi_system_io_write ( uacpi_handle  handle,
uacpi_size  offset,
uacpi_u8  width,
uacpi_u64  in 
)

Definition at line 1223 of file io.c.

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}
uacpi_status uacpi_kernel_io_write8(uacpi_handle, uacpi_size offset, uacpi_u8 in_value)
Definition: uacpiosl.c:320
uacpi_status uacpi_kernel_io_write32(uacpi_handle, uacpi_size offset, uacpi_u32 in_value)
Definition: uacpiosl.c:334
uacpi_status uacpi_kernel_io_write16(uacpi_handle, uacpi_size offset, uacpi_u16 in_value)
Definition: uacpiosl.c:327

Referenced by io_region_do_rw(), and uacpi_map_gas_noalloc().

◆ uacpi_system_memory_read()

uacpi_status uacpi_system_memory_read ( void *  ptr,
uacpi_size  offset,
uacpi_u8  width,
uacpi_u64 *  out 
)

Definition at line 1132 of file io.c.

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}
#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_read32
Definition: io.h:90
#define UACPI_PTR_ADD(ptr, value)
Definition: utilities.h:23

Referenced by memory_region_do_rw(), table_data_region_do_rw(), and uacpi_map_gas_noalloc().

◆ uacpi_system_memory_write()

uacpi_status uacpi_system_memory_write ( void *  ptr,
uacpi_size  offset,
uacpi_u8  width,
uacpi_u64  in 
)

Definition at line 1158 of file io.c.

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}
#define uacpi_mmio_write16
Definition: io.h:94
#define uacpi_mmio_write64
Definition: io.h:96
#define uacpi_mmio_write32
Definition: io.h:95
#define uacpi_mmio_write8
Definition: io.h:93

Referenced by memory_region_do_rw(), table_data_region_do_rw(), and uacpi_map_gas_noalloc().

◆ uacpi_unmap_gas()

void uacpi_unmap_gas ( uacpi_mapped_gas *  gas)

Definition at line 1054 of file io.c.

1055{
1057 uacpi_free(gas, sizeof(*gas));
1058}

◆ uacpi_unmap_gas_nofree()

void uacpi_unmap_gas_nofree ( uacpi_mapped_gas *  gas)

Definition at line 1049 of file io.c.

1050{
1051 gas->unmap(gas->mapping, gas->access_bit_width / 8);
1052}

Referenced by free_gpe_block(), uacpi_deinitialize_registers(), uacpi_gas_read(), uacpi_gas_write(), and uacpi_unmap_gas().

◆ uacpi_write_buffer_field()

void uacpi_write_buffer_field ( uacpi_buffer_field *  field,
const void *  src,
uacpi_size  size 
)

Definition at line 152 of file io.c.

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}
static void do_write_misaligned_buffer_field(uacpi_buffer_field *field, const void *src, uacpi_size size)
Definition: io.c:134

Referenced by object_assign_with_implicit_cast().

◆ uacpi_write_field_unit()

uacpi_status uacpi_write_field_unit ( uacpi_field_unit *  field,
const void *  src,
uacpi_size  size,
uacpi_data_view *  wtr_response 
)

Definition at line 738 of file io.c.

742{
743 return write_field_unit(field, src, size, size, wtr_response);
744}
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

Referenced by access_field_unit(), and store_to_field_unit().

◆ uacpi_write_field_unit_in_chunks()

uacpi_status uacpi_write_field_unit_in_chunks ( uacpi_field_unit *  field,
const void *  src,
uacpi_size  size,
uacpi_data_view *  wtr_response 
)

Definition at line 746 of file io.c.

750{
751 return write_field_unit(
753 wtr_response
754 );
755}

Referenced by store_to_field_unit().

◆ unlock_field_unit_transaction()

static void unlock_field_unit_transaction ( uacpi_field_unit *  field)
static

Definition at line 256 of file io.c.

257{
259
261 uacpi_release_aml_mutex(g_uacpi_rt_ctx.global_lock_mutex);
262
264}
void uacpi_release_opregion_lock(void)
Definition: opregion.c:487

Referenced by uacpi_read_field_unit(), and write_field_unit().

◆ unmap_gas_io()

static void unmap_gas_io ( uacpi_handle  io_handle,
uacpi_size  size 
)
static

Definition at line 986 of file io.c.

987{
989 uacpi_kernel_io_unmap(io_handle);
990}
#define UACPI_UNUSED(x)
Definition: helpers.h:7
void uacpi_kernel_io_unmap(uacpi_handle handle)
Definition: uacpiosl.c:171

Referenced by uacpi_map_gas_noalloc().

◆ write_field_unit()

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 
)
static

Definition at line 696 of file io.c.

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}
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
static uacpi_status write_generic_field_unit(uacpi_field_unit *field, const void *src, uacpi_size size)
Definition: io.c:625
const void * const_data
Definition: types.h:103

Referenced by uacpi_write_field_unit(), and uacpi_write_field_unit_in_chunks().

◆ write_generic_field_unit()

static uacpi_status write_generic_field_unit ( uacpi_field_unit *  field,
const void *  src,
uacpi_size  size 
)
static

Definition at line 625 of file io.c.

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}
@ 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

Referenced by write_field_unit().

◆ wtr_buffer_size()

static uacpi_status wtr_buffer_size ( uacpi_field_unit *  field,
uacpi_address_space  space,
uacpi_size *  out_size 
)
static

Definition at line 345 of file io.c.

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}
@ 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
#define IPMI_DATA_SIZE
Definition: io.c:343
#define SERIAL_HEADER_SIZE
Definition: io.c:342
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID ULONG out_size
Definition: file.c:72

Referenced by handle_special_field().