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 // enter real mode
mtsrr0 5 mtsrr0 5
mfmsr 31 mfmsr 31
// MSR_IR (1 << 5) = 0 li 31, (1 << ((32-1) - 19))
// MSR_DR (1 << 4) = 0 mtmsr 31
// 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
// now we can rfi to so_real // now we can rfi to so_real
sync sync
isync isync
rfi
.global vap_get_fake .global vap_get_fake
.extern VAP_KERN_BASE .extern VAP_KERN_BASE
.extern VAP_KERN_PHOF .extern VAP_KERN_PHOF
@ -39,44 +33,7 @@ vap_get_real:
vap_get_fake: vap_get_fake:
// we are now in actual real mode, the registers shouldn't have changed // 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 // for the first 256MiB, virtual=physical
#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:
// normally i'd write register names as their true values, but with the bat registers // normally i'd write register names as their true values, but with the bat registers
// that'd just make things purely unreadable // that'd just make things purely unreadable
@ -116,138 +73,24 @@ vap_get_fake:
mtspr dbat3u, 30 mtspr dbat3u, 30
mtspr dbat3l, 30 mtspr dbat3l, 30
// here we define a macro for calculating the bat register values // now we can set up the bat registers
// the bat registers are referred to as "upper" and "lower" registers li 7, ((0x7FF<<2)|2)
// the upper register contains the virtual address of the page, and the lower register contains li 8, ((2<<3)|2)
// 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
li \upper, 18 sync
srw \mask, \size, \upper // calculate the mask (size >> 18) isync
// create the block length mask by duplicating the leading 1 14 times mtspr dbat0u, 7
// the block length mask indicates the length by number of bits set mtspr dbat0l, 8
li \upper, 14 sync
mtctr \upper isync
li \upper, 1 mtspr ibat0u, 7
0: mtspr ibat0l, 8
srw \lower, \mask, \upper sync
or \mask, \mask, \lower isync
bdnz 0b
// end of 0:
// & the mask with 0x07ff to assure that we map at most 256mib
andi. \mask, \mask, 0x07ff
// calculate the upper register // zero the rest
// 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
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: finish_bat:
// theoretically, we should be done with the bat registers now // 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 // 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 // but also re-enable MSR_IR and MSR_DR so that we can use the bat registers
mfmsr 31 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 mtsrr1 31
//mr 1, 8 // restore the stack pointer //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!("phys_translation_table: {:x}", phys_translation_table);
debug!("page_count: {:x}", page_count); debug!("page_count: {:x}", page_count);
debug!("kernal base: {:x}", VAP_KERN_BASE as usize); debug!("phys_vap_get_fake: {:x}", phys_vap_get_fake);
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!("mem_size: {:x}", mem_size); debug!("mem_size: {:x}", mem_size);
debug!("vap_stack: {:x}", VAP_STACK as usize); debug!("vap_stack: {:x}", VAP_STACK as usize);
debug!("openfirmware entry fn: {:x}", unsafe { 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!"); debug!("filled vap allocator with available memory, see you on the flip side!");
unsafe { 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] #[no_mangle]
pub extern "C" fn finalize_bootstrapping() -> ! { pub extern "C" fn finalize_bootstrapping() -> ! {
//test1(); // we made it!
panic!("test"); debug!("hiiii");
memory::ppc32::allocation::VapAllocator::init(); let available = get_available_memory();
debug!("available memory: {:?}", available);
memory::VapAllocator::init(available);
debug!("initialised vap allocator"); debug!("initialised vap allocator");
debug!("patching interrupt vectors"); debug!("patching interrupt vectors");
patch_interrupt_vectors(); patch_interrupt_vectors();

View file

@ -3,6 +3,7 @@
#![feature(lang_items)] #![feature(lang_items)]
#![feature(asm_experimental_arch)] #![feature(asm_experimental_arch)]
#![feature(once_cell)] #![feature(once_cell)]
#![feature(lazy_cell)]
#![no_std] #![no_std]
#![no_main] #![no_main]
@ -252,6 +253,12 @@ pub fn kernel_main() -> ! {
stack_pointer stack_pointer
}; };
println!("bootstrapping"); println!("initializing scheduler");
bootstrap::bootstrap(); 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 // set the stack pointer to the end of the stack
task.savestate.sp = stack as u32 + 0x100000; task.savestate.sp = stack as u32 + 0x100000;
task.stack_base = stack as usize; 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 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() { 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 // reset the last_run value of the task with the highest priority
scheduler.tasks[index_with_highest_priority].as_mut().unwrap().last_run = 0; scheduler.tasks[index_with_highest_priority].as_mut().unwrap().last_run = 0;
// set the current task to the task with the highest priority //debug!("now running task {} with srr0 {:x}", scheduler.current_task, scheduler.tasks[index_with_highest_priority].as_mut().unwrap().savestate.srr0);
scheduler.current_task = scheduler.tasks[index_with_highest_priority].as_mut().unwrap().uuid;
// return to the task with the highest priority // return to the task with the highest priority
unsafe { unsafe {