I am trying to figure out how to perform a PCI burst read on an
in-house PCI card. Currently I use a loop that reads the address of
the PCI card and stores the data into a buffer. I would like to find a
faster approach.
I’ve been trying to use in-line assembly code but can’t figure out
the correct protocol. Any clues? I’m looking for maybe an example of
a multiple read from a PCI card or some help with in-line assembly code.
Thanks,
Ryan Fauth
MESH Inc.
I’m not familliar with PCI burst read, but wouldn’t the memcpy (in
confunction with the -Oi
flag) be the fastest. mempcy becomes inline code.
…
“ryan fauth” <ryan@fauth.com> wrote in message
news:3A411810.524E2A1E@fauth.com…
I am trying to figure out how to perform a PCI burst read on an
in-house PCI card. Currently I use a loop that reads the address of
the PCI card and stores the data into a buffer. I would like to find a
faster approach.
I’ve been trying to use in-line assembly code but can’t figure out
the correct protocol. Any clues? I’m looking for maybe an example of
a multiple read from a PCI card or some help with in-line assembly code.
Thanks,
Ryan Fauth
MESH Inc.
Ok, I think using memcpy is what I need to do. A couple of questions:
- I couldn’t find the flag -Oi, but I’m guessing it has something to do
with inline Optimization… - If I have one double word pointer for my PCI card address, how do I use
that with memcpy, just pass
the address as the source or do I need to declare it differently using
malloc or something.
Thanks,
Ryan
Mario Charest wrote:
I’m not familliar with PCI burst read, but wouldn’t the memcpy (in
confunction with the -Oi
flag) be the fastest. mempcy becomes inline code.
.
“ryan fauth” <> ryan@fauth.com> > wrote in message
news:> 3A411810.524E2A1E@fauth.com> …
I am trying to figure out how to perform a PCI burst read on an
in-house PCI card. Currently I use a loop that reads the address of
the PCI card and stores the data into a buffer. I would like to find a
faster approach.
I’ve been trying to use in-line assembly code but can’t figure out
the correct protocol. Any clues? I’m looking for maybe an example of
a multiple read from a PCI card or some help with in-line assembly code.
Thanks,
Ryan Fauth
MESH Inc.
Hi Ryan,
Check out the docs on mmap() (you can find this in the help docs).
Erick.
ryan fauth <ryan@fauth.com> wrote:
I am trying to figure out how to perform a PCI burst read on an
in-house PCI card. Currently I use a loop that reads the address of
the PCI card and stores the data into a buffer. I would like to find a
faster approach.
I’ve been trying to use in-line assembly code but can’t figure out
the correct protocol. Any clues? I’m looking for maybe an example of
a multiple read from a PCI card or some help with in-line assembly code.
Thanks,
Ryan Fauth
MESH Inc.
I have done several PCI pro audio cards.
The fastest transfer would be repeated dword transfers, or in ASM
rep movsd
To use this, you must map the physical address of the memory on the PCI card
into your program.
See mmap().
ryan fauth <ryan@fauth.com> wrote in message
news:3A422E21.EE0C688B@fauth.com…
Ok, I think using memcpy is what I need to do. A couple of questions:
- I couldn’t find the flag -Oi, but I’m guessing it has something to
do
with inline Optimization…- If I have one double word pointer for my PCI card address, how do I
use
that with memcpy, just pass
the address as the source or do I need to declare it differently
using
malloc or something.
Thanks,Ryan
Mario Charest wrote:I’m not familliar with PCI burst read, but wouldn’t the memcpy (in
confunction with the -Oi
flag) be the fastest. mempcy becomes inline code.
.
“ryan fauth” <> ryan@fauth.com> > wrote in message
news:> 3A411810.524E2A1E@fauth.com> …
I am trying to figure out how to perform a PCI burst read on
an
in-house PCI card. Currently I use a loop that reads the address
of
the PCI card and stores the data into a buffer. I would like to find
a
faster approach.
I’ve been trying to use in-line assembly code but can’t figure
out
the correct protocol. Any clues? I’m looking for maybe an example
of
a multiple read from a PCI card or some help with in-line assembly
code.
Thanks,
Ryan Fauth
MESH Inc.
I am trying to figure out how to perform a PCI burst read on an
in-house PCI card.
I did a project a while back on a ram/memory card. I recall that
the PCI burst feature on this card was only available when
using the cards DMA feature. It moved data at close to
30MegaBYTE/sec. Using code to move the data via shared
memory brought the speed down quite a few notches.
Mitchell Schoenbrun --------- maschoen@pobox.com
“ryan fauth” <ryan@fauth.com> wrote in message
news:3A422E21.EE0C688B@fauth.com…
Ok, I think using memcpy is what I need to do. A couple of questions:
- I couldn’t find the flag -Oi, but I’m guessing it has something to
do
with inline Optimization…
Woops sorry I got confuse with QNX4. If fairly confident if you use
-O2 gcc will inline the memcpy. I never looked at the assembly code
but this is basic optimisation
I think I am using the mmapping functions properly. Since I know the PCI card
memory address, I use mmap_device_memory, like this:
long *ret_addr;
ret_addr = mmap_device_memory(0, sizeof(long),
PROT_READ|PROT_WRITE|PROT_NOCACHE, MAP_SHARED, mem_location);
I can then write to this address and read from it multiple times like this:
*ret_addr = PCI_command_to_send;
// loop for buffer size
buffer[x++] = *ret_addr;
My problem is I can’t read from the card fast enough, I can never empty the
buffer on the card. Using asm seems like a logical way to go, but I
haven’t found any good examples, or info on how to do this, I looked at the GNU
web page on compiling assembly code, and this just confused me even more. I
have Watcom code for a movsd function, but this uses an asm{} pragma, and isn’t
like gcc at all.
So, if using asm is the way to speed the read cycle up, how do I use it?
Thanks,
Ryan
Bill at Sierra Design wrote:
I have done several PCI pro audio cards.
The fastest transfer would be repeated dword transfers, or in ASM
rep movsdTo use this, you must map the physical address of the memory on the PCI card
into your program.See mmap().
ryan fauth wrote:
I think I am using the mmapping functions properly. Since I know the PCI card
memory address, I use mmap_device_memory, like this:
long *ret_addr;
ret_addr = mmap_device_memory(0, sizeof(long),
PROT_READ|PROT_WRITE|PROT_NOCACHE, MAP_SHARED, mem_location);I can then write to this address and read from it multiple times like this:
*ret_addr = PCI_command_to_send;
// loop for buffer size
buffer[x++] = *ret_addr;My problem is I can’t read from the card fast enough, I can never empty the
buffer on the card. Using asm seems like a logical way to go, but I
haven’t found any good examples, or info on how to do this, I looked at the GNU
web page on compiling assembly code, and this just confused me even more. I
have Watcom code for a movsd function, but this uses an asm{} pragma, and isn’t
like gcc at all.
Try memmove(buffer, ret_addr, buffer_size) plus
the -O2 option (as Mario mentioned) … and
disassemble the object file. The inline code
should be more or less optimal.
Armin
Many thanks for all the help, it’s been appreciated, however, I believe I’m
still stuck in confusion land.
I’ve used objdump on an object file to try and find the inline code for
memmove: I can’t figure out what in the assembly code I need to use:
here is the C file and resulting objdump output
--------- snip -----------
int main(int argc, char *argv[])
{
long *addr1;
long rbuf[100];
addr1 = 0xC0000000L;
memmove(rbuf,addr1,40000);
exit(1);
}
#objdump -D code.c
code.o: file format elf32-i386
Disassembly of section .text:
0000000000000000 :
0: 55 pushl %ebp
1: 89 e5 movl %esp,%ebp
3: 81 ec 98 01 00 subl $0x198,%esp
8: 00
9: 83 c4 fc addl $0xfffffffc,%esp
c: 68 40 9c 00 00 pushl $0x9c40
11: 68 00 00 00 c0 pushl $0xc0000000
16: 8d 85 70 fe ff leal 0xfffffe70(%ebp),%eax
1b: ff
1c: 50 pushl %eax
1d: e8 fc ff ff ff call 1e <main+0x1e>
22: 83 c4 f4 addl $0xfffffff4,%esp
25: 6a 01 pushl $0x1
27: e8 fc ff ff ff call 28 <main+0x28>
– Would I want to use the last 4 lines somehow with asm to get data from an
address?
I have assembly code (Watcom style) that uses a function called movsd, that
Bill had mentioned, but it has op codes that gnu doesn’t use:
void movsd(void *from, void *to, int count)
{
_asm{
mov cx,count
lds si,from
les di,to
rep movsd
}
}
But lds, and les aren’t used by gnu so I would have to figure out what these
do and apply that in gnu language.
In case you’re as lost as I am, this is my dilemma:
------------ snip ------------------
ret_addr = mmap_device_memory(0,
sizeof(long),PROT_READ|PROT_WRITE|PROT_NOCACHE, MAP_SHARED, mem_location);
// loop for buffer size
buffer[x++] = *ret_addr;
This code yields PCI bus read signals around 4Mhz, it’s a 33Mhz bus! - I must
be able to read faster somehow.
Ryan Fauth
In my dealings with PCI based reflective memory cards, I was only able to get
approximately 25 megabytes/second when reading without using DMA. This was
also utilizing 100% of the CPU on a 400Mhz Pentium. Needless to say that
project was scrapped, and my suggestion to you is to somehow get DMA to play
with or you’re going to be disappointed. There’s just no way to do the reads
via CPU in an efficient manner. There are a few tricks you can do with writes,
but they don’t apply to reads.
If you insist on trying this without DMA (not recommended), then the assembley
you’re looking for is basically the string move instruction with the repeat
prefix, REP MOVS. Of course you’ll want to use the 32-bit variant of this for
maximum efficiency. The way it works is DS:ESI points to the source memory
address, ES:EDI points to the destination memory address, and ECX contains the
number of DWORDS (bytes / 4) to be moved. The Watcom example you have below is
16-bit code, hence the SI and DI as opposed to ESI and EDI references. “LDS
SI, from” loads DS with the data segment value of the label “from”, and loads
SI with the offset of “from”. You could do “LDS ESI, from” and “LES ESI, to”
to get the desired 32-bit result where from is the source address and to is the
destination. I’m not sure how GCC treats ES, so it’s safest to push it before
you mangle it. You want something like this:
pushl %es # Preserve registers
pushl %eax
pushl %ecx
pushl %esi
pushl %edi
movl %ds, %eax # DS to EAX
movl %eax, %es # EAX to ES
movl $from, %esi # Source offset to ESI
movl $to, %edi # Dest offset to EDI
movl $10000, %ecx # DWORD count to ECX
rep; movsl # Move the memory
popl %edi
popl %esi
popl %ecx
popl %eax
popl %es # Restore registers
If you’re not moving an even number of dwords then you’ll have to do some
mucking about with a “REP; MOVSB” followup to catch the straggling bytes, so I
suggest moving an even number of DWORDS. You’ll be best off straight-lining
this code in your program so you don’t incurr the overhead of a function call.
The above code assumes “from” and “to” are DWORD variables defined somewhere in
the program. You’ll have to get someone else to tell you exactly how to insert
this type of code in the middle of a function, as I haven’t gotten around to
playing with that part of it yet. I believe Colin Burgess gave me an example
in a different thread before he blasted off Down Under (lucky bastard!). I
hope this helps…
-Warren “SEE the cpu… BE, the cpu…” Peece
“ryan fauth” <ryan@fauth.com> wrote in message
news:3A49506C.781FFDFA@fauth.com…
| Many thanks for all the help, it’s been appreciated, however, I believe I’m
| still stuck in confusion land.
|
| I’ve used objdump on an object file to try and find the inline code for
| memmove: I can’t figure out what in the assembly code I need to use:
| here is the C file and resulting objdump output
|
| --------- snip -----------
| int main(int argc, char *argv[])
| {
| long *addr1;
| long rbuf[100];
|
| addr1 = 0xC0000000L;
| memmove(rbuf,addr1,40000);
|
| exit(1);
} |
---|
#objdump -D code.c |
code.o: file format elf32-i386 |
Disassembly of section .text: |
0000000000000000 : |
0: 55 pushl %ebp |
1: 89 e5 movl %esp,%ebp |
3: 81 ec 98 01 00 subl $0x198,%esp |
8: 00 |
9: 83 c4 fc addl $0xfffffffc,%esp |
c: 68 40 9c 00 00 pushl $0x9c40 |
11: 68 00 00 00 c0 pushl $0xc0000000 |
16: 8d 85 70 fe ff leal 0xfffffe70(%ebp),%eax |
1b: ff |
1c: 50 pushl %eax |
1d: e8 fc ff ff ff call 1e <main+0x1e> |
22: 83 c4 f4 addl $0xfffffff4,%esp |
25: 6a 01 pushl $0x1 |
27: e8 fc ff ff ff call 28 <main+0x28> |
# |
– Would I want to use the last 4 lines somehow with asm to get data from an |
address? |
I have assembly code (Watcom style) that uses a function called movsd, that |
Bill had mentioned, but it has op codes that gnu doesn’t use: |
void movsd(void *from, void *to, int count) |
{ |
_asm{ |
mov cx,count |
lds si,from |
les di,to |
rep movsd |
} |
} |
But lds, and les aren’t used by gnu so I would have to figure out what these |
do and apply that in gnu language. |
In case you’re as lost as I am, this is my dilemma: |
------------ snip ------------------ |
ret_addr = mmap_device_memory(0, |
sizeof(long),PROT_READ |
// loop for buffer size |
buffer[x++] = *ret_addr; |
------------------------------------ |
This code yields PCI bus read signals around 4Mhz, it’s a 33Mhz bus! - I |
must
| be able to read faster somehow.
Uhm, not necessarily.
| Ryan Fauth
|
|
|
would an MMX 64 bit move go faster?
probably if you had 64 bit PCI bus
or - if your host-PCI chip turns 64 bit requests into a burst read
or other multi-word access (strings? BCD?)
IANA assembly programmer
ryan fauth <ryan@fauth.com> wrote in message
news:3A49506C.781FFDFA@fauth.com…
Many thanks for all the help, it’s been appreciated, however, I believe
I’m
still stuck in confusion land.------------ snip ------------------
This code yields PCI bus read signals around 4Mhz, it’s a 33Mhz bus! - I
must
be able to read faster somehow.
Ryan Fauth
Eeks! I didn’t quite get part of that right as far as the addresses of the
buffers goes. Assuming you have something like:
void *ret_addr;
uint8_t buffer[40000];
You’ll want to do:
movl ret_addr, %esi # Load contents of “ret_addr” to ESI
movl $buffer, %edi # Load address of “buffer” to EDI
The $ tells the assembler to treat the value as immediate, so $buffer refers to
the offset of buffer within the data segment (or the address of buffer, if you
will). The “movl ret_addr, %esi” takes the DWORD stored at where ret_addr is
in the data segment, which would be the address of your PCI memory as retrieved
from the mmap_device_memory() call. The difference is subtle, but important.
Apply the above two lines in the example below, and who knows, it may even
work!
-Warren
“Warren Peece” <warren@nospam.com> wrote in message
news:92d26m$6du$1@inn.qnx.com…
| In my dealings with PCI based reflective memory cards, I was only able to get
| approximately 25 megabytes/second when reading without using DMA. This was
| also utilizing 100% of the CPU on a 400Mhz Pentium. Needless to say that
| project was scrapped, and my suggestion to you is to somehow get DMA to play
| with or you’re going to be disappointed. There’s just no way to do the reads
| via CPU in an efficient manner. There are a few tricks you can do with
writes,
| but they don’t apply to reads.
|
| If you insist on trying this without DMA (not recommended), then the
assembley
| you’re looking for is basically the string move instruction with the repeat
| prefix, REP MOVS. Of course you’ll want to use the 32-bit variant of this
for
| maximum efficiency. The way it works is DS:ESI points to the source memory
| address, ES:EDI points to the destination memory address, and ECX contains
the
| number of DWORDS (bytes / 4) to be moved. The Watcom example you have below
is
| 16-bit code, hence the SI and DI as opposed to ESI and EDI references. “LDS
| SI, from” loads DS with the data segment value of the label “from”, and loads
| SI with the offset of “from”. You could do “LDS ESI, from” and “LES ESI, to”
| to get the desired 32-bit result where from is the source address and to is
the
| destination. I’m not sure how GCC treats ES, so it’s safest to push it
before
| you mangle it. You want something like this:
|
| pushl %es # Preserve registers
| pushl %eax
| pushl %ecx
| pushl %esi
| pushl %edi
|
| movl %ds, %eax # DS to EAX
| movl %eax, %es # EAX to ES
| movl $from, %esi # Source offset to ESI
| movl $to, %edi # Dest offset to EDI
| movl $10000, %ecx # DWORD count to ECX
| rep; movsl # Move the memory
|
| popl %edi
| popl %esi
| popl %ecx
| popl %eax
| popl %es # Restore registers
|
| If you’re not moving an even number of dwords then you’ll have to do some
| mucking about with a “REP; MOVSB” followup to catch the straggling bytes, so
I
| suggest moving an even number of DWORDS. You’ll be best off straight-lining
| this code in your program so you don’t incurr the overhead of a function
call.
| The above code assumes “from” and “to” are DWORD variables defined somewhere
in
| the program. You’ll have to get someone else to tell you exactly how to
insert
| this type of code in the middle of a function, as I haven’t gotten around to
| playing with that part of it yet. I believe Colin Burgess gave me an example
| in a different thread before he blasted off Down Under (lucky bastard!). I
| hope this helps…
|
| -Warren “SEE the cpu… BE, the cpu…” Peece
|
|
|
| “ryan fauth” <ryan@fauth.com> wrote in message
| news:3A49506C.781FFDFA@fauth.com…
| | Many thanks for all the help, it’s been appreciated, however, I believe I’m
| | still stuck in confusion land.
| |
| | I’ve used objdump on an object file to try and find the inline code for
| | memmove: I can’t figure out what in the assembly code I need to use:
| | here is the C file and resulting objdump output
| |
| | --------- snip -----------
| | int main(int argc, char *argv[])
| | {
| | long *addr1;
| | long rbuf[100];
| |
| | addr1 = 0xC0000000L;
| | memmove(rbuf,addr1,40000);
| |
| | exit(1);
| | }
| | -------------------
| | #objdump -D code.c
| | code.o: file format elf32-i386
| |
| | Disassembly of section .text:
| |
| | 0000000000000000 :
| | 0: 55 pushl %ebp
| | 1: 89 e5 movl %esp,%ebp
| | 3: 81 ec 98 01 00 subl $0x198,%esp
| | 8: 00
| | 9: 83 c4 fc addl $0xfffffffc,%esp
| | c: 68 40 9c 00 00 pushl $0x9c40
| | 11: 68 00 00 00 c0 pushl $0xc0000000
| | 16: 8d 85 70 fe ff leal 0xfffffe70(%ebp),%eax
| | 1b: ff
| | 1c: 50 pushl %eax
| | 1d: e8 fc ff ff ff call 1e <main+0x1e>
| | 22: 83 c4 f4 addl $0xfffffff4,%esp
| | 25: 6a 01 pushl $0x1
| | 27: e8 fc ff ff ff call 28 <main+0x28>
| | #
| |
| | – Would I want to use the last 4 lines somehow with asm to get data from
an
| | address?
| |
| | I have assembly code (Watcom style) that uses a function called movsd, that
| | Bill had mentioned, but it has op codes that gnu doesn’t use:
| | void movsd(void *from, void *to, int count)
| | {
| | _asm{
| | mov cx,count
| | lds si,from
| | les di,to
| | rep movsd
| | }
| | }
| | But lds, and les aren’t used by gnu so I would have to figure out what
these
| | do and apply that in gnu language.
| |
| | In case you’re as lost as I am, this is my dilemma:
| | ------------ snip ------------------
| | ret_addr = mmap_device_memory(0,
| | sizeof(long),PROT_READ|PROT_WRITE|PROT_NOCACHE, MAP_SHARED, mem_location);
| | // loop for buffer size
| | buffer[x++] = *ret_addr;
| | ------------------------------------
| | This code yields PCI bus read signals around 4Mhz, it’s a 33Mhz bus! - I
| must
| | be able to read faster somehow.
|
| Uhm, not necessarily.
|
| | Ryan Fauth
| |
| |
| |
|
|
I tried that, and the answer is “not noticeably on a 32-bit bus”. It should be
an advantage on a 64-bit bus with a 64-bit card, although a 32-bit card on a
64-bit bus probably wouldn’t show any improvement. The time is spent
ka-chunking data cross the relatively slow PCI bus, and the instruction
overhead is insignificant by comparisson. Basically CPU reads of large amounts
of data over the PCI bus are CPU intensive and slow. DMA is a must if you need
any sort of performance whatsoever.
-Warren
“Michael J. Ferrador” <n2kra@orn.com> wrote in message
news:92d3ct$72v$1@inn.qnx.com…
| would an MMX 64 bit move go faster?
|
| probably if you had 64 bit PCI bus
|
| or - if your host-PCI chip turns 64 bit requests into a burst read
| or other multi-word access (strings? BCD?)
| IANA assembly programmer
|
| ryan fauth <ryan@fauth.com> wrote in message
| news:3A49506C.781FFDFA@fauth.com…
| > Many thanks for all the help, it’s been appreciated, however, I believe
| I’m
| > still stuck in confusion land.
| >
| > ------------ snip ------------------
| >
| > This code yields PCI bus read signals around 4Mhz, it’s a 33Mhz bus! - I
| must
| > be able to read faster somehow.
| >
| >
| > Ryan Fauth
|
|
|
Rats, another gotcha:
movw %ds, %ax # DS is 16-bits, not 32!
movw %ax, %es # Same with ES
This is why assembley language programmers are so surly- they’re frustrated out
of their minds by tiny details. You can push and pop segment registers as
DWORDS in 32-bit code though, to keep your stack aligned.
-Warren “I make no promises that any of this is right” Peece
“Warren Peece” <warren@nospam.com> wrote in message
news:92d26m$6du$1@inn.qnx.com…
| In my dealings with PCI based reflective memory cards, I was only able to get
| approximately 25 megabytes/second when reading without using DMA. This was
| also utilizing 100% of the CPU on a 400Mhz Pentium. Needless to say that
| project was scrapped, and my suggestion to you is to somehow get DMA to play
| with or you’re going to be disappointed. There’s just no way to do the reads
| via CPU in an efficient manner. There are a few tricks you can do with
writes,
| but they don’t apply to reads.
|
| If you insist on trying this without DMA (not recommended), then the
assembley
| you’re looking for is basically the string move instruction with the repeat
| prefix, REP MOVS. Of course you’ll want to use the 32-bit variant of this
for
| maximum efficiency. The way it works is DS:ESI points to the source memory
| address, ES:EDI points to the destination memory address, and ECX contains
the
| number of DWORDS (bytes / 4) to be moved. The Watcom example you have below
is
| 16-bit code, hence the SI and DI as opposed to ESI and EDI references. “LDS
| SI, from” loads DS with the data segment value of the label “from”, and loads
| SI with the offset of “from”. You could do “LDS ESI, from” and “LES ESI, to”
| to get the desired 32-bit result where from is the source address and to is
the
| destination. I’m not sure how GCC treats ES, so it’s safest to push it
before
| you mangle it. You want something like this:
|
| pushl %es # Preserve registers
| pushl %eax
| pushl %ecx
| pushl %esi
| pushl %edi
|
| movl %ds, %eax # DS to EAX
| movl %eax, %es # EAX to ES
| movl $from, %esi # Source offset to ESI
| movl $to, %edi # Dest offset to EDI
| movl $10000, %ecx # DWORD count to ECX
| rep; movsl # Move the memory
|
| popl %edi
| popl %esi
| popl %ecx
| popl %eax
| popl %es # Restore registers
|
| If you’re not moving an even number of dwords then you’ll have to do some
| mucking about with a “REP; MOVSB” followup to catch the straggling bytes, so
I
| suggest moving an even number of DWORDS. You’ll be best off straight-lining
| this code in your program so you don’t incurr the overhead of a function
call.
| The above code assumes “from” and “to” are DWORD variables defined somewhere
in
| the program. You’ll have to get someone else to tell you exactly how to
insert
| this type of code in the middle of a function, as I haven’t gotten around to
| playing with that part of it yet. I believe Colin Burgess gave me an example
| in a different thread before he blasted off Down Under (lucky bastard!). I
| hope this helps…
|
| -Warren “SEE the cpu… BE, the cpu…” Peece
|
|
|
| “ryan fauth” <ryan@fauth.com> wrote in message
| news:3A49506C.781FFDFA@fauth.com…
| | Many thanks for all the help, it’s been appreciated, however, I believe I’m
| | still stuck in confusion land.
| |
| | I’ve used objdump on an object file to try and find the inline code for
| | memmove: I can’t figure out what in the assembly code I need to use:
| | here is the C file and resulting objdump output
| |
| | --------- snip -----------
| | int main(int argc, char *argv[])
| | {
| | long *addr1;
| | long rbuf[100];
| |
| | addr1 = 0xC0000000L;
| | memmove(rbuf,addr1,40000);
| |
| | exit(1);
| | }
| | -------------------
| | #objdump -D code.c
| | code.o: file format elf32-i386
| |
| | Disassembly of section .text:
| |
| | 0000000000000000 :
| | 0: 55 pushl %ebp
| | 1: 89 e5 movl %esp,%ebp
| | 3: 81 ec 98 01 00 subl $0x198,%esp
| | 8: 00
| | 9: 83 c4 fc addl $0xfffffffc,%esp
| | c: 68 40 9c 00 00 pushl $0x9c40
| | 11: 68 00 00 00 c0 pushl $0xc0000000
| | 16: 8d 85 70 fe ff leal 0xfffffe70(%ebp),%eax
| | 1b: ff
| | 1c: 50 pushl %eax
| | 1d: e8 fc ff ff ff call 1e <main+0x1e>
| | 22: 83 c4 f4 addl $0xfffffff4,%esp
| | 25: 6a 01 pushl $0x1
| | 27: e8 fc ff ff ff call 28 <main+0x28>
| | #
| |
| | – Would I want to use the last 4 lines somehow with asm to get data from
an
| | address?
| |
| | I have assembly code (Watcom style) that uses a function called movsd, that
| | Bill had mentioned, but it has op codes that gnu doesn’t use:
| | void movsd(void *from, void *to, int count)
| | {
| | _asm{
| | mov cx,count
| | lds si,from
| | les di,to
| | rep movsd
| | }
| | }
| | But lds, and les aren’t used by gnu so I would have to figure out what
these
| | do and apply that in gnu language.
| |
| | In case you’re as lost as I am, this is my dilemma:
| | ------------ snip ------------------
| | ret_addr = mmap_device_memory(0,
| | sizeof(long),PROT_READ|PROT_WRITE|PROT_NOCACHE, MAP_SHARED, mem_location);
| | // loop for buffer size
| | buffer[x++] = *ret_addr;
| | ------------------------------------
| | This code yields PCI bus read signals around 4Mhz, it’s a 33Mhz bus! - I
| must
| | be able to read faster somehow.
|
| Uhm, not necessarily.
|
| | Ryan Fauth
| |
| |
| |
|
|
Hi Ryan,
As was mentioned in a previous message, the one thing that will speed up
your code by a factor of 4 is to do 32 bit transfers.
ryan fauth <ryan@fauth.com> wrote in message
news:3A49506C.781FFDFA@fauth.com…
[stuff removed]
In case you’re as lost as I am, this is my dilemma:
------------ snip ------------------
ret_addr = mmap_device_memory(0,
sizeof(long),PROT_READ|PROT_WRITE|PROT_NOCACHE, MAP_SHARED, mem_location);
// loop for buffer size
buffer[x++] = *ret_addr;This code yields PCI bus read signals around 4Mhz, it’s a 33Mhz bus! - I
must
be able to read faster somehow.
Ryan Fauth