Skip to content

Commit

Permalink
Get rid of uacpi_kernel_raw_* entirely
Browse files Browse the repository at this point in the history
These are redundant in that they can be fully implemented internally in
terms of already existing kernel API, so get rid of them.

Signed-off-by: Daniil Tatianin <99danilt@gmail.com>
  • Loading branch information
d-tatianin committed Dec 21, 2024
1 parent f66d73a commit 296508e
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 144 deletions.
10 changes: 10 additions & 0 deletions include/uacpi/internal/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,13 @@ uacpi_status uacpi_read_field_unit(
uacpi_status uacpi_write_field_unit(
uacpi_field_unit *field, const void *src, uacpi_size size
);

uacpi_status uacpi_system_io_read(
uacpi_io_addr address, uacpi_u8 width, uacpi_u64 *out
);
uacpi_status uacpi_system_io_write(
uacpi_io_addr address, uacpi_u8 width, uacpi_u64 in
);

uacpi_status uacpi_system_memory_read(void *ptr, uacpi_u8 width, uacpi_u64 *out);
uacpi_status uacpi_system_memory_write(void *ptr, uacpi_u8 width, uacpi_u64 in);
32 changes: 0 additions & 32 deletions include/uacpi/kernel_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,38 +30,6 @@ void uacpi_kernel_deinitialize(void);
// Returns the PHYSICAL address of the RSDP structure via *out_rsdp_address.
uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *out_rsdp_address);

/*
* Raw IO API, this is only used for accessing verified data from
* "safe" code (aka not indirectly invoked by the AML interpreter),
* e.g. programming FADT & FACS registers.
*
* NOTE:
* 'byte_width' is ALWAYS one of 1, 2, 4, 8. You are NOT allowed to implement
* this in terms of memcpy, as hardware expects accesses to be of the EXACT
* width.
* -------------------------------------------------------------------------
*/
uacpi_status uacpi_kernel_raw_memory_read(
uacpi_phys_addr address, uacpi_u8 byte_width, uacpi_u64 *out_value
);
uacpi_status uacpi_kernel_raw_memory_write(
uacpi_phys_addr address, uacpi_u8 byte_width, uacpi_u64 in_value
);

/*
* NOTE:
* 'byte_width' is ALWAYS one of 1, 2, 4. You are NOT allowed to break e.g. a
* 4-byte access into four 1-byte accesses. Hardware ALWAYS expects accesses to
* be of the exact width.
*/
uacpi_status uacpi_kernel_raw_io_read(
uacpi_io_addr address, uacpi_u8 byte_width, uacpi_u64 *out_value
);
uacpi_status uacpi_kernel_raw_io_write(
uacpi_io_addr address, uacpi_u8 byte_width, uacpi_u64 in_value
);
// -------------------------------------------------------------------------

