Merge branch 'funny' into 'mommy'

Funny

See merge request fekhesk/vap!1
This commit is contained in:
Husky Susbaka 2023-06-27 06:53:34 +00:00
commit e823fa3080
4 changed files with 37 additions and 189 deletions

View file

@ -20,18 +20,12 @@ vap_get_real:
// enter real mode
mtsrr0 5
mfmsr 31
// MSR_IR (1 << 5) = 0
// MSR_DR (1 << 4) = 0
// MSR_EE (1 << 15) = 0
lis 30, ~0@h
ori 30, 30, ~((1 << 15) | (1 << 5) | (1 << 4))@l
and 31, 31, 30
mtsrr1 31
li 31, (1 << ((32-1) - 19))
mtmsr 31
// now we can rfi to so_real
sync
isync
rfi
.global vap_get_fake
.extern VAP_KERN_BASE
.extern VAP_KERN_PHOF
@ -39,44 +33,7 @@ vap_get_real:
vap_get_fake:
// we are now in actual real mode, the registers shouldn't have changed
// first things first, use the translation table to remap the kernel's memory
#define PAGE_WIDTH 12
#define PAGE_SIZE (1 << PAGE_WIDTH)
// some values for page copying, very much inspired by helenos's ppc32 port
li 31, PAGE_SIZE >> 2
li 30, 0
page_copy:
cmpwi 4, 0 // are we at 0 pages (done)?
beq page_copy_done // if so, jump to the end
mtctr 31 // set the counter to PAGE_SIZE >> 2
lwz 29, 0(3) // load the physical address of the page to copy
page_copy_loop:
lwz 28, 0(29) // load the word to copy
stw 28, 0(30) // store the word to the new page
// ensure everything's synced
dcbst 0, 30
sync
icbi 0, 30
sync
isync
addi 29, 29, 4 // increment the source pointer
addi 30, 30, 4 // increment the destination pointer
bdnz page_copy_loop // loop
// end of page_copy_loop
// increment the translation table pointer
addi 3, 3, 4
// decrement the number of pages left
subi 4, 4, 1
b page_copy // loop
page_copy_done:
// for the first 256MiB, virtual=physical
// normally i'd write register names as their true values, but with the bat registers
// that'd just make things purely unreadable
@ -116,138 +73,24 @@ vap_get_fake:
mtspr dbat3u, 30
mtspr dbat3l, 30
// here we define a macro for calculating the bat register values
// the bat registers are referred to as "upper" and "lower" registers
// the upper register contains the virtual address of the page, and the lower register contains
// the physical address of the page, as well as some other information
// if you want to learn more about this, i'd recommend reading this pdf:
// http://www.cs.cmu.edu/~412-s05/projects/9mac/PowerPC_Memory.pdf
// there are two notable things about this macro:
// 1. lower and upper are registers that the lower and upper bat registers should be set to
// their initial values do not matter
// 2. i kinda just stole this from helenos, i'm sorry ):
.macro BAT_COMPUTE base size mask lower upper kern_base
lis \upper, 0x0002
cmpw \size, \upper // check if we have less than 128kib remaining to map
blt finish_bat // if so, jump to the end
// now we can set up the bat registers
li 7, ((0x7FF<<2)|2)
li 8, ((2<<3)|2)
li \upper, 18
srw \mask, \size, \upper // calculate the mask (size >> 18)
sync
isync
// create the block length mask by duplicating the leading 1 14 times
// the block length mask indicates the length by number of bits set
li \upper, 14
mtctr \upper
li \upper, 1
0:
srw \lower, \mask, \upper
or \mask, \mask, \lower
bdnz 0b
// end of 0:
// & the mask with 0x07ff to assure that we map at most 256mib
andi. \mask, \mask, 0x07ff
mtspr dbat0u, 7
mtspr dbat0l, 8
sync
isync
mtspr ibat0u, 7
mtspr ibat0l, 8
sync
isync
// calculate the upper register
// the upper register contains:
// 1. the virtual address of the page
// 2. the block length mask
// 3. kernel access bit (1 << 2)
// 4. user access bit (1 << 1)
// we don't have a userspace yet! so we'll just set the kernel access bit to 1
// and the user access bit to 0
li \upper, 2
slw \mask, \mask, \upper
ori \mask, \mask, 0x0002
// zero the rest
lis \upper, (\kern_base + \base)@l
or \upper, \upper, \mask
// calculate the lower register
// the lower register contains:
// 1. the physical address of the page
// 2. storage access controls
// 3. protection bits
lis \lower, \base
ori \lower, \lower, 0x0002
.endm
// now we are finally ready to set the bat registers!
// we will load into r29 either 256MiB or the remaining memory amount, whichever is smaller
lis 30, 268435456@h
ori 30, 30, 268435456@l
// reminder that r7 contains the amount of memory we have
cmpw 7, 30
blt bat0_memsmaller
// 256mib is smaller
mr 29, 30
b bat0_constsmaller
bat0_memsmaller:
mr 29, 7
bat0_constsmaller:
BAT_COMPUTE 0x0000 29 28 27 26 VAP_KERN_PHOF
mtspr ibat0u, 26
mtspr ibat0l, 27
mtspr dbat0u, 26
mtspr dbat0l, 27
// now we will do the same thing for bat 1
sub 7, 7, 29 // decrement the amount of memory left
cmpw 7, 30
blt bat1_memsmaller
// 256mib is smaller
mr 29, 30
b bat1_constsmaller
bat1_memsmaller:
mr 29, 7
bat1_constsmaller:
BAT_COMPUTE 0x1000 29 28 27 26 VAP_KERN_PHOF
mtspr ibat1u, 26
mtspr ibat1l, 27
mtspr dbat1u, 26
mtspr dbat1l, 27
// now we will do the same thing for bat 2
sub 7, 7, 29 // decrement the amount of memory left
cmpw 7, 30
blt bat2_memsmaller
// 256mib is smaller
mr 29, 30
b bat2_constsmaller
bat2_memsmaller:
mr 29, 7
bat2_constsmaller:
BAT_COMPUTE 0x2000 29 28 27 26 VAP_KERN_PHOF
mtspr ibat2u, 26
mtspr ibat2l, 27
mtspr dbat2u, 26
mtspr dbat2l, 27
// now we will do the same thing for bat 3
sub 7, 7, 29 // decrement the amount of memory left
cmpw 7, 30
blt bat3_memsmaller
// 256mib is smaller
mr 29, 30
b bat3_constsmaller
bat3_memsmaller:
mr 29, 7
bat3_constsmaller:
BAT_COMPUTE 0x3000 29 28 27 26 VAP_KERN_PHOF
mtspr ibat3u, 26
mtspr ibat3l, 27
mtspr dbat3u, 26
mtspr dbat3l, 27
finish_bat:
// theoretically, we should be done with the bat registers now
@ -260,7 +103,8 @@ vap_get_fake:
// we need to set the srr1 register to the value of the msr register
// but also re-enable MSR_IR and MSR_DR so that we can use the bat registers
mfmsr 31
ori 31, 31, ((1 << 5) | (1 << 4))@l
li 31, ((1 << ((32-1) - 19)) | (1 << ((32-1) - 26)) | (1 << ((32-1) - 27)))
// enable bit 30 to allow system resets to be recoverable
mtsrr1 31
//mr 1, 8 // restore the stack pointer

