Logo Search packages:      
Sourcecode: faumachine version File versions  Download package

arch_gen_cpu_x86.c

/* $Id: arch_gen_cpu_x86.c,v 1.62 2009-01-28 12:59:15 potyra Exp $ 
 *
 * Copyright (C) 2007-2009 FAUmachine Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */

#define DEBUG_BIOS_POST_CODE  0

#include "config.h"
#include "compiler.h"

#include <assert.h>
#include "fixme.h"
#include <stdio.h>
#include <string.h>

#include "glue-log.h"
#include "glue-main.h"
#include "glue-shm.h"

#include "exec-all.h"
#include "arch_gen_cpu_x86_state.h"
#include "arch_gen_cpu_x86_kernel_fast.h"
#include "arch_gen_cpu_x86_core.h"
#include "arch_gen_cpu_x86_mmu.h"
#include "arch_gen_cpu_x86_reg.h"
#include "arch_gen_cpu_x86_seg.h"
#include "qemu/cpu_jit.h"

#define COMP SNAME

#if 80386 <= CONFIG_CPU
static void
NAME_(ior)(uint16_t port, unsigned int bs, uint32_t *valp)
{
      *valp = -1;
      if (unlikely(sig_host_bus_ior(env->host_bus_main, env, port, bs, valp) != 0)) {
            sig_host_bus_type_addr(env->host_bus_main, env,
                        SIG_HOST_BUS_IOR, port);
            /* delay... */
            sig_host_bus_read_data(env->host_bus_main, env,
                        bs, valp);
      }
}

static void
NAME_(iow)(uint16_t port, unsigned int bs, uint32_t val)
{
      if (unlikely(sig_host_bus_iow(env->host_bus_main, env, port, bs, val) != 0)) {
            sig_host_bus_type_addr(env->host_bus_main, env,
                        SIG_HOST_BUS_IOW, port);
            /* delay... */
            sig_host_bus_write_data(env->host_bus_main, env,
                        bs, val);
      }
}
#endif /* 80386 <= CONFIG_CPU */

uint8_t
NAME_(inb)(uint16_t port)
{
      uint8_t val8;

#if CONFIG_CPU < 80386
      sig_isa_bus_inb(env->isa_bus_main, env, &val8, port);

#else
      uint32_t val32;

      NAME_(ior)(port & ~3, 1 << (port & 3), &val32);
      val8 = (val32 >> ((port & 3) * 8)) & 0xff;
#endif

      return val8;
}

uint16_t
NAME_(inw)(uint16_t port)
{
      uint16_t val16;

#if CONFIG_CPU < 80386
      if (port & 1) {
            uint8_t val0;
            uint8_t val1;

            sig_isa_bus_inb(env->isa_bus_main, env, &val0, port + 0);
            sig_isa_bus_inb(env->isa_bus_main, env, &val1, port + 1);
            val16 = val0 | (val1 << 8);

      } else {
            sig_isa_bus_inw(env->isa_bus_main, env, &val16, port);
      }

#else
      if ((port & 3) == 3) {
            uint32_t val0;
            uint32_t val1;

            NAME_(ior)((port & ~3) + 0, (0x3 << (port & 3)) & 0xf, &val0);
            NAME_(ior)((port & ~3) + 4, (0x3 << (port & 3)) >> 4, &val1);
            val16 = (val0 >> ((port & 3) * 8))
                  | (val1 << ((4 - (port & 3)) * 8));

      } else {
            uint32_t val32;

            NAME_(ior)(port & ~3, 3 << (port & 2), &val32);
            val16 = (val32 >> ((port & 2) * 8)) & 0xffff;
      }
#endif

      return val16;
}

