Implement serial logging. Finish modularizing power management.
[monolithium.git] / kernel / src / power.c
1 /*
2  * power.c
3  *
4  * Copyright (C) 2016 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as
8  * published by the Free Software Foundation, either version 3 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <power.h>
21 #include <syscalls.h>
22 #include <user.h>
23
24 static power_callbacks_t *power_callbacks = NULL;
25
26 dword_t register_power_callbacks(power_callbacks_t *callbacks)
27 {
28     if (callbacks && power_callbacks) return ERR_EXISTS;
29     power_callbacks = callbacks;
30     return ERR_SUCCESS;
31 }
32
33 sysret_t syscall_power_control(power_command_t command)
34 {
35     if (get_previous_mode() == USER_MODE && !check_privileges(PRIVILEGE_POWER_CONTROL))
36     {
37         return ERR_FORBIDDEN;
38     }
39
40     switch (command)
41     {
42     case POWER_COMMAND_SHUTDOWN:
43         if (power_callbacks) power_callbacks->set_state(POWER_STATE_OFF);
44
45     case POWER_COMMAND_HALT:
46         disable_ints();
47         halt();
48         break;
49
50     case POWER_COMMAND_REBOOT:
51         disable_ints();
52         while (inportb(0x64) & 0x02) continue;
53         outportb(0x64, 0xFE);
54         halt();
55         break;
56
57     default:
58         return ERR_INVALID;
59     }
60
61     return ERR_SUCCESS;
62 }