backup 8.29.21

This commit is contained in:
Brett Weiland 2021-08-29 02:52:48 -05:00
parent dc0e84d577
commit 1f71b9576d
25 changed files with 507 additions and 378 deletions

View File

@ -1,205 +1,3 @@
thread 1
next
thread 1
step
print core_stacks
print core_stacks[0]
print core_stacks[1]
print core_stacks[2]
print core_stacks[3]
quit
c
c
quit
hb debug
c
c
next
info reg rax
thread 1
thread 2
info reg rax
print smp_bootstrap_stackarray
print *smp_bootstrap_stackarray
print/x *smp_bootstrap_stackarray
inf ore g rax
print smp_bootstrap_array
quit
hb debug
c
c
quit
hb debug
c
c
nexti
info reg ebx
info reg ebx
quit
hb debug
c
c
quit
hb debug
c
c
stepi
info reg ebx
stepi
stepi
info reg rsp
stepi
info reg esp
info reg rsp
x rbx
info reg rbx
print smp_bootstrap_stackarray
print/x *smp_bootstrap_stackarray
info reg ebx
quit
quit
stepi
info reg cl
info reg ecx
quit
next
quit
nexti
info reg ecx
stepi
info reg ebx
quit
c
quit
stepi
info reg ebx
stepi
info reg bl
print smp_bootstrap_bsp
info reg bl
stepi
info reg bl
info reg ebx
x 0x80f0
print (uint64_t *)0x80f0
print (uint64_t*)0x80f0
x 0x80f9
stepi
stepi
info reg rsp
print smp_bootstrap_stackarray
print/x *smp_bootstrap_stackarray
quit
info reg rax
info reg rax
x 0xbffde058
print smp_bootstrap_bsp
print &smp_bootstrap_bsp
print smp_bootstrap_bsp
x 0x80f1
print (uint64_t)*0x80f1
x smp_bootstrap_bsp
smp_bootstrap_bsp
print smp_bootstrap_bsp
smp_bootstrap_stackarray
print smp_bootstrap_stackarray
print *smp_bootstrap_stackarray
print smp_bootstrap_stackarray[0]
print/x smp_bootstrap_stackarray[0]
print/x smp_bootstrap_stackarray[1]
print/x smp_bootstrap_stackarray[0]
info reg rax
print smp_bootstrap_stackarray
quit
info reg rax
quit
next
stepi
quit
c
quit
c
stepi
quit
hb smp_trampoline
c
next
hb debug
c
quit
c
quit
c
quit
c
stepi
quit
c
quit
c
next
info reg rsp
thread 2
context
quit
quit
c
info reg cl
info reg ecx
quit
c
next
quit
info reg rax
c
info reg rax
stepi
info rax
inf oreg rax
info reg rax
info reg rbx
x 0xffff8000bffde058
x *0xffff8000bffde058
print *0xffff8000bffde058
print/x *0xffff8000bffde058
print/x (uint64_t)*0xffff8000bffde058
print/x (uint64_t)0xffff8000bffde058
print/x (uint64_t)*0xffff8000bffde058
print/x (uint64_t)0xffff8000bffde058
print/x (uint64_t)0xffff8000bffde058[1]
print ((uint64_t)0xffff8000bffde058)[1]
print ((uint64_t *)0xffff8000bffde058)[1]
print ((uint64_t *)0xffff8000bffde058)[0]
print ((uint64_t *)0xffff8000bffde058)[1]
print/x ((uint64_t *)0xffff8000bffde058)[1]
quit
c
nexti
quit
c
stepi
stepi
info thread 0
thread 1
c
quit
next
print cores_active
print cores.corecount
next
print cores.corecount
print cores_active
next
c
print cores_active
thread 0
print cores_active
thread 1
print cores_active
quit
c
stepi
info reg rax
thread 0
thread 2
print cores_active
@ -254,3 +52,205 @@ c
c
c
quit
quit
print final_gdt_descriptor
print gdt
quit
quit
quit
nexti
thread 1
thread 23
thread 2
print final_gdt_descriptor.offset
qut
quit
context
disassemble
x/i 0x80dd
quit
c
c
c
quit
next
print gdt
print gdtr
next
print gdtr
print/x (void *)&gdtr
print/x *(void *)&gdtr
hexdump &gdtr
print/x gdtr
quit
c
quit
next
stepi
info reg rax
info reg rdx
print final_gdt_descriptor
print &final_gdt_descriptor
quit
quit
c
quit
c
thread 2
next
quit
c
thread
threads
info threads
thread 1
c
c
quit
c
quit
c
quit
hb klog.c
hb klog
hb klog_init
c
quit
hb init_klog
c
print sizeof(serial_ports)
print sizeof(serial_ports) / sizeof(uint16_t)
quit
c
quit
c
quit
c
quit
hb smp_trampoline.asm:163
c
print smp_kinit
x smp_kinit
next
info reg rax
x smp_kinit
nexti
x smp_kinit
info reg rax
quit
c
quit
c
quit
c
quit
c
quit
nexti
stepi
stepi
next
quit
b _putchar
c
stepi
next
c
c
quit
hb _putchar
c
c
next
step
print screen_buffer
x 0xffff8000000b80a0
0xffff800000000000
x 0xffff800000000000
quit
c
quit
b _putchar
c
c
step
print screen_buffer
stepi
c
d
c
quit
next
quit
b init_klog
c
next
print serial_ports[0]
print/x serial_ports[0]
next
quit
quit
c
quit
c
quit
c
quit
c
quit
c
quit
b init_klog
c
print sizeof(serial_ports) / sizeof(uint16_t)
next
print p
next
make
quit
b init_klog
c
next
step
b _putchar
c
step
step
print (char *)((uint64_t)VIDEO_BUFFER + ((on_line * 160) + (on_char * 2)))
print (char *)((uint64_t)0xb8000 + ((on_line * 160) + (on_char * 2)))
quit
c
quit
hb test_shit
c
c
c
c
c
c
c
c
c
c
c
c
quit
c
quit
quit
next
quit
quit
quit
info reg edx
nexti
info reg edx
quit
next
info reg ebx
quit
hb fuckyou
quit
c
info reg ebx
quit

