* [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.