/*
* NOTE:
* 'byte_width' is ALWAYS one of 1, 2, 4. Since PCI registers are 32 bits wide
Expand Down
53 changes: 5 additions & 48 deletions source/default_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <uacpi/internal/utilities.h>
#include <uacpi/internal/helpers.h>
#include <uacpi/internal/log.h>
#include <uacpi/internal/io.h>
#include <uacpi/kernel_api.h>
#include <uacpi/uacpi.h>

Expand Down Expand Up @@ -262,50 +263,6 @@ static uacpi_status io_region_detach(uacpi_region_detach_data *data)
return UACPI_STATUS_OK;
}

static uacpi_status memory_read(void *ptr, uacpi_u8 width, uacpi_u64 *out)
{
switch (width) {
case 1:
*out = *(volatile uacpi_u8*)ptr;
break;
case 2:
*out = *(volatile uacpi_u16*)ptr;
break;
case 4:
*out = *(volatile uacpi_u32*)ptr;
break;
case 8:
*out = *(volatile uacpi_u64*)ptr;
break;
default:
return UACPI_STATUS_INVALID_ARGUMENT;
}

return UACPI_STATUS_OK;
}

static uacpi_status memory_write(void *ptr, uacpi_u8 width, uacpi_u64 in)
{
switch (width) {
case 1:
*(volatile uacpi_u8*)ptr = in;
break;
case 2:
*(volatile uacpi_u16*)ptr = in;
break;
case 4:
*(volatile uacpi_u32*)ptr = in;
break;
case 8:
*(volatile uacpi_u64*)ptr = in;
break;
default:
return UACPI_STATUS_INVALID_ARGUMENT;
}

return UACPI_STATUS_OK;
}

static uacpi_status memory_region_do_rw(
uacpi_region_op op, uacpi_region_rw_data *data
)
Expand All @@ -316,8 +273,8 @@ static uacpi_status memory_region_do_rw(
ptr = ctx->virt + (data->address - ctx->phys);

return op == UACPI_REGION_OP_READ ?
memory_read(ptr, data->byte_width, &data->value) :
memory_write(ptr, data->byte_width, data->value);
uacpi_system_memory_read(ptr, data->byte_width, &data->value) :
uacpi_system_memory_write(ptr, data->byte_width, data->value);
}

static uacpi_status handle_memory_region(uacpi_region_op op, uacpi_handle op_data)
Expand All @@ -342,8 +299,8 @@ static uacpi_status table_data_region_do_rw(
void *addr = UACPI_VIRT_ADDR_TO_PTR((uacpi_virt_addr)data->offset);

return op == UACPI_REGION_OP_READ ?
memory_read(addr, data->byte_width, &data->value) :
memory_write(addr, data->byte_width, data->value);
uacpi_system_memory_read(addr, data->byte_width, &data->value) :
uacpi_system_memory_write(addr, data->byte_width, data->value);
}

static uacpi_status handle_table_data_region(uacpi_region_op op, uacpi_handle op_data)
Expand Down
108 changes: 96 additions & 12 deletions source/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -517,13 +517,16 @@ uacpi_status uacpi_gas_read(const struct acpi_gas *gas, uacpi_u64 *out_value)
uacpi_u64 address = gas->address + (index * access_byte_width);

if (gas->address_space_id == UACPI_ADDRESS_SPACE_SYSTEM_IO) {
ret = uacpi_kernel_raw_io_read(
address, access_byte_width, &data
);
ret = uacpi_system_io_read(address, access_byte_width, &data);
} else {
ret = uacpi_kernel_raw_memory_read(
address, access_byte_width, &data
);
void *virt;

virt = uacpi_kernel_map(address, access_byte_width);
if (uacpi_unlikely(virt == UACPI_NULL))
return UACPI_STATUS_MAPPING_FAILED;

ret = uacpi_system_memory_read(virt, access_byte_width, &data);
uacpi_kernel_unmap(virt, access_bit_width);
}
if (uacpi_unlikely_error(ret))
return ret;
Expand Down Expand Up @@ -564,13 +567,16 @@ uacpi_status uacpi_gas_write(const struct acpi_gas *gas, uacpi_u64 in_value)
uacpi_u64 address = gas->address + (index * access_byte_width);

if (gas->address_space_id == UACPI_ADDRESS_SPACE_SYSTEM_IO) {
ret = uacpi_kernel_raw_io_write(
address, access_byte_width, data
);
ret = uacpi_system_io_write(address, access_byte_width, data);
} else {
ret = uacpi_kernel_raw_memory_write(
address, access_byte_width, data
);
void *virt;

virt = uacpi_kernel_map(address, access_byte_width);
if (uacpi_unlikely(virt == UACPI_NULL))
return UACPI_STATUS_MAPPING_FAILED;

ret = uacpi_system_memory_write(virt, access_byte_width, data);
uacpi_kernel_unmap(virt, access_bit_width);
}
if (uacpi_unlikely_error(ret))
return ret;
Expand All @@ -582,3 +588,81 @@ uacpi_status uacpi_gas_write(const struct acpi_gas *gas, uacpi_u64 in_value)

return UACPI_STATUS_OK;
}

uacpi_status uacpi_system_io_read(
uacpi_io_addr address, uacpi_u8 width, uacpi_u64 *out
)
{
uacpi_status ret;
uacpi_handle handle;

ret = uacpi_kernel_io_map(address, width, &handle);
if (uacpi_unlikely_error(ret))
return ret;

ret = uacpi_kernel_io_read(handle, 0, width, out);
uacpi_kernel_io_unmap(handle);

return ret;
}

uacpi_status uacpi_system_io_write(
uacpi_io_addr address, uacpi_u8 width, uacpi_u64 in
)
{
uacpi_status ret;
uacpi_handle handle;

ret = uacpi_kernel_io_map(address, width, &handle);
if (uacpi_unlikely_error(ret))
return ret;

ret = uacpi_kernel_io_write(handle, 0, width, in);
uacpi_kernel_io_unmap(handle);

return ret;
}

uacpi_status uacpi_system_memory_read(void *ptr, uacpi_u8 width, uacpi_u64 *out)
{
switch (width) {
case 1:
*out = *(volatile uacpi_u8*)ptr;
break;
case 2:
*out = *(volatile uacpi_u16*)ptr;
break;
case 4:
*out = *(volatile uacpi_u32*)ptr;
break;
case 8:
*out = *(volatile uacpi_u64*)ptr;
break;
default:
return UACPI_STATUS_INVALID_ARGUMENT;
}

return UACPI_STATUS_OK;
}

uacpi_status uacpi_system_memory_write(void *ptr, uacpi_u8 width, uacpi_u64 in)
{
switch (width) {
case 1:
*(volatile uacpi_u8*)ptr = in;
break;
case 2:
*(volatile uacpi_u16*)ptr = in;
break;
case 4:
*(volatile uacpi_u32*)ptr = in;
break;
case 8:
*(volatile uacpi_u64*)ptr = in;
break;
default:
return UACPI_STATUS_INVALID_ARGUMENT;
}

return UACPI_STATUS_OK;
}
4 changes: 2 additions & 2 deletions source/registers.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ static uacpi_status read_one(
return uacpi_gas_read(reg, out_value);
}

return uacpi_kernel_raw_io_read(*(uacpi_u32*)reg, byte_width, out_value);
return uacpi_system_io_read(*(uacpi_u32*)reg, byte_width, out_value);
}

static uacpi_status write_one(
Expand All @@ -123,7 +123,7 @@ static uacpi_status write_one(
return uacpi_gas_write(reg, in_value);
}

return uacpi_kernel_raw_io_write(*(uacpi_u32*)reg, byte_width, in_value);
return uacpi_system_io_write(*(uacpi_u32*)reg, byte_width, in_value);
}

static uacpi_status do_read_register(
Expand Down
4 changes: 1 addition & 3 deletions source/sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,9 +550,7 @@ uacpi_status uacpi_reboot(void)
* For SystemIO we don't do any checking, and we ignore bit width
* because that's what NT does.
*/
ret = uacpi_kernel_raw_io_write(
reset_reg->address, 1, fadt->reset_value
);
ret = uacpi_system_io_write(reset_reg->address, 1, fadt->reset_value);
break;
case UACPI_ADDRESS_SPACE_SYSTEM_MEMORY:
ret = uacpi_write_register(UACPI_REGISTER_RESET, fadt->reset_value);
Expand Down
65 changes: 18 additions & 47 deletions tests/runner/interface_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,45 +53,6 @@ void uacpi_kernel_deinitialize(void)
}
#endif