#if 80386 <= CONFIG_CPU
uint32_t
NAME_(inl)(uint16_t port)
{
      uint32_t val32;

      if (port & 3) {
            uint32_t val0;
            uint32_t val1;

            NAME_(ior)((port & ~3) + 0, (0xf << (port & 3)) & 0xf, &val0);
            NAME_(ior)((port & ~3) + 4, (0xf << (port & 3)) >> 4, &val1);
            val32 = (val0 >> ((port & 3) * 8))
                  | (val1 << ((4 - (port & 3)) * 8));

      } else {
            NAME_(ior)(port, 0xf, &val32);
      }

      return val32;
}
#endif /* 80386 <= CONFIG_CPU */

void
NAME_(outb)(uint8_t value, uint16_t port)
{
#if DEBUG_BIOS_POST_CODE
        if (port == 0x0080
         || port == 0x0300) {
                /* BIOS Post code. */
                fprintf(stderr, "BIOS: Post code 0x%02x.\n", value);

        }
#endif
        if (port == 0xffff) {
                /* System BIOS / VGA BIOS output port. */
                fprintf(stderr, "%c", value);
                return;
        }

#if CONFIG_CPU < 80386
      sig_isa_bus_outb(env->isa_bus_main, env, value, port);
      
#else
        uint32_t val32;

        val32 = value << ((port & 3) * 8);
        NAME_(iow)(port & ~3, 1 << (port & 3), val32);
#endif
}

void
NAME_(outw)(uint16_t value, uint16_t port)
{
#if DEBUG_BIOS_POST_CODE
        if (port == 0x0080
         || port == 0x0300) {
                /* BIOS Post code. */
                fprintf(stderr, "BIOS: Post code 0x%04x.\n", value);
        }
#endif

#if CONFIG_CPU < 80386
      if (port & 1) {
            sig_isa_bus_outb(env->isa_bus_main, env, value >> 0, port + 0);
            sig_isa_bus_outb(env->isa_bus_main, env, value >> 8, port + 1);
            
      } else {
            sig_isa_bus_outw(env->isa_bus_main, env, value, port);
      }

#else
        uint32_t val32;

        if ((port & 3) == 3) {
                unsigned char value0 = (value >> 0) & 0xff;
                unsigned char value8 = (value >> 8) & 0xff;

                fprintf(stderr, "%s: WARNING: outw->outb port 0x%04x "
                                "value 0x%x\n", __FUNCTION__, port, value);

                NAME_(outb)(value0, port + 0);
                NAME_(outb)(value8, port + 1);

        } else {
                val32 = value << ((port & 3) * 8);
                NAME_(iow)(port & ~3, 3 << (port & 3), val32);
        }
#endif
}

#if 80386 <= CONFIG_CPU
void
NAME_(outl)(uint32_t value, uint16_t port)
{
#if DEBUG_BIOS_POST_CODE
        if (port == 0x0080
         || port == 0x0300) {
                /* BIOS Post code. */
                fprintf(stderr, "BIOS: Post code 0x%08x.\n", value);
        }
#endif

        if (port & 3) {
                uint32_t val0;
                uint32_t val1;

                fprintf(stderr, "%s: WARNING: outl->outw port 0x%04x "
                        "value 0x%08lx\n", __FUNCTION__, port, (long)value);

                val0 = value << ((port & 3) * 8);
                val1 = value << ((4 - (port & 3)) * 8);

                NAME_(iow)(port & ~3, (0xf << (port & 3)) & 0xf, val0);
                NAME_(iow)((port & ~3) + 4, 0xf >> (4 - (port & 3)), val1);

        } else {
                NAME_(iow)(port & ~3, 0xf, value);
        }
}
#endif /* 80386 <= CONFIG_CPU */

#if 80386 <= CONFIG_CPU
void
NAME_(mr)(unsigned long addr, unsigned int bs, uint32_t *valp)
{
      if (unlikely(sig_host_bus_mr(env->host_bus_main, env,
                  env->smm, addr, bs, valp) != 0)) {
            sig_host_bus_type_addr(env->host_bus_main, env,
                        SIG_HOST_BUS_MR, addr);
            /* delay */
            sig_host_bus_read_data(env->host_bus_main, env,
                        bs, valp);
      }
}

