Port-sparc64 archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: sun4v trap table
Don't look at the Solaris, Illuminos, or Linux kernels. They use a
completely different trap and address space model from NetBSD.
User and kernel are not mapped into the same address space.
Trap levels above 0 are only used during trap dispatch. The kernel runs
at TL0.
The different window spill and fill handlers have to do with which address
space a particular register window is mapped to. The fill/spill normal
use the currnt active context. The other ones use and ASI to always use
the user TLB context.
When traping into the kernel, the CPU is set to kernel mode and the
primary context set to 0 {nucleus), so the TLB uses kernel mappings,
and %otherwin is set to the number of user stack frames. For the spills,
if %otherwin is not 0 it traps to the the handler that dumps the stack
frame to the user address space, otherwise it goes to the active address
space.
If there are traps during trap handling Solaris and Linux will try to
return to the trap handler that faultes. The NetBSD code will unwind the
trap state completely.
Remember, sun4u can use all 4 trap levels. sun4v can only use 2 because
the other 2 are reserved for the hypervisor. On sun4v the hypervisor and
LDOMs are always active, whether configured or not.
Eduardo
On Mon, 6 Oct 2025, Sad Clouds wrote:
> On Mon, 06 Oct 2025 17:34:42 +1100
> matthew green <mrg%eterna23.net@localhost> wrote:
>
> > include/psl.h:264:#define WSTATE_USER 022
> > include/psl.h:263:#define WSTATE_KERN 026
> >
> > since they both seem to set OTHER bits, which means that 4:2 in the
> > trap type will always be 2? so always uses SPILLBOTH()? i think i
> > am still missing something here...
>
> Looking at Illumos/Solaris: src/uts/sparc/v9/sys/privregs.h
>
> /*
> * Window State Register (WSTATE)
> *
> * |------------|
> * |OTHER|NORMAL|
> * |-----|------|
> * 5 3 2 0
> */
> #define WSTATE_BAD 0 /* unused */
> #define WSTATE_U32 1 /* 32b stack */
> #define WSTATE_U64 2 /* 64b stack */
> #define WSTATE_CLEAN32 3 /* cleanwin workaround, 32b stack */
> #define WSTATE_CLEAN64 4 /* cleanwin workaround, 64b stack */
> #define WSTATE_K32 5 /* priv 32b stack */
> #define WSTATE_K64 6 /* priv 64b stack */
> #define WSTATE_KMIX 7 /* priv mixed stack */
>
> #define WSTATE_CLEAN_OFFSET 2
> #define WSTATE_SHIFT 3 /* normal-to-other shift */
> #define WSTATE_MASK 7 /* mask for each set */
> #define WSTATE(o, n) (((o) << WSTATE_SHIFT) | (n))
>
> #define WSTATE_USER32 WSTATE(WSTATE_BAD, WSTATE_U32)
> #define WSTATE_USER64 WSTATE(WSTATE_BAD, WSTATE_U64)
> #define WSTATE_KERN WSTATE(WSTATE_U32, WSTATE_K64)
>
>
> This results in WSTATE.OTHER=0 and WSTATE.NORMAL=0-7. Unlike NetBSD,
> only WSTATE_KERN results in WSTATE.OTHER>0.
>
> WSTATE.NORMAL=0 is unused, so I guess they may use it like a NULL
> pointer to catch uninitialised WSTATE register?
>
Home |
Main Index |
Thread Index |
Old Index