27
27
#include "qemu/osdep.h"
28
28
#include "qapi/error.h"
29
29
#include "qapi/qmp/qlist.h"
30
+ #include "qom/object.h"
30
31
#include "exec/address-spaces.h"
32
+ #include "hw/block/flash.h"
31
33
#include "hw/boards.h"
32
34
#include "hw/intc/sifive_plic.h"
33
35
#include "hw/jtag/tap_ctrl.h"
@@ -155,6 +157,26 @@ enum OtEgResetRequest {
155
157
OT_EG_RESET_COUNT
156
158
};
157
159
160
+ /* Data flash buses */
161
+ enum OtEgMtdBus {
162
+ OT_EG_MTD_SPI0 ,
163
+ OT_EG_MTD_SPI1 ,
164
+ OT_EG_MTD_SPI_COUNT ,
165
+ OT_EG_MTD_EFLASH = OT_EG_MTD_SPI_COUNT ,
166
+ };
167
+
168
+ /* "Parallel" flash buses */
169
+ enum OtEgPflashBus {
170
+ OT_EG_PFLASH_OTP ,
171
+ };
172
+
173
+ enum OtEGBoardDevice {
174
+ OT_EG_BOARD_DEV_SOC ,
175
+ OT_EG_BOARD_DEV_FLASH0 ,
176
+ OT_EG_BOARD_DEV_FLASH1 ,
177
+ OT_EG_BOARD_DEV_COUNT ,
178
+ };
179
+
158
180
/* EarlGrey/CW310 Peripheral clock is 6 MHz */
159
181
#define OT_EG_PERIPHERAL_CLK_HZ 6000000u
160
182
@@ -669,6 +691,7 @@ static const IbexDeviceDef ot_eg_soc_devices[] = {
669
691
OT_EG_SOC_GPIO_ALERT (0 , 19 )
670
692
),
671
693
.prop = IBEXDEVICEPROPDEFS (
694
+ IBEX_DEV_STRING_PROP ("ot_id" , "spi0" ),
672
695
IBEX_DEV_UINT_PROP ("bus-num" , 0 )
673
696
),
674
697
},
@@ -683,6 +706,7 @@ static const IbexDeviceDef ot_eg_soc_devices[] = {
683
706
OT_EG_SOC_GPIO_ALERT (0 , 20 )
684
707
),
685
708
.prop = IBEXDEVICEPROPDEFS (
709
+ IBEX_DEV_STRING_PROP ("ot_id" , "spi1" ),
686
710
IBEX_DEV_UINT_PROP ("bus-num" , 1 )
687
711
),
688
712
},
@@ -1122,12 +1146,6 @@ static const IbexDeviceDef ot_eg_soc_devices[] = {
1122
1146
/* clang-format on */
1123
1147
};
1124
1148
1125
- enum OtEGBoardDevice {
1126
- OT_EG_BOARD_DEV_SOC ,
1127
- OT_EG_BOARD_DEV_FLASH ,
1128
- OT_EG_BOARD_DEV_COUNT ,
1129
- };
1130
-
1131
1149
/* ------------------------------------------------------------------------ */
1132
1150
/* Type definitions */
1133
1151
/* ------------------------------------------------------------------------ */
@@ -1147,7 +1165,8 @@ struct OtEGSoCState {
1147
1165
struct OtEGBoardState {
1148
1166
DeviceState parent_obj ;
1149
1167
1150
- DeviceState * * devices ;
1168
+ /* optional SPI data flash (type of device) */
1169
+ char * spiflash [OT_EG_MTD_SPI_COUNT ];
1151
1170
};
1152
1171
1153
1172
struct OtEGMachineState {
@@ -1182,7 +1201,7 @@ static void ot_eg_soc_dm_configure(DeviceState *dev, const IbexDeviceDef *def,
1182
1201
static void ot_eg_soc_flash_ctrl_configure (
1183
1202
DeviceState * dev , const IbexDeviceDef * def , DeviceState * parent )
1184
1203
{
1185
- DriveInfo * dinfo = drive_get (IF_MTD , 1 , 0 );
1204
+ DriveInfo * dinfo = drive_get (IF_MTD , OT_EG_MTD_EFLASH , 0 );
1186
1205
(void )def ;
1187
1206
(void )parent ;
1188
1207
@@ -1223,7 +1242,7 @@ static void ot_eg_soc_hart_configure(DeviceState *dev, const IbexDeviceDef *def,
1223
1242
static void ot_eg_soc_otp_ctrl_configure (
1224
1243
DeviceState * dev , const IbexDeviceDef * def , DeviceState * parent )
1225
1244
{
1226
- DriveInfo * dinfo = drive_get (IF_PFLASH , 0 , 0 );
1245
+ DriveInfo * dinfo = drive_get (IF_PFLASH , OT_EG_PFLASH_OTP , 0 );
1227
1246
(void )def ;
1228
1247
(void )parent ;
1229
1248
@@ -1401,39 +1420,100 @@ type_init(ot_eg_soc_register_types);
1401
1420
/* Board */
1402
1421
/* ------------------------------------------------------------------------ */
1403
1422
1423
+ static void ot_eg_board_set_spiflash0 (Object * obj , const char * value ,
1424
+ Error * * errp )
1425
+ {
1426
+ OtEGBoardState * board = RISCV_OT_EG_BOARD (obj );
1427
+ (void )errp ;
1428
+
1429
+ g_free (board -> spiflash [OT_EG_MTD_SPI0 ]);
1430
+ board -> spiflash [OT_EG_MTD_SPI0 ] = g_strdup (value );
1431
+ }
1432
+
1433
+ static void ot_eg_board_set_spiflash1 (Object * obj , const char * value ,
1434
+ Error * * errp )
1435
+ {
1436
+ OtEGBoardState * board = RISCV_OT_EG_BOARD (obj );
1437
+ (void )errp ;
1438
+
1439
+ g_free (board -> spiflash [OT_EG_MTD_SPI1 ]);
1440
+ board -> spiflash [OT_EG_MTD_SPI1 ] = g_strdup (value );
1441
+ }
1442
+
1404
1443
static void ot_eg_board_realize (DeviceState * dev , Error * * errp )
1405
1444
{
1406
1445
OtEGBoardState * board = RISCV_OT_EG_BOARD (dev );
1407
1446
1408
- DeviceState * soc = board -> devices [OT_EG_BOARD_DEV_SOC ];
1447
+ DeviceState * soc = qdev_new (TYPE_RISCV_OT_EG_SOC );
1448
+
1409
1449
object_property_add_child (OBJECT (board ), "soc" , OBJECT (soc ));
1410
1450
sysbus_realize_and_unref (SYS_BUS_DEVICE (soc ), & error_fatal );
1411
1451
1412
- DeviceState * spihost =
1413
- RISCV_OT_EG_SOC (soc )-> devices [OT_EG_SOC_DEV_SPI_HOST0 ];
1414
- DeviceState * flash = board -> devices [OT_EG_BOARD_DEV_FLASH ];
1415
- BusState * spibus = qdev_get_child_bus (spihost , "spi0" );
1416
- g_assert (spibus );
1417
-
1418
- DriveInfo * dinfo = drive_get (IF_MTD , 0 , 0 );
1419
- if (dinfo ) {
1420
- qdev_prop_set_drive_err (DEVICE (flash ), "drive" ,
1421
- blk_by_legacy_dinfo (dinfo ), & error_fatal );
1452
+ for (unsigned fix = 0 ; fix < OT_EG_MTD_SPI_COUNT ; fix ++ ) {
1453
+ const char * flash_type = board -> spiflash [OT_EG_MTD_SPI0 + fix ];
1454
+ /*
1455
+ * skip this flash slot if no device type has been defined on the QEMU
1456
+ * command line
1457
+ */
1458
+ if (!flash_type ) {
1459
+ continue ;
1460
+ }
1461
+
1462
+ /* qdev_new aborts if the specified device is not supported */
1463
+ DeviceState * flash = qdev_new (flash_type );
1464
+
1465
+ if (!object_dynamic_cast (OBJECT (flash ), TYPE_M25P80 )) {
1466
+ error_setg (errp , "%s is not a SPI dataflash device" , flash_type );
1467
+ }
1468
+
1469
+ /*
1470
+ * retrieve the SPI host controller bus. Although each SPI host only
1471
+ * has one SPI bus, each bus name in QEMU needs to be unique. The SPI
1472
+ * host controller uses its bus-num property as a suffix for naming its
1473
+ * bus
1474
+ */
1475
+ DeviceState * spihost =
1476
+ RISCV_OT_EG_SOC (soc )-> devices [OT_EG_SOC_DEV_SPI_HOST0 + fix ];
1477
+ char * busname = g_strdup_printf ("spi%u" , fix );
1478
+ BusState * spibus = qdev_get_child_bus (spihost , busname );
1479
+ g_assert (spibus );
1480
+
1481
+ /*
1482
+ * if a "drive" property for this bus/unit pair is defined on the QEMU
1483
+ * command line, assigned it to the flash device
1484
+ */
1485
+ DriveInfo * dinfo = drive_get (IF_MTD , fix , 0 );
1486
+ if (dinfo ) {
1487
+ qdev_prop_set_drive_err (DEVICE (flash ), "drive" ,
1488
+ blk_by_legacy_dinfo (dinfo ), & error_fatal );
1489
+ }
1490
+
1491
+ /* the flash device is a child of the board */
1492
+ char * flashname = g_strdup_printf ("dataflash%u" , fix );
1493
+ object_property_add_child (OBJECT (board ), flashname , OBJECT (flash ));
1494
+ /* connect it as a peripheral of the SPI host controller bus */
1495
+ ssi_realize_and_unref (flash , SSI_BUS (spibus ), errp );
1496
+
1497
+ /*
1498
+ * finally, connect the first CS line of the SPI controller to control
1499
+ * to select this SPI flash device
1500
+ */
1501
+ qemu_irq cs = qdev_get_gpio_in_named (flash , SSI_GPIO_CS , 0 );
1502
+ qdev_connect_gpio_out_named (spihost , SSI_GPIO_CS , 0 , cs );
1503
+
1504
+ g_free (flashname );
1505
+ g_free (busname );
1422
1506
}
1423
- object_property_add_child (OBJECT (board ), "dataflash" , OBJECT (flash ));
1424
- ssi_realize_and_unref (flash , SSI_BUS (spibus ), errp );
1425
-
1426
- qemu_irq cs = qdev_get_gpio_in_named (flash , SSI_GPIO_CS , 0 );
1427
- qdev_connect_gpio_out_named (spihost , SSI_GPIO_CS , 0 , cs );
1428
1507
}
1429
1508
1430
1509
static void ot_eg_board_init (Object * obj )
1431
1510
{
1432
- OtEGBoardState * s = RISCV_OT_EG_BOARD (obj );
1433
-
1434
- s -> devices = g_new0 (DeviceState * , OT_EG_BOARD_DEV_COUNT );
1435
- s -> devices [OT_EG_BOARD_DEV_SOC ] = qdev_new (TYPE_RISCV_OT_EG_SOC );
1436
- s -> devices [OT_EG_BOARD_DEV_FLASH ] = qdev_new ("is25wp128" );
1511
+ object_property_add_str (obj , "spiflash0" , NULL , & ot_eg_board_set_spiflash0 );
1512
+ object_property_set_description (obj , "spiflash0" ,
1513
+ "SPI dataflash on SPI0 bus" );
1514
+ object_property_add_str (obj , "spiflash1" , NULL , & ot_eg_board_set_spiflash1 );
1515
+ object_property_set_description (obj , "spiflash1" ,
1516
+ "SPI dataflash on SPI1 bus" );
1437
1517
}
1438
1518
1439
1519
static void ot_eg_board_class_init (ObjectClass * oc , void * data )
0 commit comments