diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index 7d29ec0..af3f53d 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -1,6 +1,6 @@
 obj-$(CONFIG_KVM) += kvm/
 obj-y += multiboot.o
-obj-y += pc.o pc_piix.o pc_q35.o pc_lite_acpi.o
+obj-y += pc.o pc_piix.o pc_q35.o pc_lite_acpi.o pc_lite.o
 obj-y += pc_sysfw.o
 obj-y += intel_iommu.o
 obj-$(CONFIG_XEN) += ../xenpv/ xen/
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 64ce65c..0533951 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -962,8 +962,43 @@ static long get_file_size(FILE *f)
     return size;
 }
 
-static void load_linux(PCMachineState *pcms,
-                       FWCfgState *fw_cfg)
+static void load_linux_efi(PCMachineState *pcms)
+{
+    unsigned char class;
+    MachineState *machine = MACHINE(pcms);
+    FILE *file = fopen(machine->kernel_filename, "rb");
+
+    if (!file) {
+        goto err;
+    }
+
+    if (fseek(file, EI_CLASS, 0) || fread(&class, 1, 1, file) != 1) {
+        fclose(file);
+        goto err;
+    }
+    fclose(file);
+
+    if (load_elf(machine->kernel_filename, NULL, NULL, &boot_info.entry,
+                   NULL, NULL, 0, EM_X86_64, 0, 0) < 0) {
+        goto err;
+    }
+
+    if (class == ELFCLASS64) {
+        boot_info.long_mode = true;
+    } else if (class != ELFCLASS32) {
+        goto err;
+    }
+
+    boot_info.protected_mode = true;
+    return;
+
+err:
+    fprintf(stderr, "qemu: could not load kernel '%s'\n",
+                    machine->kernel_filename);
+    exit(1);
+}
+
+static void load_linux_bzimage(PCMachineState *pcms, FWCfgState *fw_cfg)
 {
     uint16_t protocol;
     int setup_size, kernel_size, initrd_size = 0, cmdline_size;
@@ -1404,7 +1439,7 @@ void xen_load_linux(PCMachineState *pcms)
     fw_cfg = fw_cfg_init_io(FW_CFG_IO_BASE);
     rom_set_fw(fw_cfg);
 
-    load_linux(pcms, fw_cfg);
+    load_linux_bzimage(pcms, fw_cfg);
     for (i = 0; i < nb_option_roms; i++) {
         assert(!strcmp(option_rom[i].name, "linuxboot.bin") ||
                !strcmp(option_rom[i].name, "multiboot.bin"));
@@ -1421,7 +1456,7 @@ void pc_memory_init(PCMachineState *pcms,
     int linux_boot, i;
     MemoryRegion *ram, *option_rom_mr;
     MemoryRegion *ram_below_4g, *ram_above_4g;
-    FWCfgState *fw_cfg;
+    FWCfgState *fw_cfg = NULL;
     MachineState *machine = MACHINE(pcms);
     PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
 
@@ -1503,36 +1538,42 @@ void pc_memory_init(PCMachineState *pcms,
                                     &pcms->hotplug_memory.mr);
     }
 
-    /* Initialize PC system firmware */
-    pc_system_firmware_init(rom_memory, !pcmc->pci_enabled);
+    if (pcmc->type != PC_MACHINE_TYPE_LITE) {
+        /* Initialize PC system firmware */
+        pc_system_firmware_init(rom_memory, !pcmc->pci_enabled);
 
-    option_rom_mr = g_malloc(sizeof(*option_rom_mr));
-    memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
-                           &error_fatal);
-    vmstate_register_ram_global(option_rom_mr);
-    memory_region_add_subregion_overlap(rom_memory,
-                                        PC_ROM_MIN_VGA,
-                                        option_rom_mr,
-                                        1);
+        option_rom_mr = g_malloc(sizeof(*option_rom_mr));
+        memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
+                               &error_fatal);
+        vmstate_register_ram_global(option_rom_mr);
+        memory_region_add_subregion_overlap(rom_memory,
+                                            PC_ROM_MIN_VGA,
+                                            option_rom_mr,
+                                            1);
 
-    fw_cfg = bochs_bios_init(&address_space_memory, pcms);
+        fw_cfg = bochs_bios_init(&address_space_memory, pcms);
 
-    rom_set_fw(fw_cfg);
+        rom_set_fw(fw_cfg);
 
-    if (pcmc->has_reserved_memory && pcms->hotplug_memory.base) {
-        uint64_t *val = g_malloc(sizeof(*val));
-        PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
-        uint64_t res_mem_end = pcms->hotplug_memory.base;
+        if (pcmc->has_reserved_memory && pcms->hotplug_memory.base) {
+            uint64_t *val = g_malloc(sizeof(*val));
+            PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
+            uint64_t res_mem_end = pcms->hotplug_memory.base;
 
-        if (!pcmc->broken_reserved_end) {
-            res_mem_end += memory_region_size(&pcms->hotplug_memory.mr);
+            if (!pcmc->broken_reserved_end) {
+                res_mem_end += memory_region_size(&pcms->hotplug_memory.mr);
+            }
+            *val = cpu_to_le64(ROUND_UP(res_mem_end, 0x1ULL << 30));
+            fw_cfg_add_file(fw_cfg, "etc/reserved-memory-end", val, sizeof(*val));
         }
-        *val = cpu_to_le64(ROUND_UP(res_mem_end, 0x1ULL << 30));
-        fw_cfg_add_file(fw_cfg, "etc/reserved-memory-end", val, sizeof(*val));
     }
 
     if (linux_boot) {
-        load_linux(pcms, fw_cfg);
+        if (pcmc->type == PC_MACHINE_TYPE_LITE) {
+            load_linux_efi(pcms);
+        } else {
+            load_linux_bzimage(pcms, fw_cfg);
+        }
     }
 
     for (i = 0; i < nb_option_roms; i++) {
diff --git a/hw/i386/pc_lite.c b/hw/i386/pc_lite.c
new file mode 100644
index 0000000..3756848
--- /dev/null
+++ b/hw/i386/pc_lite.c
@@ -0,0 +1,205 @@
+/*
+ * Light weight PC chipset
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * Copyright (c) 2009, 2010
+ *               Isaku Yamahata <yamahata at valinux co jp>
+ *               VA Linux Systems Japan K.K.
+ * Copyright (C) 2012 Jason Baron <jbaron@redhat.com>
+ * Copyright (C) 2016 Chao Peng <chao.p.peng@linux.intel.com>
+ *
+ * This is based on pc_q35.c, but heavily modified.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/loader.h"
+#include "sysemu/arch_init.h"
+#include "hw/boards.h"
+#include "hw/xen/xen.h"
+#include "sysemu/kvm.h"
+#include "hw/kvm/clock.h"
+#include "hw/pci-host/q35.h"
+#include "exec/address-spaces.h"
+#include "hw/i386/ich9.h"
+#include "hw/smbios/smbios.h"
+#include "hw/ide/pci.h"
+#include "qemu/error-report.h"
+#include "migration/migration.h"
+
+static void pc_lite_gsi_handler(void *opaque, int n, int level)
+{
+    GSIState *s = opaque;
+
+    qemu_set_irq(s->ioapic_irq[n], level);
+}
+
+static void pc_lite_init(MachineState *machine)
+{
+    PCMachineState *pcms = PC_MACHINE(machine);
+    PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
+    PCIBus *host_bus;
+    MemoryRegion *pci_memory;
+    MemoryRegion *rom_memory;
+    MemoryRegion *ram_memory;
+    GSIState *gsi_state;
+    qemu_irq *gsi;
+    ram_addr_t lowmem;
+    DeviceState *pm;
+    MachineClass *mc = MACHINE_GET_CLASS(machine);
+
+    /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory
+     * and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping
+     * also known as MMCFG).
+     * If it doesn't, we need to split it in chunks below and above 4G.
+     * In any case, try to make sure that guest addresses aligned at
+     * 1G boundaries get mapped to host addresses aligned at 1G boundaries.
+     */
+    if (machine->ram_size >= 0xb0000000) {
+        lowmem = 0x80000000;
+    } else {
+        lowmem = 0xb0000000;
+    }
+
+    /* Handle the machine opt max-ram-below-4g.  It is basically doing
+     * min(qemu limit, user limit).
+     */
+    if (lowmem > pcms->max_ram_below_4g) {
+        lowmem = pcms->max_ram_below_4g;
+        if (machine->ram_size - lowmem > lowmem &&
+            lowmem & ((1ULL << 30) - 1)) {
+            error_report("Warning: Large machine and max_ram_below_4g(%"PRIu64
+                         ") not a multiple of 1G; possible bad performance.",
+                         pcms->max_ram_below_4g);
+        }
+    }
+
+    if (machine->ram_size >= lowmem) {
+        pcms->above_4g_mem_size = machine->ram_size - lowmem;
+        pcms->below_4g_mem_size = lowmem;
+    } else {
+        pcms->above_4g_mem_size = 0;
+        pcms->below_4g_mem_size = machine->ram_size;
+    }
+
+    if (xen_enabled()) {
+        xen_hvm_init(pcms, &ram_memory);
+    }
+
+    pc_cpus_init(pcms);
+
+    kvmclock_create();
+
+    /* pci enabled */
+    if (pcmc->pci_enabled) {
+        pci_memory = g_new(MemoryRegion, 1);
+        memory_region_init(pci_memory, NULL, "pci", UINT64_MAX);
+        rom_memory = pci_memory;
+    } else {
+        pci_memory = NULL;
+        rom_memory = get_system_memory();
+    }
+
+    pc_guest_info_init(pcms);
+
+    if (pcmc->smbios_defaults) {
+        /* These values are guest ABI, do not change */
+        smbios_set_defaults("QEMU", "Light weight PC)",
+                            mc->name, pcmc->smbios_legacy_mode,
+                            pcmc->smbios_uuid_encoded,
+                            SMBIOS_ENTRY_POINT_21);
+    }
+
+    /* allocate ram and load rom/bios */
+    if (!xen_enabled()) {
+        pc_memory_init(pcms, get_system_memory(),
+                       rom_memory, &ram_memory);
+    }
+
+    /* irq lines */
+    gsi_state = g_malloc0(sizeof(*gsi_state));
+    if (kvm_irqchip_in_kernel()) {
+        kvm_pc_setup_irq_routing(pcmc->pci_enabled);
+    }
+    gsi = qemu_allocate_irqs(pc_lite_gsi_handler, gsi_state, GSI_NUM_PINS);
+
+    if (pcmc->pci_enabled) {
+        host_bus = pci_lite_init(get_system_memory(), get_system_io(),
+                                     pci_memory);
+        pcms->bus = host_bus;
+
+        if (acpi_enabled) {
+            pm = pm_lite_init(host_bus, -1, gsi[9]);
+
+            object_property_add_link(OBJECT(machine),
+                                     PC_MACHINE_ACPI_DEVICE_PROP,
+                                     TYPE_HOTPLUG_HANDLER,
+                                     (Object **)&pcms->acpi_dev,
+                                     object_property_allow_set_link,
+                                     OBJ_PROP_LINK_UNREF_ON_RELEASE,
+                                     &error_abort);
+            object_property_set_link(OBJECT(machine), OBJECT(pm),
+                                     PC_MACHINE_ACPI_DEVICE_PROP, &error_abort);
+        }
+    }
+
+    if (pcmc->pci_enabled) {
+        ioapic_init_gsi(gsi_state, "pcilite");
+    }
+
+    pc_register_ferr_irq(gsi[13]);
+
+    if (pcms->acpi_nvdimm_state.is_enabled) {
+        nvdimm_init_acpi_state(&pcms->acpi_nvdimm_state, get_system_io(),
+                               pcms->fw_cfg, OBJECT(pcms));
+    }
+}
+
+#define DEFINE_LITE_MACHINE(suffix, name, compatfn, optionfn) \
+    static void pc_init_##suffix(MachineState *machine) \
+    { \
+        void (*compat)(MachineState *m) = (compatfn); \
+        if (compat) { \
+            compat(machine); \
+        } \
+        pc_lite_init(machine); \
+    } \
+    DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn)
+
+
+static void pc_lite_machine_options(MachineClass *m)
+{
+    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+    m->family = "pc_lite";
+    m->desc = "Light weight PC";
+    m->hot_add_cpu = pc_hot_add_cpu;
+    m->units_per_default_bus = 1;
+    m->no_floppy = 1;
+    pcmc->type = PC_MACHINE_TYPE_LITE;
+}
+
+static void pc_lite_2_7_machine_options(MachineClass *m)
+{
+    pc_lite_machine_options(m);
+    m->alias = "pc-lite";
+}
+
+DEFINE_LITE_MACHINE(v2_7, "pc-lite-2.7", NULL,
+                    pc_lite_2_7_machine_options);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 53bc968..9d25abc 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -425,11 +425,13 @@ static void pc_xen_hvm_init(MachineState *machine)
 
 static void pc_i440fx_machine_options(MachineClass *m)
 {
+    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
     m->family = "pc_piix";
     m->desc = "Standard PC (i440FX + PIIX, 1996)";
     m->hot_add_cpu = pc_hot_add_cpu;
     m->default_machine_opts = "firmware=bios-256k.bin";
     m->default_display = "std";
+    pcmc->type = PC_MACHINE_TYPE_PIIX;
 }
 
 static void pc_i440fx_2_7_machine_options(MachineClass *m)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index e4b541f..af2c201 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -274,6 +274,7 @@ static void pc_q35_init(MachineState *machine)
 
 static void pc_q35_machine_options(MachineClass *m)
 {
+    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
     m->family = "pc_q35";
     m->desc = "Standard PC (Q35 + ICH9, 2009)";
     m->hot_add_cpu = pc_hot_add_cpu;
@@ -281,6 +282,7 @@ static void pc_q35_machine_options(MachineClass *m)
     m->default_machine_opts = "firmware=bios-256k.bin";
     m->default_display = "std";
     m->no_floppy = 1;
+    pcmc->type = PC_MACHINE_TYPE_Q35;
 }
 
 static void pc_q35_2_7_machine_options(MachineClass *m)
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index ad7533b..ef0e3df 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -33,6 +33,12 @@
 #define kvm_ioapic_in_kernel()   0
 #endif
 
+typedef enum {
+    PC_MACHINE_TYPE_PIIX    = 0,
+    PC_MACHINE_TYPE_Q35     = 1,
+    PC_MACHINE_TYPE_LITE    = 2,
+} PCMachineType;
+
 /**
  * PCMachineState:
  * @acpi_dev: link to ACPI PM device that performs ACPI hotplug handling
@@ -136,6 +142,8 @@ struct PCMachineClass {
 
     /* TSC rate migration: */
     bool save_tsc_khz;
+
+    PCMachineType type;
 };
 
 #define TYPE_PC_MACHINE "generic-pc-machine"
