"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