diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h index 0a56e625..2ad513b5 100644 --- a/arch/x86/include/asm/page.h +++ b/arch/x86/include/asm/page.h @@ -60,6 +60,8 @@ #define PG_DIRTY (1 << _PAGE_BIT_DIRTY) /// Big page: 4MB (or 2MB) #define PG_PSE (1 << _PAGE_BIT_PSE) + +#define PG_MPE PG_PSE /// Global TLB entry (Pentium Pro and later) #define PG_GLOBAL (1 << _PAGE_BIT_GLOBAL) /// This virtual address range is reserved as marked diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 37e08089..74445239 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -168,9 +168,20 @@ static inline void write_cr3(uint32_t val) { asm volatile("mov %0, %%cr3" : : "r"(val)); } +static inline uint32_t read_cr4(void) { + uint32_t val; + asm volatile("mov %%cr4, %0" : "=r"(val)); + return val; +} + +static inline void write_cr4(uint32_t val) { + asm volatile("mov %0, %%cr4" : : "r"(val)); +} + /** @brief Flush a specific page entry in TLB * @param addr The (virtual) address of the page to flush */ + static inline void tlb_flush_one_page(uint32_t addr) { asm volatile("invlpg (%0)" : : "r"(addr) : "memory"); diff --git a/arch/x86/kernel/entry.asm b/arch/x86/kernel/entry.asm index a9d85364..f24b33dd 100644 --- a/arch/x86/kernel/entry.asm +++ b/arch/x86/kernel/entry.asm @@ -103,14 +103,7 @@ gdt_flush: flush2: ret -; Loads the IDT defined in '_idtp' into the processor. -; This is declared in C as 'extern void idt_load();' -global idt_load -extern idtp -idt_load: - lidt [idtp] - ret - +; determines the current instruction pointer (after the jmp) global read_eip read_eip: pop eax ; Get the return address diff --git a/arch/x86/kernel/idt.c b/arch/x86/kernel/idt.c index 4e76d847..db69a3d2 100644 --- a/arch/x86/kernel/idt.c +++ b/arch/x86/kernel/idt.c @@ -72,13 +72,13 @@ typedef struct { * "Unhandled Interrupt" exception */ static idt_entry_t idt[256] = {[0 ... 255] = {0, 0, 0, 0, 0}}; -idt_ptr_t idtp; /** @brief Loads the IDT * * The true definition lives in 'start.asm' */ -extern void idt_load(void); +//extern void idt_load(void); +static idt_ptr_t idtp; /* * Use this function to set an entry in the IDT. Alot simpler @@ -113,5 +113,5 @@ void idt_install(void) IDT_FLAG_PRESENT|IDT_FLAG_RING3|IDT_FLAG_32BIT|IDT_FLAG_TRAPGATE); /* Points the processor's internal register to the new IDT */ - idt_load(); + asm volatile("lidt %0" : : "m" (idtp)); } diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index 8103f4b1..683a5ced 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -348,6 +348,10 @@ size_t map_region(size_t viraddr, size_t phyaddr, uint32_t npages, uint32_t flag if (flags & MAP_NO_CACHE) pgt->entries[index] |= PG_PCD; +#ifdef CONFIG_ROCKCREEK + if (flags & MAP_MPE) + pgt->entries[index] |= PG_MPE; +#endif if (flags & MAP_USER_SPACE) atomic_int32_inc(&task->user_usage); @@ -695,8 +699,8 @@ int arch_paging_init(void) 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); + // map SCC's message passing buffers + viraddr = map_region(MPB_X0_Y0, MPB_X0_Y0, (MPB_OWN-MPB_X0_Y0+16*1024*1024)/PAGE_SIZE, MAP_KERNEL_SPACE|MAP_MPE); kprintf("Map message passing buffers at 0x%x\n", viraddr); #endif diff --git a/arch/x86/scc/scc_init.c b/arch/x86/scc/scc_init.c index 0e3a2197..02b6057f 100644 --- a/arch/x86/scc/scc_init.c +++ b/arch/x86/scc/scc_init.c @@ -27,6 +27,9 @@ #ifdef CONFIG_ROCKCREEK +/* PSE bit for Pentium+ equals MPE (message buffer enable) flag in RCK! So, use it to create _PAGE_MPB symbol... */ +#define _CR4_MPE 0x00000800 + /* * Workaround to create a suitable argv array */ @@ -83,6 +86,11 @@ int scc_init(void) num_ranks = RCCE_num_ues(); kprintf("Got rank %d of %d ranks\n", my_rank, num_ranks); + /* Enable Messagepassing in CR4 */ + uint32_t cr4 = read_cr4(); + cr4 = cr4 | _CR4_MPE; + write_cr4(cr4); + i = ReadConfigReg(CRB_OWN+GLCFG0); kprintf("glcfg0 0x%x\n", i); diff --git a/include/metalsvm/stdlib.h b/include/metalsvm/stdlib.h index 8119b486..fe824207 100644 --- a/include/metalsvm/stdlib.h +++ b/include/metalsvm/stdlib.h @@ -45,7 +45,9 @@ extern "C" { #define MAP_HEAP (1 << 5) #define MAP_CODE (1 << 6) #define MAP_READONLY (1 << 7) - +#ifdef CONFIG_ROCKCREEK +#define MAP_MPE (1 << 8) +#endif void NORETURN abort(void); /** @brief Kernel's memory allocator function. diff --git a/kernel/main.c b/kernel/main.c index d58d8ce7..8be29f22 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -89,6 +89,9 @@ int main(void) #endif multitasking_init(); mmu_init(); +#ifdef CONFIG_ROCKCREEK + scc_init(); +#endif initrd_init(); irq_enable();