Skip to content
This repository has been archived by the owner on May 31, 2021. It is now read-only.

Commit

Permalink
Try to make debugging less of a headache
Browse files Browse the repository at this point in the history
  • Loading branch information
klange committed May 27, 2021
1 parent 009a8d5 commit d52bc94
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 80 deletions.
4 changes: 3 additions & 1 deletion base/usr/include/kernel/arch/x86_64/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ extern struct regs * _irq12(struct regs*);
extern struct regs * _irq13(struct regs*);
extern struct regs * _irq14(struct regs*);
extern struct regs * _irq15(struct regs*);
extern struct regs * _isr127(struct regs*);
extern struct regs * _isr125(struct regs*); /* Does not actually take regs */
extern struct regs * _isr126(struct regs*); /* Does not actually take regs */
extern struct regs * _isr127(struct regs*); /* Syscall entry point */

typedef struct regs * (*interrupt_handler_t)(struct regs *);

Expand Down
1 change: 0 additions & 1 deletion base/usr/include/kernel/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const char * arch_get_loader(void);

void arch_pause(void);

__attribute__((noreturn))
void arch_fatal(void);

void arch_set_tls_base(uintptr_t tlsbase);
Expand Down
27 changes: 18 additions & 9 deletions kernel/arch/x86_64/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ static void short_delay(unsigned long amount) {
}

static volatile int _ap_current = 0;
uintptr_t lapic_final = 0;

#define cpuid(in,a,b,c,d) do { asm volatile ("cpuid" : "=a"(a),"=b"(b),"=c"(c),"=d"(d) : "a"(in)); } while(0)

Expand All @@ -113,6 +114,8 @@ void ap_main(void) {
fpu_initialize();
pat_initialize();

/* Enable our spurious vector register */
*((volatile uint32_t*)(lapic_final + 0x0F0)) = 0x127;

/* Set our pml pointers */
this_core->current_pml = &init_page_region[0];
Expand Down Expand Up @@ -160,13 +163,19 @@ void load_processor_info(void) {
}
}

void lapic_write(size_t addr, uint32_t value) {
*((volatile uint32_t*)(lapic_final + addr)) = value;
asm volatile ("":::"memory");
}

uint32_t lapic_read(size_t addr) {
return *((volatile uint32_t*)(lapic_final + addr));
}

uintptr_t lapic_final = 0;
void lapic_send_ipi(int i, uint32_t val) {
*((volatile uint32_t*)(lapic_final + 0x310)) = (i << 24);
asm volatile ("":::"memory");
*((volatile uint32_t*)(lapic_final + 0x300)) = val;
do { asm volatile ("pause" : : : "memory"); } while (*((volatile uint32_t*)(lapic_final + 0x300)) & (1 << 12));
lapic_write(0x310, i << 24);
lapic_write(0x300, val);
do { asm volatile ("pause" : : : "memory"); } while (lapic_read(0x300) & (1 << 12));
}

void acpi_initialize(void) {
Expand Down Expand Up @@ -238,15 +247,15 @@ void acpi_initialize(void) {
}
}

if (!lapic_base || cores <= 1) {
return;
}

processor_count = cores;

if (!lapic_base) return;

/* Allocate a virtual address with which we can poke the lapic */
lapic_final = (uintptr_t)mmu_map_mmio_region(lapic_base, 0x1000);

if (cores <= 1) return;

/* Map the bootstrap code */
memcpy(mmu_map_from_physical(0x1000), &_ap_bootstrap_start, (uintptr_t)&_ap_bootstrap_end - (uintptr_t)&_ap_bootstrap_start);

