Yes, of course. That's what I meant by  
>> " ...before I start creating dozens
>> of pointers - an error-prone approach if the underlying structures change
>> radically." 

because the underlying layout of the dual-ported memory isn't totally fixed
by the hardware, but partially by the software that runs on the interface
board that I'm also writing and I wanted to be able to use the "same"
header files for both the interface board program (an 80188 BTW) and the
Linux module.

If this SEGMENT-thing worked, it would be easy to create two include-files,
one for each processor that sinply defined a few #define's and then one
header file they both include that defined the actual layout at the address
defined by the first files. Thus

--FILE  OnBoard.h
#define                         blah, blah, blah
#include        layout.h

--FILE LinuxModule.h
#define                         blah, blah, blah
#include        layout.h

where LinuxModule.h defines things like the segment-statement in gcc's
dialect as a symbol and the OnBoard.h defines the same symbols as whatever
is needed in the Borland C++v3.1 compilation.

That's what I wanted to do. 

But to make one of them define the layout directly and the other one create
pointers could get really ugly (and worse, unreadable).

        Norm


At 10:18 AM 7/10/2000 -0500, Jennings, Richard R wrote:
>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