static void
NAME_(mw)(unsigned long addr, unsigned int bs, uint32_t val)
{
      if (unlikely(sig_host_bus_mw(env->host_bus_main, env,
                  env->smm, addr, bs, val) != 0)) {
            sig_host_bus_type_addr(env->host_bus_main, env,
                        SIG_HOST_BUS_MW, addr);
            /* delay */
            sig_host_bus_write_data(env->host_bus_main, env,
                        bs, val);
      }
}

static void
NAME_(mx)(unsigned long addr, unsigned int bs, uint32_t *valp)
{
      if (unlikely(sig_host_bus_mr(env->host_bus_main, env,
                  env->smm, addr, bs, valp) != 0)) {
            sig_host_bus_type_addr(env->host_bus_main, env,
                        SIG_HOST_BUS_MR, addr);
            /* delay */
            sig_host_bus_read_data(env->host_bus_main, env,
                        bs, valp);
      }
}
#endif /* 80386 <= CONFIG_CPU */

static uint32_t
NAME_(mr_data_b)(Paddr pa)
{
#if CONFIG_CPU < 80386
      uint8_t val8;

      sig_isa_bus_readb(env->isa_bus_main, env, pa, &val8);

      return val8;

#else
      uint32_t val;

      assert(! (pa & 0));

      NAME_(mr)(pa & ~3, 1 << (pa & 3), &val);

      return (val >> ((pa & 3) * 8)) & 0xff;
#endif
}

static uint32_t
NAME_(mr_data_w)(Paddr pa)
{
      assert(! (pa & 1));

#if CONFIG_CPU < 80386
      uint16_t val16;

      sig_isa_bus_readw(env->isa_bus_main, env, pa, &val16);

      return val16;

#else
      uint32_t val;

      NAME_(mr)(pa & ~2, 3 << (pa & 2), &val);

      return (val >> ((pa & 2) * 8)) & 0xffff;
#endif
}

#if 80486 <= CONFIG_CPU && CONFIG_CPU_APIC_SUPPORT
/*forward*/ static int
NAME_(apic_read)(unsigned long pa, void *to, unsigned long len);
#endif

uint32_t
NAME_(mr_data_l)(Paddr pa)
{
      assert(! (pa & 3));

#if CONFIG_CPU < 80386
      fixme();

      return 0;

#else
      uint32_t val;

#if 80486 <= CONFIG_CPU && CONFIG_CPU_APIC_SUPPORT
      if (! (pa & 0xf)) {
            if (NAME_(apic_read)(pa, &val, 4) == 0) {
                  return val;
            }
      }
#endif

      NAME_(mr)(pa & ~0, 0xf << (pa & 0), &val);

      return (val >> ((pa & 0) * 8)) & 0xffffffff;
#endif
}

static void
NAME_(mw_data_b)(Paddr pa, uint32_t val)
{
      assert(! (pa & 0));

#if CONFIG_CPU < 80386
      sig_isa_bus_writeb(env->isa_bus_main, env, pa, val);

#else
      val <<= (pa & 3) * 8;

      NAME_(mw)(pa & ~3, 1 << (pa & 3), val);
#endif
}

void
NAME_(mw_data_w)(Paddr pa, uint32_t val)
{
      assert(! (pa & 1));

#if CONFIG_CPU < 80386
      sig_isa_bus_writew(env->isa_bus_main, env, pa, val);

#else
      val <<= (pa & 2) * 8;

      NAME_(mw)(pa & ~2, 3 << (pa & 2), val);
#endif
}

#if 80486 <= CONFIG_CPU && CONFIG_CPU_APIC_SUPPORT
/*forward*/ static int
NAME_(apic_write)(unsigned long pa, const void *from, unsigned long len);
#endif