Expand Down
77 changes: 9 additions & 68 deletions kernel/arch/x86_64/idt.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ void idt_install(void) {
idt_set_gate(46, _irq14, 0x08, 0x8E, 0);
idt_set_gate(47, _irq15, 0x08, 0x8E, 0);

idt_set_gate(125, _isr125, 0x08, 0x8E, 0); /* Halts everyone. */
idt_set_gate(126, _isr126, 0x08, 0x8E, 0); /* Intentionally does nothing. */
idt_set_gate(127, _isr127, 0x08, 0x8E, 1);

asm volatile (
Expand All @@ -103,7 +105,6 @@ void idt_ap_install(void) {
);
}

static spin_lock_t fault_lock = {0};
static spin_lock_t dump_lock = {0};
static void dump_regs(struct regs * r) {
spin_lock(dump_lock);
Expand All @@ -127,41 +128,6 @@ static void dump_regs(struct regs * r) {

extern void syscall_handler(struct regs *);

static const char *exception_messages[32] = {
"Division by zero",
"Debug",
"Non-maskable interrupt",
"Breakpoint",
"Detected overflow",
"Out-of-bounds",
"Invalid opcode",
"No coprocessor",
"Double fault",
"Coprocessor segment overrun",
"Bad TSS",
"Segment not present",
"Stack fault",
"General protection fault",
"Page fault",
"Unknown interrupt",
"Coprocessor fault",
"Alignment check",
"Machine check",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved"
};

#define IRQ_CHAIN_SIZE 16
#define IRQ_CHAIN_DEPTH 4
static irq_handler_chain_t irq_routines[IRQ_CHAIN_SIZE * IRQ_CHAIN_DEPTH] = { NULL };
Expand Down Expand Up @@ -189,15 +155,11 @@ void irq_uninstall_handler(size_t irq) {
}

struct regs * isr_handler(struct regs * r) {
this_core->current_process->interrupt_registers = r;

switch (r->int_no) {
case 14: /* Page fault */ {
uintptr_t faulting_address;
asm volatile("mov %%cr2, %0" : "=r"(faulting_address));
if (!this_core->current_process || r->cs == 0x08) {
printf("Page fault in kernel (cpu=%d) at %#zx\n", this_core->cpu_id, faulting_address);
dump_regs(r);
arch_fatal();
}
if (faulting_address == 0xFFFFB00F) {
Expand All @@ -210,10 +172,6 @@ struct regs * isr_handler(struct regs * r) {
break;
}
#ifdef DEBUG_FAULTS
spin_lock(fault_lock);
printf("Page fault in pid=%d (%s; cpu=%d) at %#zx\n", (int)this_core->current_process->id, this_core->current_process->name, this_core->cpu_id, faulting_address);
dump_regs(r);
spin_unlock(fault_lock);
arch_fatal();
#else
# ifdef LOUD_SEGFAULTS
Expand All @@ -225,18 +183,12 @@ struct regs * isr_handler(struct regs * r) {
break;
}
case 13: /* GPF */ {
if (!this_core->current_process || r->cs == 0x08) {
printf("GPF in kernel (cpu=%d)\n", this_core->cpu_id);
dump_regs(r);
arch_fatal();
}
#ifdef DEBUG_FAULTS
spin_lock(fault_lock);
printf("GPF in userspace on CPU %d\n", this_core->cpu_id);
dump_regs(r);
spin_unlock(fault_lock);
arch_fatal();
#else
if (!this_core->current_process || r->cs == 0x08) {
arch_fatal();
}
# ifdef LOUD_SEGFAULTS
printf("GPF in userspace on CPU %d\n", this_core->cpu_id);
dump_regs(r);
Expand All @@ -246,11 +198,6 @@ struct regs * isr_handler(struct regs * r) {
break;
}
case 8: /* Double fault */ {
printf("Double fault?\n");
uintptr_t faulting_address;
asm volatile("mov %%cr2, %0" : "=r"(faulting_address));
printf("cr2: 0x%016lx\n", faulting_address);
dump_regs(r);
arch_fatal();
break;
}
Expand All @@ -265,18 +212,12 @@ struct regs * isr_handler(struct regs * r) {
}
default: {
if (r->int_no < 32) {
if (!this_core->current_process || r->cs == 0x08) {
printf("Unhandled %s in kernel (cpu=%d)\n", exception_messages[r->int_no], this_core->cpu_id);
dump_regs(r);
arch_fatal();
}
#ifdef DEBUG_FAULTS
spin_lock(fault_lock);
printf("Unhandled %s in userspace (cpu=%d)\n", exception_messages[r->int_no], this_core->cpu_id);
dump_regs(r);
spin_unlock(fault_lock);
arch_fatal();
#else
if (!this_core->current_process || r->cs == 0x08) {
arch_fatal();
}
send_signal(this_core->current_process->id, SIGILL, 1);
#endif
} else {
Expand All @@ -295,7 +236,7 @@ struct regs * isr_handler(struct regs * r) {

done:

if (this_core->current_process == this_core->kernel_idle_task && process_queue->head) {
if (this_core->current_process == this_core->kernel_idle_task && process_queue && process_queue->head) {
/* If this is kidle and we got here, instead of finishing the interrupt
* we can just switch task and there will probably be something else
* to run that was awoken by the interrupt. */
Expand Down
33 changes: 32 additions & 1 deletion kernel/arch/x86_64/irq.S
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
/* Interrupt Requests */
ISR_NOERR 0
ISR_NOERR 1
ISR_NOERR 2
//ISR_NOERR 2
ISR_NOERR 3
ISR_NOERR 4
ISR_NOERR 5
Expand Down Expand Up @@ -76,8 +76,39 @@ IRQ 12, 44
IRQ 13, 45
IRQ 14, 46
IRQ 15, 47

/* syscall entry point */
ISR_NOERR 127

/* No op, used to signal sleeping processor to wake and check the queue. */
.extern lapic_final
.global _isr126
.type _isr126, @function
_isr126:
pushq %r12
mov (lapic_final), %r12
movq $0, 0xb0(%r12)
popq %r12
iretq

/* Fatal signal, stop everything. */
.global _isr125
.type _isr125, @function
_isr125:
cli
1:
hlt
jmp 1b

/* Fatal signal, stop everything. */
.global _isr2
.type _isr2, @function
_isr2:
cli
1:
hlt
jmp 1b

.macro _swapgs
cmpq $8, 24(%rsp)
je 1f
Expand Down
6 changes: 6 additions & 0 deletions kernel/arch/x86_64/user.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,16 @@ void arch_pause(void) {
asm volatile (
"sti\n"
"hlt\n"
"cli\n"
);
}

extern void lapic_send_ipi(int i, uint32_t val);
void arch_fatal(void) {
for (int i = 0; i < processor_count; ++i) {
if (i == this_core->cpu_id) continue;
lapic_send_ipi(processor_local_data[i].lapic_id, 0x447D);
}
while (1) {
asm volatile (
"cli\n"
Expand Down

0 comments on commit d52bc94

Please sign in to comment.