Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 511 → Rev 512

/kernel/trunk/genarch/src/acpi/matd.c
44,8 → 44,12
 
#ifdef CONFIG_SMP
 
/** Standard ISA IRQ map; can be overriden by Interrupt Source Override entries of MADT. */
int isa_irq_map[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
 
static void madt_l_apic_entry(struct madt_l_apic *la, __u32 index);
static void madt_io_apic_entry(struct madt_io_apic *ioa, __u32 index);
static void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override, __u32 index);
static int madt_cmp(void * a, void * b);
 
struct madt_l_apic *madt_l_apic_entries = NULL;
79,20 → 83,22
static bool madt_cpu_enabled(index_t i);
static bool madt_cpu_bootstrap(index_t i);
static __u8 madt_cpu_apic_id(index_t i);
static int madt_irq_to_pin(int irq);
 
struct smp_config_operations madt_config_operations = {
.cpu_count = madt_cpu_count,
.cpu_enabled = madt_cpu_enabled,
.cpu_bootstrap = madt_cpu_bootstrap,
.cpu_apic_id = madt_cpu_apic_id
.cpu_apic_id = madt_cpu_apic_id,
.irq_to_pin = madt_irq_to_pin
};
 
static count_t madt_cpu_count(void)
count_t madt_cpu_count(void)
{
return madt_l_apic_entry_cnt;
}
 
static bool madt_cpu_enabled(index_t i)
bool madt_cpu_enabled(index_t i)
{
ASSERT(i < madt_l_apic_entry_cnt);
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->flags & 0x1;
99,18 → 105,24
 
}
 
static bool madt_cpu_bootstrap(index_t i)
bool madt_cpu_bootstrap(index_t i)
{
ASSERT(i < madt_l_apic_entry_cnt);
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id == l_apic_id();
}
 
static __u8 madt_cpu_apic_id(index_t i)
__u8 madt_cpu_apic_id(index_t i)
{
ASSERT(i < madt_l_apic_entry_cnt);
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id;
}
 
int madt_irq_to_pin(int irq)
{
ASSERT(irq < sizeof(isa_irq_map)/sizeof(int));
return isa_irq_map[irq];
}
 
int madt_cmp(void * a, void * b)
{
return
154,6 → 166,8
madt_io_apic_entry((struct madt_io_apic *) h, index);
break;
case MADT_INTR_SRC_OVRD:
madt_intr_src_ovrd_entry((struct madt_intr_src_ovrd *) h, index);
break;
case MADT_NMI_SRC:
case MADT_L_APIC_NMI:
case MADT_L_APIC_ADDR_OVRD:
209,5 → 223,12
}
}
 
void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override, __u32 index)
{
ASSERT(override->source < sizeof(isa_irq_map)/sizeof(int));
printf("Remapping irq%d to IO APIC pin%d\n", override->source, override->global_intr);
isa_irq_map[override->source] = override->global_intr;
}
 
#endif /* CONFIG_SMP */
/kernel/trunk/generic/src/main/kinit.c
117,6 → 117,11
#endif /* CONFIG_SMP */
 
/*
* At this point SMP, if present, is configured.
*/
arch_post_smp_init();
 
/*
* Create kernel console.
*/
if (t = thread_create(kconsole, NULL, TASK, 0))
164,7 → 169,7
#endif /* CONFIG_TEST */
 
while (1) {
thread_sleep(60);
thread_sleep(1);
printf("kinit... ");
}
 
/kernel/trunk/generic/src/main/main.c
170,7 → 170,6
 
arch_pre_smp_init();
smp_init();
arch_post_smp_init();
printf("config.memory_size=%dM\n", config.memory_size/(1024*1024));
printf("config.cpu_count=%d\n", config.cpu_count);
 
/kernel/trunk/generic/src/main/kconsole.c
49,5 → 49,6
while (true) {
printf("%s> ", __FUNCTION__);
gets(stdin, buf, sizeof(buf));
printf("?\n");
}
}
/kernel/trunk/arch/amd64/src/amd64.c
69,7 → 69,6
 
