Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / common / include / pci_bridge.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: pci_bridge.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#ifndef __PCI_BRIDGE_H__
24#define __PCI_BRIDGE_H__
25
26
27// this file contains register definitions of some
28// registers found in type 1 header of pci/pcie bridge.
29
30
31
32#include "pci_common.h"
33
34#define swap_hword(value) \
35 ((uint32_t)(((value) & 0xff) << 8 | (value) >> 8))
36
37#define swap_word(value) \
38 ((uint32_t)((Word)swap_hword((HWord)((value) & 0xffff)) << 16 | \
39 (Word)swap_hword((HWord)((value) >> 16))))
40
41#define swap_lword(value) \
42 ((uint64_t)((((LWord)swap_word(LO_W(value))) << 32) | \
43 ((LWord)swap_word(HI_W(value)))))
44
45
46// some macros originally defined in pcie-pci bridge code
47
48#define GET_IO_BASE(cfg_space) ( (cfg_space->readConf(PCI_BCNF_IO_BASE_HI) << 16) | \
49 (cfg_space->readConf(PCI_BCNF_IO_BASE_LOW) >> 4 << 12))
50#define GET_IO_LIMIT(cfg_space) ( (cfg_space->readConf(PCI_BCNF_IO_LIMIT_HI) << 16) | \
51 ((cfg_space->readConf(PCI_BCNF_IO_LIMIT_LOW) >> 4 << 12) | 0xfff))
52#define GET_PF_MEM_BASE(cfg_space) ((uint64_t)cfg_space->readConf(PCI_BCNF_PF_BASE_HIGH) << 32) | \
53 (cfg_space->readConf(PCI_BCNF_PF_BASE_LOW) >> 4 << 20)
54#define GET_PF_MEM_LIMIT(cfg_space) ((( (uint64_t)cfg_space->readConf(PCI_BCNF_PF_LIMIT_HIGH) << 32) | \
55 (cfg_space->readConf(PCI_BCNF_PF_LIMIT_LOW) >> 4 << 20)) | 0xfffff)
56#define GET_MEM_BASE(cfg_space) cfg_space->readConf(PCI_BCNF_MEM_BASE) >> 4 << 20
57#define GET_MEM_LIMIT(cfg_space) ((cfg_space->readConf(PCI_BCNF_MEM_LIMIT) >> 4 << 20) | 0xfffff)
58
59
60class bridgeCommandReg:public pciConfReg{
61private:
62 enum commandRegBits {IO_SPACE = 0, MEM_SPACE = 1, BUS_MASTER = 2};
63 enum space_type {IO = 0, MEM = 1, PREFETCH_MEM = 2};
64
65 bool io_enabled, mem_enabled;
66 void enable_io() {io_enabled = true;}
67 void enable_mem() {mem_enabled = true;}
68 void disable_io() {io_enabled = false;}
69 void disable_mem() {mem_enabled = false;}
70
71 void check_map(space_type spt, uint64_t base, uint64_t limit, bool isMap) {
72 if (base >= limit)
73 return;
74 if(debug_level >= 2)
75 fprintf(stderr, "%s: %s %llx %llx\n", isMap ? "Map" : "Unmap",
76 spt == IO ? "PCIE IO" :
77 (spt == MEM ? "PCIE MEM" : "PCIE PREFETCHABLE MEM"), base, limit);
78 if (spt == IO) {
79 if (isMap)
80 assert(((genericPcieDev*)data)->mapSpace(PCIE_IO, base, limit - base + 1));
81 else
82 assert(((genericPcieDev*)data)->unmapSpace(PCIE_IO, base));
83 } else {
84 if (isMap)
85 assert(((genericPcieDev*)data)->mapSpace(PCIE_MEM, base, limit - base + 1));
86 else
87 assert(((genericPcieDev*)data)->unmapSpace(PCIE_MEM, base));
88 }
89 if (!isMap) {
90 base = 0;
91 limit = 0;
92 }
93 }
94
95 void mapSpace(pcie_space spc, bool isMap){
96 uint64_t base, limit, up_base, up_limit;
97 if (spc == PCIE_IO) {
98 base = GET_IO_BASE(((genericPcieDev*)data)->confSpace);
99 limit = GET_IO_LIMIT(((genericPcieDev*)data)->confSpace);
100 check_map(IO, base, limit, isMap);
101 } else {
102 base = GET_PF_MEM_BASE(((genericPcieDev*)data)->confSpace);
103 limit = GET_PF_MEM_LIMIT(((genericPcieDev*)data)->confSpace);
104 check_map(PREFETCH_MEM, base, limit, isMap);
105
106 base = GET_MEM_BASE(((genericPcieDev*)data)->confSpace);
107 limit = GET_MEM_LIMIT(((genericPcieDev*)data)->confSpace);
108 check_map(MEM, base, limit, isMap);
109 }
110 }
111
112public:
113 bridgeCommandReg(const char * name, genericPcieDev * d, uint16_t write_mask,uint16_t val=0):pciConfReg(name,2,val,write_mask & 0x547, (void *)d)
114 {
115 if(!d){
116 printf("Bridge command reg constructor error: must provide genericPcieDev device pointer\n");
117 exit(-1);
118 }
119 io_enabled = mem_enabled = false;
120 }
121
122 bool io_mapped() {return io_enabled;}
123 bool mem_mapped() {return mem_enabled;}
124
125 uint8_t write(uint32_t buf, uint8_t byte_offset, uint8_t bytes_to_write) {
126 assert(!byte_offset);
127
128 uint8_t ret;
129 if(bytes_to_write <= 2)
130 ret = bytes_to_write;
131 else
132 ret = 2;
133
134 buf &= ~((int32_t)-1 << (ret << 3));
135
136 uint32_t new_val = val | (mask & buf);
137 uint32_t changed_bits = new_val ^ val;
138
139 if(debug_level >= 2)
140 printf("Name<%s>,size<0x%x>mask<0x%lx>value<0x%lx -> 0x%lx>\n",name,size,mask,val,new_val);
141
142 val = new_val;
143
144 if(changed_bits & 1 << IO_SPACE){ //I/O space map bit has changed
145 if(val & 1 << IO_SPACE) { //bit set to 1
146 assert(!io_mapped());
147 mapSpace(PCIE_IO, true);
148 enable_io();
149 } else if (io_mapped()) { //bit set to 0
150 mapSpace(PCIE_IO, false);
151 disable_io();
152 }
153 }
154
155 if(changed_bits & 1 << MEM_SPACE){
156 if(val & 1 << MEM_SPACE){ //bit set to 1
157 assert(!mem_mapped());
158 mapSpace(PCIE_MEM, true);
159 enable_mem();
160 }else if (mem_mapped()) {
161 mapSpace(PCIE_MEM, false);
162 disable_mem();
163 }
164 }
165 return ret;
166 }
167};
168
169
170
171class pciSecondaryStatusReg:public pciConfReg{
172public:
173 enum{
174 MHZ_CAPABLE_66 = 5,
175 FAST_BACKTO_BACK = 7,
176 MASTER_DATA_PARITY_ERR = 8,
177 DEVSEL_TIMING_LBP = 9,
178 DEVSEL_TIMING_RBP = 10,
179 SIGNALED_TARGET_ABORT = 11,
180 RECVD_TARGET_ABORT = 12,
181 RECVD_MASTER_ABORT = 13,
182 RECEIVD_SYSTEM_ERR = 14,
183 DETECTED_PARITY_ERR = 15
184 };
185
186 enum{
187 FAST_DEVSEL_TIMING = 0,
188 MEDIUM_DEVSEL_TIMING = 1,
189 SLOW_DEVSEL_TIMIMG = 2,
190 };
191 pciSecondaryStatusReg(uint16_t por_val = 0x0, uint16_t mask = 0xf900, \
192 void * d = 0, const char * name = "pciSecStatReg")
193 :pciConfReg(name, 2, por_val, mask, d){}
194
195 uint8_t write(uint32_t buf, uint8_t byte_offset, uint8_t bytes_to_write){
196 assert(bytes_to_write == 2);
197 uint32_t oldval = val;
198
199 // if fails, write a more generic function in here.
200 buf &= mask; // 0 out the ro bits if any in buf
201 buf = ~buf; // flip the 0's to 1's and vice versa
202 val &= buf; // and with val so that bits set to 1 are turned off
203 // bits written to with 0 are unaffected.
204 if(debug_level >= 2)
205 printf("Name<%s>,size<0x%x>mask<0x%lx>value<0x%lx -> 0x%lx>\n",name,size,mask,oldval,val);
206
207
208 return 2;
209 }
210
211};
212
213class pciBridgeControlReg:public pciConfReg{
214public:
215 enum{
216 PARITY_ERROR_RESPONSE_EN = 0,
217 SERR_EN = 1,
218 ISA_EN = 2,
219 VGA_EN = 3,
220 VGA_16_BIT_DECODE = 4,
221 MASTER_ABORT = 5,
222 SEC_BUS_RESET = 6,
223 FAST_BACK_TO_BACK_EN = 7,
224 PRIMARY_DISCARD_TIMER = 8,
225 SECONDARY_DISCARD_TIMER = 9,
226 DISCARD_TIMER_STATUS = 10, // RW1C bit
227 DISCARD_TIMER_ERR_EN = 11
228 };
229
230 pciBridgeControlReg(uint16_t por_val = 0x0, uint16_t mask = 0xeff, \
231 void * d = 0, const char * name = "pciBridgeCtrlReg")
232 :pciConfReg(name, 2, por_val, mask, d){}
233
234 uint8_t write(uint32_t buf, uint8_t byte_offset, uint8_t bytes_to_write){
235 uint32_t bit10_in_buf = buf & 1 << DISCARD_TIMER_STATUS;
236 uint32_t bit10_in_val = val & 1 << DISCARD_TIMER_STATUS;
237 uint32_t oldval = val;
238
239 pciConfReg::write(buf,byte_offset,bytes_to_write);
240
241 if((bytes_to_write > 1) && bit10_in_buf && bit10_in_val)
242 val &= ~((uint32_t)1 << DISCARD_TIMER_STATUS);
243
244 if(debug_level >= 2)
245 printf("Name<%s>,size<0x%x>mask<0x%lx>value<0x%lx -> 0x%lx>\n",name,size,mask,oldval,val);
246 return bytes_to_write;
247 }
248};
249
250#endif// __PCI_BRIDGE_H__
251