Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 40176
b: refs/heads/master
c: aa026ed
h: refs/heads/master
v: v3
  • Loading branch information
Andi Kleen authored and Andi Kleen committed Oct 21, 2006
1 parent d7b5571 commit aef5885
Show file tree
Hide file tree
Showing 10 changed files with 37 additions and 199 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f8829caee311207afbc882794bdc5aa0db5caf33
refs/heads/master: aa026ede513b7d672fa7d9106b2f2a475455dcf2
10 changes: 5 additions & 5 deletions trunk/Documentation/mips/time.README
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ the following functions or values:
a) board_time_init - a function pointer. Invoked at the beginnig of
time_init(). It is optional.
1. (optional) set up RTC routines
2. (optional) calibrate and set the mips_hpt_frequency
2. (optional) calibrate and set the mips_counter_frequency

b) plat_timer_setup - a function pointer. Invoked at the end of time_init()
1. (optional) over-ride any decisions made in time_init()
Expand All @@ -72,7 +72,7 @@ the following functions or values:

c) (optional) board-specific RTC routines.

d) (optional) mips_hpt_frequency - It must be definied if the board
d) (optional) mips_counter_frequency - It must be definied if the board
is using CPU counter for timer interrupt or it is using fixed rate
gettimeoffset().

Expand Down Expand Up @@ -104,7 +104,7 @@ Step 1: decide how you like to implement the time services.
or use an exnternal timer?

In order to use CPU counter register as the timer interrupt source, you
must know the counter speed (mips_hpt_frequency). It is usually the
must know the counter speed (mips_counter_frequency). It is usually the
same as the CPU speed or an integral divisor of it.

d) decide on whether you want to use high-level or low-level timer
Expand All @@ -121,8 +121,8 @@ Step 3: implement rtc routines, board_time_init() and plat_timer_setup()
if needed.

board_time_init() -
a) (optional) set up RTC routines,
b) (optional) calibrate and set the mips_hpt_frequency
a) (optional) set up RTC routines,
b) (optional) calibrate and set the mips_counter_frequency
(only needed if you intended to use fixed_rate_gettimeoffset
or use cpu counter as timer interrupt source)

Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/mips/mips-boards/generic/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id)
}

/*
* Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect
* Estimate CPU frequency. Sets mips_counter_frequency as a side-effect
*/
static unsigned int __init estimate_cpu_frequency(void)
{
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/mips/mips-boards/sim/sim_time.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id)


/*
* Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect
* Estimate CPU frequency. Sets mips_counter_frequency as a side-effect
*/
static unsigned int __init estimate_cpu_frequency(void)
{
Expand Down
167 changes: 7 additions & 160 deletions trunk/arch/mips/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,34 +30,11 @@
#include <asm/cachectl.h>
#include <asm/cpu.h>
#include <asm/dma.h>
#include <asm/kmap_types.h>
#include <asm/mmu_context.h>
#include <asm/sections.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/tlb.h>
#include <asm/fixmap.h>

/* Atomicity and interruptability */
#ifdef CONFIG_MIPS_MT_SMTC

#include <asm/mipsmtregs.h>

#define ENTER_CRITICAL(flags) \
{ \
unsigned int mvpflags; \
local_irq_save(flags);\
mvpflags = dvpe()
#define EXIT_CRITICAL(flags) \
evpe(mvpflags); \
local_irq_restore(flags); \
}
#else

#define ENTER_CRITICAL(flags) local_irq_save(flags)
#define EXIT_CRITICAL(flags) local_irq_restore(flags)

#endif /* CONFIG_MIPS_MT_SMTC */

DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);

Expand Down Expand Up @@ -103,142 +80,13 @@ unsigned long setup_zero_pages(void)
return 1UL << order;
}

/*
* These are almost like kmap_atomic / kunmap_atmic except they take an
* additional address argument as the hint.
*/

#define kmap_get_fixmap_pte(vaddr) \
pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))

