summaryrefslogtreecommitdiff
path: root/src/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/sys/arch')
-rw-r--r--src/sys/arch/amd64/conf/GENERIC4
-rw-r--r--src/sys/arch/amd64/cpu/cpu_mp.c14
-rw-r--r--src/sys/arch/amd64/cpu/trap.c5
-rw-r--r--src/sys/arch/amd64/isa/i8042.c35
-rw-r--r--src/sys/arch/amd64/os/os_proc.c19
5 files changed, 65 insertions, 12 deletions
diff --git a/src/sys/arch/amd64/conf/GENERIC b/src/sys/arch/amd64/conf/GENERIC
index 93919d8..f402941 100644
--- a/src/sys/arch/amd64/conf/GENERIC
+++ b/src/sys/arch/amd64/conf/GENERIC
@@ -2,3 +2,7 @@
// as a method. Some firmware (e.g., on some laptops)
// may not handle these well and hang.
option I8042_REBOOT yes
+
+// Controls if the i8042 should be polled
+// rather than dependent on interrupts
+option I8042_POLL no
diff --git a/src/sys/arch/amd64/cpu/cpu_mp.c b/src/sys/arch/amd64/cpu/cpu_mp.c
index ae7b367..7b691e3 100644
--- a/src/sys/arch/amd64/cpu/cpu_mp.c
+++ b/src/sys/arch/amd64/cpu/cpu_mp.c
@@ -56,10 +56,19 @@ static volatile struct limine_smp_request g_smp_req = {
.revision = 0
};
+static void
+cpu_idle(void *)
+{
+ for (;;) {
+ __ASMV("pause");
+ }
+}
+
__dead static void
ap_entry(struct limine_smp_info *)
{
struct pcore *pcore;
+ struct proc *curidle;
spinlock_acquire(&lock);
pcore = kalloc(sizeof(*pcore));
@@ -76,9 +85,10 @@ ap_entry(struct limine_smp_info *)
corelist[ncores_up - 1] = pcore;
atomic_inc_64(&ncores_up);
+ proc_ktd(&curidle, cpu_idle);
spinlock_release(&lock);
- md_proc_yield();
+ md_proc_idle();
__builtin_unreachable();
for (;;);
}
@@ -106,6 +116,7 @@ bsp_ap_startup(void)
struct limine_smp_response *resp = g_smp_req.response;
struct limine_smp_info **cpus;
struct mdcore *mdcore;
+ struct proc *curidle;
uint32_t ncores, tmp;
/* Sanity check */
@@ -139,6 +150,7 @@ bsp_ap_startup(void)
printf("mp: bringing APs online...\n");
mdcore = &g_bsp.md;
+ proc_ktd(&curidle, cpu_idle);
for (int i = 0; i < ncores; ++i) {
if (mdcore->apic_id == cpus[i]->lapic_id) {
continue;
diff --git a/src/sys/arch/amd64/cpu/trap.c b/src/sys/arch/amd64/cpu/trap.c
index 921a036..ae3a0cc 100644
--- a/src/sys/arch/amd64/cpu/trap.c
+++ b/src/sys/arch/amd64/cpu/trap.c
@@ -39,6 +39,7 @@
#include <sys/syslog.h>
#include <sys/syscall.h>
#include <machine/trap.h>
+#include <string.h>
/*
* Trap type to type string conversion table
@@ -154,6 +155,7 @@ trap_syscall(struct trapframe *tf)
struct syscall_domain *scdp;
struct syscall_win *scwp;
struct proc *self;
+ struct md_pcb *pcbp;
struct syscall_args scargs = {
.arg[0] = tf->rdi,
.arg[1] = tf->rsi,
@@ -179,6 +181,9 @@ trap_syscall(struct trapframe *tf)
return;
}
+ pcbp = &self->pcb;
+ memcpy(&pcbp->tf, tf, sizeof(pcbp->tf));
+
if (tf->rax < scwp->nimpl && tf->rax > 0) {
tf->rax = scwp->sctab[tf->rax](&scargs);
}
diff --git a/src/sys/arch/amd64/isa/i8042.c b/src/sys/arch/amd64/isa/i8042.c
index 9417206..6ffea73 100644
--- a/src/sys/arch/amd64/isa/i8042.c
+++ b/src/sys/arch/amd64/isa/i8042.c
@@ -40,6 +40,12 @@
#include <machine/pio.h>
#include <stdbool.h>
+#if defined(__I8042_POLL)
+#define I8042_POLL __I8042_POLL
+#else
+#define I8042_POLL 0
+#endif /* !I8042_POLL */
+
#define RING_NENT 16
/*
@@ -58,6 +64,7 @@ struct keybuf {
/* I/O tap forward declarations */
static struct iotap_ops tap_port0_ops;
static struct iotap_desc tap_port0;
+static struct proc *kbd_poll_td;
/* Key states */
static bool shift_key = false;
@@ -350,6 +357,20 @@ i8042_irq(struct intr_hand *hp)
return 1;
}
+static void
+i8042_poll(void *p)
+{
+ char c;
+ uint8_t scancode;
+
+ for (;;) {
+ scancode = i8042_read();
+ if (i8042_getc(scancode, &c) == 0) {
+ keybuf_enter(&buf, c);
+ }
+ }
+}
+
/*
* Initialize i8042 interrupts (IRQ 1)
*/
@@ -399,8 +420,18 @@ i8042_init(struct module *modp)
i8042_write(true, I8042_DISABLE_PORT1);
i8042_read();
- /* Initialize interrupts and taps */
- i8042_init_intr();
+ /*
+ * If we are configured to do interrupts, enable
+ * them. Otherwise, start a kernel thread and
+ * poll.
+ */
+ if (!I8042_POLL) {
+ i8042_init_intr();
+ } else {
+ proc_ktd(&kbd_poll_td, i8042_poll);
+ }
+
+ /* Enable I/O taps */
i8042_init_tap();
/* Enable the keyboard */
diff --git a/src/sys/arch/amd64/os/os_proc.c b/src/sys/arch/amd64/os/os_proc.c
index 93e5d73..23948ab 100644
--- a/src/sys/arch/amd64/os/os_proc.c
+++ b/src/sys/arch/amd64/os/os_proc.c
@@ -112,8 +112,14 @@ md_proc_init(struct proc *procp, int flags)
return error;
}
- ds = USER_DS | 3;
- cs = USER_CS | 3;
+ if (ISSET(flags, SPAWN_KTD)) {
+ ds = KERNEL_DS;
+ cs = KERNEL_CS;
+ procp->flags |= PROC_KTD;
+ } else {
+ ds = USER_DS | 3;
+ cs = USER_CS | 3;
+ }
/*
* Set up the mapping specifier, we'll use zero
@@ -146,7 +152,7 @@ md_proc_init(struct proc *procp, int flags)
* Process idle loop
*/
__dead void
-md_proc_yield(void)
+md_proc_idle(void)
{
struct proc *proc;
struct pcore *core = this_core();
@@ -161,11 +167,6 @@ md_proc_yield(void)
*/
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");
}
}
@@ -288,7 +289,7 @@ md_proc_kill(struct proc *procp, int flags)
/* If this is us, spin time */
if (self->pid == procp->pid) {
core->curproc = NULL;
- md_proc_yield();
+ md_proc_idle();
}
return 0;