Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / schizo / include / schizo_module.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: schizo_module.h
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23/*
24 * Copyright 2004 by Sun Microsystems, Inc.
25 * All rights reserved.
26 *
27 * W% 04/08/04
28 */
29#ifndef _SCHIZO_MODULE_H
30#define _SCHIZO_MODULE_H
31
32#include <assert.h>
33#include <strings.h>
34#include "pci.h"
35#include "pci_dev.h"
36#include "mmi.h"
37#include "module.h"
38#include "schizo_impl.h"
39extern devRegistry * samDevs;
40
41#define MAX_SCHIZO_DEVICES 10 // 8 devices, pciA, pciB
42#define V4_MAX_SCHIZO_DEVICES 64
43
44#define LO_U32(x) ((uint32_t)((uint32_t *)&(x))[1])
45#define HI_U32(x) ((uint32_t)((uint32_t *)&(x))[0])
46
47#define swap_hword(value) \
48 (((value) & 0xff) << 8 | (value) >> 8)
49
50#define swap_word(value) \
51 ((uint32_t)swap_hword((uint16_t)((value) & 0xffff)) << 16 | \
52 (uint32_t)swap_hword((uint16_t)((value) >> 16)))
53
54#define swap_lword(value) \
55 ((uint64_t)swap_word(LO_U32(value)) << 32 | \
56 (uint64_t)swap_word(HI_U32(value)))
57
58#define NUM_PAIRS 8
59
60#define NID(X) ((X & 0x3e0) >> 5)
61typedef struct {uint64_t addr, value;} addr_val_pair;
62
63typedef enum {LEAFA, LEAFB, NLEAF} leaf_t;
64
65typedef struct pci_info {
66 const char *name;
67 mmi_instance_t bus;
68 pciBusIf *busif;
69 uint64_t base, size, mask;
70 pci_space_t space;
71 leaf_t leaf;
72} pci_info_t;
73
74class schizoPciDev;
75
76
77//structure to map pci devices to interrupt number.
78//each PCI device is allocated 4 interrupts, based
79//upon the slot from 0-31. The other interrupts are
80//reserved for Schizo internal interrupts, OBIO and
81//new link.
82struct pciDevIntrInfo{
83 mmi_instance_t busMod; //module pointer of bus on which device is attached
84 uint8_t devNum; //sysconf device argument of device
85 uint8_t devType; //type of device eg network etc
86};
87
88
89extern "C" int schizo_access (uint32_t cpu_id, void* obj, uint64_t paddr, mmi_bool_t wr, uint32_t size, uint64_t* buf,uint8_t bytemask=PHYSIO_BYTEMASK_ALL);
90extern "C" int pci_access (uint32_t cpu_id, void* obj, uint64_t paddr, mmi_bool_t wr, uint32_t size, uint64_t* buf, uint8_t bytemask=PHYSIO_BYTEMASK_ALL);
91
92
93class Schizo : public Module, pciBridgeIf {
94 private:
95 const char *pciA, *pciB;
96 pci_info_t pci_info[NLEAF][PCI_NSPACES];
97 uint64_t cpuPaddr;
98 int aid;
99 static const uint64_t IO_SPACE_ADDR = 0x40000000000ULL;
100 static const uint64_t PCI_CONF_IO_ADDR =0x40200000000ULL;
101 static const uint64_t PCI_IO_ADDR_OFFSET = 0x1000000ULL;
102 static const uint64_t PCI_MEM_ADDR = 0x40400000000ULL;
103 static const int NUM_ENTRIES = 16; // number of TLB/TSB entries in Schizo
104 int boot_flag;
105 schizo_structT* msp;
106
107 bool retDevIntfA;
108 schizoPciDev * pciDevA;
109 schizoPciDev * pciDevB;
110 pciDevIntrInfo pciIntrInfo[V4_MAX_SCHIZO_DEVICES];
111 char fkPromBus_A_Str[7];
112 char fkPromBus_B_Str[7];
113 addr_val_pair av_pairs[NUM_PAIRS];
114
115 private:
116 bool dump(FILE *);
117 bool restore(FILE *);
118 bool restore_v4(FILE *);
119 bool restore_v5(FILE *);
120 void init_msp();
121 void init_mdu_regs();
122 void init_regs();
123 void init_pci();
124 void destroy_pci();
125 int rd_wr_mdu_reg(uint32_t paddr, uint64_t* buf, bool_t wr);
126 Register_set regs_range(uint64_t phy_addr);
127 Address_space calc_range(uint64_t *pyaddr);
128 Safari_space get_range(uint64_t *pyaddr);
129 int access_schizo_internals(uint32_t cpu_id, uint64_t paddr, bool_t wr, uint32_t, uint64_t *buf,SAM_DeviceId * samId);
130 int range_scsrbase(uint64_t paddr, bool_t wr, uint64_t *buf);
131 int range_pci_a_csrbase(uint32_t cpu_id, uint64_t paddr, bool_t wr, uint64_t *buf);
132 int range_pci_b_csrbase(uint32_t cpu_id, uint64_t paddr, bool_t wr, uint64_t *buf);
133 int rd_wr_stc_b_diags(uint32_t paddr, uint64_t* buf, bool_t wr);
134 int rd_wr_stc_a_diags(uint32_t paddr, uint64_t* buf, bool_t wr);
135
136 // mmu a
137 public:
138 uint64_t a_iommu_va2pa(int isRead, uint64_t vaddr);
139 private:
140 bool_t a_flush_entry(uint32_t vaddr);
141 void a_flush_entries(uint32_t context);
142 bool_t a_iommu_match(Tlb_entry_t* entry, uint32_t vaddr);
143 int a_get_lru_entry();
144 uint64_t a_calc_tsb_ptr( uint32_t vaddr);
145 bool_t a_schizo_iommu_lookup(uint32_t vaddr);
146 bool_t a_schizo_iommu_load_tte_tlb(uint32_t vaddr, uint64_t tte_entry);
147 uint64_t a_translate_to_paddr(uint32_t vaddr);
148 uint64_t a_vaddr2paddr(uint32_t vaddr, Tlb_entry_t* line);
149 void a_update_lru_status(int num);
150 int a_rd_wr_iommu_diags(uint32_t paddr, uint64_t* buf, bool_t wr);
151 bool_t a_check_all_used();
152 uint64_t a_compare_entry(uint32_t vpn);
153 bool_t a_any_match(Tlb_entry_t* entry, uint32_t vpn);
154
155 // mmu b
156 public:
157 uint64_t b_iommu_va2pa(int isRead, uint64_t vaddr);
158 private:
159 bool_t b_flush_entry(uint32_t vaddr);
160 void b_flush_entries(uint32_t context);
161 bool_t b_iommu_match(Tlb_entry_t* entry, uint32_t vaddr);
162 int b_get_lru_entry();
163 uint64_t b_calc_tsb_ptr( uint32_t vaddr);
164 bool_t b_schizo_iommu_lookup(uint32_t vaddr);
165 bool_t b_schizo_iommu_load_tte_tlb(uint32_t vaddr, uint64_t tte_entry);
166 uint64_t b_translate_to_paddr(uint32_t vaddr);
167 uint64_t b_vaddr2paddr(uint32_t vaddr, Tlb_entry_t* line);
168 void b_update_lru_status(int num);
169 int b_rd_wr_iommu_diags(uint32_t paddr, uint64_t* buf, bool_t wr);
170 bool_t b_check_all_used();
171 uint64_t b_compare_entry(uint32_t vpn);
172 bool_t b_any_match(Tlb_entry_t* entry, uint32_t vpn);
173
174 static const uint64_t ULL(int n) { return (uint64_t)(n); };
175 static const uint64_t KB(int n) { return 1024ULL * ULL(n); };
176 static const uint64_t MB(int n) { return (1024ULL * KB(n)); };
177 static const uint64_t GB(int n) { return (1024ULL * MB(n)); };
178 static const uint64_t BIT(int n) { return 1ULL << (n); };
179 static const int LO(uint64_t n) { return (int)n; };
180 static const int HI(uint64_t n) { return (int)(n >> 32); };
181 static const int FFS(uint64_t n) { return n ? (LO(n) ? ffs(LO(n)) : (32 + ffs(HI(n)))) : 0; };
182
183friend int schizo_access(uint32_t cpu_id, void* obj, uint64_t paddr, mmi_bool_t wr, uint32_t size, uint64_t* buf,uint8_t bytemask);
184friend int pci_access(uint32_t cpu_id, void* obj, uint64_t paddr, mmi_bool_t wr, uint32_t size, uint64_t* buf, uint8_t bytemask);
185
186 int access_memory_controllers(uint32_t cpu_id, uint64_t paddr, bool_t wr, uint32_t, uint64_t *buf);
187
188 void map_pci(leaf_t leaf, pci_space_t, uint64_t , uint64_t ,uint64_t);
189 void unmap_pci(leaf_t leaf, pci_space_t);
190
191 void send_mondo_intr(uint64_t mondo, uint32_t dev_type, uint32_t dev_id);
192 int Schizo::interrupt_deassert(int indx);
193
194 public:
195 Schizo(const char *modname, const char *instance_name);
196 ~Schizo();
197
198 public:
199 int busif_add_interrupt(mmi_instance_t busMod,int device,int dev_type, int slot_irl[], bool isMulti);
200 int busif_free_interrupt(mmi_instance_t busMod, int dev_number);
201 int busif_interrupt_in(bool set,mmi_instance_t busMod, int device, int line, SAM_DeviceId *id);
202 int busif_dma_out(uint64_t vaddr, void *data, long count, mmi_instance_t caller,uint16_t requesterId,SAM_DeviceId *id);
203 int busif_dma_in(uint64_t vaddr, void *data, long count, mmi_instance_t caller,uint16_t requesterId, SAM_DeviceId *id);
204
205// override the pciTargetIf functions. they do nothing in schizo impl. and should be never called
206
207 pciXactnStatus pciTarget_mem32access(uint64_t offset, bool wr,uint64_t * buf, uint8_t size){return SIM_INTERNAL_ERROR;}
208 pciXactnStatus pciTarget_mem64access(uint64_t offset, bool wr,uint64_t * buf, uint8_t size){return SIM_INTERNAL_ERROR;}
209 pciXactnStatus pciTarget_ioaccess(uint64_t offset, bool wr,uint64_t * buf, uint8_t size){return SIM_INTERNAL_ERROR;}
210 pciXactnStatus pciTarget_special_cycle(uint16_t mssg, uint16_t data){return SIM_INTERNAL_ERROR;}
211 pciXactnStatus pciTarget_intr_ack(uint64_t *data){return SIM_INTERNAL_ERROR;}
212
213 // the bus number is hardwired in schizo to 0
214 int busif_get_secondary_busno(){return 0;}
215
216
217 public: // Module interface
218 void record_mapping(uint64_t, uint64_t);
219 const char *get_help();
220 bool parse_arg(const char *);
221 bool check_args();
222 void init_done();
223 void module_added(mmi_instance_t, const char*);
224 void module_deleted(mmi_instance_t, const char*);
225 void modinfo();
226 void *get_interface(const char*);
227
228 void get_dev_props();
229 static void swapBuf(int size, uint64_t *buf);
230#ifndef V5_FAKEPROM
231 int getStartInterruptIndex(mmi_instance_t busMod, int devNum);
232#endif
233
234};
235
236
237//schizo appears as device 0 function 0 on the
238//pci buses it controls.
239
240class schizoPciDev:public genericPciDevIf{
241
242 uint8_t deviceNumber;
243 uint8_t functionNumber;
244 const char *busName;
245 bool isBusA;
246 Schizo* schizo;
247 pciConfSpace * confSpace;
248
249public:
250
251
252 const char *devif_getBusName(){return busName;}
253 int devif_getDevice(){return deviceNumber;}
254 int devif_getFunction(){return functionNumber;}
255 mmi_instance_t devif_getInstance(){return schizo->getInstance();}
256 const char *devif_getName(){return schizo->getName();}
257
258 pciXactnStatus devif_access_w_byte_enable(pci_space_t, uint64_t paddr, uint64_t offset, bool_t wr, uint64_t* buf, uint8_t byte_enable,SAM_DeviceId * id){
259 if(id) *id = schizo->samId;
260 return MASTER_ABORT;
261 }
262
263 pciXactnStatus devif_special_cycle(uint16_t mssg, uint16_t data){
264 return MASTER_ABORT;
265 }
266
267 pciXactnStatus devif_intr_ack(uint64_t * data){
268 return MASTER_ABORT;
269 }
270
271 pciXactnStatus devif_access_w_size(pci_space_t space, uint64_t paddr, uint64_t offset, bool_t wr, uint64_t* buf, uint8_t size,SAM_DeviceId * id){
272 if(id) *id = schizo->samId;
273 confSpace->confAccessSize(offset,wr,buf,size);
274 if(space == PCI_CFG)
275 return SUCCESS;
276 else
277 return MASTER_ABORT;
278 }
279
280 schizoPciDev(Schizo * ptr,const char * bus_name, bool bus){
281 schizo = ptr;
282 deviceNumber = 0;
283 functionNumber = 0;
284 busName = strdup(bus_name);
285 isBusA = bus;
286 confSpace = new pciConfSpace(pciHeaderNull);
287 initPci(isBusA);
288
289 };
290private:
291 void initPci(bool bus){
292 char reg_descr[100];
293
294 snprintf(reg_descr,100,"%s-%s Vendor ID", devif_getName(),busName);
295 confSpace->addConfReg(new pciConfReg(reg_descr, 2,0x108e,0x0,0x0),PCI_CONF_VENID);//0x108e, ro
296
297 snprintf(reg_descr,100,"%s-%s Device ID", devif_getName(),busName);
298 confSpace->addConfReg(new pciConfReg(reg_descr, 2,0x8001,0x0,0x0),PCI_CONF_DEVID); //0x8001, ro
299
300 snprintf(reg_descr,100,"%s-%s command reg", devif_getName(),busName);
301 confSpace->addConfReg(new pciCommandReg(reg_descr,(genericPciDev*)this,0x140,0x6),PCI_CONF_COMM);// write mask = 0x140
302
303 snprintf(reg_descr,100,"%s-%s status reg", devif_getName(),busName);
304 confSpace->addConfReg(new pciStatusReg(reg_descr,(genericPciDev*)this,bus?0x280:0x2a0,0xf900),PCI_CONF_STAT);//write mask = 0xf900
305 // this reg has some rw1c bit fields. over-ride the pciStatusReg class r/w functions in case OS ever complains.
306
307 snprintf(reg_descr,100,"%s-%s revision id", devif_getName(),busName);
308 confSpace->addConfReg(new pciConfReg(reg_descr,1,0x0,0x0,0x0),PCI_CONF_REVID);// rev id = 0x00, ro
309
310 snprintf(reg_descr,100,"%s-%s prog class",devif_getName(),busName);
311 confSpace->addConfReg(new pciConfReg(reg_descr,1,0x0,0x0),PCI_CONF_PROGCLASS);//0x00, ro
312
313 snprintf(reg_descr,100,"%s-%s sub class",devif_getName(),busName);
314 confSpace->addConfReg(new pciConfReg(reg_descr,1,0x0,0x0),PCI_CONF_SUBCLASS);//0x00, ro
315
316 snprintf(reg_descr,100,"%s-%s base class",devif_getName(),busName);
317 confSpace->addConfReg(new pciConfReg(reg_descr,1,0x06,0x0),PCI_CONF_BASCLASS);//0x06, ro
318
319 snprintf(reg_descr,100,"%s-%s latency timer",devif_getName(),busName);
320 confSpace->addConfReg(new pciConfReg(reg_descr,1,0x0,0xf8),PCI_CONF_LATENCY_TIMER);//0x00,
321
322 snprintf(reg_descr,100,"%s-%s Header type",devif_getName(),busName);
323 confSpace->addConfReg(new pciConfReg(reg_descr,1,0x00,0x00),PCI_CONF_HEADER); //0x00,ro
324
325 snprintf(reg_descr,100,"%s-%s Bus number",devif_getName(),busName);
326 confSpace->addConfReg(new pciConfReg(reg_descr,1,0x00,0xff),0x40); //0x00, rw
327
328 snprintf(reg_descr,100,"%s-%s Subordinate bus number",devif_getName(),busName);
329 confSpace->addConfReg(new pciConfReg(reg_descr,1,0x00,0xff),0x41); //0x00, rw
330 }
331};
332
333
334
335#endif /* _SCHIZO_MODULE_H */