View File

@ -1,7 +1,6 @@
[bits 16]
[extern _kernel_sector_size]
[extern _bootloader_stage1_size]
[extern _kernel_s1_loc]
jmp stage0
times 3-($-$$) db 0x90

View File

@ -1,4 +1,4 @@
[extern main]
[extern kernel_init]
[extern _kernel_stack_loc]
[extern _kernel_page_size]
enter_longmode:
@ -68,13 +68,14 @@ mov cr4, eax
;If it's not and we enable it, it will cause pagefaults on read
mov eax, 0x80000001
cpuid
and edx, 1 << 20
shr edx, 9
mov ebx, edx
and ebx, 1 << 20
shr ebx, 9
mov ecx, 0xc0000080
rdmsr
or eax, 1 << 8 | 1 << 11
or eax, edx
or eax, 1 << 8
or eax, ebx
wrmsr
mov eax, cr0
@ -90,7 +91,7 @@ enter_kernel:
bits 64
mov rbp, 0
mov rsp, _kernel_stack_loc
mov rax, QWORD main
mov rax, QWORD kernel_init
;push QWORD 0
jmp rax
jmp $

View File

@ -1,8 +1,8 @@
target remote localhost:1234
symbol-file debug/debug_syms.o
hb debug
hb smp_boot
hb fuckyou
hb kernel_init
define cs2bs

11
src/include/addr.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef ADDR_INCLUDED
#define ADDR_INCLUDED
#include <stdint.h>
//couldn't get symbols working, fix later
#define PA_OFFSET 0xffff800000000000
#define TXT_OFFSET 0xffffffff80000000
#define PHYS_TO_VIRT(addr) ((void *)((uintptr_t)(addr) | PA_OFFSET))
#endif

View File

@ -7,7 +7,7 @@
void usleep(unsigned int us);
void init_interrupts();
void init_interrupts_bsp();
typedef uint32_t *lapic_t;

View File

@ -2,14 +2,10 @@
#define KERNEL
#define PA_OFFSET 0xffff800000000000
#define TXT_OFFSET 0xffffffff80000000
#define PHYS_TO_VIRT(addr) ((void *)(addr) + PA_OFFSET)
#define DEV_EMAIL "brett_weiland@bpcspace.com"
void multicore_main();
void smp_kinit();
void kernel_init();
void kmain();
#endif

