Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 396 → Rev 395

/SPARTAN/trunk/arch/mips32/src/mm/tlb.c
37,7 → 37,6
#include <symtab.h>
#include <synch/spinlock.h>
#include <print.h>
#include <debug.h>
 
static void tlb_refill_fail(struct exception_regdump *pstate);
static void tlb_invalid_fail(struct exception_regdump *pstate);
44,7 → 43,7
static void tlb_modified_fail(struct exception_regdump *pstate);
 
static pte_t *find_mapping_and_check(__address badvaddr);
static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn);
static void prepare_entry_lo(struct entry_lo *lo, bool g, bool v, bool d, int c, __address pfn);
 
/** Initialize TLB
*
83,7 → 82,7
*/
void tlb_refill(struct exception_regdump *pstate)
{
entry_lo_t lo;
struct entry_lo lo;
__address badvaddr;
pte_t *pte;
105,12 → 104,12
* New entry is to be inserted into TLB
*/
if ((badvaddr/PAGE_SIZE) % 2 == 0) {
cp0_entry_lo0_write(lo.value);
cp0_entry_lo0_write(*((__u32 *) &lo));
cp0_entry_lo1_write(0);
}
else {
cp0_entry_lo0_write(0);
cp0_entry_lo1_write(lo.value);
cp0_entry_lo1_write(*((__u32 *) &lo));
}
tlbwr();
 
130,9 → 129,9
*/
void tlb_invalid(struct exception_regdump *pstate)
{
tlb_index_t index;
struct index index;
__address badvaddr;
entry_lo_t lo;
struct entry_lo lo;
pte_t *pte;
 
badvaddr = cp0_badvaddr_read();
141,7 → 140,7
* Locate the faulting entry in TLB.
*/
tlbp();
index.value = cp0_index_read();
*((__u32 *) &index) = cp0_index_read();
spinlock_lock(&VM->lock);
148,10 → 147,8
/*
* Fail if the entry is not in TLB.
*/
if (index.p) {
printf("TLB entry not found.\n");
if (index.p)
goto fail;
}
 
pte = find_mapping_and_check(badvaddr);
if (!pte)
173,9 → 170,9
* The entry is to be updated in TLB.
*/
if ((badvaddr/PAGE_SIZE) % 2 == 0)
cp0_entry_lo0_write(lo.value);
cp0_entry_lo0_write(*((__u32 *) &lo));
else
cp0_entry_lo1_write(lo.value);
cp0_entry_lo1_write(*((__u32 *) &lo));
tlbwi();
 
spinlock_unlock(&VM->lock);
192,11 → 189,12
*
* @param pstate Interrupted register context.
*/
 
void tlb_modified(struct exception_regdump *pstate)
{
tlb_index_t index;
struct index index;
__address badvaddr;
entry_lo_t lo;
struct entry_lo lo;
pte_t *pte;
 
badvaddr = cp0_badvaddr_read();
205,7 → 203,7
* Locate the faulting entry in TLB.
*/
tlbp();
index.value = cp0_index_read();
*((__u32 *) &index) = cp0_index_read();
spinlock_lock(&VM->lock);
212,10 → 210,8
/*
* Fail if the entry is not in TLB.
*/
if (index.p) {
printf("TLB entry not found.\n");
if (index.p)
goto fail;
}
 
pte = find_mapping_and_check(badvaddr);
if (!pte)
244,9 → 240,9
* The entry is to be updated in TLB.
*/
if ((badvaddr/PAGE_SIZE) % 2 == 0)
cp0_entry_lo0_write(lo.value);
cp0_entry_lo0_write(*((__u32 *) &lo));
else
cp0_entry_lo1_write(lo.value);
cp0_entry_lo1_write(*((__u32 *) &lo));
tlbwi();
 
spinlock_unlock(&VM->lock);
292,35 → 288,14
panic("%X: TLB Modified Exception at %X(%s)\n", cp0_badvaddr_read(), pstate->epc, symbol);
}
 
/** Invalidate TLB entries with specified ASID
*
* Invalidate TLB entries with specified ASID.
*
* @param asid ASID.
*/
void tlb_invalidate(asid_t asid)
 
void tlb_invalidate(int asid)
{
entry_hi_t hi;
pri_t pri;
int i;
ASSERT(asid != ASID_INVALID);
 
pri = cpu_priority_high();
for (i = 0; i < TLB_SIZE; i++) {
cp0_index_write(i);
tlbr();
hi.value = cp0_entry_hi_read();
if (hi.asid == asid) {
cp0_pagemask_write(TLB_PAGE_MASK_16K);
cp0_entry_hi_write(0);
cp0_entry_lo0_write(0);
cp0_entry_lo1_write(0);
tlbwi();
}
}
// TODO
cpu_priority_restore(pri);
}
336,40 → 311,34
*/
pte_t *find_mapping_and_check(__address badvaddr)
{
entry_hi_t hi;
struct entry_hi hi;
pte_t *pte;
 
hi.value = cp0_entry_hi_read();
*((__u32 *) &hi) = cp0_entry_hi_read();
 
/*
* Handler cannot succeed if the ASIDs don't match.
*/
if (hi.asid != VM->asid) {
printf("EntryHi.asid=%d, VM->asid=%d\n", hi.asid, VM->asid);
if (hi.asid != VM->asid)
return NULL;
}
/*
* Handler cannot succeed if badvaddr has no mapping.
*/
pte = find_mapping(badvaddr, 0);
if (!pte) {
printf("No such mapping.\n");
if (!pte)
return NULL;
}
 
/*
* Handler cannot succeed if the mapping is marked as invalid.
*/
if (!pte->v) {
printf("Invalid mapping.\n");
if (!pte->v)
return NULL;
}
 
return pte;
}
 
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn)
void prepare_entry_lo(struct entry_lo *lo, bool g, bool v, bool d, int c, __address pfn)
{
lo->g = g;
lo->v = v;
/SPARTAN/trunk/arch/mips32/src/mm/asid.c
1,6 → 1,5
/*
* Copyright (C) 2005 Martin Decky
* Copyright (C) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
31,8 → 30,9
#include <synch/spinlock.h>
#include <arch.h>
#include <debug.h>
#include <typedefs.h>
 
#define ASIDS 256
 
static spinlock_t asid_usage_lock;
static count_t asid_usage[ASIDS]; /**< Usage tracking array for ASIDs */
 
53,7 → 53,7
pri = cpu_priority_high();
spinlock_lock(&asid_usage_lock);
for (i = ASID_START, j = ASID_START; i < ASIDS; i++) {
for (i=0, j = 0; (i<ASIDS); i++) {
if (asid_usage[i] < min) {
j = i;
min = asid_usage[i];
62,7 → 62,7
}
}
 
asid_usage[j]++;
asid_usage[i]++;
 
spinlock_unlock(&asid_usage_lock);
cpu_priority_restore(pri);
83,8 → 83,6
pri = cpu_priority_high();
spinlock_lock(&asid_usage_lock);
 
ASSERT(asid != ASID_INVALID);
ASSERT(asid_usage[asid] > 0);
asid_usage[asid]--;
 
91,30 → 89,3
spinlock_unlock(&asid_usage_lock);
cpu_priority_restore(pri);
}
 
/** Find out whether ASID is used by more address spaces
*
* Find out whether ASID is used by more address spaces.
*
* @param asid ASID in question.
*
* @return True if 'asid' is used by more address spaces, false otherwise.
*/
bool asid_has_conflicts(asid_t asid)
{
bool has_conflicts = false;
pri_t pri;
 
ASSERT(asid != ASID_INVALID);
 
pri = cpu_priority_high();
spinlock_lock(&asid_usage_lock);
 
if (asid_usage[asid] > 1)
has_conflicts = true;
 
spinlock_unlock(&asid_usage_lock);
cpu_priority_restore(pri);
 
return has_conflicts;
}
/SPARTAN/trunk/arch/mips32/src/mm/vm.c
31,6 → 31,7
#include <mm/vm.h>
#include <arch/cp0.h>
#include <arch.h>
#include <print.h>
 
/** Install ASID of the current VM
*
40,10 → 41,10
*/
void vm_install_arch(vm_t *vm)
{
entry_hi_t hi;
struct entry_hi hi;
pri_t pri;
hi.value = cp0_entry_hi_read();
*((__u32 *) &hi) = cp0_entry_hi_read();
 
pri = cpu_priority_high();
spinlock_lock(&vm->lock);