Subject: [PATCH/RFC 2/5] s390 zlive privileged instructions
From: Carsten Otte <[EMAIL PROTECTED]>
From: Christian Borntraeger <[EMAIL PROTECTED]>
This patch adds two things to the base code:
o infrastructure for handling priviledged operations
o handlers for basic priv ops, which are necessary to run Linux
Most handlers follow the behaviour defined in Principles of Operation.
Some handlers (e.g. store system information) provide only a limited subset
of the functionality, just enough to make things work.
We do not provide functionality for classic channel subsystem I/O, instead we
return condition code 3 on store subchannel. We use paravirtualized drivers
as we currently dont need full device virtualization.
Signed-off-by: Carsten Otte <[EMAIL PROTECTED]>
---
include/system_info.h | 89 +++++++++++
include/zlpriv.h | 30 +++
priv/Makefile | 25 +++
priv/chsc.c | 28 +++
priv/insert_storage_key_extended.c | 30 +++
priv/priv.c | 46 +++++
priv/set_prefix.c | 43 +++++
priv/set_storage_key_extended.c | 32 ++++
priv/store_cpu_address.c | 34 ++++
priv/store_cpu_id.c | 86 +++++++++++
priv/store_facility_list.c | 31 ++++
priv/store_prefix.c | 32 ++++
priv/store_subchannel.c | 27 +++
priv/store_system_info.c | 284 +++++++++++++++++++++++++++++++++++++
14 files changed, 817 insertions(+)
Index: zlive/include/system_info.h
===================================================================
--- /dev/null
+++ zlive/include/system_info.h
@@ -0,0 +1,89 @@
+/*
+ * z/Live store system information privileged instruction
+ * Copyright IBM Corp. 2007
+ * Author: Christian Borntraeger <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#ifndef __system_info_h__
+#define __system_info_h__
+struct sysinfo_1_1_1
+{
+ char reserved_0[32];
+ char manufacturer[16];
+ char type[4];
+ char reserved_1[12];
+ char model[16];
+ char sequence[16];
+ char plant[4];
+};
+
+struct sysinfo_1_2_1
+{
+ char reserved_0[80];
+ char sequence[16];
+ char plant[4];
+ char reserved_1[2];
+ unsigned short cpu_address;
+};
+
+struct sysinfo_1_2_2
+{
+ char reserved_0[32];
+ unsigned int capability;
+ unsigned short cpus_total;
+ unsigned short cpus_configured;
+ unsigned short cpus_standby;
+ unsigned short cpus_reserved;
+ unsigned short adjustment[0];
+};
+
+struct sysinfo_2_2_1
+{
+ char reserved_0[80];
+ char sequence[16];
+ char plant[4];
+ unsigned short cpu_id;
+ unsigned short cpu_address;
+};
+
+struct sysinfo_2_2_2
+{
+ char reserved_0[32];
+ unsigned short lpar_number;
+ char reserved_1;
+ unsigned char characteristics;
+ #define LPAR_CHAR_DEDICATED (1 << 7)
+ #define LPAR_CHAR_SHARED (1 << 6)
+ #define LPAR_CHAR_LIMITED (1 << 5)
+ unsigned short cpus_total;
+ unsigned short cpus_configured;
+ unsigned short cpus_standby;
+ unsigned short cpus_reserved;
+ char name[8];
+ unsigned int caf;
+ char reserved_2[16];
+ unsigned short cpus_dedicated;
+ unsigned short cpus_shared;
+};
+
+struct sysinfo_3_2_2
+{
+ char reserved_0[31];
+ unsigned char count;
+ struct
+ {
+ char reserved_0[4];
+ unsigned short cpus_total;
+ unsigned short cpus_configured;
+ unsigned short cpus_standby;
+ unsigned short cpus_reserved;
+ char name[8];
+ unsigned int caf;
+ char cpi[16];
+ char reserved_1[24];
+
+ } vm[8];
+};
+#endif
Index: zlive/include/zlpriv.h
===================================================================
--- /dev/null
+++ zlive/include/zlpriv.h
@@ -0,0 +1,30 @@
+/*
+ * z/Live privileged instruction header file
+ * Copyright IBM Corp. 2007
+ * Author: Carsten Otte <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#ifndef __ZLPRIV_H
+#define __ZLPRIV_H
+#include <zlintercept.h>
+
+//opcode minors for privileged instructions
+#define PRIV_STORE_CPU_ID 0x02
+#define PRIV_SET_PREFIX 0x10
+#define PRIV_STORE_PREFIX 0x11
+#define PRIV_STORE_CPU_ADDRESS 0x12
+#define PRIV_SCLP_CALL 0x20
+#define PRIV_INSERT_STORAGE_KEY_EXTENDED 0x29
+#define PRIV_SET_STORAGE_KEY_EXTENDED 0x2b
+#define PRIV_STORE_SUBCHANNEL 0x34
+#define PRIV_CSP 0x50
+#define PRIV_CHSC 0x5f
+#define PRIV_STORE_SYSTEM_INFORMATION 0x7D
+#define PRIV_STORE_FACILITY_LIST 0xb1
+
+void register_privileged_handler (unsigned char ocminor, intercept_handler_t
handler);
+void init_priv ();
+
+#endif
Index: zlive/priv/Makefile
===================================================================
--- /dev/null
+++ zlive/priv/Makefile
@@ -0,0 +1,25 @@
+# z/Live privileged instruction makefile
+# Copyright IBM Corp. 2007
+# Author: Carsten Otte <[EMAIL PROTECTED]>
+# This file is licensed under the terms of the GNU General Public License(GPL)
+
+%.o : %.c ; echo " Compiling " $<; $(CC) $(CFLAGS) -c $<
+
+OBJS := chsc.o insert_storage_key_extended.o priv.o priv_autoinit.o
set_prefix.o set_storage_key_extended.o store_cpu_address.o store_cpu_id.o
store_facility_list.o store_prefix.o store_subchannel.o store_system_info.o
+
+all: $(OBJS)
+clean:
+ rm -f $(OBJS) priv_autoinit.c
+
+priv_autoinit.c: chsc.c insert_storage_key_extended.c set_prefix.c
set_storage_key_extended.c store_cpu_address.c store_cpu_id.c
store_facility_list.c store_prefix.c store_subchannel.c store_system_info.c
+ echo " Creating " $@
+ echo "//Makefile generated" >$@
+ echo "#define __ZLAUTOINIT(f) void f(void);" >>$@
+ cat $^ |grep __ZLAUTOINIT >>$@
+ echo "#undef __ZLAUTOINIT" >>$@
+ echo "#define __ZLAUTOINIT(f) { f(); };" >>$@
+ echo "void autoinit_priv(void) {" >>$@
+ cat $^ |grep __ZLAUTOINIT >>$@
+ echo "}" >>$@
+
+.PHONY: clean all
Index: zlive/priv/chsc.c
===================================================================
--- /dev/null
+++ zlive/priv/chsc.c
@@ -0,0 +1,28 @@
+/*
+ * z/Live channel subsystem call privileged instruction
+ * Copyright IBM Corp. 2007
+ * Author: Carsten Otte <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#include <zlautoinit.h>
+#include <zlpriv.h>
+#include <zlcpu.h>
+#include <zlcpu_lib.h>
+
+
+static int priv_chsc(struct zlcpu *cpu)
+{
+
+ debug("cpu %d: channel subsystem call at %lx", cpu->cpuno,
cl_get_psw(cpu).addr);
+ setcc(cpu, 3);
+ return may_do_cpu_work(cpu);
+}
+
+void priv_chsc_init(void)
+{
+ register_privileged_handler (PRIV_CHSC, priv_chsc);
+}
+
+__ZLAUTOINIT(priv_chsc_init)
Index: zlive/priv/insert_storage_key_extended.c
===================================================================
--- /dev/null
+++ zlive/priv/insert_storage_key_extended.c
@@ -0,0 +1,30 @@
+/*
+ * z/Live insert storage key extended privileged instruction
+ * Copyright IBM Corp. 2007
+ * Author: Carsten Otte <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#include <sys/ioctl.h>
+
+#include <zlglobals.h>
+#include <zlautoinit.h>
+#include <zlpriv.h>
+#include <zlcpu.h>
+
+static int priv_insert_storage_key_extended(struct zlcpu *cpu)
+{
+ cpu->input->iske_parm.sk_reg = (cl_get_ipbh0(cpu) & 0xf0) >> 4;
+ cpu->input->iske_parm.sk_addr = cpu->gpr->regs[cl_get_ipbh0(cpu) & 0xf];
+ cpu->input_flags |= SIE_ISKE;
+ debug ("cpu %d: iske", cpu->cpuno);
+ return may_do_cpu_work(cpu);
+}
+
+void priv_insert_storage_key_extended_init(void)
+{
+ register_privileged_handler (PRIV_INSERT_STORAGE_KEY_EXTENDED,
priv_insert_storage_key_extended);
+}
+
+__ZLAUTOINIT(priv_insert_storage_key_extended_init)
Index: zlive/priv/priv.c
===================================================================
--- /dev/null
+++ zlive/priv/priv.c
@@ -0,0 +1,46 @@
+/*
+ * z/Live privileged instruction interceptions
+ * Copyright IBM Corp. 2007
+ * Author: Carsten Otte <[EMAIL PROTECTED]>
+ * Christian Borntraeger <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#include <string.h>
+
+#include <zlintercept.h>
+#include <zlinstruction.h>
+#include <zlpriv.h>
+#include <zlmessage.h>
+#include <zlautoinit.h>
+#include <zlcpu_lib.h>
+
+
+static intercept_handler_t priv_handlers[256];
+
+int handle_priv(struct zlcpu *cpu)
+{
+ if (priv_handlers[cl_get_ipa1(cpu)]) {
+ debug ("cpu %d: processing privileged instruction b2%02x at
addr %lx",
+ cpu->cpuno, cl_get_ipa1(cpu), cl_get_psw(cpu).addr);
+ return priv_handlers[cl_get_ipa1(cpu)](cpu);
+ }
+ log ("cpu %d: unknown privileged instruction b2%02x at addr %lx,
sending prog 1",
+ cpu->cpuno, cl_get_ipa1(cpu), cl_get_psw(cpu).addr);
+ return enter_pgmcheck (cpu, 0x0001);
+}
+
+void register_privileged_handler(unsigned char code, intercept_handler_t
handler)
+{
+ if (priv_handlers[code])
+ report_it ("priv handler registered twice");
+ priv_handlers[code] = handler;
+}
+
+void init_priv(void)
+{
+ memset (priv_handlers, 0, 256*sizeof(intercept_handler_t));
+ autoinit_priv(); // see makefile magic
+ register_instruction_handler(OPCODE_MAJOR_PRIV, handle_priv);
+}
Index: zlive/priv/set_prefix.c
===================================================================
--- /dev/null
+++ zlive/priv/set_prefix.c
@@ -0,0 +1,43 @@
+/*
+ * z/Live set prefix privileged instruction
+ * Copyright IBM Corp. 2007
+ * Author: Carsten Otte <[EMAIL PROTECTED]>
+ * Christian Borntraeger <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#include <zlautoinit.h>
+#include <zlpriv.h>
+#include <zlcpu.h>
+#include <zlcpu_lib.h>
+#include <sys/ioctl.h>
+
+static int priv_set_prefix(struct zlcpu *cpu)
+{
+ unsigned long target;
+ unsigned int prefix;
+
+ target = decode_base_displacement(cpu);
+ target = apply_prefixing(cpu, target);
+
+ check_addr(cpu, target);
+
+ /* copy bits 1-18 from the specified address to the prefix register*/
+ prefix =
+ ((*(uint32_t *) (target + glo_origin)) & 0x7fffe000u) |
+ (cl_get_prefix(cpu) & 0x80001fffu);
+ cl_set_prefix(cpu, prefix);
+
+ cpu->input_flags |= SIE_FLUSH_TLB;
+
+ debug("cpu %d: prefix page set to %x at addr %lx", cpu->cpuno,
cl_get_prefix(cpu), cl_get_psw(cpu).addr);
+ return may_do_cpu_work(cpu);
+}
+
+void priv_set_prefix_init(void)
+{
+ register_privileged_handler (PRIV_SET_PREFIX, priv_set_prefix);
+}
+
+__ZLAUTOINIT(priv_set_prefix_init)
Index: zlive/priv/set_storage_key_extended.c
===================================================================
--- /dev/null
+++ zlive/priv/set_storage_key_extended.c
@@ -0,0 +1,32 @@
+/*
+ * z/Live set storage key extended privileged instruction
+ * Copyright IBM Corp. 2007
+ * Author: Carsten Otte <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#include <sys/ioctl.h>
+
+#include <zlglobals.h>
+#include <zlautoinit.h>
+#include <zlpriv.h>
+#include <zlcpu.h>
+#include <zlcpu_lib.h>
+
+static int priv_set_storage_key_extended(struct zlcpu *cpu)
+{
+ cpu->input->sske_parm.sk_reg = (cl_get_ipbh0(cpu) & 0xf0) >> 4;
+ cpu->input->sske_parm.sk_addr = cpu->gpr->regs[cl_get_ipbh0(cpu) & 0xf];
+ cpu->input_flags |= SIE_SSKE;
+ debug ("cpu %d: sske at addr %lx",
+ cpu->cpuno, cl_get_psw(cpu).addr);
+ return may_do_cpu_work(cpu);
+}
+
+void priv_set_storage_key_extended_init(void)
+{
+ register_privileged_handler (PRIV_SET_STORAGE_KEY_EXTENDED,
priv_set_storage_key_extended);
+}
+
+__ZLAUTOINIT(priv_set_storage_key_extended_init)
Index: zlive/priv/store_cpu_address.c
===================================================================
--- /dev/null
+++ zlive/priv/store_cpu_address.c
@@ -0,0 +1,34 @@
+/*
+ * z/Live store cpu address privileged instruction
+ * Copyright IBM Corp. 2007
+ * Author: Carsten Otte <[EMAIL PROTECTED]>
+ * Christian Borntraeger <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#include <zlautoinit.h>
+#include <zlpriv.h>
+#include <zlcpu.h>
+
+static int priv_store_cpu_address (struct zlcpu *cpu)
+{
+ uint64_t reg;
+ uint16_t *target;
+
+ reg = decode_base_displacement(cpu);
+ reg = apply_prefixing(cpu, reg);
+
+ check_addr(cpu, reg);
+ target = (uint16_t *) (reg + glo_origin);
+ *target = cpu->cpuno;
+
+ return may_do_cpu_work(cpu);
+}
+
+void priv_store_cpu_address_init(void)
+{
+ register_privileged_handler (PRIV_STORE_CPU_ADDRESS,
priv_store_cpu_address);
+}
+
+__ZLAUTOINIT(priv_store_cpu_address_init)
Index: zlive/priv/store_cpu_id.c
===================================================================
--- /dev/null
+++ zlive/priv/store_cpu_id.c
@@ -0,0 +1,86 @@
+/*
+ * z/Live store cpu id privileged instruction
+ * Copyright IBM Corp. 2007
+ * Author: Carsten Otte <[EMAIL PROTECTED]>
+ * Christian Borntraeger <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <zlautoinit.h>
+#include <zlpriv.h>
+#include <zlcpu.h>
+#include <zlconfig.h>
+
+struct cpu_id {
+ uint8_t version; /* ff=z/VM, fe=z/LiVE */
+ unsigned int cpuid:24; /* 3 byte cpu id */
+ uint16_t model; /* cpu model 2084,2094 etc. */
+ uint16_t flags; /* 8000/0000 global unique id, et al */
+}__attribute__ ((packed));
+
+static struct cpu_id host_cpu_id;
+
+static int priv_store_cpu_id (struct zlcpu *cpu)
+{
+ uint64_t reg;
+ struct cpu_id *local;
+
+ reg = decode_base_displacement(cpu);
+ reg = apply_prefixing(cpu, reg);
+
+ check_addr(cpu, reg);
+ local = (struct cpu_id *) (reg+glo_origin);
+ local->version = 0xfe;
+ local->cpuid = host_cpu_id.cpuid;
+ local->model = host_cpu_id.model;
+ local->flags = 0;
+
+ return may_do_cpu_work(cpu);
+}
+
+/* Fills in skeleton for cpu id, cpu model etc
+ * - checks the config file for a cpuid entry
+ * - scans /proc/cpuinfo for a line which starts with processor */
+static void init_cpuid(void)
+{
+ FILE *cpuinfo;
+ char line[1024];
+ int num, version, cpuid, model;
+ int defined_cpuid;
+
+ defined_cpuid = strtol(get_configentry(glo_activesection,"cpuid"),
+ NULL, 16);
+ if (defined_cpuid > 0xffffff) {
+ defined_cpuid &= 0xffffff;
+ screen("Invalid cpu identification specfied,"
+ "truncated to %X", defined_cpuid & 0xffffff);
+ }
+ cpuinfo = fopen("/proc/cpuinfo", "r");
+ if (!cpuinfo)
+ report_it("Cannot read /proc/cpuinfo");
+ do {
+ fgets(line, 1024, cpuinfo);
+ if (memcmp(line,"processor ",10))
+ continue;
+ sscanf(line,"processor %d: version = %d, identification = %X,
machine = %X",
+ &num, &version, &cpuid, &model);
+ host_cpu_id.version = version;
+ host_cpu_id.cpuid = cpuid;
+ host_cpu_id.model = model;
+ break;
+ } while (strlen(line));
+ if (defined_cpuid)
+ host_cpu_id.cpuid = defined_cpuid;
+}
+
+void priv_store_cpu_id_init(void)
+{
+ init_cpuid();
+ register_privileged_handler(PRIV_STORE_CPU_ID, priv_store_cpu_id);
+}
+
+__ZLAUTOINIT(priv_store_cpu_id_init)
Index: zlive/priv/store_facility_list.c
===================================================================
--- /dev/null
+++ zlive/priv/store_facility_list.c
@@ -0,0 +1,31 @@
+/*
+ * z/Live store facility list privileged instruction
+ * Copyright IBM Corp. 2007
+ * Author: Carsten Otte <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#include <zlautoinit.h>
+#include <zlpriv.h>
+#include <zlcpu.h>
+#include <zlcpu_lib.h>
+
+static int priv_store_facility_list (struct zlcpu *cpu)
+{
+ struct lowcore *lowcore;
+
+ lowcore = (void *)(glo_origin + cl_get_prefix(cpu));
+
+ /* FIXME: this is very raw. simply return everything valid for T-Rex */
+ lowcore->stfl_fac_list = 0xfcf80000;
+ debug("store facility list at addr %lx", cl_get_psw(cpu).addr);
+ return may_do_cpu_work(cpu);
+}
+
+void priv_store_facility_list_init(void)
+{
+ register_privileged_handler (PRIV_STORE_FACILITY_LIST,
priv_store_facility_list);
+}
+
+__ZLAUTOINIT(priv_store_facility_list_init)
Index: zlive/priv/store_prefix.c
===================================================================
--- /dev/null
+++ zlive/priv/store_prefix.c
@@ -0,0 +1,32 @@
+/*
+ * z/Live store prefix privileged instruction
+ * Copyright IBM Corp. 2007
+ * Author: Carsten Otte <[EMAIL PROTECTED]>
+ * Christian Borntraeger <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#include <zlautoinit.h>
+#include <zlpriv.h>
+#include <zlcpu.h>
+#include <zlcpu_lib.h>
+
+
+static int priv_store_prefix (struct zlcpu *cpu)
+{
+ uint64_t reg = decode_base_displacement(cpu);
+ reg = apply_prefixing(cpu, reg);
+ check_addr(cpu, reg);
+
+ *(uint32_t *)(unsigned long) (reg + glo_origin) = cl_get_prefix(cpu);
+ debug("store prefix at addr %lx", cl_get_psw(cpu).addr);
+ return may_do_cpu_work(cpu);
+}
+
+void priv_store_prefix_init(void)
+{
+ register_privileged_handler (PRIV_STORE_PREFIX, priv_store_prefix);
+}
+
+__ZLAUTOINIT(priv_store_prefix_init)
Index: zlive/priv/store_subchannel.c
===================================================================
--- /dev/null
+++ zlive/priv/store_subchannel.c
@@ -0,0 +1,27 @@
+/*
+ * z/Live store subchannel privileged instruction
+ * Copyright IBM Corp. 2007
+ * Author: Carsten Otte <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#include <zlautoinit.h>
+#include <zlpriv.h>
+#include <zlcpu.h>
+#include <zlcpu_lib.h>
+
+static int priv_store_subchannel(struct zlcpu *cpu)
+{
+
+ debug("cpu %d: store subchannel at %lx", cpu->cpuno,
cl_get_psw(cpu).addr);
+ setcc(cpu, 3);
+ return may_do_cpu_work(cpu);
+}
+
+void priv_store_subchannel_init(void)
+{
+ register_privileged_handler (PRIV_STORE_SUBCHANNEL,
priv_store_subchannel);
+}
+
+__ZLAUTOINIT(priv_store_subchannel_init)
Index: zlive/priv/store_system_info.c
===================================================================
--- /dev/null
+++ zlive/priv/store_system_info.c
@@ -0,0 +1,284 @@
+/*
+ * z/Live store system information privileged instruction
+ * Copyright IBM Corp. 2007
+ * Author: Christian Borntraeger <[EMAIL PROTECTED]>
+ *
+ * This file is licensed under the terms of the GNU General Public License(GPL)
+ */
+
+#include <string.h>
+#include <zlautoinit.h>
+#include <zlpriv.h>
+#include <zlcpu.h>
+#include <zlcpu_lib.h>
+#include <system_info.h>
+
+
+/* returns the Function Code, which is bits 32-35 of GPRS 0*/
+static inline unsigned int FC(struct zlcpu *cpu)
+{
+ return (cpu->gpr->regs[0] >> 28) & 15;
+}
+
+
+/* returns Selector1, which is bits 56-63 of GPRS 0*/
+static inline unsigned int Selector1(struct zlcpu *cpu)
+{
+ return (cpu->gpr->regs[0] & 0xff);
+}
+
+/* returns Selector2, which is bits 48-63 of GPRS 0*/
+static inline unsigned int Selector2(struct zlcpu *cpu)
+{
+ return (cpu->gpr->regs[1] & 0xffff);
+}
+
+/* Basic machine configuration*/
+static int stsi_111(struct zlcpu *cpu)
+{
+ uint64_t address;
+ struct sysinfo_1_1_1 *stsi111;
+
+ address = decode_base_displacement(cpu);
+ address = apply_prefixing(cpu, address);
+ check_addr(cpu, address);
+ stsi111 = (struct sysinfo_1_1_1 *) address;
+ /*FIXME implement this using real values*/
+ memcpy(stsi111->manufacturer, "\xe3\xd6\xc4\xd6\x0", 5);
+ memcpy(stsi111->type, "\xe3\xd6\xc4\xd6\x0", 5);
+ memcpy(stsi111->model, "\xe3\xd6\xc4\xd6\x0", 5);
+ memcpy(stsi111->sequence, "\xe3\xd6\xc4\xd6\x0", 5);
+ memcpy(stsi111->plant, "\xe3\xd6\xc4\xd6\x0", 5);
+ setcc(cpu, 0);
+ cpu->gpr->regs[0] = 0;
+ return may_do_cpu_work(cpu);
+}
+
+
+/* Basic machine CPU*/
+static int stsi_121(struct zlcpu *cpu)
+{
+ /*FIXME: implement this */
+ setcc(cpu, 3);
+ return may_do_cpu_work(cpu);
+
+}
+
+/* Basic machine CPUs*/
+static int stsi_122(struct zlcpu *cpu)
+{
+ uint64_t address;
+ struct sysinfo_1_2_2 *stsi122;
+
+ address = decode_base_displacement(cpu);
+ address = apply_prefixing(cpu, address);
+ check_addr(cpu, address);
+ stsi122 = (struct sysinfo_1_2_2 *) address;
+ /*FIXME: implement this using real values*/
+ stsi122->capability = 0;
+ stsi122->cpus_total = 8;
+ stsi122->cpus_configured = 8;
+ stsi122->cpus_standby = 0;
+ stsi122->cpus_reserved = 0;
+ stsi122->cpus_total = 32;
+ setcc(cpu, 0);
+ return may_do_cpu_work(cpu);
+}
+
+/* Logical-partition CPU*/
+static int stsi_221(struct zlcpu *cpu)
+{
+ /*FIXME: implement this */
+ setcc(cpu, 3);
+ return may_do_cpu_work(cpu);
+}
+
+
+/* Logical-partition CPUs*/
+static int stsi_222(struct zlcpu *cpu)
+{
+ uint64_t address;
+ struct sysinfo_2_2_2 *stsi222;
+
+ address = decode_base_displacement(cpu);
+ address = apply_prefixing(cpu, address);
+ check_addr(cpu, address);
+ stsi222 = (struct sysinfo_2_2_2 *) address;
+ /*FIXME: implement this using real values*/
+ stsi222->lpar_number = 0;
+ stsi222->characteristics = 0;
+ stsi222->cpus_total = 8;
+ stsi222->cpus_configured = 8;
+ stsi222->cpus_standby = 0;
+ stsi222->cpus_reserved = 0;
+ memcpy(stsi222->name, "\xe3\xd6\xc4\xd6\x0", 5);
+ stsi222->caf = 100;
+ stsi222->cpus_dedicated = 0;
+ stsi222->cpus_shared = 8;
+
+
+ setcc(cpu, 0);
+ return may_do_cpu_work(cpu);
+}
+
+/* Virtual machine CPUs*/
+static int stsi_322(struct zlcpu *cpu)
+{
+ uint64_t address;
+ struct sysinfo_3_2_2 *stsi322;
+
+ address = decode_base_displacement(cpu);
+ address = apply_prefixing(cpu, address);
+ check_addr(cpu, address);
+ stsi322 = (struct sysinfo_3_2_2 *) address;
+ /*FIXME: implement this using real values*/
+ stsi322->count =1;
+ memcpy(stsi322->vm[0].cpi, "\xa9\x61\xd3\x89\xe5\xc5\x0", 7);
+ memcpy(stsi322->vm[0].name, "\xe3\xd6\xc4\xd6\x0", 5); //FIXME
+ stsi322->vm[0].cpus_total = glo_numcpu;
+ stsi322->vm[0].cpus_configured=glo_numcpu;
+ stsi322->vm[0].cpus_standby = 0;
+ stsi322->vm[0].cpus_reserved = 0;
+/* unsigned int caf;
+ char reserved_1[24];
+
+ */
+
+ setcc(cpu, 0);
+ return may_do_cpu_work(cpu);
+}
+
+
+
+static int stsi_11(struct zlcpu *cpu)
+{
+ switch(Selector2(cpu)) {
+ case 1:
+ return stsi_111(cpu);
+ default:
+ setcc(cpu, 3);
+ return may_do_cpu_work(cpu);
+ }
+}
+
+static int stsi_12(struct zlcpu *cpu)
+{
+ switch(Selector2(cpu)) {
+ case 1:
+ return stsi_121(cpu);
+ case 2:
+ return stsi_122(cpu);
+ default:
+ setcc(cpu, 3);
+ return may_do_cpu_work(cpu);
+ }
+}
+
+static int stsi_22(struct zlcpu *cpu)
+{
+ switch(Selector2(cpu)) {
+ case 1:
+ return stsi_221(cpu);
+ case 2:
+ return stsi_222(cpu);
+ default:
+ setcc(cpu, 3);
+ return may_do_cpu_work(cpu);
+ }
+}
+
+static int stsi_32(struct zlcpu *cpu)
+{
+ switch(Selector2(cpu)) {
+ case 2:
+ return stsi_322(cpu);
+ default:
+ setcc(cpu, 3);
+ return may_do_cpu_work(cpu);
+ }
+}
+
+/* function code 0 of the stsi instruction requests the current
+ * configuration level number. We state to be at level 3 */
+static int stsi_0(struct zlcpu *cpu)
+{
+ /*FIXME if zlive is running under VM we are level 4*/
+ cpu->gpr->regs[0] = 0x3 << 28;
+ setcc(cpu, 0);
+ return may_do_cpu_work(cpu);
+}
+
+
+/* function code 1 of the stsi instruction: basic machine info */
+static int stsi_1(struct zlcpu *cpu)
+{
+ switch(Selector1(cpu)) {
+ case 1:
+ return stsi_11(cpu);
+ case 2:
+ return stsi_12(cpu);
+ default:
+ setcc(cpu, 3);
+ return may_do_cpu_work(cpu);
+ }
+}
+
+/* function code 2 of the stsi instruction: LPAR */
+static int stsi_2(struct zlcpu *cpu)
+{
+ switch(Selector1(cpu)) {
+ case 2:
+ return stsi_22(cpu);
+ default:
+ setcc(cpu, 3);
+ return may_do_cpu_work(cpu);
+ }
+}
+
+/* function code 3 of the stsi instruction: Virtual machine */
+static int stsi_3(struct zlcpu *cpu)
+{
+ switch(Selector1(cpu)) {
+ case 2:
+ return stsi_32(cpu);
+ default:
+ setcc(cpu, 3);
+ return may_do_cpu_work(cpu);
+ }
+}
+
+static int invalid_regs(struct zlcpu *cpu)
+{
+ /* if the function is valid, bits 36-55 of reg0 and bits 32-47 of
+ * reg1 must be 0, otherwise send a specification exception*/
+ if (cpu->gpr->regs[0] & 0x000000000fffff00L)
+ return enter_pgmcheck(cpu, 0x0006);
+ if (cpu->gpr->regs[1] & 0x00000000ffff0000L)
+ return enter_pgmcheck(cpu, 0x0006);
+ return 0;
+}
+
+static int priv_store_system_info(struct zlcpu *cpu)
+{
+ /* decode instruction according to function code*/
+ switch(FC(cpu)) {
+ case 0:
+ return invalid_regs(cpu) | stsi_0(cpu);
+ case 1:
+ return invalid_regs(cpu) | stsi_1(cpu);
+ case 2:
+ return invalid_regs(cpu) | stsi_2(cpu);
+ case 3:
+ return invalid_regs(cpu) | stsi_3(cpu);
+ default:
+ setcc(cpu, 3);
+ return may_do_cpu_work(cpu);
+ }
+}
+
+void priv_store_system_info_init(void)
+{
+ register_privileged_handler (PRIV_STORE_SYSTEM_INFORMATION,
priv_store_system_info);
+}
+
+__ZLAUTOINIT(priv_store_system_info_init)
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
kvm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel