@ -200,6 +200,7 @@ static uint64_t npcm_gcr_read(void *opaque, hwaddr offset, unsigned size)
uint32_t reg = offset / sizeof ( uint32_t ) ;
NPCMGCRState * s = opaque ;
NPCMGCRClass * c = NPCM_GCR_GET_CLASS ( s ) ;
uint64_t value ;
if ( reg > = c - > nr_regs ) {
qemu_log_mask ( LOG_GUEST_ERROR ,
@ -208,9 +209,21 @@ static uint64_t npcm_gcr_read(void *opaque, hwaddr offset, unsigned size)
return 0 ;
}
trace_npcm_gcr_read ( offset , s - > regs [ reg ] ) ;
switch ( size ) {
case 4 :
value = s - > regs [ reg ] ;
break ;
case 8 :
value = deposit64 ( s - > regs [ reg ] , 32 , 32 , s - > regs [ reg + 1 ] ) ;
break ;
default :
g_assert_not_reached ( ) ;
}
return s - > regs [ reg ] ;
trace_npcm_gcr_read ( offset , value ) ;
return value ;
}
static void npcm_gcr_write ( void * opaque , hwaddr offset ,
@ -230,29 +243,65 @@ static void npcm_gcr_write(void *opaque, hwaddr offset,
return ;
}
switch ( reg ) {
case NPCM7XX_GCR_PDID :
case NPCM7XX_GCR_PWRON :
case NPCM7XX_GCR_INTSR :
qemu_log_mask ( LOG_GUEST_ERROR ,
" %s: register @ 0x%04 " HWADDR_PRIx " is read-only \n " ,
__func__ , offset ) ;
return ;
case NPCM7XX_GCR_RESSR :
case NPCM7XX_GCR_CP2BST :
/* Write 1 to clear */
value = s - > regs [ reg ] & ~ value ;
switch ( size ) {
case 4 :
switch ( reg ) {
case NPCM7XX_GCR_PDID :
case NPCM7XX_GCR_PWRON :
case NPCM7XX_GCR_INTSR :
qemu_log_mask ( LOG_GUEST_ERROR ,
" %s: register @ 0x%04 " HWADDR_PRIx " is read-only \n " ,
__func__ , offset ) ;
return ;
case NPCM7XX_GCR_RESSR :
case NPCM7XX_GCR_CP2BST :
/* Write 1 to clear */
value = s - > regs [ reg ] & ~ value ;
break ;
case NPCM7XX_GCR_RLOCKR1 :
case NPCM7XX_GCR_MDLR :
/* Write 1 to set */
value | = s - > regs [ reg ] ;
break ;
} ;
s - > regs [ reg ] = value ;
break ;
case NPCM7XX_GCR_RLOCKR1 :
case NPCM7XX_GCR_MDLR :
/* Write 1 to set */
value | = s - > regs [ reg ] ;
case 8 :
s - > regs [ reg ] = value ;
s - > regs [ reg + 1 ] = extract64 ( v , 32 , 32 ) ;
break ;
} ;
s - > regs [ reg ] = value ;
default :
g_assert_not_reached ( ) ;
}
}
static bool npcm_gcr_check_mem_op ( void * opaque , hwaddr offset ,
unsigned size , bool is_write ,
MemTxAttrs attrs )
{
NPCMGCRClass * c = NPCM_GCR_GET_CLASS ( opaque ) ;
if ( offset > = c - > nr_regs * sizeof ( uint32_t ) ) {
return false ;
}
switch ( size ) {
case 4 :
return true ;
case 8 :
if ( offset > = NPCM8XX_GCR_SCRPAD_00 * sizeof ( uint32_t ) & &
offset < ( NPCM8XX_GCR_NR_REGS - 1 ) * sizeof ( uint32_t ) ) {
return true ;
} else {
return false ;
}
default :
return false ;
}
}
static const struct MemoryRegionOps npcm_gcr_ops = {
@ -261,7 +310,8 @@ static const struct MemoryRegionOps npcm_gcr_ops = {
. endianness = DEVICE_LITTLE_ENDIAN ,
. valid = {
. min_access_size = 4 ,
. max_access_size = 4 ,
. max_access_size = 8 ,
. accepts = npcm_gcr_check_mem_op ,
. unaligned = false ,
} ,
} ;