Changeset c9b8c5c in mainline


Ignore:
Timestamp:
2005-04-24T21:59:33Z (20 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ad36bd6
Parents:
f07bba5
Message:

APIC changes and fixes.
Be more robust during MP configuration.

Do not use APIC ID as CPU_ID_ARCH anymore.
Changing APIC ID's is not a good idea.
Use dr0 register instead.

Files:
10 edited

Legend:

Unmodified
Added
Removed
  • arch/ia32/include/asm.h

    rf07bba5 rc9b8c5c  
    5959extern void cpu_sleep(void);
    6060
     61extern void write_dr0(__u32 v);
     62extern __u32 read_dr0(void);
     63
    6164#endif
  • arch/ia32/include/cpu.h

    rf07bba5 rc9b8c5c  
    3535
    3636#ifdef __SMP__
    37 #define CPU_ID_ARCH     ((config.cpu_active>1)?l_apic_id():0)
     37#define CPU_ID_ARCH     (read_dr0())
    3838#else
    3939#define CPU_ID_ARCH     (0)
  • arch/ia32/include/smp/apic.h

    rf07bba5 rc9b8c5c  
    9999#define L_APIC_IDMask   0xf
    100100
     101/* Local APIC Version Register */
     102#define LAVR            (0x030/sizeof(__u32))
     103#define LAVR_Mask       0xff
     104#define is_local_apic(x)        (((x)&LAVR_Mask&0xf0)==0x1)
     105#define is_82489DX_apic(x)      ((((x)&LAVR_Mask&0xf0)==0x0))
     106#define is_local_xapic(x)       (((x)&LAVR_Mask)==0x14)
     107
    101108/* IO APIC */
    102109#define IOREGSEL        (0x00/sizeof(__u32))
  • arch/ia32/src/asm.s

    rf07bba5 rc9b8c5c  
    5353.global memsetw
    5454.global memcmp
     55.global write_dr0
     56.global read_dr0
     57
     58write_dr0:
     59        pushl %eax
     60        movl 8(%esp),%eax
     61        movl %eax,%dr0
     62        popl %eax
     63        ret
     64       
     65read_dr0:
     66        movl %dr0,%eax
     67        ret
    5568
    5669#
  • arch/ia32/src/ia32.c

    rf07bba5 rc9b8c5c  
    5050        pm_init();
    5151
     52        write_dr0(config.cpu_active - 1);
     53
    5254        if (config.cpu_active == 1) {
    5355                i8042_init();   /* a20 bit */
  • arch/ia32/src/interrupt.c

    rf07bba5 rc9b8c5c  
    9393{
    9494        printf("cpu%d: syscall\n", CPU->id);
    95         thread_usleep(600);
     95        thread_usleep(1000000);
    9696}
    9797
  • arch/ia32/src/smp/apic.c

    rf07bba5 rc9b8c5c  
    104104        }
    105105
    106 
    107 
    108106        /*
    109107         * Configure the BSP's lapic.
     
    184182        l_apic[ICRhi] = hi;
    185183        l_apic[ICRlo] = lo;
    186        
     184
    187185        /*
    188186         * According to MP Specification, 20us should be enough to
     
    196194        if (lo & SEND_PENDING)
    197195                printf("IPI is pending.\n");
    198        
     196
    199197        l_apic[ICRlo] = lo | DLVRMODE_INIT | DESTMODE_PHYS | LEVEL_DEASSERT | SHORTHAND_DEST | TRGRMODE_LEVEL;
    200198
     
    204202        delay(10000);
    205203
    206         /*
    207          * MP specification says this should not be done for 82489DX-based
    208          * l_apic's. However, everything is ok as long as STARTUP IPI is ignored
    209          * by 8249DX.
    210          */
    211         for (i = 0; i < 2; i++) {
    212                 lo = l_apic[ICRlo] & ICRloClear;
    213                 lo |= ((__address) ap_boot) / 4096; /* calculate the reset vector */
    214                 l_apic[ICRlo] = lo | DLVRMODE_STUP | DESTMODE_PHYS | LEVEL_ASSERT | SHORTHAND_DEST |  TRGRMODE_LEVEL;
    215                 delay(200);
    216         }
     204        if (!is_82489DX_apic(l_apic[LAVR])) {
     205                /*
     206                 * If this is not 82489DX-based l_apic we must send two STARTUP IPI's.
     207                 */
     208                for (i = 0; i<2; i++) {
     209                        lo = l_apic[ICRlo] & ICRloClear;
     210                        lo |= ((__address) ap_boot) / 4096; /* calculate the reset vector */
     211                        l_apic[ICRlo] = lo | DLVRMODE_STUP | DESTMODE_PHYS | LEVEL_ASSERT | SHORTHAND_DEST |  TRGRMODE_LEVEL;
     212                        delay(200);
     213                }
     214        }
     215       
    217216       
    218217        return apic_poll_errors();
     
    222221{
    223222        __u32 tmp, t1, t2;
    224         int cpu_id = config.cpu_active - 1;
    225        
    226 
    227         /*
    228          * Here we set local APIC ID's so that they match operating system's CPU ID's
    229          * This operation is dangerous as it is model specific.
    230          * TODO: some care should be taken.
    231          * NOTE: CPU may not be used to define APIC ID
    232          */
    233         if (l_apic_id() != cpu_id) {
    234                 l_apic[L_APIC_ID] &= L_APIC_IDClear;
    235                 l_apic[L_APIC_ID] |= (l_apic[L_APIC_ID]&L_APIC_IDClear)|((cpu_id)<<L_APIC_IDShift);
    236         }
    237223
    238224        l_apic[LVT_Err] |= (1<<16);
     
    245231        l_apic[TPR] &= TPRClear;
    246232
    247         if (CPU->arch.family >= 6)
    248                 enable_l_apic_in_msr();
     233//      if (CPU->arch.family >= 6)
     234//              enable_l_apic_in_msr();
    249235       
    250236        tmp = l_apic[ICRlo] & ICRloClear;
  • arch/ia32/src/smp/mp.c

    rf07bba5 rc9b8c5c  
    487487                if (pr[i].cpu_flags & (1<<0) == 0)
    488488                        continue;
    489        
     489
    490490                /*
    491491                 * The bootstrap processor is already up.
     
    493493                if (pr[i].cpu_flags & (1<<1))
    494494                        continue;
     495
     496                if (pr[i].l_apic_id == l_apic_id()) {
     497                        printf("%X: bad processor entry #%d, will not send IPI to myself\n", &pr[i], i);
     498                        continue;
     499                }
    495500               
    496501                /*
     
    502507                memcopy(gdt, gdt_new, GDT_ITEMS*sizeof(struct descriptor));
    503508                gdtr.base = (__address) gdt_new;
    504                
     509
    505510                if (l_apic_send_init_ipi(pr[i].l_apic_id)) {
    506511                        /*
  • src/Makefile.config

    rf07bba5 rc9b8c5c  
    2323#TEST_DIR=synch/rwlock2/
    2424#TEST_DIR=synch/rwlock3/
    25 TEST_DIR=synch/rwlock4/
    26 #TEST_DIR=synch/rwlock5/
     25#TEST_DIR=synch/rwlock4/
     26TEST_DIR=synch/rwlock5/
    2727#TEST_DIR=synch/semaphore1/
    2828#TEST_DIR=synch/semaphore2/
  • src/main/main.c

    rf07bba5 rc9b8c5c  
    119119        mp_init();      /* Multiprocessor */
    120120        #endif /* __SMP__ */
     121       
     122        printf("config.cpu_count=%d\n", config.cpu_count);
    121123
    122124        cpu_init();
Note: See TracChangeset for help on using the changeset viewer.