diff options
Diffstat (limited to 'src/arch/i386')
-rw-r--r-- | src/arch/i386/include/arch/hlt.h | 20 | ||||
-rw-r--r-- | src/arch/i386/include/arch/romcc_io.h | 57 | ||||
-rw-r--r-- | src/arch/i386/include/arch/smp/lapic.h | 55 | ||||
-rw-r--r-- | src/arch/i386/lib/cpu.c | 4 | ||||
-rw-r--r-- | src/arch/i386/smp/start_stop.c | 9 |
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) |