⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcmb_smp.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 3 页
字号:
                        CYG_BYTE id;                        char bustype[7];                        HAL_READMEM_UINT8( entry+MPCT_ENTRY_BUS_ID, id );#if SHOW_DIAGNOSTICS                                            diag_printf("        Bus\n");                        diag_printf("                ID:                       %02x\n",id);#endif                        {                            int i;                            for( i = 0; i < 6; i++ )                            {                                HAL_READMEM_UINT8( entry+MPCT_ENTRY_BUS_TYPE_STRING+i, val8 );                                bustype[i] = val8;                            }                            bustype[i] = 0;#if SHOW_DIAGNOSTICS                            diag_printf("                Type:                     %s\n",&bustype[0]);#endif                                                    }                        if( streq( bustype, "ISA   " ) )                        {                            cyg_hal_isa_bus_id = id;                            for( i = 0; i < 16; i++ )                                cyg_hal_isa_bus_irq[i] = 100;                        }                        if( streq( bustype, "PCI   " ) )                        {                            cyg_hal_pci_bus_id = id;                        }                    }                    entry += MPCT_ENTRY_BUS_SIZE;                    break;                case MPCT_ENTRY_TYPE_IOAPIC:#if SHOW_DIAGNOSTICS                                        diag_printf("        I/O APIC\n");                    HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOAPIC_ID, val8 );                    diag_printf("                ID:                       %02x\n",val8);                    HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOAPIC_VER, val8 );                    diag_printf("                Version:                  %02x\n",val8);                    HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOAPIC_FLAGS, val8 );                    diag_printf("                Flags:                    %02x\n",val8);                    HAL_READMEM_UINT32( entry+MPCT_ENTRY_IOAPIC_ADDRESS, val32 );                    diag_printf("                Address:                  %08x\n",val32);#endif                    HAL_READMEM_UINT32( entry+MPCT_ENTRY_IOAPIC_ADDRESS, cyg_hal_smp_io_apic );                    entry += MPCT_ENTRY_IOAPIC_SIZE;                                    break;                case MPCT_ENTRY_TYPE_INTERRUPT_IO:                    {                        CYG_BYTE bus, irq, dst;                        HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOINT_SOURCE_BUS, bus );                        HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOINT_SOURCE_IRQ, irq );                        HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOINT_DEST_INT, dst );#if SHOW_DIAGNOSTICS                                            diag_printf("        I/O interrupt assignment\n");                        HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOINT_TYPE, val8 );                        diag_printf("                Type:                     %02x\n",val8);                        HAL_READMEM_UINT16( entry+MPCT_ENTRY_IOINT_TYPE, val16 );                        diag_printf("                Flags:                    %04x\n",val16);                        diag_printf("                Source bus:               %02x\n",bus);                        diag_printf("                Source IRQ:               %02x\n",irq);                        HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOINT_DEST_APIC, val8 );                        diag_printf("                Dest APIC:                %02x\n",val8);                        diag_printf("                Dest Interrupt:           %02x\n",dst);#endif                        if( bus == cyg_hal_isa_bus_id )                            cyg_hal_isa_bus_irq[irq] = dst;//                        if( bus == cyg_hal_pci_bus_id )//                            cyg_hal_pci_bus_irq[irq] = dst;                                        }                    entry += MPCT_ENTRY_IOINT_SIZE;                    break;                case MPCT_ENTRY_TYPE_INTERRUPT_LOCAL:#if SHOW_DIAGNOSTICS                                        diag_printf("        Local interrupt assignment\n");                    HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOINT_TYPE, val8 );                    diag_printf("                Type:                     %02x\n",val8);                    HAL_READMEM_UINT16( entry+MPCT_ENTRY_IOINT_TYPE, val16 );                    diag_printf("                Flags:                    %04x\n",val16);                    HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOINT_SOURCE_BUS, val8 );                    diag_printf("                Source bus:               %02x\n",val8);                    HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOINT_SOURCE_IRQ, val8 );                    diag_printf("                Source IRQ:               %02x\n",val8);                    HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOINT_DEST_APIC, val8 );                    diag_printf("                Dest APIC:                %02x\n",val8);                    HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOINT_DEST_INT, val8 );                    diag_printf("                Dest Interrupt:           %02x\n",val8);#endif                    entry += MPCT_ENTRY_LOCINT_SIZE;                    break;                                default:#if SHOW_DIAGNOSTICS                                        diag_printf("        MPCT Entry: unknown type %02x\n",type);#endif                                        entry += 8;                    break;                }                        }                }    }#if SHOW_DIAGNOSTICS    diag_printf("Exported configuration:\n");    diag_printf("        Local APIC: %08x\n", cyg_hal_smp_local_apic );    diag_printf("        I/O APIC:   %08x\n", cyg_hal_smp_io_apic );    diag_printf("        CPU count:  %d\n", cyg_hal_smp_cpu_count );    for( i = 0; i < cyg_hal_smp_cpu_count; i++ )    {        diag_printf("            CPU %d %sactive %s\n",i,                    ((cyg_hal_smp_cpu_flags[i]&1)?"":"in"),                    ((cyg_hal_smp_cpu_flags[i]&2)?"master":"slave")            );    }    diag_printf("        ISA IRQ map:\n");    for( i = 0; i < 16; i++ )    {        diag_printf("            IRQ %2d -> IOAPIC INT %2d\n",i,cyg_hal_isa_bus_irq[i]);    }    #endif            return 1;}/*------------------------------------------------------------------------*/// Init local APICstatic cyg_bool cyg_hal_smp_init_apic(void){        cyg_uint32 maxlvt;    cyg_uint32 val;    HAL_SMP_CPU_TYPE cpu;        HAL_APIC_READ(HAL_APIC_ID, val );    cpu = val>>24;    #if SHOW_DIAGNOSTICS    diag_printf("Local APIC: %08x\n",cyg_hal_smp_local_apic);    diag_printf("        ID:             %08x\n",val);#endif        // get max local vector table entry offset    HAL_APIC_READ(HAL_APIC_VER, maxlvt );#if SHOW_DIAGNOSTICS    diag_printf("        VERSION:        %08x\n",maxlvt);#endif    maxlvt >>= 16;    maxlvt &= 0xFF;    #if SHOW_DIAGNOSTICS    diag_printf("maxlvt = %d\n",maxlvt);#endif    // Start by ensuring that all interrupt sources are disabled. The    // following code ensures that this happens cleanly.        // Local timer vector    HAL_APIC_READ( HAL_APIC_LVT_TIMER, val );    val |= HAL_APIC_LVT_MASK ;    HAL_APIC_WRITE( HAL_APIC_LVT_TIMER, val );#if SHOW_DIAGNOSTICS    diag_printf("        APIC_LVT_TIMER: %08x\n",val);#endif        // Local interrupt vectors    HAL_APIC_READ( HAL_APIC_LVT_INT0, val );    val |= HAL_APIC_LVT_MASK ;    HAL_APIC_WRITE( HAL_APIC_LVT_INT0, val );#if SHOW_DIAGNOSTICS    diag_printf("        APIC_LVT_INT0:  %08x\n",val);#endif    HAL_APIC_READ( HAL_APIC_LVT_INT1, val );    val |= HAL_APIC_LVT_MASK ;    HAL_APIC_WRITE( HAL_APIC_LVT_INT1, val );#if SHOW_DIAGNOSTICS    diag_printf("        APIC_LVT_INT1:  %08x\n",val);#endif     if (maxlvt >= 3 )    {        HAL_APIC_READ( HAL_APIC_LVT_ERROR, val );        val |= HAL_APIC_LVT_MASK ;        HAL_APIC_WRITE( HAL_APIC_LVT_ERROR, val );#if SHOW_DIAGNOSTICS        diag_printf("        APIC_LVT_ERROR: %08x\n",val);#endif     }    if (maxlvt >= 4 )    {        HAL_APIC_READ( HAL_APIC_LVT_PC, val );        val |= HAL_APIC_LVT_MASK ;        HAL_APIC_WRITE( HAL_APIC_LVT_PC, val );#if SHOW_DIAGNOSTICS        diag_printf("        APIC_LVT_PC:    %08x\n",val);#endif     }    // Now initialize the local vector table.        HAL_APIC_WRITE( HAL_APIC_LVT_TIMER, HAL_APIC_LVT_MASK );    HAL_APIC_WRITE( HAL_APIC_LVT_INT0, HAL_APIC_LVT_MASK );    HAL_APIC_WRITE( HAL_APIC_LVT_INT1, HAL_APIC_LVT_MASK );    if( maxlvt >= 3 )        HAL_APIC_WRITE( HAL_APIC_LVT_ERROR, HAL_APIC_LVT_MASK );    if( maxlvt >= 4 )        HAL_APIC_WRITE( HAL_APIC_LVT_PC, HAL_APIC_LVT_MASK );    // Set up DFR to flat delivery mode.    HAL_APIC_WRITE( HAL_APIC_DFR, 0xffffffff );    // Set up logical destination id. We set bit 1<<cpuid in the LDR    // register.    HAL_APIC_READ( HAL_APIC_LDR, val );    val |= 1<<(cpu+24);    HAL_APIC_WRITE( HAL_APIC_LDR, val );    // Set TPR register to accept all.    HAL_APIC_WRITE( HAL_APIC_TPR, 0 );    // Enable APIC in SPIV    HAL_APIC_WRITE( HAL_APIC_SPIV, 0x00000100 );        if( cyg_hal_smp_cpu_flags[HAL_SMP_CPU_THIS()] & 2 )    {        // This is the boot CPU, switch its PIC into APIC mode        // Non-boot CPUs are already in APIC mode.                HAL_WRITE_UINT8( 0x22, 0x70 );        HAL_WRITE_UINT8( 0x23, 0x01 );    }        return 1;}/*------------------------------------------------------------------------*/// Initialize I/O APICstatic cyg_bool cyg_hal_smp_init_ioapic(void){    CYG_WORD32 val;    cyg_uint32 tabsize = 0;    int i;    HAL_SMP_CPU_TYPE cpu_this = HAL_SMP_CPU_THIS();    HAL_SPINLOCK_CLEAR( cyg_hal_ioapic_lock );    HAL_SPINLOCK_SPIN( cyg_hal_ioapic_lock );        HAL_IOAPIC_READ( HAL_IOAPIC_REG_APICVER, val );    tabsize = (val>>16)&0xFF;    // Set up ISA interrupts    for( i = 0; i < 16; i++ )    {        if( cyg_hal_isa_bus_irq[i] != 100 )        {            CYG_WORD32 tehi = 0, telo = 0x00010000;            tehi |= cpu_this<<24;            telo |= CYGNUM_HAL_ISR_MIN+i;                        HAL_IOAPIC_WRITE( HAL_IOAPIC_REG_REDIR_LO(cyg_hal_isa_bus_irq[i]), telo );            HAL_IOAPIC_WRITE( HAL_IOAPIC_REG_REDIR_HI(cyg_hal_isa_bus_irq[i]), tehi );        }    }    #if SHOW_DIAGNOSTICS        diag_printf("I/O APIC: %08x\n",cyg_hal_smp_io_apic);    HAL_IOAPIC_READ( HAL_IOAPIC_REG_APICID, val );    diag_printf("        ID: %08x\n",val);    HAL_IOAPIC_READ( HAL_IOAPIC_REG_APICVER, val );    diag_printf("        VER: %08x\n",val);    HAL_IOAPIC_READ( HAL_IOAPIC_REG_APICARB, val );    diag_printf("        ARB: %08x\n",val);    diag_printf("        Redirection Table:\n");    for( i = 0; i < tabsize; i++ )    {        CYG_WORD32 tehi, telo;        HAL_IOAPIC_READ( HAL_IOAPIC_REG_REDIR_LO(i), telo );        HAL_IOAPIC_READ( HAL_IOAPIC_REG_REDIR_HI(i), tehi );        diag_printf("            %02d: %08x %08x\n",i,tehi,telo);    }#endif    HAL_SPINLOCK_CLEAR( cyg_hal_ioapic_lock );    return 1;}/*------------------------------------------------------------------------*/static volatile CYG_WORD32 init_deasserted;__externC volatile CYG_WORD32 cyg_hal_smp_cpu_sync_flag[HAL_SMP_CPU_MAX];__externC volatile CYG_WORD32 cyg_hal_smp_cpu_sync[HAL_SMP_CPU_MAX];__externC volatile void (*cyg_hal_smp_cpu_entry[HAL_SMP_CPU_MAX])(void);__externC volatile CYG_WORD32 cyg_hal_smp_vsr_sync_flag;__externC volatile CYG_WORD32 cyg_hal_smp_cpu_running[HAL_SMP_CPU_MAX];/*------------------------------------------------------------------------*/__externC void cyg_hal_smp_start(void);__externC CYG_BYTE cyg_hal_slave_trampoline[];__externC CYG_BYTE cyg_hal_slave_trampoline_end[];#define HAL_SLAVE_START_ADDRESS 0x00002000__externC void cyg_hal_cpu_start( HAL_SMP_CPU_TYPE cpu ){#if 1    CYG_WORD32 icrlo, icrhi;    CYG_BYTE *p = &cyg_hal_slave_trampoline[0];    CYG_BYTE *q = (CYG_BYTE *)HAL_SLAVE_START_ADDRESS;    CYG_BYTE old_cmos;    int i;        // Copy the trampoline over...    do    {        *q++ = *p++;    } while( p != &cyg_hal_slave_trampoline_end[0]);    // Init synchronization spinlock to locked to halt slave CPU in    // cyg_hal_smp_startup().    init_deasserted = 0;        // We now have to execute the grungy and unpleasant AP startup    // sequence to get the cpu running. I'm sure that not all of this    // is strictly necessary, but it works and it is too much effort    // to work out the minimal subset.    // Write warm-reset code into CMOS RAM and write the address of    // the trampoline entry point into location 40:67.    HAL_READ_CMOS( 0x0f, old_cmos );    HAL_WRITE_CMOS( 0x0f, 0x0a );    HAL_WRITEMEM_UINT16( 0x467, HAL_SLAVE_START_ADDRESS & 0xf );    HAL_WRITEMEM_UINT16( 0x469, HAL_SLAVE_START_ADDRESS>>4 );            // Send an INIT interrupt to the dest CPU    icrhi = cpu<<24;    icrlo = 0x0000C500;    HAL_APIC_WRITE( HAL_APIC_ICR_HI, icrhi );    HAL_APIC_WRITE( HAL_APIC_ICR_LO, icrlo );    hal_delay_us( 10 * 1000 );  // Wait 10ms    // Wait for the ICR to become inactive    do {        HAL_APIC_READ( HAL_APIC_ICR_LO, icrlo );    } while( (icrlo & 0x00001000) != 0 );    // Now de-assert INIT    icrlo = 0x00008500;    HAL_APIC_WRITE( HAL_APIC_ICR_HI, icrhi );        HAL_APIC_WRITE( HAL_APIC_ICR_LO, icrlo );    init_deasserted = 1;    // Now we send two STARTUP IPIs    for( i = 0; i < 2; i++ )    {        icrlo = 0x00000600 | (HAL_SLAVE_START_ADDRESS>>12);        // Send the STARTUP IPI        HAL_APIC_WRITE( HAL_APIC_ICR_HI, icrhi );        HAL_APIC_WRITE( HAL_APIC_ICR_LO, icrlo );        hal_delay_us( 300 );                // Wait for the ICR to become inactive        do {            HAL_APIC_READ( HAL_APIC_ICR_LO, icrlo );        } while( (icrlo & 0x00001000) != 0 );        hal_delay_us( 300 );    }        HAL_WRITE_CMOS( 0x0f, old_cmos );//    PC_WRITE_SCREEN( PC_SCREEN_LINE(5)+0, '!' );        hal_delay_us( 300 );    //    PC_WRITE_SCREEN( PC_SCREEN_LINE(5)+1, '!' );    #endif    }/*------------------------------------------------------------------------*/__externC void cyg_hal_smp_start(void);__externC void cyg_hal_smp_startup(void);__externC void cyg_hal_cpu_release( HAL_SMP_CPU_TYPE cpu ){//    PC_WRITE_SCREEN( PC_SCREEN_LINE(13), '!' );            //    PC_WRITE_SCREEN_8( PC_SCREEN_LINE(13), cpu );        cyg_hal_smp_cpu_entry[cpu] = cyg_hal_smp_start;    while( cyg_hal_smp_cpu_entry[cpu] != 0 )    {//        PC_WRITE_SCREEN_32( PC_SCREEN_LINE(13)+4, cyg_hal_smp_cpu_entry[cpu] );        hal_delay_us( 100 );         continue;    }}/*------------------------------------------------------------------------*/__externC void cyg_hal_smp_startup(void)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -