C51 COMPILER V7.06 PCI 08/02/2005 13:30:01 PAGE 1 C51 COMPILER V7.06, COMPILATION OF MODULE PCI OBJECT MODULE PLACED IN PCI.OBJ COMPILER INVOKED BY: d:\Keil777\C51\BIN\C51.EXE PCI.C BROWSE DEBUG OBJECTEXTEND stmt level source 1 #include *** WARNING C318 IN LINE 1 OF PCI.C: can't open file 'dos.h' 2 #include "pci.h" 3 4 #define I_VENDOR_ID 0x00 5 #define PCI_DEVICE_ID 0x02 6 #define PCI_CMD_REG 0x04 7 #define PCI_STATUS_REG 0x06 8 #define PCI_REV_ID 0x08 /* including the class code */ 9 #define PCI_CACHE_LINE_SIZE 0x0C 10 #define PCI_LATENCY_TIMER 0x0D 11 #define PCI_HEAD_TYPE 0x0E 12 #define PCI_BIST 0x0F 13 #define PCI_BASE_ADDR_0 0x10 14 #define PCI_BASE_ADDR_1 0x14 15 #define PCI_BASE_ADDR_2 0x18 16 #define PCI_BASE_ADDR_3 0x1C 17 #define PCI_BASE_ADDR_4 0x20 18 #define PCI_BASE_ADDR_5 0x24 19 #define PCI_CIS_POINTER 0x28 20 #define PCI_SUB_VENDOR_ID 0x2C 21 #define PCI_SUB_SYSTEM_ID 0x2E 22 #define PCI_EXP_ROM_BASE 0x30 23 #define PCI_INTR_LINE 0x3C 24 #define PCI_INTR_PIN 0x3D 25 #define PCI_MIN_GNT 0x3E 26 #define PCI_MAX_LAT 0x3F 27 28 #define OFFSET_TO_DW_INDEX(x) ((x) & ~0x3) 29 #define OFFSET_TO_BYTE_INDEX(x) ((x) & 0x3) 30 31 /*---------------------------------------------------------------------*/ 32 /* Ports and the bit patterns used by the Configuration Mechanism One */ 33 /*---------------------------------------------------------------------*/ 34 #define CFG_ADDR_REG 0x0CF8 35 #define CFG_DATA_REG 0x0CFC 36 #define CFG_SPACE_ENA 0x80000000 37 38 /*---------------------------------------------------------------------*/ 39 /* Ports and the bit patterns used by the Configuration Mechanism Two */ 40 /*---------------------------------------------------------------------*/ 41 #define CFG_ENABLE_REG 0x0CF8 42 #define CFG_FORWARD_REG 0x0CFA 43 #define CFG_BASE_REG 0xC000 44 #define CFG_SPACE_KEY 0xF0 45 #define SPE_CYC_ENA 0x01 46 47 #define MULTI_FUNC_BIT 0x80 48 49 50 #define MAX_PCI_DEVICES 16 51 #define MAX_BUS_NUM 16 /* the maximum value is 256 */ 52 #define MAX_DEV_NUM 32 53 #define MAX_FUNC_NUM 8 54 C51 COMPILER V7.06 PCI 08/02/2005 13:30:01 PAGE 2 55 #define PCI_CFG_MECHANISM_1 1 56 #define PCI_CFG_MECHANISM_2 2 57 58 #define PCI_NO_DEVICE_ID 0xffffffff 59 60 #define USHORT unsigned short 61 #define ULONG unsigned long 62 #define UCHAR unsigned char 63 64 typedef struct pci_cfg_info 65 { 66 struct pci_cfg_info *next; 67 USHORT vendor_id; 68 USHORT dev_id; 69 USHORT pci_bus_num; 70 USHORT pci_dev_num; 71 USHORT pci_func_num; 72 USHORT rev_id; 73 USHORT base_class; 74 USHORT sub_class; 75 ULONG class_code; 76 77 USHORT subsys_vendor_id; 78 USHORT subsys_id; 79 ULONG cfg_addr; 80 } PCI_CFG_INFO; 81 82 83 static PCI_CFG_INFO pci_cfg_info[MAX_PCI_DEVICES]; 84 85 unsigned long g_bridge_setting_IO; 86 87 88 USHORT pci_cfg_rd_w(ULONG addr, ULONG offset); 89 UCHAR pci_cfg_rd_b(ULONG addr, ULONG offset); 90 ULONG pci_cfg_rd_l(ULONG addr, ULONG offset); 91 92 static ULONG inpd(int portnum) 93 { 94 1 static ULONG value ; 95 1 asm mov dx,portnum ; *** ERROR C202 IN LINE 95 OF PCI.C: 'asm': undefined identifier *** ERROR C141 IN LINE 95 OF PCI.C: syntax error near 'mov' 96 1 asm lea bx,value ; *** ERROR C202 IN LINE 96 OF PCI.C: 'asm': undefined identifier *** ERROR C141 IN LINE 96 OF PCI.C: syntax error near 'lea' 97 1 __emit__(0x66,0x50, // push EAX 98 1 0x66,0xED, // in EAX,DX 99 1 0x66,0x89,0x07, // mov [BX],EAX 100 1 0x66,0x58) ; // pop EAX 101 1 return value ; 102 1 } 103 104 static void outpd(int portnum, ULONG val) 105 { 106 1 static ULONG value = 0 ; 107 1 108 1 value = val ; 109 1 asm mov dx,portnum ; 110 1 asm lea bx,value ; 111 1 __emit__(0x66,0x50, // push EAX 112 1 0x66,0x8B,0x07, // mov EAX,[BX] C51 COMPILER V7.06 PCI 08/02/2005 13:30:01 PAGE 3 113 1 0x66,0xEF, // out DX,EAX 114 1 0x66,0x58) ; // pop EAX 115 1 return ; 116 1 } 117 118 PCI_CFG_INFO * get_pci_cfg_info_tbl() 119 { 120 1 PCI_CFG_INFO *pinfo; 121 1 ULONG dnum, fnum, bus_num; 122 1 ULONG addr, addr_f; 123 1 ULONG tmpl; 124 1 ULONG tmps; 125 1 ULONG pci_found; 126 1 127 1 128 1 pinfo = &pci_cfg_info[0]; 129 1 pci_found = 0; 130 1 131 1 for(bus_num=0; bus_num < MAX_BUS_NUM; bus_num++) 132 1 { 133 2 for(dnum=0; dnum < MAX_DEV_NUM; dnum++) 134 2 { 135 3 addr = (bus_num << 16) | (dnum << 11); 136 3 for(fnum=0; fnum < MAX_FUNC_NUM; fnum++) 137 3 { 138 4 /*---------------------------------------------------------*/ 139 4 /* read vendor and device IDs and check them */ 140 4 /*---------------------------------------------------------*/ 141 4 addr_f = addr | (fnum << 8); 142 4 tmpl = pci_cfg_rd_l(addr_f, 0); 143 4 if(tmpl == PCI_NO_DEVICE_ID) 144 4 break; 145 4 146 4 pinfo->vendor_id = tmpl & 0xFFFF; 147 4 pinfo->dev_id = (tmpl >> 16) & 0xFFFF; 148 4 pinfo->pci_bus_num = bus_num; 149 4 pinfo->pci_dev_num = dnum; 150 4 pinfo->pci_func_num = fnum; 151 4 152 4 pinfo->subsys_id = pci_cfg_rd_w(addr_f, 153 4 PCI_SUB_VENDOR_ID); 154 4 155 4 pinfo->subsys_vendor_id = pci_cfg_rd_w(addr_f, 156 4 PCI_SUB_SYSTEM_ID); 157 4 158 4 tmpl = pci_cfg_rd_l(addr_f, PCI_REV_ID); 159 4 pinfo->rev_id = tmpl & 0xf; 160 4 pinfo->class_code = (tmpl >> 8) & 0xffffff; 161 4 pinfo->base_class = (tmpl >> 24) & 0xff; 162 4 pinfo->sub_class = (tmpl >> 16) & 0xff; 163 4 164 4 pinfo->cfg_addr = addr_f; 165 4 166 4 pci_found++; 167 4 168 4 if(pci_found >= MAX_PCI_DEVICES) 169 4 break; 170 4 171 4 pinfo->next = &pci_cfg_info[pci_found]; 172 4 pinfo = pinfo->next; 173 4 174 4 tmpl = pci_cfg_rd_b(addr| (fnum << 8), PCI_HEAD_TYPE); C51 COMPILER V7.06 PCI 08/02/2005 13:30:01 PAGE 4 175 4 if(!(tmpl & MULTI_FUNC_BIT)) 176 4 break; 177 4 } 178 3 } 179 2 } 180 1 pinfo->next = 0; 181 1 return &pci_cfg_info[0]; 182 1 } /* get_pci_cfg_info_tbl() */ 183 184 185 ULONG pci_cfg_read(ULONG dev_idx, ULONG offset, ULONG bytes) 186 { 187 1 ULONG addr; 188 1 189 1 addr = pci_cfg_info[dev_idx].cfg_addr; 190 1 191 1 if(bytes == 1) 192 1 return pci_cfg_rd_b(addr, offset); 193 1 else if(bytes == 2) 194 1 return pci_cfg_rd_w(addr, offset); 195 1 else 196 1 return pci_cfg_rd_l(addr, offset); 197 1 198 1 } 199 200 201 USHORT pci_cfg_rd_w(ULONG addr, ULONG offset) 202 { 203 1 USHORT wtmp; 204 1 205 1 addr |= CFG_SPACE_ENA; 206 1 outpd(CFG_ADDR_REG, addr | OFFSET_TO_DW_INDEX(offset)); 207 1 wtmp = inport(CFG_DATA_REG | OFFSET_TO_BYTE_INDEX(offset)); 208 1 outpd(CFG_ADDR_REG, 0); 209 1 210 1 return wtmp; 211 1 } /* pci_cfg_rd_w() */ 212 213 UCHAR pci_cfg_rd_b(ULONG addr, ULONG offset) 214 { 215 1 UCHAR btmp; 216 1 217 1 addr |= CFG_SPACE_ENA; 218 1 outpd(CFG_ADDR_REG, addr | OFFSET_TO_DW_INDEX(offset)); 219 1 btmp = inportb(CFG_DATA_REG | OFFSET_TO_BYTE_INDEX(offset)); 220 1 outpd(CFG_ADDR_REG, 0); 221 1 222 1 return btmp; 223 1 224 1 } /* pci_cfg_rd_b() */ 225 226 227 ULONG pci_cfg_rd_l(ULONG addr, ULONG offset) 228 { 229 1 ULONG ltmp; 230 1 231 1 addr |= CFG_SPACE_ENA; 232 1 outpd(CFG_ADDR_REG, addr | OFFSET_TO_DW_INDEX(offset)); 233 1 ltmp = inpd(CFG_DATA_REG); 234 1 outpd(CFG_ADDR_REG, 0); 235 1 236 1 return ltmp; C51 COMPILER V7.06 PCI 08/02/2005 13:30:01 PAGE 5 237 1 238 1 } /* pci_cfg_rd_l() */ 239 240 241 242 ULONG findPCIdev(ULONG classcode, ULONG *puBaseAddress, ULONG *puIntLevel) 243 { 244 1 PCI_CFG_INFO *pci_tblp; 245 1 ULONG dev_idx; 246 1 ULONG uHostType; 247 1 ULONG uRetVal; 248 1 ULONG uData; 249 1 dev_idx = 0; 250 1 pci_tblp = get_pci_cfg_info_tbl(); 251 1 252 1 /*************************************/ 253 1 /* No PCI device found in the system */ 254 1 /*************************************/ 255 1 if(pci_tblp->vendor_id == 0xffff && pci_tblp->dev_id == 0xffff) { 256 2 return 0; 257 2 } 258 1 259 1 /*************************************/ 260 1 /* Search for USB host controllers */ 261 1 /*************************************/ 262 1 while (pci_tblp) { 263 2 /* Is it the end of pSOS PCI device table? */ 264 2 if (pci_tblp->vendor_id == 0xffff && pci_tblp->dev_id == 0xffff) 265 2 break; 266 2 267 2 /* Is it a USB host controller? */ 268 2 if (pci_tblp->class_code == classcode) { 269 3 *puBaseAddress = pci_cfg_read(dev_idx, PCI_BASE_ADDR_2, 4UL) & 0xFFFFFFF0; 270 3 g_bridge_setting_IO = pci_cfg_read(dev_idx, PCI_BASE_ADDR_1, 4UL) & 0xFFFFFFF0; 271 3 *puIntLevel = pci_cfg_read(dev_idx, PCI_INTR_LINE, 1UL); 272 3 return 1; 273 3 } /* if */ 274 2 275 2 dev_idx++; 276 2 pci_tblp = pci_tblp->next; 277 2 278 2 } /* while */ 279 1 280 1 return 0; 281 1 282 1 } /* findPCIdev() */ 283 284 void set_pci_bridge( void ) 285 { 286 1 unsigned long wait_cycle=3L; 287 1 unsigned long tmp; 288 1 289 1 tmp = inpd (g_bridge_setting_IO + 0x18); 290 1 tmp &= ~0x0000003C; // mask register[5..2] 291 1 tmp |= wait_cycle << 2; 292 1 293 1 outpd(g_bridge_setting_IO + 0x18, tmp); 294 1 outpd( g_bridge_setting_IO + 0x68, 0x00000900 ); 295 1 } 296 297 C51 COMPILATION COMPLETE. 1 WARNING(S), 4 ERROR(S)