Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 4 → Rev 5

/SPARTAN/trunk/include/mm/tlb.h
29,7 → 29,22
#ifndef __TLB_H__
#define __TLB_H__
 
extern void tlb_shutdown(void);
#ifdef __SMP__
extern void tlb_init(void);
extern void tlb_shutdown_start(void);
extern void tlb_shutdown_finalize(void);
extern void tlb_shutdown_ipi_recv(void);
#else
 
#define tlb_init() ;
#define tlb_shutdown_start() ;
#define tlb_shutdown_finalize() ;
#define tlb_shutdown_ipi_recv() ;
 
#endif /* __SMP__ */
 
/* Export TLB interface that each architecture must implement. */
extern void tlb_invalidate(int asid);
extern void tlb_shutdown_ipi_send(void);
 
#endif
/SPARTAN/trunk/src/main/main.c
46,6 → 46,7
 
#include <mm/frame.h>
#include <mm/page.h>
#include <mm/tlb.h>
#include <synch/waitq.h>
 
#include <arch.h>
110,6 → 111,7
heap_init(config.base + hardcoded_ktext_size + hardcoded_kdata_size, CONFIG_HEAP_SIZE);
frame_init();
page_init();
tlb_init();
 
#ifdef __SMP__
mp_init(); /* Multiprocessor */
/SPARTAN/trunk/src/mm/tlb.c
27,8 → 27,43
*/
 
#include <mm/tlb.h>
#include <synch/spinlock.h>
#include <typedefs.h>
#include <arch/atomic.h>
#include <config.h>
 
void tlb_shutdown(void)
#ifdef __SMP__
static spinlock_t tlblock;
static volatile int tlb_shutdown_cnt;
 
void tlb_init(void)
{
/* TODO: implement tlb_shutdown */
spinlock_initialize(&tlblock);
tlb_shutdown_cnt = 0;
}
 
/* must be called with interrupts disabled */
void tlb_shutdown_start(void)
{
spinlock_lock(&tlblock);
tlb_shutdown_ipi_send();
while (tlb_shutdown_cnt < config.cpu_active - 1)
;
tlb_shutdown_cnt = 0;
}
 
void tlb_shutdown_finalize(void)
{
spinlock_unlock(&tlblock);
}
 
void tlb_shutdown_ipi_recv(void)
{
atomic_inc((int *) &tlb_shutdown_cnt);
spinlock_lock(&tlblock);
spinlock_unlock(&tlblock);
tlb_invalidate(0); /* TODO: use valid ASID */
}
#endif /* __SMP__ */
/SPARTAN/trunk/src/mm/vm.c
29,6 → 29,7
#include <mm/vm.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <mm/tlb.h>
#include <arch/mm/page.h>
#include <arch/types.h>
#include <typedefs.h>
142,7 → 143,7
 
for (i=0; i<a->size; i++)
map_page_to_frame(a->address + i*PAGE_SIZE, 0, PAGE_NOT_PRESENT, 0);
spinlock_unlock(&a->lock);
cpu_priority_restore(pri);
}
168,6 → 169,9
pri_t pri;
pri = cpu_priority_high();
 
tlb_shutdown_start();
 
spinlock_lock(&m->lock);
 
for(l = m->vm_area_head.next; l != &m->vm_area_head; l = l->next)
174,5 → 178,9
vm_area_unmap(list_get_instance(l, vm_area_t, link));
 
spinlock_unlock(&m->lock);
 
tlb_invalidate(0);
tlb_shutdown_finalize();
 
cpu_priority_restore(pri);
}
/SPARTAN/trunk/arch/ia32/include/interrupt.h
59,6 → 59,7
#define VECTOR_KBD (IVT_IRQBASE+IRQ_KBD)
 
#define VECTOR_SYSCALL (IVT_FREEBASE+0)
#define VECTOR_TLB_SHUTDOWN (IVT_FREEBASE+1)
 
typedef void (* iroutine)(__u8 n, __u32 stack[]);
 
76,6 → 77,7
extern void gp_fault(__u8 n, __u32 stack[]);
extern void page_fault(__u8 n, __u32 stack[]);
extern void syscall(__u8 n, __u32 stack[]);
extern void tlb_shutdown_ipi(__u8 n, __u32 stack[]);
 
