Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2008 → Rev 2009

/trunk/kernel/arch/sparc64/include/interrupt.h
43,9 → 43,14
#define IVT_ITEMS 15
#define IVT_FIRST 1
 
/* This needs to be defined for inter-architecture API portability. */
#define VECTOR_TLB_SHOOTDOWN_IPI 0
#define IPI_TLB_SHOOTDOWN VECTOR_TLB_SHOOTDOWN_IPI
 
enum {
IPI_TLB_SHOOTDOWN = VECTOR_TLB_SHOOTDOWN_IPI,
IPI_DCACHE_SHOOTDOWN
};
 
struct istate {
uint64_t tnpc;
uint64_t tpc;
/trunk/kernel/arch/sparc64/include/mm/as.h
52,7 → 52,7
#ifdef CONFIG_TSB
tsb_entry_t *itsb;
tsb_entry_t *dtsb;
#endif
#endif /* CONFIG_TSB */
} as_arch_t;
 
#ifdef CONFIG_TSB
/trunk/kernel/arch/sparc64/include/mm/cache.h
35,6 → 35,16
#ifndef KERN_sparc64_CACHE_H_
#define KERN_sparc64_CACHE_H_
 
#ifdef CONFIG_SMP
extern void dcache_shootdown_start(void);
extern void dcache_shootdown_finalize(void);
extern void dcache_shootdown_ipi_recv(void);
#else /* CONFIG_SMP */
#define dcache_shootdown_start();
#define dcache_shootdown_finalize();
#define dcache_shootdown_ipi_recv();
#endif /* CONFIG_SMP */
 
extern void dcache_flush(void);
 
#endif
/trunk/kernel/arch/sparc64/include/cpu.h
55,6 → 55,7
uint32_t mid; /**< Processor ID as read from UPA_CONFIG. */
ver_reg_t ver;
uint32_t clock_frequency; /**< Processor frequency in MHz. */
int dcache_active; /**< When non-zero, the D-cache is not being shot down. */
};
#endif
/trunk/kernel/arch/sparc64/Makefile.inc
84,6 → 84,7
arch/$(ARCH)/src/dummy.s \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/cache.c \
arch/$(ARCH)/src/mm/cache_asm.S \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
/trunk/kernel/arch/sparc64/src/smp/ipi.c
38,6 → 38,7
#include <arch/asm.h>
#include <config.h>
#include <mm/tlb.h>
#include <arch/mm/cache.h>
#include <arch/interrupt.h>
#include <arch/trap/interrupt.h>
#include <arch/barrier.h>
120,6 → 121,9
case IPI_TLB_SHOOTDOWN:
func = tlb_shootdown_ipi_recv;
break;
case IPI_DCACHE_SHOOTDOWN:
func = dcache_shootdown_ipi_recv;
break;
default:
panic("Unknown IPI (%d).\n", ipi);
break;
/trunk/kernel/arch/sparc64/src/trap/interrupt.c
44,6 → 44,7
#include <print.h>
#include <arch.h>
#include <mm/tlb.h>
#include <arch/mm/cache.h>
#include <config.h>
#include <synch/spinlock.h>
 
90,6 → 91,8
#ifdef CONFIG_SMP
if (data0 == (uintptr_t) tlb_shootdown_ipi_recv) {
tlb_shootdown_ipi_recv();
} else if (data0 == (uintptr_t) dcache_shootdown_ipi_recv) {
dcache_shootdown_ipi_recv();
}
#endif
} else {
/trunk/kernel/arch/sparc64/src/cpu/cpu.c
92,6 → 92,11
dtlb_insert_mapping((uintptr_t) CPU->stack, KA2PA(CPU->stack), PAGESIZE_8K, true, true);
}
 
/*
* Set the D-cache active flag.
* Needed for the D-cache to work.
*/
CPU->arch.dcache_active = 1;
}
 
