#include <debug.h>
#include <mach_kgdb.h>
#include <mach_vm_debug.h>
#include <db_machine_commands.h>
#include <kern/thread.h>
#include <mach/vm_attributes.h>
#include <mach/vm_param.h>
#include <vm/vm_kern.h>
#include <vm/vm_map.h>
#include <vm/vm_page.h>
#include <kern/spl.h>
#include <kern/misc_protos.h>
#include <ppc/exception.h>
#include <ppc/misc_protos.h>
#include <ppc/proc_reg.h>
#include <vm/pmap.h>
#include <ppc/pmap.h>
#include <ppc/mem.h>
#include <ppc/new_screen.h>
#include <ppc/Firmware.h>
#include <ppc/mappings.h>
#include <ddb/db_output.h>
#include <console/video_console.h>
#define patper 253
int main(void);
void clrarea(unsigned int *source, unsigned int *sink);
int tstcopy(void *src, void *snk, unsigned int lgn);
void clrarea2(unsigned int *source, unsigned int *sink);
int tstcopy2(void *src, void *snk, unsigned int lgn);
int tstcopy3(void *src, void *snk, unsigned int lgn);
int tstcopy4(void *src, void *snk, unsigned int lgn);
int tstcopy5(void *src, void *snk, unsigned int lgn);
int dumbcopy(void *src, void *snk, unsigned int lgn);
unsigned int gtick(void);
void bcopytest(void);
void bcopytest(void) {
void *srcptr, *snkptr, *asrc, *asnk;
int bsrc, bsnk, size, i, ret, n;
volatile int dbg = 0;
unsigned int *sink, *source;
kern_return_t retr;
db_printf("bcopy test\n");
retr = kmem_alloc_wired(kernel_map, (vm_offset_t *)&sink, (1024*1024)+4096);
if(retr != KERN_SUCCESS) {
panic("bcopytest: Whoops... no memory for sink\n");
}
retr = kmem_alloc_wired(kernel_map, (vm_offset_t *)&source, (1024*1024)+4096);
if(retr != KERN_SUCCESS) {
panic("bcopytest: Whoops... no memory for source\n");
}
db_printf("Source at %08X; Sink at %08X\n", source, sink);
srcptr = (void *)&source[0];
snkptr = (void *)&sink[0];
#if 1
db_printf("Testing non-overlap case; source bndry = 0 to 7F; sink bndry = 0 - 7F; lgn = 1 to 256\n");
for(bsrc = 0; bsrc < 128; bsrc++) {
for(bsnk = 0; bsnk < 128; bsnk++) {
for(size = 1; size <= 256; size++) {
clrarea(source, sink);
if(size == 255) {
dbg = 99;
}
if(tstcopy((void *)((unsigned int)srcptr + bsrc), (void *)((unsigned int)snkptr + bsnk), size)) {
db_printf("Test failed; source = %02X; sink = %02X; length = %d\n", bsrc, bsnk, size);
db_printf("failed\n");
}
}
}
}
db_printf("Non-overlap test complete\n");
#endif
#if 1
db_printf("Testing overlap\n");
for(bsrc = 1; bsrc < 128; bsrc++) {
for(bsnk = 0; bsnk < 128; bsnk++) {
for(size = 1; size <= 256; size++) {
clrarea2(source, sink);
if(bsrc < bsnk) {
dbg = 88;
}
else {
dbg = 99;
}
if(tstcopy2((void *)((unsigned int)srcptr + bsrc), (void *)((unsigned int)srcptr + bsnk), size)) {
db_printf("Test failed; source = %02X; sink = %02X; length = %d\n", bsrc, bsnk, size);
db_printf("failed\n");
}
}
}
}
db_printf("Overlap test complete\n");
#endif
#if 1
db_printf("Starting exhaustive tests\n");
for(i = 0; i < 262144 * 4; i++) {
((unsigned char *)srcptr)[i] = i % patper;
((unsigned char *)snkptr)[i] = i % patper;
}
db_printf("No overlap; source < sink, length = 0 to 1023\nSource =");
#if 1
for(bsrc = 0; bsrc < 128; bsrc++) {
db_printf(" %3d", bsrc);
for(bsnk = 0; bsnk < 128; bsnk++) {
for(size = 0; size < 1025; size++) {
asrc = (void *)((unsigned int)srcptr + bsrc);
asnk = (void *)((unsigned int)srcptr + bsnk + 2048);
ret = tstcopy5(asrc, asnk, size);
if(ret) {
db_printf("\nTest failed - source = %3d, sink = %3d size = %d\n", bsrc, bsnk, size);
db_printf("failed\n");
}
}
}
}
#endif
db_printf("\n");
db_printf("No overlap; source > sink, length = 0 to 1023\nSource =");
#if 1
for(bsrc = 0; bsrc < 128; bsrc++) {
db_printf(" %3d", bsrc);
for(bsnk = 0; bsnk < 128; bsnk++) {
for(size = 0; size < 1025; size++) {
asrc = (void *)((unsigned int)srcptr + bsrc + 2048);
asnk = (void *)((unsigned int)srcptr + bsnk);
ret = tstcopy5(asrc, asnk, size);
if(ret) {
db_printf("\nTest failed - source = %3d, sink = %3d size = %d\n", bsrc, bsnk, size);
db_printf("failed\n");
}
}
}
}
#endif
db_printf("\n");
db_printf("Overlap; source = sink + N (N = 0 to 127), length = 0 to 1023\nN =");
#if 1
for(n = 0; n < 128; n++) {
db_printf(" %3d", n);
for(bsnk = 0; bsnk < 128; bsnk++) {
for(size = 0; size < 1025; size++) {
asrc = (void *)((unsigned int)srcptr + bsnk + n);
asnk = (void *)((unsigned int)srcptr + bsnk);
ret = tstcopy5(asrc, asnk, size);
if(ret) {
db_printf("\nTest failed - source = %3d, sink = %3d size = %d\n", bsrc, bsnk, size);
db_printf("failed\n");
}
}
}
}
#endif
db_printf("\n");
db_printf("Overlap; source + N = sink (N = 0 to 127), length = 0 to 1023\nSource =");
#if 1
for(bsrc = 0; bsrc < 128; bsrc++) {
db_printf(" %3d", bsrc);
for(n = 0; n < 128; n++) {
for(size = 0; size < 1025; size++) {
asrc = (void *)((unsigned int)srcptr + bsnk);
asnk = (void *)((unsigned int)srcptr + bsnk + n);
ret = tstcopy5(asrc, asnk, size);
if(ret) {
db_printf("\nTest failed - source = %3d, n = %3d size = %d\n", bsrc, n, size);
db_printf("failed\n");
}
}
}
}
#endif
db_printf("\n");
db_printf("Overlap; source = sink + N + 128 (N = 0 to 127), length = 0 to 1023\nN =");
#if 1
for(n = 0; n < 128; n++) {
db_printf(" %3d", n);
for(bsnk = 0; bsnk < 128; bsnk++) {
for(size = 0; size < 1025; size++) {
asrc = (void *)((unsigned int)srcptr + bsnk + n + 128);
asnk = (void *)((unsigned int)srcptr + bsnk);
ret = tstcopy5(asrc, asnk, size);
if(ret) {
db_printf("\nTest failed - source = %3d, sink = %3d size = %d\n", bsrc, bsnk, size);
db_printf("failed\n");
}
}
}
}
#endif
db_printf("\n");
db_printf("Overlap; source + N + 128 = sink (N = 0 to 127), length = 0 to 1023\nSource =");
#if 1
for(bsrc = 0; bsrc < 128; bsrc++) {
db_printf(" %3d", bsrc);
for(n = 0; n < 128; n++) {
for(size = 0; size < 1025; size++) {
asrc = (void *)((unsigned int)srcptr + bsnk);
asnk = (void *)((unsigned int)srcptr + bsnk + n + 128);
ret = tstcopy5(asrc, asnk, size);
if(ret) {
db_printf("\nTest failed - source = %3d, n = %3d size = %d\n", bsrc, n, size);
db_printf("failed\n");
}
}
}
}
#endif
db_printf("\n");
db_printf("Overlap; source = sink + N + 256 (N = 0 to 127), length = 0 to 1023\nSource =");
#if 1
for(n = 0; n < 128; n++) {
db_printf(" %3d", n);
for(bsnk = 0; bsnk < 128; bsnk++) {
for(size = 0; size < 1025; size++) {
asrc = (void *)((unsigned int)srcptr + bsnk + n + 256);
asnk = (void *)((unsigned int)srcptr + bsnk);
ret = tstcopy5(asrc, asnk, size);
if(ret) {
db_printf("\nTest failed - source = %3d, sink = %3d size = %d\n", bsrc, bsnk, size);
db_printf("failed\n");
}
}
}
}
#endif
db_printf("\n");
db_printf("Overlap; source + N + 256 = sink (N = 0 to 127), length = 0 to 1023\nSource =");
#if 1
for(bsrc = 0; bsrc < 128; bsrc++) {
db_printf(" %3d", bsrc);
for(n = 0; n < 128; n++) {
for(size = 0; size < 1025; size++) {
asrc = (void *)((unsigned int)srcptr + bsnk);
asnk = (void *)((unsigned int)srcptr + bsnk + n + 256);
ret = tstcopy5(asrc, asnk, size);
if(ret) {
db_printf("\nTest failed - source = %3d, n = %3d size = %d\n", bsrc, n, size);
db_printf("failed\n");
}
}
}
}
#endif
#endif
#if 0
iterations = 1000;
tottime = 0;
totbytes = 0;
db_printf("Random test starting; iterations = %d\n", iterations);
for(i = 0; i < 262144 * 4; i++) {
((unsigned char *)srcptr)[i] = i & 255;
}
for(i = 0; i < iterations; i++) {
makerand = rand() << 16 | (rand() & 0x0000FFFF);
bsrc = makerand & 0x0007FFFF;
makerand = rand() << 16 | (rand() & 0x0000FFFF);
bsnk = makerand & 0x0007FFFF;
makerand = rand() << 16 | (rand() & 0x0000FFFF);
size = makerand & 0x0007FFFF;
#if 1
db_printf("rt %7d: src = %08X; sink = %08X; length = %7d\n", i, ((unsigned int)srcptr + bsrc),
((unsigned int)srcptr + bsnk), size);
#endif
asrc = (void *)((unsigned int)srcptr + bsrc);
asnk = (void *)((unsigned int)srcptr + bsnk);
timein = gtick();
ret = tstcopy3(asrc, asnk, size);
timeout = gtick();
if(ret) {
db_printf("Test failed; source = %02X; sink = %02X; length = %d\n", bsrc, bsnk, size);
db_printf("failed\n");
}
ticks = timeout - timein;
tottime += ticks;
totbytes += size;
rate = (double) totbytes / (double)tottime;
rate = rate * (double)tbfreq;
rate = rate / (double)1000000.0;
db_printf("Total bytes = %lld; total time = %lld; rate = %f10\n", totbytes, tottime, rate);
}
#endif
#if 0
iterations = 100;
tottime = 0;
totbytes = 0;
db_printf("Random test starting; iterations = %d\n", iterations);
for(i = 0; i < 262144 * 4; i++) {
((unsigned char *)srcptr)[i] = i & 255;
}
for(i = 0; i < iterations; i++) {
makerand = rand() << 16 | (rand() & 0x0000FFFF);
bsrc = makerand & 0x0007FFFF;
makerand = rand() << 16 | (rand() & 0x0000FFFF);
bsnk = makerand & 0x0007FFFF;
makerand = rand() << 16 | (rand() & 0x0000FFFF);
size = makerand & 0x0007FFFF;
#if 1
db_printf("rt %7d: src = %08X; sink = %08X; length = %7d\n", i, ((unsigned int)srcptr + bsrc),
((unsigned int)srcptr + bsnk), size);
#endif
asrc = (void *)((unsigned int)srcptr + bsrc);
asnk = (void *)((unsigned int)srcptr + bsnk);
timein = gtick();
ret = tstcopy4(asrc, asnk, size);
timeout = gtick();
if(ret) {
db_printf("Test failed; source = %02X; sink = %02X; length = %d\n", bsrc, bsnk, size);
db_printf("failed\n");
}
ticks = timeout - timein;
tottime += ticks;
totbytes += size;
rate = (double) totbytes / (double)tottime;
rate = rate * (double)tbfreq;
rate = rate / (double)1000000.0;
db_printf("Total bytes = %lld; total time = %lld; rate = %f10\n", totbytes, tottime, rate);
}
#endif
#if 0
iterations = 100;
tottime = 0;
totbytes = 0;
db_printf("Random test starting; iterations = %d\n", iterations);
for(i = 0; i < 262144 * 4; i++) {
((unsigned char *)srcptr)[i] = i & 255;
}
for(i = 0; i < iterations; i++) {
makerand = rand() << 16 | (rand() & 0x0000FFFF);
bsrc = makerand & 0x0007FFFF;
makerand = rand() << 16 | (rand() & 0x0000FFFF);
bsnk = makerand & 0x0007FFFF;
makerand = rand() << 16 | (rand() & 0x0000FFFF);
size = makerand & 0x0007FFFF;
#if 1
db_printf("rt %7d: src = %08X; sink = %08X; length = %7d\n", i, ((unsigned int)srcptr + bsrc),
((unsigned int)srcptr + bsnk), size);
#endif
asrc = (void *)((unsigned int)srcptr + bsrc);
asnk = (void *)((unsigned int)srcptr + bsnk);
timein = gtick();
ret = dumbcopy(asrc, asnk, size);
timeout = gtick();
if(ret) {
db_printf("Test failed; source = %02X; sink = %02X; length = %d\n", bsrc, bsnk, size);
db_printf("failed\n");
}
ticks = timeout - timein;
tottime += ticks;
totbytes += size;
rate = (double) totbytes / (double)tottime;
rate = rate * (double)tbfreq;
rate = rate / (double)1000000.0;
db_printf("Total bytes = %lld; total time = %lld; rate = %f10\n", totbytes, tottime, rate);
}
#endif
kmem_free(kernel_map, (vm_offset_t) sink, (1024*1024)+4096);
kmem_free(kernel_map, (vm_offset_t) source, (1024*1024)+4096);
if(dbg == 22) db_printf("Gabbagoogoo\n");
return;
}
void clrarea(unsigned int *source, unsigned int *sink) {
unsigned int i;
for(i=0; i < 1024; i++) {
source[i] = 0x55555555;
sink[i] = 0xAAAAAAAA;
}
return;
}
void
clrarea2(unsigned int *source, __unused unsigned int *sink)
{
unsigned int i;
unsigned char *ss;
ss = (unsigned char *)&source[0];
for(i=0; i < 1024 * 4; i++) {
ss[i] = i & 0xFF;
}
return;
}
int tstcopy(void *src, void *snk, unsigned int lgn) {
unsigned int i, crap;
bcopy(src, snk, lgn);
for(i = 0; i < lgn; i++) {
if(((unsigned char *)snk)[i] != 0x55) {
crap = (unsigned int)&((unsigned char *)snk)[i];
db_printf("bad copy at sink[%d] (%08X) it is %02X\n", i,crap, ((unsigned char *)snk)[i]);
return 1;
}
}
if(((unsigned char *)snk)[lgn] != 0xAA) {
crap = (unsigned int)&((unsigned char *)snk)[i];
db_printf("Copied too far at sink[%d] (%08X) it is %02X\n", i, crap, ((unsigned char *)snk)[lgn]);
return 1;
}
return 0;
}
int tstcopy2(void *src, void *snk, unsigned int lgn) {
unsigned int i, crap;
unsigned char ic, ec;
ic = ((unsigned char *)src)[0];
ec = ((unsigned char *)snk)[lgn];
bcopy(src, snk, lgn);
for(i = 0; i < lgn; i++) {
if(((unsigned char *)snk)[i] != ic) {
crap = (unsigned int)&((unsigned char *)snk)[i];
db_printf("bad copy at sink[%d] (%08X) it is %02X\n", i,crap, ((unsigned char *)snk)[i]);
return 1;
}
ic = (ic + 1) & 0xFF;
}
if(((unsigned char *)snk)[lgn] != ec) {
crap = (unsigned int)&((unsigned char *)snk)[i];
db_printf("Copied too far at sink[%d] (%08X) it is %02X\n", i, crap, ((unsigned char *)snk)[lgn]);
return 1;
}
return 0;
}
int tstcopy3(void *src, void *snk, unsigned int lgn) {
unsigned int i, crap;
unsigned char ic, ec, oic;
oic = ((unsigned char *)snk)[0];
ic = ((unsigned char *)src)[0];
ec = ((unsigned char *)snk)[lgn];
bcopy(src, snk, lgn);
for(i = 0; i < lgn; i++) {
if(((unsigned char *)snk)[i] != ic) {
crap = (unsigned int)&((unsigned char *)snk)[i];
db_printf("bad copy at sink[%d] (%08X) it is %02X\n", i ,crap, ((unsigned char *)snk)[i]);
return 1;
}
ic = (ic + 1) & 0xFF;
}
if(((unsigned char *)snk)[lgn] != ec) {
crap = (unsigned int)&((unsigned char *)snk)[i];
db_printf("Copied too far at sink[%d] (%08X) it is %02X\n", i, crap, ((unsigned char *)snk)[lgn]);
return 1;
}
for(i=0; i < lgn; i++) {
((unsigned char *)snk)[i] = oic;
oic = (oic + 1) & 0xFF;
}
return 0;
}
int tstcopy4(void *src, void *snk, unsigned int lgn) {
bcopy(src, snk, lgn);
return 0;
}
int tstcopy5(void *src, void *snk, unsigned int lgn) {
unsigned int i = 0, crap;
unsigned char ic, ec, oic, pc;
oic = ((unsigned char *)snk)[0];
ic = ((unsigned char *)src)[0];
ec = ((unsigned char *)snk)[lgn];
pc = ((unsigned char *)snk)[-1];
bcopy(src, snk, lgn);
if(((unsigned char *)snk)[lgn] != ec) {
crap = (unsigned int)&((unsigned char *)snk)[i];
db_printf("Copied too far at sink[%d] (%08X) it is %02X\n", i, crap, ((unsigned char *)snk)[lgn]);
return 1;
}
if(((unsigned char *)snk)[-1] != pc) {
crap = (unsigned int)&((unsigned char *)snk)[i];
db_printf("Copied too far at sink[%d] (%08X) it is %02X\n", i, crap, ((unsigned char *)snk)[lgn]);
return 1;
}
for(i = 0; i < lgn; i++) {
if(((unsigned char *)snk)[i] != ic) {
crap = (unsigned int)&((unsigned char *)snk)[i];
db_printf("bad copy at sink[%d] (%08X) it is %02X\n", i ,crap, ((unsigned char *)snk)[i]);
return 1;
}
ic = (ic + 1) % patper;
}
for(i=0; i < lgn; i++) {
((unsigned char *)snk)[i] = oic;
oic = (oic + 1) % patper;
}
return 0;
}
int dumbcopy(void *src, void *snk, unsigned int lgn) {
unsigned int i;
char *p = (char *)snk;
char *q = (char *)src;
for(i = 0; i < lgn; i++) {
*p++ = *q++;
}
return 0;
}