/SPARTAN/trunk/src/Makefile.config |
---|
22,7 → 22,7 |
#TEST_DIR=synch/rwlock1/ |
#TEST_DIR=synch/rwlock2/ |
#TEST_DIR=synch/rwlock3/ |
TEST_DIR=synch/rwlock4/ |
#TEST_DIR=synch/rwlock5/ |
#TEST_DIR=synch/rwlock4/ |
TEST_DIR=synch/rwlock5/ |
#TEST_DIR=synch/semaphore1/ |
#TEST_DIR=synch/semaphore2/ |
/SPARTAN/trunk/src/main/main.c |
---|
118,6 → 118,8 |
#ifdef __SMP__ |
mp_init(); /* Multiprocessor */ |
#endif /* __SMP__ */ |
printf("config.cpu_count=%d\n", config.cpu_count); |
cpu_init(); |
calibrate_delay_loop(); |
/SPARTAN/trunk/arch/ia32/include/smp/apic.h |
---|
98,6 → 98,13 |
#define L_APIC_IDShift 24 |
#define L_APIC_IDMask 0xf |
/* Local APIC Version Register */ |
#define LAVR (0x030/sizeof(__u32)) |
#define LAVR_Mask 0xff |
#define is_local_apic(x) (((x)&LAVR_Mask&0xf0)==0x1) |
#define is_82489DX_apic(x) ((((x)&LAVR_Mask&0xf0)==0x0)) |
#define is_local_xapic(x) (((x)&LAVR_Mask)==0x14) |
/* IO APIC */ |
#define IOREGSEL (0x00/sizeof(__u32)) |
#define IOWIN (0x10/sizeof(__u32)) |
/SPARTAN/trunk/arch/ia32/include/asm.h |
---|
58,4 → 58,7 |
extern void halt_cpu(void); |
extern void cpu_sleep(void); |
extern void write_dr0(__u32 v); |
extern __u32 read_dr0(void); |
#endif |
/SPARTAN/trunk/arch/ia32/include/cpu.h |
---|
34,7 → 34,7 |
#include <arch/pm.h> |
#ifdef __SMP__ |
#define CPU_ID_ARCH ((config.cpu_active>1)?l_apic_id():0) |
#define CPU_ID_ARCH (read_dr0()) |
#else |
#define CPU_ID_ARCH (0) |
#endif |
/SPARTAN/trunk/arch/ia32/src/ia32.c |
---|
49,6 → 49,8 |
{ |
pm_init(); |
write_dr0(config.cpu_active - 1); |
if (config.cpu_active == 1) { |
i8042_init(); /* a20 bit */ |
i8259_init(); /* PIC */ |
/SPARTAN/trunk/arch/ia32/src/smp/apic.c |
---|
103,8 → 103,6 |
} |
} |
/* |
* Configure the BSP's lapic. |
*/ |
183,7 → 181,7 |
l_apic[ICRhi] = hi; |
l_apic[ICRlo] = lo; |
/* |
* According to MP Specification, 20us should be enough to |
* deliver the IPI. |
195,7 → 193,7 |
lo = l_apic[ICRlo] & ICRloClear; |
if (lo & SEND_PENDING) |
printf("IPI is pending.\n"); |
l_apic[ICRlo] = lo | DLVRMODE_INIT | DESTMODE_PHYS | LEVEL_DEASSERT | SHORTHAND_DEST | TRGRMODE_LEVEL; |
/* |
203,18 → 201,19 |
*/ |
delay(10000); |
/* |
* MP specification says this should not be done for 82489DX-based |
* l_apic's. However, everything is ok as long as STARTUP IPI is ignored |
* by 8249DX. |
*/ |
for (i = 0; i < 2; i++) { |
lo = l_apic[ICRlo] & ICRloClear; |
lo |= ((__address) ap_boot) / 4096; /* calculate the reset vector */ |
l_apic[ICRlo] = lo | DLVRMODE_STUP | DESTMODE_PHYS | LEVEL_ASSERT | SHORTHAND_DEST | TRGRMODE_LEVEL; |
delay(200); |
if (!is_82489DX_apic(l_apic[LAVR])) { |
/* |
* If this is not 82489DX-based l_apic we must send two STARTUP IPI's. |
*/ |
for (i = 0; i<2; i++) { |
lo = l_apic[ICRlo] & ICRloClear; |
lo |= ((__address) ap_boot) / 4096; /* calculate the reset vector */ |
l_apic[ICRlo] = lo | DLVRMODE_STUP | DESTMODE_PHYS | LEVEL_ASSERT | SHORTHAND_DEST | TRGRMODE_LEVEL; |
delay(200); |
} |
} |
return apic_poll_errors(); |
} |
221,20 → 220,7 |
void l_apic_init(void) |
{ |
__u32 tmp, t1, t2; |
int cpu_id = config.cpu_active - 1; |
/* |
* Here we set local APIC ID's so that they match operating system's CPU ID's |
* This operation is dangerous as it is model specific. |
* TODO: some care should be taken. |
* NOTE: CPU may not be used to define APIC ID |
*/ |
if (l_apic_id() != cpu_id) { |
l_apic[L_APIC_ID] &= L_APIC_IDClear; |
l_apic[L_APIC_ID] |= (l_apic[L_APIC_ID]&L_APIC_IDClear)|((cpu_id)<<L_APIC_IDShift); |
} |
l_apic[LVT_Err] |= (1<<16); |
l_apic[LVT_LINT0] |= (1<<16); |
l_apic[LVT_LINT1] |= (1<<16); |
244,8 → 230,8 |
l_apic[TPR] &= TPRClear; |
if (CPU->arch.family >= 6) |
enable_l_apic_in_msr(); |
// if (CPU->arch.family >= 6) |
// enable_l_apic_in_msr(); |
tmp = l_apic[ICRlo] & ICRloClear; |
l_apic[ICRlo] = tmp | DLVRMODE_INIT | DESTMODE_PHYS | LEVEL_DEASSERT | SHORTHAND_INCL | TRGRMODE_LEVEL; |
/SPARTAN/trunk/arch/ia32/src/smp/mp.c |
---|
486,12 → 486,17 |
*/ |
if (pr[i].cpu_flags & (1<<0) == 0) |
continue; |
/* |
* The bootstrap processor is already up. |
*/ |
if (pr[i].cpu_flags & (1<<1)) |
continue; |
if (pr[i].l_apic_id == l_apic_id()) { |
printf("%X: bad processor entry #%d, will not send IPI to myself\n", &pr[i], i); |
continue; |
} |
/* |
* Prepare new GDT for CPU in question. |
501,7 → 506,7 |
memcopy(gdt, gdt_new, GDT_ITEMS*sizeof(struct descriptor)); |
gdtr.base = (__address) gdt_new; |
if (l_apic_send_init_ipi(pr[i].l_apic_id)) { |
/* |
* There may be just one AP being initialized at |
/SPARTAN/trunk/arch/ia32/src/asm.s |
---|
52,7 → 52,20 |
.global memsetb |
.global memsetw |
.global memcmp |
.global write_dr0 |
.global read_dr0 |
write_dr0: |
pushl %eax |
movl 8(%esp),%eax |
movl %eax,%dr0 |
popl %eax |
ret |
read_dr0: |
movl %dr0,%eax |
ret |
# |
# set priority level high |
cpu_priority_high: |
/SPARTAN/trunk/arch/ia32/src/interrupt.c |
---|
92,7 → 92,7 |
void syscall(__u8 n, __u32 stack[]) |
{ |
printf("cpu%d: syscall\n", CPU->id); |
thread_usleep(600); |
thread_usleep(1000000); |
} |
void tlb_shootdown_ipi(__u8 n, __u32 stack[]) |