summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2022-02-12 11:18:44 +1100
committerDamien Zammit <damien@zamaudio.com>2022-02-12 11:18:44 +1100
commit64c73eea8732cc890fce2281a234ddc0fd55750a (patch)
tree2bf2c1f05439c76444e878dab517a9fe85607332
parenta9ad1c6dd440bad1237db845cfa7ae45a237ce33 (diff)
acpi: Remove /dev/mem, use device_open(mem)
-rw-r--r--acpi/acpi.c73
-rw-r--r--libacpica/acpi_init.c59
2 files changed, 79 insertions, 53 deletions
diff --git a/acpi/acpi.c b/acpi/acpi.c
index ae84f869..a3ee74c2 100644
--- a/acpi/acpi.c
+++ b/acpi/acpi.c
@@ -27,29 +27,46 @@
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
-
+#include <hurd.h>
+#include <device/device.h>
+#include <error.h>
#include "acpi.h"
int
mmap_phys_acpi_header(uintptr_t base_addr, struct acpi_header **ptr_to_header,
- void **virt_addr, int fd)
+ void **virt_addr)
{
- /* The memory mapping must be done aligned to page size
- * but we have a known physical address we want to inspect,
- * therefore we must compute offsets.
- */
- uintptr_t pa_acpi = base_addr & ~(sysconf(_SC_PAGE_SIZE) - 1);
- uintptr_t pa_start = base_addr - pa_acpi;
-
- /* Map the ACPI table at the nearest page (rounded down) */
- *virt_addr = 0;
- *virt_addr = mmap(NULL, ESCD_SIZE, PROT_READ, MAP_SHARED,
- fd, (off_t) pa_acpi);
-
- if (*virt_addr == MAP_FAILED)
- return errno;
-
- /* Fabricate a pointer to our magic address */
+ int err;
+ mach_port_t device_master;
+ device_t mem_device;
+ mach_port_t memobj;
+ uintptr_t pa_offset = base_addr & ~(sysconf(_SC_PAGE_SIZE) - 1);
+ uintptr_t pa_start = base_addr - pa_offset;
+
+ err = get_privileged_ports (0, &device_master);
+ if (err)
+ error (2, err, "Cannot get device master port");
+
+ err = device_open (device_master, 0, "mem", &mem_device);
+ mach_port_deallocate (mach_task_self (), device_master);
+ if (err)
+ error (2, err, "device_open(mem)");
+
+ err = device_map (mem_device, VM_PROT_READ, pa_offset, ESCD_SIZE + pa_start, &memobj, 0);
+ mach_port_deallocate (mach_task_self (), mem_device);
+
+ if (! err)
+ {
+ *virt_addr = 0;
+ err =
+ vm_map (mach_task_self (), (vm_address_t *)virt_addr, ESCD_SIZE + pa_start, 0, 1,
+ memobj, 0, 0, VM_PROT_READ, VM_PROT_READ, VM_INHERIT_NONE);
+ mach_port_deallocate (mach_task_self (), memobj);
+ }
+
+ if (err)
+ return err;
+
*ptr_to_header = (struct acpi_header *)(*virt_addr + pa_start);
return 0;
@@ -59,7 +76,6 @@ int
acpi_get_num_tables(size_t *num_tables)
{
int err;
- int fd_mem;
uintptr_t sdt_base = (uintptr_t)0;
uintptr_t root = (uintptr_t)0;
bool is_64bit = false;
@@ -72,10 +88,7 @@ acpi_get_num_tables(size_t *num_tables)
if (err)
return err;
- if ((fd_mem = open("/dev/mem", O_RDWR)) < 0)
- return EPERM;
-
- err = mmap_phys_acpi_header(sdt_base, &root_sdt, &virt_addr, fd_mem);
+ err = mmap_phys_acpi_header(sdt_base, &root_sdt, &virt_addr);
if (err)
{
munmap(virt_addr, ESCD_SIZE);
@@ -98,9 +111,9 @@ acpi_get_num_tables(size_t *num_tables)
uintptr_t acpi_ptr32 = (uintptr_t)*((uint32_t *)(acpi_ptr + i*sz_ptr));
uintptr_t acpi_ptr64 = (uintptr_t)*((uint64_t *)(acpi_ptr + i*sz_ptr));
if (is_64bit)
- err = mmap_phys_acpi_header(acpi_ptr64, &next, &virt_addr2, fd_mem);
+ err = mmap_phys_acpi_header(acpi_ptr64, &next, &virt_addr2);
else
- err = mmap_phys_acpi_header(acpi_ptr32, &next, &virt_addr2, fd_mem);
+ err = mmap_phys_acpi_header(acpi_ptr32, &next, &virt_addr2);
char name[5] = { 0 };
snprintf(name, 5, "%s", &next->signature[0]);
@@ -122,7 +135,6 @@ int
acpi_get_tables(struct acpi_table **tables)
{
int err;
- int fd_mem;
void *virt_addr, *virt_addr2;
uintptr_t sdt_base = (uintptr_t)0;
uintptr_t root = (uintptr_t)0;
@@ -145,10 +157,7 @@ acpi_get_tables(struct acpi_table **tables)
if (err)
return err;
- if ((fd_mem = open("/dev/mem", O_RDWR)) < 0)
- return EPERM;
-
- err = mmap_phys_acpi_header(sdt_base, &root_sdt, &virt_addr, fd_mem);
+ err = mmap_phys_acpi_header(sdt_base, &root_sdt, &virt_addr);
if (err)
{
munmap(virt_addr, ESCD_SIZE);
@@ -171,7 +180,7 @@ acpi_get_tables(struct acpi_table **tables)
uintptr_t acpi_ptr64 = (uintptr_t)*((uint64_t *)(acpi_ptr + i*sz_ptr));
if (is_64bit)
{
- err = mmap_phys_acpi_header(acpi_ptr64, &next, &virt_addr2, fd_mem);
+ err = mmap_phys_acpi_header(acpi_ptr64, &next, &virt_addr2);
if (err)
{
munmap(virt_addr, ESCD_SIZE);
@@ -180,7 +189,7 @@ acpi_get_tables(struct acpi_table **tables)
}
else
{
- err = mmap_phys_acpi_header(acpi_ptr32, &next, &virt_addr2, fd_mem);
+ err = mmap_phys_acpi_header(acpi_ptr32, &next, &virt_addr2);
if (err)
{
munmap(virt_addr, ESCD_SIZE);
diff --git a/libacpica/acpi_init.c b/libacpica/acpi_init.c
index aba0049d..0214498c 100644
--- a/libacpica/acpi_init.c
+++ b/libacpica/acpi_init.c
@@ -26,6 +26,9 @@
#include <semaphore.h>
#include <limits.h>
+#include <hurd.h>
+#include <device/device.h>
+
#define ACPI_MAX_TABLES 128
// Lets keep the ACPI tables in this module
@@ -125,20 +128,12 @@ acpi_os_execute(acpi_execute_type type,
int
acpi_get_root_table_pointer(uintptr_t *root, uintptr_t *sdt_base, bool *is_64bit)
{
- int fd_mem;
int err = 0;
void *virt_addr;
struct rsdp_descr2 rsdp = { 0 };
unsigned char *buf;
- if ((fd_mem = open("/dev/mem", O_RDWR)) < 0)
- return EPERM;
-
- virt_addr = mmap(NULL, ESCD_SIZE, PROT_READ,
- MAP_SHARED, fd_mem, ESCD);
- if (virt_addr == MAP_FAILED)
- return errno;
-
+ virt_addr = acpi_os_map_memory(ESCD, ESCD_SIZE);
buf = (unsigned char *)virt_addr;
/* RSDP magic string is 16 byte aligned */
@@ -161,8 +156,6 @@ acpi_get_root_table_pointer(uintptr_t *root, uintptr_t *sdt_base, bool *is_64bit
}
}
- munmap(virt_addr, ESCD_SIZE);
- close(fd_mem);
return err;
}
@@ -195,24 +188,48 @@ acpi_os_get_timer(void)
void *
acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
{
- int fd_mem;
- void * virt_addr;
- uintptr_t into_page = phys % PAGE_SIZE;
- uintptr_t nearest_page = (uintptr_t)trunc_page(phys);
+ int err;
+ mach_port_t device_master;
+ device_t mem_device;
+ mach_port_t memobj;
+ void *virt_addr;
+ uintptr_t pa_offset = phys & ~(sysconf(_SC_PAGE_SIZE) - 1);
+ uintptr_t pa_start = phys - pa_offset;
- if ((fd_mem = open("/dev/mem", O_RDWR)) < 0) {
- acpi_os_printf("Can't open /dev/mem\n");
+ err = get_privileged_ports (0, &device_master);
+ if (err) {
+ acpi_os_printf("Cannot get device master port");
return (void *)-1;
}
- virt_addr = mmap(NULL, into_page + size, PROT_READ,
- MAP_SHARED, fd_mem, nearest_page);
- if (virt_addr == MAP_FAILED) {
+ err = device_open (device_master, 0, "mem", &mem_device);
+ mach_port_deallocate (mach_task_self (), device_master);
+ if (err) {
+ acpi_os_printf("device_open(mem)");
+ return (void *)-1;
+ }
+
+ err =
+ device_map (mem_device, VM_PROT_READ | VM_PROT_WRITE, pa_offset, size + pa_start, &memobj, 0);
+ mach_port_deallocate (mach_task_self (), mem_device);
+
+ if (! err) {
+ virt_addr = 0;
+ err =
+ vm_map (mach_task_self (), (vm_address_t *)&virt_addr, size + pa_start, 0, 1,
+ memobj, 0, 0,
+ VM_PROT_READ | VM_PROT_WRITE,
+ VM_PROT_READ | VM_PROT_WRITE,
+ VM_INHERIT_NONE);
+ mach_port_deallocate (mach_task_self (), memobj);
+ }
+
+ if (err) {
acpi_os_printf("Can't map memory 0x%llx\n", phys);
return (void *)-1;
}
- return virt_addr + into_page;
+ return virt_addr + pa_start;
}
acpi_status