Skip to content

Commit 8b6de0e

Browse files
committed
[ot] hw/riscv: ot_earlgrey: add jtag support to lc ctrl
Signed-off-by: Luís Marques <[email protected]>
1 parent 314dace commit 8b6de0e

File tree

3 files changed

+113
-10
lines changed

3 files changed

+113
-10
lines changed

docs/opentitan/lc_ctrl_dmi.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
# Darjeeling LifeCycle Controller over DTM
1+
# LifeCycle Controller over DTM
22

3-
## Communicating with the JTAG Mailbox through a JTAG connection
3+
## Communicating with the Life Cycle Controller through a JTAG connection
44

5-
In QEMU, a bridge between the Debug Transport Module (DTM) and the JTAG Mailbox is implemented
6-
as Debug Module bridge.
5+
In QEMU, a bridge between the Debug Transport Module (DTM) and the Life Cycle Controller is
6+
implemented as a Debug Module bridge.
77

88
```
99
+----------------+
@@ -25,9 +25,16 @@ where:
2525
`P` is the private OT bus
2626
`D` is the debug bus
2727

28-
QEMU should be started with an option such as:
28+
In Darjeeling, a top-level debug crossbar multiplexes debug access to several devices, including
29+
the Life Cycle Controller. Therefore, there is a single DTM and Debug Module bridge. In the QEMU
30+
implementation of Darjeeling we thus have a single JTAG server, reachable over the `taprbb`
31+
character device. For that machine, QEMU should be started with an option such as:
2932
`-chardev socket,id=taprbb,host=localhost,port=3335,server=on,wait=off` so that the JTAG server is
30-
instantiated and listens for incoming connection on TCP port 3335.
33+
instantiated and listens for incoming connections on TCP port 3335.
34+
35+
In Earlgrey, we have multiple JTAG TAPs, including one for the Life Cycle Controller. The Life Cycle
36+
Controller instantiates its own DTM and Debug Module bridge. Therefore, in the QEMU implementation
37+
of Earlgrey we use a separate character device for that JTAG server, named instead `taprbb-lc-ctrl`.
3138

3239
## Communicating with JTAG server and Life Cycle controller using Python
3340

docs/opentitan/ot_earlgrey.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ Devices in this group implement subset(s) of the real HW.
5959
* KMAC
6060
* Masking is not supported
6161
* Lifecycle controller
62+
* [LC controller](lc_ctrl_dmi.md) can be accessed through JTAG using a DM-TL bridge
6263
* [ROM controller](ot_rom_ctrl.md)
6364
* SRAM controller
6465
* Initialization and scrambling from OTP key supported

hw/riscv/ot_earlgrey.c

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,15 @@
3838
#include "hw/jtag/tap_ctrl.h"
3939
#include "hw/jtag/tap_ctrl_rbb.h"
4040
#include "hw/misc/pulp_rv_dm.h"
41+
#include "hw/opentitan/ot_address_space.h"
4142
#include "hw/opentitan/ot_aes.h"
4243
#include "hw/opentitan/ot_alert.h"
4344
#include "hw/opentitan/ot_aon_timer.h"
4445
#include "hw/opentitan/ot_ast_eg.h"
4546
#include "hw/opentitan/ot_clkmgr.h"
4647
#include "hw/opentitan/ot_common.h"
4748
#include "hw/opentitan/ot_csrng.h"
49+
#include "hw/opentitan/ot_dm_tl.h"
4850
#include "hw/opentitan/ot_edn.h"
4951
#include "hw/opentitan/ot_eg_pad_ring.h"
5052
#include "hw/opentitan/ot_entropy_src.h"
@@ -101,6 +103,8 @@ static void ot_eg_soc_otp_ctrl_configure(
101103
DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent);
102104
static void ot_eg_soc_tap_ctrl_configure(
103105
DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent);
106+
static void ot_eg_soc_lc_ctrl_tap_ctrl_configure(
107+
DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent);
104108
static void ot_eg_soc_spi_device_configure(
105109
DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent);
106110
static void ot_eg_soc_uart_configure(DeviceState *dev, const IbexDeviceDef *def,
@@ -112,6 +116,14 @@ static void ot_eg_soc_usbdev_configure(
112116
/* Constants */
113117
/* ------------------------------------------------------------------------ */
114118

119+
enum OtEgMemoryRegion {
120+
OT_EG_DEFAULT_MEMORY_REGION,
121+
OT_EG_LC_CTRL_TAP_MEMORY_REGION,
122+
};
123+
124+
#define LC_CTRL_TAP_MEMORY(_addr_) \
125+
IBEX_MEMMAP_MAKE_REG((_addr_), OT_EG_LC_CTRL_TAP_MEMORY_REGION)
126+
115127
enum OtEGSocDevice {
116128
OT_EG_SOC_DEV_ADC_CTRL,
117129
OT_EG_SOC_DEV_AES,
@@ -122,6 +134,7 @@ enum OtEGSocDevice {
122134
OT_EG_SOC_DEV_CSRNG,
123135
OT_EG_SOC_DEV_DM,
124136
OT_EG_SOC_DEV_DTM,
137+
OT_EG_SOC_DEV_LC_CTRL_DTM,
125138
OT_EG_SOC_DEV_EDN0,
126139
OT_EG_SOC_DEV_EDN1,
127140
OT_EG_SOC_DEV_ENTROPY_SRC,
@@ -150,13 +163,15 @@ enum OtEGSocDevice {
150163
OT_EG_SOC_DEV_ROM_CTRL,
151164
OT_EG_SOC_DEV_RSTMGR,
152165
OT_EG_SOC_DEV_RV_DM,
166+
OT_EG_SOC_DEV_DM_LC_CTRL,
153167
OT_EG_SOC_DEV_SENSOR_CTRL,
154168
OT_EG_SOC_DEV_SPI_DEVICE,
155169
OT_EG_SOC_DEV_SPI_HOST0,
156170
OT_EG_SOC_DEV_SPI_HOST1,
157171
OT_EG_SOC_DEV_SRAM_MAIN_CTRL,
158172
OT_EG_SOC_DEV_SYSRST_CTRL,
159173
OT_EG_SOC_DEV_TAP_CTRL,
174+
OT_EG_SOC_DEV_LC_CTRL_TAP_CTRL,
160175
OT_EG_SOC_DEV_TIMER,
161176
OT_EG_SOC_DEV_UART0,
162177
OT_EG_SOC_DEV_UART1,
@@ -198,6 +213,24 @@ enum OtEGBoardDevice {
198213
OT_EG_BOARD_DEV_COUNT,
199214
};
200215

216+
/*
217+
* <opentitan>/hw/ip/lc_ctrl/rtl/lc_ctrl.sv instantiates a DMI module (with
218+
* abits=7) and a DMI to TL-UL adapter. Together, they create a private bus,
219+
* exposing the LC Ctrl registers over JTAG <-> DTM <-> DMI <-> TL-UL. On the
220+
* DMI side we have the address space [0 .. 2^7); those addresses are mapped to
221+
* words on the TL-UL side, addressing [0 .. 2^7*4) bytes, and accessing the LC
222+
* Ctrl registers at the appropriate (documented) offset.
223+
*/
224+
#define OT_EG_LC_CTRL_TAP_DMI_ABITS 7u
225+
#define OT_EG_LC_CTRL_TAP_DMI_ADDR 0x0u
226+
#define OT_EG_LC_CTRL_TAP_DMI_SIZE (1u << OT_EG_LC_CTRL_TAP_DMI_ABITS)
227+
#define OT_EG_LC_CTRL_TAP_TL_ADDR 0x0u
228+
#define OT_EG_LC_CTRL_TAP_TL_SIZE ((1u << OT_EG_LC_CTRL_TAP_DMI_ABITS) * 4u)
229+
230+
#define OT_EG_LC_CTRL_TAP "ot-lc_ctrl-tap"
231+
#define OT_EG_LC_CTRL_TAP_XBAR OT_EG_LC_CTRL_TAP ".xbar"
232+
#define OT_EG_LC_CTRL_TAP_AS OT_EG_LC_CTRL_TAP ".as"
233+
201234
#define OT_EG_IBEX_WRAPPER_NUM_REGIONS 2u
202235

203236
static const uint8_t ot_eg_pmp_cfgs[] = {
@@ -363,6 +396,14 @@ static const IbexDeviceDef ot_eg_soc_devices[] = {
363396
IBEX_DEV_UINT_PROP("idcode", EG_RV_DM_TAP_IDCODE)
364397
),
365398
},
399+
[OT_EG_SOC_DEV_LC_CTRL_TAP_CTRL] = {
400+
.type = TYPE_TAP_CTRL_RBB,
401+
.cfg = &ot_eg_soc_lc_ctrl_tap_ctrl_configure,
402+
.prop = IBEXDEVICEPROPDEFS(
403+
IBEX_DEV_UINT_PROP("ir_length", IBEX_TAP_IR_LENGTH),
404+
IBEX_DEV_UINT_PROP("idcode", EG_LC_CTRL_TAP_IDCODE)
405+
),
406+
},
366407
[OT_EG_SOC_DEV_DTM] = {
367408
.type = TYPE_RISCV_DTM,
368409
.link = IBEXDEVICELINKDEFS(
@@ -372,6 +413,15 @@ static const IbexDeviceDef ot_eg_soc_devices[] = {
372413
IBEX_DEV_UINT_PROP("abits", 7u)
373414
),
374415
},
416+
[OT_EG_SOC_DEV_LC_CTRL_DTM] = {
417+
.type = TYPE_RISCV_DTM,
418+
.link = IBEXDEVICELINKDEFS(
419+
OT_EG_SOC_DEVLINK("tap-ctrl", LC_CTRL_TAP_CTRL)
420+
),
421+
.prop = IBEXDEVICEPROPDEFS(
422+
IBEX_DEV_UINT_PROP("abits", OT_EG_LC_CTRL_TAP_DMI_ABITS)
423+
),
424+
},
375425
[OT_EG_SOC_DEV_DM] = {
376426
.type = TYPE_RISCV_DM,
377427
.cfg = &ot_eg_soc_dm_configure,
@@ -751,7 +801,8 @@ static const IbexDeviceDef ot_eg_soc_devices[] = {
751801
[OT_EG_SOC_DEV_LC_CTRL] = {
752802
.type = TYPE_OT_LC_CTRL,
753803
.memmap = MEMMAPENTRIES(
754-
{ .base = 0x40140000u }
804+
{ .base = 0x40140000u },
805+
{ .base = LC_CTRL_TAP_MEMORY(OT_EG_LC_CTRL_TAP_TL_ADDR) }
755806
),
756807
.gpio = IBEXGPIOCONNDEFS(
757808
OT_EG_SOC_RSP(OT_PWRMGR_LC, PWRMGR),
@@ -1380,6 +1431,19 @@ static const IbexDeviceDef ot_eg_soc_devices[] = {
13801431
OT_EG_SOC_GPIO_ALERT(0, 40)
13811432
),
13821433
},
1434+
[OT_EG_SOC_DEV_DM_LC_CTRL] = {
1435+
.type = TYPE_OT_DM_TL,
1436+
.link = IBEXDEVICELINKDEFS(
1437+
OT_EG_SOC_DEVLINK("dtm", LC_CTRL_DTM),
1438+
OT_EG_SOC_DEVLINK("tl_dev", LC_CTRL)
1439+
),
1440+
.prop = IBEXDEVICEPROPDEFS(
1441+
IBEX_DEV_UINT_PROP("dmi_addr", OT_EG_LC_CTRL_TAP_DMI_ADDR),
1442+
IBEX_DEV_UINT_PROP("dmi_size", OT_EG_LC_CTRL_TAP_DMI_SIZE),
1443+
IBEX_DEV_UINT_PROP("tl_addr", OT_EG_LC_CTRL_TAP_TL_ADDR),
1444+
IBEX_DEV_STRING_PROP("tl_as_name", OT_EG_LC_CTRL_TAP_AS)
1445+
)
1446+
},
13831447
[OT_EG_SOC_DEV_PLIC] = {
13841448
.type = TYPE_SIFIVE_PLIC,
13851449
.memmap = MEMMAPENTRIES(
@@ -1625,6 +1689,20 @@ static void ot_eg_soc_tap_ctrl_configure(
16251689
}
16261690
}
16271691

1692+
static void ot_eg_soc_lc_ctrl_tap_ctrl_configure(
1693+
DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent)
1694+
{
1695+
(void)parent;
1696+
(void)def;
1697+
1698+
Chardev *chr;
1699+
1700+
chr = ibex_get_chardev_by_id("taprbb-lc-ctrl");
1701+
if (chr) {
1702+
qdev_prop_set_chr(dev, "chardev", chr);
1703+
}
1704+
}
1705+
16281706
static void ot_eg_soc_spi_device_configure(
16291707
DeviceState *dev, const IbexDeviceDef *def, DeviceState *parent)
16301708
{
@@ -1770,9 +1848,26 @@ static void ot_eg_soc_realize(DeviceState *dev, Error **errp)
17701848
ot_eg_soc_devices,
17711849
ARRAY_SIZE(ot_eg_soc_devices));
17721850

1773-
MemoryRegion *mrs[] = { get_system_memory(), NULL, NULL, NULL };
1774-
ibex_map_devices(s->devices, mrs, ot_eg_soc_devices,
1775-
ARRAY_SIZE(ot_eg_soc_devices));
1851+
MemoryRegion *lc_ctrl_tap_mr = g_new0(MemoryRegion, 1u);
1852+
memory_region_init(lc_ctrl_tap_mr, OBJECT(dev), OT_EG_LC_CTRL_TAP_XBAR,
1853+
OT_EG_LC_CTRL_TAP_TL_SIZE);
1854+
1855+
MemoryRegion *mrs[IBEX_MEMMAP_REGIDX_COUNT] = {
1856+
[OT_EG_DEFAULT_MEMORY_REGION] = get_system_memory(),
1857+
[OT_EG_LC_CTRL_TAP_MEMORY_REGION] = lc_ctrl_tap_mr,
1858+
};
1859+
ibex_map_devices_mask(s->devices, mrs, ot_eg_soc_devices,
1860+
ARRAY_SIZE(ot_eg_soc_devices),
1861+
IBEX_MEMMAP_MAKE_REG_MASK(
1862+
OT_EG_DEFAULT_MEMORY_REGION) |
1863+
IBEX_MEMMAP_MAKE_REG_MASK(
1864+
OT_EG_LC_CTRL_TAP_MEMORY_REGION));
1865+
Object *oas;
1866+
AddressSpace *as = g_new0(AddressSpace, 1u);
1867+
address_space_init(as, lc_ctrl_tap_mr, OT_EG_LC_CTRL_TAP_AS);
1868+
oas = object_new(TYPE_OT_ADDRESS_SPACE);
1869+
object_property_add_child(OBJECT(dev), as->name, oas);
1870+
ot_address_space_set(OT_ADDRESS_SPACE(oas), as);
17761871

17771872
qdev_connect_gpio_out_named(DEVICE(s->devices[OT_EG_SOC_DEV_RSTMGR]),
17781873
OT_RSTMGR_SOC_RST, 0,

0 commit comments

Comments
 (0)