Skip to content

Instantly share code, notes, and snippets.

@heiher
Last active March 6, 2020 04:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save heiher/4c8c717e5f9fd1fc1f2dcbcf03b0468b to your computer and use it in GitHub Desktop.
Save heiher/4c8c717e5f9fd1fc1f2dcbcf03b0468b to your computer and use it in GitHub Desktop.
Loongson 7A Watchdog Timer Userspace Daemon
#define _GNU_SOURCE
#include <fcntl.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/sysinfo.h>
static volatile unsigned int *wdtr;
static void
signal_handler (int signum)
{
wdtr[12] = 0;
exit (0);
}
int
main (int argc, char *argv[])
{
int fd, max_cpu;
void *ptr;
fd = open ("/dev/mem", O_RDWR | O_DSYNC);
if (fd < 0) {
fprintf (stderr, "Open /dev/mem failed!\n");
goto exit;
}
ptr = mmap (NULL, 16384, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
0x100d0000UL);
if (ptr == MAP_FAILED) {
fprintf (stderr, "Map /dev/mem failed!\n");
goto exit_close;
}
wdtr = ptr;
max_cpu = get_nprocs_conf ();
signal (SIGINT, signal_handler);
signal (SIGQUIT, signal_handler);
signal (SIGTERM, signal_handler);
wdtr[12] = 2;
for (;;) {
int i;
cpu_set_t set;
for (i = 0; i < max_cpu; i++) {
CPU_ZERO (&set);
CPU_SET (i, &set);
for (;;) {
sched_setaffinity (0, sizeof (set), &set);
if (sched_getcpu () == i) {
break;
}
sleep (1);
}
}
wdtr[13] = 1;
sleep (30);
}
munmap (ptr, 16384);
exit_close:
close (fd);
exit:
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment