added broken raspi2 port
fixed all arm ports
This commit is contained in:
parent
eb46090547
commit
d0736af522
33 changed files with 477 additions and 23 deletions
|
@ -1,5 +1,5 @@
|
|||
GCC_VERSION=6.3.0
|
||||
GCC_MAJOR_VERSION=6.3.0
|
||||
GCC_VERSION=7.1.0
|
||||
GCC_MAJOR_VERSION=7.1.0
|
||||
gcc.tar.bz2: gcc-$(GCC_VERSION).tar.bz2
|
||||
mv $^ $@
|
||||
|
||||
|
@ -24,7 +24,8 @@ gcc-configure:
|
|||
../gcc/configure --prefix=$(CROSSPATH) --target=$(TARGET) --disable-nls --enable-languages=c,c++ --without-headers
|
||||
|
||||
gcc-make: gcc-configure
|
||||
$(MAKE) -C builddir all-gcc all-target-libgcc
|
||||
$(MAKE) -C builddir all-gcc
|
||||
$(MAKE) -C builddir all-target-libgcc
|
||||
|
||||
gcc-install: gcc-make
|
||||
$(MAKE) -C builddir install-gcc install-target-libgcc
|
||||
|
|
14
do_all.sh
14
do_all.sh
|
@ -1,3 +1,4 @@
|
|||
unset CFLAGS CXXFLAGS LDFLAGS
|
||||
builddir() {
|
||||
rm -rf build/ &&
|
||||
mkdir -pv build/
|
||||
|
@ -59,4 +60,15 @@ mv kernel9 build/kernel &&
|
|||
buildtools/sighax-firm.sh &&
|
||||
mv sighax.firm out/ &&
|
||||
cp -v build/kernel/kernel out/arm11loaderhax.elf
|
||||
rm -rf build/
|
||||
|
||||
{
|
||||
echo 2
|
||||
echo 2
|
||||
yes ''
|
||||
} | ./config.py &&
|
||||
builddir &&
|
||||
pushd build &&
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm-none-eabi.cmake .. &&
|
||||
make -j$(nproc) &&
|
||||
popd &&
|
||||
cp -v build/kernel/kernel out/raspi2.elf
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
SET(PLATFORM_C_FLAGS "-I../../kernel/arch/arm/3ds11/include -mcpu=mpcore -mlittle-endian -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft -O9")
|
||||
SET(PLATFORM_C_FLAGS "-I../../kernel/arch/arm/3ds11/include -mcpu=mpcore -mlittle-endian -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft -O2")
|
||||
SET(PLATFORM_CXX_FLAGS "${PLATFORM_C_FLAGS}")
|
||||
SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}")
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
ENTRY(_start)
|
||||
SECTIONS {
|
||||
. = 0x20000000;
|
||||
. = 0x20401000; /*If luma wouldn't put the entire firm at 0x20001000, I'd have used 0x20000000 */
|
||||
kernel_start = .;
|
||||
.text : {
|
||||
KEEP(*(.text.boot));
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
.section .text.boot
|
||||
_start:
|
||||
CPSID aif //Disable interrupts
|
||||
ldr sp, =kernel_stack
|
||||
ldr sp, =svc_stack
|
||||
//set other stacks
|
||||
mrs r0, cpsr
|
||||
bic r2, r0, #0x1F
|
||||
|
@ -44,9 +44,12 @@ _start:
|
|||
blx start
|
||||
|
||||
.section .bss
|
||||
.align 16
|
||||
.space 4096
|
||||
interrupt_stack:
|
||||
.space 4096
|
||||
exception_stack:
|
||||
.space 4096
|
||||
svc_stack:
|
||||
.space 16384
|
||||
kernel_stack:
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
SET(PLATFORM_C_FLAGS "-I../../kernel/arch/arm/3ds9/include -mcpu=arm946e-s -march=armv5te -mthumb-interwork -marm -O9")
|
||||
SET(PLATFORM_C_FLAGS "-I../../kernel/arch/arm/3ds9/include -mcpu=arm946e-s -march=armv5te -mthumb-interwork -marm -Os")
|
||||
SET(PLATFORM_CXX_FLAGS "${PLATFORM_C_FLAGS}")
|
||||
SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}")
|
||||
|
|
|
@ -5,13 +5,12 @@
|
|||
|
||||
PICAfb term;
|
||||
void main();
|
||||
extern "C" void start() { main(); }
|
||||
extern "C" void start() { main();
|
||||
for(;;);
|
||||
}
|
||||
void drivers_init() {
|
||||
term << "initing main tty\n";
|
||||
setMainTTY(&term);
|
||||
--term;
|
||||
term << "Initing vectors\n";
|
||||
initVectors();
|
||||
term << "trying svc\n";
|
||||
asm volatile("svc #0");
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ _start:
|
|||
mov r1, r2
|
||||
orr r1, #0b10011 //SVC
|
||||
msr cpsr, r1
|
||||
ldr sp, =kernel_stack
|
||||
ldr sp, =svc_stack
|
||||
orr r1, #0b11111 //SYS
|
||||
msr cpsr, r1
|
||||
ldr sp, =kernel_stack
|
||||
|
@ -121,9 +121,12 @@ _start:
|
|||
blx start
|
||||
|
||||
.section .bss
|
||||
.align 16
|
||||
.space 4096
|
||||
interrupt_stack:
|
||||
.space 4096
|
||||
exception_stack:
|
||||
.space 4096
|
||||
svc_stack:
|
||||
.space 16384
|
||||
kernel_stack:
|
||||
|
|
|
@ -1 +1 @@
|
|||
config["SYSTEM"] = get_from_list("System", ["3ds9","3ds11"])
|
||||
config["SYSTEM"] = get_from_list("System", ["3ds9","3ds11", "raspi2"])
|
||||
|
|
|
@ -42,6 +42,7 @@ extern "C" cpu_state *handleINT(int number, cpu_state *state) {
|
|||
else
|
||||
state->returnAddr -= 4;
|
||||
}
|
||||
out->puti(state->cpsr);
|
||||
return state;
|
||||
}
|
||||
extern "C" void panic2(char *msg, cpu_state *state) {
|
||||
|
|
2
kernel/arch/arm/raspi2/config.py
Normal file
2
kernel/arch/arm/raspi2/config.py
Normal file
|
@ -0,0 +1,2 @@
|
|||
config["LOWEST_CPU"] = "cortex-a7"
|
||||
|
3
kernel/arch/arm/raspi2/flags.cmake
Normal file
3
kernel/arch/arm/raspi2/flags.cmake
Normal file
|
@ -0,0 +1,3 @@
|
|||
SET(PLATFORM_C_FLAGS "-I../../kernel/arch/arm/3ds11/include -mcpu=cortex-a7 -mlittle-endian -mtune=cortex-a7 -mfloat-abi=hard -mtp=soft -O2")
|
||||
SET(PLATFORM_CXX_FLAGS "${PLATFORM_C_FLAGS}")
|
||||
SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}")
|
36
kernel/arch/arm/raspi2/layout.ld
Normal file
36
kernel/arch/arm/raspi2/layout.ld
Normal file
|
@ -0,0 +1,36 @@
|
|||
ENTRY(_start)
|
||||
SECTIONS {
|
||||
. = 0x8000; /*If luma wouldn't put the entire firm at 0x20001000, I'd have used 0x20000000 */
|
||||
kernel_start = .;
|
||||
.text : {
|
||||
KEEP(*(.text.boot));
|
||||
*(.text)
|
||||
}
|
||||
.data : {
|
||||
start_ctors = .;
|
||||
KEEP(*(.init_array));
|
||||
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)));
|
||||
KEEP(*(.ctors));
|
||||
end_ctors = .;
|
||||
start_dtors = .;
|
||||
KEEP(*(.fini_array));
|
||||
KEEP(*(.fini_array.*));
|
||||
KEEP(*(.dtors));
|
||||
end_dtors = .;
|
||||
start_eh_frame = .;
|
||||
KEEP(*(.eh_frame));
|
||||
KEEP(*(.eh_frame.*));
|
||||
QUAD(0);
|
||||
KEEP(*(.gcc_except_table));
|
||||
KEEP(*(.gcc_except_table.*));
|
||||
*(.data)
|
||||
}
|
||||
.rodata : {
|
||||
*(.rodata)
|
||||
}
|
||||
.bss : {
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
kernel_end = .;
|
||||
}
|
14
kernel/arch/arm/raspi2/start.cpp
Normal file
14
kernel/arch/arm/raspi2/start.cpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
#include "../../../hw/raspi2/serial/serial.hpp"
|
||||
#include "../../../hw/raspi2/vector/vector.hpp"
|
||||
#include <base.hpp>
|
||||
#include <config.h>
|
||||
|
||||
Serial term;
|
||||
void main();
|
||||
extern "C" void start() { main(); }
|
||||
void drivers_init() {
|
||||
setMainTTY(&term);
|
||||
--term;
|
||||
initVectors();
|
||||
asm volatile("svc #0");
|
||||
}
|
54
kernel/arch/arm/raspi2/start.s
Normal file
54
kernel/arch/arm/raspi2/start.s
Normal file
|
@ -0,0 +1,54 @@
|
|||
.arm
|
||||
.arch armv6k
|
||||
.fpu vfpv2
|
||||
.align 4
|
||||
.global _start
|
||||
.extern start
|
||||
.section .text.boot
|
||||
_start:
|
||||
CPSID aif //Disable interrupts
|
||||
ldr sp, =svc_stack
|
||||
push {r0,r1,r2}
|
||||
//set other stacks
|
||||
mrs r0, cpsr
|
||||
bic r2, r0, #0x1F
|
||||
mov r1, r2
|
||||
orr r1, #0b10001 //FIQ
|
||||
msr cpsr, r1
|
||||
ldr sp, =interrupt_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b10010 //IRQ
|
||||
msr cpsr, r1
|
||||
ldr sp, =interrupt_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b10111 //Abort
|
||||
msr cpsr, r1
|
||||
ldr sp, =exception_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b11011 //Undefined
|
||||
msr cpsr, r1
|
||||
ldr sp, =exception_stack
|
||||
orr r1, #0b11111 //SYS
|
||||
msr cpsr, r1
|
||||
ldr sp, =kernel_stack
|
||||
//Enable FPU
|
||||
MRC p15, 0, r0, c1, c1, 2
|
||||
ORR r0, r0, #3<<10 // enable fpu
|
||||
MCR p15, 0, r0, c1, c1, 2
|
||||
LDR r0, =(0xF << 20)
|
||||
MCR p15, 0, r0, c1, c0, 2
|
||||
MOV r3, #0x40000000
|
||||
VMSR FPEXC, r3
|
||||
//Start MTGos
|
||||
blx start
|
||||
|
||||
.section .bss
|
||||
.align 16
|
||||
.space 4096
|
||||
interrupt_stack:
|
||||
.space 4096
|
||||
exception_stack:
|
||||
.space 4096
|
||||
svc_stack:
|
||||
.space 16384
|
||||
kernel_stack:
|
|
@ -47,6 +47,7 @@ branch_macro:
|
|||
|
||||
//pop the special registers
|
||||
pop {r0, r3, r4, lr}
|
||||
msr spsr, r0
|
||||
tst r0, #0x20 //Is code ARM or thumb?
|
||||
beq 2f
|
||||
orr lr, lr, #1 //Enable thumb mode on return#
|
||||
|
@ -93,7 +94,9 @@ pop_regs.append("mov sp, r0")
|
|||
|
||||
for opc in push_regs:
|
||||
int_handler.write(" "+opc+"\n")
|
||||
int_handler.write(" push {lr}\n")
|
||||
int_handler.write(" blx handleINT\n")
|
||||
int_handler.write(" pop {lr}\n")
|
||||
for opc in reversed(pop_regs):
|
||||
int_handler.write(" "+opc+"\n")
|
||||
int_handler.write(" bx lr\n")
|
||||
|
|
0
kernel/cpu/arm/cortex-a7/config.py
Normal file
0
kernel/cpu/arm/cortex-a7/config.py
Normal file
|
@ -8,5 +8,6 @@ if config["ENABLE_I2C"]:
|
|||
add_driver(True, "framebuffer")
|
||||
add_driver(False, "picafb")
|
||||
add_driver(False, "vectorinit")
|
||||
add_driver(False, "pmm")
|
||||
print("Enable complete Unicode font: NO (because of the size)")
|
||||
config["ENABLE_FRAMEBUFFER_UNICODE"] = False
|
||||
|
|
|
@ -2,5 +2,6 @@ config["ENABLE_EXTRA_MEMORY"] = get_yes_no("Enable 512KB of memory on n3DS", Tru
|
|||
add_driver(True, "framebuffer")
|
||||
add_driver(False, "picafb")
|
||||
add_driver(False, "vectorinit")
|
||||
add_driver(False, "pmm")
|
||||
print("Enable complete Unicode font: NO (because of the size)")
|
||||
config["ENABLE_FRAMEBUFFER_UNICODE"] = False
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "framebuffer.hpp"
|
||||
#include <genfont.h>
|
||||
#include <base.hpp>
|
||||
auto Framebuffer::plotPixel(int x, int y, int col) -> void {}
|
||||
auto Framebuffer::plotChar(int x, int y, int c) -> void {
|
||||
if (c > 65535) return;
|
||||
|
|
|
@ -8,3 +8,4 @@ else:
|
|||
add_driver(False, "cgaterm")
|
||||
add_driver(False, "8259")
|
||||
add_driver(False, "idt")
|
||||
add_driver(False, "pmm")
|
||||
|
|
3
kernel/hw/raspi2/config.py
Normal file
3
kernel/hw/raspi2/config.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
add_driver(False, "uart")
|
||||
add_driver(False, "serial")
|
||||
add_driver(False, "vector")
|
72
kernel/hw/raspi2/serial/serial.cpp
Normal file
72
kernel/hw/raspi2/serial/serial.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
#include "serial.hpp"
|
||||
Serial::Serial(): TTY(80,25), uart(UART::getInstance()) {
|
||||
uart[UART_MEM::IBRD] = 1;
|
||||
uart[UART_MEM::FBRD] = 40;
|
||||
uart[UART_MEM::LCRH] = 0b1110000;
|
||||
uart[UART_MEM::IMSC] = 0b11111110010;
|
||||
uart[UART_MEM::CR] = 0b1100000001;
|
||||
}
|
||||
auto Serial::serial_putc(char c) -> void {
|
||||
while(uart[UART_MEM::FR] & 0x20);
|
||||
uart[UART_MEM::DR] = (uint8_t)c;
|
||||
}
|
||||
auto Serial::serial_putc(int c) -> void {
|
||||
//UTF-8 encoder
|
||||
if(c <= 0x7F)
|
||||
return this->serial_putc((char)c);
|
||||
if(c <= 0x7FF) {
|
||||
this->serial_putc((char)(0b11000000 | (c >> 6)));
|
||||
this->serial_putc((char)(0b10000000 | (c & 0x3F)));
|
||||
return;
|
||||
}
|
||||
if(c <= 0xFFFF) {
|
||||
this->serial_putc((char)(0b11100000 | (c >> 12)));
|
||||
this->serial_putc((char)(0b10000000 | ((c >> 6)&0x3F)));
|
||||
this->serial_putc((char)(0b10000000 | (c&0x3F)));
|
||||
return;
|
||||
}
|
||||
this->serial_putc((char)(0b11110000 | (c >> 18)));
|
||||
this->serial_putc((char)(0b10000000 | ((c >> 12)&0x3F)));
|
||||
this->serial_putc((char)(0b10000000 | ((c >> 6)&0x3F)));
|
||||
this->serial_putc((char)(0b10000000 | (c&0x3F)));
|
||||
}
|
||||
auto Serial::serial_puti(int i) -> void {
|
||||
char buf[65];
|
||||
char *ptr=buf+63;
|
||||
ptr[1]=0;
|
||||
char *chars = "0123456789";
|
||||
do {
|
||||
*(ptr--) = chars[i%10];
|
||||
i/=10;
|
||||
} while (i && (ptr != buf));
|
||||
ptr++;
|
||||
while(*ptr)
|
||||
this->serial_putc(*(ptr++));
|
||||
}
|
||||
auto Serial::plotChar(int x, int y, int c) -> void {
|
||||
//Send position
|
||||
serial_putc(0x1B);
|
||||
serial_putc('[');
|
||||
serial_puti(y+1);
|
||||
serial_putc(';');
|
||||
serial_puti(x+1);
|
||||
serial_putc('H');
|
||||
//Send color
|
||||
int r = rgbColor >> 16;
|
||||
int g = (rgbColor >> 8) & 0xFF;
|
||||
int b = rgbColor & 0xFF;
|
||||
serial_putc(0x1B);
|
||||
serial_putc('[');
|
||||
serial_puti(38);
|
||||
serial_putc(';');
|
||||
serial_puti(2);
|
||||
serial_putc(';');
|
||||
serial_puti(r);
|
||||
serial_putc(';');
|
||||
serial_puti(g);
|
||||
serial_putc(';');
|
||||
serial_puti(b);
|
||||
serial_putc('m');
|
||||
//Actually write the character
|
||||
serial_putc(c);
|
||||
}
|
14
kernel/hw/raspi2/serial/serial.hpp
Normal file
14
kernel/hw/raspi2/serial/serial.hpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
#include "../uart/uart.hpp"
|
||||
#include <base.hpp>
|
||||
class Serial: public TTY {
|
||||
private:
|
||||
UART &uart;
|
||||
auto serial_putc(int c) -> void;
|
||||
auto serial_putc(char c) -> void;
|
||||
auto serial_puti(int i) -> void;
|
||||
protected:
|
||||
virtual auto plotChar(int x, int y, int c) -> void;
|
||||
public:
|
||||
Serial();
|
||||
};
|
25
kernel/hw/raspi2/uart/uart.cpp
Normal file
25
kernel/hw/raspi2/uart/uart.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include "uart.hpp"
|
||||
static volatile uint32_t x;
|
||||
auto delay = [&x](uint32_t count) {
|
||||
for(x=0;x<count;x++);
|
||||
};
|
||||
UART &UART::getInstance() {
|
||||
static UART instance;
|
||||
return instance;
|
||||
}
|
||||
uint32_t &UART::operator[](uint32_t off) {
|
||||
return *((uint32_t*)(0x3F200000+off));
|
||||
}
|
||||
uint32_t &UART::operator[](UART_MEM off) {
|
||||
return (*this)[(uint32_t)off];
|
||||
}
|
||||
UART::UART() {
|
||||
auto &self = *this;
|
||||
self[UART_MEM::CR] = 0;
|
||||
self[UART_MEM::GPPUD] = 0;
|
||||
delay(150);
|
||||
self[UART_MEM::GPPUDCLK0] = (3 << 14);
|
||||
delay(150);
|
||||
self[UART_MEM::GPPUDCLK0] = 0;
|
||||
self[UART_MEM::ICR] = 0x7FF; //Clear interrupts
|
||||
}
|
34
kernel/hw/raspi2/uart/uart.hpp
Normal file
34
kernel/hw/raspi2/uart/uart.hpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
enum class UART_MEM: uint32_t {
|
||||
GPPUD = 0x94,
|
||||
GPPUDCLK0 = 0x98,
|
||||
DR = 0x00,
|
||||
RSRECR = 0x04,
|
||||
FR = 0x18,
|
||||
ILPR = 0x20,
|
||||
IBRD = 0x24,
|
||||
FBRD = 0x28,
|
||||
LCRH = 0x2C,
|
||||
CR = 0x30,
|
||||
IFLS = 0x34,
|
||||
IMSC = 0x38,
|
||||
RIS = 0x3C,
|
||||
MIS = 0x40,
|
||||
ICR = 0x44,
|
||||
DMACR = 0x48,
|
||||
ITCR = 0x80,
|
||||
ITIP = 0x84,
|
||||
ITOP = 0x88,
|
||||
TDR = 0x8C
|
||||
};
|
||||
class UART {
|
||||
public:
|
||||
static UART &getInstance();
|
||||
uint32_t &operator[](uint32_t off); ///< Returns a reference to the corresponding MMIO register
|
||||
uint32_t &operator[](UART_MEM off); ///< @see UART::operator[](uint32_t off);
|
||||
UART(UART const&) = delete;
|
||||
UART &operator=(UART const&) = delete;
|
||||
private:
|
||||
UART();
|
||||
};
|
32
kernel/hw/raspi2/vector/vector.cpp
Normal file
32
kernel/hw/raspi2/vector/vector.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include <stdint.h>
|
||||
extern "C" {
|
||||
void data_abort();
|
||||
void fast_irq();
|
||||
void normal_irq();
|
||||
void prefetch_abort();
|
||||
void svc_call();
|
||||
void undefined_op();
|
||||
extern uintptr_t branch_macro;
|
||||
}
|
||||
void initVectors() {
|
||||
uintptr_t *vectors = (uintptr_t*)nullptr;
|
||||
uintptr_t branch = 0xEA000000;
|
||||
vectors[1] = branch + 5;
|
||||
vectors[2] = branch + 6;
|
||||
vectors[3] = branch + 7;
|
||||
vectors[4] = branch + 8;
|
||||
vectors[6] = branch + 8;
|
||||
vectors[7] = branch + 9;
|
||||
vectors[8] = branch_macro;
|
||||
vectors[9] = (uintptr_t)&undefined_op;
|
||||
vectors[10] = branch_macro;
|
||||
vectors[11] = (uintptr_t)&svc_call;
|
||||
vectors[12] = branch_macro;
|
||||
vectors[13] = (uintptr_t)&prefetch_abort;
|
||||
vectors[14] = branch_macro;
|
||||
vectors[15] = (uintptr_t)&data_abort;
|
||||
vectors[16] = branch_macro;
|
||||
vectors[17] = (uintptr_t)&normal_irq;
|
||||
vectors[18] = branch_macro;
|
||||
vectors[19] = (uintptr_t)&fast_irq;
|
||||
}
|
2
kernel/hw/raspi2/vector/vector.hpp
Normal file
2
kernel/hw/raspi2/vector/vector.hpp
Normal file
|
@ -0,0 +1,2 @@
|
|||
#pragma once
|
||||
void initVectors();
|
|
@ -17,3 +17,10 @@ void *operator new(size_t s, void *p) { return p; }
|
|||
void *operator new[](size_t s, void *p) { return p; }
|
||||
void operator delete(void *, void *p) {}
|
||||
void operator delete[](void *, void *p) {}
|
||||
__extension__ typedef int __guard __attribute__((mode(__DI__)));
|
||||
extern "C" int __cxa_guard_acquire(__guard *g) {
|
||||
return !*(char*)g;
|
||||
}
|
||||
extern "C" int __cxa_guard_release(__guard *g) {
|
||||
*(char *)g = 1;
|
||||
}
|
||||
|
|
|
@ -5,4 +5,9 @@ extern TTY *out; ///< main TTY for output
|
|||
/***
|
||||
* Sets the main TTY to some other TTY object.
|
||||
*/
|
||||
void setMainTTY(Kobject *obj);
|
||||
void setMainTTY(TTY *obj);
|
||||
|
||||
/**
|
||||
* Halts the kernel due to a unresolvable error
|
||||
*/
|
||||
extern "C" void panic(const char* s);
|
||||
|
|
40
kernel/src/include/pmm.hpp
Normal file
40
kernel/src/include/pmm.hpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
typedef uintptr_t phys_t; ///< Type used for physical addresses
|
||||
/**
|
||||
* A single entry in the PMM list
|
||||
*/
|
||||
struct PMM_ent {
|
||||
PMM_ent* next; ///< Next element in the list
|
||||
phys_t val; ///< This for not having to cast in the code.
|
||||
};
|
||||
/**
|
||||
* Structure for a memory map
|
||||
*/
|
||||
struct mmap_ent {
|
||||
phys_t start;
|
||||
phys_t end;
|
||||
}
|
||||
/**
|
||||
* Physical memory manager. It stores the free memory in a linked list
|
||||
*/
|
||||
class PMM {
|
||||
protected:
|
||||
PMM_ent *head; ///< Head of the linked list
|
||||
virtual auto isFree(phys_t addr) -> bool; ///< Returns true if the provided page is free to use
|
||||
phys_t page_size; ///< Contains the size of a single memory page, in bytes
|
||||
public:
|
||||
PMM(phys_t page_size, mmap_ent *entries, int length);
|
||||
virtual ~PMM();
|
||||
virtual auto operator<<(phys_t page) -> PMM &; ///< Frees a page. O(1)
|
||||
virtual auto operator>>(phys_t &page) -> PMM &; ///< Allocates a page. O(1)
|
||||
virtual auto operator,(size_t no_pages) -> phys_t; ///< Allocates multiple pages. O(n²)
|
||||
virtual auto operator(phys_t pages,size_t no_pages) -> void; ///< Deallocates multiple pages. O(n)
|
||||
virtual auto operator&&(phys_t page) -> bool; //Returns true if this page is free. O(n).
|
||||
};
|
||||
/**
|
||||
* This definition is for having a python-like syntax - like `page in pmm`
|
||||
*/
|
||||
#define in and
|
||||
|
||||
auto operator&&(phys_t a, PMM mm) -> bool; ///< Returns true when page is free. Used for syntax `page in pmm`
|
||||
auto operator&&(phys_t a, PMM *mm) -> bool; ///< Returns true when page is free. Present in case that mm is a pointer.
|
|
@ -1,12 +1,10 @@
|
|||
#include <base.hpp>
|
||||
TTY *out;
|
||||
bool tty_set = false;
|
||||
void setMainTTY(Kobject *obj) {
|
||||
if (obj->type == kobjectType::TTY) {
|
||||
++*obj;
|
||||
// if(tty_set)
|
||||
// --*out;
|
||||
out = (TTY *)obj;
|
||||
tty_set = true;
|
||||
}
|
||||
void setMainTTY(TTY *obj) {
|
||||
++*obj;
|
||||
// if(tty_set)
|
||||
// --*out;
|
||||
out = obj;
|
||||
tty_set = true;
|
||||
}
|
||||
|
|
87
kernel/src/pmm.cpp.old
Normal file
87
kernel/src/pmm.cpp.old
Normal file
|
@ -0,0 +1,87 @@
|
|||
#include <base.hpp>
|
||||
#include <pmm.hpp>
|
||||
extern "C" int kernel_start;
|
||||
extern "C" int kernel_end;
|
||||
auto PMM::isFree(phys_t addr) -> bool {
|
||||
if(addr == 0)
|
||||
return false;
|
||||
phys_t start = (phys_t)(&kernel_start);
|
||||
phys_t end = (phys_t)(&kernel_end);
|
||||
if((addr >= start) or (addr < end))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
PMM::PMM(phys_t page_size, mmap_ent *entries, int length): page_size(page_size), head(nullptr) {
|
||||
for(int i=0;i< length; i++) {
|
||||
for(phys_t j=entries[i].start;j<entries[i].end;j+=page_size) {
|
||||
if(isFree(j))
|
||||
*this << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
PMM::~PMM() {}
|
||||
|
||||
auto PMM::operator<<(phys_t page) -> PMM & {
|
||||
*this(page,1);
|
||||
return *this;
|
||||
}
|
||||
auto PMM::operator>>(phys_t &page) -> PMM & {
|
||||
page = *this, 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto PMM::operator,(size_t no_pages) -> phys_t {
|
||||
if(head == nullptr)
|
||||
panic("No free physical memory is available.");
|
||||
if(no_pages == 1) {
|
||||
//Simple. Just return the fist page.
|
||||
PMM_ent *curr=head;
|
||||
head=head->next;
|
||||
return curr->val;
|
||||
}
|
||||
//Now we need to find a free page with n-1 free pages after it
|
||||
PMM_ent *curr=head;
|
||||
while(curr) {
|
||||
//Is curr+n pages free?
|
||||
if((curr->val+((no_pages-1)*page_size)) in this) {
|
||||
//We're onto something
|
||||
bool notfound=false;
|
||||
phys_t i;
|
||||
size_t j;
|
||||
for(i=curr->val,j=0; j<no_pages; i+=page_size, j++) {
|
||||
if(!(i in this)) {
|
||||
notfound=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!notfound)
|
||||
return curr->val;
|
||||
}
|
||||
//Not found.
|
||||
curr=curr->next;
|
||||
}
|
||||
panic("Not enough continuous free memory is available.");
|
||||
}
|
||||
auto PMM::operator(phys_t pages, size_t no_pages) -> void {
|
||||
for(size_t i=0; i<no_pages; i++, pages+=page_size) {
|
||||
PMM_ent *curr=(PMM_ent *)pages;
|
||||
curr->next=head;
|
||||
curr->val=pages;
|
||||
head=curr;
|
||||
}
|
||||
}
|
||||
virtual auto operator&&(phys_t page) -> bool {
|
||||
PMM_ent *curr = head;
|
||||
while(curr) {
|
||||
if(curr->value==page)
|
||||
return true;
|
||||
curr=curr->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
auto operator&&(phys_t a, PMM mm) -> bool {
|
||||
return mm && a;
|
||||
}
|
||||
auto operator&&(phys_t a, PMM *mm) -> bool {
|
||||
return a in *mm;
|
||||
}
|
Loading…
Reference in a new issue