diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 8ea0d1e6..d5f21089 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -36,6 +36,7 @@ extern "C" { #define APIC_ICR1 0x0300 // Interrupt Command Register [0-31] #define APIC_ICR2 0x0310 // Interrupt Command Register [32-63] #define APIC_LVT_T 0x0320 // LVT Timer Register +#define APIC_LVT_TSR 0x0330 // LVT Thermal Sensor Register #define APIC_LVT_PMC 0x0340 // LVT Performance Monitoring Counters Register #define APIC_LINT0 0x0350 // LVT LINT0 Register #define APIC_LINT1 0x0360 // LVT LINT1 Register diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index a8e1daaf..27294236 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -32,22 +32,6 @@ extern "C" { #endif #ifdef CONFIG_ROCKCREEK -/*#define SCC_PMEM_REGIONS 2 - -typedef struct { - uint32_t low; - uint32_t high; -} mem_region_t; - -typedef struct { - uint32_t pid; - uint32_t tile_frequency; // in MHz - uint32_t router_frequency; // in MHz - mem_region_t private_mem[SCC_PMEM_REGIONS]; -} scc_info_t; - -extern scc_info_t scc_info;*/ - int scc_init(void); #endif @@ -158,9 +142,6 @@ uint32_t read_eip(void); inline static int system_init(void) { -#ifdef CONFIG_ROCKCREEK - scc_init(); -#endif gdt_install(); apic_init(); #ifdef CONFIG_PCI diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index e134483b..206619ef 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -76,6 +76,7 @@ static inline void lapic_write(uint32_t addr, uint32_t value) * to avoid a pentium bug, we have to read a apic register * before we write a value to this register */ + //asm volatile ("cmpl (%0), %%eax; movl %1, (%0)" :: "r"(lapic+addr), "r"(value)); asm volatile ("movl (%%eax), %%edx; movl %%ebx, (%%eax)" :: "a"(lapic+addr), "b"(value) : "%edx"); //*((volatile uint32_t*) (lapic+addr)) = value; } @@ -109,6 +110,26 @@ uint32_t apic_cpu_id(void) return 0; } +static inline uint32_t apic_version(void) +{ + if (lapic) { + uint32_t i = *((uint32_t*) (lapic+APIC_VERSION)); + return i & 0xFF; + } + + return 0; +} + +static inline uint32_t apic_lvt_entries(void) +{ + if (lapic) { + uint32_t i = *((uint32_t*) (lapic+APIC_VERSION)); + return (i >> 16) & 0xFF; + } + + return 0; +} + int has_apic(void) { return (lapic != 0); @@ -276,10 +297,11 @@ int apic_calibration(void) ; diff = 0xFFFFFFFF - lapic_read(APIC_CCR); + diff = diff / 3; lapic_write(APIC_DCR, 0xB); // set it to 1 clock increments lapic_write(APIC_LVT_T, 0x2007B); // connects the timer to 123 and enables it - lapic_write(APIC_ICR, diff / 3); + lapic_write(APIC_ICR, diff); // Now, MetalSVM is able to use the APIC => Therefore, we disable the PIC outportb(0xA1, 0xFF); @@ -316,13 +338,14 @@ int apic_calibration(void) } while(ticks*TIMER_FREQ < 3*RC_REFCLOCKMHZ*1000000); diff = 0xFFFFFFFF - lapic_read(APIC_CCR); + diff = diff / 3; lapic_write(APIC_DCR, 0xB); // set it to 1 clock increments lapic_write(APIC_LVT_T, 0x2007B); // connects the timer to 123 and enables it - lapic_write(APIC_ICR, diff / 3); + lapic_write(APIC_ICR, diff); #endif - kprintf("APIC calibration determines an ICR of 0x%x\n", diff / 3); + kprintf("APIC calibration determines an ICR of 0x%x\n", diff); flags = irq_nested_disable(); #if MAX_CORES > 1 @@ -471,16 +494,20 @@ check_lapic: if (!lapic) goto out; - i = *((uint32_t*) (lapic+APIC_VERSION)); kprintf("Found APIC at 0x%x\n", lapic); - kprintf("Maximum LVT Entry: 0x%x\n", (i >> 16) & 0xFF); - kprintf("APIC Version: 0x%x\n", i & 0xFF); + kprintf("Maximum LVT Entry: 0x%x\n", apic_lvt_entries()); + kprintf("APIC Version: 0x%x\n", apic_version()); - if (!((i & 0xFF) >> 4)) { + if (!((apic_version() >> 4))) { kprintf("Currently, MetalSVM didn't supports extern APICs!\n"); goto out; } + if (apic_lvt_entries() < 3) { + kprintf("LVT is too small\n"); + goto out; + } + return 0; out: @@ -501,18 +528,25 @@ int apic_init(void) { int ret; uint8_t i; - + uint32_t v; + uint32_t max_lvt; + ret = apic_probe(); if (!ret) return ret; + max_lvt = apic_lvt_entries(); + + lapic_write(APIC_SVR, 0x17F); // enable the apic and connect to the idt entry 127 lapic_write(APIC_TPR, 0x00); // allow all interrupts lapic_write(APIC_LVT_T, 0x10000); // disable timer interrupt - lapic_write(APIC_LVT_PMC, 0x10000);// disable performance counter interrupt + if (max_lvt >= 4) + lapic_write(APIC_LVT_TSR, 0x10000); // disable thermal sensor interrupt + if (max_lvt >= 5) + lapic_write(APIC_LVT_PMC, 0x10000); // disable performance counter interrupt lapic_write(APIC_LINT0, 0x7C); // connect LINT0 to idt entry 124 lapic_write(APIC_LINT1, 0x7D); // connect LINT1 to idt entry 125 lapic_write(APIC_LVT_ER, 0x7E); // connect error to idt entry 126 - lapic_write(APIC_SVR, 0x17F); // enable the apic and connect to the idt entry 127 if (0) { //ioapic) { // enable timer interrupt diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index 6711bc47..114f2a66 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -30,6 +30,10 @@ #include #include #include +#ifdef CONFIG_ROCKCREEK +#include +#include +#endif /* * Virtual Memory Layout of the standard configuration @@ -675,6 +679,16 @@ int arch_paging_init(void) } #endif +#ifdef CONFIG_ROCKCREEK + // map SCC's configuration registers + viraddr = map_region(CRB_X0_Y0, CRB_X0_Y0, (CRB_OWN-CRB_X0_Y0+16*1024*1024)/PAGE_SIZE, MAP_KERNEL_SPACE|MAP_NO_CACHE); + kprintf("Map configuration registers at 0x%x\n", viraddr); + + // map SCC's configuration registers + viraddr = map_region(MPB_X0_Y0, MPB_X0_Y0, (MPB_OWN-MPB_X0_Y0+16*1024*1024)/PAGE_SIZE, MAP_KERNEL_SPACE); + kprintf("Map message passing buffers at 0x%x\n", viraddr); +#endif + /* enable paging */ write_cr3((uint32_t) &boot_pgd); i = read_cr0(); diff --git a/arch/x86/scc/RCCE_admin.c b/arch/x86/scc/RCCE_admin.c index 4316b216..8b4cbccc 100644 --- a/arch/x86/scc/RCCE_admin.c +++ b/arch/x86/scc/RCCE_admin.c @@ -51,7 +51,7 @@ // GLOBAL VARIABLES USED BY THE LIBRARY //...................................................................................... int RCCE_NP; // number of participating cores -int RC_REFCLOCKMHZ=533; // baseline CPU frequency (MHz) +int RC_REFCLOCKMHZ; // baseline CPU frequency (MHz) int RC_MY_COREID; // physical ID of calling core int RC_COREID[RCCE_MAXNP]; // array of physical core IDs for all participating // cores, sorted by rank @@ -232,7 +232,7 @@ int RCCE_init( unsigned int RCCE_SHM_BUFFER_offset ,result, rd_slot_nbr, wr_slot_nbr; #endif void *nothing = NULL; - + #ifdef SCC // Copperridge specific initialization... InitAPI(0); //fflush(0) diff --git a/arch/x86/scc/scc_init.c b/arch/x86/scc/scc_init.c index b3ef5cbd..0e3a2197 100644 --- a/arch/x86/scc/scc_init.c +++ b/arch/x86/scc/scc_init.c @@ -27,22 +27,23 @@ #ifdef CONFIG_ROCKCREEK -#define CCR_INTR_ACTIVE 0x02 - -//scc_info_t scc_info; -static char* rcce_argv[] = {"MetalSVM", "1", "533", "0"}; +/* + * Workaround to create a suitable argv array + */ +static char* argv_strings[] = {"MetalSVM", "1", "533", "0"}; +static char* argv[4] = {[0 ... 3] = NULL}; +static char** rcce_argv = argv; static int rcce_argc = 4; /* - * This is a modified MPB program, which is part of the RCCE distribution (src/mpb.c). + * This is the modified MPB program, which is part of the RCCE distribution (src/mpb.c). + * + * This function clears the local MPB and resets the test&set register. */ -static int scc_reset(void) +static int scc_clear(void) { int tmp, x, y, z, offset; - - // Initialize API - InitAPI(0); - + // Find out who I am... tmp=ReadConfigReg(CRB_OWN+MYTILEID); x=(tmp>>3) & 0x0f; // bits 06:03 @@ -69,14 +70,12 @@ static int scc_reset(void) int scc_init(void) { -// uint32_t x, y, z; -// uint32_t tmp; int num_ranks; - int my_rank; - - return 0; + int i, my_rank; kprintf("Initialize Rock Creek!\n"); + for(i=0; i>3) & 0x0f; // bits 06:03 - y=(tmp>>7) & 0x0f; // bits 10:07 - z=(tmp ) & 0x07; // bits 02:00 - scc_info.pid = PID(x, y, z); - kprintf("SCC Processor Id: %u (%u,%u,%u)\n", scc_info.pid, x, y, z); -*/ - /* default values for 16 GB system */ - /*scc_info.private_mem[0].low = 0x00; - scc_info.private_mem[0].high = 0x13FFFFFF; - scc_info.private_mem[1].low = 0xFF000000; - scc_info.private_mem[1].high = 0xFFFFFFFF; -*/ -// tmp = *((uint32_t*) (CRB_OWN+GCBCFG)); -// tmp = (tmp & 0x3FFFFFF) >> 7; - //kprintf("Own GCBCFG is 0x%x\n", tmp); -/* if (tmp == 0x70E1) { - scc_info.tile_frequency = 800; - scc_info.router_frequency = 1600; - } else { - scc_info.tile_frequency = 533; - scc_info.router_frequency = 800; - } -*/ - -/* kprintf("The default tile frequency is %u MHz\nThe default router frequency is %u MHz\n", - scc_info.tile_frequency, scc_info.router_frequency); - - if (z == 0) - tmp = *((uint32_t*) (CRB_OWN+GLCFG0)); - else if (z == 1) - tmp = *((uint32_t*) (CRB_OWN+GLCFG1)); - else - tmp = 0; -*/ - /* set INTR to enable maskable interrupts */ -/* tmp = tmp | CCR_INTR_ACTIVE; - if (z == 0) - *((uint32_t*) (CRB_OWN+GLCFG0)) = tmp; - else if (z == 1) - *((uint32_t*) (CRB_OWN+GLCFG1)) = tmp; -*/ - /* reload core configuration */ -/* tmp = 0; - if (z == 0) - tmp = *((uint32_t*) (CRB_OWN+GLCFG0)); - else if (z == 1) - tmp = *((uint32_t*) (CRB_OWN+GLCFG1)); - kprintf("Core Configuration %u: 0x%x\n", z, tmp); -*/ + //RCCE_barrier(&RCCE_COMM_WORLD); kputs("Now, the SCC is initialized!\n"); diff --git a/kernel/init.c b/kernel/init.c index 2fafb5b9..307d17f4 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -107,7 +107,7 @@ int STDCALL network_task(void* arg) } #endif -int network_shotdown(void) +int network_shutdown(void) { done = 1; diff --git a/tools/scc_setup.asm b/tools/scc_setup.asm index 2dd77af4..aacf105e 100644 --- a/tools/scc_setup.asm +++ b/tools/scc_setup.asm @@ -28,53 +28,11 @@ _start: msg db "?ello from MetalSVM bootloader!!",0 -enable_A20: - call a20wait - mov al,0xAD - out 0x64,al - - call a20wait - mov al,0xD0 - out 0x64,al - - call a20wait2 - in al,0x60 - push eax - - call a20wait - mov al,0xD1 - out 0x64,al - - call a20wait - pop eax - or al,2 - out 0x60,al - - call a20wait - mov al,0xAE - out 0x64,al - - call a20wait - ret - -a20wait: - in al,0x64 - test al,2 - jnz a20wait - ret - -a20wait2: - in al,0x64 - test al,1 - jz a20wait2 - ret - _realstart: ; IRQs are already disabled by reset_vector ; cli lgdt [gdtr] - ; call enable_A20 ; switch to protected mode by setting PE bit mov eax, cr0