@ -54,6 +54,8 @@ static uint8_t exception_mask(uint8_t ring)
switch ( ring ) {
switch ( ring ) {
case TM_QW1_OS :
case TM_QW1_OS :
return TM_QW1_NSR_EO ;
return TM_QW1_NSR_EO ;
case TM_QW3_HV_PHYS :
return TM_QW3_NSR_HE ;
default :
default :
g_assert_not_reached ( ) ;
g_assert_not_reached ( ) ;
}
}
@ -88,7 +90,16 @@ static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
uint8_t * regs = & tctx - > regs [ ring ] ;
uint8_t * regs = & tctx - > regs [ ring ] ;
if ( regs [ TM_PIPR ] < regs [ TM_CPPR ] ) {
if ( regs [ TM_PIPR ] < regs [ TM_CPPR ] ) {
regs [ TM_NSR ] | = exception_mask ( ring ) ;
switch ( ring ) {
case TM_QW1_OS :
regs [ TM_NSR ] | = TM_QW1_NSR_EO ;
break ;
case TM_QW3_HV_PHYS :
regs [ TM_NSR ] | = ( TM_QW3_NSR_HE_PHYS < < 6 ) ;
break ;
default :
g_assert_not_reached ( ) ;
}
qemu_irq_raise ( tctx - > output ) ;
qemu_irq_raise ( tctx - > output ) ;
}
}
}
}
@ -109,6 +120,38 @@ static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr)
* XIVE Thread Interrupt Management Area ( TIMA )
* XIVE Thread Interrupt Management Area ( TIMA )
*/
*/
static void xive_tm_set_hv_cppr ( XiveTCTX * tctx , hwaddr offset ,
uint64_t value , unsigned size )
{
xive_tctx_set_cppr ( tctx , TM_QW3_HV_PHYS , value & 0xff ) ;
}
static uint64_t xive_tm_ack_hv_reg ( XiveTCTX * tctx , hwaddr offset , unsigned size )
{
return xive_tctx_accept ( tctx , TM_QW3_HV_PHYS ) ;
}
static uint64_t xive_tm_pull_pool_ctx ( XiveTCTX * tctx , hwaddr offset ,
unsigned size )
{
uint64_t ret ;
ret = tctx - > regs [ TM_QW2_HV_POOL + TM_WORD2 ] & TM_QW2W2_POOL_CAM ;
tctx - > regs [ TM_QW2_HV_POOL + TM_WORD2 ] & = ~ TM_QW2W2_POOL_CAM ;
return ret ;
}
static void xive_tm_vt_push ( XiveTCTX * tctx , hwaddr offset ,
uint64_t value , unsigned size )
{
tctx - > regs [ TM_QW3_HV_PHYS + TM_WORD2 ] = value & 0xff ;
}
static uint64_t xive_tm_vt_poll ( XiveTCTX * tctx , hwaddr offset , unsigned size )
{
return tctx - > regs [ TM_QW3_HV_PHYS + TM_WORD2 ] & 0xff ;
}
/*
/*
* Define an access map for each page of the TIMA that we will use in
* Define an access map for each page of the TIMA that we will use in
* the memory region ops to filter values when doing loads and stores
* the memory region ops to filter values when doing loads and stores
@ -288,10 +331,16 @@ static const XiveTmOp xive_tm_operations[] = {
* effects
* effects
*/
*/
{ XIVE_TM_OS_PAGE , TM_QW1_OS + TM_CPPR , 1 , xive_tm_set_os_cppr , NULL } ,
{ XIVE_TM_OS_PAGE , TM_QW1_OS + TM_CPPR , 1 , xive_tm_set_os_cppr , NULL } ,
{ XIVE_TM_HV_PAGE , TM_QW3_HV_PHYS + TM_CPPR , 1 , xive_tm_set_hv_cppr , NULL } ,
{ XIVE_TM_HV_PAGE , TM_QW3_HV_PHYS + TM_WORD2 , 1 , xive_tm_vt_push , NULL } ,
{ XIVE_TM_HV_PAGE , TM_QW3_HV_PHYS + TM_WORD2 , 1 , NULL , xive_tm_vt_poll } ,
/* MMIOs above 2K : special operations with side effects */
/* MMIOs above 2K : special operations with side effects */
{ XIVE_TM_OS_PAGE , TM_SPC_ACK_OS_REG , 2 , NULL , xive_tm_ack_os_reg } ,
{ XIVE_TM_OS_PAGE , TM_SPC_ACK_OS_REG , 2 , NULL , xive_tm_ack_os_reg } ,
{ XIVE_TM_OS_PAGE , TM_SPC_SET_OS_PENDING , 1 , xive_tm_set_os_pending , NULL } ,
{ XIVE_TM_OS_PAGE , TM_SPC_SET_OS_PENDING , 1 , xive_tm_set_os_pending , NULL } ,
{ XIVE_TM_HV_PAGE , TM_SPC_ACK_HV_REG , 2 , NULL , xive_tm_ack_hv_reg } ,
{ XIVE_TM_HV_PAGE , TM_SPC_PULL_POOL_CTX , 4 , NULL , xive_tm_pull_pool_ctx } ,
{ XIVE_TM_HV_PAGE , TM_SPC_PULL_POOL_CTX , 8 , NULL , xive_tm_pull_pool_ctx } ,
} ;
} ;
static const XiveTmOp * xive_tm_find_op ( hwaddr offset , unsigned size , bool write )
static const XiveTmOp * xive_tm_find_op ( hwaddr offset , unsigned size , bool write )
@ -323,7 +372,7 @@ void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
const XiveTmOp * xto ;
const XiveTmOp * xto ;
/*
/*
* TODO : check V bit in Q [ 0 - 3 ] W2 , check PTER bit associated with CPU
* TODO : check V bit in Q [ 0 - 3 ] W2
*/
*/
/*
/*
@ -360,7 +409,7 @@ uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size)
const XiveTmOp * xto ;
const XiveTmOp * xto ;
/*
/*
* TODO : check V bit in Q [ 0 - 3 ] W2 , check PTER bit associated with CPU
* TODO : check V bit in Q [ 0 - 3 ] W2
*/
*/
/*
/*
@ -472,6 +521,8 @@ static void xive_tctx_reset(void *dev)
*/
*/
tctx - > regs [ TM_QW1_OS + TM_PIPR ] =
tctx - > regs [ TM_QW1_OS + TM_PIPR ] =
ipb_to_pipr ( tctx - > regs [ TM_QW1_OS + TM_IPB ] ) ;
ipb_to_pipr ( tctx - > regs [ TM_QW1_OS + TM_IPB ] ) ;
tctx - > regs [ TM_QW3_HV_PHYS + TM_PIPR ] =
ipb_to_pipr ( tctx - > regs [ TM_QW3_HV_PHYS + TM_IPB ] ) ;
}
}
static void xive_tctx_realize ( DeviceState * dev , Error * * errp )
static void xive_tctx_realize ( DeviceState * dev , Error * * errp )