summaryrefslogblamecommitdiffstats
path: root/src/core/hle/kernel/kernel.cpp
blob: e8bf83a4436b8e69f59e17b080c29825f3c90fb8 (plain) (tree)
1
2
3
4
5
6
7
8
9

                                            
                                          
 

                    

                          
                      


                                   
                  
 
                         
                           
                     
 
                            


                              
                                                                          









                                                         
                                                


                                     
                                                                                          


             
                                                








                                       
                           
                                         




                                                  
                       


                              
                                                
 
                                                                               


                                        
                          


                                         
                                                                                                        
                                                




             
                                   
                                                              

 
                                               
                                                  
                   
 
 
                         
             
                            

 
                       
                 
                                
 
                                                      

 





                                                          

                                         
                                                                     
                                                  


                

              
// Copyright 2014 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#include <algorithm>

#include "common/common.h"

#include "core/core.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/thread.h"

namespace Kernel {

Handle g_main_thread = 0;
HandleTable g_handle_table;
u64 g_program_id = 0;

HandleTable::HandleTable() {
    next_id = INITIAL_NEXT_ID;
}

Handle HandleTable::Create(Object* obj, int range_bottom, int range_top) {
    if (range_top > MAX_COUNT) {
        range_top = MAX_COUNT;
    }
    if (next_id >= range_bottom && next_id < range_top) {
        range_bottom = next_id++;
    }
    for (int i = range_bottom; i < range_top; i++) {
        if (!occupied[i]) {
            occupied[i] = true;
            pool[i] = obj;
            pool[i]->handle = i + HANDLE_OFFSET;
            return i + HANDLE_OFFSET;
        }
    }
    LOG_ERROR(Kernel, "Unable to allocate kernel object, too many objects slots in use.");
    return 0;
}

bool HandleTable::IsValid(Handle handle) const {
    int index = handle - HANDLE_OFFSET;
    if (index < 0)
        return false;
    if (index >= MAX_COUNT)
        return false;

    return occupied[index];
}

void HandleTable::Clear() {
    for (int i = 0; i < MAX_COUNT; i++) {
        //brutally clear everything, no validation
        if (occupied[i])
            delete pool[i];
        occupied[i] = false;
    }
    pool.fill(nullptr);
    next_id = INITIAL_NEXT_ID;
}

Object* &HandleTable::operator [](Handle handle)
{
    _dbg_assert_msg_(Kernel, IsValid(handle), "GRABBING UNALLOCED KERNEL OBJ");
    return pool[handle - HANDLE_OFFSET];
}

void HandleTable::List() {
    for (int i = 0; i < MAX_COUNT; i++) {
        if (occupied[i]) {
            if (pool[i]) {
                LOG_DEBUG(Kernel, "KO %i: %s \"%s\"", i + HANDLE_OFFSET, pool[i]->GetTypeName().c_str(),
                    pool[i]->GetName().c_str());
            }
        }
    }
}

int HandleTable::GetCount() const {
    return std::count(occupied.begin(), occupied.end(), true);
}

Object* HandleTable::CreateByIDType(int type) {
    LOG_ERROR(Kernel, "Unimplemented: %d.", type);
    return nullptr;
}

/// Initialize the kernel
void Init() {
    Kernel::ThreadingInit();
}

/// Shutdown the kernel
void Shutdown() {
    Kernel::ThreadingShutdown();

    g_handle_table.Clear(); // Free all kernel objects
}

/**
 * Loads executable stored at specified address
 * @entry_point Entry point in memory of loaded executable
 * @return True on success, otherwise false
 */
bool LoadExec(u32 entry_point) {
    Core::g_app_core->SetPC(entry_point);

    // 0x30 is the typical main thread priority I've seen used so far
    g_main_thread = Kernel::SetupMainThread(0x30);

    return true;
}

} // namespace