added broken raspi2 port

fixed all arm ports
This commit is contained in:
Morten Delenk 2017-07-20 09:26:35 +01:00
parent eb46090547
commit d0736af522
33 changed files with 477 additions and 23 deletions

View file

@ -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

View file

@ -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

View file

@ -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}")

View file

@ -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));

View file

@ -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:

View file

@ -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}")

View file

@ -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");
} }

View file

@ -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:

View file

@ -1 +1 @@
config["SYSTEM"] = get_from_list("System", ["3ds9","3ds11"]) config["SYSTEM"] = get_from_list("System", ["3ds9","3ds11", "raspi2"])

View file

@ -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) {

View file

@ -0,0 +1,2 @@
config["LOWEST_CPU"] = "cortex-a7"

View 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}")

View 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 = .;
}

View 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");
}

View 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:

View file

@ -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")

View file

View 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

View file

@ -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

View file

@ -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;

View file

@ -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")

View file

@ -0,0 +1,3 @@
add_driver(False, "uart")
add_driver(False, "serial")
add_driver(False, "vector")

View 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);
}

View 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();
};

View 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
}

View 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();
};

View 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;
}

View file

@ -0,0 +1,2 @@
#pragma once
void initVectors();

View file

@ -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;
}

View file

@ -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);

View 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.

View file

@ -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 = (TTY *)obj; out = obj;
tty_set = true; tty_set = true;
} }
}

87
kernel/src/pmm.cpp.old Normal file
View 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;
}