View file

@ -55,12 +55,7 @@ pub fn bootstrap() -> ! {
debug!("phys_translation_table: {:x}", phys_translation_table);
debug!("page_count: {:x}", page_count);
debug!("kernal base: {:x}", VAP_KERN_BASE as usize);
debug!("vap_get_real: {:x}", vap_get_real as usize);
debug!("phys_get_fake: {:x}", phys_get_fake);
debug!("vap_get_fake: {:x}", vap_get_fake as usize);
debug!("so_fake: {:x}", so_fake as usize);
debug!("phys_so_fake: {:x}", translate_to_phys(so_fake as usize).unwrap());
debug!("phys_vap_get_fake: {:x}", phys_vap_get_fake);
debug!("mem_size: {:x}", mem_size);
debug!("vap_stack: {:x}", VAP_STACK as usize);
debug!("openfirmware entry fn: {:x}", unsafe {
@ -70,7 +65,7 @@ pub fn bootstrap() -> ! {
debug!("filled vap allocator with available memory, see you on the flip side!");
unsafe {
vap_get_real(phys_translation_table, page_count, phys_get_fake, so_fake as usize, mem_size, VAP_STACK as usize);
vap_get_real(phys_translation_table, page_count, phys_vap_get_fake, finalize_bootstrapping as usize, mem_size);
}
}
@ -85,9 +80,11 @@ extern "C" fn test1() {
#[no_mangle]
pub extern "C" fn finalize_bootstrapping() -> ! {
//test1();
panic!("test");
memory::ppc32::allocation::VapAllocator::init();
// we made it!
debug!("hiiii");
let available = get_available_memory();
debug!("available memory: {:?}", available);
memory::VapAllocator::init(available);
debug!("initialised vap allocator");
debug!("patching interrupt vectors");
patch_interrupt_vectors();

View file

@ -3,6 +3,7 @@
#![feature(lang_items)]
#![feature(asm_experimental_arch)]
#![feature(once_cell)]
#![feature(lazy_cell)]
#![no_std]
#![no_main]
@ -252,6 +253,12 @@ pub fn kernel_main() -> ! {
stack_pointer
};
println!("bootstrapping");
bootstrap::bootstrap();
println!("initializing scheduler");
scheduling::add_task(None, kernel_callback).expect("failed to add kernel callback task");
//debug!("constructing terminal window");
//terminal::construct_terminal_window();
//macros::USE_RAW.store(false, core::sync::atomic::Ordering::SeqCst);
unsafe { scheduling::init_scheduler() };
loop {}
}

View file

@ -137,6 +137,7 @@ pub extern "C" fn scheduler_callback(savestate: *const SaveState) -> ! {
// set the stack pointer to the end of the stack
task.savestate.sp = stack as u32 + 0x100000;
task.stack_base = stack as usize;
//debug!("added task {} to scheduler", task.uuid);
// if the next task points to a task that isn't empty, then we need to push the task
if scheduler.tasks.get(scheduler.next_task as usize).is_none() || scheduler.tasks[scheduler.next_task as usize].is_some() {
@ -227,8 +228,7 @@ pub extern "C" fn scheduler_callback(savestate: *const SaveState) -> ! {
// reset the last_run value of the task with the highest priority
scheduler.tasks[index_with_highest_priority].as_mut().unwrap().last_run = 0;
// set the current task to the task with the highest priority
scheduler.current_task = scheduler.tasks[index_with_highest_priority].as_mut().unwrap().uuid;
//debug!("now running task {} with srr0 {:x}", scheduler.current_task, scheduler.tasks[index_with_highest_priority].as_mut().unwrap().savestate.srr0);
// return to the task with the highest priority
unsafe {