/** Read version information from the current processor. */
/trunk/kernel/arch/sparc64/src/mm/cache.S
File deleted
/trunk/kernel/arch/sparc64/src/mm/tlb.c
111,9 → 111,9
data.pfn = fr.pfn;
data.l = locked;
data.cp = cacheable;
#ifdef CONFIG_VIRT_IDX_CACHE
#ifdef CONFIG_VIRT_IDX_DCACHE
data.cv = cacheable;
#endif /* CONFIG_VIRT_IDX_CACHE */
#endif /* CONFIG_VIRT_IDX_DCACHE */
data.p = true;
data.w = true;
data.g = false;
148,9 → 148,9
data.pfn = fr.pfn;
data.l = false;
data.cp = t->c;
#ifdef CONFIG_VIRT_IDX_CACHE
#ifdef CONFIG_VIRT_IDX_DCACHE
data.cv = t->c;
#endif /* CONFIG_VIRT_IDX_CACHE */
#endif /* CONFIG_VIRT_IDX_DCACHE */
data.p = t->k; /* p like privileged */
data.w = ro ? false : t->w;
data.g = t->g;
184,9 → 184,6
data.pfn = fr.pfn;
data.l = false;
data.cp = t->c;
#ifdef CONFIG_VIRT_IDX_CACHE
data.cv = t->c;
#endif /* CONFIG_VIRT_IDX_CACHE */
data.p = t->k; /* p like privileged */
data.w = false;
data.g = t->g;
/trunk/kernel/arch/sparc64/src/mm/as.c
47,8 → 47,12
#include <mm/frame.h>
#include <bitops.h>
#include <macros.h>
#endif
#endif /* CONFIG_TSB */
 
#ifdef CONFIG_VIRT_IDX_DCACHE
#include <arch/mm/cache.h>
#endif /* CONFIG_VIRT_IDX_DCACHE */
 
/** Architecture dependent address space init. */
void as_arch_init(void)
{
158,6 → 162,23
tsb_base.base = ((uintptr_t) as->arch.dtsb) >> PAGE_WIDTH;
dtsb_base_write(tsb_base.value);
#endif
#ifdef CONFIG_VIRT_IDX_DCACHE
if (as->dcache_flush_on_install) {
/*
* Some mappings in this address space are illegal address
* aliases. Upon their creation, the flush_dcache_on_install
* flag was set.
*
* We are now obliged to flush the D-cache in order to guarantee
* that there will be at most one cache line for each address
* alias.
*
* This flush performs a cleanup after another address space in
* which the alias might have existed.
*/
dcache_flush();
}
#endif /* CONFIG_VIRT_IDX_DCACHE */
}
 
/** Perform sparc64-specific tasks when an address space is removed from the processor.
192,6 → 213,26
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, tsb);
}
#endif
#ifdef CONFIG_VIRT_IDX_DCACHE
if (as->dcache_flush_on_deinstall) {
/*
* Some mappings in this address space are illegal address
* aliases. Upon their creation, the flush_dcache_on_deinstall
* flag was set.
*
* We are now obliged to flush the D-cache in order to guarantee
* that there will be at most one cache line for each address
* alias.
*
* This flush performs a cleanup after this address space. It is
* necessary because other address spaces that contain the same
* alias are not necessarily aware of the need to carry out the
* cache flush. The only address spaces that are aware of it are
* those that created the illegal alias.
*/
dcache_flush();
}
#endif /* CONFIG_VIRT_IDX_DCACHE */
}
 
/** @}
/trunk/kernel/arch/sparc64/src/mm/cache.c
0,0 → 1,98
/*
* Copyright (C) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64mm
* @{
*/
/**
* @file
* @brief D-cache shootdown algorithm.
*/
 
#include <arch/mm/cache.h>
 
#ifdef CONFIG_SMP
 
#include <smp/ipi.h>
#include <arch/interrupt.h>
#include <synch/spinlock.h>
#include <arch.h>
#include <debug.h>
 
/**
* This spinlock is used by the processors to synchronize during the D-cache
* shootdown.
*/
SPINLOCK_INITIALIZE(dcachelock);
 
/** Initialize the D-cache shootdown sequence.
*
* Start the shootdown sequence by sending out an IPI and wait until all
* processors spin on the dcachelock spinlock.
*/
void dcache_shootdown_start(void)
{
int i;
 
CPU->arch.dcache_active = 0;
spinlock_lock(&dcachelock);
 
ipi_broadcast(IPI_DCACHE_SHOOTDOWN);
 
busy_wait:
for (i = 0; i < config.cpu_count; i++)
if (cpus[i].arch.dcache_active)
goto busy_wait;
}
 