if (config.cpu_active == 1) {
bios_init();
i8042_init(); /* a20 bit */
i8259_init(); /* PIC */
i8254_init(); /* hard clock */
 
102,7 → 101,7
 
void arch_post_smp_init(void)
{
trap_virtual_enable_irqs(1<<IRQ_KBD);
i8042_init(); /* keyboard controller */
}
 
void calibrate_delay_loop(void)
/kernel/trunk/arch/ia32/include/smp/apic.h
114,7 → 114,56
#define IOAPICARB 0x02
#define IOREDTBL 0x10
 
/** Delivery modes. */
#define DELMOD_FIXED 0x0
#define DELMOD_LOWPRI 0x1
#define DELMOD_SMI 0x2
/* 0x3 reserved */
#define DELMOD_NMI 0x4
#define DELMOD_INIT 0x5
/* 0x6 reserved */
#define DELMOD_EXTINT 0x7
 
/** Destination modes. */
#define DESTMOD_PHYS 0x0
#define DESTMOD_LOGIC 0x1
 
/** Trigger Modes. */
#define TRIGMOD_EDGE 0x0
#define TRIGMOD_LEVEL 0x1
 
/** Interrupt Input Pin Polarities. */
#define POLARITY_HIGH 0x0
#define POLARITY_LOW 0x1
 
/** I/O Redirection Register. */
struct io_redirection_reg {
union {
__u32 lo;
struct {
unsigned intvec : 8; /**< Interrupt Vector. */
unsigned delmod : 3; /**< Delivery Mode. */
unsigned destmod : 1; /**< Destination mode. */
unsigned delivs : 1; /**< Delivery status (RO). */
unsigned intpol : 1; /**< Interrupt Input Pin Polarity. */
unsigned irr : 1; /**< Remote IRR (RO). */
unsigned trigger_mode : 1; /**< Trigger Mode. */
unsigned masked : 1; /**< Interrupt Mask. */
unsigned : 15; /**< Reserved. */
};
};
union {
__u32 hi;
struct {
unsigned : 24; /**< Reserved. */
unsigned dest : 8; /**< Destination Field. */
};
};
} __attribute__ ((packed));
 
typedef struct io_redirection_reg io_redirection_reg_t;
 
extern volatile __u32 *l_apic;
extern volatile __u32 *io_apic;
 
/kernel/trunk/arch/ia32/include/smp/mps.h
120,8 → 120,6
 
extern struct smp_config_operations mps_config_operations;
 
extern int mps_irq_to_pin(int irq);
 
extern void mps_init(void);
extern void kmp(void *arg);
 
/kernel/trunk/arch/ia32/include/smp/smp.h
32,11 → 32,15
#include <arch/types.h>
#include <typedefs.h>
 
/** SMP config opertaions interface. */
struct smp_config_operations {
count_t (* cpu_count)(void);
bool (* cpu_enabled)(index_t i);
bool (*cpu_bootstrap)(index_t i);
__u8 (*cpu_apic_id)(index_t i);
count_t (* cpu_count)(void); /**< Return number of detected processors. */
bool (* cpu_enabled)(index_t i); /**< Check whether the processor of index i is enabled. */
bool (*cpu_bootstrap)(index_t i); /**< Check whether the processor of index i is BSP. */
__u8 (*cpu_apic_id)(index_t i); /**< Return APIC ID of the processor of index i. */
int (*irq_to_pin)(int irq); /**< Return mapping between irq and APIC pin. */
};
 
extern int smp_irq_to_pin(int irq);
 
#endif
/kernel/trunk/arch/ia32/src/ia32.c
56,7 → 56,6
 
if (config.cpu_active == 1) {
bios_init();
i8042_init(); /* keyboard controller */
i8259_init(); /* PIC */
i8254_init(); /* hard clock */
89,7 → 88,7
 
void arch_post_smp_init(void)
{
trap_virtual_enable_irqs(1<<IRQ_KBD);
i8042_init(); /* keyboard controller */
}
 
void calibrate_delay_loop(void)
/kernel/trunk/arch/ia32/src/smp/mps.c
89,12 → 89,14
static bool is_cpu_enabled(index_t i);
static bool is_bsp(index_t i);
static __u8 get_cpu_apic_id(index_t i);
static int mps_irq_to_pin(int irq);
 
struct smp_config_operations mps_config_operations = {
.cpu_count = get_cpu_count,
.cpu_enabled = is_cpu_enabled,
.cpu_bootstrap = is_bsp,
.cpu_apic_id = get_cpu_apic_id
.cpu_apic_id = get_cpu_apic_id,
.irq_to_pin = mps_irq_to_pin
};
 
count_t get_cpu_count(void)
/kernel/trunk/arch/ia32/src/smp/smp.c
165,4 → 165,10
waitq_wakeup(&kmp_completion_wq, WAKEUP_FIRST);
}
 
int smp_irq_to_pin(int irq)
{
ASSERT(ops != NULL);
return ops->irq_to_pin(irq);
}
 
#endif /* CONFIG_SMP */
/kernel/trunk/arch/ia32/src/smp/apic.c
40,8 → 40,7
#ifdef CONFIG_SMP
 
/*
* This is functional, far-from-general-enough interface to the APIC.
* Advanced Programmable Interrupt Controller for MP systems.
* Advanced Programmable Interrupt Controller for SMP systems.
* Tested on:
* Bochs 2.0.2 - Bochs 2.2 with 2-8 CPUs
* Simics 2.0.28 - Simics 2.2.14 2-4 CPUs
82,11 → 81,12
*/
io_apic_disable_irqs(0xffff);
trap_register(VECTOR_CLK, l_apic_timer_interrupt);
for (i=1; i<16; i++) {
for (i=0; i<16; i++) {
int pin;
if ((pin = mps_irq_to_pin(i)) != -1)
io_apic_change_ioredtbl(pin,0xf,IVT_IRQBASE+i,LOPRI);
if ((pin = smp_irq_to_pin(i)) != -1) {
io_apic_change_ioredtbl(pin,0xff,IVT_IRQBASE+i,LOPRI);
}
}
 
352,29 → 352,31
 
void io_apic_change_ioredtbl(int signal, int dest, __u8 v, int flags)
{
__u32 reglo, reghi;
io_redirection_reg_t reg;
int dlvr = 0;
if (flags & LOPRI)
dlvr = 1;
dlvr = DELMOD_LOWPRI;
 
reglo = io_apic_read(IOREDTBL + signal*2);
reghi = io_apic_read(IOREDTBL + signal*2 + 1);
reg.lo = io_apic_read(IOREDTBL + signal*2);
reg.hi = io_apic_read(IOREDTBL + signal*2 + 1);
reghi &= ~0x0f000000;
reghi |= (dest<<24);
reg.dest = dest;
reg.destmod = DESTMOD_LOGIC;
reg.trigger_mode = TRIGMOD_EDGE;
reg.intpol = POLARITY_HIGH;
reg.delmod = dlvr;
reg.intvec = v;
 
reglo &= (~0x1ffff) | (1<<16); /* don't touch the mask */
reglo |= (0<<15) | (0<<13) | (0<<11) | (dlvr<<8) | v;
 
io_apic_write(IOREDTBL + signal*2, reglo);
io_apic_write(IOREDTBL + signal*2 + 1, reghi);
io_apic_write(IOREDTBL + signal*2, reg.lo);
io_apic_write(IOREDTBL + signal*2 + 1, reg.hi);
}
 
void io_apic_disable_irqs(__u16 irqmask)
{
int i,pin;
__u32 reglo;
io_redirection_reg_t reg;
int i, pin;
for (i=0;i<16;i++) {
if ((irqmask>>i) & 1) {
382,11 → 384,11
* Mask the signal input in IO APIC if there is a
* mapping for the respective IRQ number.
*/
pin = mps_irq_to_pin(i);
pin = smp_irq_to_pin(i);
if (pin != -1) {
reglo = io_apic_read(IOREDTBL + pin*2);
reglo |= (1<<16);
io_apic_write(IOREDTBL + pin*2,reglo);
reg.lo = io_apic_read(IOREDTBL + pin*2);
reg.masked = true;
io_apic_write(IOREDTBL + pin*2, reg.lo);
}
}
395,8 → 397,8
 
void io_apic_enable_irqs(__u16 irqmask)
{
int i,pin;
__u32 reglo;
int i, pin;
io_redirection_reg_t reg;
for (i=0;i<16;i++) {
if ((irqmask>>i) & 1) {
404,11 → 406,11
* Unmask the signal input in IO APIC if there is a
* mapping for the respective IRQ number.
*/
pin = mps_irq_to_pin(i);
pin = smp_irq_to_pin(i);
if (pin != -1) {
reglo = io_apic_read(IOREDTBL + pin*2);
reglo &= ~(1<<16);
io_apic_write(IOREDTBL + pin*2,reglo);
reg.lo = io_apic_read(IOREDTBL + pin*2);
reg.masked = false;
io_apic_write(IOREDTBL + pin*2, reg.lo);
}
}
/kernel/trunk/arch/ia32/src/drivers/i8042.c
43,6 → 43,14
* It takes care of low-level keyboard functions.
*/
 
#define i8042_DATA 0x60
#define i8042_STATUS 0x64
 
/** Keyboard commands. */
#define KBD_ENABLE 0xf4
#define KBD_DISABLE 0xf5
#define KBD_ACK 0xfa
 
#define SPECIAL '?'
#define KEY_RELEASE 0x80
 
230,6 → 238,7
void i8042_init(void)
{
trap_register(VECTOR_KBD, i8042_interrupt);
trap_virtual_enable_irqs(1<<IRQ_KBD);
spinlock_initialize(&keylock);
chardev_initialize(&kbrd, &ops);
stdin = &kbrd;
245,7 → 254,7
__u8 x;
 
trap_virtual_eoi();
x = inb(0x60);
x = inb(i8042_DATA);
if (x & KEY_RELEASE)
key_released(x ^ KEY_RELEASE);
else