void
NAME_(mw_data_l)(Paddr pa, uint32_t val)
{
      assert(! (pa & 3));

#if CONFIG_CPU < 80386
      fixme();

#else
      val <<= (pa & 0) * 8;

#if 80486 <= CONFIG_CPU && CONFIG_CPU_APIC_SUPPORT
      if (! (pa & 0xf)) {
            if (NAME_(apic_write)(pa, &val, 4) == 0) {
                  return;
            }
      }
#endif

      NAME_(mw)(pa & ~0, 0xf << (pa & 0), val);
#endif
}

static uint32_t
NAME_(mx_code_b)(Paddr pa)
{
      assert(! (pa & 0));

#if CONFIG_CPU < 80386
      uint8_t val8;

      sig_isa_bus_readb(env->isa_bus_main, env, pa, &val8);

      return val8;

#else
      uint32_t val;

      NAME_(mx)(pa & ~3, 1 << (pa & 3), &val);

      return (val >> ((pa & 3) * 8)) & 0xff;
#endif
}

static uint32_t
NAME_(mx_code_w)(Paddr pa)
{
      assert(! (pa & 1));

#if CONFIG_CPU < 80386
      uint16_t val16;

      sig_isa_bus_readw(env->isa_bus_main, env, pa, &val16);

      return val16;

#else
      uint32_t val;

      NAME_(mx)(pa & ~2, 3 << (pa & 2), &val);

      return (val >> ((pa & 2) * 8)) & 0xffff;
#endif
}

static uint32_t
NAME_(mx_code_l)(Paddr pa)
{
      assert(! (pa & 3));

#if CONFIG_CPU < 80386
      fixme();

      return 0;

#else
      uint32_t val;

      NAME_(mx)(pa & ~0, 0xf << (pa & 0), &val);

      return (val >> ((pa & 0) * 8)) & 0xffffffff;
#endif
}

static void
NAME_(mw_code_b)(Paddr pa, uint32_t val)
{
      NAME_(tb_invalidate_phys_page_fast)(pa, 1);
      NAME_(mw_data_b)(pa, val);
}

static void
NAME_(mw_code_w)(Paddr pa, uint32_t val)
{
      NAME_(tb_invalidate_phys_page_fast)(pa, 2);
      NAME_(mw_data_w)(pa, val);
}

static void
NAME_(mw_code_l)(Paddr pa, uint32_t val)
{
      NAME_(tb_invalidate_phys_page_fast)(pa, 4);
      NAME_(mw_data_l)(pa, val);
}

#if 80486 <= CONFIG_CPU && CONFIG_CPU_APIC_SUPPORT
/*forward*/ static int
NAME_(apic_map)(unsigned long pa,
      uint32_t **haddrp,
      unsigned long *lenp,
      int *wflagp
);
#endif

static int
NAME_(map)(
      unsigned long pa,
      Haddr *haddr_mr_p,
      Haddr *haddr_mw_p,
      Haddr *haddr_mx_p
)
{
#if 80486 <= CONFIG_CPU && CONFIG_CPU_APIC_SUPPORT
      uint32_t *haddr;
      unsigned long len;
      int wflag;
#endif
      int ret;

#if 80486 <= CONFIG_CPU && CONFIG_CPU_APIC_SUPPORT
      /* First try internal APIC. */
      ret = NAME_(apic_map)(pa, &haddr, &len, &wflag);
      if (ret == 0) {
            assert(! haddr);
            assert(len == 4096);
            assert(wflag);

            *haddr_mr_p = NULL;
            *haddr_mw_p = NULL;
            *haddr_mx_p = NULL;
            return 0;
      }
#endif

#if CONFIG_CPU < 80386
      /* Try isa bus components. */
      ret = sig_isa_bus_map(env->isa_bus_main, env,
                  pa, 4096, haddr_mr_p, haddr_mw_p);
      if (ret == 0) {
            *haddr_mx_p = *haddr_mr_p;
            return 0;
      }

#else
      /* Try host bus components. */
      ret = sig_host_bus_map(env->host_bus_main, env,
                  env->smm, pa, 4096, haddr_mr_p, haddr_mw_p, haddr_mx_p);
      if (ret == 0) {
            return 0;
      }
#endif

      /* Region unknown => not mapped. */
      *haddr_mr_p = NULL;
      *haddr_mw_p = NULL;
      *haddr_mx_p = NULL;
      return 1;
}

