mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 23:18:21 +00:00
acpi: /dev/acpi
This commit is contained in:
@@ -80,6 +80,8 @@ void kernel_entry() {
|
|||||||
sockfs_init();
|
sockfs_init();
|
||||||
ext2_init();
|
ext2_init();
|
||||||
|
|
||||||
|
acpi_initdevice();
|
||||||
|
|
||||||
tty_init();
|
tty_init();
|
||||||
pty_init();
|
pty_init();
|
||||||
|
|
||||||
|
|||||||
@@ -10,4 +10,9 @@ void acpi_init(void);
|
|||||||
int acpi_poweroff(void);
|
int acpi_poweroff(void);
|
||||||
int acpi_reboot(void);
|
int acpi_reboot(void);
|
||||||
|
|
||||||
|
void acpi_signaldevice(char c);
|
||||||
|
|
||||||
|
// Depends on devfs
|
||||||
|
void acpi_initdevice(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
#define DEV_MAJOR_NET 10
|
#define DEV_MAJOR_NET 10
|
||||||
#define DEV_MAJOR_MOUSE 11
|
#define DEV_MAJOR_MOUSE 11
|
||||||
#define DEV_MAJOR_PTY 12
|
#define DEV_MAJOR_PTY 12
|
||||||
|
#define DEV_MAJOR_ACPI 13
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int (*open)(int minor, vnode_t **vnode, int flags);
|
int (*open)(int minor, vnode_t **vnode, int flags);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ void acpi_early_init(void) {
|
|||||||
|
|
||||||
void acpi_dopoweroff(uacpi_handle ctx) {
|
void acpi_dopoweroff(uacpi_handle ctx) {
|
||||||
(void)ctx;
|
(void)ctx;
|
||||||
acpi_poweroff();
|
acpi_signaldevice('p');
|
||||||
}
|
}
|
||||||
|
|
||||||
static uacpi_interrupt_ret handle_pwrbtn(uacpi_handle ctx) {
|
static uacpi_interrupt_ret handle_pwrbtn(uacpi_handle ctx) {
|
||||||
|
|||||||
@@ -0,0 +1,119 @@
|
|||||||
|
#include <kernel/acpi.h>
|
||||||
|
#include <kernel/devfs.h>
|
||||||
|
#include <kernel/poll.h>
|
||||||
|
#include <spinlock.h>
|
||||||
|
#include <ringbuffer.h>
|
||||||
|
#include <logging.h>
|
||||||
|
|
||||||
|
static ringbuffer_t ringbuffer;
|
||||||
|
static pollheader_t pollheader;
|
||||||
|
static spinlock_t lock;
|
||||||
|
|
||||||
|
void acpi_signaldevice(char c) {
|
||||||
|
long ipl = spinlock_acquireraiseipl(&lock, IPL_DPC);
|
||||||
|
|
||||||
|
if (ringbuffer_write(&ringbuffer, &c, 1))
|
||||||
|
poll_event(&pollheader, POLLIN);
|
||||||
|
|
||||||
|
spinlock_releaseloweripl(&lock, ipl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int internalpoll(polldata_t *data, int events) {
|
||||||
|
int revents = 0;
|
||||||
|
if (events & POLLOUT)
|
||||||
|
revents |= POLLOUT;
|
||||||
|
|
||||||
|
if ((events & POLLIN) && RINGBUFFER_DATACOUNT(&ringbuffer))
|
||||||
|
revents |= POLLIN;
|
||||||
|
|
||||||
|
if (revents == 0)
|
||||||
|
poll_add(&pollheader, data, events);
|
||||||
|
|
||||||
|
return revents;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read(int minor, void *buffer, size_t size, uintmax_t offset, int flags, size_t *readc) {
|
||||||
|
*readc = 0;
|
||||||
|
|
||||||
|
if (size < 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
polldesc_t desc;
|
||||||
|
int error = poll_initdesc(&desc, 1);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
long ipl = spinlock_acquireraiseipl(&lock, IPL_DPC);
|
||||||
|
|
||||||
|
int revents = internalpoll(&desc.data[0], POLLIN);
|
||||||
|
|
||||||
|
spinlock_releaseloweripl(&lock, ipl);
|
||||||
|
|
||||||
|
if (revents)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (flags & V_FFLAGS_NONBLOCKING) {
|
||||||
|
error = EAGAIN;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = poll_dowait(&desc, 0);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
poll_leave(&desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
long ipl = spinlock_acquireraiseipl(&lock, IPL_DPC);
|
||||||
|
|
||||||
|
*readc = ringbuffer_read(&ringbuffer, buffer, size);
|
||||||
|
|
||||||
|
spinlock_releaseloweripl(&lock, ipl);
|
||||||
|
|
||||||
|
leave:
|
||||||
|
poll_leave(&desc);
|
||||||
|
poll_destroydesc(&desc);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write(int minor, void *buffer, size_t size, uintmax_t offset, int flags, size_t *writec) {
|
||||||
|
if (size < 1) {
|
||||||
|
*writec = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *c = buffer;
|
||||||
|
switch (*c) {
|
||||||
|
case 'p':
|
||||||
|
acpi_poweroff();
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
acpi_reboot();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int poll(int minor, polldata_t *data, int events) {
|
||||||
|
long ipl = spinlock_acquireraiseipl(&lock, IPL_DPC);
|
||||||
|
|
||||||
|
int revents = internalpoll(data, events);
|
||||||
|
|
||||||
|
spinlock_releaseloweripl(&lock, ipl);
|
||||||
|
return revents;
|
||||||
|
}
|
||||||
|
|
||||||
|
static devops_t acpiops = {
|
||||||
|
.read = read,
|
||||||
|
.write = write,
|
||||||
|
.poll = poll
|
||||||
|
};
|
||||||
|
|
||||||
|
void acpi_initdevice(void) {
|
||||||
|
__assert(devfs_register(&acpiops, "acpi", V_TYPE_CHDEV, DEV_MAJOR_ACPI, 0, 0600, NULL) == 0);
|
||||||
|
__assert(ringbuffer_init(&ringbuffer, 64) == 0);
|
||||||
|
POLL_INITHEADER(&pollheader);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user