@ -357,7 +357,12 @@ static void stellaris_gptm_realize(DeviceState *dev, Error **errp)
/* System controller. */
typedef struct {
# define TYPE_STELLARIS_SYS "stellaris-sys"
OBJECT_DECLARE_SIMPLE_TYPE ( ssys_state , STELLARIS_SYS )
struct ssys_state {
SysBusDevice parent_obj ;
MemoryRegion iomem ;
uint32_t pborctl ;
uint32_t ldopctl ;
@ -371,11 +376,18 @@ typedef struct {
uint32_t dcgc [ 3 ] ;
uint32_t clkvclr ;
uint32_t ldoarst ;
qemu_irq irq ;
/* Properties (all read-only registers) */
uint32_t user0 ;
uint32_t user1 ;
qemu_irq irq ;
stellaris_board_info * board ;
} ssys_state ;
uint32_t did0 ;
uint32_t did1 ;
uint32_t dc0 ;
uint32_t dc1 ;
uint32_t dc2 ;
uint32_t dc3 ;
uint32_t dc4 ;
} ;
static void ssys_update ( ssys_state * s )
{
@ -430,7 +442,7 @@ static uint32_t pllcfg_fury[16] = {
static int ssys_board_class ( const ssys_state * s )
{
uint32_t did0 = s - > board - > did0 ;
uint32_t did0 = s - > did0 ;
switch ( did0 & DID0_VER_MASK ) {
case DID0_VER_0 :
return DID0_CLASS_SANDSTORM ;
@ -456,19 +468,19 @@ static uint64_t ssys_read(void *opaque, hwaddr offset,
switch ( offset ) {
case 0x000 : /* DID0 */
return s - > board - > did0 ;
return s - > did0 ;
case 0x004 : /* DID1 */
return s - > board - > did1 ;
return s - > did1 ;
case 0x008 : /* DC0 */
return s - > board - > dc0 ;
return s - > dc0 ;
case 0x010 : /* DC1 */
return s - > board - > dc1 ;
return s - > dc1 ;
case 0x014 : /* DC2 */
return s - > board - > dc2 ;
return s - > dc2 ;
case 0x018 : /* DC3 */
return s - > board - > dc3 ;
return s - > dc3 ;
case 0x01c : /* DC4 */
return s - > board - > dc4 ;
return s - > dc4 ;
case 0x030 : /* PBORCTL */
return s - > pborctl ;
case 0x034 : /* LDOPCTL */
@ -646,9 +658,9 @@ static const MemoryRegionOps ssys_ops = {
. endianness = DEVICE_NATIVE_ENDIAN ,
} ;
static void ssys_reset ( void * opaqu e )
static void stellaris_sys_reset_enter ( Object * obj , ResetType typ e )
{
ssys_state * s = ( ssys_state * ) opaque ;
ssys_state * s = STELLARIS_SYS ( obj ) ;
s - > pborctl = 0x7ffd ;
s - > rcc = 0x078e3ac0 ;
@ -661,9 +673,19 @@ static void ssys_reset(void *opaque)
s - > rcgc [ 0 ] = 1 ;
s - > scgc [ 0 ] = 1 ;
s - > dcgc [ 0 ] = 1 ;
}
static void stellaris_sys_reset_hold ( Object * obj )
{
ssys_state * s = STELLARIS_SYS ( obj ) ;
ssys_calculate_system_clock ( s ) ;
}
static void stellaris_sys_reset_exit ( Object * obj )
{
}
static int stellaris_sys_post_load ( void * opaque , int version_id )
{
ssys_state * s = opaque ;
@ -695,27 +717,66 @@ static const VMStateDescription vmstate_stellaris_sys = {
}
} ;
static Property stellaris_sys_properties [ ] = {
DEFINE_PROP_UINT32 ( " user0 " , ssys_state , user0 , 0 ) ,
DEFINE_PROP_UINT32 ( " user1 " , ssys_state , user1 , 0 ) ,
DEFINE_PROP_UINT32 ( " did0 " , ssys_state , did0 , 0 ) ,
DEFINE_PROP_UINT32 ( " did1 " , ssys_state , did1 , 0 ) ,
DEFINE_PROP_UINT32 ( " dc0 " , ssys_state , dc0 , 0 ) ,
DEFINE_PROP_UINT32 ( " dc1 " , ssys_state , dc1 , 0 ) ,
DEFINE_PROP_UINT32 ( " dc2 " , ssys_state , dc2 , 0 ) ,
DEFINE_PROP_UINT32 ( " dc3 " , ssys_state , dc3 , 0 ) ,
DEFINE_PROP_UINT32 ( " dc4 " , ssys_state , dc4 , 0 ) ,
DEFINE_PROP_END_OF_LIST ( )
} ;
static void stellaris_sys_instance_init ( Object * obj )
{
ssys_state * s = STELLARIS_SYS ( obj ) ;
SysBusDevice * sbd = SYS_BUS_DEVICE ( s ) ;
memory_region_init_io ( & s - > iomem , obj , & ssys_ops , s , " ssys " , 0x00001000 ) ;
sysbus_init_mmio ( sbd , & s - > iomem ) ;
sysbus_init_irq ( sbd , & s - > irq ) ;
}
static int stellaris_sys_init ( uint32_t base , qemu_irq irq ,
stellaris_board_info * board ,
uint8_t * macaddr )
{
ssys_state * s ;
DeviceState * dev = qdev_new ( TYPE_STELLARIS_SYS ) ;
SysBusDevice * sbd = SYS_BUS_DEVICE ( dev ) ;
s = g_new0 ( ssys_state , 1 ) ;
s - > irq = irq ;
s - > board = board ;
/* Most devices come preprogrammed with a MAC address in the user data. */
s - > user0 = macaddr [ 0 ] | ( macaddr [ 1 ] < < 8 ) | ( macaddr [ 2 ] < < 16 ) ;
s - > user1 = macaddr [ 3 ] | ( macaddr [ 4 ] < < 8 ) | ( macaddr [ 5 ] < < 16 ) ;
qdev_prop_set_uint32 ( dev , " user0 " ,
macaddr [ 0 ] | ( macaddr [ 1 ] < < 8 ) | ( macaddr [ 2 ] < < 16 ) ) ;
qdev_prop_set_uint32 ( dev , " user1 " ,
macaddr [ 3 ] | ( macaddr [ 4 ] < < 8 ) | ( macaddr [ 5 ] < < 16 ) ) ;
qdev_prop_set_uint32 ( dev , " did0 " , board - > did0 ) ;
qdev_prop_set_uint32 ( dev , " did1 " , board - > did1 ) ;
qdev_prop_set_uint32 ( dev , " dc0 " , board - > dc0 ) ;
qdev_prop_set_uint32 ( dev , " dc1 " , board - > dc1 ) ;
qdev_prop_set_uint32 ( dev , " dc2 " , board - > dc2 ) ;
qdev_prop_set_uint32 ( dev , " dc3 " , board - > dc3 ) ;
qdev_prop_set_uint32 ( dev , " dc4 " , board - > dc4 ) ;
sysbus_realize_and_unref ( sbd , & error_fatal ) ;
sysbus_mmio_map ( sbd , 0 , base ) ;
sysbus_connect_irq ( sbd , 0 , irq ) ;
/*
* Normally we should not be resetting devices like this during
* board creation . For the moment we need to do so , because
* system_clock_scale will only get set when the STELLARIS_SYS
* device is reset , and we need its initial value to pass to
* the watchdog device . This hack can be removed once the
* watchdog has been converted to use a Clock input instead .
*/
device_cold_reset ( dev ) ;
memory_region_init_io ( & s - > iomem , NULL , & ssys_ops , s , " ssys " , 0x00001000 ) ;
memory_region_add_subregion ( get_system_memory ( ) , base , & s - > iomem ) ;
ssys_reset ( s ) ;
vmstate_register ( NULL , VMSTATE_INSTANCE_ID_ANY , & vmstate_stellaris_sys , s ) ;
return 0 ;
}
/* I2C controller. */
# define TYPE_STELLARIS_I2C "stellaris-i2c"
@ -1553,11 +1614,32 @@ static const TypeInfo stellaris_adc_info = {
. class_init = stellaris_adc_class_init ,
} ;
static void stellaris_sys_class_init ( ObjectClass * klass , void * data )
{
DeviceClass * dc = DEVICE_CLASS ( klass ) ;
ResettableClass * rc = RESETTABLE_CLASS ( klass ) ;
dc - > vmsd = & vmstate_stellaris_sys ;
rc - > phases . enter = stellaris_sys_reset_enter ;
rc - > phases . hold = stellaris_sys_reset_hold ;
rc - > phases . exit = stellaris_sys_reset_exit ;
device_class_set_props ( dc , stellaris_sys_properties ) ;
}
static const TypeInfo stellaris_sys_info = {
. name = TYPE_STELLARIS_SYS ,
. parent = TYPE_SYS_BUS_DEVICE ,
. instance_size = sizeof ( ssys_state ) ,
. instance_init = stellaris_sys_instance_init ,
. class_init = stellaris_sys_class_init ,
} ;
static void stellaris_register_types ( void )
{
type_register_static ( & stellaris_i2c_info ) ;
type_register_static ( & stellaris_gptm_info ) ;
type_register_static ( & stellaris_adc_info ) ;
type_register_static ( & stellaris_sys_info ) ;
}
type_init ( stellaris_register_types )