/** Finish the D-cache shootdown sequence. */
void dcache_shootdown_finalize(void)
{
spinlock_unlock(&dcachelock);
CPU->arch.dcache_active = 1;
}
 
/** Process the D-cache shootdown IPI. */
void dcache_shootdown_ipi_recv(void)
{
ASSERT(CPU);
 
CPU->arch.dcache_active = 0;
spinlock_lock(&dcachelock);
spinlock_unlock(&dcachelock);
dcache_flush();
 
CPU->arch.dcache_active = 1;
}
 
#endif /* CONFIG_SMP */
 
/** @}
*/
 
/trunk/kernel/arch/sparc64/src/mm/cache_asm.S
0,0 → 1,44
/*
* Copyright (C) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include <arch/arch.h>
 
#define DCACHE_SIZE (16*1024)
#define DCACHE_LINE_SIZE 64
 
.global dcache_flush
dcache_flush:
set (DCACHE_SIZE - DCACHE_LINE_SIZE), %g1
stxa %g0, [%g1] ASI_DCACHE_TAG
0: membar #Sync
subcc %g1, DCACHE_LINE_SIZE, %g1
bnz,pt %xcc, 0b
stxa %g0, [%g1] ASI_DCACHE_TAG
retl
membar #Sync
 
/trunk/kernel/arch/sparc64/src/mm/tsb.c
100,9 → 100,6
tsb->data.size = PAGESIZE_8K;
tsb->data.pfn = t->frame >> FRAME_WIDTH;
tsb->data.cp = t->c;
#ifdef CONFIG_VIRT_IDX_CACHE
tsb->data.cv = t->c;
#endif /* CONFIG_VIRT_IDX_CACHE */
tsb->data.p = t->k; /* p as privileged */
tsb->data.v = t->p;
142,9 → 139,9
tsb->data.size = PAGESIZE_8K;
tsb->data.pfn = t->frame >> FRAME_WIDTH;
tsb->data.cp = t->c;
#ifdef CONFIG_VIRT_IDX_CACHE
#ifdef CONFIG_VIRT_IDX_DCACHE
tsb->data.cv = t->c;
#endif /* CONFIG_VIRT_IDX_CACHE */
#endif /* CONFIG_VIRT_IDX_DCACHE */
tsb->data.p = t->k; /* p as privileged */
tsb->data.w = ro ? false : t->w;
tsb->data.v = t->p;
/trunk/kernel/arch/sparc64/src/start.S
122,11 → 122,11
stxa %g1, [VA_DMMU_TAG_ACCESS] %asi
membar #Sync
 
#ifdef CONFIG_VIRT_IDX_CACHE
#ifdef CONFIG_VIRT_IDX_DCACHE
#define TTE_LOW_DATA(imm) (TTE_CP | TTE_CV | TTE_P | LMA | (imm))
#else /* CONFIG_VIRT_IDX_CACHE */
#else /* CONFIG_VIRT_IDX_DCACHE */
#define TTE_LOW_DATA(imm) (TTE_CP | TTE_P | LMA | (imm))
#endif /* CONFIG_VIRT_IDX_CACHE */
#endif /* CONFIG_VIRT_IDX_DCACHE */
 
#define SET_TLB_DATA(r1, r2, imm) \
set TTE_LOW_DATA(imm), %r1; \
360,8 → 360,8
*/
.global kernel_8k_tlb_data_template
kernel_8k_tlb_data_template:
#ifdef CONFIG_VIRT_IDX_CACHE
#ifdef CONFIG_VIRT_IDX_DCACHE
.quad ((1 << TTE_V_SHIFT) | (PAGESIZE_8K << TTE_SIZE_SHIFT) | TTE_CP | TTE_CV | TTE_P | TTE_W)
#else /* CONFIG_VIRT_IDX_CACHE */
#else /* CONFIG_VIRT_IDX_DCACHE */
.quad ((1 << TTE_V_SHIFT) | (PAGESIZE_8K << TTE_SIZE_SHIFT) | TTE_CP | TTE_P | TTE_W)
#endif /* CONFIG_VIRT_IDX_CACHE */
#endif /* CONFIG_VIRT_IDX_DCACHE */