View File

@ -1,26 +1,19 @@
//these com values are just guesses! Figure out how to find em later if you want
#ifndef _SERIAL_H_
#define _SERIAL_H_
#include <stdint.h>
#include <stdbool.h>
#define COM1 0x3f8
#define COM2 0x2f8
#define COM3 0x3e8
#define COM4 0x2e8
bool init_serial(uint16_t port);
void init_klog();
void serial_out(uint16_t port, char *string);
void _putchar_serial(uint16_t port, char character);
void move_cursor(unsigned int x, unsigned int y);
//TODO fix shitty header
void _putchar_screen(char character);
void clear_screen();

View File

@ -52,6 +52,9 @@ void panic(int reason, void *frame_p, struct registers *regs);
#define KERNEL_PANIC_INVALID_RSDT 35
#define KERNEL_PANIC_INVALID_IOAPIC_VEC 36
#define KERNEL_PANIC_HPET_REQUIRED 37
#define KERNEL_PANIC_SMP_FAILED 38
#define DEV_EMAIL "brett_weiland@bpcspace.com"

View File

@ -61,6 +61,7 @@ void _putchar(char character);
int printf_(const char* format, ...);
/**
* Tiny sprintf implementation
* Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD!

17
src/include/smp_sync.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef SMP_SYNC_INCLUDED
#define SMP_SYNC_INCLUDED
static inline void lock(uint8_t *lock) {
asm("mov al, 1\n"
"spinlock:\n"
"lock xchgb [%0], al\n"
"test al, al\n"
"jnz spinlock\n"
::"r"(lock):"al");
}
static inline void unlock(uint8_t *lock) {
asm("lock andb [%0], 0"::"r"(lock));
}
#endif

Binary file not shown.

View File

@ -1,13 +1,13 @@
#include <acpi.h>
#include <stdint.h>
#include <printf.h>
#include <kernel.h>
#include <stdbool.h>
#include <kernel.h>
#include <addr.h>
#include <io.h>
#include <int.h>
#include <libc.h>
#include <panic.h>
#include <addr.h>
//finding rsdp

View File

@ -4,7 +4,7 @@
#include <paging.h>
#include <printf.h>
#include <isv.h>
#include <kernel.h>
#include <addr.h>
#include <libc.h>
#include <madt.h>
#include <timer.h>
@ -44,7 +44,6 @@
.present = 1 \
})
#define GDT_ADDR (uint64_t)PHYS_TO_VIRT(0x7e22)
#define IOAPICR_VER 1
@ -74,18 +73,10 @@ struct idt_reg {
uint64_t offset;
} __attribute__((packed));
struct gdt_reg {
uint16_t size;
uint64_t offset;
} __attribute__((packed));
struct idt_descriptor *idt;
static struct idt_reg idtr;
struct gdt_reg gdtr = {
.size = 0x17,
.offset = GDT_ADDR
};
lapic_t lapic; //would make this static but it's needed by timer.c
@ -211,7 +202,7 @@ void init_exceptions() {
//void new_idt
void init_interrupts() {
void init_interrupts_bsp() {
init_madt();
debug_madt();
lapic = get_lapic();
@ -232,9 +223,7 @@ void init_interrupts() {
bzero(&isr_bitmap, sizeof(isr_bitmap));
isr_bitmap[0] = (((uint64_t)1 << 32) - 1);
//set idt and new gdt
asm("lgdt [%0]\n"
"lidt [%1]\n":: "m"(gdtr), "m"(idtr));
asm("lidt [%0]\n"::"m"(idtr));
//Spurrious Interrupt (permanent, required for APIC)
@ -251,3 +240,6 @@ void init_interrupts() {
init_timer();
asm("sti\n");
}
void smp_init_interrupts() {
}

View File

@ -1,12 +1,12 @@
#include <stdbool.h>
#include <smp.h>
#include <serial.h>
#include <klog.h>
#include <printf.h>
#include <paging.h>
#include <video.h>
#include <acpi.h>
#include <panic.h>
#include <kernel.h>
#include <addr.h>
#include <stdbool.h>
#include <int.h>
#include <io.h>
@ -19,31 +19,36 @@
//testing headers
#include <testmalloc.h>
void multicore_main() {
printf("\nKernal started\n");
asm("cli\nhlt");
void kmain() {
PANIC(KERNEL_PANIC_KERNEL_RETURNED);
}
void main() {
#ifndef SCREEN_OUTPUT
if(init_serial(COM1)) printf("\nKernal started on CPU 1!\n");
#endif
void smp_kinit() {
printf("\nKernal started on core\n"); //TODO get lapic working, then print core number
kmain();
}
//TODO move to global constructors
void kernel_init() {
size_t pmap_size;
get_mem_capabilities();
init_pmap(map_complete_physical());
pmap_size = map_complete_physical();
init_klog();
init_pmap(pmap_size);
printf("\nKernal started on CPU 1!\n");
find_root_sdp();
debug_acpi();
init_interrupts();
init_interrupts_bsp();
randinit();
smp_boot();
fix_stack();
unmap_lowmem();
PANIC(KERNEL_PANIC_KERNEL_RETURNED);
//unmap_lowmem();
kmain();
}

View File

@ -1,57 +1,104 @@
#include <stdint.h>
#include <serial.h>
#include <io.h>
#include <printf.h>
#include <kernel.h>
#include <addr.h>
#include <stdbool.h>
#include <libc.h>
#include <klog.h>
//README
//this file has some temporary workarounds until I get further into development
//this isn't going to be the serial driver I end up keeping
//right now, this program is simply for debuging.
//Later in development, we will hook it up to a TTY, impliment FCS, etc
#define VIDEO_BUFFER PHYS_TO_VIRT(0xb8000)
#define MAX_LOOPBACK_ATTEMPTS 20
//later we'll set it up for interrupting instead of polling
bool init_serial(uint16_t port) {
outb_wait(port + 1, 0x00);
outb_wait(port + 2, 0x00);
outb_wait(port + 3, 0x80);
outb_wait(port + 0, 0x01); //here
outb_wait(port + 1, 0x00);
outb_wait(port + 3, 0x03);
outb_wait(port + 2, 0xc7);
outb_wait(port + 4, 0x0b);
outb_wait(port + 4, 0x1e);
#define KLOG_COM1 0
#define KLOG_COM2 1
#define KLOG_COM3 2
#define KLOG_COM4 3
#define KLOG_SCREEN 4
static int debug_output = KLOG_SCREEN;
#define SERIAL_THR 0 //transmitter holding buffer
#define SERIAL_RBR 1 //receiving holding buffer
#define SERIAL_DLL 0 //divisor latch low byte
#define SERIAL_DLH 1 //divisor latch high byte
#define SERIAL_FCR 2
#define SERIAL_IIR 2
#define SERIAL_LCR 3
#define SERIAL_MCR 4
#define SERIAL_LSR 5
#define SERIAL_MSR 6
#define SERIAL_SR 7
#define COM1 0x3f8
#define COM2 0x2f8
#define COM3 0x3e8
#define COM4 0x2e8
uint16_t serial_ports[4] = {COM1, COM2, COM3, COM4};
/**
enum com_ports {
COM1 = 0x3f8,
COM2 = 0x2f8,
COM3 = 0x3e8,
COM4 = 0x2e8
};
**/
//we shouldn't accept this as a loopback success.
//I'm making an exception because my dell desktop has a faulty serial port
//that requires some extra effort.
static bool detect_serial(uint16_t port) {
outb(port + SERIAL_FCR, 0xe7);
outb(port + SERIAL_SR, 0xba);
if((inb(port + SERIAL_IIR) & (1 << 6)) && (inb(port + SERIAL_SR) == 0xba)) {
outb_wait(port + 1, 0x00);
outb_wait(port + 2, 0x00);
outb_wait(port + 3, 0x80);
outb_wait(port + 0, 0x01);
outb_wait(port + 1, 0x00);
outb_wait(port + 3, 0x03);
outb_wait(port + 2, 0xc7);
outb_wait(port + 4, 0x0b);
outb_wait(port + 4, 0x1e);
uint8_t loopback_byte;
for(int attempts = 0; attempts < MAX_LOOPBACK_ATTEMPTS; attempts++) {
outb_wait(port + 0, 0xae); // test char
loopback_byte = inb(port);
if(loopback_byte == 0xae) break;
}
if(loopback_byte != 0xae) {
//I'm sorry if these next few lines give you a stroke. They gave me one.
uint8_t loopback_byte;
for(int attempts = 0; attempts < MAX_LOOPBACK_ATTEMPTS; attempts++) {
outb_wait(port + 0, 0xae);
loopback_byte = inb(port);
if(loopback_byte == 0xae) break;
}
if(loopback_byte != 0xae) {
//you better delete this once you get tty drivers working...
int a = 0 / 0;
}
//My old Dell test desktop has disfunctional serial hardware that only works after a reboot.
//Seeing we don't have ACPI set up yet, we can't reboot without crashing.
//IM GOING TO REMOVE THIS ONCE I DEVELOP THE "REAL" SERIAL DRIVER!!!!
asm("mov rax, 0\n"
"div rax\n");
return false;
outb_wait(port + 4, 0x0f);
return true;
}
outb_wait(port + 4, 0x0f);
return true;
return false;
}
//this function is going to be teleted after ttys work.
//but, for now, if a serial port is detected, it'll set debug_output to 0-3 (com port #).
//debug_output == 4 is for screen output.
void init_klog() {
for(unsigned int p = 0; p < (sizeof(serial_ports) / sizeof(uint16_t)); p++) {
if(detect_serial(serial_ports[p])) {
debug_output = p;
return;
}
}
debug_output = KLOG_SCREEN;
_putchar('\n');
}
void _putchar_serial(uint16_t port, char msg) {
while(!(inb(port + 5) & 0x20)); //wait for transmit to be done
outb_wait(port, msg);
@ -80,13 +127,10 @@ void next_line() {
}
void move_cursor(unsigned int x, unsigned int y) {
//yeah yeah yeah, it doens't test for overflows... I'm gonna delete this once i get serial working
//on my second desktop
on_char = x;
on_line = y;
}
//until we get serial working on hp
void _putchar_screen(char msg) {
if(on_char >= 80) {
next_line();
@ -94,7 +138,55 @@ void _putchar_screen(char msg) {
next_line();
return;
}
char *screen_buffer = (void *)((uint64_t)VIDEO_BUFFER + ((on_line * 160) + (on_char * 2)));
*screen_buffer = msg;
*(char *)((uint64_t)VIDEO_BUFFER + ((on_line * 160) + (on_char * 2))) = msg;
on_char++;
}
void _putchar(char character) {
if(debug_output < (sizeof(serial_ports) / sizeof(uint16_t))) {
_putchar_serial(serial_ports[debug_output], character);
}
else {
_putchar_screen(character);
}
}
/**
* Set the value "0xE7" to the FCR to test the status of the FIFO flags.
Read the value of the IIR to test for what flags actually got set.
If Bit 6 is set Then
If Bit 7 is set Then
If Bit 5 is set Then
UART is 16750 (64 bit fifo)
Else
UART is 16550A (idk why this matters, 16 bit fifo)
End If
Else
UART is 16550 (16 bit fifo)
End If
Else you know the chip doesn't use FIFO, so we need to check the scratch register
Set some arbitrary value like 0x2A to the Scratch Register.
If the arbitrary value comes back identical
UART is 16450 (idk why this matters, 1 byte at a time)
Else
UART is 8250 (one byte at a time)
End If
End If
#define UART_16750 0
#define UART_16550A 1
#define UART_16550 2
#define UART_16450 3
#define UART_8250 4
#define KLOG_COM1 0
#define KLOG_COM2 1
#define KLOG_COM3 2
#define KLOG_COM4 3
#define KLOG_SCREEN 4 * 5 // 5 leaves enough space for com ports
**/

View File

@ -2,7 +2,7 @@
#include <libc.h>
#include <acpi.h>
#include <int.h>
#include <kernel.h>
#include <addr.h>
#include <stddef.h>
#include <heap.h>
#include <printf.h>

View File

@ -4,7 +4,7 @@
#include <limits.h>
#include <panic.h>
#include <math.h>
#include <kernel.h>
#include <addr.h>
#include <stdbool.h>
#include <cpuid.h>

View File

@ -1,12 +1,15 @@
#include <panic.h>
#include <stdint.h>
#include <printf.h>
#include <kernel.h>
#include <serial.h>
#include <addr.h>
#include <klog.h>
#include <isv.h>
#include <smp_sync.h>
static uint8_t panic_lock = 0;
void panic(int reason, void *eframe_p, struct registers *regs) { // will fill with debugging info latter
lock(&panic_lock);
#ifdef EASTEREGG_BLOATWARE
printf("\nKernel PANIC!!!!!!!\n");
@ -49,6 +52,9 @@ void panic(int reason, void *eframe_p, struct registers *regs) { // will fill wi
break;
case KERNEL_PANIC_HPET_REQUIRED:
printf("\nHPET is required. \nIf you get this error, let know;\nif enough people share this issue, I'll impliment PIT usage.\n");
case KERNEL_PANIC_SMP_FAILED:
printf("\nNot all cores booted successfully (see text before panic).\n");
break;
default:
printf("\nUnknown panic code %i\n.", reason);
break;

View File

@ -33,10 +33,11 @@
#include <stdbool.h>
#include <stdint.h>
#include "printf.h"
//this is my own ugly library
#include <serial.h>
#include <klog.h>
//and my options
/**
@ -161,12 +162,7 @@ static inline void _out_char(char character, void* buffer, size_t idx, size_t ma
{
(void)buffer; (void)idx; (void)maxlen;
if (character) {
#ifdef SCREEN_OUTPUT
_putchar_screen(character);
#else
_putchar_serial(COM1, character); // later we should figure out a way to not specifify exclusively com1
#endif
_putchar(character);
}
}
@ -874,17 +870,24 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
///////////////////////////////////////////////////////////////////////////////
#include <smp_sync.h>
static uint8_t printf_lock = 0;
int printf_(const char* format, ...)
{
//BRETT modification
lock(&printf_lock);
va_list va;
va_start(va, format);
char buffer[1];
const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va);
va_end(va);
unlock(&printf_lock);
return ret;
}
///////////////////////////////////////////////////////////////////////////////
int sprintf_(char* buffer, const char* format, ...)
{

View File

@ -1,4 +1,4 @@
#include <kernel.h>
#include <addr.h>
#include <printf.h>
#include <madt.h>
#include <timer.h>
@ -7,6 +7,7 @@
#include <libc.h>
#include <paging.h>
#include <heap.h>
#include <panic.h>
#define LAPIC_ICR_LOW 192
#define LAPIC_ICR_HIGH 196
@ -16,6 +17,7 @@ extern char __load_start_smp_bootloader, __load_stop_smp_bootloader;
extern uint8_t *smp_bootstrap_corecount;
extern uint8_t smp_bootstrap_bsp;
extern uint64_t *smp_bootstrap_stackarray;
extern char final_gdt_descriptor;
struct icr_reg {
uint8_t vector;
@ -30,22 +32,30 @@ struct icr_reg {
unsigned int reserved_2:12;
}__attribute__((packed));
//1: get bsp number 2
//2: get list of lapics 3
//3: copy code 1
//4:
static inline void write_icr(uint8_t dest, uint32_t message) {
lapic[LAPIC_ICR_HIGH] = (uint32_t)dest << 24;
lapic[LAPIC_ICR_LOW] = message;
}
struct gdt_descriptor {
uint16_t size;
void *offset;
} __attribute__((packed));
static struct gdt_descriptor gdtr;
void smp_boot() {
uint8_t cores_active = 1; //TODO change in asm
uint8_t cores_active = 1;
struct cores_info cores;
struct icr_reg icr;
get_coreinfo(&cores);
if(cores.corecount == 1) {
asm("sgdt [%0]"::"m"(gdtr));
gdtr.offset = PHYS_TO_VIRT(gdtr.offset);
asm("lgdt [%0]"::"m"(gdtr));
return;
}
bzero(&icr, sizeof(icr));
void **core_stacks = malloc(sizeof(void *) * (cores.corecount - 1));
@ -57,9 +67,7 @@ void smp_boot() {
&__load_stop_smp_bootloader - &__load_start_smp_bootloader);
smp_bootstrap_corecount = &cores_active;
smp_bootstrap_bsp = cores.bsp;
smp_bootstrap_stackarray = (uint64_t)core_stacks;
smp_bootstrap_stackarray = (void *)core_stacks;
icr.deliv_mode = 0b101;
icr.dest_shorthand = 0b11;
@ -74,10 +82,9 @@ void smp_boot() {
if(cores_active != cores.corecount) write_icr(0, *(uint32_t *)&icr);
usleep(200);
if(cores_active != cores.corecount) {
printf("NOT ALL CORES ONLINE\n");
asm("cli\nhlt");
}
else {
printf("%i!!!!!!\n", cores_active);
printf("Only %i cores online (expected %i)\n", cores_active, cores.corecount); //maybe add a panic
PANIC(KERNEL_PANIC_SMP_FAILED);
}
printf("%i \n", cores_active);
//asm("lgdt [%0]\n"::"r"(PHYS_TO_VIRT(&final_gdt_descriptor))); TODO NOW
}

View File

@ -1,13 +1,19 @@
global smp_bootstrap_stackarray
global smp_bootstrap_bsp
global smp_bootstrap_corecount
global final_gdt_descriptor
extern multicore_main
extern smp_kinit
extern _pmem_vaddr
[bits 16]
smp_trampoline:
cli
in al, 0x92
or al, 2
out 0x92, al
xor ax, ax
mov ds, ax
lgdt [.gdt_descriptor_p]
@ -15,12 +21,11 @@ mov eax, cr0
or eax, 0x1
mov cr0, eax ; now in long mode
jmp 0x8:.smp_protected
jmp 0x8:smp_protected
;________________________________________________________________________________________
;TODO find how to use old gdt
.gdt_start_p: ; we need to start with a null gdt
dd 0
dd 0
@ -52,9 +57,9 @@ SMP_PROTECTED_DATA_SEGMENT equ .gdt_data_p - .gdt_start_p
;________________________________________________________________________________________
.smp_protected:
smp_protected:
[bits 32]
bits 32
mov ax, SMP_PROTECTED_DATA_SEGMENT
mov ds, ax
mov ss, ax
@ -62,10 +67,8 @@ mov es, ax
mov fs, ax
mov gs, ax
lgdt [.gdt_descriptor_l]
mov eax, 0x10000 ;TODO clarify _why_ this is a thing
mov eax, 0x10000
mov cr3, eax
;setting up misc features
@ -78,13 +81,15 @@ mov cr4, eax
;set NX and LME
mov eax, 0x80000001
cpuid
and edx, 1 << 20
shr edx, 9
mov ebx, edx
and ebx, 1 << 20
shr ebx, 9
mov ecx, 0xc0000080
rdmsr
or eax, 1 << 8 | 1 << 11
or eax, edx
or eax, 1 << 8
fuckyou:
or eax, ebx
wrmsr
@ -94,14 +99,16 @@ or eax, 1 << 31 | 1 << 0;
and ax, ~(1 << 2)
mov cr0, eax
lgdt [final_gdt_descriptor]
jmp SMP_LONG_CODE_SEGMENT:.counter
jmp SMP_LONG_CODE_SEGMENT:smp_longsetup
;________________________________________________________________________________________
[bits 64]
;TODO do we really need all this?
.gdt_start_l:
bits 64
final_gdt:
.start:
;and now we set up a temporary GDT creating a 1:1 mapping
dw 0xffff
dw 0
@ -111,7 +118,7 @@ db 1
db 0
;now for the code GDT:
.gdt_code_l:
.code:
dw 0 ; segment limit 15:00 (I don't think this matters in 64 bit mode!)
dw 0 ; base address 15:00
db 0 ; base address 23:16
@ -119,7 +126,7 @@ db 10011010b
db 00100000b
db 0
.gdt_data_l:
.data:
dw 0
dw 0
db 0
@ -127,17 +134,18 @@ db 10010010b
db 00100000b
db 0
.gdt_end_l: ; later calculates offset in defs below
.end: ; later calculates offset in defs below
.gdt_descriptor_l:
dw .gdt_end_l - .gdt_start_l - 1
dq .gdt_start_l
final_gdt_descriptor:
dw final_gdt.end - final_gdt.start - 1
.offset:
dq final_gdt.start
SMP_LONG_CODE_SEGMENT equ .gdt_code_l - .gdt_start_l
SMP_LONG_DATA_SEGMENT equ .gdt_data_l - .gdt_start_l
SMP_LONG_CODE_SEGMENT equ final_gdt.code - final_gdt.start
SMP_LONG_DATA_SEGMENT equ final_gdt.data - final_gdt.start
.counter:
smp_longsetup:
mov eax, 1
cpuid
shr ebx, 24
@ -146,19 +154,29 @@ jl .apic_below_bsp
sub bl, 1
.apic_below_bsp:
mov rax, QWORD [smp_bootstrap_stackarray]
debug:
mov rsp, QWORD [rax + rbx * 8]
mov rax, [smp_bootstrap_corecount]
inc BYTE [rax]
mov rax, 0xffff800000000000
;or QWORD [final_gdt_descriptor.offset], rax
;lgdt [final_gdt_descriptor]
mov rax, multicore_main
.inc_corecounter:
mov rax, [smp_bootstrap_corecount]
lock inc BYTE [rax]
smp_enter_kernel:
mov rax, smp_kinit
jmp rax
align 8
smp_bootstrap_stackarray: dq 0
smp_lock: dq 0
smp_bootstrap_bsp: db 0
smp_bootstrap_corecount: db 0
times 512 - ($ - $$) db 0

View File

@ -3,7 +3,7 @@
#include <io.h>
#include <printf.h>
#include <libc.h>
#include <kernel.h>
#include <addr.h>
#include <cpuid.h>
#include <panic.h>
#include <int.h>
@ -204,10 +204,8 @@ void init_timer() {
uint32_t unused, cpuid_reg;
__get_cpuid(0x80000007, &unused, &unused, &unused, &cpuid_reg);
//goto debug_tsc;
if((cpuid_reg >> 8) & 1) {
printf("Detected invariant TSC\n");
//.1 second to calibrate, TODO do we need to check if the register is big enough?
uint64_t hpet_ticks = (100000000000000 * (1 / (double)hpet_info.hpet_period)) + 0.5;
printf("Starting TSC calibration...\n");
uint64_t volatile start_tsc, end_tsc;
@ -274,7 +272,7 @@ void init_timer() {
apic_div = (((apic_div & 0b100) << 1) | (apic_div * 0b1011));
}
lapic_timer_lvt.vector = SPURRIOUS_VECTOR; //TODO CHANGE ME
lapic_timer_lvt.vector = SPURRIOUS_VECTOR;
lapic_timer_lvt.timer_mode = LAPIC_TIMER_MODE_PERIODIC;
lapic_timer_lvt.delivery_status = 0;
lapic_timer_lvt.mask = 1;

View File

@ -1,6 +1,7 @@
SEARCH_DIR(objects)
_kernel_s1_loc = 0xffffffff80000000;
_txt_vaddr = 0xffffffff80000000;
_pmem_vaddr = 0xffff800000000000;
_meminfo = 0x7000;
_vbe_infoblock = 0x500;
@ -15,7 +16,7 @@ SECTIONS
{
smp_trampoline.o(.text)
}
kernel _kernel_s1_loc :
kernel _txt_vaddr :
AT (0 + SIZEOF(smp_bootloader) + SIZEOF(bootloader))
{
EXCLUDE_FILE (*bootloader.o *smp_trampoline.o) *(.text .data .bss .rodata .comment .eh_frame)

View File

@ -44,20 +44,6 @@ all: $(ASM_OBJFILES) $(C_OBJFILES) $(MISC_OBJFILES) bootloader.o smp_trampoline.
isv.o: kernel/isv.c
$(CC) $(CFLAGS) $(INC) -mgeneral-regs-only -MMD -MP -c kernel/isv.c -o objects/$@
printf.o: kernel/printf.c
ifdef screen
$(CC) $(CFLAGS) $(INC) -MMD -MP -DSCREEN_OUTPUT -c kernel/printf.c -o objects/$@
else
$(CC) $(CFLAGS) $(INC) -MMD -MP -c kernel/printf.c -o objects/$@
endif
kernel.o: kernel/kernel.c
ifdef screen
$(CC) $(CFLAGS) $(INC) -MMD -MP -DSCREEN_OUTPUT -c kernel/kernel.c -o objects/$@
else
$(CC) $(CFLAGS) $(INC) -MMD -MP -c kernel/kernel.c -o objects/$@
endif
%.o: kernel/%.c makefile
$(CC) $(CFLAGS) $(INC) -MMD -MP -c $< -o objects/$@