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_VERSION=7.1.0
|
||||||
GCC_MAJOR_VERSION=6.3.0
|
GCC_MAJOR_VERSION=7.1.0
|
||||||
gcc.tar.bz2: gcc-$(GCC_VERSION).tar.bz2
|
gcc.tar.bz2: gcc-$(GCC_VERSION).tar.bz2
|
||||||
mv $^ $@
|
mv $^ $@
|
||||||
|
|
||||||
|
@ -24,7 +24,8 @@ gcc-configure:
|
||||||
../gcc/configure --prefix=$(CROSSPATH) --target=$(TARGET) --disable-nls --enable-languages=c,c++ --without-headers
|
../gcc/configure --prefix=$(CROSSPATH) --target=$(TARGET) --disable-nls --enable-languages=c,c++ --without-headers
|
||||||
|
|
||||||
gcc-make: gcc-configure
|
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
|
gcc-install: gcc-make
|
||||||
$(MAKE) -C builddir install-gcc install-target-libgcc
|
$(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() {
|
builddir() {
|
||||||
rm -rf build/ &&
|
rm -rf build/ &&
|
||||||
mkdir -pv build/
|
mkdir -pv build/
|
||||||
|
@ -59,4 +60,15 @@ mv kernel9 build/kernel &&
|
||||||
buildtools/sighax-firm.sh &&
|
buildtools/sighax-firm.sh &&
|
||||||
mv sighax.firm out/ &&
|
mv sighax.firm out/ &&
|
||||||
cp -v build/kernel/kernel out/arm11loaderhax.elf
|
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_CXX_FLAGS "${PLATFORM_C_FLAGS}")
|
||||||
SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}")
|
SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
. = 0x20000000;
|
. = 0x20401000; /*If luma wouldn't put the entire firm at 0x20001000, I'd have used 0x20000000 */
|
||||||
kernel_start = .;
|
kernel_start = .;
|
||||||
.text : {
|
.text : {
|
||||||
KEEP(*(.text.boot));
|
KEEP(*(.text.boot));
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
.section .text.boot
|
.section .text.boot
|
||||||
_start:
|
_start:
|
||||||
CPSID aif //Disable interrupts
|
CPSID aif //Disable interrupts
|
||||||
ldr sp, =kernel_stack
|
ldr sp, =svc_stack
|
||||||
//set other stacks
|
//set other stacks
|
||||||
mrs r0, cpsr
|
mrs r0, cpsr
|
||||||
bic r2, r0, #0x1F
|
bic r2, r0, #0x1F
|
||||||
|
@ -44,9 +44,12 @@ _start:
|
||||||
blx start
|
blx start
|
||||||
|
|
||||||
.section .bss
|
.section .bss
|
||||||
|
.align 16
|
||||||
.space 4096
|
.space 4096
|
||||||
interrupt_stack:
|
interrupt_stack:
|
||||||
.space 4096
|
.space 4096
|
||||||
exception_stack:
|
exception_stack:
|
||||||
|
.space 4096
|
||||||
|
svc_stack:
|
||||||
.space 16384
|
.space 16384
|
||||||
kernel_stack:
|
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_CXX_FLAGS "${PLATFORM_C_FLAGS}")
|
||||||
SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}")
|
SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}")
|
||||||
|
|
|
@ -5,13 +5,12 @@
|
||||||
|
|
||||||
PICAfb term;
|
PICAfb term;
|
||||||
void main();
|
void main();
|
||||||
extern "C" void start() { main(); }
|
extern "C" void start() { main();
|
||||||
|
for(;;);
|
||||||
|
}
|
||||||
void drivers_init() {
|
void drivers_init() {
|
||||||
term << "initing main tty\n";
|
|
||||||
setMainTTY(&term);
|
setMainTTY(&term);
|
||||||
--term;
|
--term;
|
||||||
term << "Initing vectors\n";
|
|
||||||
initVectors();
|
initVectors();
|
||||||
term << "trying svc\n";
|
|
||||||
asm volatile("svc #0");
|
asm volatile("svc #0");
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ _start:
|
||||||
mov r1, r2
|
mov r1, r2
|
||||||
orr r1, #0b10011 //SVC
|
orr r1, #0b10011 //SVC
|
||||||
msr cpsr, r1
|
msr cpsr, r1
|
||||||
ldr sp, =kernel_stack
|
ldr sp, =svc_stack
|
||||||
orr r1, #0b11111 //SYS
|
orr r1, #0b11111 //SYS
|
||||||
msr cpsr, r1
|
msr cpsr, r1
|
||||||
ldr sp, =kernel_stack
|
ldr sp, =kernel_stack
|
||||||
|
@ -121,9 +121,12 @@ _start:
|
||||||
blx start
|
blx start
|
||||||
|
|
||||||
.section .bss
|
.section .bss
|
||||||
|
.align 16
|
||||||
.space 4096
|
.space 4096
|
||||||
interrupt_stack:
|
interrupt_stack:
|
||||||
.space 4096
|
.space 4096
|
||||||
exception_stack:
|
exception_stack:
|
||||||
|
.space 4096
|
||||||
|
svc_stack:
|
||||||
.space 16384
|
.space 16384
|
||||||
kernel_stack:
|
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
|
else
|
||||||
state->returnAddr -= 4;
|
state->returnAddr -= 4;
|
||||||
}
|
}
|
||||||
|
out->puti(state->cpsr);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
extern "C" void panic2(char *msg, cpu_state *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 the special registers
|
||||||
pop {r0, r3, r4, lr}
|
pop {r0, r3, r4, lr}
|
||||||
|
msr spsr, r0
|
||||||
tst r0, #0x20 //Is code ARM or thumb?
|
tst r0, #0x20 //Is code ARM or thumb?
|
||||||
beq 2f
|
beq 2f
|
||||||
orr lr, lr, #1 //Enable thumb mode on return#
|
orr lr, lr, #1 //Enable thumb mode on return#
|
||||||
|
@ -93,7 +94,9 @@ pop_regs.append("mov sp, r0")
|
||||||
|
|
||||||
for opc in push_regs:
|
for opc in push_regs:
|
||||||
int_handler.write(" "+opc+"\n")
|
int_handler.write(" "+opc+"\n")
|
||||||
|
int_handler.write(" push {lr}\n")
|
||||||
int_handler.write(" blx handleINT\n")
|
int_handler.write(" blx handleINT\n")
|
||||||
|
int_handler.write(" pop {lr}\n")
|
||||||
for opc in reversed(pop_regs):
|
for opc in reversed(pop_regs):
|
||||||
int_handler.write(" "+opc+"\n")
|
int_handler.write(" "+opc+"\n")
|
||||||
int_handler.write(" bx lr\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(True, "framebuffer")
|
||||||
add_driver(False, "picafb")
|
add_driver(False, "picafb")
|
||||||
add_driver(False, "vectorinit")
|
add_driver(False, "vectorinit")
|
||||||
|
add_driver(False, "pmm")
|
||||||
print("Enable complete Unicode font: NO (because of the size)")
|
print("Enable complete Unicode font: NO (because of the size)")
|
||||||
config["ENABLE_FRAMEBUFFER_UNICODE"] = False
|
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(True, "framebuffer")
|
||||||
add_driver(False, "picafb")
|
add_driver(False, "picafb")
|
||||||
add_driver(False, "vectorinit")
|
add_driver(False, "vectorinit")
|
||||||
|
add_driver(False, "pmm")
|
||||||
print("Enable complete Unicode font: NO (because of the size)")
|
print("Enable complete Unicode font: NO (because of the size)")
|
||||||
config["ENABLE_FRAMEBUFFER_UNICODE"] = False
|
config["ENABLE_FRAMEBUFFER_UNICODE"] = False
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "framebuffer.hpp"
|
#include "framebuffer.hpp"
|
||||||
#include <genfont.h>
|
#include <genfont.h>
|
||||||
|
#include <base.hpp>
|
||||||
auto Framebuffer::plotPixel(int x, int y, int col) -> void {}
|
auto Framebuffer::plotPixel(int x, int y, int col) -> void {}
|
||||||
auto Framebuffer::plotChar(int x, int y, int c) -> void {
|
auto Framebuffer::plotChar(int x, int y, int c) -> void {
|
||||||
if (c > 65535) return;
|
if (c > 65535) return;
|
||||||
|
|
|
@ -8,3 +8,4 @@ else:
|
||||||
add_driver(False, "cgaterm")
|
add_driver(False, "cgaterm")
|
||||||
add_driver(False, "8259")
|
add_driver(False, "8259")
|
||||||
add_driver(False, "idt")
|
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 new[](size_t s, void *p) { return p; }
|
||||||
void operator delete(void *, void *p) {}
|
void operator delete(void *, void *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.
|
* 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>
|
#include <base.hpp>
|
||||||
TTY *out;
|
TTY *out;
|
||||||
bool tty_set = false;
|
bool tty_set = false;
|
||||||
void setMainTTY(Kobject *obj) {
|
void setMainTTY(TTY *obj) {
|
||||||
if (obj->type == kobjectType::TTY) {
|
++*obj;
|
||||||
++*obj;
|
// if(tty_set)
|
||||||
// if(tty_set)
|
// --*out;
|
||||||
// --*out;
|
out = obj;
|
||||||
out = (TTY *)obj;
|
tty_set = true;
|
||||||
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