static void
NAME_(ack)(uint8_t *vecp)
{
#if CONFIG_CPU < 80386
      sig_isa_bus_ack(env->isa_bus_main, env, vecp);

#else
      sig_host_bus_inta_addr(env->host_bus_main, env);
      sig_host_bus_inta_data(env->host_bus_main, env, vecp);
#endif
}

#include "arch_gen_cpu_x86_apic.c"
#include "arch_gen_cpu_x86_core.c"
#include "arch_gen_cpu_x86_io.c"
#include "arch_gen_cpu_x86_mmu.c"
#include "arch_gen_cpu_x86_reg.c"

#if 80386 <= CONFIG_CPU
static void
NAME_(a20m_set)(void *_env, unsigned int a20_state)
{
      struct CPUState *oldenv = env;

      env = (struct CPUState *) _env;

      NAME_(mmu_a20m_set)(a20_state);

      env = oldenv;
}
#endif /* 80386 <= CONFIG_CPU */

void
NAME_(unmap)(void *_env, unsigned long pa, unsigned long len)
{
      struct CPUState *oldenv = env;

      env = (struct cpu *) _env;

      NAME_(mmu_unmap_range)(pa, len);

      env = oldenv;
}

static void
NAME_(lint0_set)(void *_env, unsigned int val)
{
      struct CPUState *oldenv = env;

      assert(val == 0 || val == 1);

      env = (struct cpu *) _env;

      NAME_(apic_lint0_set)(val);

      env = oldenv;
}

static void
NAME_(lint1_set)(void *_env, unsigned int val)
{
      struct CPUState *oldenv = env;

      assert(val == 0 || val == 1);

      env = (struct cpu *) _env;

      NAME_(apic_lint1_set)(val);

      env = oldenv;
}

#if 80386 <= CONFIG_CPU
static void
NAME_(smi_set)(void *_env, unsigned int val)
{
      struct CPUState *oldenv = env;

      env = (struct cpu *) _env;

      assert(val == 0 || val == 1);

      NAME_(apic_smi_set)(val);

      env = oldenv;
}
#endif /* 80386 <= CONFIG_CPU */

#if 80486 <= CONFIG_CPU && CONFIG_CPU_APIC_SUPPORT
static void
NAME_(eoi_receive)(void *_env, uint8_t vector)
{
      struct CPUState *oldenv = env;

      NAME_(apic_eoi_receive)(vector);

      env = oldenv;
}

static void
NAME_(msg0_receive)(
      void *_env,
      unsigned int destination_mode,
      unsigned int delivery_mode,
      unsigned int level,
      unsigned int trigger_mode,
      uint8_t vector,
      uint8_t destination
)
{
      struct CPUState *oldenv = env;

      env = (struct cpu *) _env;

      NAME_(apic_msg0_receive)(destination_mode, delivery_mode, level,
                  trigger_mode, vector, destination);

      env = oldenv;
}

static void
NAME_(status0_receive)(void *_env, unsigned int status)
{
      struct CPUState *oldenv = env;

      NAME_(apic_status0_receive)(status);

      env = oldenv;
}

static void
NAME_(msg1_receive)(void *_env, uint8_t processor_priority)
{
      struct CPUState *oldenv = env;

      NAME_(apic_msg1_receive)(processor_priority);

      env = oldenv;
}

static void
NAME_(status1_receive)(void *_env, unsigned int status)
{
      struct CPUState *oldenv = env;

      NAME_(apic_status1_receive)(status);

      env = oldenv;
}
#endif /* 80486 <= CONFIG_CPU && CONFIG_CPU_APIC_SUPPORT */

static void
NAME_(power_set)(void *_env, unsigned int val)
{
      struct CPUState *oldenv = env;

      env = (struct CPUState *) _env;

      NAME_(core_power_set)(val);

      env = oldenv;
}

