Message ID | 1375366359-11553-3-git-send-email-jjherne@us.ibm.com |
---|---|
State | New |
Headers | show |
Am 01.08.2013 16:12, schrieb Jason J. Herne: > From: "Jason J. Herne" <jjherne@us.ibm.com> > > Implement the CPU data in SCLP "Read SCP Info". And implement "Read CPU Info" > SCLP command. This data will be used by the guest to get information about hot > plugged cpus. > > Signed-off-by: Jason J. Herne <jjherne@us.ibm.com> > --- > hw/s390x/sclp.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ > include/hw/s390x/sclp.h | 32 +++++++++++++++++++++++++++++ > 2 files changed, 83 insertions(+) > > diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c > index cb53d7e..da8cf7a 100644 > --- a/hw/s390x/sclp.c > +++ b/hw/s390x/sclp.c > @@ -15,6 +15,7 @@ > #include "cpu.h" > #include "sysemu/kvm.h" > #include "exec/memory.h" > +#include "sysemu/sysemu.h" > > #include "hw/s390x/sclp.h" > > @@ -31,7 +32,26 @@ static inline S390SCLPDevice *get_event_facility(void) > static void read_SCP_info(SCCB *sccb) > { > ReadInfo *read_info = (ReadInfo *) sccb; > + CPUState *cpu; > int shift = 0; > + int cpu_count = 0; > + int i = 0; > + > + for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { > + cpu_count++; > + } > + > + /* CPU information */ > + read_info->entries_cpu = cpu_to_be16(cpu_count); > + read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries)); > + read_info->highest_cpu = cpu_to_be16(max_cpus); > + > + for (i = 0; i < cpu_count; i++) { > + read_info->entries[i].address = i; > + read_info->entries[i].type = 0; > + } > + > + read_info->facilities = cpu_to_be64(SCLP_HAS_CPU_INFO); > > while ((ram_size >> (20 + shift)) > 65535) { > shift++; > @@ -41,6 +61,34 @@ static void read_SCP_info(SCCB *sccb) > sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION); > } > > +/* Provide information about the CPU */ > +static void sclp_read_cpu_info(SCCB *sccb) > +{ > + ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb; > + CPUState *cpu; > + int cpu_count = 0; > + int i = 0; > + > + for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { This becomes CPU_FOREACH(cpu) { now. > + cpu_count++; > + } > + > + cpu_info->nr_configured = cpu_to_be16(cpu_count); > + cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries)); > + cpu_info->nr_standby = cpu_to_be16(0); > + > + /* The standby offset is 16-byte for each CPU */ > + cpu_info->offset_standby = cpu_to_be16(cpu_info->offset_configured > + + cpu_info->nr_configured*sizeof(CpuEntry)); > + > + for (i = 0; i < cpu_count; i++) { > + cpu_info->entries[i].address = i; > + cpu_info->entries[i].type = 0; > + } > + > + sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION); > +} > + > static void sclp_execute(SCCB *sccb, uint64_t code) > { > S390SCLPDevice *sdev = get_event_facility(); > @@ -50,6 +98,9 @@ static void sclp_execute(SCCB *sccb, uint64_t code) > case SCLP_CMDW_READ_SCP_INFO_FORCED: > read_SCP_info(sccb); > break; > + case SCLP_CMDW_READ_CPU_INFO: > + sclp_read_cpu_info(sccb); > + break; > default: > sdev->sclp_command_handler(sdev->ef, sccb, code); > break; > diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h > index 174097d..89ae7d1 100644 > --- a/include/hw/s390x/sclp.h > +++ b/include/hw/s390x/sclp.h > @@ -79,12 +79,44 @@ typedef struct SCCBHeader { > > #define SCCB_DATA_LEN (SCCB_SIZE - sizeof(SCCBHeader)) > > +/* CPU information */ > +typedef struct CpuEntry { > + uint8_t address; > + uint8_t reserved0[13]; > + uint8_t type; > + uint8_t reserved1; > +} QEMU_PACKED CpuEntry; Feel free to use CPUEntry capitalization if this is not copied from a Linux struct of that name - your choice. Andreas > + > typedef struct ReadInfo { > SCCBHeader h; > uint16_t rnmax; > uint8_t rnsize; > + uint8_t _reserved1[16 - 11]; /* 11-15 */ > + uint16_t entries_cpu; /* 16-17 */ > + uint16_t offset_cpu; /* 18-19 */ > + uint8_t _reserved2[24 - 20]; /* 20-23 */ > + uint8_t loadparm[8]; /* 24-31 */ > + uint8_t _reserved3[48 - 32]; /* 32-47 */ > + uint64_t facilities; /* 48-55 */ > + uint8_t _reserved0[100 - 56]; > + uint32_t rnsize2; > + uint64_t rnmax2; > + uint8_t _reserved4[120-112]; /* 112-119 */ > + uint16_t highest_cpu; > + uint8_t _reserved5[128 - 122]; /* 122-127 */ > + struct CpuEntry entries[0]; > } QEMU_PACKED ReadInfo; > > +typedef struct ReadCpuInfo { > + SCCBHeader h; > + uint16_t nr_configured; /* 8-9 */ > + uint16_t offset_configured; /* 10-11 */ > + uint16_t nr_standby; /* 12-13 */ > + uint16_t offset_standby; /* 14-15 */ > + uint8_t reserved0[24-16]; /* 16-23 */ > + struct CpuEntry entries[0]; > +} QEMU_PACKED ReadCpuInfo; > + > typedef struct SCCB { > SCCBHeader h; > char data[SCCB_DATA_LEN]; >
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c index cb53d7e..da8cf7a 100644 --- a/hw/s390x/sclp.c +++ b/hw/s390x/sclp.c @@ -15,6 +15,7 @@ #include "cpu.h" #include "sysemu/kvm.h" #include "exec/memory.h" +#include "sysemu/sysemu.h" #include "hw/s390x/sclp.h" @@ -31,7 +32,26 @@ static inline S390SCLPDevice *get_event_facility(void) static void read_SCP_info(SCCB *sccb) { ReadInfo *read_info = (ReadInfo *) sccb; + CPUState *cpu; int shift = 0; + int cpu_count = 0; + int i = 0; + + for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { + cpu_count++; + } + + /* CPU information */ + read_info->entries_cpu = cpu_to_be16(cpu_count); + read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries)); + read_info->highest_cpu = cpu_to_be16(max_cpus); + + for (i = 0; i < cpu_count; i++) { + read_info->entries[i].address = i; + read_info->entries[i].type = 0; + } + + read_info->facilities = cpu_to_be64(SCLP_HAS_CPU_INFO); while ((ram_size >> (20 + shift)) > 65535) { shift++; @@ -41,6 +61,34 @@ static void read_SCP_info(SCCB *sccb) sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION); } +/* Provide information about the CPU */ +static void sclp_read_cpu_info(SCCB *sccb) +{ + ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb; + CPUState *cpu; + int cpu_count = 0; + int i = 0; + + for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { + cpu_count++; + } + + cpu_info->nr_configured = cpu_to_be16(cpu_count); + cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries)); + cpu_info->nr_standby = cpu_to_be16(0); + + /* The standby offset is 16-byte for each CPU */ + cpu_info->offset_standby = cpu_to_be16(cpu_info->offset_configured + + cpu_info->nr_configured*sizeof(CpuEntry)); + + for (i = 0; i < cpu_count; i++) { + cpu_info->entries[i].address = i; + cpu_info->entries[i].type = 0; + } + + sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION); +} + static void sclp_execute(SCCB *sccb, uint64_t code) { S390SCLPDevice *sdev = get_event_facility(); @@ -50,6 +98,9 @@ static void sclp_execute(SCCB *sccb, uint64_t code) case SCLP_CMDW_READ_SCP_INFO_FORCED: read_SCP_info(sccb); break; + case SCLP_CMDW_READ_CPU_INFO: + sclp_read_cpu_info(sccb); + break; default: sdev->sclp_command_handler(sdev->ef, sccb, code); break; diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h index 174097d..89ae7d1 100644 --- a/include/hw/s390x/sclp.h +++ b/include/hw/s390x/sclp.h @@ -79,12 +79,44 @@ typedef struct SCCBHeader { #define SCCB_DATA_LEN (SCCB_SIZE - sizeof(SCCBHeader)) +/* CPU information */ +typedef struct CpuEntry { + uint8_t address; + uint8_t reserved0[13]; + uint8_t type; + uint8_t reserved1; +} QEMU_PACKED CpuEntry; + typedef struct ReadInfo { SCCBHeader h; uint16_t rnmax; uint8_t rnsize; + uint8_t _reserved1[16 - 11]; /* 11-15 */ + uint16_t entries_cpu; /* 16-17 */ + uint16_t offset_cpu; /* 18-19 */ + uint8_t _reserved2[24 - 20]; /* 20-23 */ + uint8_t loadparm[8]; /* 24-31 */ + uint8_t _reserved3[48 - 32]; /* 32-47 */ + uint64_t facilities; /* 48-55 */ + uint8_t _reserved0[100 - 56]; + uint32_t rnsize2; + uint64_t rnmax2; + uint8_t _reserved4[120-112]; /* 112-119 */ + uint16_t highest_cpu; + uint8_t _reserved5[128 - 122]; /* 122-127 */ + struct CpuEntry entries[0]; } QEMU_PACKED ReadInfo; +typedef struct ReadCpuInfo { + SCCBHeader h; + uint16_t nr_configured; /* 8-9 */ + uint16_t offset_configured; /* 10-11 */ + uint16_t nr_standby; /* 12-13 */ + uint16_t offset_standby; /* 14-15 */ + uint8_t reserved0[24-16]; /* 16-23 */ + struct CpuEntry entries[0]; +} QEMU_PACKED ReadCpuInfo; + typedef struct SCCB { SCCBHeader h; char data[SCCB_DATA_LEN];