244 lines
8.0 KiB
Diff
244 lines
8.0 KiB
Diff
|
#qemu-only -> submit upstream qemu
|
||
|
Index: kvm-75/qemu/Makefile.target
|
||
|
===================================================================
|
||
|
--- kvm-75.orig/qemu/Makefile.target
|
||
|
+++ kvm-75/qemu/Makefile.target
|
||
|
@@ -610,7 +610,7 @@ ifeq ($(TARGET_BASE_ARCH), i386)
|
||
|
OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o
|
||
|
OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
|
||
|
OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
|
||
|
-OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o hpet.o lpc.o
|
||
|
+OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o hpet.o lpc.o applesmc.o
|
||
|
ifeq ($(USE_KVM_PIT), 1)
|
||
|
OBJS+= i8254-kvm.o
|
||
|
endif
|
||
|
Index: kvm-75/qemu/hw/applesmc.c
|
||
|
===================================================================
|
||
|
--- /dev/null
|
||
|
+++ kvm-75/qemu/hw/applesmc.c
|
||
|
@@ -0,0 +1,171 @@
|
||
|
+/*
|
||
|
+ * Apple SMC controller
|
||
|
+ *
|
||
|
+ * Copyright (c) 2007 Alexander Graf
|
||
|
+ *
|
||
|
+ * This library is free software; you can redistribute it and/or
|
||
|
+ * modify it under the terms of the GNU Lesser General Public
|
||
|
+ * License as published by the Free Software Foundation; either
|
||
|
+ * version 2 of the License, or (at your option) any later version.
|
||
|
+ *
|
||
|
+ * This library is distributed in the hope that it will be useful,
|
||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
+ * Lesser General Public License for more details.
|
||
|
+ *
|
||
|
+ * You should have received a copy of the GNU Lesser General Public
|
||
|
+ * License along with this library; if not, write to the Free Software
|
||
|
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
+ *
|
||
|
+ * *****************************************************************
|
||
|
+ *
|
||
|
+ * In all Intel-based Apple hardware there is an SMC chip to control the
|
||
|
+ * backlight, fans and several other generic device parameters. It also
|
||
|
+ * contains the magic keys used to dongle Mac OS X to the device.
|
||
|
+ *
|
||
|
+ * This driver was mostly created by looking at the Linux AppleSMC driver
|
||
|
+ * implementation and does not support IRQ.
|
||
|
+ *
|
||
|
+ */
|
||
|
+
|
||
|
+#include "hw.h"
|
||
|
+#include "pci.h"
|
||
|
+#include "console.h"
|
||
|
+#include "qemu-timer.h"
|
||
|
+
|
||
|
+/* data port used by Apple SMC */
|
||
|
+#define APPLESMC_DATA_PORT 0x300
|
||
|
+/* command/status port used by Apple SMC */
|
||
|
+#define APPLESMC_CMD_PORT 0x304
|
||
|
+#define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */
|
||
|
+#define APPLESMC_MAX_DATA_LENGTH 32
|
||
|
+
|
||
|
+#define APPLESMC_READ_CMD 0x10
|
||
|
+#define APPLESMC_WRITE_CMD 0x11
|
||
|
+#define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12
|
||
|
+#define APPLESMC_GET_KEY_TYPE_CMD 0x13
|
||
|
+
|
||
|
+static char osk[64] = "This is a dummy key. Enter the real key using the -osk parameter";
|
||
|
+
|
||
|
+struct AppleSMCData {
|
||
|
+ uint8_t len;
|
||
|
+ char *key;
|
||
|
+ char *data;
|
||
|
+};
|
||
|
+
|
||
|
+static struct AppleSMCData data[] = {
|
||
|
+ { .key = "REV ", .len=6, .data="\0x01\0x13\0x0f\0x00\0x00\0x03" },
|
||
|
+ { .key = "OSK0", .len=32, .data=osk },
|
||
|
+ { .key = "OSK1", .len=32, .data=osk+32 },
|
||
|
+ { .key = "NATJ", .len=1, .data="\0" },
|
||
|
+ { .key = "MSSP", .len=1, .data="\0" },
|
||
|
+ { .key = "MSSD", .len=1, .data="\0x3" },
|
||
|
+ { .len=0 }
|
||
|
+};
|
||
|
+
|
||
|
+struct AppleSMCStatus {
|
||
|
+ uint8_t cmd;
|
||
|
+ uint8_t status;
|
||
|
+ uint8_t key[4];
|
||
|
+ uint8_t read_pos;
|
||
|
+ uint8_t data_len;
|
||
|
+ uint8_t data_pos;
|
||
|
+ uint8_t data[255];
|
||
|
+ uint8_t charactic[4];
|
||
|
+};
|
||
|
+
|
||
|
+static void applesmc_io_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
|
||
|
+{
|
||
|
+ struct AppleSMCStatus *s = (struct AppleSMCStatus *)opaque;
|
||
|
+ printf("APPLESMC: CMD Write B: %#x = %#x\n", addr, val);
|
||
|
+ switch(val) {
|
||
|
+ case APPLESMC_READ_CMD:
|
||
|
+ s->status = 0x0c;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ s->cmd = val;
|
||
|
+ s->read_pos = 0;
|
||
|
+ s->data_pos = 0;
|
||
|
+}
|
||
|
+
|
||
|
+static void applesmc_fill_data(struct AppleSMCStatus *s)
|
||
|
+{
|
||
|
+ struct AppleSMCData *d;
|
||
|
+ for(d=data; d->len; d++) {
|
||
|
+ uint32_t key_data = *((uint32_t*)d->key);
|
||
|
+ uint32_t key_current = *((uint32_t*)s->key);
|
||
|
+ if(key_data == key_current) {
|
||
|
+ printf("APPLESMC: Key matched (%s Len=%d Data=%s)\n", d->key, d->len, d->data);
|
||
|
+ memcpy(s->data, d->data, d->len);
|
||
|
+ return;
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static void applesmc_io_data_writeb(void *opaque, uint32_t addr, uint32_t val)
|
||
|
+{
|
||
|
+ struct AppleSMCStatus *s = (struct AppleSMCStatus *)opaque;
|
||
|
+ printf("APPLESMC: DATA Write B: %#x = %#x\n", addr, val);
|
||
|
+ switch(s->cmd) {
|
||
|
+ case APPLESMC_READ_CMD:
|
||
|
+ if(s->read_pos < 4) {
|
||
|
+ s->key[s->read_pos] = val;
|
||
|
+ s->status = 0x04;
|
||
|
+ } else if(s->read_pos == 4) {
|
||
|
+ s->data_len = val;
|
||
|
+ s->status = 0x05;
|
||
|
+ s->data_pos = 0;
|
||
|
+ printf("APPLESMC: Key = %c%c%c%c Len = %d\n", s->key[0], s->key[1], s->key[2], s->key[3], val);
|
||
|
+ applesmc_fill_data(s);
|
||
|
+ }
|
||
|
+ s->read_pos++;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static uint32_t applesmc_io_data_readb(void *opaque, uint32_t addr1)
|
||
|
+{
|
||
|
+ struct AppleSMCStatus *s = (struct AppleSMCStatus *)opaque;
|
||
|
+ uint8_t retval = 0;
|
||
|
+ switch(s->cmd) {
|
||
|
+ case APPLESMC_READ_CMD:
|
||
|
+ if(s->data_pos < s->data_len) {
|
||
|
+ retval = s->data[s->data_pos];
|
||
|
+ printf("APPLESMC: READ_DATA[%d] = %#hhx\n", s->data_pos, retval);
|
||
|
+ s->data_pos++;
|
||
|
+ if(s->data_pos == s->data_len) {
|
||
|
+ s->status = 0x00;
|
||
|
+ printf("APPLESMC: EOF\n");
|
||
|
+ } else
|
||
|
+ s->status = 0x05;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ printf("APPLESMC: DATA Read b: %#x = %#x\n", addr1, retval);
|
||
|
+ return retval;
|
||
|
+}
|
||
|
+
|
||
|
+static uint32_t applesmc_io_cmd_readb(void *opaque, uint32_t addr1)
|
||
|
+{
|
||
|
+ printf("APPLESMC: CMD Read B: %#x\n", addr1);
|
||
|
+ return ((struct AppleSMCStatus*)opaque)->status;
|
||
|
+}
|
||
|
+
|
||
|
+void applesmc_setkey(char *key) {
|
||
|
+ if(strlen(key) == 64) {
|
||
|
+ memcpy(osk, key, 64);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+void applesmc_init() {
|
||
|
+ struct ApleSMCStatus *s;
|
||
|
+ s = qemu_mallocz(sizeof(struct AppleSMCStatus));
|
||
|
+
|
||
|
+ if(osk[0] == 'T') {
|
||
|
+ printf("WARNING: Using AppleSMC with invalid key\n");
|
||
|
+ }
|
||
|
+ register_ioport_read(APPLESMC_DATA_PORT, 4, 1, applesmc_io_data_readb, s);
|
||
|
+ register_ioport_read(APPLESMC_CMD_PORT, 4, 1, applesmc_io_cmd_readb, s);
|
||
|
+ register_ioport_write(APPLESMC_DATA_PORT, 4, 1, applesmc_io_data_writeb, s);
|
||
|
+ register_ioport_write(APPLESMC_CMD_PORT, 4, 1, applesmc_io_cmd_writeb, s);
|
||
|
+}
|
||
|
+
|
||
|
Index: kvm-75/qemu/hw/pc.h
|
||
|
===================================================================
|
||
|
--- kvm-75.orig/qemu/hw/pc.h
|
||
|
+++ kvm-75/qemu/hw/pc.h
|
||
|
@@ -150,6 +150,10 @@ void pci_piix4_ide_init(PCIBus *bus, Blo
|
||
|
|
||
|
void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd);
|
||
|
|
||
|
+/* applesmc.c */
|
||
|
+void applesmc_init(void);
|
||
|
+void applesmc_setkey(char *key);
|
||
|
+
|
||
|
/* lpc.c */
|
||
|
void lpc_init(PCIBus *bus, int devfn, qemu_irq *pic);
|
||
|
|
||
|
Index: kvm-75/qemu/vl.c
|
||
|
===================================================================
|
||
|
--- kvm-75.orig/qemu/vl.c
|
||
|
+++ kvm-75/qemu/vl.c
|
||
|
@@ -8381,6 +8381,7 @@ static void help(int exitcode)
|
||
|
#endif
|
||
|
#ifdef TARGET_I386
|
||
|
"-no-fd-bootchk disable boot signature checking for floppy disks\n"
|
||
|
+ "-osk key set AppleSMC key\n"
|
||
|
#endif
|
||
|
"-m megs set virtual RAM size to megs MB [default=%d]\n"
|
||
|
"-smp n set the number of CPUs to 'n' [default=1]\n"
|
||
|
@@ -8547,6 +8548,7 @@ enum {
|
||
|
QEMU_OPTION_snapshot,
|
||
|
#ifdef TARGET_I386
|
||
|
QEMU_OPTION_no_fd_bootchk,
|
||
|
+ QEMU_OPTION_osk,
|
||
|
#endif
|
||
|
QEMU_OPTION_m,
|
||
|
QEMU_OPTION_nographic,
|
||
|
@@ -8648,6 +8650,7 @@ const QEMUOption qemu_options[] = {
|
||
|
{ "snapshot", 0, QEMU_OPTION_snapshot },
|
||
|
#ifdef TARGET_I386
|
||
|
{ "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
|
||
|
+ { "osk", HAS_ARG, QEMU_OPTION_osk },
|
||
|
#endif
|
||
|
{ "m", HAS_ARG, QEMU_OPTION_m },
|
||
|
{ "nographic", 0, QEMU_OPTION_nographic },
|
||
|
@@ -9360,6 +9363,9 @@ int main(int argc, char **argv)
|
||
|
case QEMU_OPTION_no_fd_bootchk:
|
||
|
fd_bootchk = 0;
|
||
|
break;
|
||
|
+ case QEMU_OPTION_osk:
|
||
|
+ applesmc_setkey(optarg);
|
||
|
+ break;
|
||
|
#endif
|
||
|
case QEMU_OPTION_net:
|
||
|
if (nb_net_clients >= MAX_NET_CLIENTS) {
|