removed files that aren't part of kernel9
This commit is contained in:
parent
9cee98801e
commit
9c221fca53
85 changed files with 4 additions and 2677 deletions
103
config.py
103
config.py
|
@ -1,103 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
"This tool is for configuring mtgos"
|
||||
def get_from_list(p,l):
|
||||
print("Select one of:")
|
||||
for i,j in enumerate(l):
|
||||
print(str(i)+":",j)
|
||||
if len(l) == 1:
|
||||
print(p+": 0 (autoselected)")
|
||||
return l[0]
|
||||
i=-1
|
||||
while (i<0) or (i >= len(l)):
|
||||
x = input(p+": ")
|
||||
try:
|
||||
i = int(x)
|
||||
except:
|
||||
i = -1
|
||||
print()
|
||||
return l[i]
|
||||
def get_yes_no(p, default=None):
|
||||
x="a"
|
||||
defaultstr = "[yn]"
|
||||
if default:
|
||||
defaultstr = "[Yn]"
|
||||
elif default == False:
|
||||
defaultstr = "[yN]"
|
||||
while x not in "ynYN":
|
||||
x = input(p+" "+defaultstr+": ")
|
||||
if (x == "") and default is not None:
|
||||
return default
|
||||
return x in "yY"
|
||||
def add_driver(common, name):
|
||||
if common:
|
||||
drivers.append("hw/"+name+"/")
|
||||
else:
|
||||
drivers.append("hw/"+config["SYSTEM"]+"/"+name+"/")
|
||||
drivers=[]
|
||||
config={}
|
||||
config["ARCH"] = get_from_list("Architecture", ["x86","x86_64","arm"])
|
||||
exec(open("kernel/arch/"+config["ARCH"]+"/config.py").read())
|
||||
exec(open("kernel/arch/"+config["ARCH"]+"/"+config["SYSTEM"]+"/config.py").read())
|
||||
exec(open("kernel/cpu/"+config["ARCH"]+"/"+config["LOWEST_CPU"]+"/config.py").read())
|
||||
exec(open("kernel/hw/"+config["SYSTEM"]+"/config.py").read())
|
||||
exec(open("kernel/hw/config.py").read())
|
||||
with open("config.cmake", "w") as f:
|
||||
for key, val in config.items():
|
||||
if val == True:
|
||||
f.write('SET('+key+' 1)\n')
|
||||
elif val != False:
|
||||
f.write('SET('+key+' '+str(val)+')\n')
|
||||
for driver in drivers:
|
||||
f.write("SET(DRIVER_SRCS ${DRIVER_SRCS} "+driver+"*.c "+driver+"*.cpp "+driver+"*.s)\n")
|
||||
|
||||
with open("config.h", "w") as f:
|
||||
for key, val in config.items():
|
||||
if val == True:
|
||||
f.write("#define "+key+" 1\n")
|
||||
elif val == False:
|
||||
f.write("#undef "+key+"\n")
|
||||
elif isinstance(val, int):
|
||||
f.write("#define "+key+" ("+str(val)+")\n")
|
||||
else:
|
||||
f.write("#define "+key+' "'+val+'"\n')
|
||||
if "ENABLE_FRAMEBUFFER_UNICODE" in config:
|
||||
#Write the font
|
||||
chars=range(65536)
|
||||
if not config["ENABLE_FRAMEBUFFER_UNICODE"]:
|
||||
chars = [0x0000, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C,
|
||||
0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8, 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B4, 0x25BC]
|
||||
chars += list(range(0x20, 0x7F))
|
||||
chars += [0x2302]
|
||||
chars += [0xC7, 0xFC, 0xE9, 0xE2, 0xE4, 0xE0, 0xE5, 0xE7, 0xEA, 0xEB, 0xE8, 0xEF, 0xEE, 0xEC, 0xC4, 0xC5,
|
||||
0xC9, 0xE6, 0xC6, 0xF4, 0xF6, 0xF2, 0xFB, 0xF9, 0xFF, 0xD6, 0xDC, 0xA2, 0xA3, 0xA5, 0x20A7, 0x0192,
|
||||
0xE1, 0xED, 0xF3, 0xFA, 0xF1, 0xD1, 0xAA, 0xBA, 0xBF, 0x2310, 0xAC, 0xBD, 0xBC, 0xA1, 0xAB, 0xBB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0]
|
||||
chars.sort()
|
||||
ch=chars
|
||||
chars=[]
|
||||
for c in ch:
|
||||
chars.append("{0:0{1}X}".format(c,4))
|
||||
x=open("unifont.hex").readlines()
|
||||
from subprocess import *
|
||||
p = Popen(["./fontgen.py"], stdin=PIPE)
|
||||
for l in x:
|
||||
if l[:4] in chars:
|
||||
p.stdin.write(l.encode("UTF-8"))
|
||||
p.stdin.close()
|
||||
p.wait()
|
||||
|
||||
print("Generating sourcecode…")
|
||||
int_handler = open("kernel/arch/"+config["ARCH"]+"/int.s","w")
|
||||
import os
|
||||
try:
|
||||
os.makedirs("kernel/arch/"+config["ARCH"]+"/include")
|
||||
except:
|
||||
pass
|
||||
reg_struct = open("kernel/arch/"+config["ARCH"]+"/include/regs.h","w")
|
||||
exec(open("kernel/arch/"+config["ARCH"]+"/sourcegen.py").read())
|
||||
int_handler.close()
|
||||
reg_struct.close()
|
|
@ -1,7 +0,0 @@
|
|||
config["LOWEST_CPU"] = "arm11mpcore"
|
||||
config["ENABLE_HARD"] = get_yes_no("Enable VFP ABI", True)
|
||||
if not config["ENABLE_HARD"]:
|
||||
config["ENABLE_THUMB"] = get_yes_no("Enable Thumb")
|
||||
import sys
|
||||
sys.argv=["","kernel/mmaps/3ds11.mc"]
|
||||
from buildtools import mmapcomp
|
|
@ -1,3 +0,0 @@
|
|||
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,37 +0,0 @@
|
|||
ENTRY(_start)
|
||||
SECTIONS {
|
||||
. = 0x20401000; /*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)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
}
|
||||
kernel_end = .;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
#include "../../../hw/3ds11/picafb/picafb.hpp"
|
||||
#include "../../../hw/3ds11/vectorinit/vectorinit.hpp"
|
||||
#include <base.hpp>
|
||||
#include <config.h>
|
||||
#include "../../../mmaps/3ds11.mh"
|
||||
#include "../../../hw/pmm/pmm.hpp"
|
||||
|
||||
PICAfb term;
|
||||
PMM_MMAP lpmm;
|
||||
void main();
|
||||
extern "C" void start() { main(); }
|
||||
void drivers_init() {
|
||||
pmm=(PMM*)(&lpmm);
|
||||
setMainTTY(&term);
|
||||
--term;
|
||||
*((volatile uint32_t*)0x17E00600)=67108;
|
||||
*((volatile uint32_t*)0x17E00608)=3;
|
||||
asm volatile("CPSIE aif");
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
.arm
|
||||
.arch armv6k
|
||||
.fpu vfpv2
|
||||
.align 4
|
||||
.global _start
|
||||
.extern start
|
||||
.section .text.boot
|
||||
_start:
|
||||
CPSID aif //Disable interrupts
|
||||
ldr sp, =svc_stack
|
||||
//set other stacks
|
||||
mrs r0, cpsr
|
||||
bic r2, r0, #0x1F
|
||||
mov r1, r2
|
||||
orr r1, #0b10001 //FIQ
|
||||
msr cpsr, r1
|
||||
ldr sp, =fiq_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b10010 //IRQ
|
||||
msr cpsr, r1
|
||||
ldr sp, =irq_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b10111 //Abort
|
||||
msr cpsr, r1
|
||||
ldr sp, =abt_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b11011 //Undefined
|
||||
msr cpsr, r1
|
||||
ldr sp, =und_stack
|
||||
orr r1, #0b11111 //SYS
|
||||
msr cpsr, r1
|
||||
ldr sp, =kernel_stack
|
||||
//Enable FPU
|
||||
mov r0, #0
|
||||
mov r1, #0xF00000
|
||||
mcr p15, 0, r1, c1, c0, 2
|
||||
mcr p15, 0, r0, c7, c5, 4
|
||||
mov r1, #0x40000000
|
||||
mov r2, #0x3C00000
|
||||
fmxr fpexc, r1
|
||||
fmxr fpscr, r2
|
||||
|
||||
//Start MTGos
|
||||
blx start
|
||||
|
||||
.section .bss
|
||||
.align 16
|
||||
.space 4096
|
||||
irq_stack:
|
||||
.space 4096
|
||||
fiq_stack:
|
||||
.space 4096
|
||||
abt_stack:
|
||||
.space 4096
|
||||
und_stack:
|
||||
.space 4096
|
||||
svc_stack:
|
||||
.space 4096
|
||||
kernel_stack:
|
|
@ -1,5 +0,0 @@
|
|||
config["LOWEST_CPU"] = "arm946e-s"
|
||||
config["ENABLE_THUMB"] = get_yes_no("Enable Thumb", True)
|
||||
import sys
|
||||
sys.argv=["","kernel/mmaps/3ds9.mc"]
|
||||
from buildtools import mmapcomp
|
|
@ -1 +0,0 @@
|
|||
config["SYSTEM"] = get_from_list("System", ["3ds9","3ds11", "raspi2"])
|
|
@ -1,4 +0,0 @@
|
|||
config["LOWEST_CPU"] = "cortex-a7"
|
||||
import sys
|
||||
sys.argv=["","kernel/mmaps/raspi2.mc"]
|
||||
from buildtools import mmapcomp
|
|
@ -1,3 +0,0 @@
|
|||
SET(PLATFORM_C_FLAGS "-I../../kernel/arch/arm/3ds11/include -mcpu=cortex-a7 -mlittle-endian -mtune=cortex-a7 -mfloat-abi=hard -mtp=soft -O0")
|
||||
SET(PLATFORM_CXX_FLAGS "${PLATFORM_C_FLAGS}")
|
||||
SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}")
|
|
@ -1,37 +0,0 @@
|
|||
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)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
}
|
||||
kernel_end = .;
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
#include "../../../hw/raspi2/serial/serial.hpp"
|
||||
#include "../../../hw/raspi2/vector/vector.hpp"
|
||||
#include <base.hpp>
|
||||
#include <config.h>
|
||||
#include "../../../mmaps/raspi2.mh"
|
||||
#include "../../../hw/pmm/pmm.hpp"
|
||||
|
||||
Serial term;
|
||||
PMM_MMAP lpmm;
|
||||
void main();
|
||||
extern "C" void start() { main(); }
|
||||
void drivers_init() {
|
||||
pmm=(PMM*)(&lpmm);
|
||||
setMainTTY(&term);
|
||||
--term;
|
||||
initVectors();
|
||||
asm volatile("CPSIE aif");
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
.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, =fiq_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b10010 //IRQ
|
||||
msr cpsr, r1
|
||||
ldr sp, =irq_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b10111 //Abort
|
||||
msr cpsr, r1
|
||||
ldr sp, =abt_stack
|
||||
mov r1, r2
|
||||
orr r1, #0b11011 //Undefined
|
||||
msr cpsr, r1
|
||||
ldr sp, =und_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
|
||||
fiq_stack:
|
||||
.space 4096
|
||||
irq_stack:
|
||||
.space 4096
|
||||
abt_stack:
|
||||
.space 4096
|
||||
und_stack:
|
||||
.space 4096
|
||||
svc_stack:
|
||||
.space 16384
|
||||
kernel_stack:
|
|
@ -1,120 +0,0 @@
|
|||
int_handler.write(
|
||||
"""\
|
||||
.arm
|
||||
.fpu vfpv2
|
||||
.section .bss
|
||||
.space 4096
|
||||
exception_stack:
|
||||
.section .data
|
||||
.space 4
|
||||
oldsp:
|
||||
.section .text
|
||||
.global branch_macro
|
||||
branch_macro:
|
||||
ldr pc, [pc, #-4] //Load the next word into PC
|
||||
.macro interrupt_handler intid
|
||||
push {r0-r12,lr} //Push registers
|
||||
|
||||
//Get previous sp and lr
|
||||
mrs r1, cpsr //Current mode
|
||||
mrs r0, spsr //Previous mode
|
||||
orr r0, #0xC0 //Disable interrupts in the previous mode
|
||||
bic r0, #0x20 //enable ARM mode in there
|
||||
|
||||
//If the mode is user, switch to system mode
|
||||
and r2, r0, #0x1F
|
||||
cmp r2, #0x10
|
||||
bne 1f
|
||||
orr r0, #0x1F
|
||||
1:
|
||||
//Change mode
|
||||
msr cpsr, r0
|
||||
mov r2, sp
|
||||
mov r3, lr
|
||||
//Switch back
|
||||
msr cpsr, r1
|
||||
mrs r0, spsr
|
||||
|
||||
//Push those registers
|
||||
push {r0, r2, r3, lr}
|
||||
|
||||
//Set argument 1
|
||||
ldr r0, =\intid
|
||||
|
||||
//Jump to generic handler
|
||||
|
||||
bl intr_common_handler
|
||||
|
||||
//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#
|
||||
2:
|
||||
str lr, [sp, #0x34] //Set correct lr
|
||||
|
||||
ldmfd sp!, {r0-r12, pc}^ //Return back to original mode
|
||||
.endm
|
||||
.global data_abort
|
||||
data_abort:
|
||||
interrupt_handler 0
|
||||
.global fast_irq
|
||||
fast_irq:
|
||||
interrupt_handler 1
|
||||
.global normal_irq
|
||||
normal_irq:
|
||||
interrupt_handler 2
|
||||
.global prefetch_abort
|
||||
prefetch_abort:
|
||||
interrupt_handler 3
|
||||
.global svc_call
|
||||
svc_call:
|
||||
interrupt_handler 4
|
||||
.global undefined_op
|
||||
undefined_op:
|
||||
interrupt_handler 5
|
||||
|
||||
.extern handleINT
|
||||
intr_common_handler:
|
||||
""")
|
||||
push_regs=[]
|
||||
pop_regs=[]
|
||||
if ("ENABLE_HARD" in config) and config["ENABLE_HARD"]:
|
||||
#Save the registers
|
||||
for i,j in enumerate(["fpsid","fpscr","fpexc"]):
|
||||
push_regs.append("fmrx r"+str(i+1)+", "+j)
|
||||
pop_regs.append("fmxr "+j+", r"+str(i+1))
|
||||
push_regs.append("push {r1,r2,r3}")
|
||||
pop_regs.append("pop {r1,r2,r3}")
|
||||
push_regs.append("vpush {d0-d15}")
|
||||
pop_regs.append("vpop {d0-d15}")
|
||||
push_regs.append("mov r1, sp")
|
||||
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")
|
||||
|
||||
int_handler.write(".global panic\n.extern panic2\npanic:\n push {r0-r12,lr}\n")
|
||||
for opc in push_regs:
|
||||
int_handler.write(" "+opc+"\n")
|
||||
int_handler.write(" b panic\n")
|
||||
|
||||
reg_struct.write("#include <stdint.h>\nstruct cpu_state {\n")
|
||||
if ("ENABLE_HARD" in config) and config["ENABLE_HARD"]:
|
||||
for reg in ("d"+str(i) for i in range(16)):
|
||||
reg_struct.write(" double "+reg+";\n")
|
||||
for reg in ["fpsid","fpscr","fpexc"]:
|
||||
reg_struct.write(" uint32_t "+reg+";\n")
|
||||
for reg in ["cpsr","sp","lr","returnAddr"]:
|
||||
reg_struct.write(" uint32_t "+reg+";\n")
|
||||
for i in range(13):
|
||||
reg_struct.write(" uint32_t r"+str(i)+";\n")
|
||||
reg_struct.write(" uint32_t pc;\n};")
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
config["SYSTEM"] = get_from_list("System", ["pc"])
|
||||
if not get_yes_no("Build for generic x86"):
|
||||
config["LOWEST_CPU"] = get_from_list("Lowest supported CPU", ["486", "pentium", "pentium2", "pentium3", "pentium4"])
|
||||
else:
|
||||
config["LOWEST_CPU"] = "486"
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
SET(ISA_C_FLAGS "-m32 -I../../kernel/arch/x86/include/")
|
||||
SET(ISA_CXX_FLAGS "${ISA_C_FLAGS}")
|
||||
SET(ISA_ASM_FLAGS "${ISA_C_FLAGS}")
|
|
@ -1,42 +0,0 @@
|
|||
#include "../../hw/pc/8259/pic.hpp"
|
||||
#include <base.hpp>
|
||||
#include <regs.h>
|
||||
#include <irq.hpp>
|
||||
void print_regdump(cpu_state *state) {
|
||||
(*out << "eax: ").puti(state->eax);
|
||||
(*out << " ebx: ").puti(state->ebx);
|
||||
(*out << " ecx: ").puti(state->ecx);
|
||||
(*out << " edx: ").puti(state->edx);
|
||||
(*out << " esi: ").puti(state->esi);
|
||||
(*out << " edi: ").puti(state->edi);
|
||||
(*out << " ebp: ").puti(state->ebp);
|
||||
(*out << " eip: ").puti(state->eip);
|
||||
(*out << " esp: ").puti(state->esp);
|
||||
*out << "\n";
|
||||
}
|
||||
extern "C" void panic2(cpu_state *state);
|
||||
extern "C" cpu_state *handleINT(cpu_state *state) {
|
||||
*out << "Interrupt ";
|
||||
out->puti(state->intr);
|
||||
*out << " occurred!\n";
|
||||
cpu_state *new_cpu=state;
|
||||
if (state->intr < 32) {
|
||||
out->setColor(Color::RED);
|
||||
print_regdump(state);
|
||||
*out << "KERNEL PANIC: Unhandled CPU exception\n";
|
||||
for (;;)
|
||||
;
|
||||
} else if(state->intr < 48) {
|
||||
new_cpu=(cpu_state*)irqs->handleIRQ(new_cpu);
|
||||
}
|
||||
return new_cpu;
|
||||
}
|
||||
extern "C" void panic2(cpu_state *state) {
|
||||
state->esp = (uintptr_t)state;
|
||||
state->eip = state->intr;
|
||||
out->setColor(Color::RED);
|
||||
*out << "KERNEL PANIC: " << (char *)state->error << "\n";
|
||||
print_regdump(state);
|
||||
for (;;)
|
||||
;
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
config["ENABLE_FPU"]=get_yes_no("Enable x87 FPU", True)
|
||||
config["ENABLE_SSE"]=get_yes_no("Enable SSE")
|
|
@ -1,3 +0,0 @@
|
|||
SET(PLATFORM_C_FLAGS "-I../../kernel/arch/x86/pc/include -O2")
|
||||
SET(PLATFORM_CXX_FLAGS "${PLATFORM_C_FLAGS}")
|
||||
SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}")
|
|
@ -1,264 +0,0 @@
|
|||
/* multiboot.h - Multiboot header file. */
|
||||
/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
|
||||
* DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MULTIBOOT_HEADER
|
||||
#define MULTIBOOT_HEADER 1
|
||||
|
||||
/* How many bytes from the start of the file we search for the header. */
|
||||
#define MULTIBOOT_SEARCH 8192
|
||||
#define MULTIBOOT_HEADER_ALIGN 4
|
||||
|
||||
/* The magic field should contain this. */
|
||||
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
|
||||
|
||||
/* This should be in %eax. */
|
||||
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
|
||||
|
||||
/* Alignment of multiboot modules. */
|
||||
#define MULTIBOOT_MOD_ALIGN 0x00001000
|
||||
|
||||
/* Alignment of the multiboot info structure. */
|
||||
#define MULTIBOOT_INFO_ALIGN 0x00000004
|
||||
|
||||
/* Flags set in the 'flags' member of the multiboot header. */
|
||||
|
||||
/* Align all boot modules on i386 page (4KB) boundaries. */
|
||||
#define MULTIBOOT_PAGE_ALIGN 0x00000001
|
||||
|
||||
/* Must pass memory information to OS. */
|
||||
#define MULTIBOOT_MEMORY_INFO 0x00000002
|
||||
|
||||
/* Must pass video information to OS. */
|
||||
#define MULTIBOOT_VIDEO_MODE 0x00000004
|
||||
|
||||
/* This flag indicates the use of the address fields in the header. */
|
||||
#define MULTIBOOT_AOUT_KLUDGE 0x00010000
|
||||
|
||||
/* Flags to be set in the 'flags' member of the multiboot info structure. */
|
||||
|
||||
/* is there basic lower/upper memory information? */
|
||||
#define MULTIBOOT_INFO_MEMORY 0x00000001
|
||||
/* is there a boot device set? */
|
||||
#define MULTIBOOT_INFO_BOOTDEV 0x00000002
|
||||
/* is the command-line defined? */
|
||||
#define MULTIBOOT_INFO_CMDLINE 0x00000004
|
||||
/* are there modules to do something with? */
|
||||
#define MULTIBOOT_INFO_MODS 0x00000008
|
||||
|
||||
/* These next two are mutually exclusive */
|
||||
|
||||
/* is there a symbol table loaded? */
|
||||
#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010
|
||||
/* is there an ELF section header table? */
|
||||
#define MULTIBOOT_INFO_ELF_SHDR 0X00000020
|
||||
|
||||
/* is there a full memory map? */
|
||||
#define MULTIBOOT_INFO_MEM_MAP 0x00000040
|
||||
|
||||
/* Is there drive info? */
|
||||
#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080
|
||||
|
||||
/* Is there a config table? */
|
||||
#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100
|
||||
|
||||
/* Is there a boot loader name? */
|
||||
#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200
|
||||
|
||||
/* Is there a APM table? */
|
||||
#define MULTIBOOT_INFO_APM_TABLE 0x00000400
|
||||
|
||||
/* Is there video information? */
|
||||
#define MULTIBOOT_INFO_VBE_INFO 0x00000800
|
||||
#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000
|
||||
|
||||
#ifndef ASM_FILE
|
||||
#define multiboot_PACKED __attribute__((packed))
|
||||
typedef unsigned char multiboot_uint8_t;
|
||||
typedef unsigned short multiboot_uint16_t;
|
||||
typedef unsigned int multiboot_uint32_t;
|
||||
typedef unsigned long long multiboot_uint64_t;
|
||||
|
||||
struct multiboot_header {
|
||||
/* Must be MULTIBOOT_MAGIC - see above. */
|
||||
multiboot_uint32_t magic;
|
||||
|
||||
/* Feature flags. */
|
||||
multiboot_uint32_t flags;
|
||||
|
||||
/* The above fields plus this one must equal 0 mod 2^32. */
|
||||
multiboot_uint32_t checksum;
|
||||
|
||||
/* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */
|
||||
multiboot_uint32_t header_addr;
|
||||
multiboot_uint32_t load_addr;
|
||||
multiboot_uint32_t load_end_addr;
|
||||
multiboot_uint32_t bss_end_addr;
|
||||
multiboot_uint32_t entry_addr;
|
||||
|
||||
/* These are only valid if MULTIBOOT_VIDEO_MODE is set. */
|
||||
multiboot_uint32_t mode_type;
|
||||
multiboot_uint32_t width;
|
||||
multiboot_uint32_t height;
|
||||
multiboot_uint32_t depth;
|
||||
};
|
||||
|
||||
/* The symbol table for a.out. */
|
||||
struct multiboot_aout_symbol_table {
|
||||
multiboot_uint32_t tabsize;
|
||||
multiboot_uint32_t strsize;
|
||||
multiboot_uint32_t addr;
|
||||
multiboot_uint32_t reserved;
|
||||
};
|
||||
typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
|
||||
|
||||
/* The section header table for ELF. */
|
||||
struct multiboot_elf_section_header_table {
|
||||
multiboot_uint32_t num;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t addr;
|
||||
multiboot_uint32_t shndx;
|
||||
};
|
||||
typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
|
||||
|
||||
struct multiboot_info {
|
||||
/* Multiboot info version number */
|
||||
multiboot_uint32_t flags;
|
||||
|
||||
/* Available memory from BIOS */
|
||||
multiboot_uint32_t mem_lower;
|
||||
multiboot_uint32_t mem_upper;
|
||||
|
||||
/* "root" partition */
|
||||
multiboot_uint32_t boot_device;
|
||||
|
||||
/* Kernel command line */
|
||||
multiboot_uint32_t cmdline;
|
||||
|
||||
/* Boot-Module list */
|
||||
multiboot_uint32_t mods_count;
|
||||
multiboot_uint32_t mods_addr;
|
||||
|
||||
union {
|
||||
multiboot_aout_symbol_table_t aout_sym;
|
||||
multiboot_elf_section_header_table_t elf_sec;
|
||||
} u;
|
||||
|
||||
/* Memory Mapping buffer */
|
||||
multiboot_uint32_t mmap_length;
|
||||
multiboot_uint32_t mmap_addr;
|
||||
|
||||
/* Drive Info buffer */
|
||||
multiboot_uint32_t drives_length;
|
||||
multiboot_uint32_t drives_addr;
|
||||
|
||||
/* ROM configuration table */
|
||||
multiboot_uint32_t config_table;
|
||||
|
||||
/* Boot Loader Name */
|
||||
multiboot_uint32_t boot_loader_name;
|
||||
|
||||
/* APM table */
|
||||
multiboot_uint32_t apm_table;
|
||||
|
||||
/* Video */
|
||||
multiboot_uint32_t vbe_control_info;
|
||||
multiboot_uint32_t vbe_mode_info;
|
||||
multiboot_uint16_t vbe_mode;
|
||||
multiboot_uint16_t vbe_interface_seg;
|
||||
multiboot_uint16_t vbe_interface_off;
|
||||
multiboot_uint16_t vbe_interface_len;
|
||||
|
||||
multiboot_uint64_t framebuffer_addr;
|
||||
multiboot_uint32_t framebuffer_pitch;
|
||||
multiboot_uint32_t framebuffer_width;
|
||||
multiboot_uint32_t framebuffer_height;
|
||||
multiboot_uint8_t framebuffer_bpp;
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
|
||||
multiboot_uint8_t framebuffer_type;
|
||||
union {
|
||||
struct {
|
||||
multiboot_uint32_t framebuffer_palette_addr;
|
||||
multiboot_uint16_t framebuffer_palette_num_colors;
|
||||
};
|
||||
struct {
|
||||
multiboot_uint8_t framebuffer_red_field_position;
|
||||
multiboot_uint8_t framebuffer_red_mask_size;
|
||||
multiboot_uint8_t framebuffer_green_field_position;
|
||||
multiboot_uint8_t framebuffer_green_mask_size;
|
||||
multiboot_uint8_t framebuffer_blue_field_position;
|
||||
multiboot_uint8_t framebuffer_blue_mask_size;
|
||||
};
|
||||
};
|
||||
};
|
||||
typedef struct multiboot_info multiboot_info_t;
|
||||
|
||||
struct multiboot_color {
|
||||
multiboot_uint8_t red;
|
||||
multiboot_uint8_t green;
|
||||
multiboot_uint8_t blue;
|
||||
};
|
||||
|
||||
struct multiboot_mmap_entry {
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint64_t addr;
|
||||
multiboot_uint64_t len;
|
||||
#define MULTIBOOT_MEMORY_AVAILABLE 1
|
||||
#define MULTIBOOT_MEMORY_RESERVED 2
|
||||
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
|
||||
#define MULTIBOOT_MEMORY_NVS 4
|
||||
#define MULTIBOOT_MEMORY_BADRAM 5
|
||||
multiboot_uint32_t type;
|
||||
} multiboot_PACKED;
|
||||
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
|
||||
|
||||
struct multiboot_mod_list {
|
||||
/* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
|
||||
multiboot_uint32_t mod_start;
|
||||
multiboot_uint32_t mod_end;
|
||||
|
||||
/* Module command line */
|
||||
multiboot_uint32_t cmdline;
|
||||
|
||||
/* padding to take it to 16 bytes (must be zero) */
|
||||
multiboot_uint32_t pad;
|
||||
};
|
||||
typedef struct multiboot_mod_list multiboot_module_t;
|
||||
|
||||
/* APM BIOS info. */
|
||||
struct multiboot_apm_info {
|
||||
multiboot_uint16_t version;
|
||||
multiboot_uint16_t cseg;
|
||||
multiboot_uint32_t offset;
|
||||
multiboot_uint16_t cseg_16;
|
||||
multiboot_uint16_t dseg;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint16_t cseg_len;
|
||||
multiboot_uint16_t cseg_16_len;
|
||||
multiboot_uint16_t dseg_len;
|
||||
};
|
||||
|
||||
#endif /* ! ASM_FILE */
|
||||
|
||||
#endif /* ! MULTIBOOT_HEADER */
|
|
@ -1,37 +0,0 @@
|
|||
ENTRY(_start)
|
||||
SECTIONS {
|
||||
. = 0x100000;
|
||||
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)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
}
|
||||
kernel_end = .;
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
#include <config.h>
|
||||
#include <multiboot.h>
|
||||
#ifndef ENABLE_FRAMEBUFFER
|
||||
#include "../../../hw/pc/cgaterm/cgaterm.hpp"
|
||||
#else
|
||||
#include "../../../hw/pc/vesafb/vesafb.hpp"
|
||||
#endif
|
||||
#include "../../../hw/pc/8259/pic.hpp"
|
||||
#include "../../../hw/pc/idt/idt.hpp"
|
||||
#include "../../../hw/pc/pmm/pmm.hpp"
|
||||
|
||||
#include <base.hpp>
|
||||
static multiboot_info_t *mb_info;
|
||||
#ifndef ENABLE_FRAMEBUFFER
|
||||
CGATerm term;
|
||||
#else
|
||||
VESAfb term(mb_info);
|
||||
#endif
|
||||
PMM_MB lpmm(mb_info);
|
||||
void main();
|
||||
extern "C" void start(int eax, multiboot_info_t *ebx) {
|
||||
mb_info = ebx;
|
||||
main();
|
||||
}
|
||||
void drivers_init() {
|
||||
pmm=(PMM*)(&lpmm);
|
||||
setMainTTY(&term);
|
||||
--term;
|
||||
initIDT();
|
||||
PIC::initPIC(0x20, 0x28);
|
||||
asm volatile("sti");
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
#define ASM_FILE 1
|
||||
#include <config.h>
|
||||
#include <multiboot.h>
|
||||
.section .text.boot
|
||||
.global _start
|
||||
_start:
|
||||
jmp _start2
|
||||
.align MULTIBOOT_HEADER_ALIGN
|
||||
.int MULTIBOOT_HEADER_MAGIC
|
||||
#ifndef ENABLE_FRAMEBUFFER
|
||||
.int 0x0
|
||||
.int -(MULTIBOOT_HEADER_MAGIC)
|
||||
#else
|
||||
.int 0x7
|
||||
.int -(MULTIBOOT_HEADER_MAGIC+0x7)
|
||||
.int 0,0,0,0,0
|
||||
.int 0
|
||||
.int 1024, 768, 24
|
||||
#endif
|
||||
.align MULTIBOOT_HEADER_ALIGN
|
||||
.extern start
|
||||
_start2:
|
||||
lgdt gdtr
|
||||
mov $0x10, %cx
|
||||
mov %cx, %ds
|
||||
mov %cx, %es
|
||||
mov %cx, %fs
|
||||
mov %cx, %gs
|
||||
mov %cx, %ss
|
||||
ljmp $0x08, $_start3
|
||||
_start3:
|
||||
mov $kernel_stack, %esp //Initialize Stack
|
||||
push %ebx
|
||||
push %eax //Push arguments to start()
|
||||
#ifdef ENABLE_FPU
|
||||
finit //Enable FPU
|
||||
#endif
|
||||
#ifdef ENABLE_SSE
|
||||
//Check for SSE
|
||||
mov $1, %eax
|
||||
cpuid
|
||||
test $1<<25, %edx
|
||||
jz _noSSE
|
||||
mov %cr0, %eax
|
||||
and $0xFFFB, %ax
|
||||
or $0x2, %ax
|
||||
mov %eax, %cr0
|
||||
mov %cr4, %eax
|
||||
or $3<<9, %ax
|
||||
mov %eax, %cr4
|
||||
_noSSE:
|
||||
#endif
|
||||
call start
|
||||
_stop:
|
||||
cli
|
||||
hlt
|
||||
jmp _stop
|
||||
|
||||
|
||||
.section .data
|
||||
gdtr:
|
||||
.word 9 * 8
|
||||
.int gdt
|
||||
gdt:
|
||||
.quad 0 //NULL
|
||||
//32-bit kernel code
|
||||
.word 0xFFFF
|
||||
.word 0x0000
|
||||
.byte 0x00
|
||||
.byte 0x9A
|
||||
.byte 0xCF
|
||||
.byte 0x00
|
||||
//32-bit kernel code
|
||||
.word 0xFFFF
|
||||
.word 0x0000
|
||||
.byte 0x00
|
||||
.byte 0x92
|
||||
.byte 0xCF
|
||||
.byte 00
|
||||
//32-bit user code
|
||||
.word 0xFFFF
|
||||
.word 0x0000
|
||||
.byte 0x00
|
||||
.byte 0xFA
|
||||
.byte 0xCF
|
||||
.byte 0x00
|
||||
//32-bit user data
|
||||
.word 0xFFFF
|
||||
.word 0x0000
|
||||
.byte 0x00
|
||||
.byte 0xF2
|
||||
.byte 0xCF
|
||||
.byte 00
|
||||
//64-bit kernel code
|
||||
.word 0xFFFF
|
||||
.word 0x0000
|
||||
.byte 0x00
|
||||
.byte 0x9B
|
||||
.byte 0xAF
|
||||
.byte 0x00
|
||||
//64-bit kernel code
|
||||
.word 0xFFFF
|
||||
.word 0x0000
|
||||
.byte 0x00
|
||||
.byte 0x93
|
||||
.byte 0xCF
|
||||
.byte 00
|
||||
//64-bit user code
|
||||
.word 0xFFFF
|
||||
.word 0x0000
|
||||
.byte 0x00
|
||||
.byte 0xFB
|
||||
.byte 0xAF
|
||||
.byte 0x00
|
||||
//64-bit user data
|
||||
.word 0xFFFF
|
||||
.word 0x0000
|
||||
.byte 0x00
|
||||
.byte 0xF3
|
||||
.byte 0xCF
|
||||
.byte 00
|
||||
.section .bss
|
||||
.space 16384
|
||||
kernel_stack:
|
|
@ -1,74 +0,0 @@
|
|||
print("Writing interrupt stubs")
|
||||
int_handler.write(".macro intr_stub nr\n.global intr_stub_\\nr\n.align 16\nintr_stub_\\nr:\n pushl $0\n pushl $\\nr\n jmp intr_common_handler\n.endm\n.macro intr_stub_error_code nr\n.global intr_stub_\\nr\n.align 16\nintr_stub_\\nr:\n pushl $\\nr\n jmp intr_common_handler\n.endm\n")
|
||||
for i in range(256):
|
||||
if i in [8,10,11,12,13,14,17]:
|
||||
int_handler.write("intr_stub_error_code "+str(i)+"\n")
|
||||
else:
|
||||
int_handler.write("intr_stub "+str(i)+"\n")
|
||||
|
||||
int_handler.write(".extern handleINT\n")
|
||||
int_handler.write("intr_common_handler:\n")
|
||||
int_handler.write(" cli\n")
|
||||
print("Generating register save/restore")
|
||||
all_regs_push=[]
|
||||
all_regs_pop=[]
|
||||
data_section=""
|
||||
for reg in ["ebp","edi","esi","edx","ecx","ebx","eax"]:
|
||||
all_regs_push.append("push %"+reg)
|
||||
all_regs_pop.append("pop %"+reg)
|
||||
if config["ENABLE_FPU"] and not config["ENABLE_SSE"]:
|
||||
data_section+="fsave_reg:\n .space 108\n"
|
||||
all_regs_push.append("fsave fsave_reg")
|
||||
all_regs_pop.append("frstor fsave_reg")
|
||||
all_regs_push.append("pushl $fsave_reg")
|
||||
if config["ENABLE_SSE"]:
|
||||
data_section+=".align 16\nfxsave_reg:\n .space 512"
|
||||
all_regs_push.append("fxsave fxsave_reg")
|
||||
all_regs_pop.append("fxrstor (%eax)")
|
||||
all_regs_pop.append("pop %eax")
|
||||
all_regs_push.append("pushl $fxsave_reg")
|
||||
|
||||
print("Writing interrupt handler")
|
||||
for ins in all_regs_push:
|
||||
int_handler.write(" "+ins+"\n")
|
||||
int_handler.write(" push %esp\n call handleINT\n mov %eax, %esp\n")
|
||||
for ins in reversed(all_regs_pop):
|
||||
int_handler.write(" "+ins+"\n")
|
||||
int_handler.write(" add $8, %esp\n iret\n")
|
||||
|
||||
print("Writing panic handler")
|
||||
int_handler.write(".global panic\n.extern panic2\npanic:\n")
|
||||
for ins in all_regs_push:
|
||||
int_handler.write(" "+ins+"\n")
|
||||
int_handler.write(" push %esp\n jmp panic2\n")
|
||||
|
||||
int_handler.write(".section .data\n"+data_section)
|
||||
|
||||
print("Generating cpu_state struct")
|
||||
reg_struct.write("#include <stdint.h>\n")
|
||||
if config["ENABLE_FPU"] and not config["ENABLE_SSE"]:
|
||||
reg_struct.write("struct fpu_state {\n")
|
||||
for reg in ["cwd","swd","twd","fip","fcs","foo","fos"]:
|
||||
reg_struct.write(" uint32_t "+reg+";\n")
|
||||
for reg in ("st"+str(i) for i in range(8)):
|
||||
reg_struct.write(" __float80 "+reg+";\n")
|
||||
reg_struct.write("}__attribute__((packed,aligned(16)));\n")
|
||||
if config["ENABLE_SSE"]:
|
||||
reg_struct.write("struct fpu_state {\n")
|
||||
for reg in ["cwd","swd","twd","fop"]:
|
||||
reg_struct.write(" uint16_t "+reg+";\n")
|
||||
for reg in ["fip","fcs","foo","fos","mxcsr","mxcsr_mask"]:
|
||||
reg_struct.write(" uint32_t "+reg+";\n")
|
||||
for reg in range(8):
|
||||
reg_struct.write(" __float80 st"+str(reg)+";\n")
|
||||
reg_struct.write(" char buf"+str(reg)+"[6];\n")
|
||||
for reg in range(16):
|
||||
reg_struct.write(" __float128 xmm"+str(reg)+";\n")
|
||||
reg_struct.write("}__attribute__((packed,aligned(16)));\n")
|
||||
reg_struct.write("struct cpu_state {\n")
|
||||
if config["ENABLE_FPU"]:
|
||||
reg_struct.write(" fpu_state *fpu;\n")
|
||||
for reg in ["eax","ebx","ecx","edx","esi","edi","ebp","intr","error","eip","cs","eflags","esp","ss"]:
|
||||
reg_struct.write(" uint32_t "+reg+";\n")
|
||||
reg_struct.write("}__attribute__((packed));")
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
config["SYSTEM"] = get_from_list("System", ["pc"])
|
||||
if not get_yes_no("Build for generic x86_64"):
|
||||
config["LOWEST_CPU"] = get_from_list("Lowest supported CPU", ["pentium4", "core2", "nehalem", "westmere", "sandybridge", "ivybridge", "haswell", "broadwell", "skylake", "kabylake"])
|
||||
else:
|
||||
config["LOWEST_CPU"] = "pentium4"
|
|
@ -1,3 +0,0 @@
|
|||
SET(ISA_C_FLAGS "-m64 -I../../kernel/arch/x86_64/include/")
|
||||
SET(ISA_CXX_FLAGS "${ISA_C_FLAGS}")
|
||||
SET(ISA_ASM_FLAGS "${ISA_ASM_FLAGS}")
|
|
@ -1,49 +0,0 @@
|
|||
#include "../../hw/pc/8259/pic.hpp"
|
||||
#include <base.hpp>
|
||||
#include <regs.h>
|
||||
void print_regdump(cpu_state *state) {
|
||||
(*out << "rax: ").puti(state->rax);
|
||||
(*out << " rbx: ").puti(state->rbx);
|
||||
(*out << " rcx: ").puti(state->rcx);
|
||||
(*out << " rdx: ").puti(state->rdx);
|
||||
(*out << " rsi: ").puti(state->rsi);
|
||||
(*out << " rdi: ").puti(state->rdi);
|
||||
(*out << " rbp: ").puti(state->rbp);
|
||||
(*out << " rip: ").puti(state->rip);
|
||||
(*out << " rsp: ").puti(state->rsp);
|
||||
(*out << " r8: ").puti(state->r8);
|
||||
(*out << " r9: ").puti(state->r9);
|
||||
(*out << " r10: ").puti(state->r10);
|
||||
(*out << " r11: ").puti(state->r11);
|
||||
(*out << " r12: ").puti(state->r12);
|
||||
(*out << " r13: ").puti(state->r13);
|
||||
(*out << " r14: ").puti(state->r14);
|
||||
(*out << " r15: ").puti(state->r15);
|
||||
*out << "\n";
|
||||
}
|
||||
extern "C" void panic2(cpu_state *state);
|
||||
extern "C" cpu_state *handleINT(cpu_state *state) {
|
||||
*out << "Interrupt ";
|
||||
out->puti(state->intr);
|
||||
*out << " occurred!\n";
|
||||
cpu_state *new_cpu=state;
|
||||
if (state->intr < 32) {
|
||||
out->setColor(Color::RED);
|
||||
print_regdump(state);
|
||||
*out << "KERNEL PANIC: Unhandled CPU exception\n";
|
||||
for (;;)
|
||||
;
|
||||
} else if(state->intr < 48) {
|
||||
new_cpu=(cpu_state*)irqs->handleIRQ(new_cpu);
|
||||
}
|
||||
return new_cpu;
|
||||
}
|
||||
extern "C" void panic2(cpu_state *state) {
|
||||
state->rsp = (uintptr_t)state;
|
||||
state->rip = state->intr;
|
||||
out->setColor(Color::RED);
|
||||
*out << "KERNEL PANIC: " << (char *)state->rdi << "\n";
|
||||
print_regdump(state);
|
||||
for (;;)
|
||||
;
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
config["ENABLE_FPU"] = True
|
||||
config["ENABLE_SSE"] = get_yes_no("Enable FPU", True)
|
|
@ -1,3 +0,0 @@
|
|||
SET(PLATFORM_C_FLAGS "-I../../kernel/arch/x86_64/pc/include -O0")
|
||||
SET(PLATFORM_CXX_FLAGS "${PLATFORM_C_FLAGS}")
|
||||
SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}")
|
|
@ -1,264 +0,0 @@
|
|||
/* multiboot.h - Multiboot header file. */
|
||||
/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
|
||||
* DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MULTIBOOT_HEADER
|
||||
#define MULTIBOOT_HEADER 1
|
||||
|
||||
/* How many bytes from the start of the file we search for the header. */
|
||||
#define MULTIBOOT_SEARCH 8192
|
||||
#define MULTIBOOT_HEADER_ALIGN 4
|
||||
|
||||
/* The magic field should contain this. */
|
||||
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
|
||||
|
||||
/* This should be in %eax. */
|
||||
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
|
||||
|
||||
/* Alignment of multiboot modules. */
|
||||
#define MULTIBOOT_MOD_ALIGN 0x00001000
|
||||
|
||||
/* Alignment of the multiboot info structure. */
|
||||
#define MULTIBOOT_INFO_ALIGN 0x00000004
|
||||
|
||||
/* Flags set in the 'flags' member of the multiboot header. */
|
||||
|
||||
/* Align all boot modules on i386 page (4KB) boundaries. */
|
||||
#define MULTIBOOT_PAGE_ALIGN 0x00000001
|
||||
|
||||
/* Must pass memory information to OS. */
|
||||
#define MULTIBOOT_MEMORY_INFO 0x00000002
|
||||
|
||||
/* Must pass video information to OS. */
|
||||
#define MULTIBOOT_VIDEO_MODE 0x00000004
|
||||
|
||||
/* This flag indicates the use of the address fields in the header. */
|
||||
#define MULTIBOOT_AOUT_KLUDGE 0x00010000
|
||||
|
||||
/* Flags to be set in the 'flags' member of the multiboot info structure. */
|
||||
|
||||
/* is there basic lower/upper memory information? */
|
||||
#define MULTIBOOT_INFO_MEMORY 0x00000001
|
||||
/* is there a boot device set? */
|
||||
#define MULTIBOOT_INFO_BOOTDEV 0x00000002
|
||||
/* is the command-line defined? */
|
||||
#define MULTIBOOT_INFO_CMDLINE 0x00000004
|
||||
/* are there modules to do something with? */
|
||||
#define MULTIBOOT_INFO_MODS 0x00000008
|
||||
|
||||
/* These next two are mutually exclusive */
|
||||
|
||||
/* is there a symbol table loaded? */
|
||||
#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010
|
||||
/* is there an ELF section header table? */
|
||||
#define MULTIBOOT_INFO_ELF_SHDR 0X00000020
|
||||
|
||||
/* is there a full memory map? */
|
||||
#define MULTIBOOT_INFO_MEM_MAP 0x00000040
|
||||
|
||||
/* Is there drive info? */
|
||||
#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080
|
||||
|
||||
/* Is there a config table? */
|
||||
#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100
|
||||
|
||||
/* Is there a boot loader name? */
|
||||
#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200
|
||||
|
||||
/* Is there a APM table? */
|
||||
#define MULTIBOOT_INFO_APM_TABLE 0x00000400
|
||||
|
||||
/* Is there video information? */
|
||||
#define MULTIBOOT_INFO_VBE_INFO 0x00000800
|
||||
#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000
|
||||
|
||||
#ifndef ASM_FILE
|
||||
#define multiboot_PACKED __attribute__((packed))
|
||||
typedef unsigned char multiboot_uint8_t;
|
||||
typedef unsigned short multiboot_uint16_t;
|
||||
typedef unsigned int multiboot_uint32_t;
|
||||
typedef unsigned long long multiboot_uint64_t;
|
||||
|
||||
struct multiboot_header {
|
||||
/* Must be MULTIBOOT_MAGIC - see above. */
|
||||
multiboot_uint32_t magic;
|
||||
|
||||
/* Feature flags. */
|
||||
multiboot_uint32_t flags;
|
||||
|
||||
/* The above fields plus this one must equal 0 mod 2^32. */
|
||||
multiboot_uint32_t checksum;
|
||||
|
||||
/* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */
|
||||
multiboot_uint32_t header_addr;
|
||||
multiboot_uint32_t load_addr;
|
||||
multiboot_uint32_t load_end_addr;
|
||||
multiboot_uint32_t bss_end_addr;
|
||||
multiboot_uint32_t entry_addr;
|
||||
|
||||
/* These are only valid if MULTIBOOT_VIDEO_MODE is set. */
|
||||
multiboot_uint32_t mode_type;
|
||||
multiboot_uint32_t width;
|
||||
multiboot_uint32_t height;
|
||||
multiboot_uint32_t depth;
|
||||
};
|
||||
|
||||
/* The symbol table for a.out. */
|
||||
struct multiboot_aout_symbol_table {
|
||||
multiboot_uint32_t tabsize;
|
||||
multiboot_uint32_t strsize;
|
||||
multiboot_uint32_t addr;
|
||||
multiboot_uint32_t reserved;
|
||||
};
|
||||
typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
|
||||
|
||||
/* The section header table for ELF. */
|
||||
struct multiboot_elf_section_header_table {
|
||||
multiboot_uint32_t num;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t addr;
|
||||
multiboot_uint32_t shndx;
|
||||
};
|
||||
typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
|
||||
|
||||
struct multiboot_info {
|
||||
/* Multiboot info version number */
|
||||
multiboot_uint32_t flags;
|
||||
|
||||
/* Available memory from BIOS */
|
||||
multiboot_uint32_t mem_lower;
|
||||
multiboot_uint32_t mem_upper;
|
||||
|
||||
/* "root" partition */
|
||||
multiboot_uint32_t boot_device;
|
||||
|
||||
/* Kernel command line */
|
||||
multiboot_uint32_t cmdline;
|
||||
|
||||
/* Boot-Module list */
|
||||
multiboot_uint32_t mods_count;
|
||||
multiboot_uint32_t mods_addr;
|
||||
|
||||
union {
|
||||
multiboot_aout_symbol_table_t aout_sym;
|
||||
multiboot_elf_section_header_table_t elf_sec;
|
||||
} u;
|
||||
|
||||
/* Memory Mapping buffer */
|
||||
multiboot_uint32_t mmap_length;
|
||||
multiboot_uint32_t mmap_addr;
|
||||
|
||||
/* Drive Info buffer */
|
||||
multiboot_uint32_t drives_length;
|
||||
multiboot_uint32_t drives_addr;
|
||||
|
||||
/* ROM configuration table */
|
||||
multiboot_uint32_t config_table;
|
||||
|
||||
/* Boot Loader Name */
|
||||
multiboot_uint32_t boot_loader_name;
|
||||
|
||||
/* APM table */
|
||||
multiboot_uint32_t apm_table;
|
||||
|
||||
/* Video */
|
||||
multiboot_uint32_t vbe_control_info;
|
||||
multiboot_uint32_t vbe_mode_info;
|
||||
multiboot_uint16_t vbe_mode;
|
||||
multiboot_uint16_t vbe_interface_seg;
|
||||
multiboot_uint16_t vbe_interface_off;
|
||||
multiboot_uint16_t vbe_interface_len;
|
||||
|
||||
multiboot_uint64_t framebuffer_addr;
|
||||
multiboot_uint32_t framebuffer_pitch;
|
||||
multiboot_uint32_t framebuffer_width;
|
||||
multiboot_uint32_t framebuffer_height;
|
||||
multiboot_uint8_t framebuffer_bpp;
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
|
||||
multiboot_uint8_t framebuffer_type;
|
||||
union {
|
||||
struct {
|
||||
multiboot_uint32_t framebuffer_palette_addr;
|
||||
multiboot_uint16_t framebuffer_palette_num_colors;
|
||||
};
|
||||
struct {
|
||||
multiboot_uint8_t framebuffer_red_field_position;
|
||||
multiboot_uint8_t framebuffer_red_mask_size;
|
||||
multiboot_uint8_t framebuffer_green_field_position;
|
||||
multiboot_uint8_t framebuffer_green_mask_size;
|
||||
multiboot_uint8_t framebuffer_blue_field_position;
|
||||
multiboot_uint8_t framebuffer_blue_mask_size;
|
||||
};
|
||||
};
|
||||
};
|
||||
typedef struct multiboot_info multiboot_info_t;
|
||||
|
||||
struct multiboot_color {
|
||||
multiboot_uint8_t red;
|
||||
multiboot_uint8_t green;
|
||||
multiboot_uint8_t blue;
|
||||
};
|
||||
|
||||
struct multiboot_mmap_entry {
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint64_t addr;
|
||||
multiboot_uint64_t len;
|
||||
#define MULTIBOOT_MEMORY_AVAILABLE 1
|
||||
#define MULTIBOOT_MEMORY_RESERVED 2
|
||||
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
|
||||
#define MULTIBOOT_MEMORY_NVS 4
|
||||
#define MULTIBOOT_MEMORY_BADRAM 5
|
||||
multiboot_uint32_t type;
|
||||
} multiboot_PACKED;
|
||||
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
|
||||
|
||||
struct multiboot_mod_list {
|
||||
/* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
|
||||
multiboot_uint32_t mod_start;
|
||||
multiboot_uint32_t mod_end;
|
||||
|
||||
/* Module command line */
|
||||
multiboot_uint32_t cmdline;
|
||||
|
||||
/* padding to take it to 16 bytes (must be zero) */
|
||||
multiboot_uint32_t pad;
|
||||
};
|
||||
typedef struct multiboot_mod_list multiboot_module_t;
|
||||
|
||||
/* APM BIOS info. */
|
||||
struct multiboot_apm_info {
|
||||
multiboot_uint16_t version;
|
||||
multiboot_uint16_t cseg;
|
||||
multiboot_uint32_t offset;
|
||||
multiboot_uint16_t cseg_16;
|
||||
multiboot_uint16_t dseg;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint16_t cseg_len;
|
||||
multiboot_uint16_t cseg_16_len;
|
||||
multiboot_uint16_t dseg_len;
|
||||
};
|
||||
|
||||
#endif /* ! ASM_FILE */
|
||||
|
||||
#endif /* ! MULTIBOOT_HEADER */
|
|
@ -1,37 +0,0 @@
|
|||
ENTRY(_start)
|
||||
SECTIONS {
|
||||
. = 0x200000;
|
||||
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)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
}
|
||||
kernel_end = .;
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
#include <config.h>
|
||||
#include <multiboot.h>
|
||||
#ifndef ENABLE_FRAMEBUFFER
|
||||
#include "../../../hw/pc/cgaterm/cgaterm.hpp"
|
||||
#else
|
||||
#include "../../../hw/pc/vesafb/vesafb.hpp"
|
||||
#endif
|
||||
#include "../../../hw/pc/8259/pic.hpp"
|
||||
#include "../../../hw/pc/idt/idt.hpp"
|
||||
#include "../../../hw/pc/pmm/pmm.hpp"
|
||||
|
||||
#include <base.hpp>
|
||||
static multiboot_info_t *mb_info;
|
||||
#ifndef ENABLE_FRAMEBUFFER
|
||||
CGATerm term;
|
||||
#else
|
||||
VESAfb term(mb_info);
|
||||
#endif
|
||||
PMM_MB lpmm(mb_info);
|
||||
void main();
|
||||
extern "C" void start(int eax, multiboot_info_t *ebx) {
|
||||
mb_info = ebx;
|
||||
main();
|
||||
}
|
||||
void drivers_init() {
|
||||
pmm=(PMM*)(&lpmm);
|
||||
setMainTTY(&term);
|
||||
--term;
|
||||
initIDT();
|
||||
PIC::initPIC(0x20, 0x28);
|
||||
asm volatile("sti");
|
||||
}
|
|
@ -1,181 +0,0 @@
|
|||
#define ASM_FILE 1
|
||||
#include <config.h>
|
||||
#include <multiboot.h>
|
||||
.code32
|
||||
.section .text.boot
|
||||
.global _start
|
||||
_start:
|
||||
jmp _start2
|
||||
.align MULTIBOOT_HEADER_ALIGN
|
||||
.int MULTIBOOT_HEADER_MAGIC
|
||||
#ifndef ENABLE_FRAMEBUFFER
|
||||
.int 0x0
|
||||
.int -(MULTIBOOT_HEADER_MAGIC)
|
||||
#else
|
||||
.int 0x7
|
||||
.int -(MULTIBOOT_HEADER_MAGIC+0x7)
|
||||
.int 0,0,0,0,0
|
||||
.int 0
|
||||
.int 1024, 768, 24
|
||||
#endif
|
||||
.align MULTIBOOT_HEADER_ALIGN
|
||||
.extern start
|
||||
_start2:
|
||||
mov $mb_ptr, %edi
|
||||
stosl
|
||||
mov %ebx, %eax
|
||||
stosl // Store mb stuff
|
||||
|
||||
#ifdef ENABLE_FPU
|
||||
finit //Enable FPU
|
||||
#endif
|
||||
#ifdef ENABLE_SSE
|
||||
//No check for SSE as SSE2+ is always present on x86_64
|
||||
mov %cr0, %eax
|
||||
and $0xFFFB, %ax
|
||||
or $0x2, %ax
|
||||
mov %eax, %cr0
|
||||
mov %cr4, %eax
|
||||
or $3<<9, %ax
|
||||
mov %eax, %cr4
|
||||
#endif
|
||||
mov $kernel_stack, %esp
|
||||
mov $0x80000001, %eax
|
||||
cpuid
|
||||
and $0x20000000, %edx //Check if long mode is supported
|
||||
jz x86_64_err
|
||||
jmp x86_64_OK
|
||||
x86_64_err:
|
||||
cli
|
||||
hlt
|
||||
jmp x86_64_err
|
||||
x86_64_OK:
|
||||
//Assume PAE is supported
|
||||
mov $pmfill, %esi
|
||||
mov $pagemapL4, %edi
|
||||
movsl
|
||||
movsl
|
||||
mov $pagedirPT, %edi
|
||||
mov $0x87, %eax
|
||||
xor %ebx, %ebx
|
||||
mov $1023, %ecx
|
||||
.ptloop:
|
||||
stosl
|
||||
xchg %eax, %ebx
|
||||
stosl
|
||||
xchg %eax, %ebx
|
||||
add $0x40000000, %eax
|
||||
jnc .ptloop_nc
|
||||
inc %ebx
|
||||
.ptloop_nc:
|
||||
loop .ptloop
|
||||
mov %cr4, %eax
|
||||
or $0x20, %eax
|
||||
mov %eax, %cr4 //Activate PAE
|
||||
mov $0xC0000080, %ecx
|
||||
rdmsr
|
||||
or $0x00000100, %eax
|
||||
wrmsr //Activate x86_64
|
||||
mov $pagemapL4, %eax
|
||||
mov %eax, %cr3 //Load page table
|
||||
mov %cr0, %eax
|
||||
bswap %eax
|
||||
or $0x80, %eax
|
||||
bswap %eax
|
||||
mov %eax, %cr0 //Activate paging
|
||||
lgdt gdtr
|
||||
mov $0x30, %ax
|
||||
ljmp $0x28, $_start3 //Jump into long mode
|
||||
.code64
|
||||
_start3:
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
mov %ax, %ss //Load 64-bit data
|
||||
mov $mb_ptr, %rsi
|
||||
lodsl
|
||||
mov %rax, %rdi
|
||||
lodsl
|
||||
mov %rax, %rsi
|
||||
call start
|
||||
_stop:
|
||||
cli
|
||||
hlt
|
||||
jmp _stop
|
||||
|
||||
|
||||
.section .data
|
||||
gdtr:
|
||||
.word 9 * 8
|
||||
.int gdt
|
||||
gdt:
|
||||
.quad 0 //NULL
|
||||
//32-bit kernel code
|
||||
.word 0xFFFF
|
||||
.word 0x0000
|
||||
.byte 0x00
|
||||
.byte 0x9A
|
||||
.byte 0xCF
|
||||
.byte 0x00
|
||||
//32-bit kernel code
|
||||
.word 0xFFFF
|
||||
.word 0x0000
|
||||
.byte 0x00
|
||||
.byte 0x92
|
||||
.byte 0xCF
|
||||
.byte 00
|
||||
//32-bit user code
|
||||
.word 0xFFFF
|
||||
.word 0x0000
|
||||
.byte 0x00
|
||||
.byte 0xFA
|
||||
.byte 0xCF
|
||||
.byte 0x00
|
||||
//32-bit user data
|
||||
.word 0xFFFF
|
||||
.word 0x0000
|
||||
.byte 0x00
|
||||
.byte 0xF2
|
||||
.byte 0xCF
|
||||
.byte 00
|
||||
//64-bit kernel code
|
||||
.word 0xFFFF
|
||||
.word 0x0000
|
||||
.byte 0x00
|
||||
.byte 0x9B
|
||||
.byte 0xAF
|
||||
.byte 0x00
|
||||
//64-bit kernel code
|
||||
.word 0xFFFF
|
||||
.word 0x0000
|
||||
.byte 0x00
|
||||
.byte 0x93
|
||||
.byte 0xCF
|
||||
.byte 00
|
||||
//64-bit user code
|
||||
.word 0xFFFF
|
||||
.word 0x0000
|
||||
.byte 0x00
|
||||
.byte 0xFB
|
||||
.byte 0xAF
|
||||
.byte 0x00
|
||||
//64-bit user data
|
||||
.word 0xFFFF
|
||||
.word 0x0000
|
||||
.byte 0x00
|
||||
.byte 0xF3
|
||||
.byte 0xCF
|
||||
.byte 00
|
||||
pmfill:
|
||||
.int pagedirPT + 0x7
|
||||
.int 0
|
||||
.section .bss
|
||||
mb_ptr:
|
||||
.space 16384
|
||||
kernel_stack:
|
||||
.align 4096
|
||||
pagemapL4:
|
||||
.space 4096
|
||||
pagedirPT:
|
||||
.space 4096
|
|
@ -1,74 +0,0 @@
|
|||
print("Writing interrupt stubs")
|
||||
int_handler.write(".macro intr_stub nr\n.global intr_stub_\\nr\n.align 16\nintr_stub_\\nr:\n pushq $0\n pushq $\\nr\n jmp intr_common_handler\n.endm\n.macro intr_stub_error_code nr\n.global intr_stub_\\nr\n.align 16\nintr_stub_\\nr:\n pushq $\\nr\n jmp intr_common_handler\n.endm\n")
|
||||
for i in range(256):
|
||||
if i in [8,10,11,12,13,14,17]:
|
||||
int_handler.write("intr_stub_error_code "+str(i)+"\n")
|
||||
else:
|
||||
int_handler.write("intr_stub "+str(i)+"\n")
|
||||
|
||||
int_handler.write(".extern handleINT\n")
|
||||
int_handler.write("intr_common_handler:\n")
|
||||
int_handler.write(" cli\n")
|
||||
print("Generating register save/restore")
|
||||
all_regs_push=[]
|
||||
all_regs_pop=[]
|
||||
data_section=""
|
||||
for reg in ["r15","r14","r13","r12","r11","r10","r9","r8","rbp","rdi","rsi","rdx","rcx","rbx","rax"]:
|
||||
all_regs_push.append("push %"+reg)
|
||||
all_regs_pop.append("pop %"+reg)
|
||||
if config["ENABLE_FPU"] and not config["ENABLE_SSE"]:
|
||||
data_section+="fsave_reg:\n .space 108\n"
|
||||
all_regs_push.append("fsave fsave_reg")
|
||||
all_regs_pop.append("frstor fsave_reg")
|
||||
all_regs_push.append("pushq $fsave_reg")
|
||||
if config["ENABLE_SSE"]:
|
||||
data_section+=".align 16\nfxsave_reg:\n .space 512"
|
||||
all_regs_push.append("fxsave fxsave_reg")
|
||||
all_regs_pop.append("fxrstor (%rax)")
|
||||
all_regs_pop.append("pop %rax")
|
||||
all_regs_push.append("pushq $fxsave_reg")
|
||||
|
||||
print("Writing interrupt handler")
|
||||
for ins in all_regs_push:
|
||||
int_handler.write(" "+ins+"\n")
|
||||
int_handler.write(" mov %rsp, %rdi\n call handleINT\n mov %rax, %rsp\n")
|
||||
for ins in reversed(all_regs_pop):
|
||||
int_handler.write(" "+ins+"\n")
|
||||
int_handler.write(" add $16, %rsp\n iretq\n")
|
||||
|
||||
print("Writing panic handler")
|
||||
int_handler.write(".global panic\n.extern panic2\npanic:\n")
|
||||
for ins in all_regs_push:
|
||||
int_handler.write(" "+ins+"\n")
|
||||
int_handler.write(" mov %rsp, %rdi\n jmp panic2\n")
|
||||
|
||||
int_handler.write(".section .data\n"+data_section)
|
||||
|
||||
print("Generating cpu_state struct")
|
||||
reg_struct.write("#include <stdint.h>\n")
|
||||
if config["ENABLE_FPU"] and not config["ENABLE_SSE"]:
|
||||
reg_struct.write("struct fpu_state {\n")
|
||||
for reg in ["cwd","swd","twd","fip","fcs","foo","fos"]:
|
||||
reg_struct.write(" uint32_t "+reg+";\n")
|
||||
for reg in ("st"+str(i) for i in range(8)):
|
||||
reg_struct.write(" __float80 "+reg+";\n")
|
||||
reg_struct.write("}__attribute__((packed,aligned(16)));\n")
|
||||
if config["ENABLE_SSE"]:
|
||||
reg_struct.write("struct fpu_state {\n")
|
||||
for reg in ["cwd","swd","twd","fop"]:
|
||||
reg_struct.write(" uint16_t "+reg+";\n")
|
||||
for reg in ["fip","fcs","foo","fos","mxcsr","mxcsr_mask"]:
|
||||
reg_struct.write(" uint32_t "+reg+";\n")
|
||||
for reg in range(8):
|
||||
reg_struct.write(" __float80 st"+str(reg)+";\n")
|
||||
reg_struct.write(" char buf"+str(reg)+"[6];\n")
|
||||
for reg in range(16):
|
||||
reg_struct.write(" __float128 xmm"+str(reg)+";\n")
|
||||
reg_struct.write("}__attribute__((packed,aligned(16)));\n")
|
||||
reg_struct.write("struct cpu_state {\n")
|
||||
if config["ENABLE_FPU"]:
|
||||
reg_struct.write(" fpu_state *fpu;\n")
|
||||
for reg in ["rax","rbx","rcx","rdx","rsi","rdi","rbp","r8","r9","r10","r11","r12","r13","r14","r15","intr","error","rip","cs","rflags","rsp","ss"]:
|
||||
reg_struct.write(" uint64_t "+reg+";\n")
|
||||
reg_struct.write("}__attribute__((packed));")
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
config["ENABLE_N3DS_OVERCLOCK"] = get_yes_no("Enable overclocking on n3ds", True)
|
||||
config["ENABLE_I2C"] = get_yes_no("Enable i2c driver", True)
|
||||
if config["ENABLE_I2C"]:
|
||||
config["PROTECT_MCU"] = get_yes_no("Prevent writes to MCU firmware (Device 3, Register 5)", True)
|
||||
config["ENABLE_SCREENINIT"] = get_yes_no("Enable screeninit.", True)
|
||||
add_driver(False, "i2c")
|
||||
add_driver(False, "mcu")
|
||||
add_driver(True, "framebuffer")
|
||||
add_driver(False, "picafb")
|
||||
add_driver(False, "vectorinit")
|
||||
add_driver(True, "pmm")
|
||||
print("Enable complete Unicode font: NO (because of the size)")
|
||||
config["ENABLE_FRAMEBUFFER_UNICODE"] = False
|
|
@ -1,66 +0,0 @@
|
|||
#include "i2c.hpp"
|
||||
struct I2CBus {
|
||||
volatile uint8_t data;
|
||||
volatile uint8_t ctl;
|
||||
uint16_t cntex;
|
||||
uint16_t scl;
|
||||
} __attribute__((packed));
|
||||
I2CBus *buses[] = {(I2CBus *)0x10161000, (I2CBus *)0x10144000, (I2CBus *)0x10148000};
|
||||
I2C::I2C() {}
|
||||
I2C::~I2C() {}
|
||||
auto I2C::waitBusy() -> void {
|
||||
while (buses[busID]->ctl & 0x80)
|
||||
;
|
||||
}
|
||||
auto I2C::getResult() -> bool {
|
||||
waitBusy();
|
||||
return buses[busID]->ctl & 0x10;
|
||||
}
|
||||
auto I2C::stop() -> bool {
|
||||
buses[busID]->ctl = 0xC0;
|
||||
waitBusy();
|
||||
buses[busID]->ctl = 0xC5;
|
||||
}
|
||||
auto I2C::selectDev(int dev) -> bool {
|
||||
static int buss[] = {1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 2, 1, 3};
|
||||
static int addr[] = {0x4a, 0x7a, 0x78, 0x4a, 0x78, 0x2C, 0x2E, 0x40, 0x44,
|
||||
0xA6, 0xD0, 0xD2, 0xA4, 0x9A, 0xA0, 0xEE, 0x40, 0x54};
|
||||
currDev = dev;
|
||||
busID = buss[dev];
|
||||
waitBusy();
|
||||
buses[busID]->data = addr[dev];
|
||||
buses[busID]->ctl = 0xC2;
|
||||
return getResult();
|
||||
}
|
||||
auto I2C::selectReg(int reg) -> bool {
|
||||
#ifdef PROTECT_MCU
|
||||
if ((currReg == 3) && (reg == 5)) return false;
|
||||
#endif
|
||||
currReg = reg;
|
||||
waitBusy();
|
||||
buses[busID]->data = (uint8_t)reg;
|
||||
buses[busID]->ctl = 0xC0;
|
||||
return getResult();
|
||||
}
|
||||
auto I2C::write(uint8_t data) -> bool {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
waitBusy();
|
||||
buses[busID]->data = data;
|
||||
buses[busID]->ctl = 0xC1;
|
||||
if (getResult()) { return true; }
|
||||
stop();
|
||||
selectDev(currDev);
|
||||
selectReg(currReg);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
auto I2C::read() -> uint8_t {
|
||||
waitBusy();
|
||||
buses[busID]->ctl = 0xE1;
|
||||
waitBusy();
|
||||
uint8_t data = buses[busID]->data;
|
||||
buses[busID]->ctl |= 0x10;
|
||||
getResult();
|
||||
stop();
|
||||
return data;
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
#pragma once
|
||||
#include <config.h>
|
||||
#include <stdint.h>
|
||||
/**
|
||||
* I2C class for the 3DS
|
||||
*/
|
||||
class I2C {
|
||||
private:
|
||||
int currDev;
|
||||
int currReg;
|
||||
int busID;
|
||||
|
||||
public:
|
||||
I2C();
|
||||
~I2C();
|
||||
auto waitBusy() -> void; ///< Waits for the currently selected device to finish
|
||||
auto getResult() -> bool; ///< Returns true when the device sent a ACK
|
||||
auto stop() -> bool; ///< Stops the current transfer
|
||||
auto selectDev(int dev) -> bool; ///< Selects current I2C device
|
||||
auto selectReg(int reg) -> bool; ///< Selects current register
|
||||
auto write(uint8_t data) -> bool; ///< Sends 8 bits of data
|
||||
auto read() -> uint8_t; ///< Receives 8 bits of data
|
||||
};
|
|
@ -1,62 +0,0 @@
|
|||
#include "mcu.hpp"
|
||||
namespace MCU {
|
||||
I2C access;
|
||||
uint8_t HIDStatus;
|
||||
static auto read(int reg) -> unsigned char {
|
||||
access.selectDev(3);
|
||||
access.selectReg(reg);
|
||||
return access.read();
|
||||
}
|
||||
static auto write(int reg, uint8_t value) -> void {
|
||||
access.selectDev(3);
|
||||
access.selectReg(reg);
|
||||
access.write(value);
|
||||
}
|
||||
auto getVersionLo() -> unsigned char { return read(0); }
|
||||
auto getVersionHi() -> unsigned char { return read(1); }
|
||||
auto getLCDFlickerTop() -> unsigned char { return read(3); }
|
||||
auto setLCDFlickerTop(unsigned char val) -> void { write(3, val); }
|
||||
auto getLCDFlickerBottom() -> unsigned char { return read(4); }
|
||||
auto setLCDFlickerBottom(unsigned char val) -> void { write(4, val); }
|
||||
auto get3DSlider() -> unsigned char { return read(8); }
|
||||
auto getVolume() -> unsigned char { return read(9); }
|
||||
auto getBatteryPercent() -> unsigned char { return read(11); }
|
||||
auto getSystemVoltage() -> unsigned char { return read(13); }
|
||||
auto isCharging() -> bool { return read(15) & 0x10; }
|
||||
auto isOpen() -> bool { return read(15) & 0x2; }
|
||||
auto updateHIDStatus() -> void { HIDStatus = read(16); }
|
||||
auto powerButtonPressed() -> bool { return HIDStatus & 0x1; }
|
||||
auto powerButtonLongPressed() -> bool { return HIDStatus & 0x2; }
|
||||
auto homeButtonPressed() -> bool { return HIDStatus & 0x4; }
|
||||
auto homeButtonReleased() -> bool { return HIDStatus & 0x8; }
|
||||
auto wifiEnabled() -> bool { return HIDStatus & 0x10; }
|
||||
auto closed() -> bool { return HIDStatus & 0x20; }
|
||||
auto opened() -> bool { return HIDStatus & 0x40; }
|
||||
auto poweroff() -> void { write(32, 1); }
|
||||
auto reboot() -> void { write(32, 4); }
|
||||
auto enableTopLCD() -> void { write(34, 0b100010); }
|
||||
auto disableTopLCD() -> void { write(34, 0b010010); }
|
||||
auto enableBottomLCD() -> void { write(34, 0b1010); }
|
||||
auto disableBottomLCD() -> void { write(34, 0b0110); }
|
||||
auto setWifiLED(char val) -> void { write(0x2A, (unsigned char)val); }
|
||||
auto setCameraLED(char val) -> void { write(0x2B, (unsigned char)val); }
|
||||
auto set3DLED(char val) -> void { write(0x2C, (unsigned char)val); }
|
||||
auto getRTC(RTC_date *date) -> void {
|
||||
auto bcdToVal = [](unsigned char c) -> unsigned char { return (c & 0xF) + (10 * (c >> 4)); };
|
||||
date->seconds = bcdToVal(read(0x30));
|
||||
date->minutes = bcdToVal(read(0x31));
|
||||
date->hours = bcdToVal(read(0x32));
|
||||
date->days = bcdToVal(read(0x34));
|
||||
date->months = bcdToVal(read(0x35));
|
||||
date->years = bcdToVal(read(0x36));
|
||||
}
|
||||
auto setRTC(RTC_date *date) -> void {
|
||||
auto valToBCD = [](unsigned char c) -> unsigned char { return (c % 10) + (c / 10) << 4; };
|
||||
write(0x30, valToBCD(date->seconds));
|
||||
write(0x31, valToBCD(date->minutes));
|
||||
write(0x32, valToBCD(date->hours));
|
||||
write(0x34, valToBCD(date->days));
|
||||
write(0x35, valToBCD(date->months));
|
||||
write(0x36, valToBCD(date->years));
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
#pragma once
|
||||
#include "../i2c/i2c.hpp"
|
||||
/**
|
||||
* Namespace containing all currently supported MCU functions
|
||||
*/
|
||||
namespace MCU {
|
||||
extern I2C access; ///< Private variable which is used to access the MCU
|
||||
auto getVersionLo() -> unsigned char; ///< Installed MCU firmware version. Current is 56 on n3ds and 27 on o3ds
|
||||
auto getVersionHi() -> unsigned char; ///< Installed MCU firmware version. Current is 3 on n3ds and 2 on o3ds
|
||||
auto getLCDFlickerTop() -> unsigned char; ///< Returns the top LCDs bias voltage in some wax
|
||||
auto setLCDFlickerTop(unsigned char) -> void; ///< Changes the top LCDs bias voltage
|
||||
auto getLCDFlickerBottom() -> unsigned char; ///< Returns the bottom LCDs bias voltage
|
||||
auto setLCDFlickerTop(unsigned char) -> void; ///< Changes the bottom LCDs bias voltage
|
||||
auto get3DSlider() -> unsigned char; ///< Returns how far the 3D slider has moved up
|
||||
auto getVolume() -> unsigned char; ///< Returns the current volume
|
||||
auto getBatteryPercent() -> unsigned char; ///< Returns the battery percentage
|
||||
auto getSystemVoltage() -> unsigned char; ///< Returns the system voltage
|
||||
auto isCharging() -> bool; ///< Returns true if the system is being charged
|
||||
auto isOpen() -> bool; ///< Returns true if the system is not closed
|
||||
extern uint8_t HIDStatus; ///< Storage variable for a few functions
|
||||
auto updateHIDStatus() -> void; ///< Updates HIDStatus
|
||||
auto powerButtonPressed() -> bool; ///< true if the power button got pressed
|
||||
auto powerButtonLongPressed() -> bool; ///< true if the power button got pressed for a long time
|
||||
auto homeButtonPressed() -> bool; ///< true if the home button got pressed
|
||||
auto homeButtonReleased() -> bool; ///< true if the home button got released
|
||||
auto wifiEnabled() -> bool; ///< true if wifi is enabled
|
||||
auto closed() -> bool; ///< true if the system got closed
|
||||
auto opened() -> bool; ///< true if the system got reopened
|
||||
auto poweroff() -> void; ///< powers the system off
|
||||
auto reboot() -> void; ///< restarts the system
|
||||
auto enableTopLCD() -> void; ///< enables the top LCD
|
||||
auto disableTopLCD() -> void; ///< disables the top LCD
|
||||
auto enableBottomLCD() -> void; ///< enables the bottom LCD
|
||||
auto disableBottomLCD() -> void; ///< disables the bottom LCD
|
||||
auto setWifiLED(char val) -> void; ///< set to a value between 1 and 0xF to turn on the Wifi LED
|
||||
auto setCameraLED(char val) -> void; ///< set to a value between 1 and 0xF to turn on the Camera LED
|
||||
auto set3DLED(char val)
|
||||
-> void; ///< set to a value between 1 and 0xF to turn on the 3D LED. Most devices don't have this LED
|
||||
/**
|
||||
* Struct for a RTC. Range is between 2000 and 2050.
|
||||
* Will probably be off by a lot, as the raw value is adjusted.
|
||||
*/
|
||||
struct RTC_date {
|
||||
unsigned char seconds; ///< seconds. Range: 0…59
|
||||
unsigned char minutes; ///< minutes. Range: 0…59
|
||||
unsigned char hours; ///< hours. Range: 0…23
|
||||
unsigned char days; ///< days. Range: 1…31
|
||||
unsigned char months; ///< months. Range: 1…12
|
||||
unsigned char years; ///< years. Range: 0…50
|
||||
};
|
||||
auto getRTC(RTC_date *) -> void; ///< sets the passed struct to the current date
|
||||
auto setRTC(RTC_date *) -> void; ///< sets the RTC to the data in the passed struct.
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
#include "picafb.hpp"
|
||||
#include <config.h>
|
||||
#ifdef ENABLE_SCREENINIT
|
||||
#include "../mcu/mcu.hpp"
|
||||
#endif
|
||||
#define GL_RGBA8_OES 0
|
||||
#define GL_RGB8_OES 1
|
||||
#define GL_RGB565_OES 2
|
||||
#define GL_RGB5_A1_OES 3
|
||||
#define GL_RGBA4_OES 4
|
||||
PICAfb::PICAfb() : Framebuffer(50, 15) {
|
||||
#ifdef ENABLE_SCREENINIT
|
||||
MCU::enableTopLCD();
|
||||
MCU::enableBottomLCD();
|
||||
*((uint32_t *)0x10141200) = 0x1007F; // Enable Backlights and GPU IO region
|
||||
*((uint32_t *)0x10202014) = 1;
|
||||
*((uint32_t *)0x1020200C) &= 0xFFFEFFFE;
|
||||
|
||||
*((uint32_t *)0x10202240) = 0x3F; // Top screen brightness
|
||||
*((uint32_t *)0x10202A40) = 0x3F; // Bottom screen brightness
|
||||
*((uint32_t *)0x10202244) = 0x1023E;
|
||||
*((uint32_t *)0x10202A44) = 0x1023E;
|
||||
// TODO this code is ugly and copied right out of the arm9loaderhax git
|
||||
// find out what 90% of this does
|
||||
// Top screen
|
||||
*(volatile uint32_t *)0x10400400 = 0x000001c2;
|
||||
*(volatile uint32_t *)0x10400404 = 0x000000d1;
|
||||
*(volatile uint32_t *)0x10400408 = 0x000001c1;
|
||||
*(volatile uint32_t *)0x1040040c = 0x000001c1;
|
||||
*(volatile uint32_t *)0x10400410 = 0x00000000;
|
||||
*(volatile uint32_t *)0x10400414 = 0x000000cf;
|
||||
*(volatile uint32_t *)0x10400418 = 0x000000d1;
|
||||
*(volatile uint32_t *)0x1040041c = 0x01c501c1;
|
||||
*(volatile uint32_t *)0x10400420 = 0x00010000;
|
||||
*(volatile uint32_t *)0x10400424 = 0x0000019d;
|
||||
*(volatile uint32_t *)0x10400428 = 0x00000002;
|
||||
*(volatile uint32_t *)0x1040042c = 0x00000192;
|
||||
*(volatile uint32_t *)0x10400430 = 0x00000192;
|
||||
*(volatile uint32_t *)0x10400434 = 0x00000192;
|
||||
*(volatile uint32_t *)0x10400438 = 0x00000001;
|
||||
*(volatile uint32_t *)0x1040043c = 0x00000002;
|
||||
*(volatile uint32_t *)0x10400440 = 0x01960192;
|
||||
*(volatile uint32_t *)0x10400444 = 0x00000000;
|
||||
*(volatile uint32_t *)0x10400448 = 0x00000000;
|
||||
*(volatile uint32_t *)0x1040045C = 0x00f00190;
|
||||
*(volatile uint32_t *)0x10400460 = 0x01c100d1;
|
||||
*(volatile uint32_t *)0x10400464 = 0x01920002;
|
||||
*(volatile uint32_t *)0x10400468 = 0x18300000;
|
||||
*(volatile uint32_t *)0x10400470 = 0x80341;
|
||||
*(volatile uint32_t *)0x10400474 = 0x00010501;
|
||||
*(volatile uint32_t *)0x10400478 = 0;
|
||||
*(volatile uint32_t *)0x10400490 = 0x000002D0;
|
||||
*(volatile uint32_t *)0x1040049C = 0x00000000;
|
||||
|
||||
// Disco register
|
||||
for (uint32_t i = 0; i < 256; i++) *(volatile uint32_t *)0x10400484 = 0x10101 * i;
|
||||
|
||||
// Bottom screen
|
||||
*(volatile uint32_t *)0x10400500 = 0x000001c2;
|
||||
*(volatile uint32_t *)0x10400504 = 0x000000d1;
|
||||
*(volatile uint32_t *)0x10400508 = 0x000001c1;
|
||||
*(volatile uint32_t *)0x1040050c = 0x000001c1;
|
||||
*(volatile uint32_t *)0x10400510 = 0x000000cd;
|
||||
*(volatile uint32_t *)0x10400514 = 0x000000cf;
|
||||
*(volatile uint32_t *)0x10400518 = 0x000000d1;
|
||||
*(volatile uint32_t *)0x1040051c = 0x01c501c1;
|
||||
*(volatile uint32_t *)0x10400520 = 0x00010000;
|
||||
*(volatile uint32_t *)0x10400524 = 0x0000019d;
|
||||
*(volatile uint32_t *)0x10400528 = 0x00000052;
|
||||
*(volatile uint32_t *)0x1040052c = 0x00000192;
|
||||
*(volatile uint32_t *)0x10400530 = 0x00000192;
|
||||
*(volatile uint32_t *)0x10400534 = 0x0000004f;
|
||||
*(volatile uint32_t *)0x10400538 = 0x00000050;
|
||||
*(volatile uint32_t *)0x1040053c = 0x00000052;
|
||||
*(volatile uint32_t *)0x10400540 = 0x01980194;
|
||||
*(volatile uint32_t *)0x10400544 = 0x00000000;
|
||||
*(volatile uint32_t *)0x10400548 = 0x00000011;
|
||||
*(volatile uint32_t *)0x1040055C = 0x00f00140;
|
||||
*(volatile uint32_t *)0x10400560 = 0x01c100d1;
|
||||
*(volatile uint32_t *)0x10400564 = 0x01920052;
|
||||
*(volatile uint32_t *)0x10400568 = 0x18300000 + 0x46500;
|
||||
*(volatile uint32_t *)0x10400570 = 0x80301;
|
||||
*(volatile uint32_t *)0x10400574 = 0x00010501;
|
||||
*(volatile uint32_t *)0x10400578 = 0;
|
||||
*(volatile uint32_t *)0x10400590 = 0x000002D0;
|
||||
*(volatile uint32_t *)0x1040059C = 0x00000000;
|
||||
|
||||
// Disco register
|
||||
for (uint32_t i = 0; i < 256; i++) *(volatile uint32_t *)0x10400584 = 0x10101 * i;
|
||||
|
||||
#endif
|
||||
}
|
||||
PICAfb::~PICAfb() {}
|
||||
auto PICAfb::plotPixel(int x, int y, int col) -> void {
|
||||
unsigned char *lfb = (unsigned char *)0x18300000;
|
||||
y=240-y-1;
|
||||
int off = (x * 240 + y) * 3;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
lfb[off++] = col;
|
||||
col >>= 8;
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#pragma once
|
||||
#include "../../framebuffer/framebuffer.hpp"
|
||||
/**
|
||||
* Framebuffer for the 3ds
|
||||
*/
|
||||
class PICAfb : public Framebuffer {
|
||||
protected:
|
||||
virtual auto plotPixel(int x, int y, int col) -> void;
|
||||
|
||||
public:
|
||||
PICAfb();
|
||||
virtual ~PICAfb();
|
||||
};
|
|
@ -1,56 +0,0 @@
|
|||
#include "vectorinit.hpp"
|
||||
extern "C" {
|
||||
extern uintptr_t branch_macro;
|
||||
void data_abort();
|
||||
void fast_irq();
|
||||
void normal_irq();
|
||||
void prefetch_abort();
|
||||
void svc_call();
|
||||
void undefined_op();
|
||||
}
|
||||
void initVectors() {
|
||||
uintptr_t *vectors = (uintptr_t *)0x1FFFFFA0;
|
||||
// branch_macro is a ldr pc, [pc,#-4], meaning it reads the following word as PC
|
||||
vectors[0] = branch_macro;
|
||||
vectors[1] = (uintptr_t)&normal_irq;
|
||||
vectors[2] = branch_macro;
|
||||
vectors[3] = (uintptr_t)&fast_irq;
|
||||
vectors[4] = branch_macro;
|
||||
vectors[5] = (uintptr_t)&svc_call;
|
||||
vectors[6] = branch_macro;
|
||||
vectors[7] = (uintptr_t)&undefined_op;
|
||||
vectors[8] = branch_macro;
|
||||
vectors[9] = (uintptr_t)&prefetch_abort;
|
||||
vectors[10] = branch_macro;
|
||||
vectors[11] = (uintptr_t)&data_abort;
|
||||
}
|
||||
IRQ_IO::IRQ_IO() {
|
||||
initVectors();
|
||||
*((volatile uint32_t*)0x17E00100)=1;
|
||||
*((volatile uint32_t*)0x17E00104)=0xF0;
|
||||
for(int i=0;i<32;i+=4) {
|
||||
*((volatile uint32_t*)(0x17E01100+i))=~0;
|
||||
}
|
||||
uint32_t intid;
|
||||
while((intid=*((volatile uint32_t*)0x17E00118))&1023!=1023) {
|
||||
*((volatile uint32_t*)0x17E00110)=intid;
|
||||
}
|
||||
}
|
||||
IRQ_IO::~IRQ_IO() {}
|
||||
|
||||
void *IRQ_IO::handleIRQ(void *data) {
|
||||
uint32_t interrupt=*((volatile uint32_t*)0x17E0010C);
|
||||
int intid = interrupt & 255;
|
||||
data = handlers[intid](data);
|
||||
*((volatile uint32_t*)0x17E00110) = interrupt;
|
||||
return data;
|
||||
}
|
||||
|
||||
void IRQ_IO::mask(int number) {}
|
||||
void IRQ_IO::unmask(int number) {}
|
||||
|
||||
static IRQ_IO irq;
|
||||
__attribute__((constructor))
|
||||
static void init_irq() {
|
||||
irqs = (IRQ*)&irq;
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <irq.hpp>
|
||||
void initVectors();
|
||||
|
||||
struct IRQ_IO: IRQ {
|
||||
IRQ_IO();
|
||||
virtual ~IRQ_IO();
|
||||
virtual void* handleIRQ(void *data);
|
||||
virtual void mask(int number);
|
||||
virtual void unmask(int number);
|
||||
};
|
|
@ -1,7 +0,0 @@
|
|||
config["ENABLE_EXTRA_MEMORY"] = get_yes_no("Enable 512KB of memory on n3DS", True)
|
||||
add_driver(True, "framebuffer")
|
||||
add_driver(False, "picafb")
|
||||
add_driver(False, "vectorinit")
|
||||
add_driver(True, "pmm")
|
||||
print("Enable complete Unicode font: NO (because of the size)")
|
||||
config["ENABLE_FRAMEBUFFER_UNICODE"] = False
|
|
@ -1,110 +0,0 @@
|
|||
#include "pic.hpp"
|
||||
#include "../io.hpp"
|
||||
#include <regs.h>
|
||||
#define PIC1 0x20
|
||||
#define PIC2 0xA0
|
||||
#define PIC1_COMMAND PIC1
|
||||
#define PIC1_DATA (PIC1 + 1)
|
||||
#define PIC2_COMMAND PIC2
|
||||
#define PIC2_DATA (PIC2 + 1)
|
||||
|
||||
#define PIC_EOI 0x20
|
||||
#define ICW1_ICW4 0x01
|
||||
#define ICW1_SINGLE 0x02
|
||||
#define ICW1_INTERVAL4 0x04
|
||||
#define ICW1_LEVEL 0x08
|
||||
#define ICW1_INIT 0x10
|
||||
|
||||
#define ICW4_8086 0x01
|
||||
#define ICW4_AUTO 0x02
|
||||
#define ICW4_BUF_SLAVE 0x04
|
||||
#define ICW4_BUF_MASTER 0x0C
|
||||
#define ICW4_SFNM 0x10
|
||||
IRQ_PIC::IRQ_PIC() {
|
||||
PIC::initPIC(0x20, 0x28);
|
||||
}
|
||||
IRQ_PIC::~IRQ_PIC() {
|
||||
PIC::disable();
|
||||
}
|
||||
void* IRQ_PIC::handleIRQ(void *data) {
|
||||
cpu_state* cpu = (cpu_state*)data;
|
||||
auto val = handlers[cpu->intr-0x20](data);
|
||||
PIC::sendEOI(cpu->intr > 0x27);
|
||||
return val;
|
||||
}
|
||||
void IRQ_PIC::mask(int number) {
|
||||
PIC::mask(number);
|
||||
}
|
||||
void IRQ_PIC::unmask(int number) {
|
||||
PIC::unmask(number);
|
||||
}
|
||||
static IRQ_PIC irqpic;
|
||||
__attribute__((constructor))
|
||||
static void initIRQ() {
|
||||
irqs = &irqpic;
|
||||
//Init pic
|
||||
out<uint8_t>(0x43, 0x34);
|
||||
out<uint8_t>(0x40, 156);
|
||||
out<uint8_t>(0x40, 46);
|
||||
}
|
||||
namespace PIC {
|
||||
auto sendEOI(bool slave) -> void {
|
||||
if (slave) { out<unsigned char>(PIC2_COMMAND, PIC_EOI); }
|
||||
out<unsigned char>(PIC1_COMMAND, PIC_EOI);
|
||||
}
|
||||
auto initPIC(int off1, int off2) -> void {
|
||||
uint8_t a1 = in<uint8_t>(PIC1_DATA);
|
||||
uint8_t a2 = in<uint8_t>(PIC2_DATA);
|
||||
|
||||
out<uint8_t>(PIC1_COMMAND, ICW1_INIT + ICW1_ICW4);
|
||||
out<uint8_t>(PIC2_COMMAND, ICW1_INIT + ICW1_ICW4);
|
||||
out<uint8_t>(PIC1_DATA, off1);
|
||||
out<uint8_t>(PIC2_DATA, off2);
|
||||
out<uint8_t>(PIC1_DATA, 4); // Slave at 2
|
||||
out<uint8_t>(PIC2_DATA, 2); // Self at 2
|
||||
|
||||
out<uint8_t>(PIC1_DATA, ICW4_8086);
|
||||
out<uint8_t>(PIC2_DATA, ICW4_8086);
|
||||
|
||||
out(PIC1_DATA, a1);
|
||||
out(PIC2_DATA, a2);
|
||||
}
|
||||
auto disable() -> void {
|
||||
out<uint8_t>(PIC1_DATA, 0xFF);
|
||||
out<uint8_t>(PIC2_DATA, 0xFF);
|
||||
}
|
||||
auto mask(int no) -> void {
|
||||
if (no < 8) {
|
||||
out<uint8_t>(PIC1_DATA, in<uint8_t>(PIC1_DATA) | (1 << no));
|
||||
} else {
|
||||
no -= 8;
|
||||
out<uint8_t>(PIC2_DATA, in<uint8_t>(PIC2_DATA) | (1 << no));
|
||||
}
|
||||
}
|
||||
auto unmask(int no) -> void {
|
||||
if (no < 8) {
|
||||
out<uint8_t>(PIC1_DATA, in<uint8_t>(PIC1_DATA) & ~(1 << no));
|
||||
} else {
|
||||
no -= 8;
|
||||
out<uint8_t>(PIC2_DATA, in<uint8_t>(PIC2_DATA) & ~(1 << no));
|
||||
}
|
||||
}
|
||||
auto disableSlave() -> void { mask(2); }
|
||||
auto enableSlave() -> void { unmask(2); }
|
||||
auto isSpurious(bool slave) -> bool {
|
||||
if (slave) {
|
||||
out<uint8_t>(PIC2_COMMAND, 0x0B);
|
||||
io_wait();
|
||||
if (!(in<uint8_t>(PIC2_DATA) & 0x80)) {
|
||||
sendEOI(false);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
out<uint8_t>(PIC1_COMMAND, 0x0B);
|
||||
io_wait();
|
||||
return (in<uint8_t>(PIC1_DATA) & 0x80) ? true : false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <irq.hpp>
|
||||
struct IRQ_PIC: IRQ {
|
||||
IRQ_PIC();
|
||||
virtual ~IRQ_PIC();
|
||||
virtual void* handleIRQ(void *data);
|
||||
virtual void mask(int number);
|
||||
virtual void unmask(int number);
|
||||
};
|
||||
/**
|
||||
* Namespace contains function to control the Programmable Interrupt Controller
|
||||
*/
|
||||
namespace PIC {
|
||||
auto sendEOI(bool slave) -> void; ///< Signals the PIC that the interrupt has ended
|
||||
auto initPIC(int off1, int off2) -> void; ///< Initializes the pic/remaps it
|
||||
auto disable() -> void; ///< disables PIC completely
|
||||
auto mask(int no) -> void; ///< disables a single IRQ
|
||||
auto unmask(int no) -> void; ///< reenables a single IRQ
|
||||
auto disableSlave() -> void; ///< disables IRQ2 and 8-15
|
||||
auto enableSlave() -> void; ///< reenables at least IRQ2
|
||||
auto isSpurious(bool slave) -> bool; ///< Return if this isn't an actual IRQ.
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
#include "cgaterm.hpp"
|
||||
#include "cp437.hpp"
|
||||
CGATerm::CGATerm() : TTY(80, 25) {}
|
||||
CGATerm::~CGATerm() {}
|
||||
auto CGATerm::rgbSupport() -> bool { return false; }
|
||||
struct ScreenChar {
|
||||
unsigned char ch;
|
||||
char fgcolor : 4;
|
||||
char bgcolor : 4;
|
||||
} __attribute__((packed));
|
||||
ScreenChar *scr = (ScreenChar *)0xB8000;
|
||||
auto CGATerm::plotChar(int x, int y, int c) -> void {
|
||||
char ch = unicodeToCP437(c);
|
||||
scr[y * 80 + x].ch = ch;
|
||||
scr[y * 80 + x].bgcolor = 0;
|
||||
char col = 0;
|
||||
switch (curColor) {
|
||||
case Color::BLACK: col = 0; break;
|
||||
case Color::BLUE: col = 1; break;
|
||||
case Color::GREEN: col = 2; break;
|
||||
case Color::CYAN: col = 3; break;
|
||||
case Color::RED: col = 4; break;
|
||||
case Color::MAGENTA: col = 5; break;
|
||||
case Color::BROWN: col = 6; break;
|
||||
case Color::LIGHT_GRAY: col = 7; break;
|
||||
case Color::GRAY: col = 8; break;
|
||||
case Color::LIGHT_BLUE: col = 9; break;
|
||||
case Color::LIGHT_GREEN: col = 10; break;
|
||||
case Color::LIGHT_CYAN: col = 11; break;
|
||||
case Color::LIGHT_RED: col = 12; break;
|
||||
case Color::LIGHT_MAGENTA: col = 13; break;
|
||||
case Color::YELLOW: col = 14; break;
|
||||
case Color::WHITE: col = 15; break;
|
||||
}
|
||||
scr[y * 80 + x].fgcolor = col;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#pragma once
|
||||
#include <tty.hpp>
|
||||
/**
|
||||
* TTY for a CGA terminal. Limitations: 80x25, no RGB
|
||||
*/
|
||||
class CGATerm : public TTY {
|
||||
protected:
|
||||
virtual auto plotChar(int x, int y, int c) -> void;
|
||||
|
||||
public:
|
||||
CGATerm();
|
||||
virtual ~CGATerm();
|
||||
virtual auto rgbSupport() -> bool;
|
||||
};
|
|
@ -1,21 +0,0 @@
|
|||
int tbl[] = {0, 9786, 9787, 9829, 9830, 9827, 9824, 8226, 9688, 9675, 9689, 9794, 9792, 9834, 9835, 9788, 9658, 9668,
|
||||
8597, 8252, 182, 167, 9644, 8616, 8593, 8595, 8594, 8592, 8735, 8596, 9652, 9660, 32, 33, 34, 35,
|
||||
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
|
||||
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
|
||||
72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
|
||||
90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
|
||||
108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
|
||||
126, 8962, 199, 252, 233, 226, 228, 224, 229, 231, 234, 235, 232, 239, 238, 236, 196, 197,
|
||||
201, 230, 198, 244, 246, 242, 251, 249, 255, 214, 220, 162, 163, 165, 8359, 402, 225, 237,
|
||||
243, 250, 241, 209, 170, 186, 191, 8976, 172, 189, 188, 161, 171, 187, 9617, 9618, 9619, 9474,
|
||||
9508, 9569, 9570, 9558, 9557, 9571, 9553, 9559, 9565, 9564, 9563, 9488, 9492, 9524, 9516, 9500, 9472, 9532,
|
||||
9566, 9567, 9562, 9556, 9577, 9574, 9568, 9552, 9580, 9575, 9576, 9572, 9573, 9561, 9560, 9554, 9555, 9579,
|
||||
9578, 9496, 9484, 9608, 9604, 9612, 9616, 9600, 945, 223, 915, 960, 931, 963, 181, 964, 934, 920,
|
||||
937, 948, 8734, 966, 949, 8745, 8801, 177, 8805, 8804, 8992, 8993, 247, 8776, 176, 8729, 183, 8730,
|
||||
8319, 178, 9632, 160};
|
||||
char unicodeToCP437(int c) {
|
||||
for (int i = 0; i < 256; i++)
|
||||
if (tbl[i] == c) return (char)i;
|
||||
return 0;
|
||||
}
|
||||
int CP437ToUnicode(char c) { return tbl[(unsigned char)c]; }
|
|
@ -1,8 +0,0 @@
|
|||
/**
|
||||
* converts a unicode codepoint to a CP437 codepoint
|
||||
*/
|
||||
char unicodeToCP437(int c);
|
||||
/**
|
||||
* converts a CP437 codepoint to a unicode codepoint
|
||||
*/
|
||||
int CP437ToUnicode(char c);
|
|
@ -1,11 +0,0 @@
|
|||
config["ENABLE_FRAMEBUFFER"] = get_yes_no("Use VESA Framebuffer?", True)
|
||||
if config["ENABLE_FRAMEBUFFER"]:
|
||||
config["ENABLE_FRAMEBUFFER_UNICODE"] = get_yes_no("Enable full Unicode BMP font (Adds around 1MB to binary)", False)
|
||||
if config["ENABLE_FRAMEBUFFER"]:
|
||||
add_driver(True, "framebuffer")
|
||||
add_driver(False, "vesafb")
|
||||
else:
|
||||
add_driver(False, "cgaterm")
|
||||
add_driver(False, "8259")
|
||||
add_driver(False, "idt")
|
||||
add_driver(False, "pmm")
|
|
@ -1,35 +0,0 @@
|
|||
#include "idt.hpp"
|
||||
extern "C" void intr_stub_0();
|
||||
IDT_entry entries[256];
|
||||
void setIDTEntry(int i, void *entry) {
|
||||
uintptr_t p = (uintptr_t)entry;
|
||||
entries[i].offset0 = (uint16_t)p;
|
||||
p >>= 16;
|
||||
#ifndef __x86_64__
|
||||
entries[i].selector = 0x8;
|
||||
#else
|
||||
entries[i].selector = 0x28;
|
||||
#endif
|
||||
entries[i].zero = 0;
|
||||
entries[i].type = 0b1110;
|
||||
entries[i].storageSeg = false;
|
||||
entries[i].dpl = 3;
|
||||
entries[i].used = true;
|
||||
entries[i].offset1 = (uint16_t)p;
|
||||
p >>= 16;
|
||||
#ifdef __x86_64__
|
||||
entries[i].offset2 = (uint32_t)p;
|
||||
entries[i].zero2 = 0;
|
||||
#endif
|
||||
}
|
||||
void initIDT() {
|
||||
void *start_vectors = (void *)&intr_stub_0;
|
||||
for (int i = 0; i < 256; i++) setIDTEntry(i, start_vectors + 16 * i);
|
||||
struct {
|
||||
uint16_t size;
|
||||
IDT_entry *off;
|
||||
} __attribute__((packed)) idtr;
|
||||
idtr.size = sizeof(entries);
|
||||
idtr.off = (IDT_entry *)(&entries);
|
||||
asm volatile("lidt %0" : : "m"(idtr));
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
/**
|
||||
* Element of the interrupt descriptor table.
|
||||
*/
|
||||
struct IDT_entry {
|
||||
uint16_t offset0; ///< bits 0…15 of interrupt entry address
|
||||
uint16_t selector; ///< segment of the interrupt handler
|
||||
uint8_t zero; ///< has to be zero
|
||||
uint8_t type : 4; ///< Type of the interrupt
|
||||
bool storageSeg : 1; ///< 0 for interrupt gates (???)
|
||||
uint8_t dpl : 2; ///< Priviledge level required for calling this interrupt
|
||||
bool used : 1; ///< true if the entry is usable
|
||||
uint16_t offset1; ///< Bits 16…31 of the entrypoint
|
||||
#ifdef __x86_64__
|
||||
uint32_t offset2; ///< Bits 32…63 of the entrypoint. Only present on AMD64
|
||||
uint32_t zero2; ///< Must be zero. Only present on AMD64
|
||||
#endif
|
||||
} __attribute__((packed));
|
||||
void initIDT();
|
|
@ -1,21 +0,0 @@
|
|||
template <typename T>
|
||||
static void out(uint16_t port, T val) {
|
||||
if (sizeof(T) == 1)
|
||||
asm volatile("outb %0, %1" : : "a"(val), "Nd"(port));
|
||||
else if (sizeof(T) == 2)
|
||||
asm volatile("outw %0, %1" : : "a"(val), "Nd"(port));
|
||||
else if (sizeof(T) == 4)
|
||||
asm volatile("outl %0, %1" : : "a"(val), "Nd"(port));
|
||||
}
|
||||
template <typename T>
|
||||
static T in(uint16_t port) {
|
||||
T val = 0;
|
||||
if (sizeof(T) == 1)
|
||||
asm volatile("inb %1, %0" : "=a"(val) : "Nd"(port));
|
||||
else if (sizeof(T) == 2)
|
||||
asm volatile("inw %1, %0" : "=a"(val) : "Nd"(port));
|
||||
else if (sizeof(T) == 4)
|
||||
asm volatile("inl %1, %0" : "=a"(val) : "Nd"(port));
|
||||
return val;
|
||||
}
|
||||
static void io_wait() { out<unsigned char>(0x80, 0); }
|
|
@ -1,34 +0,0 @@
|
|||
#include "pmm.hpp"
|
||||
PMM_MB::PMM_MB(multiboot_info_t *mb_info): PMM(0x1000), mb_info(mb_info) {
|
||||
auto mmap = (multiboot_memory_map_t*)((uintptr_t)(mb_info->mmap_addr));
|
||||
uint32_t count = mb_info->mmap_length / sizeof(mmap[0]);
|
||||
for(uint32_t i=0;i<count;i++) {
|
||||
if(mmap[i].type != MULTIBOOT_MEMORY_AVAILABLE)
|
||||
continue;
|
||||
if((phys_t)mmap[i].addr < lowest_page)
|
||||
lowest_page = (phys_t)mmap[i].addr;
|
||||
if((phys_t)(mmap[i].addr + mmap[i].len) > highest_page)
|
||||
highest_page = (phys_t)(mmap[i].addr + mmap[i].len);
|
||||
}
|
||||
fill();
|
||||
}
|
||||
|
||||
PMM_MB::~PMM_MB() {}
|
||||
|
||||
auto PMM_MB::isFree(phys_t addr) -> bool {
|
||||
auto mmap = (multiboot_memory_map_t*)((uintptr_t)(mb_info->mmap_addr));
|
||||
bool free=false;
|
||||
uint32_t count = mb_info->mmap_length / sizeof(mmap[0]);
|
||||
for(uint32_t i=0;i<count;i++) {
|
||||
if((mmap[i].addr > addr) || (mmap[i].addr + mmap[i].len < addr))
|
||||
continue;
|
||||
if(mmap[i].type != MULTIBOOT_MEMORY_AVAILABLE)
|
||||
return false;
|
||||
free=true;
|
||||
}
|
||||
if(!free)
|
||||
return false;
|
||||
if(addr == (phys_t)((uintptr_t)mb_info))
|
||||
return false;
|
||||
return PMM::isFree(addr);
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
#pragma once
|
||||
#include <pmm.hpp>
|
||||
#include <multiboot.h>
|
||||
class PMM_MB: public PMM {
|
||||
protected:
|
||||
multiboot_info_t *mb_info;
|
||||
virtual auto isFree(phys_t addr) -> bool;
|
||||
public:
|
||||
PMM_MB()=delete;
|
||||
PMM_MB(multiboot_info_t *mb_info);
|
||||
virtual ~PMM_MB();
|
||||
};
|
|
@ -1,14 +0,0 @@
|
|||
#include "vesafb.hpp"
|
||||
#include <stdint.h>
|
||||
auto VESAfb::plotPixel(int x, int y, int col) -> void {
|
||||
unsigned char *lfb = (unsigned char *)((uintptr_t)(mb_info->framebuffer_addr));
|
||||
int off = y * mb_info->framebuffer_pitch / (mb_info->framebuffer_bpp / 8) + x;
|
||||
off *= mb_info->framebuffer_bpp / 8;
|
||||
for (int i = 0; i < mb_info->framebuffer_bpp / 8; i++) {
|
||||
lfb[off++] = col;
|
||||
col >>= 8;
|
||||
}
|
||||
}
|
||||
VESAfb::VESAfb(multiboot_info_t *mb_info)
|
||||
: mb_info(mb_info), Framebuffer(mb_info->framebuffer_width / 8, mb_info->framebuffer_height / 16) {}
|
||||
VESAfb::~VESAfb() {}
|
|
@ -1,12 +0,0 @@
|
|||
#pragma once
|
||||
#include "../../framebuffer/framebuffer.hpp"
|
||||
#include <multiboot.h>
|
||||
class VESAfb : public Framebuffer {
|
||||
protected:
|
||||
multiboot_info_t *mb_info;
|
||||
virtual auto plotPixel(int x, int y, int col) -> void;
|
||||
|
||||
public:
|
||||
VESAfb(multiboot_info_t *mb_info);
|
||||
virtual ~VESAfb();
|
||||
};
|
|
@ -1,4 +0,0 @@
|
|||
add_driver(False, "uart")
|
||||
add_driver(False, "serial")
|
||||
add_driver(False, "vector")
|
||||
add_driver(True, "pmm")
|
|
@ -1,72 +0,0 @@
|
|||
#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);
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#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();
|
||||
};
|
|
@ -1,25 +0,0 @@
|
|||
#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
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
#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();
|
||||
};
|
|
@ -1,32 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
#pragma once
|
||||
void initVectors();
|
9
readme
9
readme
|
@ -2,8 +2,7 @@ to build mtgos you need the cross compilers, whose makefile is included in cross
|
|||
|
||||
Quick walkthrough of the steps needed for building:
|
||||
|
||||
1) ./config.py - this will ask you a couple questions needed for building and create a appropriate config.cmake and config.h
|
||||
2) mkdir -pv build; cd build - this will enter a build directory, as an in-dir build is not supported
|
||||
3) cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/<toolchain name here>.cmake ..
|
||||
4) make
|
||||
5) Kernel is in kernel/kernel
|
||||
1) mkdir -pv build; cd build - this will enter a build directory, as an in-dir build is not supported
|
||||
2) cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm-none-eabi.cmake ..
|
||||
3) make
|
||||
4) Kernel is in kernel/kernel
|
||||
|
|
Loading…
Reference in a new issue