Skip to content

Commit 1851c8d

Browse files
committed
wip memcpy tests
1 parent 19a89db commit 1851c8d

File tree

6 files changed

+222
-2
lines changed

6 files changed

+222
-2
lines changed

examples/memcpy_bench/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "psp-memcpy-bench"
3+
version = "0.1.0"
4+
authors = ["Paul Sajna <[email protected]>"]
5+
edition = "2021"
6+
7+
[dependencies]
8+
psp = { path = "../../psp" }
9+
10+
[profile.release]
11+
debug=true

examples/memcpy_bench/src/main.rs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#![no_std]
2+
#![no_main]
3+
4+
extern crate alloc;
5+
use alloc::alloc::Layout;
6+
use alloc::format;
7+
use core::time::Duration;
8+
use core::ffi::c_void;
9+
use psp::sys::SceUid;
10+
11+
psp::module!("sample_module", 1, 1);
12+
13+
fn psp_main() {
14+
psp::enable_home_button();
15+
16+
// Enable the VFPU
17+
//unsafe {
18+
//use psp::sys::{self, ThreadAttributes};
19+
//sys::sceKernelChangeCurrentThreadAttr(0, ThreadAttributes::VFPU);
20+
//}
21+
22+
let iters: [usize; 11] = [16, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1];
23+
let sizes: [usize; 11] = [32,64,512,1024,2048,16348,32768,65536,131072,524288,1048576];
24+
25+
let mut cpu_dur: Duration;
26+
let mut kernel_dur: Duration;
27+
let mut dmac_dur: Duration;
28+
let mut vfpu_dur: Duration;
29+
30+
let fd = unsafe { psp::sys::sceIoOpen(b"host0:/results.txt\0".as_ptr(), psp::sys::IoOpenFlags::CREAT | psp::sys::IoOpenFlags::RD_WR, 0o777) };
31+
32+
for i in 0..11 {
33+
let size = sizes[i];
34+
let iterations = iters[i];
35+
let src = unsafe { alloc::alloc::alloc(Layout::from_size_align_unchecked(size, 16)) };
36+
let dst = unsafe { alloc::alloc::alloc(Layout::from_size_align_unchecked(size, 16)) };
37+
38+
let src = unsafe { core::mem::transmute::<*mut u8, *mut u32>(src) };
39+
let dst = unsafe { core::mem::transmute::<*mut u8, *mut u32>(dst) };
40+
41+
unsafe { psp::sys::sceKernelMemset(src, 0xAA, size) };
42+
43+
let src = unsafe { core::mem::transmute::<*mut u32, *mut u8>(src) };
44+
let dst = unsafe { core::mem::transmute::<*mut u32, *mut u8>(dst) };
45+
46+
47+
cpu_dur = psp::benchmark(|| {
48+
for _ in 0..iterations {
49+
unsafe { memcpy(dst, src as *const u8, size); }
50+
}
51+
}, 10);
52+
assert_eq!(unsafe { *dst }, 0xAA);
53+
54+
55+
let src = unsafe { core::mem::transmute::<*mut u8, *mut u32>(src) };
56+
let dst = unsafe { core::mem::transmute::<*mut u8, *mut u32>(dst) };
57+
58+
unsafe { psp::sys::sceKernelMemset(src, 0x00, size) };
59+
60+
unsafe { psp::sys::sceKernelMemset(src, 0xAA, size) };
61+
kernel_dur = psp::benchmark(|| {
62+
for _ in 0..iterations {
63+
unsafe { psp::sys::sceKernelMemcpy(dst, src, size); }
64+
}
65+
}, 10);
66+
assert_eq!(unsafe { *dst }, 0xAA);
67+
unsafe { psp::sys::sceKernelMemset(src, 0x00, size) };
68+
69+
unsafe { psp::sys::sceKernelMemset(src, 0xAA, size) };
70+
dmac_dur = psp::benchmark(|| {
71+
for _ in 0..iterations {
72+
unsafe { psp::sys::sceDmacMemcpy(dst, src, size); }
73+
}
74+
}, 10);
75+
assert_eq!(unsafe { *dst }, 0xAA);
76+
unsafe { psp::sys::sceKernelMemset(src, 0x00, size) };
77+
78+
vfpu_dur = Duration::new(0, 0);
79+
80+
//unsafe { psp::sys::sceKernelMemset(src, 0xAA, size) };
81+
//vfpu_dur = psp::benchmark(|| {
82+
//for _ in 0..iterations {
83+
//unsafe { psp::sys::sceVfpuMemcpy(dst, src as *const u8, size); }
84+
//}
85+
//}, 10);
86+
//assert_eq!(unsafe { *dst }, 0xAA);
87+
//unsafe { psp::sys::sceKernelMemset(src, 0x00, size) };
88+
89+
let src = unsafe { core::mem::transmute::<*mut u32, *mut u8>(src) };
90+
let dst = unsafe { core::mem::transmute::<*mut u32, *mut u8>(dst) };
91+
92+
unsafe { alloc::alloc::dealloc(src, Layout::from_size_align_unchecked(size, 16)); }
93+
unsafe { alloc::alloc::dealloc(dst, Layout::from_size_align_unchecked(size, 16)); }
94+
95+
let output = format!(
96+
"size: {} bytes
97+
iterations: {}
98+
cpu: {} microseconds
99+
kernel: {} microseconds
100+
dmac: {} microseconds
101+
vfpu: {} microseconds\n\n",
102+
size, iterations, cpu_dur.as_micros(),
103+
kernel_dur.as_micros(), dmac_dur.as_micros(),
104+
vfpu_dur.as_micros()
105+
);
106+
write_to_fd(fd, output);
107+
}
108+
unsafe { psp::sys::sceIoClose(fd) };
109+
}
110+
111+
fn write_to_fd(fd: SceUid, msg: alloc::string::String) {
112+
113+
unsafe {
114+
psp::sys::sceIoWrite(
115+
fd,
116+
msg.as_str().as_bytes().as_ptr() as *const u8 as *const c_void,
117+
msg.len()
118+
)
119+
};
120+
}
121+
122+
extern "C" {
123+
fn memcpy(dst: *mut u8, src: *const u8, num: usize) -> *mut u8;
124+
}

