|
@@ -762,6 +762,9 @@ static void pnv_xive2_vst_set_exclusive(PnvXive2 *xive, uint8_t type,
|
|
* entries provisioned by FW (such as skiboot) and resize the
|
|
* entries provisioned by FW (such as skiboot) and resize the
|
|
* ESB window accordingly.
|
|
* ESB window accordingly.
|
|
*/
|
|
*/
|
|
|
|
+ if (memory_region_is_mapped(&xsrc->esb_mmio)) {
|
|
|
|
+ memory_region_del_subregion(&xive->esb_mmio, &xsrc->esb_mmio);
|
|
|
|
+ }
|
|
if (!(VSD_INDIRECT & vsd)) {
|
|
if (!(VSD_INDIRECT & vsd)) {
|
|
memory_region_set_size(&xsrc->esb_mmio, vst_tsize * SBE_PER_BYTE
|
|
memory_region_set_size(&xsrc->esb_mmio, vst_tsize * SBE_PER_BYTE
|
|
* (1ull << xsrc->esb_shift));
|
|
* (1ull << xsrc->esb_shift));
|
|
@@ -777,6 +780,9 @@ static void pnv_xive2_vst_set_exclusive(PnvXive2 *xive, uint8_t type,
|
|
/*
|
|
/*
|
|
* Backing store pages for the END.
|
|
* Backing store pages for the END.
|
|
*/
|
|
*/
|
|
|
|
+ if (memory_region_is_mapped(&end_xsrc->esb_mmio)) {
|
|
|
|
+ memory_region_del_subregion(&xive->end_mmio, &end_xsrc->esb_mmio);
|
|
|
|
+ }
|
|
if (!(VSD_INDIRECT & vsd)) {
|
|
if (!(VSD_INDIRECT & vsd)) {
|
|
memory_region_set_size(&end_xsrc->esb_mmio, (vst_tsize / info->size)
|
|
memory_region_set_size(&end_xsrc->esb_mmio, (vst_tsize / info->size)
|
|
* (1ull << end_xsrc->esb_shift));
|
|
* (1ull << end_xsrc->esb_shift));
|
|
@@ -801,13 +807,10 @@ static void pnv_xive2_vst_set_exclusive(PnvXive2 *xive, uint8_t type,
|
|
* Both PC and VC sub-engines are configured as each use the Virtual
|
|
* Both PC and VC sub-engines are configured as each use the Virtual
|
|
* Structure Tables
|
|
* Structure Tables
|
|
*/
|
|
*/
|
|
-static void pnv_xive2_vst_set_data(PnvXive2 *xive, uint64_t vsd)
|
|
|
|
|
|
+static void pnv_xive2_vst_set_data(PnvXive2 *xive, uint64_t vsd,
|
|
|
|
+ uint8_t type, uint8_t blk)
|
|
{
|
|
{
|
|
uint8_t mode = GETFIELD(VSD_MODE, vsd);
|
|
uint8_t mode = GETFIELD(VSD_MODE, vsd);
|
|
- uint8_t type = GETFIELD(VC_VSD_TABLE_SELECT,
|
|
|
|
- xive->vc_regs[VC_VSD_TABLE_ADDR >> 3]);
|
|
|
|
- uint8_t blk = GETFIELD(VC_VSD_TABLE_ADDRESS,
|
|
|
|
- xive->vc_regs[VC_VSD_TABLE_ADDR >> 3]);
|
|
|
|
uint64_t vst_addr = vsd & VSD_ADDRESS_MASK;
|
|
uint64_t vst_addr = vsd & VSD_ADDRESS_MASK;
|
|
|
|
|
|
if (type > VST_ERQ) {
|
|
if (type > VST_ERQ) {
|
|
@@ -842,6 +845,16 @@ static void pnv_xive2_vst_set_data(PnvXive2 *xive, uint64_t vsd)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void pnv_xive2_vc_vst_set_data(PnvXive2 *xive, uint64_t vsd)
|
|
|
|
+{
|
|
|
|
+ uint8_t type = GETFIELD(VC_VSD_TABLE_SELECT,
|
|
|
|
+ xive->vc_regs[VC_VSD_TABLE_ADDR >> 3]);
|
|
|
|
+ uint8_t blk = GETFIELD(VC_VSD_TABLE_ADDRESS,
|
|
|
|
+ xive->vc_regs[VC_VSD_TABLE_ADDR >> 3]);
|
|
|
|
+
|
|
|
|
+ pnv_xive2_vst_set_data(xive, vsd, type, blk);
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* MMIO handlers
|
|
* MMIO handlers
|
|
*/
|
|
*/
|
|
@@ -1271,7 +1284,7 @@ static void pnv_xive2_ic_vc_write(void *opaque, hwaddr offset,
|
|
case VC_VSD_TABLE_ADDR:
|
|
case VC_VSD_TABLE_ADDR:
|
|
break;
|
|
break;
|
|
case VC_VSD_TABLE_DATA:
|
|
case VC_VSD_TABLE_DATA:
|
|
- pnv_xive2_vst_set_data(xive, val);
|
|
|
|
|
|
+ pnv_xive2_vc_vst_set_data(xive, val);
|
|
break;
|
|
break;
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1490,6 +1503,16 @@ static uint64_t pnv_xive2_ic_pc_read(void *opaque, hwaddr offset,
|
|
return val;
|
|
return val;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void pnv_xive2_pc_vst_set_data(PnvXive2 *xive, uint64_t vsd)
|
|
|
|
+{
|
|
|
|
+ uint8_t type = GETFIELD(PC_VSD_TABLE_SELECT,
|
|
|
|
+ xive->pc_regs[PC_VSD_TABLE_ADDR >> 3]);
|
|
|
|
+ uint8_t blk = GETFIELD(PC_VSD_TABLE_ADDRESS,
|
|
|
|
+ xive->pc_regs[PC_VSD_TABLE_ADDR >> 3]);
|
|
|
|
+
|
|
|
|
+ pnv_xive2_vst_set_data(xive, vsd, type, blk);
|
|
|
|
+}
|
|
|
|
+
|
|
static void pnv_xive2_ic_pc_write(void *opaque, hwaddr offset,
|
|
static void pnv_xive2_ic_pc_write(void *opaque, hwaddr offset,
|
|
uint64_t val, unsigned size)
|
|
uint64_t val, unsigned size)
|
|
{
|
|
{
|
|
@@ -1500,12 +1523,18 @@ static void pnv_xive2_ic_pc_write(void *opaque, hwaddr offset,
|
|
switch (offset) {
|
|
switch (offset) {
|
|
|
|
|
|
/*
|
|
/*
|
|
- * VSD table settings. Only taken into account in the VC
|
|
|
|
- * sub-engine because the Xive2Router model combines both VC and PC
|
|
|
|
- * sub-engines
|
|
|
|
|
|
+ * VSD table settings.
|
|
|
|
+ * The Xive2Router model combines both VC and PC sub-engines. We
|
|
|
|
+ * allow to configure the tables through both, for the rare cases
|
|
|
|
+ * where a table only really needs to be configured for one of
|
|
|
|
+ * them (e.g. the NVG table for the presenter). It assumes that
|
|
|
|
+ * firmware passes the same address to the VC and PC when tables
|
|
|
|
+ * are defined for both, which seems acceptable.
|
|
*/
|
|
*/
|
|
case PC_VSD_TABLE_ADDR:
|
|
case PC_VSD_TABLE_ADDR:
|
|
|
|
+ break;
|
|
case PC_VSD_TABLE_DATA:
|
|
case PC_VSD_TABLE_DATA:
|
|
|
|
+ pnv_xive2_pc_vst_set_data(xive, val);
|
|
break;
|
|
break;
|
|
|
|
|
|
case PC_NXC_PROC_CONFIG:
|
|
case PC_NXC_PROC_CONFIG:
|