Added spinlocks

This commit is contained in:
Xnoe 2022-04-15 21:10:10 +01:00
parent dc2fe698a3
commit 6339b3e4bd
Signed by: xnoe
GPG Key ID: 45AC398F44F0DAFE
8 changed files with 58 additions and 10 deletions

View File

@ -136,9 +136,9 @@ void main() {
// But first, we should load the kernel somewhere
uint8_t* kernel_location = 0x542000; // Just load it at 0x524000 for now
mark_unavailble(kernel_location, 0x10000, bitmap); // Just treat the kernel as not growing beyond 32k for now.
mark_unavailble(kernel_location, 0x20000, bitmap); // Just treat the kernel as not growing beyond 128k for now.
map_many_4k_phys_to_virt(kernel_location, 0xc0000000, kernel_page_directory, kernel_page_tables, 0x10); // Map 16 pages from 0x522000 to 0xc0000000;
map_many_4k_phys_to_virt(kernel_location, 0xc0000000, kernel_page_directory, kernel_page_tables, 0x20); // Map 32 pages from 0x522000 to 0xc0000000;
map_4k_phys_to_virt((uint32_t)kernel_page_directory, 0xc0100000, kernel_page_directory, kernel_page_tables); // Map the page directory to 0xc0100000
map_many_4k_phys_to_virt(0x121000, 0xc0101000, kernel_page_directory, kernel_page_tables, 1024); // Map 1024 pages from 0x121000 to 0xc0101000
map_4k_phys_to_virt(0xb8000, 0xc0501000, kernel_page_directory, kernel_page_tables); // Map 0xb8000 (video) to 0xc0501000
@ -153,7 +153,7 @@ void main() {
memset(vm_bitmap, 0x20000, 0xff);
mark_unavailble(0xc07a0000, 0x20000, vm_bitmap);
mark_unavailble(0xc0000000, 0x10000, vm_bitmap);
mark_unavailble(0xc0000000, 0x20000, vm_bitmap);
mark_unavailble(0xc0100000, 0x1000, vm_bitmap);
mark_unavailble(0xc0101000, 0x400000, vm_bitmap);
mark_unavailble(0xc0501000, 0x1000, vm_bitmap);

View File

@ -74,6 +74,7 @@ bool ATA::validDevice() {
}
void ATA::ATARead(uint32_t sector, uint8_t* buffer) {
driveLock.lock();
DriveSelectRegister.writeb(0xE0 | ((sector >> 24) & 0xf));
SectorCountRegister.writeb(1);
LBALo.writeb((uint8_t)sector);
@ -83,9 +84,11 @@ void ATA::ATARead(uint32_t sector, uint8_t* buffer) {
pollTillNotBSY();
for (int i=0; i<256; i++)
((uint16_t*)buffer)[i] = DataRegister.readw();
driveLock.unlock();
}
void ATA::ATAWrite(uint32_t sector, uint8_t* buffer) {
driveLock.lock();
DriveSelectRegister.writeb(0xE0 | ((sector >> 24) & 0xf));
SectorCountRegister.writeb(1);
LBALo.writeb((uint8_t)sector);
@ -96,6 +99,7 @@ void ATA::ATAWrite(uint32_t sector, uint8_t* buffer) {
for (int i=0; i<256; i++)
DataRegister.writew(((uint16_t*)buffer)[i]);
CommandRegister.writeb(0xe7);
driveLock.unlock();
}
ATAReadWriter::ATAReadWriter(uint32_t owner, uint32_t bus):
@ -105,6 +109,7 @@ ReadWriter(owner) {
}
uint32_t ATAReadWriter::read(uint32_t count, uint8_t* buffer) {
driveLock.lock();
uint32_t remainingBytes = count;
uint32_t inThisSector = currentPosition % 512;
@ -125,9 +130,11 @@ uint32_t ATAReadWriter::read(uint32_t count, uint8_t* buffer) {
}
c++;
}
driveLock.unlock();
return c;
}
uint32_t ATAReadWriter::write(uint32_t count, uint8_t* buffer) {
driveLock.lock();
uint32_t remainingBytes = count;
uint32_t inThisSector = currentPosition % 512;
@ -151,6 +158,7 @@ uint32_t ATAReadWriter::write(uint32_t count, uint8_t* buffer) {
}
// Perform a final write to ensure that we've written everything to disk.
ATAWrite((currentPosition / 512), sectorBuffer);
driveLock.unlock();
return c;
}
uint32_t ATAReadWriter::size() {

View File

@ -8,6 +8,8 @@
#include "stdio/readwriter.h"
#include "spinlock.h"
// Bus 0
// Control Ports: 1F0-1F7
// DCR / Alt Status: 3F6
@ -56,6 +58,7 @@ enum ATADriveType {
class ATA {
private:
ATADriveType type;
Spinlock driveLock;
protected:
uint32_t bus;
@ -93,6 +96,7 @@ class ATAReadWriter: public ReadWriter, public ATA {
private:
uint8_t sectorBuffer[512];
uint32_t currentPosition;
Spinlock driveLock;
public:
ATAReadWriter(uint32_t owner, uint32_t bus);

View File

@ -3,6 +3,7 @@
#include "../types.h"
#include "../memory.h"
#include "../spinlock.h"
namespace xnoe {
template<typename T>
@ -20,8 +21,9 @@ namespace xnoe {
template<typename T>
struct linkedlist {
xnoe::linkedlistelem<T>* start;
xnoe::linkedlistelem<T>* end;
xnoe::linkedlistelem<T>* start=0;
xnoe::linkedlistelem<T>* end=0;
Spinlock lock = Spinlock();
bool has(T t) {
xnoe::linkedlistelem<T>* current = this->start;
@ -49,6 +51,7 @@ namespace xnoe {
}
void append(xnoe::linkedlistelem<T>* llelem) {
lock.lock();
if (this->start && this->end) {
this->end->next = llelem;
llelem->prev = this->end;
@ -58,6 +61,7 @@ namespace xnoe {
this->start = llelem;
this->end = llelem;
}
lock.unlock();
}
void prepend(T t) {
@ -66,6 +70,7 @@ namespace xnoe {
}
void prepend(xnoe::linkedlistelem<T>* llelem) {
lock.lock();
if (this->start && this->end) {
this->start->prev = llelem;
llelem->next = this->start;
@ -75,14 +80,17 @@ namespace xnoe {
this->start = llelem;
this->end = llelem;
}
lock.unlock();
}
void insert(linkedlist<T>* ll, uint32_t index) {
lock.lock();
linkedlistelem<T>* current = this->start;
for (int i=0; i<index; i++, current = current->next);
current->next->prev = ll->end;
current->next = ll->start;
lock.unlock();
}
/*void remove(uint32_t index) {
@ -96,6 +104,7 @@ namespace xnoe {
}*/
void remove(linkedlistelem<T>* elem) {
lock.lock();
linkedlistelem<T>* current = start;
while (current) {
if (current == elem) {
@ -111,13 +120,16 @@ namespace xnoe {
if (current = end)
end = current->prev;
lock.unlock();
return;
}
current = current->next;
}
lock.unlock();
}
void remove(T elem) {
lock.lock();
linkedlistelem<T>* current = start;
while (current) {
if (current->elem == elem) {
@ -135,10 +147,12 @@ namespace xnoe {
delete current;
lock.unlock();
return;
}
current = current->next;
}
lock.unlock();
}
};
}

View File

@ -26,7 +26,7 @@ void handle_fault(frame_struct* frame) {
asm ("cli");
uint32_t problem_address;
asm ("mov %%cr2, %0" : "=a" (problem_address):);
Global::kernel->terminal->printf("\x1b[44;37;1m(CS %x EIP %x): ", frame->cs, frame->eip);
/*Global::kernel->terminal->printf("\x1b[44;37;1m(CS %x EIP %x): ", frame->cs, frame->eip);
switch (frame->gate) {
case 0: // Divide by zero
Global::kernel->terminal->printf("Divide by Zero");
@ -44,13 +44,13 @@ void handle_fault(frame_struct* frame) {
Global::kernel->terminal->printf("Unkown Fault!");
break;
}
Global::kernel->terminal->printf(" Error Code: %x\n", frame->errcode);
Global::kernel->terminal->printf(" Error Code: %x\n", frame->errcode);*/
if (!(frame->cs & 3)) {
Global::kernel->terminal->printf("[FATAL] Kernel Fault!!!\n");
while (1) asm("hlt");
} else {
// Print an error message.
Global::kernel->terminal->printf("PID %d Terminated due to fault!\n", Global::currentProc->PID);
//Global::kernel->terminal->printf("PID %d Terminated due to fault!\n", Global::currentProc->PID);
asm volatile ("mov %0, %%esp" ::"m"(Global::kernel->globalISRStack));
Global::kernel->PD->select();

View File

@ -31,7 +31,7 @@ Process::Process(uint32_t PID)
this->page_remaining = 0;
this->last_page_pointer = 0;
this->stack = this->allocate(0x8000);
this->kernelStackPtr = (new uint8_t[0x1000]) + 0x1000;
this->kernelStackPtr = (new uint8_t[0x4000]) + 0x4000;
this->state = Running;
}
@ -57,7 +57,7 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, uin
uint8_t* program_data = this->allocate(filesize + 12) + 12;
this->stack = this->allocate(0x8000);
this->kernelStackPtr = (new uint8_t[0x1000]) + 0xffc;
this->kernelStackPtr = (new uint8_t[0x4000]) + 0x4000;
this->kernelStackPtrDefault = this->kernelStackPtr;
uint32_t pCR3;

8
src/kernel/spinlock.cpp Normal file
View File

@ -0,0 +1,8 @@
#include "spinlock.h"
void Spinlock::lock() {
asm volatile ("spin_lock: mov $1, %%eax; lock xchg %0, %%eax; test %%eax, %%eax; jnz spin_lock" :: "m"(locked) : "eax");
}
void Spinlock::unlock() {
asm volatile ("xor %%eax, %%eax; lock xchg %0, %%eax" :: "m"(locked) : "eax");
}

14
src/kernel/spinlock.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef SPINLOCK_H
#define SPINLOCK_H
#include "types.h"
class Spinlock {
private:
uint32_t locked = 0;
public:
void lock();
void unlock();
};
#endif