aboutsummaryrefslogtreecommitdiffstats
path: root/3rdparty/python-console/test_cli.cpp
blob: 76d0f251a401e044417e6f03053071329f62ff85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <string>
#include "ParseHelper.h"
#include "ParseListener.h"
#include "Interpreter.h"

const std::string STD_PROMPT = ">>> ";
const std::string MULTILINE_PROMPT = "... ";

struct InterpreterRelay : public ParseListener
{
    Interpreter* m_interpreter;

    InterpreterRelay( ):
        m_interpreter( new Interpreter )
    { }

    virtual void parseEvent( const ParseMessage& msg )
    {
        if ( msg.errorCode )
        {
            std::cout << "(" << msg.errorCode << ") " << msg.message << "\n";
            return;
        }
        else
        {
            int err;
            std::string res = m_interpreter->interpret( msg.message, &err );
            std::cout << "(" << msg.errorCode << ") " << res << "\n";
        }
    }
};

int main( int argc, char *argv[] )
{
    Interpreter::Initialize( );
    const std::string* prompt = &STD_PROMPT;
    ParseHelper helper;
    ParseListener* listener = new InterpreterRelay;
    helper.subscribe( listener );

    std::string str;
    std::cout << *prompt;
    std::getline( std::cin, str );
    while ( str != "quit" )
    {
        std::cout << str << "\n";
        helper.process( str );
        if ( helper.buffered( ) )
        {
            prompt = &MULTILINE_PROMPT;
        }
        else
        {
            prompt = &STD_PROMPT;
        }
        std::cout << *prompt;
        std::getline( std::cin, str );
    }

    Interpreter::Finalize( );
    return 0;
}
background-color: #f0f0f0; padding: 0 5px 0 5px; } td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; } span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; } .highlight .hll { background-color: #ffffcc } .highlight { background: #ffffff; } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/*
 * Copyright (c) 2004, Intel Corporation.
 * Copyright (c) 2006, Keir Fraser, XenSource Inc.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License, version 
 * 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT ANY 
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place - Suite 330, Boston, MA 02111-1307 USA.
 */

#include "acpi2_0.h"
#include "ssdt_s3.h"
#include "ssdt_s4.h"
#include "ssdt_tpm.h"
#include "ssdt_pm.h"
#include "../config.h"
#include "../util.h"

#define align16(sz)        (((sz) + 15) & ~15)
#define fixed_strcpy(d, s) strncpy((d), (s), sizeof(d))

extern struct acpi_20_rsdp Rsdp;
extern struct acpi_20_rsdt Rsdt;
extern struct acpi_20_xsdt Xsdt;
extern struct acpi_20_fadt Fadt;
extern struct acpi_20_facs Facs;
extern struct acpi_20_waet Waet;

/*
 * Located at ACPI_INFO_PHYSICAL_ADDRESS.
 *
 * This must match the Field("BIOS"....) definition in the DSDT.
 */
struct acpi_info {
    uint8_t  com1_present:1;    /* 0[0] - System has COM1? */
    uint8_t  com2_present:1;    /* 0[1] - System has COM2? */
    uint8_t  lpt1_present:1;    /* 0[2] - System has LPT1? */
    uint8_t  hpet_present:1;    /* 0[3] - System has HPET? */
    uint32_t pci_min, pci_len;  /* 4, 8 - PCI I/O hole boundaries */
    uint32_t madt_csum_addr;    /* 12   - Address of MADT checksum */
    uint32_t madt_lapic0_addr;  /* 16   - Address of first MADT LAPIC struct */
    uint32_t vm_gid_addr;       /* 20   - Address of VM generation id buffer */
};

/* Number of processor objects in the chosen DSDT. */
static unsigned int nr_processor_objects;

static void set_checksum(
    void *table, uint32_t checksum_offset, uint32_t length)
{
    uint8_t *p, sum = 0;

    p = table;
    p[checksum_offset] = 0;

    while ( length-- )
        sum = sum + *p++;

    p = table;
    p[checksum_offset] = -sum;
}

static uint8_t battery_port_exists(void)
{
    return (inb(0x88) == 0x1F);
}

static struct acpi_20_madt *construct_madt(struct acpi_info *info)
{
    struct acpi_20_madt           *madt;
    struct acpi_20_madt_intsrcovr *intsrcovr;
    struct acpi_20_madt_ioapic    *io_apic;
    struct acpi_20_madt_lapic     *lapic;
    int i, sz;

    sz  = sizeof(struct acpi_20_madt);
    sz += sizeof(struct acpi_20_madt_intsrcovr) * 16;
    sz += sizeof(struct acpi_20_madt_ioapic);
    sz += sizeof(struct acpi_20_madt_lapic) * nr_processor_objects;