static void
NAME_(n_reset_set)(void *_env, unsigned int n_val)
{
      struct CPUState *oldenv = env;

      env = (struct CPUState *) _env;

      NAME_(core_n_reset_set)(n_val);

      env = oldenv;
}

#if 80386 <= CONFIG_CPU
static void
NAME_(n_init_set)(void *_env, unsigned int n_val)
{
      struct CPUState *oldenv = env;

      env = (struct CPUState *) _env;

      NAME_(core_n_init_set)(n_val);

      env = oldenv;
}
#endif /* 80386 <= CONFIG_CPU */

static void
NAME_(n_ignne_set)(void *_env, unsigned int n_val)
{
      struct CPUState *oldenv = env;

      env = (struct CPUState *) _env;

      NAME_(core_n_ignne_set)(n_val);

      env = oldenv;
}

void
NAME_(init)(
      unsigned int nr,
      struct sig_boolean *port_power,
      struct sig_boolean *port_n_reset,
#if 80386 < CONFIG_CPU
      struct sig_boolean *port_n_init,
#endif
      struct sig_boolean_or *port_irq,
      struct sig_boolean_or *port_nmi,
#if 80386 <= CONFIG_CPU
      struct sig_boolean *port_smi,
#endif
      struct sig_boolean_or *port_n_ferr,
      struct sig_boolean *port_n_ignne,
#if 80386 <= CONFIG_CPU
      struct sig_boolean *port_a20,
#endif
#if 80486 <= CONFIG_CPU && CONFIG_CPU_APIC_SUPPORT
      struct sig_icc_bus *port_icc,
#endif
#if CONFIG_CPU < 80386
      struct sig_isa_bus_main *port_isa_bus
#else
      struct sig_host_bus_main *port_host_bus
#endif
)
{
      /* APIC */
      static const struct sig_boolean_or_funcs lint0_func = {
            .set = NAME_(lint0_set),
      };
      static const struct sig_boolean_or_funcs lint1_func = {
            .set = NAME_(lint1_set),
      };
#if 80386 <= CONFIG_CPU
      static const struct sig_boolean_funcs smi_func = {
            .set = NAME_(smi_set),
      };
#endif /* 80386 <= CONFIG_CPU */
#if 80486 <= CONFIG_CPU && CONFIG_CPU_APIC_SUPPORT
      static const struct sig_icc_bus_funcs icc_funcs = {
            .eoi = NAME_(eoi_receive),
            .msg0 = NAME_(msg0_receive),
            .status0 = NAME_(status0_receive),
            .msg1 = NAME_(msg1_receive),
            .status1 = NAME_(status1_receive),
      };
#endif /* 80486 <= CONFIG_CPU && CONFIG_CPU_APIC_SUPPORT */

      /* Core */
      static const struct sig_boolean_funcs power_funcs = {
            .set = NAME_(power_set),
      };
      static const struct sig_boolean_funcs n_reset_funcs = {
            .set = NAME_(n_reset_set),
      };
#if 80386 <= CONFIG_CPU
      static const struct sig_boolean_funcs n_init_funcs = {
            .set = NAME_(n_init_set),
      };
#endif
      static const struct sig_boolean_funcs n_ignne_funcs = {
            .set = NAME_(n_ignne_set),
      };

#if 80386 <= CONFIG_CPU
      /* MMU */
      static const struct sig_boolean_funcs a20_func = {
            .set = NAME_(a20m_set),
      };
#endif

      /* I/O */
#if CONFIG_CPU < 80386
      /* FIXME */
#else
      static const struct sig_host_bus_main_funcs main_funcs = {
            .unmap = NAME_(unmap),
      };
#endif

      struct cpu *cpssp;

      /* Switch on host optimization. */
#if USE_KFAUM && 0      /* FIXME */
      NAME_(kfaum_init)();
#endif

      cpssp = shm_map(COMP, nr, sizeof(*cpssp), 1);

      cpssp->a20_mask = 0xffffffff;

      cpssp->sig_power = port_power;
      cpssp->sig_n_reset = port_n_reset;
#if 80386 < CONFIG_CPU
      cpssp->sig_n_init = port_n_init;
#endif
      cpssp->sig_irq = port_irq;
      cpssp->sig_nmi = port_nmi;
#if 80386 <= CONFIG_CPU
      cpssp->sig_smi = port_smi;
#endif
      cpssp->sig_n_ferr = port_n_ferr;
      cpssp->sig_n_ignne = port_n_ignne;
#if 80386 <= CONFIG_CPU
      cpssp->sig_a20 = port_a20;
#endif
#if 80486 <= CONFIG_CPU && CONFIG_CPU_APIC_SUPPORT
      cpssp->icc_bus = port_icc;
#endif
#if CONFIG_CPU < 80386
      cpssp->isa_bus_main = port_isa_bus;
#else
      cpssp->host_bus_main = port_host_bus;
#endif

      NAME_(mmu_init)(cpssp);
      NAME_(jit_buffer_init)(cpssp);
      NAME_(jit_compile_init)(cpssp);
      NAME_(io_init)(cpssp);
      NAME_(apic_init)(cpssp);

      /* Output signals. */
      sig_boolean_or_connect_out(cpssp->sig_n_ferr, cpssp, 0);

      /* Cycle signals. */
#if CONFIG_CPU < 80386
      /* FIXME */
#else
      sig_host_bus_main_connect(cpssp->host_bus_main, cpssp, &main_funcs);
#endif
#if 80486 <= CONFIG_CPU && CONFIG_CPU_APIC_SUPPORT
      sig_icc_bus_connect(cpssp->icc_bus, cpssp, &icc_funcs);
#endif

      /* Input signals. */
      sig_boolean_connect_in(cpssp->sig_power, cpssp, &power_funcs);
      sig_boolean_connect_in(cpssp->sig_n_reset, cpssp, &n_reset_funcs);
#if 80386 <= CONFIG_CPU /* FIXME */
      sig_boolean_connect_in(cpssp->sig_n_init, cpssp, &n_init_funcs);
#endif

      sig_boolean_or_connect_in(cpssp->sig_irq, cpssp, &lint0_func);
      sig_boolean_or_connect_in(cpssp->sig_nmi, cpssp, &lint1_func);
#if 80386 <= CONFIG_CPU
      sig_boolean_connect_in(cpssp->sig_smi, cpssp, &smi_func);
#endif

      sig_boolean_connect_in(cpssp->sig_n_ignne, cpssp, &n_ignne_funcs);

#if 80386 <= CONFIG_CPU
      sig_boolean_connect_in(cpssp->sig_a20, cpssp, &a20_func);
#endif

      sched_process_init(&cpssp->process, NAME_(step), cpssp);
}

unsigned int
NAME_(create)(void)
{
      static unsigned int nr = 0;
      struct cpu *cpssp;

      shm_create(COMP, nr, sizeof(*cpssp));
      cpssp = shm_map(COMP, nr, sizeof(*cpssp), 1);

      /* Configuration */
      /* FIXME */
      cpssp->apic_cluster_id = 1;
      cpssp->apic_arbitration_id = nr;

      cpssp->process.inst_hz = CONFIG_CPU_FREQ;

      NAME_(apic_create)(cpssp);

      shm_unmap(cpssp, sizeof(*cpssp));

      return nr++;
}

void
NAME_(destroy)(unsigned int nr)
{
      struct cpu *cpssp;

      cpssp = shm_map(COMP, nr, sizeof(*cpssp), 1);

      NAME_(apic_destroy)(cpssp);

      shm_unmap(cpssp, sizeof(*cpssp));
      shm_destroy(COMP, nr);
}

#undef DEBUG_BIOS_POST_CODE

Generated by  Doxygen 1.6.0   Back to index