Commit 71569cd8ab for qemu.org

commit 71569cd8aba31fcb3a326c56c307d2b811417c0b
Merge: 94d689d0c6 0f17ae24b5
Author: Stefan Hajnoczi <stefanha@redhat.com>
Date:   Wed Mar 12 07:50:24 2025 +0800

    Merge tag 'pull-ppc-for-10.0-1-20250311' of https://gitlab.com/npiggin/qemu into staging

    * Next round of XIVE patches...

    * tag 'pull-ppc-for-10.0-1-20250311' of https://gitlab.com/npiggin/qemu: (72 commits)
      docs/system/ppc/amigang.rst: Update for NVRAM emulation
      ppc/amigaone: Add #defines for memory map constants
      ppc/amigaone: Add kernel and initrd support
      ppc/amigaone: Add default environment
      ppc/amigaone: Implement NVRAM emulation
      ppc/amigaone: Simplify replacement dummy_fw
      spapr: Generate random HASHPKEYR for spapr machines
      target/ppc: Avoid warning message for zero process table entries
      target/ppc: Wire up BookE ATB registers for e500 family
      target/ppc: fix timebase register reset state
      spapr: nested: Add support for reporting Hostwide state counter
      ppc: spapr: Enable 2nd DAWR on Power10 pSeries machine
      ppc: Enable 2nd DAWR support on Power10 PowerNV machine
      hw/ppc/epapr: Do not swap ePAPR magic value
      hw/ppc/spapr: Convert DIRTY_HPTE() macro as hpte_set_dirty() method
      hw/ppc/spapr: Convert CLEAN_HPTE() macro as hpte_set_clean() method
      hw/ppc/spapr: Convert HPTE_DIRTY() macro as hpte_is_dirty() method
      hw/ppc/spapr: Convert HPTE_VALID() macro as hpte_is_valid() method
      hw/ppc/spapr: Convert HPTE() macro as hpte_get_ptr() method
      target/ppc: Restrict ATTN / SCV / PMINSN helpers to TCG
      ...

    [Fix __packed macro redefinition on FreeBSD 14 hosts:
    ../hw/ppc/pnv_occ.c:397:9: error: '__packed' macro redefined [-Werror,-Wmacro-redefined]
      397 | #define __packed QEMU_PACKED
          |         ^
    /usr/include/sys/cdefs.h:217:9: note: previous definition is here
      217 | #define __packed        __attribute__((__packed__))
          |         ^
    --Stefan]

    Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>

diff --cc hw/ppc/pnv_occ.c
index 48123ceae1,d9ce35a4d6..bda6b23ad3
--- a/hw/ppc/pnv_occ.c
+++ b/hw/ppc/pnv_occ.c
@@@ -308,3 -363,568 +363,570 @@@ static void pnv_occ_register_types(void
  }

  type_init(pnv_occ_register_types);
