Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 139736
b: refs/heads/master
c: a24e5e1
h: refs/heads/master
v: v3
  • Loading branch information
Jack Steiner authored and Linus Torvalds committed Apr 3, 2009
1 parent 377d022 commit b2d6e34
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 161 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: 438846043af39fef286f68b197d42bd75f49898e
refs/heads/master: a24e5e1caf4875bbe09f328b5f4daef6d25ebcc4
2 changes: 1 addition & 1 deletion trunk/drivers/misc/sgi-gru/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ ifdef CONFIG_SGI_GRU_DEBUG
endif

obj-$(CONFIG_SGI_GRU) := gru.o
gru-y := grufile.o grumain.o grufault.o grutlbpurge.o gruprocfs.o grukservices.o
gru-y := grufile.o grumain.o grufault.o grutlbpurge.o gruprocfs.o grukservices.o gruhandles.o

197 changes: 197 additions & 0 deletions trunk/drivers/misc/sgi-gru/gruhandles.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/*
* GRU KERNEL MCS INSTRUCTIONS
*
* Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include <linux/kernel.h>
#include "gru.h"
#include "grulib.h"
#include "grutables.h"

/* 10 sec */
#ifdef CONFIG_IA64
#include <asm/processor.h>
#define GRU_OPERATION_TIMEOUT (((cycles_t) local_cpu_data->itc_freq)*10)
#else
#include <asm/tsc.h>
#define GRU_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
#endif

/* Extract the status field from a kernel handle */
#define GET_MSEG_HANDLE_STATUS(h) (((*(unsigned long *)(h)) >> 16) & 3)

static void start_instruction(void *h)
{
unsigned long *w0 = h;

wmb(); /* setting CMD bit must be last */
*w0 = *w0 | 1;
gru_flush_cache(h);
}

static int wait_instruction_complete(void *h, enum mcs_op opc)
{
int status;
cycles_t start_time = get_cycles();

while (1) {
cpu_relax();
status = GET_MSEG_HANDLE_STATUS(h);
if (status != CCHSTATUS_ACTIVE)
break;
if (GRU_OPERATION_TIMEOUT < (get_cycles() - start_time))
panic("GRU %p is malfunctioning\n", h);
}
return status;
}

#if defined CONFIG_IA64
static void cch_allocate_set_asids(
struct gru_context_configuration_handle *cch, int asidval)
{
int i;

for (i = 0; i < 8; i++) {
cch->asid[i] = (asidval++);
#if 0
/* ZZZ hugepages not supported yet */
if (i == RGN_HPAGE)
cch->sizeavail[i] = GRU_SIZEAVAIL(hpage_shift);
else
#endif
cch->sizeavail[i] = GRU_SIZEAVAIL(PAGE_SHIFT);
}
}
#elif defined CONFIG_X86_64
static void cch_allocate_set_asids(
struct gru_context_configuration_handle *cch, int asidval)
{
int i;

for (i = 0; i < 8; i++) {
cch->asid[i] = asidval++;
cch->sizeavail[i] = GRU_SIZEAVAIL(PAGE_SHIFT) |
GRU_SIZEAVAIL(21);
}
}
#endif

int cch_allocate(struct gru_context_configuration_handle *cch,
int asidval, unsigned long cbrmap,
unsigned long dsrmap)
{
cch_allocate_set_asids(cch, asidval);
cch->dsr_allocation_map = dsrmap;
cch->cbr_allocation_map = cbrmap;
cch->opc = CCHOP_ALLOCATE;
start_instruction(cch);
return wait_instruction_complete(cch, cchop_allocate);
}

int cch_start(struct gru_context_configuration_handle *cch)
{
cch->opc = CCHOP_START;
start_instruction(cch);
return wait_instruction_complete(cch, cchop_start);
}

int cch_interrupt(struct gru_context_configuration_handle *cch)
{
cch->opc = CCHOP_INTERRUPT;
start_instruction(cch);
return wait_instruction_complete(cch, cchop_interrupt);
}

int cch_deallocate(struct gru_context_configuration_handle *cch)
{
cch->opc = CCHOP_DEALLOCATE;
start_instruction(cch);
return wait_instruction_complete(cch, cchop_deallocate);
}

