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/