extern void trap_virtual_enable_irqs(__u16 irqmask);
extern void trap_virtual_disable_irqs(__u16 irqmask);
/SPARTAN/trunk/arch/ia32/include/apic.h
39,6 → 39,7
#define IPI_INIT 0
#define IPI_STARTUP 0
 
#define DLVRMODE_FIXED (0<<8)
#define DLVRMODE_INIT (5<<8)
#define DLVRMODE_STUP (6<<8)
#define DESTMODE_PHYS (0<<11)
56,7 → 57,7
/* Interrupt Command Register */
#define ICRlo (0x300/sizeof(__u32))
#define ICRhi (0x310/sizeof(__u32))
#define ICRloClear ((0xff<<0)|(1<<13)|(3<<16)|(0xfff<<20))
#define ICRloClear ((1<<13)|(3<<16)|(0xfff<<20))
#define ICRhiClear (0xffffff<<0)
 
/* End Of Interrupt */
115,6 → 116,7
 
extern void l_apic_init(void);
extern void l_apic_eoi(void);
extern int l_apic_broadcast_custom_ipi(__u8 vector);
extern int l_apic_send_init_ipi(__u8 apicid);
extern void l_apic_debug(void);
extern void l_apic_timer_interrupt(__u8 n, __u32 stack[]);
/SPARTAN/trunk/arch/ia32/src/ia32.c
56,6 → 56,10
i8254_init(); /* hard clock */
trap_register(VECTOR_SYSCALL, syscall);
#ifdef __SMP__
trap_register(VECTOR_TLB_SHUTDOWN, tlb_shutdown_ipi);
#endif /* __SMP__ */
}
}
 
/SPARTAN/trunk/arch/ia32/src/smp/apic.c
142,6 → 142,29
}
 
/*
* Send all CPUs excluding the->cpu IPI vector.
*/
int l_apic_broadcast_custom_ipi(__u8 vector)
{
__u32 lo;
 
/*
* Read the ICR register in and zero all non-reserved fields.
*/
lo = l_apic[ICRlo] & ICRloClear;
 
lo |= DLVRMODE_FIXED | DESTMODE_LOGIC | LEVEL_ASSERT | SHORTHAND_EXCL | TRGRMODE_LEVEL | vector;
l_apic[ICRlo] = lo;
 
lo = l_apic[ICRlo] & ICRloClear;
if (lo & SEND_PENDING)
printf("IPI is pending.\n");
 
return apic_poll_errors();
}
 
/*
* Universal Start-up Algorithm for bringing up the AP processors.
*/
int l_apic_send_init_ipi(__u8 apicid)
/SPARTAN/trunk/arch/ia32/src/mm/tlb.c
29,7 → 29,19
#include <mm/tlb.h>
#include <arch/asm.h>
 
#ifdef __SMP__
#include <arch/apic.h>
#include <arch/interrupt.h>
#endif /* __SMP__ */
 
void tlb_invalidate(int asid)
{
cpu_write_dba(cpu_read_dba());
}
 
#ifdef __SMP__
void tlb_shutdown_ipi_send(void)
{
(void) l_apic_broadcast_custom_ipi(VECTOR_TLB_SHUTDOWN);
}
#endif /* __SMP__ */
/SPARTAN/trunk/arch/ia32/src/mm/page.c
134,6 → 134,4
pt[pte].page_cache_disable = !(flags & PAGE_CACHEABLE);
pt[pte].uaccessible = (flags & PAGE_USER) != 0;
pt[pte].writeable = (flags & PAGE_WRITE) != 0;
tlb_invalidate(0);
}
/SPARTAN/trunk/arch/ia32/src/interrupt.c
33,6 → 33,7
#include <func.h>
#include <cpu.h>
#include <arch/asm.h>
#include <mm/tlb.h>
 
/*
* Interrupt and exception dispatching.
93,6 → 94,12
thread_sleep(1);
}
 
void tlb_shutdown_ipi(__u8 n, __u32 stack[])
{
trap_virtual_eoi();
tlb_shutdown_ipi_recv();
}
 
void trap_virtual_enable_irqs(__u16 irqmask)
{
if (enable_irqs_function)