Added spinlocks
This commit is contained in:
parent
dc2fe698a3
commit
6339b3e4bd
@ -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);
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
8
src/kernel/spinlock.cpp
Normal 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
14
src/kernel/spinlock.h
Normal 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
|
Loading…
x
Reference in New Issue
Block a user