    madt = mem_alloc(sz, 16);
    if (!madt) return NULL;

    memset(madt, 0, sizeof(*madt));
    madt->header.signature    = ACPI_2_0_MADT_SIGNATURE;
    madt->header.revision     = ACPI_2_0_MADT_REVISION;
    fixed_strcpy(madt->header.oem_id, ACPI_OEM_ID);
    fixed_strcpy(madt->header.oem_table_id, ACPI_OEM_TABLE_ID);
    madt->header.oem_revision = ACPI_OEM_REVISION;
    madt->header.creator_id   = ACPI_CREATOR_ID;
    madt->header.creator_revision = ACPI_CREATOR_REVISION;
    madt->lapic_addr = LAPIC_BASE_ADDRESS;
    madt->flags      = ACPI_PCAT_COMPAT;

    intsrcovr = (struct acpi_20_madt_intsrcovr *)(madt + 1);
    for ( i = 0; i < 16; i++ )
    {
        memset(intsrcovr, 0, sizeof(*intsrcovr));
        intsrcovr->type   = ACPI_INTERRUPT_SOURCE_OVERRIDE;
        intsrcovr->length = sizeof(*intsrcovr);
        intsrcovr->source = i;

        if ( i == 0 )
        {
            /* ISA IRQ0 routed to IOAPIC GSI 2. */
            intsrcovr->gsi    = 2;
            intsrcovr->flags  = 0x0;
        }
        else if ( PCI_ISA_IRQ_MASK & (1U << i) )
        {
            /* PCI: active-low level-triggered. */
            intsrcovr->gsi    = i;
            intsrcovr->flags  = 0xf;
        }
        else
        {
            /* No need for a INT source override structure. */
            continue;
        }

        intsrcovr++;
    }

    io_apic = (struct acpi_20_madt_ioapic *)intsrcovr;
    memset(io_apic, 0, sizeof(*io_apic));
    io_apic->type        = ACPI_IO_APIC;
    io_apic->length      = sizeof(*io_apic);
    io_apic->ioapic_id   = IOAPIC_ID;
    io_apic->ioapic_addr = IOAPIC_BASE_ADDRESS;

    lapic = (struct acpi_20_madt_lapic *)(io_apic + 1);
    info->madt_lapic0_addr = (uint32_t)lapic;
    for ( i = 0; i < nr_processor_objects; i++ )
    {
        memset(lapic, 0, sizeof(*lapic));
        lapic->type    = ACPI_PROCESSOR_LOCAL_APIC;
        lapic->length  = sizeof(*lapic);
        /* Processor ID must match processor-object IDs in the DSDT. */
        lapic->acpi_processor_id = i;
        lapic->apic_id = LAPIC_ID(i);
        lapic->flags = ((i < hvm_info->nr_vcpus) &&
                        test_bit(i, hvm_info->vcpu_online)
                        ? ACPI_LOCAL_APIC_ENABLED : 0);
        lapic++;
    }

    madt->header.length = (unsigned char *)lapic - (unsigned char *)madt;
    set_checksum(madt, offsetof(struct acpi_header, checksum),
                 madt->header.length);
    info->madt_csum_addr = (uint32_t)&madt->header.checksum;

    return madt;
}

static struct acpi_20_hpet *construct_hpet(void)
{
    struct acpi_20_hpet *hpet;

    hpet = mem_alloc(sizeof(*hpet), 16);
    if (!hpet) return NULL;

    memset(hpet, 0, sizeof(*hpet));
    hpet->header.signature    = ACPI_2_0_HPET_SIGNATURE;
    hpet->header.revision     = ACPI_2_0_HPET_REVISION;
    fixed_strcpy(hpet->header.oem_id, ACPI_OEM_ID);
    fixed_strcpy(hpet->header.oem_table_id, ACPI_OEM_TABLE_ID);
    hpet->header.oem_revision = ACPI_OEM_REVISION;
    hpet->header.creator_id   = ACPI_CREATOR_ID;
    hpet->header.creator_revision = ACPI_CREATOR_REVISION;
    hpet->timer_block_id      = 0x8086a201;
    hpet->addr.address        = ACPI_HPET_ADDRESS;

    hpet->header.length = sizeof(*hpet);
    set_checksum(hpet, offsetof(struct acpi_header, checksum), sizeof(*hpet));
    return hpet;
}

static struct acpi_20_waet *construct_waet(void)
{
    struct acpi_20_waet *waet;