#ifdef CONFIG_MIPS_MT_SMTC
static pte_t *kmap_coherent_pte;
static void __init kmap_coherent_init(void)
{
unsigned long vaddr;

/* cache the first coherent kmap pte */
vaddr = __fix_to_virt(FIX_CMAP_BEGIN);
kmap_coherent_pte = kmap_get_fixmap_pte(vaddr);
}
#else
static inline void kmap_coherent_init(void) {}
#endif

static inline void *kmap_coherent(struct page *page, unsigned long addr)
{
enum fixed_addresses idx;
unsigned long vaddr, flags, entrylo;
unsigned long old_ctx;
pte_t pte;
int tlbidx;

inc_preempt_count();
idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1);
#ifdef CONFIG_MIPS_MT_SMTC
idx += FIX_N_COLOURS * smp_processor_id();
#endif
vaddr = __fix_to_virt(FIX_CMAP_END - idx);
pte = mk_pte(page, PAGE_KERNEL);
#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
entrylo = pte.pte_high;
#else
entrylo = pte_val(pte) >> 6;
#endif

ENTER_CRITICAL(flags);
old_ctx = read_c0_entryhi();
write_c0_entryhi(vaddr & (PAGE_MASK << 1));
write_c0_entrylo0(entrylo);
write_c0_entrylo1(entrylo);
#ifdef CONFIG_MIPS_MT_SMTC
set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte);
/* preload TLB instead of local_flush_tlb_one() */
mtc0_tlbw_hazard();
tlb_probe();
tlb_probe_hazard();
tlbidx = read_c0_index();
mtc0_tlbw_hazard();
if (tlbidx < 0)
tlb_write_random();
else
tlb_write_indexed();
#else
tlbidx = read_c0_wired();
write_c0_wired(tlbidx + 1);
write_c0_index(tlbidx);
mtc0_tlbw_hazard();
tlb_write_indexed();
#endif
tlbw_use_hazard();
write_c0_entryhi(old_ctx);
EXIT_CRITICAL(flags);

return (void*) vaddr;
}

#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))

static inline void kunmap_coherent(struct page *page)
{
#ifndef CONFIG_MIPS_MT_SMTC
unsigned int wired;
unsigned long flags, old_ctx;

ENTER_CRITICAL(flags);
old_ctx = read_c0_entryhi();
wired = read_c0_wired() - 1;
write_c0_wired(wired);
write_c0_index(wired);
write_c0_entryhi(UNIQUE_ENTRYHI(wired));
write_c0_entrylo0(0);
write_c0_entrylo1(0);
mtc0_tlbw_hazard();
tlb_write_indexed();
tlbw_use_hazard();
write_c0_entryhi(old_ctx);
EXIT_CRITICAL(flags);
#endif
dec_preempt_count();
preempt_check_resched();
}

void copy_to_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len)
{
if (cpu_has_dc_aliases) {
void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(vto, src, len);
kunmap_coherent(page);
} else
memcpy(dst, src, len);
if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc)
flush_cache_page(vma, vaddr, page_to_pfn(page));
}

EXPORT_SYMBOL(copy_to_user_page);

void copy_from_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len)
{
if (cpu_has_dc_aliases) {
void *vfrom =
kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(dst, vfrom, len);
kunmap_coherent(page);
} else
memcpy(dst, src, len);
}

EXPORT_SYMBOL(copy_from_user_page);


#ifdef CONFIG_HIGHMEM
pte_t *kmap_pte;
pgprot_t kmap_prot;

#define kmap_get_fixmap_pte(vaddr) \
pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))

static void __init kmap_init(void)
{
unsigned long kmap_vstart;
Expand All @@ -249,12 +97,11 @@ static void __init kmap_init(void)

kmap_prot = PAGE_KERNEL;
}
#endif /* CONFIG_HIGHMEM */

