@ -53,8 +53,11 @@
# include "net/net.h"
# include "hw/core/split-irq.h"
# define MPS2TZ_NUMIRQ 92
typedef enum MPS2TZFPGAType {
FPGA_AN505 ,
FPGA_AN521 ,
} MPS2TZFPGAType ;
typedef struct {
@ -85,6 +88,7 @@ typedef struct {
SplitIRQ sec_resp_splitter ;
qemu_or_irq uart_irq_orgate ;
DeviceState * lan9118 ;
SplitIRQ cpu_irq_splitter [ MPS2TZ_NUMIRQ ] ;
} MPS2TZMachineState ;
# define TYPE_MPS2TZ_MACHINE "mps2tz"
@ -111,6 +115,23 @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
memory_region_add_subregion ( get_system_memory ( ) , base , mr ) ;
}
static qemu_irq get_sse_irq_in ( MPS2TZMachineState * mms , int irqno )
{
/* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
MPS2TZMachineClass * mmc = MPS2TZ_MACHINE_GET_CLASS ( mms ) ;
assert ( irqno < MPS2TZ_NUMIRQ ) ;
switch ( mmc - > fpga_type ) {
case FPGA_AN505 :
return qdev_get_gpio_in_named ( DEVICE ( & mms - > iotkit ) , " EXP_IRQ " , irqno ) ;
case FPGA_AN521 :
return qdev_get_gpio_in ( DEVICE ( & mms - > cpu_irq_splitter [ irqno ] ) , 0 ) ;
default :
g_assert_not_reached ( ) ;
}
}
/* Most of the devices in the AN505 FPGA image sit behind
* Peripheral Protection Controllers . These data structures
* define the layout of which devices sit behind which PPCs .
@ -161,7 +182,6 @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
int txirqno = i * 2 + 1 ;
int combirqno = i + 10 ;
SysBusDevice * s ;
DeviceState * iotkitdev = DEVICE ( & mms - > iotkit ) ;
DeviceState * orgate_dev = DEVICE ( & mms - > uart_irq_orgate ) ;
sysbus_init_child_obj ( OBJECT ( mms ) , name , uart , sizeof ( mms - > uart [ 0 ] ) ,
@ -170,14 +190,11 @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
qdev_prop_set_uint32 ( DEVICE ( uart ) , " pclk-frq " , SYSCLK_FRQ ) ;
object_property_set_bool ( OBJECT ( uart ) , true , " realized " , & error_fatal ) ;
s = SYS_BUS_DEVICE ( uart ) ;
sysbus_connect_irq ( s , 0 , qdev_get_gpio_in_named ( iotkitdev ,
" EXP_IRQ " , txirqno ) ) ;
sysbus_connect_irq ( s , 1 , qdev_get_gpio_in_named ( iotkitdev ,
" EXP_IRQ " , rxirqno ) ) ;
sysbus_connect_irq ( s , 0 , get_sse_irq_in ( mms , txirqno ) ) ;
sysbus_connect_irq ( s , 1 , get_sse_irq_in ( mms , rxirqno ) ) ;
sysbus_connect_irq ( s , 2 , qdev_get_gpio_in ( orgate_dev , i * 2 ) ) ;
sysbus_connect_irq ( s , 3 , qdev_get_gpio_in ( orgate_dev , i * 2 + 1 ) ) ;
sysbus_connect_irq ( s , 4 , qdev_get_gpio_in_named ( iotkitdev ,
" EXP_IRQ " , combirqno ) ) ;
sysbus_connect_irq ( s , 4 , get_sse_irq_in ( mms , combirqno ) ) ;
return sysbus_mmio_get_region ( SYS_BUS_DEVICE ( uart ) , 0 ) ;
}
@ -213,7 +230,6 @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
const char * name , hwaddr size )
{
SysBusDevice * s ;
DeviceState * iotkitdev = DEVICE ( & mms - > iotkit ) ;
NICInfo * nd = & nd_table [ 0 ] ;
/* In hardware this is a LAN9220; the LAN9118 is software compatible
@ -225,7 +241,7 @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
qdev_init_nofail ( mms - > lan9118 ) ;
s = SYS_BUS_DEVICE ( mms - > lan9118 ) ;
sysbus_connect_irq ( s , 0 , qdev_get_gpio_in_named ( iotkitdev , " EXP_IRQ " , 16 ) ) ;
sysbus_connect_irq ( s , 0 , get_sse_irq_in ( mms , 16 ) ) ;
return sysbus_mmio_get_region ( s , 0 ) ;
}
@ -315,12 +331,9 @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
s = SYS_BUS_DEVICE ( dma ) ;
/* Wire up DMACINTR, DMACINTERR, DMACINTTC */
sysbus_connect_irq ( s , 0 , qdev_get_gpio_in_named ( iotkitdev ,
" EXP_IRQ " , 58 + i * 3 ) ) ;
sysbus_connect_irq ( s , 1 , qdev_get_gpio_in_named ( iotkitdev ,
" EXP_IRQ " , 56 + i * 3 ) ) ;
sysbus_connect_irq ( s , 2 , qdev_get_gpio_in_named ( iotkitdev ,
" EXP_IRQ " , 57 + i * 3 ) ) ;
sysbus_connect_irq ( s , 0 , get_sse_irq_in ( mms , 58 + i * 3 ) ) ;
sysbus_connect_irq ( s , 1 , get_sse_irq_in ( mms , 56 + i * 3 ) ) ;
sysbus_connect_irq ( s , 2 , get_sse_irq_in ( mms , 57 + i * 3 ) ) ;
g_free ( mscname ) ;
return sysbus_mmio_get_region ( s , 0 ) ;
@ -339,21 +352,20 @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
*/
PL022State * spi = opaque ;
int i = spi - & mms - > spi [ 0 ] ;
DeviceState * iotkitdev = DEVICE ( & mms - > iotkit ) ;
SysBusDevice * s ;
sysbus_init_child_obj ( OBJECT ( mms ) , name , spi , sizeof ( mms - > spi [ 0 ] ) ,
TYPE_PL022 ) ;
object_property_set_bool ( OBJECT ( spi ) , true , " realized " , & error_fatal ) ;
s = SYS_BUS_DEVICE ( spi ) ;
sysbus_connect_irq ( s , 0 ,
qdev_get_gpio_in_named ( iotkitdev , " EXP_IRQ " , 51 + i ) ) ;
sysbus_connect_irq ( s , 0 , get_sse_irq_in ( mms , 51 + i ) ) ;
return sysbus_mmio_get_region ( s , 0 ) ;
}
static void mps2tz_common_init ( MachineState * machine )
{
MPS2TZMachineState * mms = MPS2TZ_MACHINE ( machine ) ;
MPS2TZMachineClass * mmc = MPS2TZ_MACHINE_GET_CLASS ( mms ) ;
MachineClass * mc = MACHINE_GET_CLASS ( machine ) ;
MemoryRegion * system_memory = get_system_memory ( ) ;
DeviceState * iotkitdev ;
@ -371,11 +383,38 @@ static void mps2tz_common_init(MachineState *machine)
iotkitdev = DEVICE ( & mms - > iotkit ) ;
object_property_set_link ( OBJECT ( & mms - > iotkit ) , OBJECT ( system_memory ) ,
" memory " , & error_abort ) ;
qdev_prop_set_uint32 ( iotkitdev , " EXP_NUMIRQ " , 92 ) ;
qdev_prop_set_uint32 ( iotkitdev , " EXP_NUMIRQ " , MPS2TZ_NUMIRQ ) ;
qdev_prop_set_uint32 ( iotkitdev , " MAINCLK " , SYSCLK_FRQ ) ;
object_property_set_bool ( OBJECT ( & mms - > iotkit ) , true , " realized " ,
& error_fatal ) ;
/*
* The AN521 needs us to create splitters to feed the IRQ inputs
* for each CPU in the SSE - 200 from each device in the board .
*/
if ( mmc - > fpga_type = = FPGA_AN521 ) {
for ( i = 0 ; i < MPS2TZ_NUMIRQ ; i + + ) {
char * name = g_strdup_printf ( " mps2-irq-splitter%d " , i ) ;
SplitIRQ * splitter = & mms - > cpu_irq_splitter [ i ] ;
object_initialize_child ( OBJECT ( machine ) , name ,
splitter , sizeof ( * splitter ) ,
TYPE_SPLIT_IRQ , & error_fatal , NULL ) ;
g_free ( name ) ;
object_property_set_int ( OBJECT ( splitter ) , 2 , " num-lines " ,
& error_fatal ) ;
object_property_set_bool ( OBJECT ( splitter ) , true , " realized " ,
& error_fatal ) ;
qdev_connect_gpio_out ( DEVICE ( splitter ) , 0 ,
qdev_get_gpio_in_named ( DEVICE ( & mms - > iotkit ) ,
" EXP_IRQ " , i ) ) ;
qdev_connect_gpio_out ( DEVICE ( splitter ) , 1 ,
qdev_get_gpio_in_named ( DEVICE ( & mms - > iotkit ) ,
" EXP_CPU1_IRQ " , i ) ) ;
}
}
/* The sec_resp_cfg output from the IoTKit must be split into multiple
* lines , one for each of the PPCs we create here , plus one per MSC .
*/
@ -426,7 +465,7 @@ static void mps2tz_common_init(MachineState *machine)
object_property_set_bool ( OBJECT ( & mms - > uart_irq_orgate ) , true ,
" realized " , & error_fatal ) ;
qdev_connect_gpio_out ( DEVICE ( & mms - > uart_irq_orgate ) , 0 ,
qdev_get_gpio_in_named ( iotkitdev , " EXP_IRQ " , 15 ) ) ;
get_sse_irq_in ( mms , 15 ) ) ;
/* Most of the devices in the FPGA are behind Peripheral Protection
* Controllers . The required order for initializing things is :