2 * GRU KERNEL MCS INSTRUCTIONS
4 * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <linux/kernel.h>
24 #include "grutables.h"
28 #include <asm/processor.h>
29 #define GRU_OPERATION_TIMEOUT (((cycles_t) local_cpu_data->itc_freq)*10)
32 #define GRU_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
35 /* Extract the status field from a kernel handle */
36 #define GET_MSEG_HANDLE_STATUS(h) (((*(unsigned long *)(h)) >> 16) & 3)
38 static void start_instruction(void *h)
40 unsigned long *w0 = h;
42 wmb(); /* setting CMD bit must be last */
47 static int wait_instruction_complete(void *h, enum mcs_op opc)
50 cycles_t start_time = get_cycles();
54 status = GET_MSEG_HANDLE_STATUS(h);
55 if (status != CCHSTATUS_ACTIVE)
57 if (GRU_OPERATION_TIMEOUT < (get_cycles() - start_time))
58 panic("GRU %p is malfunctioning\n", h);
63 #if defined CONFIG_IA64
64 static void cch_allocate_set_asids(
65 struct gru_context_configuration_handle *cch, int asidval)
69 for (i = 0; i < 8; i++) {
70 cch->asid[i] = (asidval++);
72 /* ZZZ hugepages not supported yet */
74 cch->sizeavail[i] = GRU_SIZEAVAIL(hpage_shift);
77 cch->sizeavail[i] = GRU_SIZEAVAIL(PAGE_SHIFT);
80 #elif defined CONFIG_X86_64
81 static void cch_allocate_set_asids(
82 struct gru_context_configuration_handle *cch, int asidval)
86 for (i = 0; i < 8; i++) {
87 cch->asid[i] = asidval++;
88 cch->sizeavail[i] = GRU_SIZEAVAIL(PAGE_SHIFT) |
94 int cch_allocate(struct gru_context_configuration_handle *cch,
95 int asidval, unsigned long cbrmap,
98 cch_allocate_set_asids(cch, asidval);
99 cch->dsr_allocation_map = dsrmap;
100 cch->cbr_allocation_map = cbrmap;
101 cch->opc = CCHOP_ALLOCATE;
102 start_instruction(cch);
103 return wait_instruction_complete(cch, cchop_allocate);
106 int cch_start(struct gru_context_configuration_handle *cch)
108 cch->opc = CCHOP_START;
109 start_instruction(cch);
110 return wait_instruction_complete(cch, cchop_start);
113 int cch_interrupt(struct gru_context_configuration_handle *cch)
115 cch->opc = CCHOP_INTERRUPT;
116 start_instruction(cch);
117 return wait_instruction_complete(cch, cchop_interrupt);
120 int cch_deallocate(struct gru_context_configuration_handle *cch)
122 cch->opc = CCHOP_DEALLOCATE;
123 start_instruction(cch);
124 return wait_instruction_complete(cch, cchop_deallocate);
127 int cch_interrupt_sync(struct gru_context_configuration_handle
130 cch->opc = CCHOP_INTERRUPT_SYNC;
131 start_instruction(cch);
132 return wait_instruction_complete(cch, cchop_interrupt_sync);
135 int tgh_invalidate(struct gru_tlb_global_handle *tgh,
136 unsigned long vaddr, unsigned long vaddrmask,
137 int asid, int pagesize, int global, int n,
138 unsigned short ctxbitmap)
142 tgh->pagesize = pagesize;
144 tgh->global = global;
145 tgh->vaddrmask = vaddrmask;
146 tgh->ctxbitmap = ctxbitmap;
147 tgh->opc = TGHOP_TLBINV;
148 start_instruction(tgh);
149 return wait_instruction_complete(tgh, tghop_invalidate);
152 void tfh_write_only(struct gru_tlb_fault_handle *tfh,
153 unsigned long pfn, unsigned long vaddr,
154 int asid, int dirty, int pagesize)
156 tfh->fillasid = asid;
157 tfh->fillvaddr = vaddr;
160 tfh->pagesize = pagesize;
161 tfh->opc = TFHOP_WRITE_ONLY;
162 start_instruction(tfh);
165 void tfh_write_restart(struct gru_tlb_fault_handle *tfh,
166 unsigned long paddr, int gaa,
167 unsigned long vaddr, int asid, int dirty,
170 tfh->fillasid = asid;
171 tfh->fillvaddr = vaddr;
172 tfh->pfn = paddr >> GRU_PADDR_SHIFT;
175 tfh->pagesize = pagesize;
176 tfh->opc = TFHOP_WRITE_RESTART;
177 start_instruction(tfh);
180 void tfh_restart(struct gru_tlb_fault_handle *tfh)
182 tfh->opc = TFHOP_RESTART;
183 start_instruction(tfh);
186 void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh)
188 tfh->opc = TFHOP_USER_POLLING_MODE;
189 start_instruction(tfh);
192 void tfh_exception(struct gru_tlb_fault_handle *tfh)
194 tfh->opc = TFHOP_EXCEPTION;
195 start_instruction(tfh);