psp/src/sys/dmac.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
psp_extern! {
2+
#![name = "sceDmac"]
3+
#![flags = 0x4001]
4+
#![version = (0x00, 0x11)]
5+
6+
#[psp(0x617F3FE6)]
7+
pub fn sceDmacMemcpy(dst: *mut u32, src: *const u32, size: usize) -> i32;
8+
}

psp/src/sys/kernel/mod.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -645,8 +645,8 @@ psp_extern! {
645645

646646
psp_extern! {
647647
#![name = "Kernel_Library"]
648-
#![flags = 0x0001]
649-
#![version = (0x00, 0x00)]
648+
#![flags = 0x0011]
649+
#![version = (0x00, 0x01)]
650650

651651
#[psp(0x092968F4)]
652652
/// Suspend all interrupts.
@@ -691,6 +691,12 @@ psp_extern! {
691691
///
692692
/// 1 if interrupts are currently enabled.
693693
pub fn sceKernelIsCpuIntrEnable() -> i32;
694+
695+
#[psp(0x1839852A)]
696+
pub fn sceKernelMemcpy(dst: *mut u32, src: *const u32, num: usize) -> *mut u32;
697+
698+
#[psp(0xA089ECA4)]
699+
pub fn sceKernelMemset(dst: *mut u32, val: u32, num: usize) -> *mut u32;
694700
}
695701

696702
#[repr(C)]

psp/src/sys/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ pub use font::*;
107107
mod psmf;
108108
pub use psmf::*;
109109

110+
mod dmac;
111+
pub use dmac::*;
112+
113+
mod vfpu;
114+
pub use vfpu::*;
115+
110116
// These are not found (likely because this was tested in user mode on a PSP-2000).
111117
// pub mod sircs;
112118
// pub mod codec;

psp/src/sys/vfpu.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//#[no_mangle]
2+
//pub unsafe extern "C" fn sceVfpuMemcpy(
3+
//dst: *mut u8,
4+
//src: *const u8,
5+
//size: usize,
6+
//) -> *mut u8 {
7+
//if size == 0 {
8+
//return dst
9+
//}
10+
11+
//let mut size = size;
12+
//let mut dst8 = dst;
13+
//let mut src8 = src;
14+
15+
//if ((src8 as u32)&0xF) == 0 //Both src and dst are 16byte aligned
16+
//{
17+
//while size > 63 {
18+
//vfpu_asm!(
19+
//lv.q C000, 0(a1);
20+
//lv.q C010, 16(a1);
21+
//lv.q C020, 32(a1);
22+
//lv.q C030, 48(a1);
23+
//sv.q C000, 0(a0);
24+
//sv.q C010, 16(a0);
25+
//sv.q C020, 32(a0);
26+
//sv.q C030, 48(a0);
27+
//: : "{4}"(dst8), "{5}"(src8), "{6}"(size) : "memory" : "volatile"
28+
//);
29+
//dst8 = dst8.add(64);
30+
//src8 = src8.add(64);
31+
//size = size.saturating_sub(64);
32+
//}
33+
34+
//while size > 15 {
35+
//vfpu_asm!(
36+
//lv.q C000, 0(a1);
37+
//sv.q C000, 0(a0);
38+
//: : "{4}"(dst8), "{5}"(src8), "{6}"(size) : "memory" : "volatile"
39+
//)
40+
//dst8 = dst8.add(16);
41+
//src8 = src8.add(16);
42+
//size = size.saturating_sub(16);
43+
//}
44+
45+
//let mut dst32 = dst8 as *mut u32;
46+
//let mut src32 = src8 as *const u32;
47+
48+
//while size > 3 {
49+
//*dst32 = *src32;
50+
//dst32 = dst32.add(1);
51+
//src32 = src32.add(1);
52+
//size = size.saturating_sub(4);
53+
//}
54+
55+
//while size > 0 {
56+
//*dst8 = *src8;
57+
//dst8 = dst8.add(1);
58+
//src8 = src8.add(1);
59+
//size = size.saturating_sub(1);
60+
//}
61+
//dst
62+
//} else {
63+
//panic!("Unaligned vfpu memcpy");
64+
//}
65+
//}

0 commit comments

Comments
 (0)