+
+ /* From skiboot/hw/occ.c with tab to space conversion */
+ /* OCC Communication Area for PStates */
+
+ #define OPAL_DYNAMIC_DATA_OFFSET        0x0B80
+ /* relative to HOMER_OPAL_DATA_OFFSET */
+
+ #define MAX_PSTATES                     256
+ #define MAX_P8_CORES                    12
+ #define MAX_P9_CORES                    24
+ #define MAX_P10_CORES                   32
+
+ #define MAX_OPAL_CMD_DATA_LENGTH        4090
+ #define MAX_OCC_RSP_DATA_LENGTH         8698
+
+ #define P8_PIR_CORE_MASK                0xFFF8
+ #define P9_PIR_QUAD_MASK                0xFFF0
+ #define P10_PIR_CHIP_MASK               0x0000
+ #define FREQ_MAX_IN_DOMAIN              0
+ #define FREQ_MOST_RECENTLY_SET          1
+
+ #define u8 uint8_t
+ #define s8 int8_t
+ #define u16 uint16_t
+ #define s16 int16_t
+ #define u32 uint32_t
+ #define s32 int32_t
+ #define u64 uint64_t
+ #define s64 int64_t
+ #define __be16 uint16_t
+ #define __be32 uint32_t
++#ifndef __packed
+ #define __packed QEMU_PACKED
++#endif /* !__packed */
+
+ /**
+  * OCC-OPAL Shared Memory Region
+  *
+  * Reference document :
+  * https://github.com/open-power/docs/blob/master/occ/OCC_OpenPwr_FW_Interfaces.pdf
+  *
+  * Supported layout versions:
+  * - 0x01, 0x02 : P8
+  * https://github.com/open-power/occ/blob/master_p8/src/occ/proc/proc_pstate.h
+  *
+  * - 0x90 : P9
+  * https://github.com/open-power/occ/blob/master/src/occ_405/proc/proc_pstate.h
+  *   In 0x90 the data is separated into :-
+  *   -- Static Data (struct occ_pstate_table): Data is written once by OCC
+  *   -- Dynamic Data (struct occ_dynamic_data): Data is updated at runtime
+  *
+  * struct occ_pstate_table -    Pstate table layout
+  * @valid:                      Indicates if data is valid
+  * @version:                    Layout version [Major/Minor]
+  * @v2.throttle:                Reason for limiting the max pstate
+  * @v9.occ_role:                OCC role (Master/Slave)
+  * @v#.pstate_min:              Minimum pstate ever allowed
+  * @v#.pstate_nom:              Nominal pstate
+  * @v#.pstate_turbo:            Maximum turbo pstate
+  * @v#.pstate_ultra_turbo:      Maximum ultra turbo pstate and the maximum
+  *                              pstate ever allowed
+  * @v#.pstates:                 Pstate-id and frequency list from Pmax to Pmin
+  * @v#.pstates.id:              Pstate-id
+  * @v#.pstates.flags:           Pstate-flag(reserved)
+  * @v2.pstates.vdd:             Voltage Identifier
+  * @v2.pstates.vcs:             Voltage Identifier
+  * @v#.pstates.freq_khz:        Frequency in KHz
+  * @v#.core_max[1..N]:          Max pstate with N active cores
+  * @spare/reserved/pad:         Unused data
+  */
+ struct occ_pstate_table {
+     u8 valid;
+     u8 version;
+     union __packed {
+         struct __packed { /* Version 0x01 and 0x02 */
+             u8 throttle;
+             s8 pstate_min;
+             s8 pstate_nom;
+             s8 pstate_turbo;
+             s8 pstate_ultra_turbo;
+             u8 spare;
+             u64 reserved;
+             struct __packed {
+                 s8 id;
+                 u8 flags;
+                 u8 vdd;
+                 u8 vcs;
+                 __be32 freq_khz;
+             } pstates[MAX_PSTATES];
+             s8 core_max[MAX_P8_CORES];
+             u8 pad[100];
+         } v2;
+         struct __packed { /* Version 0x90 */
+             u8 occ_role;
+             u8 pstate_min;
+             u8 pstate_nom;
+             u8 pstate_turbo;
+             u8 pstate_ultra_turbo;
+             u8 spare;
+             u64 reserved1;
+             u64 reserved2;
+             struct __packed {
+                 u8 id;
+                 u8 flags;
+                 u16 reserved;
+                 __be32 freq_khz;
+             } pstates[MAX_PSTATES];
+             u8 core_max[MAX_P9_CORES];
+             u8 pad[56];
+         } v9;
+         struct __packed { /* Version 0xA0 */
+             u8 occ_role;
+             u8 pstate_min;
+             u8 pstate_fixed_freq;
+             u8 pstate_base;
+             u8 pstate_ultra_turbo;
+             u8 pstate_fmax;
+             u8 minor;
+             u8 pstate_bottom_throttle;
+             u8 spare;
+             u8 spare1;
+             u32 reserved_32;
+             u64 reserved_64;
+             struct __packed {
+                 u8 id;
+                 u8 valid;
+                 u16 reserved;
+                 __be32 freq_khz;
+             } pstates[MAX_PSTATES];
+             u8 core_max[MAX_P10_CORES];
+             u8 pad[48];
+         } v10;
+     };
+ } __packed;
+
+ /**
+  * OPAL-OCC Command Response Interface
+  *
+  * OPAL-OCC Command Buffer
+  *
+  * ---------------------------------------------------------------------
+  * | OPAL  |  Cmd    | OPAL |          | Cmd Data | Cmd Data | OPAL    |
+  * | Cmd   | Request | OCC  | Reserved | Length   | Length   | Cmd     |
+  * | Flags |   ID    | Cmd  |          | (MSB)    | (LSB)    | Data... |
+  * ---------------------------------------------------------------------
+  * |  ….OPAL Command Data up to max of Cmd Data Length 4090 bytes      |
+  * |                                                                   |
+  * ---------------------------------------------------------------------
+  *
+  * OPAL Command Flag
+  *
+  * -----------------------------------------------------------------
+  * | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
+  * | (msb) |       |       |       |       |       |       | (lsb) |
+  * -----------------------------------------------------------------
+  * |Cmd    |       |       |       |       |       |       |       |
+  * |Ready  |       |       |       |       |       |       |       |
+  * -----------------------------------------------------------------
+  *
+  * struct opal_command_buffer - Defines the layout of OPAL command buffer
+  * @flag:                       Provides general status of the command
+  * @request_id:                 Token to identify request
+  * @cmd:                        Command sent
+  * @data_size:                  Command data length
+  * @data:                       Command specific data
+  * @spare:                      Unused byte
+  */
+ struct opal_command_buffer {
+     u8 flag;
+     u8 request_id;
+     u8 cmd;
+     u8 spare;
+     __be16 data_size;
+     u8 data[MAX_OPAL_CMD_DATA_LENGTH];
+ } __packed;
+
+ /**
+  * OPAL-OCC Response Buffer
+  *
+  * ---------------------------------------------------------------------
+  * | OCC   |  Cmd    | OPAL | Response | Rsp Data | Rsp Data | OPAL    |
+  * | Rsp   | Request | OCC  |  Status  | Length   | Length   | Rsp     |
+  * | Flags |   ID    | Cmd  |          | (MSB)    | (LSB)    | Data... |
+  * ---------------------------------------------------------------------
+  * |  ….OPAL Response Data up to max of Rsp Data Length 8698 bytes     |
+  * |                                                                   |
+  * ---------------------------------------------------------------------
+  *
+  * OCC Response Flag
+  *
+  * -----------------------------------------------------------------
+  * | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
+  * | (msb) |       |       |       |       |       |       | (lsb) |
+  * -----------------------------------------------------------------
+  * |       |       |       |       |       |       |OCC in  | Rsp  |
+  * |       |       |       |       |       |       |progress|Ready |
+  * -----------------------------------------------------------------
+  *
+  * struct occ_response_buffer - Defines the layout of OCC response buffer
+  * @flag:                       Provides general status of the response
+  * @request_id:                 Token to identify request
+  * @cmd:                        Command requested
+  * @status:                     Indicates success/failure status of
+  *                              the command
+  * @data_size:                  Response data length
+  * @data:                       Response specific data
+  */
+ struct occ_response_buffer {
+     u8 flag;
+     u8 request_id;
+     u8 cmd;
+     u8 status;
+     __be16 data_size;
+     u8 data[MAX_OCC_RSP_DATA_LENGTH];
+ } __packed;
+
+ /**
+  * OCC-OPAL Shared Memory Interface Dynamic Data Vx90
+  *
+  * struct occ_dynamic_data -    Contains runtime attributes
+  * @occ_state:                  Current state of OCC
+  * @major_version:              Major version number
+  * @minor_version:              Minor version number (backwards compatible)
+  *                              Version 1 indicates GPU presence populated
+  * @gpus_present:               Bitmask of GPUs present (on systems where GPU
+  *                              presence is detected through APSS)
+  * @cpu_throttle:               Reason for limiting the max pstate
+  * @mem_throttle:               Reason for throttling memory
+  * @quick_pwr_drop:             Indicates if QPD is asserted
+  * @pwr_shifting_ratio:         Indicates the current percentage of power to
+  *                              take away from the CPU vs GPU when shifting
+  *                              power to maintain a power cap. Value of 100
+  *                              means take all power from CPU.
+  * @pwr_cap_type:               Indicates type of power cap in effect
+  * @hard_min_pwr_cap:           Hard minimum system power cap in Watts.
+  *                              Guaranteed unless hardware failure
+  * @max_pwr_cap:                Maximum allowed system power cap in Watts
+  * @cur_pwr_cap:                Current system power cap
+  * @soft_min_pwr_cap:           Soft powercap minimum. OCC may or may not be
+  *                              able to maintain this
+  * @spare/reserved:             Unused data
+  * @cmd:                        Opal Command Buffer
+  * @rsp:                        OCC Response Buffer
+  */
+ struct occ_dynamic_data {
+     u8 occ_state;
+     u8 major_version;
+     u8 minor_version;
+     u8 gpus_present;
+     union __packed {
+         struct __packed { /* Version 0x90 */
+             u8 spare1;
+         } v9;
+         struct __packed { /* Version 0xA0 */
+             u8 wof_enabled;
+         } v10;
+     };
+     u8 cpu_throttle;
+     u8 mem_throttle;
+     u8 quick_pwr_drop;
+     u8 pwr_shifting_ratio;
+     u8 pwr_cap_type;
+     __be16 hard_min_pwr_cap;
+     __be16 max_pwr_cap;
+     __be16 cur_pwr_cap;
+     __be16 soft_min_pwr_cap;
+     u8 pad[110];
+     struct opal_command_buffer cmd;
+     struct occ_response_buffer rsp;
+ } __packed;
+
+ enum occ_response_status {
+     OCC_RSP_SUCCESS                 = 0x00,
+     OCC_RSP_INVALID_COMMAND         = 0x11,
+     OCC_RSP_INVALID_CMD_DATA_LENGTH = 0x12,
+     OCC_RSP_INVALID_DATA            = 0x13,
+     OCC_RSP_INTERNAL_ERROR          = 0x15,
+ };
+
+ #define OCC_ROLE_SLAVE                  0x00
+ #define OCC_ROLE_MASTER                 0x01
+
+ #define OCC_FLAG_RSP_READY              0x01
+ #define OCC_FLAG_CMD_IN_PROGRESS        0x02
+ #define OPAL_FLAG_CMD_READY             0x80
+
+ #define PCAP_MAX_POWER_W                100
+ #define PCAP_SOFT_MIN_POWER_W            20
+ #define PCAP_HARD_MIN_POWER_W            10
+
+ static bool occ_write_static_data(PnvOCC *occ,
+                                  struct occ_pstate_table *static_data,
+                                  Error **errp)
+ {
+     PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
+     PnvHomer *homer = occ->homer;
+     hwaddr static_addr = homer->base + poc->opal_shared_memory_offset;
+     MemTxResult ret;
+
+     ret = address_space_write(&address_space_memory, static_addr,
+                              MEMTXATTRS_UNSPECIFIED, static_data,
+                              sizeof(*static_data));
+     if (ret != MEMTX_OK) {
+         error_setg(errp, "OCC: cannot write OCC-OPAL static data");
+         return false;
+     }
+
+     return true;
+ }
+
+ static bool occ_read_dynamic_data(PnvOCC *occ,
+                                   struct occ_dynamic_data *dynamic_data,
+                                   Error **errp)
+ {
+     PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
+     PnvHomer *homer = occ->homer;
+     hwaddr static_addr = homer->base + poc->opal_shared_memory_offset;
+     hwaddr dynamic_addr = static_addr + OPAL_DYNAMIC_DATA_OFFSET;
+     MemTxResult ret;
+
+     ret = address_space_read(&address_space_memory, dynamic_addr,
+                              MEMTXATTRS_UNSPECIFIED, dynamic_data,
+                              sizeof(*dynamic_data));
+     if (ret != MEMTX_OK) {
+         error_setg(errp, "OCC: cannot read OCC-OPAL dynamic data");
+         return false;
+     }
+
+     return true;
+ }
+
+ static bool occ_write_dynamic_data(PnvOCC *occ,
+                                   struct occ_dynamic_data *dynamic_data,
+                                   Error **errp)
+ {
+     PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
+     PnvHomer *homer = occ->homer;
+     hwaddr static_addr = homer->base + poc->opal_shared_memory_offset;
+     hwaddr dynamic_addr = static_addr + OPAL_DYNAMIC_DATA_OFFSET;
+     MemTxResult ret;
+
+     ret = address_space_write(&address_space_memory, dynamic_addr,
+                              MEMTXATTRS_UNSPECIFIED, dynamic_data,
+                              sizeof(*dynamic_data));
+     if (ret != MEMTX_OK) {
+         error_setg(errp, "OCC: cannot write OCC-OPAL dynamic data");
+         return false;
+     }
+
+     return true;
+ }
+
+ static bool occ_opal_send_response(PnvOCC *occ,
+                                    struct occ_dynamic_data *dynamic_data,
+                                    enum occ_response_status status,
+                                    uint8_t *data, uint16_t datalen)
+ {
+     struct opal_command_buffer *cmd = &dynamic_data->cmd;
+     struct occ_response_buffer *rsp = &dynamic_data->rsp;
+
+     rsp->request_id = cmd->request_id;
+     rsp->cmd = cmd->cmd;
+     rsp->status = status;
+     rsp->data_size = cpu_to_be16(datalen);
+     if (datalen) {
+         memcpy(rsp->data, data, datalen);
+     }
+     if (!occ_write_dynamic_data(occ, dynamic_data, NULL)) {
+         return false;
+     }
+     /* Would be a memory barrier here */
+     rsp->flag = OCC_FLAG_RSP_READY;
+     cmd->flag = 0;
+     if (!occ_write_dynamic_data(occ, dynamic_data, NULL)) {
+         return false;
+     }
+
+     pnv_occ_raise_msg_irq(occ);
+
+     return true;
+ }
+
+ /* Returns error status */
+ static bool occ_opal_process_command(PnvOCC *occ,
+                                      struct occ_dynamic_data *dynamic_data)
+ {
+     struct opal_command_buffer *cmd = &dynamic_data->cmd;
+     struct occ_response_buffer *rsp = &dynamic_data->rsp;
+
+     if (rsp->flag == 0) {
+         /* Spend one "tick" in the in-progress state */
+         rsp->flag = OCC_FLAG_CMD_IN_PROGRESS;
+         return occ_write_dynamic_data(occ, dynamic_data, NULL);
+     } else if (rsp->flag != OCC_FLAG_CMD_IN_PROGRESS) {
+         return occ_opal_send_response(occ, dynamic_data,
+                                       OCC_RSP_INTERNAL_ERROR,
+                                       NULL, 0);
+     }
+
+     switch (cmd->cmd) {
+     case 0xD1: { /* SET_POWER_CAP */
+         uint16_t data;
+         if (be16_to_cpu(cmd->data_size) != 2) {
+             return occ_opal_send_response(occ, dynamic_data,
+                                           OCC_RSP_INVALID_CMD_DATA_LENGTH,
+                                           (uint8_t *)&dynamic_data->cur_pwr_cap,
+                                           2);
+         }
+         data = be16_to_cpu(*(uint16_t *)cmd->data);
+         if (data == 0) { /* clear power cap */
+             dynamic_data->pwr_cap_type = 0x00; /* none */
+             data = PCAP_MAX_POWER_W;
+         } else {
+             dynamic_data->pwr_cap_type = 0x02; /* user set in-band */
+             if (data < PCAP_HARD_MIN_POWER_W) {
+                 data = PCAP_HARD_MIN_POWER_W;
+             } else if (data > PCAP_MAX_POWER_W) {
+                 data = PCAP_MAX_POWER_W;
+             }
+         }
+         dynamic_data->cur_pwr_cap = cpu_to_be16(data);
+         return occ_opal_send_response(occ, dynamic_data,
+                                       OCC_RSP_SUCCESS,
+                                       (uint8_t *)&dynamic_data->cur_pwr_cap, 2);
+     }
+
+     default:
+         return occ_opal_send_response(occ, dynamic_data,
+                                       OCC_RSP_INVALID_COMMAND,
+                                       NULL, 0);
+     }
+     g_assert_not_reached();
+ }
+
+ static bool occ_model_tick(PnvOCC *occ)
+ {
+     struct occ_dynamic_data dynamic_data;
+
+     if (!occ_read_dynamic_data(occ, &dynamic_data, NULL)) {
+         /* Can't move OCC state field to safe because we can't map it! */
+         qemu_log("OCC: failed to read HOMER data, shutting down OCC\n");
+         return false;
+     }
+     if (dynamic_data.cmd.flag == OPAL_FLAG_CMD_READY) {
+         if (!occ_opal_process_command(occ, &dynamic_data)) {
+             qemu_log("OCC: failed to write HOMER data, shutting down OCC\n");
+             return false;
+         }
+     }
+
+     return true;
+ }
+
+ static bool occ_init_homer_memory(PnvOCC *occ, Error **errp)
+ {
+     PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
+     PnvHomer *homer = occ->homer;
+     PnvChip *chip = homer->chip;
+     struct occ_pstate_table static_data;
+     struct occ_dynamic_data dynamic_data;
+     int i;
+
+     memset(&static_data, 0, sizeof(static_data));
+     static_data.valid = 1;
+     static_data.version = poc->opal_shared_memory_version;
+     switch (poc->opal_shared_memory_version) {
+     case 0x02:
+         static_data.v2.throttle = 0;
+         static_data.v2.pstate_min = -2;
+         static_data.v2.pstate_nom = -1;
+         static_data.v2.pstate_turbo = -1;
+         static_data.v2.pstate_ultra_turbo = 0;
+         static_data.v2.pstates[0].id = 0;
+         static_data.v2.pstates[1].freq_khz = cpu_to_be32(4000000);
+         static_data.v2.pstates[1].id = -1;
+         static_data.v2.pstates[1].freq_khz = cpu_to_be32(3000000);
+         static_data.v2.pstates[2].id = -2;
+         static_data.v2.pstates[2].freq_khz = cpu_to_be32(2000000);
+         for (i = 0; i < chip->nr_cores; i++) {
+             static_data.v2.core_max[i] = 1;
+         }
+         break;
+     case 0x90:
+         if (chip->chip_id == 0) {
+             static_data.v9.occ_role = OCC_ROLE_MASTER;
+         } else {
+             static_data.v9.occ_role = OCC_ROLE_SLAVE;
+         }
+         static_data.v9.pstate_min = 2;
+         static_data.v9.pstate_nom = 1;
+         static_data.v9.pstate_turbo = 1;
+         static_data.v9.pstate_ultra_turbo = 0;
+         static_data.v9.pstates[0].id = 0;
+         static_data.v9.pstates[0].freq_khz = cpu_to_be32(4000000);
+         static_data.v9.pstates[1].id = 1;
+         static_data.v9.pstates[1].freq_khz = cpu_to_be32(3000000);
+         static_data.v9.pstates[2].id = 2;
+         static_data.v9.pstates[2].freq_khz = cpu_to_be32(2000000);
+         for (i = 0; i < chip->nr_cores; i++) {
+             static_data.v9.core_max[i] = 1;
+         }
+         break;
+     case 0xA0:
+         if (chip->chip_id == 0) {
+             static_data.v10.occ_role = OCC_ROLE_MASTER;
+         } else {
+             static_data.v10.occ_role = OCC_ROLE_SLAVE;
+         }
+         static_data.v10.pstate_min = 4;
+         static_data.v10.pstate_fixed_freq = 3;
+         static_data.v10.pstate_base = 2;
+         static_data.v10.pstate_ultra_turbo = 0;
+         static_data.v10.pstate_fmax = 1;
+         static_data.v10.minor = 0x01;
+         static_data.v10.pstates[0].valid = 1;
+         static_data.v10.pstates[0].id = 0;
+         static_data.v10.pstates[0].freq_khz = cpu_to_be32(4200000);
+         static_data.v10.pstates[1].valid = 1;
+         static_data.v10.pstates[1].id = 1;
+         static_data.v10.pstates[1].freq_khz = cpu_to_be32(4000000);
+         static_data.v10.pstates[2].valid = 1;
+         static_data.v10.pstates[2].id = 2;
+         static_data.v10.pstates[2].freq_khz = cpu_to_be32(3800000);
+         static_data.v10.pstates[3].valid = 1;
+         static_data.v10.pstates[3].id = 3;
+         static_data.v10.pstates[3].freq_khz = cpu_to_be32(3000000);
+         static_data.v10.pstates[4].valid = 1;
+         static_data.v10.pstates[4].id = 4;
+         static_data.v10.pstates[4].freq_khz = cpu_to_be32(2000000);
+         for (i = 0; i < chip->nr_cores; i++) {
+             static_data.v10.core_max[i] = 1;
+         }
+         break;
+     default:
+         g_assert_not_reached();
+     }
+     if (!occ_write_static_data(occ, &static_data, errp)) {
+         return false;
+     }
+
+     memset(&dynamic_data, 0, sizeof(dynamic_data));
+     dynamic_data.occ_state = 0x3; /* active */
+     dynamic_data.major_version = 0x0;
+     dynamic_data.hard_min_pwr_cap = cpu_to_be16(PCAP_HARD_MIN_POWER_W);
+     dynamic_data.max_pwr_cap = cpu_to_be16(PCAP_MAX_POWER_W);
+     dynamic_data.cur_pwr_cap = cpu_to_be16(PCAP_MAX_POWER_W);
+     dynamic_data.soft_min_pwr_cap = cpu_to_be16(PCAP_SOFT_MIN_POWER_W);
+     switch (poc->opal_shared_memory_version) {
+     case 0xA0:
+         dynamic_data.minor_version = 0x1;
+         dynamic_data.v10.wof_enabled = 0x1;
+         break;
+     case 0x90:
+         dynamic_data.minor_version = 0x1;
+         break;
+     case 0x02:
+         dynamic_data.minor_version = 0x0;
+         break;
+     default:
+         g_assert_not_reached();
+     }
+     if (!occ_write_dynamic_data(occ, &dynamic_data, errp)) {
+         return false;
+     }
+
+     return true;
+ }