uacpi_status uacpi_kernel_raw_memory_read(
uacpi_phys_addr, uacpi_u8, uacpi_u64 *ret
)
{
*ret = 0;
return UACPI_STATUS_OK;
}

uacpi_status uacpi_kernel_raw_memory_write(
uacpi_phys_addr, uacpi_u8, uacpi_u64
)
{
return UACPI_STATUS_OK;
}

uacpi_status uacpi_kernel_raw_io_read(
uacpi_io_addr addr, uacpi_u8 width, uacpi_u64 *ret
)
{
if (io_space && addr <= UINT16_MAX) {
*ret = 0;
memcpy(ret, &io_space[addr], width);
} else {
*ret = 0xFFFFFFFFFFFFFFFF;
}

return UACPI_STATUS_OK;
}

uacpi_status uacpi_kernel_raw_io_write(
uacpi_io_addr addr, uacpi_u8 width, uacpi_u64 value
)
{
if (io_space && addr <= UINT16_MAX)
memcpy(&io_space[addr], &value, width);

return UACPI_STATUS_OK;
}

uacpi_status uacpi_kernel_io_map(uacpi_io_addr addr, uacpi_size,
uacpi_handle *out_handle)
{
Expand All @@ -106,9 +67,16 @@ uacpi_status uacpi_kernel_io_read(
uacpi_u8 byte_width, uacpi_u64 *value
)
{
return uacpi_kernel_raw_io_read(
(uacpi_io_addr)handle + offset, byte_width, value
);
auto addr = (uacpi_io_addr)handle + offset;

if (io_space && addr <= UINT16_MAX) {
*value = 0;
memcpy(value, &io_space[addr], byte_width);
} else {
*value = 0xFFFFFFFFFFFFFFFF;
}

return UACPI_STATUS_OK;
}

uacpi_status uacpi_kernel_pci_read(
Expand All @@ -124,16 +92,19 @@ uacpi_status uacpi_kernel_io_write(
uacpi_u8 byte_width, uacpi_u64 value
)
{
return uacpi_kernel_raw_io_write(
(uacpi_io_addr)handle + offset, byte_width, value
);
auto addr = (uacpi_io_addr)handle + offset;

if (io_space && addr <= UINT16_MAX)
memcpy(&io_space[addr], &value, byte_width);

return UACPI_STATUS_OK;
}

uacpi_status uacpi_kernel_pci_write(
uacpi_pci_address*, uacpi_size, uacpi_u8, uacpi_u64
uacpi_pci_address*, uacpi_size offset, uacpi_u8 byte_width, uacpi_u64 value
)
{
return UACPI_STATUS_OK;
return uacpi_kernel_io_write(nullptr, offset, byte_width, value);
}

bool g_expect_virtual_addresses = true;
Expand Down

0 comments on commit 296508e

Please sign in to comment.