summaryrefslogtreecommitdiff
path: root/src/sys
diff options
context:
space:
mode:
Diffstat (limited to 'src/sys')
-rw-r--r--src/sys/arch/amd64/cpu/cpu_mp.c3
-rw-r--r--src/sys/arch/amd64/isa/i8042.c127
-rw-r--r--src/sys/arch/amd64/os/os_proc.c17
-rw-r--r--src/sys/conf/GENERIC4
-rw-r--r--src/sys/include/arch/amd64/i8042var.h11
-rw-r--r--src/sys/include/io/cons/cons.h2
-rw-r--r--src/sys/include/sys/fbdev.h2
-rw-r--r--src/sys/include/sys/spawn.h46
-rw-r--r--src/sys/io/cons/cons.c78
9 files changed, 281 insertions, 9 deletions
diff --git a/src/sys/arch/amd64/cpu/cpu_mp.c b/src/sys/arch/amd64/cpu/cpu_mp.c
index d95ba70..ae7b367 100644
--- a/src/sys/arch/amd64/cpu/cpu_mp.c
+++ b/src/sys/arch/amd64/cpu/cpu_mp.c
@@ -77,6 +77,9 @@ ap_entry(struct limine_smp_info *)
corelist[ncores_up - 1] = pcore;
atomic_inc_64(&ncores_up);
spinlock_release(&lock);
+
+ md_proc_yield();
+ __builtin_unreachable();
for (;;);
}
diff --git a/src/sys/arch/amd64/isa/i8042.c b/src/sys/arch/amd64/isa/i8042.c
index 9bbd85d..9417206 100644
--- a/src/sys/arch/amd64/isa/i8042.c
+++ b/src/sys/arch/amd64/isa/i8042.c
@@ -30,6 +30,7 @@
#include <sys/syslog.h>
#include <sys/proc.h>
#include <sys/errno.h>
+#include <sys/ascii.h>
#include <os/module.h>
#include <os/clkdev.h>
#include <os/iotap.h>
@@ -58,6 +59,11 @@ struct keybuf {
static struct iotap_ops tap_port0_ops;
static struct iotap_desc tap_port0;
+/* Key states */
+static bool shift_key = false;
+static bool capslock = false;
+static bool capslock_released = true;
+
static struct clkdev *clk;
static struct spinlock lock;
static struct keybuf buf = {0};
@@ -73,6 +79,26 @@ static char keytab[] = {
'b', 'n', 'm', ',', '.', '/', '\0', '\0', '\0', ' '
};
+static char keytab_shift[] = {
+ '\0', '\0', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
+ '_', '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
+ 'O', 'P', '{', '}', '\n', '\0', 'A', 'S', 'D', 'F', 'G', 'H',
+ 'J', 'K', 'L', ':', '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V',
+ 'B', 'N', 'M', '<', '>', '?', '\0', '\0', '\0', ' '
+};
+
+static char keytab_caps[] = {
+ '\0', '\0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
+ '-','=', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
+ 'O', 'P', '[', ']', '\n', '\0', 'A', 'S', 'D', 'F', 'G', 'H',
+ 'J', 'K', 'L', ';', '\'', '`', '\0', '\\', 'Z', 'X', 'C', 'V',
+ 'B', 'N', 'M', ',', '.', '/', '\0', '\0', '\0', ' '
+};
+
+static uint8_t i8042_read(void);
+static void i8042_write(bool is_cmd, uint8_t v);
+static int i8042_devsend(bool aux, uint8_t data);
+
/*
* Compute the length of a kbp ring
*/
@@ -215,16 +241,111 @@ i8042_read(void)
}
/*
+ * Send data to an i8042 device
+ *
+ * @aux: If true, send data to the mouse
+ * @data: Byte to send to the bus
+ *
+ * Returns zero on success
+ */
+static int
+i8042_devsend(bool aux, uint8_t data)
+{
+ if (aux) {
+ i8042_write(true, I8042_PORT1_SEND);
+ }
+
+ i8042_write(false, data);
+ return i8042_read();
+}
+
+/*
+ * Send a keyboard LED mask to the controller
+ *
+ * @mask: Keyboard LED mask (I8042_LED_*)
+ */
+static void
+i8042_kbdled(uint8_t mask)
+{
+ i8042_devsend(false, 0xED);
+ i8042_devsend(false, mask);
+}
+
+/*
+ * Convert scancode to character
+ *
+ * @sc: Scancode
+ * @chr: Character output
+ *
+ * Returns 0 when a char is given back.
+ */
+static int
+i8042_getc(uint8_t sc, char *chr)
+{
+ bool release = ISSET(sc, BIT(7));
+ uint8_t led_mask;
+
+ switch (sc) {
+ case 0x76:
+ *chr = ASCII_ESC;
+ return 0;
+ /* Caps lock [press] */
+ case 0x3A:
+ if (!capslock_released) {
+ return -EAGAIN;
+ }
+ capslock_released = false;
+ capslock = !capslock;
+ i8042_kbdled(capslock << CAPS_LED_SHIFT);
+ return -EAGAIN;
+ /* Caps lock [release] */
+ case 0xBA:
+ capslock_released = true;
+ return -EAGAIN;
+ /* Shift */
+ case 0x36:
+ case 0xAA:
+ case 0x2A:
+ case 0xB6:
+ if (!release) {
+ shift_key = true;
+ } else {
+ shift_key = false;
+ }
+ return -EAGAIN;
+ }
+
+ if (release) {
+ return -EAGAIN;
+ }
+
+ if (capslock) {
+ *chr = keytab_caps[sc];
+ return 0;
+ }
+
+ if (shift_key) {
+ *chr = keytab_shift[sc];
+ return 0;
+ }
+
+ *chr = keytab[sc];
+ return 0;
+}
+
+/*
* IRQ 1 handler
*/
static int
i8042_irq(struct intr_hand *hp)
{
+ char c;
uint8_t scancode;
+ int error;
scancode = i8042_read();
- if (!ISSET(scancode, 0x80)) {
- keybuf_enter(&buf, scancode);
+ if (i8042_getc(scancode, &c) == 0) {
+ keybuf_enter(&buf, c);
}
return 1;
}
@@ -292,7 +413,7 @@ static struct iotap_ops tap_port0_ops = {
};
static struct iotap_desc tap_port0 = {
- .name = "i8042.port.0",
+ .name = "input.igkbd",
.ops = &tap_port0_ops
};
diff --git a/src/sys/arch/amd64/os/os_proc.c b/src/sys/arch/amd64/os/os_proc.c
index d944f41..b8e7c99 100644
--- a/src/sys/arch/amd64/os/os_proc.c
+++ b/src/sys/arch/amd64/os/os_proc.c
@@ -137,11 +137,24 @@ md_proc_init(struct proc *procp, int flags)
__dead void
md_proc_yield(void)
{
- /* Clear pending interrupts and oneshot */
+ struct proc *proc;
+ struct pcore *core = this_core();
+ int error;
+
lapic_eoi();
- lapic_timer_oneshot_us(9000);
+ /*
+ * Set the oneshot timer and check if there is
+ * any procs in our runqueues. If not, wait for
+ * it to fire again.
+ */
for (;;) {
+ lapic_timer_oneshot_us(9000);
+ error = sched_deq(&core->scq, &proc);
+ if (error == 0) {
+ core->curproc = proc;
+ md_proc_kick(proc);
+ }
__ASMV("sti; hlt");
}
}
diff --git a/src/sys/conf/GENERIC b/src/sys/conf/GENERIC
index a667a78..a7321d8 100644
--- a/src/sys/conf/GENERIC
+++ b/src/sys/conf/GENERIC
@@ -2,3 +2,7 @@ option DUMP_MEMMAP yes // Dump memory map on boot
// PCI switches and knobs
setval PCI_MAX_BUS 8 // Max buses to scan on boot
+
+// Default console attributes
+setval CONS_BG 0x000000 // Background color
+setval CONS_FG 0xB57614 // Foreground color
diff --git a/src/sys/include/arch/amd64/i8042var.h b/src/sys/include/arch/amd64/i8042var.h
index ec2c36e..53f5029 100644
--- a/src/sys/include/arch/amd64/i8042var.h
+++ b/src/sys/include/arch/amd64/i8042var.h
@@ -67,10 +67,15 @@
#define I8042_AUX_DISABLE 0xF5
#define I8042_AUX_RESET 0xFF
+/* LED shifts */
+#define SCROLL_LED_SHIFT 0
+#define NUM_LED_SHIFT 1
+#define CAPS_LED_SHIFT 2
+
/* LED bits */
-#define I8042_LED_SCROLL BIT(0)
-#define I8042_LED_NUM BIT(1)
-#define I8042_LED_CAPS BIT(2)
+#define I8042_LED_SCROLL (1 << SCROLL_LED_SHIFT)
+#define I8042_LED_NUM (1 << NUM_LED_SHIFT)
+#define I8042_LED_CAPS (1 << CAPS_LED_SHIFT)
/* Extended scancode types */
#define I8042_XSC_ENDPR 0 /* End pressed */
diff --git a/src/sys/include/io/cons/cons.h b/src/sys/include/io/cons/cons.h
index 4ae99a0..6b5c4f1 100644
--- a/src/sys/include/io/cons/cons.h
+++ b/src/sys/include/io/cons/cons.h
@@ -39,6 +39,8 @@ struct cons_scr {
struct bootvar_fb fbvars;
size_t text_x;
size_t text_y;
+ size_t cursor_x;
+ size_t cursor_y;
size_t max_col;
size_t max_row;
uint32_t scr_bg;
diff --git a/src/sys/include/sys/fbdev.h b/src/sys/include/sys/fbdev.h
index 2acddbf..e6f5d8f 100644
--- a/src/sys/include/sys/fbdev.h
+++ b/src/sys/include/sys/fbdev.h
@@ -35,7 +35,7 @@
#include <stdint.h>
#endif /* !_KERNEL */
-#define FBDEV_NSO "video:attr"
+#define FBDEV_NSO "output.fbdev.attr"
struct fb_info {
uint32_t width;
diff --git a/src/sys/include/sys/spawn.h b/src/sys/include/sys/spawn.h
new file mode 100644
index 0000000..d15439d
--- /dev/null
+++ b/src/sys/include/sys/spawn.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2025 Ian Marco Moffett and L5 engineers
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_SPAWN_H_
+#define _SYS_SPAWN_H_ 1
+
+#include <sys/types.h>
+
+/*
+ * Spawn a process
+ *
+ * @path: Path of program image to spawn
+ * @argv: Argument list
+ *
+ * Returns the PID on success, otherwise a less than
+ * zero value on failure.
+ */
+int spawn(const char *path, char **argv);
+
+#endif /* !_SYS_SPAWN_H_ */
diff --git a/src/sys/io/cons/cons.c b/src/sys/io/cons/cons.c
index d9ebb5c..0543e89 100644
--- a/src/sys/io/cons/cons.c
+++ b/src/sys/io/cons/cons.c
@@ -37,11 +37,26 @@
#include <stdbool.h>
#include <string.h>
+/* kconf background color config */
+#if defined(__CONS_BG)
+#define DEFAULT_BG __CONS_BG
+#else
#define DEFAULT_BG 0x000000
+#endif /* __CONS_BG */
+
+/* kconf foreground color config */
+#if defined(__CONS_FG)
+#define DEFAULT_FG __CONS_FG
+#else
#define DEFAULT_FG 0xB57614
+#endif /* !__CONS_FG */
+
#define FONT_WIDTH 8
#define FONT_HEIGHT 20
+#define CURSOR_WIDTH FONT_WIDTH
+#define CURSOR_HEIGHT 4
+
struct cons_scr g_root_scr;
/* Forward declarations */
@@ -64,6 +79,53 @@ fb_get_index(uint32_t pitch, uint32_t x, uint32_t y)
}
/*
+ * Invert an RGB color
+ *
+ * @rgb: Color to invert
+ *
+ * Returns inverted color code (RGB)
+ */
+__always_inline static inline uint32_t
+rgb_invert(uint32_t rgb)
+{
+ return (0xFFFFFF - rgb);
+}
+
+/*
+ * Draw the text cursor onto the screen
+ *
+ * @scr: Screen to draw onto
+ * @hide: True if it should be hidden
+ */
+static void
+cons_draw_cursor(struct cons_scr *scr, bool hide)
+{
+ struct bootvar_fb *fbvars;
+ uint32_t *fbio, idx;
+ uint32_t color;
+
+ if (scr == NULL) {
+ return;
+ }
+
+ fbvars = &scr->fbvars;
+ fbio = fbvars->io;
+
+ for (uint32_t cy = 0; cy < CURSOR_HEIGHT; ++cy) {
+ for (uint32_t cx = 0; cx < CURSOR_WIDTH; ++cx) {
+ idx = fb_get_index(
+ fbvars->pitch,
+ cx + scr->cursor_x,
+ (cy + scr->cursor_y) + FONT_HEIGHT / 2
+ );
+
+ color = (hide) ? scr->scr_bg : rgb_invert(scr->scr_bg);
+ fbio[idx] = color;
+ }
+ }
+}
+
+/*
* Write a newline onto the console and handle
* Y overflows
*
@@ -75,12 +137,22 @@ cons_newline(struct cons_scr *scr)
scr->text_x = 0;
scr->text_y += FONT_HEIGHT;
+ cons_draw_cursor(scr, true);
+ scr->cursor_y += FONT_HEIGHT;
+ scr->cursor_x = 0;
+
/* Handle console y overflow */
if (scr->text_y >= scr->max_row - FONT_HEIGHT) {
scr->text_x = 0;
scr->text_y = 0;
+
+ scr->cursor_x = 0;
+ scr->cursor_y = 0;
fill_screen(scr, scr->scr_bg);
}
+
+ /* Redraw the cursor */
+ cons_draw_cursor(scr, false);
}
/*
@@ -152,6 +224,10 @@ cons_putch(struct cons_scr *scr, struct cons_ch *ch)
x = ch->x;
y = ch->y;
+ /* Update the cursor */
+ cons_draw_cursor(scr, true);
+ scr->cursor_x += FONT_WIDTH;
+
/* Begin the plotting */
for (int cy = 0; cy < hdr->csize; ++cy) {
for (int cx = 0; cx < 8; ++cx) {
@@ -162,6 +238,8 @@ cons_putch(struct cons_scr *scr, struct cons_ch *ch)
fbio[idx] = color;
}
}
+
+ cons_draw_cursor(scr, false);
}
/*