"Garrett D'Amore" <garrett_damore at tadpole.com> writes:

> As another example, I recently updated the Atheros HAL on NetBSD, and
> would like to do so on Solaris as well -- including a HAL for SPARC
> systems!  There are ABI changes (minor), and I'm sure I could make those

There's actually an open CR for ath(7D) on SPARC: 6409272.  I've started
working on it, fetched the sparcv9 HAL object file corresponding to the
current x86 version, modified an O/N tree to build on SPARC, too, and built
the module.

When I first tried it, it didn't load:

Jun 12 14:52:25 xayide krtld: [ID 819705 kern.notice] /kernel/drv/sparcv9/ath: 
undefined symbol
Jun 12 14:52:25 xayide krtld: [ID 826211 kern.notice]  'ath_hal_reg_write'
Jun 12 14:52:25 xayide krtld: [ID 819705 kern.notice] /kernel/drv/sparcv9/ath: 
undefined symbol
Jun 12 14:52:25 xayide krtld: [ID 826211 kern.notice]  'ath_hal_reg_read'
Jun 12 14:52:25 xayide krtld: [ID 472681 kern.notice] WARNING: mod_load: cannot 
load module 'ath'

Those references are from the sparcv9 hal.o.  In the current madwifi Linux
osdep files

        http://madwifi.org/browser/trunk/hal/linux/ah_osdep.h

I found the following:

/*
 * Register read/write; we assume the registers will always
 * be memory-mapped.  Note that register accesses are done
 * using target-specific functions when debugging is enabled
 * (AH_DEBUG) or we are explicitly configured this way.  The
 * latter is used on some platforms where the full i/o space
 * cannot be directly mapped.
 *
 * The hardware registers are native little-endian byte order.
 * Big-endian hosts are handled by enabling hardware byte-swap
 * of register reads and writes at reset.  But the PCI clock
 * domain registers are not byte swapped!  Thus, on big-endian
 * platforms we have to byte-swap thoese registers specifically.
 * Most of this code is collapsed at compile time because the
 * register values are constants.
 */
#if AH_BYTE_ORDER == AH_BIG_ENDIAN
#define _OS_REG_WRITE(_ah, _reg, _val) do {                                 \
        if ( (_reg) >= 0x4000 && (_reg) < 0x5000)                           \
                *((volatile u_int32_t *)((_ah)->ah_sh + (_reg))) =          \
                        __bswap32((_val));                                  \
        else                                                                \
                *((volatile u_int32_t *)((_ah)->ah_sh + (_reg))) = (_val);  \
} while (0)
#define _OS_REG_READ(_ah, _reg) \
        (((_reg) >= 0x4000 && (_reg) < 0x5000) ? \
                __bswap32(*((volatile u_int32_t *)((_ah)->ah_sh + (_reg)))) : \
                *((volatile u_int32_t *)((_ah)->ah_sh + (_reg))))
#else /* AH_LITTLE_ENDIAN */
[...]

It seems to me that this code should use ddi_get32/ddi_put32 on Solaris,
but (having never done any driver programming on Solaris), I haven't
investigated much further yet.  I had planned to use dtrace to figure out
with empty implementations of those functions how they are used on
Solaris/SPARC.

        Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Faculty of Technology, Bielefeld University

Reply via email to