source: trunk/packages/xen-common/xen-common/xen/arch/powerpc/dart_u4.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 4.8 KB
Line 
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
15 *
16 * Copyright (C) IBM Corp. 2005
17 *
18 * Authors: Jimi Xenidis <jimix@watson.ibm.com>
19 */
20
21#undef DEBUG
22#define INVALIDATE_ALL
23
24#include <xen/config.h>
25#include <xen/types.h>
26#include <xen/sched.h>
27#include <xen/init.h>
28#include <xen/mm.h>
29#include <public/xen.h>
30#include <asm/io.h>
31#include <asm/current.h>
32#include "tce.h"
33#include "iommu.h"
34#include "dart.h"
35
36#define TOO_MANY_RETRIES ~0
37
38union dart_ctl {
39    u32 dc_word;
40    struct {
41        u32 dc_darten:1;      /* DART Enable (0:disabled) */
42        u32 dc_ione:1;        /* Invalidate one DART TLB entry (using ILPN) */
43        u32 dc_iall:1;        /* Invalidate all DART TLB entries */
44        u32 dc_idle:1;        /* DART is idle */
45        u32 dc_peen:1;        /* Parity Checking is enabled */
46        u32 dc_ilpn:27;       /* 27-bit Logical Page Address for
47                               * invalidating one TLB entry */
48    } dc_bits;
49};
50
51union dart_base {
52    u32 db_word;
53    struct {
54        u32 _db_resv:8;
55        u32 db_dartbase:24;     /* Base Address of DART (4K byte Alignment) */
56    } db_bits;
57};
58
59union dart_size {
60    u32 ds_word;
61    struct {
62        u32 _ds_resv:15;
63        u32 ds_dartsize:17;     /* Size of Dart in 4K-Byte Pages */
64    } ds_bits;
65};
66
67union dart_excp {
68    u32 de_word;
69    struct {
70        u32 de_rqsrc:1;    /* Request Source.  [0:PCIE, 1:HT] */
71        u32 de_lpn:27;     /* 27Ðbit Logical Address of Exception [25:51] */
72        u32 de_rqop:1;     /* Request operation.  [0:Read, 1:Write] */
73        u32 de_xcd:3;      /* Exception code */
74    } de_bits;
75};
76
77struct dart {
78    /* 0x00 */
79    union dart_ctl d_dartcntl;
80    u32 _pad0x04_0x10[3];
81    /* 0x10 */
82    union dart_base d_dartbase;
83    u32 _pad0x14_0x20[3];
84    /* 0x20 */
85    union dart_size d_dartsize;
86    u32 _pad0x24_0x30[3];
87    /* 0x30 */
88    union dart_excp d_dartexcp;
89    u32 _pad0x34_0x40[3];
90};
91
92static volatile struct dart *dart;
93
94static void u4_inv_all(void)
95{
96    union dart_ctl dc;
97    ulong r = 0;
98    int l = 0;
99
100    for (;;) {
101        dc.dc_word = in_32(&dart->d_dartcntl.dc_word);
102        dc.dc_bits.dc_iall = 1;
103        out_32(&dart->d_dartcntl.dc_word, dc.dc_word);
104
105        do {
106            dc.dc_word = in_32(&dart->d_dartcntl.dc_word);
107            r++;
108        } while ((dc.dc_bits.dc_iall == 1) && (r < (1 << l)));
109
110        if (r == (1 << l)) {
111            if (l < 4) {
112                l++;
113                dc.dc_word = in_32(&dart->d_dartcntl.dc_word);
114                dc.dc_bits.dc_iall = 0;
115                out_32(&dart->d_dartcntl.dc_word, dc.dc_word);
116                continue;
117            } else {
118                panic(" broken U4???\n");
119            }
120        }
121        return;
122    }
123}
124
125static void u4_inv_entry(ulong pgn)
126{
127#ifdef INVALIDATE_ALL
128    return u4_inv_all();
129#else
130    union dart_ctl dc;
131    ulong retries = 0;
132
133    return u4_inv_all();
134
135    dc.dc_word = in_32(&dart->d_dartcntl.dc_word);
136    dc.dc_bits.dc_ilpn = pgn;
137    dc.dc_bits.dc_ione = 1;
138    out_32(&dart->d_dartcntl.dc_word, dc.dc_word);
139
140    /* wait for completion */
141    /* FIXME: since we do this from the HV do we need to wait?! */
142    do {
143        dc.dc_word = in_32(&dart->d_dartcntl.dc_word);
144        retries++;
145        if (retries > 1000000)
146            panic("WAY! too long\n");
147    } while (dc.dc_bits.dc_ione != 0);
148#endif
149}
150
151static struct dart_ops u4_ops = {
152    .do_inv_all = u4_inv_all,
153    .do_inv_entry = u4_inv_entry,
154};
155
156struct dart_ops *u4_init(ulong base, ulong table, ulong dart_pages)
157{
158    union dart_base db;
159    union dart_size ds;
160    union dart_ctl dc;
161
162    dart = (struct dart *)base;
163
164    db.db_word = 0;
165    db.db_bits.db_dartbase = table >> PAGE_SHIFT;
166
167    ds.ds_word = 0;
168    ds.ds_bits.ds_dartsize = dart_pages;
169
170    dc.dc_word = in_32(&dart->d_dartcntl.dc_word);
171    if (dc.dc_bits.dc_darten == 1) {
172        panic("%s: dart is already enabled: 0x%x\n", __func__, dc.dc_word);
173    }
174    dc.dc_bits.dc_darten = 1;   /* enable it */
175
176    printk("Initializing DART Model U4: ctl: 0x%x base: 0x%x size: 0x%x\n",
177           dc.dc_word, db.db_word, ds.ds_word);
178
179    out_32(&dart->d_dartbase.db_word, db.db_word);
180    out_32(&dart->d_dartsize.ds_word, ds.ds_word);
181    out_32(&dart->d_dartcntl.dc_word, dc.dc_word);
182
183    return &u4_ops;
184}
Note: See TracBrowser for help on using the repository browser.