Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions kernel/arch/aarch64/syscall/linux_syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ constexpr uint64_t RT_SIGACTION = 134;
constexpr uint64_t RT_SIGPROCMASK = 135;
constexpr uint64_t RT_SIGPENDING = 136;
constexpr uint64_t RT_SIGRETURN = 139;
constexpr uint64_t REBOOT = 142;
constexpr uint64_t SETPGID = 154;
constexpr uint64_t GETPGID = 155;
constexpr uint64_t UNAME = 160;
Expand Down
1 change: 1 addition & 0 deletions kernel/arch/x86_64/syscall/linux_syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ constexpr uint64_t SETPGID = 109;
constexpr uint64_t GETPGID = 121;
constexpr uint64_t RT_SIGPENDING = 127;
constexpr uint64_t ARCH_PRCTL = 158;
constexpr uint64_t REBOOT = 169;
constexpr uint64_t GETTID = 186;
constexpr uint64_t TKILL = 200;
constexpr uint64_t FUTEX = 202;
Expand Down
49 changes: 49 additions & 0 deletions kernel/syscall/handlers/sys_power.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "syscall/handlers/sys_power.h"

#include "power/power.h"
#include "hw/cpu.h"
#include "common/logging.h"

// Linux reboot(2) magic values, required so a stray syscall with a
// garbage number cannot take the machine down by accident.
constexpr uint32_t REBOOT_MAGIC1 = 0xFEE1DEAD;
constexpr uint32_t REBOOT_MAGIC2 = 672274793;
constexpr uint32_t REBOOT_MAGIC2A = 85072278;
constexpr uint32_t REBOOT_MAGIC2B = 369367448;
constexpr uint32_t REBOOT_MAGIC2C = 537993216;

// Linux reboot(2) commands
constexpr uint32_t REBOOT_CMD_RESTART = 0x01234567;
constexpr uint32_t REBOOT_CMD_HALT = 0xCDEF0123;
constexpr uint32_t REBOOT_CMD_POWER_OFF = 0x4321FEDC;

DEFINE_SYSCALL3(reboot, magic1, magic2, cmd) {
if (static_cast<uint32_t>(magic1) != REBOOT_MAGIC1) {
return syscall::EINVAL;
}

uint32_t m2 = static_cast<uint32_t>(magic2);
if (m2 != REBOOT_MAGIC2 && m2 != REBOOT_MAGIC2A &&
m2 != REBOOT_MAGIC2B && m2 != REBOOT_MAGIC2C) {
return syscall::EINVAL;
}

switch (static_cast<uint32_t>(cmd)) {
case REBOOT_CMD_RESTART:
log::info("power: restarting system");
power::reboot();
return syscall::EOPNOTSUPP;
case REBOOT_CMD_POWER_OFF:
log::info("power: powering off");
power::shutdown();
return syscall::EOPNOTSUPP;
case REBOOT_CMD_HALT:
log::info("power: system halted");
cpu::irq_disable();
while (true) {
cpu::halt();
}
Comment thread
FlareCoding marked this conversation as resolved.
default:
return syscall::EINVAL;
}
}
8 changes: 8 additions & 0 deletions kernel/syscall/handlers/sys_power.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef STELLUX_SYSCALL_HANDLERS_SYS_POWER_H
#define STELLUX_SYSCALL_HANDLERS_SYS_POWER_H

#include "syscall/syscall_table.h"

DECLARE_SYSCALL(reboot);

#endif // STELLUX_SYSCALL_HANDLERS_SYS_POWER_H
2 changes: 2 additions & 0 deletions kernel/syscall/syscall_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "syscall/handlers/sys_pipe.h"
#include "syscall/handlers/sys_uname.h"
#include "syscall/handlers/sys_futex.h"
#include "syscall/handlers/sys_power.h"

namespace syscall {

Expand Down Expand Up @@ -85,6 +86,7 @@ __PRIVILEGED_CODE void init_syscall_table() {
REGISTER_SYSCALL(linux_nr::CLOCK_GETRES, clock_getres);
REGISTER_SYSCALL(linux_nr::GETTIMEOFDAY, gettimeofday);
REGISTER_SYSCALL(linux_nr::UNAME, uname);
REGISTER_SYSCALL(linux_nr::REBOOT, reboot);

REGISTER_SYSCALL(linux_nr::SOCKET, socket);
REGISTER_SYSCALL(linux_nr::SOCKETPAIR, socketpair);
Expand Down
3 changes: 2 additions & 1 deletion userland/apps/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
APP_DIRS := init hello shell ls cat rm stat touch sleep true false clear ptytest date \
clockbench stlxdm stlxterm doom ping ifconfig nslookup arp udpecho tcpecho \
fetch polltest sigtest dropbear blackjack wordle hangman snake tetris \
grep wc head threadtest pthreadtest uname kill cxxtest synctest python vim stlxtop
grep wc head threadtest pthreadtest uname kill cxxtest synctest python vim stlxtop \
reboot shutdown
APP_COUNT := $(words $(APP_DIRS))

all:
Expand Down
2 changes: 2 additions & 0 deletions userland/apps/reboot/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
APP_NAME := reboot
include ../../mk/app.mk
13 changes: 13 additions & 0 deletions userland/apps/reboot/src/reboot.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <stdio.h>
#include <sys/reboot.h>

int main(void) {
printf("Restarting system...\n");
fflush(stdout);

reboot(RB_AUTOBOOT);

// Only reachable when the kernel could not restart the machine
perror("reboot");
return 1;
}
2 changes: 2 additions & 0 deletions userland/apps/shutdown/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
APP_NAME := shutdown
include ../../mk/app.mk
18 changes: 18 additions & 0 deletions userland/apps/shutdown/src/shutdown.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <stdio.h>
#include <sys/reboot.h>

int main(void) {
printf("Powering off...\n");
fflush(stdout);

reboot(RB_POWER_OFF);

// Only reachable when the platform could not power off, so stop
// the machine in a state that is safe to switch off by hand.
printf("Power off unsupported, halting instead.\n");
fflush(stdout);
reboot(RB_HALT_SYSTEM);

perror("shutdown");
return 1;
}
Loading