int cch_interrupt_sync(struct gru_context_configuration_handle
*cch)
{
cch->opc = CCHOP_INTERRUPT_SYNC;
start_instruction(cch);
return wait_instruction_complete(cch, cchop_interrupt_sync);
}

int tgh_invalidate(struct gru_tlb_global_handle *tgh,
unsigned long vaddr, unsigned long vaddrmask,
int asid, int pagesize, int global, int n,
unsigned short ctxbitmap)
{
tgh->vaddr = vaddr;
tgh->asid = asid;
tgh->pagesize = pagesize;
tgh->n = n;
tgh->global = global;
tgh->vaddrmask = vaddrmask;
tgh->ctxbitmap = ctxbitmap;
tgh->opc = TGHOP_TLBINV;
start_instruction(tgh);
return wait_instruction_complete(tgh, tghop_invalidate);
}

void tfh_write_only(struct gru_tlb_fault_handle *tfh,
unsigned long pfn, unsigned long vaddr,
int asid, int dirty, int pagesize)
{
tfh->fillasid = asid;
tfh->fillvaddr = vaddr;
tfh->pfn = pfn;
tfh->dirty = dirty;
tfh->pagesize = pagesize;
tfh->opc = TFHOP_WRITE_ONLY;
start_instruction(tfh);
}

void tfh_write_restart(struct gru_tlb_fault_handle *tfh,
unsigned long paddr, int gaa,
unsigned long vaddr, int asid, int dirty,
int pagesize)
{
tfh->fillasid = asid;
tfh->fillvaddr = vaddr;
tfh->pfn = paddr >> GRU_PADDR_SHIFT;
tfh->gaa = gaa;
tfh->dirty = dirty;
tfh->pagesize = pagesize;
tfh->opc = TFHOP_WRITE_RESTART;
start_instruction(tfh);
}

void tfh_restart(struct gru_tlb_fault_handle *tfh)
{
tfh->opc = TFHOP_RESTART;
start_instruction(tfh);
}

void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh)
{
tfh->opc = TFHOP_USER_POLLING_MODE;
start_instruction(tfh);
}

void tfh_exception(struct gru_tlb_fault_handle *tfh)
{
tfh->opc = TFHOP_EXCEPTION;
start_instruction(tfh);
}