#ifdef CONFIG_32BIT
void __init fixrange_init(unsigned long start, unsigned long end,
pgd_t *pgd_base)
{
#if defined(CONFIG_HIGHMEM) || defined(CONFIG_MIPS_MT_SMTC)
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
Expand All @@ -275,7 +122,7 @@ void __init fixrange_init(unsigned long start, unsigned long end,
for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
if (pmd_none(*pmd)) {
pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
set_pmd(pmd, __pmd((unsigned long)pte));
set_pmd(pmd, __pmd(pte));
if (pte != pte_offset_kernel(pmd, 0))
BUG();
}
Expand All @@ -285,8 +132,9 @@ void __init fixrange_init(unsigned long start, unsigned long end,
}
j = 0;
}
#endif
}
#endif /* CONFIG_32BIT */
#endif /* CONFIG_HIGHMEM */

#ifndef CONFIG_NEED_MULTIPLE_NODES
extern void pagetable_init(void);
Expand Down Expand Up @@ -327,7 +175,6 @@ void __init paging_init(void)
#ifdef CONFIG_HIGHMEM
kmap_init();
#endif
kmap_coherent_init();

max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
low = max_low_pfn;
Expand Down
7 changes: 3 additions & 4 deletions trunk/arch/mips/mm/pgtable-32.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,9 @@ void pgd_init(unsigned long page)

void __init pagetable_init(void)
{
unsigned long vaddr;
pgd_t *pgd_base;
#ifdef CONFIG_HIGHMEM
pgd_t *pgd;
unsigned long vaddr;
pgd_t *pgd, *pgd_base;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
Expand All @@ -45,6 +44,7 @@ void __init pagetable_init(void)
pgd_init((unsigned long)swapper_pg_dir
+ sizeof(pgd_t) * USER_PTRS_PER_PGD);

#ifdef CONFIG_HIGHMEM
pgd_base = swapper_pg_dir;

/*
Expand All @@ -53,7 +53,6 @@ void __init pagetable_init(void)
vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
fixrange_init(vaddr, 0, pgd_base);

#ifdef CONFIG_HIGHMEM
/*
* Permanent kmaps:
*/
Expand Down
11 changes: 0 additions & 11 deletions trunk/arch/mips/mm/pgtable-64.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
*/
#include <linux/init.h>
#include <linux/mm.h>
#include <asm/fixmap.h>
#include <asm/pgtable.h>

void pgd_init(unsigned long page)
Expand Down Expand Up @@ -53,17 +52,7 @@ void pmd_init(unsigned long addr, unsigned long pagetable)

void __init pagetable_init(void)
{
unsigned long vaddr;
pgd_t *pgd_base;

/* Initialize the entire pgd. */
pgd_init((unsigned long)swapper_pg_dir);
pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);

pgd_base = swapper_pg_dir;
/*
* Fixed mappings:
*/
vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
fixrange_init(vaddr, 0, pgd_base);
}
2 changes: 1 addition & 1 deletion trunk/arch/x86_64/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,7 @@ __cpuinit int unsynchronized_tsc(void)
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
#ifdef CONFIG_ACPI
/* But TSC doesn't tick in C3 so don't use it there */
if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 100)
if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 1000)
return 1;
#endif
return 0;
Expand Down
19 changes: 15 additions & 4 deletions trunk/include/asm-mips/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,24 @@ extern void (*flush_icache_range)(unsigned long start, unsigned long end);
#define flush_cache_vmap(start, end) flush_cache_all()
#define flush_cache_vunmap(start, end) flush_cache_all()

extern void copy_to_user_page(struct vm_area_struct *vma,
static inline void copy_to_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len);
unsigned long len)
{
if (cpu_has_dc_aliases)
flush_cache_page(vma, vaddr, page_to_pfn(page));
memcpy(dst, src, len);
__flush_icache_page(vma, page);
}

extern void copy_from_user_page(struct vm_area_struct *vma,
static inline void copy_from_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len);
unsigned long len)
{
if (cpu_has_dc_aliases)
flush_cache_page(vma, vaddr, page_to_pfn(page));
memcpy(dst, src, len);
}

extern void (*flush_cache_sigtramp)(unsigned long addr);
extern void (*flush_icache_all)(void);
Expand Down
Loading

0 comments on commit aef5885

Please sign in to comment.