Apples hardware dongle sits withing the fan control. To get Mac OS X up
and running, this control device needs to be emulated and given the
correct dongle key. This key has to be given via the command line.
Index: qemu-snapshot-2008-01-08_05/Makefile.target
===
--- qemu-snapshot-2008-01-08_05.orig/Makefile.target
+++ qemu-snapshot-2008-01-08_05/Makefile.target
@@ -441,7 +441,7 @@ ifeq ($(TARGET_BASE_ARCH), i386)
VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o
VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
VL_OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
-VL_OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o smbios.o hpet.o lpc.o
+VL_OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o smbios.o hpet.o lpc.o applesmc.o
CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
endif
ifeq ($(TARGET_BASE_ARCH), ppc)
Index: qemu-snapshot-2008-01-08_05/hw/applesmc.c
===
--- /dev/null
+++ qemu-snapshot-2008-01-08_05/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