    waet = mem_alloc(sizeof(*waet), 16);
    if (!waet) return NULL;

    memcpy(waet, &Waet, sizeof(*waet));

    waet->header.length = sizeof(*waet);
    set_checksum(waet, offsetof(struct acpi_header, checksum), sizeof(*waet));

    return waet;
}

static int construct_secondary_tables(unsigned long *table_ptrs,
                                      struct acpi_info *info)
{
    int nr_tables = 0;
    struct acpi_20_madt *madt;
    struct acpi_20_hpet *hpet;
    struct acpi_20_waet *waet;
    struct acpi_20_tcpa *tcpa;
    unsigned char *ssdt;
    static const uint16_t tis_signature[] = {0x0001, 0x0001, 0x0001};
    uint16_t *tis_hdr;
    void *lasa;

    /* MADT. */
    if ( (hvm_info->nr_vcpus > 1) || hvm_info->apic_mode )
    {
        madt = construct_madt(info);
        if (!madt) return -1;
        table_ptrs[nr_tables++] = (unsigned long)madt;
    }

    /* HPET. Always included in DSDT, so always include it here too. */
    /* (And it's unconditionally required by Windows SVVP tests.) */
    hpet = construct_hpet();
    if (!hpet) return -1;
    table_ptrs[nr_tables++] = (unsigned long)hpet;

    /* WAET. */
    waet = construct_waet();
    if (!waet) return -1;
    table_ptrs[nr_tables++] = (unsigned long)waet;

    if ( battery_port_exists() )
    {
        ssdt = mem_alloc(sizeof(ssdt_pm), 16);
        if (!ssdt) return -1;
        memcpy(ssdt, ssdt_pm, sizeof(ssdt_pm));
        table_ptrs[nr_tables++] = (unsigned long)ssdt;
    }

    if ( !strncmp(xenstore_read("platform/acpi_s3", "1"), "1", 1) )
    {
        ssdt = mem_alloc(sizeof(ssdt_s3), 16);
        if (!ssdt) return -1;
        memcpy(ssdt, ssdt_s3, sizeof(ssdt_s3));
        table_ptrs[nr_tables++] = (unsigned long)ssdt;
    } else {
        printf("S3 disabled\n");
    }

    if ( !strncmp(xenstore_read("platform/acpi_s4", "1"), "1", 1) )
    {
        ssdt = mem_alloc(sizeof(ssdt_s4), 16);
        if (!ssdt) return -1;
        memcpy(ssdt, ssdt_s4, sizeof(ssdt_s4));
        table_ptrs[nr_tables++] = (unsigned long)ssdt;
    } else {
        printf("S4 disabled\n");
    }

    /* TPM TCPA and SSDT. */
    tis_hdr = (uint16_t *)0xFED40F00;
    if ( (tis_hdr[0] == tis_signature[0]) &&
         (tis_hdr[1] == tis_signature[1]) &&
         (tis_hdr[2] == tis_signature[2]) )
    {
        ssdt = mem_alloc(sizeof(ssdt_tpm), 16);
        if (!ssdt) return -1;
        memcpy(ssdt, ssdt_tpm, sizeof(ssdt_tpm));
        table_ptrs[nr_tables++] = (unsigned long)ssdt;

        tcpa = mem_alloc(sizeof(struct acpi_20_tcpa), 16);
        if (!tcpa) return -1;
        memset(tcpa, 0, sizeof(*tcpa));
        table_ptrs[nr_tables++] = (unsigned long)tcpa;

        tcpa->header.signature = ACPI_2_0_TCPA_SIGNATURE;
        tcpa->header.length    = sizeof(*tcpa);
        tcpa->header.revision  = ACPI_2_0_TCPA_REVISION;
        fixed_strcpy(tcpa->header.oem_id, ACPI_OEM_ID);
        fixed_strcpy(tcpa->header.oem_table_id, ACPI_OEM_TABLE_ID);
        tcpa->header.oem_revision = ACPI_OEM_REVISION;
        tcpa->header.creator_id   = ACPI_CREATOR_ID;
        tcpa->header.creator_revision = ACPI_CREATOR_REVISION;
        if ( (lasa = mem_alloc(ACPI_2_0_TCPA_LAML_SIZE, 16)) != NULL )
        {
            tcpa->lasa = virt_to_phys(lasa);
            tcpa->laml = ACPI_2_0_TCPA_LAML_SIZE;
            memset(lasa, 0, tcpa->laml);
            set_checksum(tcpa,
                         offsetof(struct acpi_header, checksum),
                         tcpa->header.length);
        }
    }

    table_ptrs[nr_tables] = 0;
    return nr_tables;
}

