* [parisc-linux] __asm__
@ 2000-03-01 14:07 willy
2000-03-01 15:50 ` Philipp Rumpf
0 siblings, 1 reply; 4+ messages in thread
From: willy @ 2000-03-01 14:07 UTC (permalink / raw)
To: parisc-linux
Grant was asking where to find documentation on __asm__, and I think
this is useful to enough people that it's worth posting here.
__asm__ is a gcc extension. It allows you to write inline assembler in
your C source file rather than forcing you to write a separate function
in a .S file and call it. The original documnetation can be found by
typing `info gcc' (make sure you have the gcc info files installed
or you'll just get the manpage). Follow the menus: `C Extensions',
``Extended Asm'. I find the documentation pretty obscure, and I have
to think very carefully every time I write an __asm__ statement.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [parisc-linux] __asm__
2000-03-01 14:07 [parisc-linux] __asm__ willy
@ 2000-03-01 15:50 ` Philipp Rumpf
2000-03-01 19:24 ` [parisc-linux] sba_io_pdir_entry() Grant Grundler
0 siblings, 1 reply; 4+ messages in thread
From: Philipp Rumpf @ 2000-03-01 15:50 UTC (permalink / raw)
To: willy; +Cc: parisc-linux
> __asm__ is a gcc extension. It allows you to write inline assembler in
> your C source file rather than forcing you to write a separate function
> in a .S file and call it. The original documnetation can be found by
> typing `info gcc' (make sure you have the gcc info files installed
> or you'll just get the manpage). Follow the menus: `C Extensions',
> ``Extended Asm'. I find the documentation pretty obscure, and I have
> to think very carefully every time I write an __asm__ statement.
info '(gcc) Extended Asm' if you don't want to search for it.
The documentation definitely isn't very good, so I would propose to write
to the list whenever you need an asm statements and aren't sure how
exactly to do it (most likely you don't even need the asm statement).
Philipp
^ permalink raw reply [flat|nested] 4+ messages in thread
* [parisc-linux] sba_io_pdir_entry()
2000-03-01 15:50 ` Philipp Rumpf
@ 2000-03-01 19:24 ` Grant Grundler
2000-03-01 20:07 ` sba_io_pdir_entry() Philipp Rumpf
0 siblings, 1 reply; 4+ messages in thread
From: Grant Grundler @ 2000-03-01 19:24 UTC (permalink / raw)
To: Philipp Rumpf; +Cc: willy, parisc-linux
Philipp Rumpf wrote:
> The documentation definitely isn't very good, so I would propose to write
> to the list whenever you need an asm statements and aren't sure how
> exactly to do it (most likely you don't even need the asm statement).
Ok. Let's try it.
I'm working on the code which generates/writes the I/O Pdir entry
for the "sba" I/O Pdir. It will be called for every physical page
which needs to be mapped for DMA.
Here are some constraints:
o I'd like to have as much of this in 'C' as possible without
compromising performance.
o This code will probably only be called from two (maybe four)
locations that are variants of the performance path.
o Will only be executed on PA2.0 processor - could be running
in narrow or wide mode (ie 32 or 64-bit kernel binary).
I haven't read the "info gcc" stuff yet.
But here's what I've cooked up so far:
/*
* SBA Mapping Routine
*
* Given a virtual address (vba, arg2) and space id, (sid, arg1)
* init_io_pdir_entry() loads the I/O PDIR entry pointed to by
* pdir_ptr (arg0). Each IO Pdir entry consists of 8 bytes as
* shown below (MSB == bit 0):
*
* 0 19 51 55 63
* +-+---------------------+----------------------------------+----+--------+
* |V| U | PPN[43:12] | U | VI |
* +-+---------------------+----------------------------------+----+--------+
*
* V == Valid Bit
* U == Unused
* PPN == Physical Page Number
* VI == Virtual Index
*
* The physical address fields are filled with the results of the LPA
* instruction. The virtual index field is filled with the results of
* of the LCI (Load Coherence Index) instruction. The 8 bits used for
* the virtual index are bits 12:19 of the value returned by LCI.
*
* We need to pre-swap the bytes since PCX-W is Big Endian.
*/
void __inline__ sba_io_pdir_entry(u64_t *pdir_ptr, space_t sid, void *vba)
{
register u64_t tmp;
mtsp(sid,1);
__asm__("lpa (%sr1,%1),%0" /* Load the physical address */
: "=r" (tmp) : "r" (vba));
tmp &= ~0xfffUL; /* clear page offset bits */
__asm__( "depdi 0x1,0,1,%0" /* Set enable bit */
"lci (%sr1, %1),%r29\n\t" /* Load coherent index */
"extru %r29,19,8,%r29\n\t" /* right shift coherent index */
"depd %r29,63,8,%0" /* insert coherent index */
: "=&r" (tmp) /* output */
: "r" (vba) /* input */
: "r29" /* side effects? */
)
*pdir_ptr = cpu_to_le64(tmp); /* swap and store into I/O Pdir */
}
Side note: should "space_t" be "unsigned long" or does parisc-linux
define something already for space ID's?
I would prefer not to assume space ID is always zero or something else
hard coded.
thanks,
grant
Grant Grundler
Unix Development Lab
+1.408.447.7253
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: sba_io_pdir_entry()
2000-03-01 19:24 ` [parisc-linux] sba_io_pdir_entry() Grant Grundler
@ 2000-03-01 20:07 ` Philipp Rumpf
0 siblings, 0 replies; 4+ messages in thread
From: Philipp Rumpf @ 2000-03-01 20:07 UTC (permalink / raw)
To: Grant Grundler; +Cc: willy, parisc-linux
> /*
> * SBA Mapping Routine
> *
> * Given a virtual address (vba, arg2) and space id, (sid, arg1)
> * init_io_pdir_entry() loads the I/O PDIR entry pointed to by
> * pdir_ptr (arg0). Each IO Pdir entry consists of 8 bytes as
> * shown below (MSB == bit 0):
> *
> * 0 19 51 55 63
> * +-+---------------------+----------------------------------+----+--------+
> * |V| U | PPN[43:12] | U | VI |
> * +-+---------------------+----------------------------------+----+--------+
> *
> * V == Valid Bit
> * U == Unused
> * PPN == Physical Page Number
> * VI == Virtual Index
> *
> * The physical address fields are filled with the results of the LPA
> * instruction. The virtual index field is filled with the results of
> * of the LCI (Load Coherence Index) instruction. The 8 bits used for
> * the virtual index are bits 12:19 of the value returned by LCI.
> *
> * We need to pre-swap the bytes since PCX-W is Big Endian.
> */
>
> void __inline__ sba_io_pdir_entry(u64_t *pdir_ptr, space_t sid, void *vba)
> {
> register u64_t tmp;
^^^^^^
u64, not u64_t, please
> mtsp(sid,1);
> __asm__("lpa (%sr1,%1),%0" /* Load the physical address */
> : "=r" (tmp) : "r" (vba));
>
> tmp &= ~0xfffUL; /* clear page offset bits */
>
> __asm__( "depdi 0x1,0,1,%0" /* Set enable bit */
> "lci (%sr1, %1),%r29\n\t" /* Load coherent index */
> "extru %r29,19,8,%r29\n\t" /* right shift coherent index */
> "depd %r29,63,8,%0" /* insert coherent index */
>
> : "=&r" (tmp) /* output */
> : "r" (vba) /* input */
> : "r29" /* side effects? */
> )
asm("lpa (%sr1, %1), %0", "=r" (pa), "r" (vba));
asm("lci (%sr1, %1), %0", "=r" (ci), "r" (vba));
pa &= ~4095;
ci = (ci >> 10) & 255;
tmp = (ci<<foo) | (pa<<bar);
sounds better to me.
> Side note: should "space_t" be "unsigned long" or does parisc-linux
> define something already for space ID's?
unsigned long should be fine.
> I would prefer not to assume space ID is always zero or something else
> hard coded.
We want to map IO space to userspace, so the version above is all right
(it's a bit careful, but it shouldn't waste any performance).
Philipp
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2000-03-02 1:07 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2000-03-01 14:07 [parisc-linux] __asm__ willy
2000-03-01 15:50 ` Philipp Rumpf
2000-03-01 19:24 ` [parisc-linux] sba_io_pdir_entry() Grant Grundler
2000-03-01 20:07 ` sba_io_pdir_entry() Philipp Rumpf
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.