Rod Dore
06/16/2008 11:11 AM
post9193
|
I'm creating some short test applications which access physical memory on a PCI card, in QNX 4.25O, with watcom debugger
10.6.
I'm using the qnx_segment_overlay_flags() call along with the MK_FP() macro to create a pointer to the physical memory..
.. then when I use "wd" to step through the application, when I get to the line which accesses the memory with the
pointer, the system crashes. If I run the application without the debugger, it works fine.
I tried a similar experiment using shn_open() and mmap() calls. The system crashes as soon as I attempt to step over the
mmap() call, but the application runs fine when I run it on its own.
Is there some compile/link switches I need, or some options for "wd' that I should be using? Or some other words of
wisdom?
|
|
|
Mario Charest
06/17/2008 3:47 PM
post9359
|
> I'm creating some short test applications which access physical memory on a
> PCI card, in QNX 4.25O, with watcom debugger 10.6.
>
> I'm using the qnx_segment_overlay_flags() call along with the MK_FP() macro to
> create a pointer to the physical memory.... then when I use "wd" to step
> through the application, when I get to the line which accesses the memory with
> the pointer, the system crashes. If I run the application without the
> debugger, it works fine.
>
> I tried a similar experiment using shn_open() and mmap() calls. The system
> crashes as soon as I attempt to step over the mmap() call, but the application
> runs fine when I run it on its own.
>
> Is there some compile/link switches I need, or some options for "wd' that I
> should be using? Or some other words of wisdom?
It might be speed dependent. For example, the reading of the physical memory may generate an interrupt or some other
fault, which at slow speed ( wd ) is causing grief but manages to run ok without the debugger.
Just a guess.
|
|
|
Rod Dore
06/24/2008 1:09 PM
post9609
|
I've discovered the problem... The code I'm debugging contains __far pointers to physical memory addresses (hardware on
a PCI card).
When the code is being stepped through the functions that contain these pointers, the debugger is attempting to read the
contents of the memory at the pointers. Due to the nature of the hardware, these reads sometimes cannot be accepted.
With a PCI bus analyzer I can see the reads occuring, but since the hardware is not always ready to accept the reads,
the PCI bus goes into perpetual Read Re-Tries. This is what hangs the PC.
I turned off the "Locals" display on the debugger, but this did not stop the debugger from attempting to read the
contents of pointers.
Does anyone know how to stop the debugger from automatically accessing the contents of __far pointers.
....Rod.
|
|
|
Mario Charest
06/24/2008 1:21 PM
post9613
|
Good catch,
I don`t know how to stop the debugger from doing that. However just wanted to point out that using __far pointer is
useless if you are using 32 bit code.
> I've discovered the problem... The code I'm debugging contains __far pointers
> to physical memory addresses (hardware on a PCI card).
>
> When the code is being stepped through the functions that contain these
> pointers, the debugger is attempting to read the contents of the memory at the
> pointers. Due to the nature of the hardware, these reads sometimes cannot be
> accepted. With a PCI bus analyzer I can see the reads occuring, but since the
> hardware is not always ready to accept the reads, the PCI bus goes into
> perpetual Read Re-Tries. This is what hangs the PC.
>
> I turned off the "Locals" display on the debugger, but this did not stop the
> debugger from attempting to read the contents of pointers.
>
> Does anyone know how to stop the debugger from automatically accessing the
> contents of __far pointers.
>
> ....Rod.
|
|
|
Rod Dore
06/24/2008 2:06 PM
post9618
|
How would you suggest that I access the devices on my PCI card?, other than using __far pointers?
Here's what I do now...
1, Use _CA_PCI_Read_Config_DWord() to obtain the Base_Address registers of the PCI device (obtain a list of physical
memory and/or I/O addresses). In my case the BAR's are memory addresses.
2, Seg = qnx_segment_overlay_flags(physical_mem_addr, size, flags); //setup a segment.
3, volatile _my_device __far *ptr; // declare pointer
4. ptr = MK_FP(Seg, offset); // setup the pointer
5. ptr->item1 = value; // write a value to a register in the device. OR
value = ptr->item2; // read a value from some register.
|
|
|
Hugh Brown
06/24/2008 2:13 PM
post9619
|
Are you doing a PCI_MEM_ADDRESS(address) on the address obtained from
the Base Address register before doing the qnx_segment_overlay? What
flags are you passing to the qnx_segment_overlay() function and what is
the value of "offset" in the MK_FP()?
-----Original Message-----
From: Rod Dore [mailto:rod@connecttech.com]
Sent: Tuesday, June 24, 2008 2:07 PM
To: qnx4-community
Subject: Re: "wd" crashes system
How would you suggest that I access the devices on my PCI card?, other
than using __far pointers?
Here's what I do now...
1, Use _CA_PCI_Read_Config_DWord() to obtain the Base_Address registers
of the PCI device (obtain a list of physical memory and/or I/O
addresses). In my case the BAR's are memory addresses.
2, Seg = qnx_segment_overlay_flags(physical_mem_addr, size, flags);
//setup a segment.
3, volatile _my_device __far *ptr; // declare pointer
4. ptr = MK_FP(Seg, offset); // setup the pointer
5. ptr->item1 = value; // write a value to a register in the device.
OR
value = ptr->item2; // read a value from some register.
_______________________________________________
QNX4 Community Support
http://community.qnx.com/sf/go/post9618
|
|
|
Rod Dore
06/24/2008 2:40 PM
post9625
|
Hello Hugh,
I left out a few of the details in the posting. Here's the real code lines
(I've left out most of the declarations).
----------------------------
_CA_PCI_Read_Config_DWord (busnum, devfuncnum,
offsetof(struct _pci_config_regs, Base_Address_Regs[0]),
4, (char *)&address[0]);
MemoryAperture1 = PCI_MEM_ADDR( address[2] );
Seg = qnx_segment_overlay_flags(MemoryAperture1, 0x2000, _PMF_GLOBAL |
_PMF_GLOBAL_OWN);
volatile _my_device __far *ptr;
ptr = MK_FP(Seg, 0);
ptr->register = some_value;
----------------------------
The code works just fine, the problem occurs when "wd" (the debugger) is
used to step through the functions which contain the __far pointer. The
debugger wants to get the value of the object which the pointer points to,
and this causes the problems because the hardware is not always ready to
respond to the resulting reads. Even when the hardware is ready to respond
to the reads, the debugger reads the "memory" in a indiscriminate way, often
accessing register addesses that don't actually exist in the hardware.
It would be great if I could just tell the debugger to NOT access the values
of "Local" function variables.
Regards... Rod Doré rod@connecttech.com
Engineering Manager & Hardware Developer
Connect Tech Inc. www.connecttech.com
1-800-426-8979 x224
> -----Original Message-----
> From: Hugh Brown [mailto:hsbrown@qnx.com]
> Sent: June 24, 2008 2:14 PM
> To: qnx4-community
> Subject: RE: "wd" crashes system
>
> Are you doing a PCI_MEM_ADDRESS(address) on the address
> obtained from the Base Address register before doing the
> qnx_segment_overlay? What flags are you passing to the
> qnx_segment_overlay() function and what is the value of
> "offset" in the MK_FP()?
>
>
> -----Original Message-----
> From: Rod Dore [mailto:rod@connecttech.com]
> Sent: Tuesday, June 24, 2008 2:07 PM
> To: qnx4-community
> Subject: Re: "wd" crashes system
>
> How would you suggest that I access the devices on my PCI
> card?, other than using __far pointers?
>
> Here's what I do now...
>
> 1, Use _CA_PCI_Read_Config_DWord() to obtain the Base_Address
> registers of the PCI device (obtain a list of physical memory
> and/or I/O addresses). In my case the BAR's are memory addresses.
>
> 2, Seg = qnx_segment_overlay_flags(physical_mem_addr, size,
> flags); //setup a segment.
>
> 3, volatile _my_device __far *ptr; // declare pointer
>
> 4. ptr = MK_FP(Seg, offset); // setup the pointer
>
> 5. ptr->item1 = value; // write a value to a register in the device.
> OR
> value = ptr->item2; // read a value from some register.
>
>
> _______________________________________________
> QNX4 Community Support
> http://community.qnx.com/sf/go/post9618
>
>
> _______________________________________________
> QNX4 Community Support
> http://community.qnx.com/sf/go/post9619
>
|
|
|
Hugh Brown
06/24/2008 3:18 PM
post9629
|
Do you have the assembly register window open in the debugger? This could cause a problem, as the debugger is constantly
trying to read that memory to update the window.
-----Original Message-----
From: Rod Dore [mailto:rod@connecttech.com]
Sent: Tuesday, June 24, 2008 2:41 PM
To: qnx4-community
Subject: RE: "wd" crashes system
Hello Hugh,
I left out a few of the details in the posting. Here's the real code lines
(I've left out most of the declarations).
----------------------------
_CA_PCI_Read_Config_DWord (busnum, devfuncnum,
offsetof(struct _pci_config_regs, Base_Address_Regs[0]),
4, (char *)&address[0]);
MemoryAperture1 = PCI_MEM_ADDR( address[2] );
Seg = qnx_segment_overlay_flags(MemoryAperture1, 0x2000, _PMF_GLOBAL |
_PMF_GLOBAL_OWN);
volatile _my_device __far *ptr;
ptr = MK_FP(Seg, 0);
ptr->register = some_value;
----------------------------
The code works just fine, the problem occurs when "wd" (the debugger) is
used to step through the functions which contain the __far pointer. The
debugger wants to get the value of the object which the pointer points to,
and this causes the problems because the hardware is not always ready to
respond to the resulting reads. Even when the hardware is ready to respond
to the reads, the debugger reads the "memory" in a indiscriminate way, often
accessing register addesses that don't actually exist in the hardware.
It would be great if I could just tell the debugger to NOT access the values
of "Local" function variables.
Regards... Rod Doré rod@connecttech.com
Engineering Manager & Hardware Developer
Connect Tech Inc. www.connecttech.com
1-800-426-8979 x224
> -----Original Message-----
> From: Hugh Brown [mailto:hsbrown@qnx.com]
> Sent: June 24, 2008 2:14 PM
> To: qnx4-community
> Subject: RE: "wd" crashes system
>
> Are you doing a PCI_MEM_ADDRESS(address) on the address
> obtained from the Base Address register before doing the
> qnx_segment_overlay? What flags are you passing to the
> qnx_segment_overlay() function and what is the value of
> "offset" in the MK_FP()?
>
>
> -----Original Message-----
> From: Rod Dore [mailto:rod@connecttech.com]
> Sent: Tuesday, June 24, 2008 2:07 PM
> To: qnx4-community
> Subject: Re: "wd" crashes system
>
> How would you suggest that I access the devices on my PCI
> card?, other than using __far pointers?
>
> Here's what I do now...
>
> 1, Use _CA_PCI_Read_Config_DWord() to obtain the Base_Address
> registers of the PCI device (obtain a list of physical memory
> and/or I/O addresses). In my case the BAR's are memory addresses.
>
> 2, Seg = qnx_segment_overlay_flags(physical_mem_addr, size,
> flags); //setup a segment.
>
> 3, volatile _my_device __far *ptr; // declare pointer
>
> 4. ptr = MK_FP(Seg, offset); // setup the pointer
>
> 5. ptr->item1 = value; // write a value to a register in the device.
> OR
> value = ptr->item2; // read a value from some register.
>
>
> _______________________________________________
> QNX4 Community Support
> http://community.qnx.com/sf/go/post9618
>
>
> _______________________________________________
> QNX4 Community Support
> http://community.qnx.com/sf/go/post9619
>
_______________________________________________
QNX4 Community Support
http://community.qnx.com/sf/go/post9625
|
|
|
Rod Dore
06/25/2008 8:29 AM
post9656
|
Hi Hugh,
I turned off ALL windows except the "source" window.
I tried something else yesterday... I moved the declarations for the __far
pointer, outside the function (so that the pointer would not be a "local"
variable). But the debugger behaved the same (ie: it tried to gather up the
contents of the pointer). The __far pointer points to a reasonably long
region of physically memory. Something like the following.
typedef struct {
unsigned short register1;
unsigned short register2;
unsigned char gap[20];
unsigned short register3;
etc... (totaling about 1024 bytes)
}_my_device;
volatile _my_device __far *ptr;
The data structure represents the register layout of the hardware device,
with some registers that can't be accessed (read) in an indiscriminate way,
and there are gaps in the register layout (non-existent locations) which
should not be accessed at all. What's particularily disturbing is that the
debugger just blindly reads the entire contents of the pointer, which
destroys the operation of the device.
Regards... Rod
|
|
|
|