Hi Norm,
I would suggest an alternate approach using a method I
learned from "Stupid Pointer Tricks 101".  You can address
absolutely located hardware as structures using this method 
as long as the address space is linear.  I'm assuming you are
talking about RTLinux modules running in kernel space and 
kernel space is linear.

Here is a snippet of code that employs this method.  I hope it
gives you the general idea.

/*##########################################################################
#*\
 *                        Hardware Structure Definitions
\*##########################################################################
#*/

/* system configuration pointer */
typedef struct
{
  UINT16          xx1;
  UINT8           xx2;
  UINT8           sysbus;
  UINT32          xx3;
  UINT16          iscp_addr_lo;
  UINT16          iscp_addr_hi;
}
SCP_TYPE;

/* intermediate system configuration pointer */
typedef struct
{
  UINT8           xx1;
  UINT8           busy;
  UINT16          scb_offset;
  UINT16          scb_addr_lo;
  UINT16          scb_addr_hi;
}
ISCP_TYPE;

/* transmit command block .. can be used in simplified mode with data
 *  in the tcb or flexible mode using tbds */
typedef struct
{
  UINT16          status;
  UINT16          cmd;
  UINT16          link_addr_lo;
  UINT16          link_addr_hi;
  UINT16          tbd_addr_lo;  /* set to all 1s for simplified mode */
  UINT16          tbd_addr_hi;
  UINT16          eof_tcb_bcnt; /* always set eof in simplified mode */
  UINT16          xx1;
  UINT8           dst_ena[6];
  UINT16          type_fld;     /* 24 bytes to this point */
  union
  {
    UINT8           byte[1500];
    UINT16          hword[750];
    UINT32          lword[375];
  }
  tx_data;
  unsigned long   time_tag;
  unsigned long   xmit_no;
  unsigned long   free_addr;
  unsigned long   unused_pad[3];
}
TCB_TYPE;       /* 1552 (610h) bytes each */


/*##########################################################################
#*\
 *                        Hardware Address Definitions
\*##########################################################################
#*/

/* 0xA0000000 and up is non-cached view of memory - MIPS processors */
#define ETH_BASE             0xA00C8000

/* define all Ethernet structures based on ETH_BASE base address */
#define SCB_ADDR        (ETH_BASE)
#define GEN_CB_ADDR     (ETH_BASE + sizeof(SCB_TYPE))

/* 128 tcbs @ 1552 bytes each => 0x30800 bytes */
#define TCB_ADDR        (GEN_CB_ADDR + sizeof(CB_TYPE))

/* TCB to be used in Ethernet interrupt handler */
#define INT_TCB_ADDR    (TCB_ADDR + (sizeof(TCB_TYPE) * NO_OF_TCBS))
  
   .
   .
   .

/* force 16 byte alignment on SCP */
#define SCP_ADDR         ((CMDTASK_TCB_ADDR + \
                          ((sizeof(UDPIP_HDR_TYPE)*NO_OF_TCBS) + 15)) & \
                           0xFFFFFFF0)
#define ISCP_ADDR        (SCP_ADDR+sizeof(SCP_TYPE))

/*##########################################################################
#*\
 *            "Fake" Structure Definitions (stupid pointer tricks)
\*##########################################################################
#*/

/* "fake" structs for absolute location -- ONLY works for linear addressing
*/
#define scp     (*((SCP_TYPE*)(SCP_ADDR)))
#define iscp    (*((ISCP_TYPE*)(ISCP_ADDR)))

/* for arrays use this syntax */
#define tcb       ((TCB_TYPE*)(TCB_ADDR))
#define tbd_hdr   ((TBD_TYPE*)(TBD_HEADER_ADDR))

/*##########################################################################
#*\
 *                           Code Access Examples
\*##########################################################################
#*/

  /* initialize the system configuration pointer (SCP) */
  /* linear mode, int active low, lock disabled, internal tmr */
  scp.sysbus = I82596_SCP_ASTEP_MODE |
    I82596_SCP_INT_POL_LO |
    I82596_SCP_LOCK_DSBL |
    I82596_SCP_BTT_I_TRIG |
    I82596_SCP_MODE_LINEAR;
  scp.iscp_addr_lo = PHYS_LO(ISCP_ADDR);
  scp.iscp_addr_hi = PHYS_HI(ISCP_ADDR);
  scp.xx1 = 0;
  scp.xx2 = 0;
  scp.xx3 = 0;

  /* initialize the intermediate system config pointer (ISCP) */
  iscp.busy = 1;                /* 596 will clear when info read */
  iscp.xx1 = 0;
  iscp.scb_offset = 0;
  iscp.scb_addr_lo = PHYS_LO(SCB_ADDR);
  iscp.scb_addr_hi = PHYS_HI(SCB_ADDR);


  /* initialize transmit control block structures & header/data tbd structs
*/
  for (i = 0; i < NO_OF_TCBS; i++)
  {
    /** TCB initialization **/
    tcb[i].status = 0x8000;     /* set complete bit to avoid 1st time
timeout*/
    tcb[i].cmd = 0x8004;        /* end of list, simplified mode */
    tcb[i].link_addr_lo = PHYS_LO(&tcb[i]); /* link to self */
    tcb[i].link_addr_hi = PHYS_HI(&tcb[i]);
    tcb[i].tbd_addr_lo = 0xFFFF;/* all ones for simplified mode */
    tcb[i].tbd_addr_hi = 0xFFFF;/* link to tbd_hdr for chaining */
    tcb[i].eof_tcb_bcnt = 0x8000;   /* this count includes dst_ena &
type_fld*/
    tcb[i].xx1 = 0;
    tcb[i].time_tag = 0xFFFFFFFF;   /* implies invalid time tag */
    tcb[i].xmit_no = 0;
    tcb[i].free_addr = 0;
  }

