[coreboot] FILO: read time of LPC flash
Nikolay Petukhov
nikolaypetukhov at gmail.com
Thu Mar 13 12:00:12 CET 2008
Hi, all.
Here is simple measure time of reading memory device.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/time.h>
int main(int argc, char *argv[])
{
int fd_mem;
volatile char *pchar;
volatile int *pint;
char *buffer;
int *buffer_int;
struct timeval t1, t2;
long time_transfer;
int i;
int size;
if (argc != 2) {
fprintf(stderr, "Usage: %s size Kb\n", argv[0]);
return 0;
}
size = atoi (argv[1]);
if (!size || size > 2048)
size = 512;
size *= 1024;
if (getuid()) {
fprintf(stderr, "Run me as root, I need access to /dev/mem.\n");
}
fd_mem = open("/dev/mem", O_RDWR);
if (fd_mem < 0) {
perror("Could not open /dev/mem:");
exit(1);
}
pchar = mmap(0, size, PROT_WRITE | PROT_READ, MAP_SHARED,
fd_mem, (off_t) (0xFFFFFFFF - size + 1));
if (pchar == MAP_FAILED) {
perror("Can't mmap registers using /dev/mem");
exit(1);
}
buffer = (char *)malloc (size);
gettimeofday(&t1, NULL);
memcpy (buffer, pchar, size);
gettimeofday(&t2, NULL);
time_transfer = (t2.tv_sec - t1.tv_sec)*1000 + (t2.tv_usec -
t1.tv_usec)/1000;
printf ("memcpy time_transfer %d KB for %ld ms\n", size, time_transfer);
gettimeofday(&t1, NULL);
for (i = 0; i < size; i++)
buffer[i] = pchar[i];
gettimeofday(&t2, NULL);
time_transfer = (t2.tv_sec - t1.tv_sec)*1000 + (t2.tv_usec -
t1.tv_usec)/1000;
printf ("char time_transfer %d KB for %ld ms\n", size, time_transfer);
pint = (int *)pchar;
buffer_int = (int *)buffer;
gettimeofday(&t1, NULL);
for (i = 0; i < size/4; i++) {
buffer_int[i] = pint[i];
}
gettimeofday(&t2, NULL);
time_transfer = (t2.tv_sec - t1.tv_sec)*1000 + (t2.tv_usec -
t1.tv_usec)/1000;
printf ("int time_transfer %d KB for %ld ms\n", size, time_transfer);
free (buffer);
close(fd_mem);
return 0;
}
Result of tests:
1. Board iei/pcisa-lx-800 (AMD LX800 + CS5536), flash sst49lf016c (2048 KB).
./testmem 2048
memcpy time_transfer 2097152 KB for 3478 ms
char time_transfer 2097152 KB for 3592 ms
int time_transfer 2097152 KB for 2086 ms
./testmem 1024
memcpy time_transfer 1048576 KB for 1740 ms
char time_transfer 1048576 KB for 1795 ms
int time_transfer 1048576 KB for 1041 ms
./testmem 512
memcpy time_transfer 524288 KB for 873 ms
char time_transfer 524288 KB for 898 ms
int time_transfer 524288 KB for 521 ms
2. Board iei/pcisa-lx-800(AMD LX800 + CS5536)), flash pm49fl004 (512 KB).
./testmem 512
memcpy time_transfer 524288 KB for 868 ms
char time_transfer 524288 KB for 897 ms
int time_transfer 524288 KB for 524 ms
Conclusion:
For large amounts of speed reading memory flash limited to memcpy () function.
The FILO also use memcpy() for reading memory flash.
This patch add macro READ_OVER_MEMCPY in FILO Config and some code to
blockdev.c. With this patch loading time of kernel and initrd (1.9MB)
redused by 1.5sec.
diff -Nru filo-0.5/defconfig filo-0.5-memcpy/defconfig
--- filo-0.5/defconfig 2008-01-16 19:19:17.000000000 +0500
+++ filo-0.5-memcpy/defconfig 2008-03-13 13:03:14.000000000 +0500
@@ -93,3 +93,6 @@
#DEBUG_USB = 1
#DEBUG_ELTORITO = 1
+#Read flash memory
+#READ_OVER_MEMCPY=1
+
diff -Nru filo-0.5/fs/blockdev.c filo-0.5-memcpy/fs/blockdev.c
--- filo-0.5/fs/blockdev.c 2006-04-29 04:53:26.000000000 +0600
+++ filo-0.5-memcpy/fs/blockdev.c 2008-03-13 13:03:08.000000000 +0500
@@ -361,7 +361,21 @@
len = 512 - byte_offset;
if (len > byte_len)
len = byte_len;
- memcpy(dest, sector_buffer + byte_offset, len);
+
+#ifdef READ_OVER_MEMCPY
+ if (dev_type == DISK_MEM) {
+
+ int * src_int = (int *)(sector_buffer + byte_offset);
+ int * dest_int = (int *)dest;
+ int i;
+
+ for (i = 0; i < len/4; i++)
+ dest_int[i] = src_int[i];
+ }
+ else
+#endif
+ memcpy(dest, sector_buffer + byte_offset, len);
+
sector++;
byte_offset = 0;
byte_len -= len;
--
Nikolay
More information about the coreboot
mailing list