summaryrefslogtreecommitdiff
path: root/410guests/station/kern/station.c
blob: b11bb0fd61416c00a596a5347769b65e2e8ce56b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/** @file station.c
 *
 *  @brief Exercises clock interrupts in a charming fashion.
 *
 *  @author de0u
 *
 *  PebPeb-only executable -- it doesn't work on hardware.
 *
 */

#include <common_kern.h>

/* libc includes. */
#include <malloc.h>
#include <simics.h> /* lprintf() */
#include <stdio.h>

/* multiboot header file */
#include <multiboot.h> /* boot_info */

/* memory includes. */
#include <lmm.h> /* lmm_remove_free() */

/* x86 specific includes */
#include <x86/asm.h> /* enable_interrupts() */
#include <x86/cr.h>
#include <x86/interrupt_defines.h> /* interrupt_setup() */
#include <x86/page.h>
#include <x86/seg.h> /* install_user_segs() */

#include <hvcall.h>
#include <malloc_internal.h>
#include <video_defines.h>

#define DEBUG
#include <contracts.h>

#include <assert.h>
#include <string.h>

/* https://classictrainsongs.com/down_by_station/down_by_the_station.htm */
char *lyrics[] = {
    "Down by the station early in the morning,\n",
    "See the little puffer bellies all in a row.\n",
    "See the station master turn the little handle,\n", 
    "Chug, chug, toot, toot, off we go.\n",
    NULL
};

void
twiddle(void)
{
    volatile int accumulator = 0;
    while (accumulator != -1)
        ++accumulator;
    panic("Uh oh, overflow, population, common group");
}

#define DELAY_TICKS 10 // If you make this much larger, what happens next will shock you!

volatile int tick = 0;
volatile int line = 0;

void
tickback(void)
{
    if (++tick == DELAY_TICKS) {
        tick = 0;
        hv_print(strlen(lyrics[line]), (unsigned char *)lyrics[line]);
        ++line;
        if (lyrics[line] == NULL)
            hv_exit(0);
    }
    hv_enable_interrupts();
    twiddle();
}

/** @brief Kernel entrypoint.
 *
 *  This is the entrypoint for the kernel.
 *
 * @return Does not return
 */
int
kernel_main(mbinfo_t *mbinfo, int argc, char **argv, char **envp)
{
    if (!hv_isguest()) {
        lprintf("I am NOT supposed to be here!!!");
        panic("This payload is guest-only");
        return (-1);
    }
    hv_setidt(HV_TICKBACK, tickback, HV_SETIDT_PRIVILEGED);
    hv_setidt(HV_KEYBOARD, tickback, HV_SETIDT_PRIVILEGED);
    hv_enable_interrupts();
    twiddle();
    return (-99);
}