********** END OF CODE **********

I find the code using this method much more readable.  Hope it helps.

Regards,
Rich

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Richard R. Jennings
Embedded Software Engineer 4 - The Boeing Company
Flight Simulation Technology / Advanced Avionics Center - St. Louis
Computational & Image Generation Group
(314)234-0460  FAX (314)232-7972
[EMAIL PROTECTED]



> ----------
> From:         Norm Dresner[SMTP:[EMAIL PROTECTED]]
> Sent:         Monday, July 10, 2000 9:10 AM
> To:   [EMAIL PROTECTED]
> Subject:      [rtl] possible insmod bug
> 
> I'm having a problem because INSMOD is not loading one module correctly.
> Here's the system:
>       RH 5.2 w/Real-Time Linux 0.9J extensions to the kernel
>       gcc-2.7.2.3-14
>       binutils (ld) 2.9.1.0.15-1
>       modutils  (insmod) 2.1.85-9
> 
> An interface board I'm using has its 64K dual-ported segment located in
> PC-address space at 0x000D0000, so I'm trying to get the module compiled
> so
> that a particular `segment' falls at that address so I can use direct
> addressing of registers instead of having to dereference pointers for
> every
> access.
> 
> Here's how the memory is declared in the C-function that uses it:
> 
>       unsigned char     DualPortedMemory[2]  
>               __attribute__ ((section (".DPM" ) ) )   
>                       ={0x68,0x89};
> 
> and here's the loader command-file (invoked with -T load_cmds) on the
> ld-line of the make-file:
> 
> 
> MEMORY        {
>                DUALPORT (rw)  :  ORIGIN = 0x000D0000   , LENGTH = 64K 
>               }                        
> 
> 
> SECTIONS      {
>               .bss                            :       { *(.bss) }
>               .text                           :       { *(.text) }
>               .data                           :       { *(.data) }
>               .note                           :       { *(.note) }
>               .comment                        :       { *(.comment) }
>               .rodata                         :       { *(.rodata)  }  
>               .DPM 0x000D0000 (NOLOAD) :      { *(.DPM) }   >DUALPORT
> :NONE
>               }
> 
> The headers of the linked-moduel (as examined with objdump) show that the
> segment .DPM is located at the right address:
> 
> dummy.o:     file format elf32-i386
> 
> Sections:
> Idx Name          Size          VMA          LMA           File off
> Algn
>                       .       .       .
>   6 .DPM          00000002  000d0000  000d0000  00001218  2**0
>                   ALLOC
> 
> and the load-map from the insmod command has the following:
> 
>       Sections:       Size           Address   Align
>       .moduse         00000004  0807a000  2**2
>       .text                   0000088e  0807a004  2**2
>       .rodata                 00000358  0807a892  2**0
>       .data                   0000050c  0807abec  2**2
>       .bss                    0000009c  0807b0f8   2**2
>       .DPM                    00000002  0807b194  2**0
> 
> showing that, despite everything I've tried, insmod insists on loading the
> module without properly relocating the .DPM-segment to 0x000D0000.
> 
> I've tried just about every possible combination of things in the loader
> command-file, but that doesn't seem to be the problem since the disassemby
> of the loader's output shows that references to array DualPortedMemory[]
> are being correctly relocated to the .DPM segment located at the correct
> address.
> 
> I've scanned the code for an older version of insmod (which is all I could
> find quickly) and it looks like it was never designed to do what I want it
> do .
> 
> 1. Is there something obvious I'm missing?
> 2. Has anyone every done this successfully before?
> 3. Can anyone confirm this "bug"?
> 
> I'd like to exhaust all possible approaches before I start creating dozens
> of pointers - an error-prone approach if the underlying structures change
> radically.
> 
> Thanks.
> 
>       Norm
> 
> 
> -- [rtl] ---
> To unsubscribe:
> echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
> echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
> ---
> For more information on Real-Time Linux see:
> http://www.rtlinux.org/rtlinux/
> 
-- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
---
For more information on Real-Time Linux see:
http://www.rtlinux.org/rtlinux/

Reply via email to