mirror of
https://github.com/Maschell/libutils.git
synced 2024-11-28 06:34:13 +01:00
Added function for installing syscall 0x25 (KernelCopyData)
This commit is contained in:
parent
d3657d14eb
commit
ab456c08c9
@ -5,6 +5,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include "FSUtils.h"
|
#include "FSUtils.h"
|
||||||
#include "CFile.hpp"
|
#include "CFile.hpp"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
|
||||||
s32 FSUtils::LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size){
|
s32 FSUtils::LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size){
|
||||||
//! always initialze input
|
//! always initialze input
|
||||||
@ -143,6 +144,7 @@ bool FSUtils::saveBufferToFile(const char * path, void * buffer, u32 size){
|
|||||||
close(res);
|
close(res);
|
||||||
CFile file(path, CFile::WriteOnly);
|
CFile file(path, CFile::WriteOnly);
|
||||||
if (!file.isOpen()){
|
if (!file.isOpen()){
|
||||||
|
DEBUG_FUNCTION_LINE("Failed to open %s\n",path);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
file.write((const u8*) buffer,size);
|
file.write((const u8*) buffer,size);
|
||||||
|
146
source/kernel/kernel_utils.c
Normal file
146
source/kernel/kernel_utils.c
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
#include <dynamic_libs/os_defs.h>
|
||||||
|
#include <dynamic_libs/os_functions.h>
|
||||||
|
|
||||||
|
static void KernelCopyData(unsigned int addr, unsigned int src, unsigned int len){
|
||||||
|
/*
|
||||||
|
* Setup a DBAT access with cache inhibited to write through and read directly from memory
|
||||||
|
*/
|
||||||
|
unsigned int dbatu0, dbatl0, dbatu1, dbatl1;
|
||||||
|
// save the original DBAT value
|
||||||
|
asm volatile("mfdbatu %0, 0" : "=r" (dbatu0));
|
||||||
|
asm volatile("mfdbatl %0, 0" : "=r" (dbatl0));
|
||||||
|
asm volatile("mfdbatu %0, 1" : "=r" (dbatu1));
|
||||||
|
asm volatile("mfdbatl %0, 1" : "=r" (dbatl1));
|
||||||
|
|
||||||
|
unsigned int target_dbatu0 = 0;
|
||||||
|
unsigned int target_dbatl0 = 0;
|
||||||
|
unsigned int target_dbatu1 = 0;
|
||||||
|
unsigned int target_dbatl1 = 0;
|
||||||
|
|
||||||
|
unsigned char *dst_p = (unsigned char*)addr;
|
||||||
|
unsigned char *src_p = (unsigned char*)src;
|
||||||
|
|
||||||
|
// we only need DBAT modification for addresses out of our own DBAT range
|
||||||
|
// as our own DBAT is available everywhere for user and supervisor
|
||||||
|
// since our own DBAT is on DBAT5 position we don't collide here
|
||||||
|
if(addr < 0x00800000 || addr >= 0x01000000)
|
||||||
|
{
|
||||||
|
target_dbatu0 = (addr & 0x00F00000) | 0xC0000000 | 0x1F;
|
||||||
|
target_dbatl0 = (addr & 0xFFF00000) | 0x32;
|
||||||
|
asm volatile("mtdbatu 0, %0" : : "r" (target_dbatu0));
|
||||||
|
asm volatile("mtdbatl 0, %0" : : "r" (target_dbatl0));
|
||||||
|
dst_p = (unsigned char*)((addr & 0xFFFFFF) | 0xC0000000);
|
||||||
|
}
|
||||||
|
if(src < 0x00800000 || src >= 0x01000000)
|
||||||
|
{
|
||||||
|
target_dbatu1 = (src & 0x00F00000) | 0xB0000000 | 0x1F;
|
||||||
|
target_dbatl1 = (src & 0xFFF00000) | 0x32;
|
||||||
|
|
||||||
|
asm volatile("mtdbatu 1, %0" : : "r" (target_dbatu1));
|
||||||
|
asm volatile("mtdbatl 1, %0" : : "r" (target_dbatl1));
|
||||||
|
src_p = (unsigned char*)((src & 0xFFFFFF) | 0xB0000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
|
||||||
|
unsigned int i;
|
||||||
|
for(i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
// if we are on the edge to next chunk
|
||||||
|
if((target_dbatu0 != 0) && (((unsigned int)dst_p & 0x00F00000) != (target_dbatu0 & 0x00F00000)))
|
||||||
|
{
|
||||||
|
target_dbatu0 = ((addr + i) & 0x00F00000) | 0xC0000000 | 0x1F;
|
||||||
|
target_dbatl0 = ((addr + i) & 0xFFF00000) | 0x32;
|
||||||
|
dst_p = (unsigned char*)(((addr + i) & 0xFFFFFF) | 0xC0000000);
|
||||||
|
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
asm volatile("mtdbatu 0, %0" : : "r" (target_dbatu0));
|
||||||
|
asm volatile("mtdbatl 0, %0" : : "r" (target_dbatl0));
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
}
|
||||||
|
if((target_dbatu1 != 0) && (((unsigned int)src_p & 0x00F00000) != (target_dbatu1 & 0x00F00000)))
|
||||||
|
{
|
||||||
|
target_dbatu1 = ((src + i) & 0x00F00000) | 0xB0000000 | 0x1F;
|
||||||
|
target_dbatl1 = ((src + i) & 0xFFF00000) | 0x32;
|
||||||
|
src_p = (unsigned char*)(((src + i) & 0xFFFFFF) | 0xB0000000);
|
||||||
|
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
asm volatile("mtdbatu 1, %0" : : "r" (target_dbatu1));
|
||||||
|
asm volatile("mtdbatl 1, %0" : : "r" (target_dbatl1));
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
}
|
||||||
|
|
||||||
|
*dst_p = *src_p;
|
||||||
|
|
||||||
|
++dst_p;
|
||||||
|
++src_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Restore original DBAT value
|
||||||
|
*/
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
asm volatile("mtdbatu 0, %0" : : "r" (dbatu0));
|
||||||
|
asm volatile("mtdbatl 0, %0" : : "r" (dbatl0));
|
||||||
|
asm volatile("mtdbatu 1, %0" : : "r" (dbatu1));
|
||||||
|
asm volatile("mtdbatl 1, %0" : : "r" (dbatl1));
|
||||||
|
asm volatile("eieio; isync");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read a 32-bit word with kernel permissions */
|
||||||
|
uint32_t __attribute__ ((noinline)) kern_read(const void *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
asm volatile (
|
||||||
|
"li 3,1\n"
|
||||||
|
"li 4,0\n"
|
||||||
|
"li 5,0\n"
|
||||||
|
"li 6,0\n"
|
||||||
|
"li 7,0\n"
|
||||||
|
"lis 8,1\n"
|
||||||
|
"mr 9,%1\n"
|
||||||
|
"li 0,0x3400\n"
|
||||||
|
"mr %0,1\n"
|
||||||
|
"sc\n"
|
||||||
|
"nop\n"
|
||||||
|
"mr 1,%0\n"
|
||||||
|
"mr %0,3\n"
|
||||||
|
: "=r"(result)
|
||||||
|
: "b"(addr)
|
||||||
|
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
|
||||||
|
"11", "12"
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write a 32-bit word with kernel permissions */
|
||||||
|
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value)
|
||||||
|
{
|
||||||
|
asm volatile (
|
||||||
|
"li 3,1\n"
|
||||||
|
"li 4,0\n"
|
||||||
|
"mr 5,%1\n"
|
||||||
|
"li 6,0\n"
|
||||||
|
"li 7,0\n"
|
||||||
|
"lis 8,1\n"
|
||||||
|
"mr 9,%0\n"
|
||||||
|
"mr %1,1\n"
|
||||||
|
"li 0,0x3500\n"
|
||||||
|
"sc\n"
|
||||||
|
"nop\n"
|
||||||
|
"mr 1,%1\n"
|
||||||
|
:
|
||||||
|
: "r"(addr), "r"(value)
|
||||||
|
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
|
||||||
|
"11", "12"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_kernel_syscalls(){
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl1 + (0x25 * 4)), (unsigned int)KernelCopyData);
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl2 + (0x25 * 4)), (unsigned int)KernelCopyData);
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl3 + (0x25 * 4)), (unsigned int)KernelCopyData);
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl4 + (0x25 * 4)), (unsigned int)KernelCopyData);
|
||||||
|
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl5 + (0x25 * 4)), (unsigned int)KernelCopyData);
|
||||||
|
}
|
14
source/kernel/kernel_utils.h
Normal file
14
source/kernel/kernel_utils.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef __KERNEL_UTILS_H_
|
||||||
|
#define __KERNEL_UTILS_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void init_kernel_syscalls();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __KERNEL_UTILS_H_
|
Loading…
Reference in New Issue
Block a user