176 changes: 17 additions & 159 deletions trunk/drivers/misc/sgi-gru/gruhandles.h
Original file line number Diff line number Diff line change
Expand Up @@ -495,164 +495,22 @@ enum gru_cbr_state {
/* minimum TLB purge count to ensure a full purge */
#define GRUMAXINVAL 1024UL


/* Extract the status field from a kernel handle */
#define GET_MSEG_HANDLE_STATUS(h) (((*(unsigned long *)(h)) >> 16) & 3)

static inline void start_instruction(void *h)
{
unsigned long *w0 = h;

wmb(); /* setting CMD bit must be last */
*w0 = *w0 | 1;
gru_flush_cache(h);
}

static inline int wait_instruction_complete(void *h)
{
int status;

do {
cpu_relax();
barrier();
status = GET_MSEG_HANDLE_STATUS(h);
} while (status == CCHSTATUS_ACTIVE);
return status;
}

#if defined CONFIG_IA64
static inline void cch_allocate_set_asids(
struct gru_context_configuration_handle *cch, int asidval)
{
int i;

for (i = 0; i <= RGN_HPAGE; i++) { /* assume HPAGE is last region */
cch->asid[i] = (asidval++);
#if 0
/* ZZZ hugepages not supported yet */
if (i == RGN_HPAGE)
cch->sizeavail[i] = GRU_SIZEAVAIL(hpage_shift);
else
#endif
cch->sizeavail[i] = GRU_SIZEAVAIL(PAGE_SHIFT);
}
}
#elif defined CONFIG_X86_64
static inline void cch_allocate_set_asids(
struct gru_context_configuration_handle *cch, int asidval)
{
int i;

for (i = 0; i < 8; i++) {
cch->asid[i] = asidval++;
cch->sizeavail[i] = GRU_SIZEAVAIL(PAGE_SHIFT) |
GRU_SIZEAVAIL(21);
}
}
#endif

static inline int cch_allocate(struct gru_context_configuration_handle *cch,
int asidval, unsigned long cbrmap,
unsigned long dsrmap)
{
cch_allocate_set_asids(cch, asidval);
cch->dsr_allocation_map = dsrmap;
cch->cbr_allocation_map = cbrmap;
cch->opc = CCHOP_ALLOCATE;
start_instruction(cch);
return wait_instruction_complete(cch);
}

static inline int cch_start(struct gru_context_configuration_handle *cch)
{
cch->opc = CCHOP_START;
start_instruction(cch);
return wait_instruction_complete(cch);
}

static inline int cch_interrupt(struct gru_context_configuration_handle *cch)
{
cch->opc = CCHOP_INTERRUPT;
start_instruction(cch);
return wait_instruction_complete(cch);
}

static inline int cch_deallocate(struct gru_context_configuration_handle *cch)
{
cch->opc = CCHOP_DEALLOCATE;
start_instruction(cch);
return wait_instruction_complete(cch);
}

static inline int cch_interrupt_sync(struct gru_context_configuration_handle
*cch)
{
cch->opc = CCHOP_INTERRUPT_SYNC;
start_instruction(cch);
return wait_instruction_complete(cch);
}

static inline int tgh_invalidate(struct gru_tlb_global_handle *tgh,
unsigned long vaddr, unsigned long vaddrmask,
int asid, int pagesize, int global, int n,
unsigned short ctxbitmap)
{
tgh->vaddr = vaddr;
tgh->asid = asid;
tgh->pagesize = pagesize;
tgh->n = n;
tgh->global = global;
tgh->vaddrmask = vaddrmask;
tgh->ctxbitmap = ctxbitmap;
tgh->opc = TGHOP_TLBINV;
start_instruction(tgh);
return wait_instruction_complete(tgh);
}

static inline void tfh_write_only(struct gru_tlb_fault_handle *tfh,
unsigned long pfn, unsigned long vaddr,
int asid, int dirty, int pagesize)
{
tfh->fillasid = asid;
tfh->fillvaddr = vaddr;
tfh->pfn = pfn;
tfh->dirty = dirty;
tfh->pagesize = pagesize;
tfh->opc = TFHOP_WRITE_ONLY;
start_instruction(tfh);
}

static inline void tfh_write_restart(struct gru_tlb_fault_handle *tfh,
unsigned long paddr, int gaa,
unsigned long vaddr, int asid, int dirty,
int pagesize)
{
tfh->fillasid = asid;
tfh->fillvaddr = vaddr;
tfh->pfn = paddr >> GRU_PADDR_SHIFT;
tfh->gaa = gaa;
tfh->dirty = dirty;
tfh->pagesize = pagesize;
tfh->opc = TFHOP_WRITE_RESTART;
start_instruction(tfh);
}

static inline void tfh_restart(struct gru_tlb_fault_handle *tfh)
{
tfh->opc = TFHOP_RESTART;
start_instruction(tfh);
}

static inline void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh)
{
tfh->opc = TFHOP_USER_POLLING_MODE;
start_instruction(tfh);
}

static inline void tfh_exception(struct gru_tlb_fault_handle *tfh)
{
tfh->opc = TFHOP_EXCEPTION;
start_instruction(tfh);
}
int cch_allocate(struct gru_context_configuration_handle *cch,
int asidval, unsigned long cbrmap, unsigned long dsrmap);

int cch_start(struct gru_context_configuration_handle *cch);
int cch_interrupt(struct gru_context_configuration_handle *cch);
int cch_deallocate(struct gru_context_configuration_handle *cch);
int cch_interrupt_sync(struct gru_context_configuration_handle *cch);
int tgh_invalidate(struct gru_tlb_global_handle *tgh, unsigned long vaddr,
unsigned long vaddrmask, int asid, int pagesize, int global, int n,
unsigned short ctxbitmap);
void tfh_write_only(struct gru_tlb_fault_handle *tfh, unsigned long pfn,
unsigned long vaddr, int asid, int dirty, int pagesize);
void tfh_write_restart(struct gru_tlb_fault_handle *tfh, unsigned long paddr,
int gaa, unsigned long vaddr, int asid, int dirty, int pagesize);
void tfh_restart(struct gru_tlb_fault_handle *tfh);
void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh);
void tfh_exception(struct gru_tlb_fault_handle *tfh);

#endif /* __GRUHANDLES_H__ */
Loading

0 comments on commit b2d6e34

Please sign in to comment.