summaryrefslogtreecommitdiff
path: root/src/arch/i386
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/i386')
-rw-r--r--src/arch/i386/include/arch/hlt.h20
-rw-r--r--src/arch/i386/include/arch/romcc_io.h57
-rw-r--r--src/arch/i386/include/arch/smp/lapic.h55
-rw-r--r--src/arch/i386/lib/cpu.c4
-rw-r--r--src/arch/i386/smp/start_stop.c9
5 files changed, 132 insertions, 13 deletions
diff --git a/src/arch/i386/include/arch/hlt.h b/src/arch/i386/include/arch/hlt.h
new file mode 100644
index 0000000000..86ed7c8f41
--- /dev/null
+++ b/src/arch/i386/include/arch/hlt.h
@@ -0,0 +1,20 @@
+#ifndef ARCH_HLT_H
+#define ARCH_HLT_H
+
+#ifdef __ROMCC__
+static void hlt(void)
+{
+ __builtin_hlt();
+}
+
+#endif
+
+#ifdef __GNUC__
+static inline void hlt(void)
+{
+ asm("hlt");
+ return;
+}
+#endif
+
+#endif /* ARCH_HLT_H */
diff --git a/src/arch/i386/include/arch/romcc_io.h b/src/arch/i386/include/arch/romcc_io.h
index 1a646359a7..c3a0ff76fa 100644
--- a/src/arch/i386/include/arch/romcc_io.h
+++ b/src/arch/i386/include/arch/romcc_io.h
@@ -1,11 +1,7 @@
#ifndef ARCH_ROMCC_IO_H
#define ARCH_ROMCC_IO_H 1
-
-static void hlt(void)
-{
- __builtin_hlt();
-}
+#include <stdint.h>
typedef __builtin_div_t div_t;
typedef __builtin_ldiv_t ldiv_t;
@@ -59,6 +55,9 @@ int log2(int value)
#define PCI_ID(VENDOR_ID, DEVICE_ID) \
((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
+
+#define PNP_DEV(PORT, FUNC) (((PORT) << 8) | (FUNC))
+
typedef unsigned device_t;
static unsigned char pci_read_config8(device_t dev, unsigned where)
@@ -122,4 +121,52 @@ static device_t pci_locate_device(unsigned pci_id, device_t dev)
return PCI_DEV_INVALID;
}
+
+/* Generic functions for pnp devices */
+static inline void pnp_write_config(device_t dev, uint8_t reg, uint8_t value)
+{
+ unsigned port = dev >> 8;
+ outb(reg, port );
+ outb(value, port +1);
+}
+
+static inline uint8_t pnp_read_config(device_t dev, uint8_t reg)
+{
+ unsigned port = dev >> 8;
+ outb(reg, port);
+ return inb(port +1);
+}
+
+static inline void pnp_set_logical_device(device_t dev)
+{
+ unsigned device = dev & 0xff;
+ pnp_write_config(dev, 0x07, device);
+}
+
+static inline void pnp_set_enable(device_t dev, int enable)
+{
+ pnp_write_config(dev, 0x30, enable?0x1:0x0);
+}
+
+static inline int pnp_read_enable(device_t dev)
+{
+ return !!pnp_read_config(dev, 0x30);
+}
+
+static inline void pnp_set_iobase(device_t dev, unsigned index, unsigned iobase)
+{
+ pnp_write_config(dev, index + 0, (iobase >> 8) & 0xff);
+ pnp_write_config(dev, index + 1, iobase & 0xff);
+}
+
+static inline void pnp_set_irq(device_t dev, unsigned index, unsigned irq)
+{
+ pnp_write_config(dev, index, irq);
+}
+
+static inline void pnp_set_drq(device_t dev, unsigned index, unsigned drq)
+{
+ pnp_write_config(dev, index, drq & 0xff);
+}
+
#endif /* ARCH_ROMCC_IO_H */
diff --git a/src/arch/i386/include/arch/smp/lapic.h b/src/arch/i386/include/arch/smp/lapic.h
new file mode 100644
index 0000000000..0ac87aa2d3
--- /dev/null
+++ b/src/arch/i386/include/arch/smp/lapic.h
@@ -0,0 +1,55 @@
+#ifndef ARCH_SMP_LAPIC_H
+#define ARCH_SMP_LAPIC_H
+
+#include <cpu/p6/msr.h>
+#include <cpu/p6/apic.h>
+#include <arch/hlt.h>
+
+static void enable_lapic(void)
+{
+
+ msr_t msr;
+ msr = rdmsr(0x1b);
+ msr.hi &= 0xffffff00;
+ msr.lo &= 0x000007ff;
+ msr.lo |= APIC_DEFAULT_BASE | (1 << 11);
+ wrmsr(0x1b, msr);
+}
+
+static void disable_lapic(void)
+{
+ msr_t msr;
+ msr = rdmsr(0x1b);
+ msr.lo &= ~ (1 << 11);
+ wrmsr(0x1b, msr);
+}
+
+static inline unsigned long lapicid(void)
+{
+ return apic_read(APIC_ID) >> 24;
+}
+
+static void stop_this_cpu(void)
+{
+ unsigned apicid;
+ apicid = lapicid();
+
+ /* Send an APIC INIT to myself */
+ apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
+ apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT);
+ /* Wait for the ipi send to finish */
+ apic_wait_icr_idle();
+
+ /* Deassert the APIC INIT */
+ apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
+ apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT);
+ /* Wait for the ipi send to finish */
+ apic_wait_icr_idle();
+
+ /* If I haven't halted spin forever */
+ for(;;) {
+ hlt();
+ }
+}
+
+#endif /* ARCH_SMP_LAPIC_H */
diff --git a/src/arch/i386/lib/cpu.c b/src/arch/i386/lib/cpu.c
index ad982dbc6c..f459f3a853 100644
--- a/src/arch/i386/lib/cpu.c
+++ b/src/arch/i386/lib/cpu.c
@@ -10,6 +10,7 @@
#include <cpu/p6/msr.h>
#include <cpu/p6/apic.h>
#include <cpu/p5/cpuid.h>
+#include <arch/smp/lapic.h>
#if 0
#include <cpu/l2_cache.h>
#endif
@@ -97,8 +98,7 @@ static void interrupts_on()
APIC_DELIVERY_MODE_NMI)
);
- printk_debug(" apic_id: %d ",
- apic_read(APIC_ID));
+ printk_debug(" apic_id: %d ", lapicid());
#else /* APIC */
#if i686==1
diff --git a/src/arch/i386/smp/start_stop.c b/src/arch/i386/smp/start_stop.c
index b40452403c..bf26437984 100644
--- a/src/arch/i386/smp/start_stop.c
+++ b/src/arch/i386/smp/start_stop.c
@@ -4,16 +4,13 @@
#include <delay.h>
#include <string.h>
#include <console/console.h>
+#include <arch/smp/lapic.h>
+#include <arch/hlt.h>
-static inline void hlt(void)
-{
- asm("hlt");
- return;
-}
unsigned long this_processors_id(void)
{
- return apic_read(APIC_ID) >> 24;
+ return lapicid();
}
int processor_index(unsigned long apicid)