void acpi_build_tables(struct acpi_config *config, unsigned int physical)
{
    struct acpi_info *acpi_info;
    struct acpi_20_rsdp *rsdp;
    struct acpi_20_rsdt *rsdt;
    struct acpi_20_xsdt *xsdt;
    struct acpi_20_fadt *fadt;
    struct acpi_10_fadt *fadt_10;
    struct acpi_20_facs *facs;
    unsigned char       *dsdt;
    unsigned long        secondary_tables[16];
    int                  nr_secondaries, i;

    /* Allocate and initialise the acpi info area. */
    mem_hole_populate_ram(ACPI_INFO_PHYSICAL_ADDRESS >> PAGE_SHIFT, 1);
    acpi_info = (struct acpi_info *)ACPI_INFO_PHYSICAL_ADDRESS;
    memset(acpi_info, 0, sizeof(*acpi_info));

    /*
     * Fill in high-memory data structures, starting at @buf.
     */

    facs = mem_alloc(sizeof(struct acpi_20_facs), 16);
    if (!facs) goto oom;
    memcpy(facs, &Facs, sizeof(struct acpi_20_facs));

    /*
     * Alternative DSDTs we get linked against. A cover-all DSDT for up to the
     * implementation-defined maximum number of VCPUs, and an alternative for use
     * when a guest can only have up to 15 VCPUs.
     *
     * The latter is required for Windows 2000, which experiences a BSOD of
     * KMODE_EXCEPTION_NOT_HANDLED if it sees more than 15 processor objects.
     */
    if ( hvm_info->nr_vcpus <= 15 && config->dsdt_15cpu)
    {
        dsdt = mem_alloc(config->dsdt_15cpu_len, 16);
        if (!dsdt) goto oom;
        memcpy(dsdt, config->dsdt_15cpu, config->dsdt_15cpu_len);
        nr_processor_objects = 15;
    }
    else
    {
        dsdt = mem_alloc(config->dsdt_anycpu_len, 16);
        if (!dsdt) goto oom;
        memcpy(dsdt, config->dsdt_anycpu, config->dsdt_anycpu_len);
        nr_processor_objects = HVM_MAX_VCPUS;
    }

    /*
     * N.B. ACPI 1.0 operating systems may not handle FADT with revision 2
     * or above properly, notably Windows 2000, which tries to copy FADT
     * into a 116 bytes buffer thus causing an overflow. The solution is to
     * link the higher revision FADT with the XSDT only and introduce a
     * compatible revision 1 FADT that is linked with the RSDT. Refer to:
     *     http://www.acpi.info/presentations/S01USMOBS169_OS%20new.ppt
     */
    fadt_10 = mem_alloc(sizeof(struct acpi_10_fadt), 16);
    if (!fadt_10) goto oom;
    memcpy(fadt_10, &Fadt, sizeof(struct acpi_10_fadt));
    fadt_10->header.length = sizeof(struct acpi_10_fadt);
    fadt_10->header.revision = ACPI_1_0_FADT_REVISION;
    fadt_10->dsdt          = (unsigned long)dsdt;
    fadt_10->firmware_ctrl = (unsigned long)facs;
    set_checksum(fadt_10,
                 offsetof(struct acpi_header, checksum),
                 sizeof(struct acpi_10_fadt));

    fadt = mem_alloc(sizeof(struct acpi_20_fadt), 16);
    if (!fadt) goto oom;
    memcpy(fadt, &Fadt, sizeof(struct acpi_20_fadt));
    fadt->dsdt   = (unsigned long)dsdt;
    fadt->x_dsdt = (unsigned long)dsdt;
    fadt->firmware_ctrl   = (unsigned long)facs;
    fadt->x_firmware_ctrl = (unsigned long)facs;
    set_checksum(fadt,
                 offsetof(struct acpi_header, checksum),
                 sizeof(struct acpi_20_fadt));

    nr_secondaries = construct_secondary_tables(secondary_tables, acpi_info);
    if ( nr_secondaries < 0 )
        goto oom;

    xsdt = mem_alloc(sizeof(struct acpi_20_xsdt)+
                     sizeof(uint64_t)*nr_secondaries,
                     16);
    if (!xsdt) goto oom;
    memcpy(xsdt, &Xsdt, sizeof(struct acpi_header));
    xsdt->entry[0] = (unsigned long)fadt;
    for ( i = 0; secondary_tables[i]; i++ )
        xsdt->entry[i+1] = secondary_tables[i];
    xsdt->header.length = sizeof(struct acpi_header) + (i+1)*sizeof(uint64_t);