Changeset 295 for soft/giet_vm/giet_drivers/ioc_driver.c
- Timestamp:
- Mar 26, 2014, 6:44:44 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_drivers/ioc_driver.c
r289 r295 7 7 /////////////////////////////////////////////////////////////////////////////////// 8 8 // The ioc_driver.c and ioc_driver.h files are part ot the GIET-VM kernel. 9 // This driver supports the SocLib vci_block_device component, that is 10 // a single channel, block oriented, external storage contrÃŽler. 11 // 12 // It can exist only one block-device controler in the architecture. 13 // 14 // The _ioc_read() and _ioc_write() functions use the _ioc_access() function, 15 // that is always blocking. The _ioc_access function will call the read or 16 // write function in the driver of the choosen IOC peripheral, which can be for 17 // now: BDV, HBA and SPI. This function can be called in 4 modes: 18 // 19 // - In BOOT_PA mode, the _ioc_access() function use the buffer virtual address 20 // as a physical address (as the page tables are not build). This mode is 21 // used by the boot code to load the map.bin file into memory. 22 // 23 // - In BOOT_VA mode, the _ioc_access() function makes a V2P translation to 24 // compute the buffer physical address. This mode is used by the boot code to 25 // load the various .elf files into memory. 26 // 27 // - In KERNEL mode, the _ioc_access() function makes a V2P translation to 28 // compute the buffer physical address. There is no checking of user access 29 // right to the memory buffer. This mode must be used to access IOC, for an 30 // "open" system call. 31 // 32 // - In USER mode, the _ioc_access() function makes a V2P translation to 33 // compute the buffer physical address. The user access right to the memory 34 // buffer must be checked. This mode must be used to access IOC, for a 35 // "read/write" system call. 9 // 10 // This abstact driver define a generic API, supporting various physical 11 // block device controlers, including: 12 // - vci_block_device : single channel) => bdv_driver 13 // - vci_ahci : multi channels => hba_driver 14 // - sd_card : single channel => sdc_driver 15 // - ramdisk (single channel meory mapped virtual disk) => rdk_driver 16 // 17 // It can exist only one block-device type in the architecture, that must be 18 // defined by one of the following configuration variables in hard_config.h file: 19 // USE_IOC_BDV, USE_IOC_SDC, USE_IOC_HBA, USE_IOC_RDK. 20 // 21 // Any physical driver xxx must provide the following API: 22 // - _xxx_init() 23 // - _xxx_read() 24 // - _xxx_write() 25 // - _xxx_get_status() 26 // - _xxx_get_block_size() 27 // The "channel" parameter is no transmited to single channel devices. 28 // 29 // The _ioc_read() and _ioc_write() functions are always blocking for 30 // the calling user program. 31 // 32 // These functions compute the physical address of the memory buffer before 33 // calling the proper physical device. They can be called in 3 modes: 34 // 35 // - In BOOT mode, these functions use the buffer virtual address 36 // as a physical address if the MMU is not activated. 37 // They make a V2P translation if the MMU is activated. 38 // This mode is used to load the map.bin file (before memory activation), 39 // or to load the various .elf files (after MMU activation). 40 // 41 // - In KERNEL mode, these functions make a V2P translation to 42 // compute the buffer physical address. 43 // There is no checking of user access right to the memory buffer. 44 // This mode must be used for an "open" system call. 45 // 46 // - In USER mode, these functions make a V2P translation to 47 // compute the buffer physical address. 48 // The user access right to the memory buffer are checked. 49 // This mode must be used for a "read" or "write" system call. 36 50 // 37 51 // The IOMMU can be activated or not: … … 60 74 // if the IOMMU is not activated. 61 75 // An error code is returned if these conditions are not verified. 76 // 77 // The "seg_ioc_base" virtual base address of the segment containing the 78 // memory-mapped registers of the device must be defined in the giet_vsegs.ld file. 79 // If the RAMDISK is used, an extra memory segment with virtual base address 80 // "seg_ramdisk_base" must be defined in the giet_vsegs.ld file. 62 81 /////////////////////////////////////////////////////////////////////////////////// 63 // The seg_ioc_base virtual base addresses must be defined in giet_vsegs.ld file. 82 // Implementation note: 83 // In order to share the code, the two _ioc_read() and _ioc_write() functions 84 // call the same _ioc_access() function. 64 85 /////////////////////////////////////////////////////////////////////////////////// 65 86 66 87 #include <giet_config.h> 67 88 #include <ioc_driver.h> 89 #include <bdv_driver.h> 90 #include <hba_driver.h> 91 #include <sdc_driver.h> 92 #include <rdk_driver.h> 68 93 #include <utils.h> 69 94 #include <tty_driver.h> … … 81 106 #endif 82 107 83 #if (USE_ BDV + USE_SPI + USE_HBA) != 184 # error: You must use only one IOC controller (BDV or SPI or HBA)85 #endif 86 87 #if USE_ BDV108 #if (USE_IOC_BDV + USE_IOC_SPI + USE_IOC_HBA + USE_IOC_RDK) != 1 109 # error: You must use only one IOC controller type (BDV or SPI or HBA or RDK) 110 #endif 111 112 #if USE_IOC_BDV 88 113 # include <bdv_driver.h> 89 114 #endif 90 115 91 #if USE_ SPI116 #if USE_IOC_SPI 92 117 # include <sdc_driver.h> 93 118 #endif 94 119 95 #if USE_ HBA120 #if USE_IOC_HBA 96 121 # include <hba_driver.h> 97 122 #endif 98 123 124 #if USE_IOC_RDK 125 # include <rdk_driver.h> 126 #endif 127 128 /////////////////////////////////////////////////////////////////////////////// 129 // IOC global variables 130 /////////////////////////////////////////////////////////////////////////////// 99 131 100 132 #define in_unckdata __attribute__((section (".unckdata"))) 101 133 102 ///////////////////// IOC global variables103 104 in_unckdata unsigned int _ioc_lock = 0;105 in_unckdata unsigned int _ioc_status = 0;106 in_unckdata volatile unsigned int _ioc_gtid;107 134 in_unckdata volatile unsigned int _ioc_iommu_ix1 = 0; 108 135 in_unckdata volatile unsigned int _ioc_iommu_npages; 109 136 110 137 /////////////////////////////////////////////////////////////////////////////// 111 // _ioc_access()112 138 // This function transfer data between a memory buffer and the block device. 113 139 // The buffer lentgth is (count*block_size) bytes. 114 140 // Arguments are: 115 141 // - to_mem : from external storage to memory when non 0. 116 // - kernel : kernel buffer with identity mapping when non 0.142 // - mode : BOOT_PA / BOOT_VA / KERNEL / USER 117 143 // - lba : first block index on the external storage. 118 144 // - buf_vaddr : virtual base address of the memory buffer. … … 121 147 /////////////////////////////////////////////////////////////////////////////// 122 148 static unsigned int _ioc_access( unsigned int to_mem, 149 unsigned int channel, 123 150 unsigned int mode, 124 151 unsigned int lba, … … 128 155 129 156 #if GIET_DEBUG_IOC_DRIVER 130 _tty_get_lock( 0 ); 131 _puts("\n[IOC DEBUG] Enter _ioc_access() at cycle "); 132 _putd( _get_proctime() ); 133 _puts(" for processor "); 134 _putd( _get_procid() ); 135 _puts("\n - mode = "); 136 _putd( mode ); 137 _puts("\n - vaddr = "); 138 _putx( buf_vaddr ); 139 _puts("\n - sectors = "); 140 _putd( count ); 141 _puts("\n - lba = "); 142 _putx( lba ); 143 _puts("\n"); 144 _tty_release_lock( 0 ); 157 unsigned int procid = _get_procid(); 158 unsigned int cid = procid / NB_PROCS_MAX; 159 unsigned int lpid = procid % NB_PROCS_MAX; 160 unsigned int x = cid >> Y_WIDTH; 161 unsigned int y = cid & ((1<<Y_WIDTH) - 1); 162 163 _printf("\n[IOC DEBUG] Processor[%d,%d,%d] enters _ioc_access() at cycle %d\n" 164 " - channel = %d\n" 165 " - mode = %d\n" 166 " - vaddr = %d\n" 167 " - sectors = %d\n" 168 " - lba = %d\n", 169 x, y, lpid, _get_proctime(), channel, mode, buf_vaddr, count, lba ); 145 170 #endif 146 171 … … 160 185 if ((unsigned int) buf_vaddr & 0x3) 161 186 { 162 _tty_get_lock( 0 ); 163 _puts("\n[GIET ERROR] in _ioc_access() : buffer not word aligned\n"); 164 _tty_release_lock( 0 ); 165 return 1; 187 _printf("\n[GIET ERROR] in _ioc_access() : buffer not word aligned\n"); 188 _exit(); 189 } 190 191 // check channel 192 if ( (USE_IOC_HBA == 0) && (channel > 0) ) 193 { 194 _printf("\n[GIET ERROR] in _ioc_access() : channel must be 0 when HBA not used\n"); 195 _exit(); 166 196 } 167 197 168 198 unsigned int length = count << 9; // count * 512 bytes 169 199 170 // computing targetbuffer physical address171 if ( mode == IOC_BOOT_PA_MODE )// identity mapping200 // computing memory buffer physical address 201 if ( (mode == IOC_BOOT_MODE) && ((_get_mmu_mode() & 0x4) == 0) ) // identity mapping 172 202 { 173 203 buf_paddr = (paddr_t)buf_vaddr; 174 204 } 175 else // V2P translation205 else // V2P translation required 176 206 { 177 207 // get page table virtual address 178 208 pt_vbase = _get_context_slot(CTX_PTAB_ID); 179 vpn_min = buf_vaddr >> 12;180 vpn_max = (buf_vaddr + length - 1) >> 12;209 vpn_min = buf_vaddr >> 12; 210 vpn_max = (buf_vaddr + length - 1) >> 12; 181 211 182 212 // loop on all virtual pages covering the user buffer 183 for (vpn = vpn_min, ix2 = 0 ; 184 vpn <= vpn_max ; 185 vpn++, ix2++ ) 213 for (vpn = vpn_min, ix2 = 0 ; vpn <= vpn_max ; vpn++, ix2++ ) 186 214 { 187 215 // get ppn and flags for each vpn … … 193 221 if ( ko ) 194 222 { 195 _tty_get_lock( 0 ); 196 _puts("\n[GIET ERROR] in _ioc_access() : buffer unmapped\n"); 197 _tty_release_lock( 0 ); 223 _printf("\n[GIET ERROR] in _ioc_access() : buffer unmapped\n"); 198 224 return 1; 199 225 } … … 201 227 if ( (mode == IOC_USER_MODE) && ((flags & PTE_U) == 0) ) 202 228 { 203 _tty_get_lock( 0 ); 204 _puts("\n[GIET ERROR] in _ioc_access() : buffer not user accessible\n"); 205 _tty_release_lock( 0 ); 229 _printf("\n[GIET ERROR] in _ioc_access() : buffer not user accessible\n"); 206 230 return 1; 207 231 } … … 209 233 if ( ((flags & PTE_W) == 0 ) && to_mem ) 210 234 { 211 _tty_get_lock( 0 ); 212 _puts("\n[GIET ERROR] in _ioc_access() : buffer not writable\n"); 213 _tty_release_lock( 0 ); 235 _printf("\n[GIET ERROR] in _ioc_access() : buffer not writable\n"); 214 236 return 1; 215 237 } … … 223 245 if (ix2 > 511) // check buffer length < 2 Mbytes 224 246 { 225 _tty_get_lock( 0 ); 226 _puts("\n[GIET ERROR] in _ioc_access() : user buffer > 2 Mbytes\n"); 227 _tty_release_lock( 0 ); 247 _printf("\n[GIET ERROR] in _ioc_access() : user buffer > 2 Mbytes\n"); 228 248 return 1; 229 249 } … … 242 262 if ((ppn - ppn_first) != ix2) 243 263 { 244 _tty_get_lock( 0 ); 245 _puts("[GIET ERROR] in _ioc_access() : split physical buffer\n"); 246 _tty_release_lock( 0 ); 264 _printf("[GIET ERROR] in _ioc_access() : split physical buffer\n"); 247 265 return 1; 248 266 } … … 272 290 else // memory read : update data caches 273 291 { 274 // L1 cache : nothing to do ifL1 write-through292 // L1 cache : nothing to do for L1 write-through 275 293 276 294 // L2 cache (only if IOB used) … … 280 298 if ( GIET_USE_IOMMU ) buf_paddr = (paddr_t) buf_xaddr; 281 299 282 #if USE_BDV 283 if (to_mem) error = _bdv_read (mode, lba, buf_paddr, count); 284 else error = _bdv_write(mode, lba, buf_paddr, count); 285 #elif USE_SPI 286 if (to_mem) error = _sdc_read (mode, lba, buf_paddr, count); 287 else error = _sdc_write(mode, lba, buf_paddr, count); 288 #elif USE_HBA 289 if (to_mem) error = _hba_read (mode, lba, buf_paddr, count); 290 else error = _hba_write(mode, lba, buf_paddr, count); 300 /////////////////////////////////////////// 301 // select the proper physical device 302 /////////////////////////////////////////// 303 304 #if ( USE_IOC_BDV ) 305 306 #if GIET_DEBUG_IOC_DRIVER 307 _printf("\n[IOC DEBUG] Calling BDV driver\n"); 308 #endif 309 if (to_mem) error = _bdv_read ( mode, lba, buf_paddr, count); 310 else error = _bdv_write( mode, lba, buf_paddr, count); 311 312 #elif ( USE_IOC_SPI ) 313 314 #if GIET_DEBUG_IOC_DRIVER 315 _printf("\n[IOC DEBUG] Calling SPI driver\n"); 316 #endif 317 if (to_mem) error = _sdc_read (mode, lba, buf_paddr, count); 318 else error = _sdc_write(mode, lba, buf_paddr, count); 319 320 #elif ( USE_IOC_HBA ) 321 322 #if GIET_DEBUG_IOC_DRIVER 323 _printf("\n[IOC DEBUG] Calling HBA driver\n"); 324 #endif 325 if (to_mem) error = _hba_read (channel, mode, lba, buf_paddr, count); 326 else error = _hba_write(channel, mode, lba, buf_paddr, count); 327 328 #elif ( USE_IOC_RDK ) 329 330 #if GIET_DEBUG_IOC_DRIVER 331 _printf("\n[IOC DEBUG] Calling RDK driver\n"); 332 #endif 333 if (to_mem) error = _rdk_read (lba, buf_vaddr, count); 334 else error = _rdk_write(lba, buf_vaddr, count); 335 291 336 #endif 292 337 … … 295 340 296 341 /////////////////////////////////////////////////////////////////////////////// 297 // _ioc_init()298 342 // This function cheks block size, and activates the IOC interrupts. 299 343 // Return 0 for success. … … 301 345 unsigned int _ioc_init( unsigned int channel ) 302 346 { 303 #if USE_BDV 304 return _bdv_init( channel ); 305 #elif USE_SPI 306 return _sdc_init( channel ); 307 #elif USE_HBA 347 348 #if ( USE_IOC_BDV ) 349 350 return _bdv_init(); 351 352 #elif ( USE_IOC_SPI ) 353 354 return _sdc_init(); 355 356 #elif ( USE_IOC_HBA ) 357 308 358 return _hba_init( channel ); 309 #endif 359 360 #elif ( USE_IOC_RDK ) 361 362 return _rdk_init(); 363 364 #endif 365 310 366 } 311 367 312 368 /////////////////////////////////////////////////////////////////////////////// 313 // _ioc_read()314 369 // Transfer data from the block device to a memory buffer. 315 // - mode : BOOT / KERNEL / USER370 // - mode : BOOT_PA / BOOT_VA / KERNEL / USER 316 371 // - lba : first block index on the block device 317 372 // - buffer : base address of the memory buffer (must be word aligned) … … 319 374 // Returns 0 if success, > 0 if error. 320 375 /////////////////////////////////////////////////////////////////////////////// 321 unsigned int _ioc_read( unsigned int mode, 376 unsigned int _ioc_read( unsigned int channel, 377 unsigned int mode, 322 378 unsigned int lba, 323 379 void* buffer, … … 325 381 { 326 382 return _ioc_access( 1, // read access 383 channel, 327 384 mode, 328 385 lba, … … 332 389 333 390 /////////////////////////////////////////////////////////////////////////////// 334 // _ioc_write()335 391 // Transfer data from a memory buffer to the block device. 336 // - mode : BOOT / KERNEL / USER392 // - mode : BOOT_PA / BOOT_VA / KERNEL / USER 337 393 // - lba : first block index on the block device 338 394 // - buffer : base address of the memory buffer (must be word aligned) … … 340 396 // Returns 0 if success, > 0 if error. 341 397 /////////////////////////////////////////////////////////////////////////////// 342 unsigned int _ioc_write( unsigned int mode, 398 unsigned int _ioc_write( unsigned int channel, 399 unsigned int mode, 343 400 unsigned int lba, 344 401 const void* buffer, … … 346 403 { 347 404 return _ioc_access( 0, // write access 405 channel, 348 406 mode, 349 407 lba, … … 353 411 354 412 /////////////////////////////////////////////////////////////////////////////// 355 // _ioc_get_status()356 413 // This function returns in the status variable, the transfert status, and 357 414 // acknowledge the IRQ if the IOC controler is not busy. 358 415 // Returns 0 if success, > 0 if error 359 416 /////////////////////////////////////////////////////////////////////////////// 360 unsigned int _ioc_get_status( unsigned int channel, 361 unsigned int* status ) 362 { 363 #if USE_BDV 364 return _bdv_get_status(channel, status); 365 #elif USE_SPI 366 return _sdc_get_status(channel, status); 367 #elif USE_HBA 368 return _hba_get_status(channel, status); 369 #endif 417 unsigned int _ioc_get_status( unsigned int channel ) 418 { 419 420 #if ( USE_IOC_BDV ) 421 422 return _bdv_get_status( ); 423 424 #elif ( USE_IOC_SPI ) 425 426 return _sdc_get_status( ); 427 428 #elif ( USE_IOC_HBA ) 429 430 return _hba_get_status( channel ); 431 432 #elif ( USE_IOC_RDK ) 433 434 _printf("[GIET ERROR] _ioc_get_status() should not be called"); 435 _printf(" when RAMDISK is used...\n"); 436 _exit(); 437 438 return 0; 439 440 #endif 441 370 442 } 371 443 372 444 /////////////////////////////////////////////////////////////////////////////// 373 // _ioc_get_block_size()374 445 // This function returns the block_size with which the IOC has been configured. 375 446 /////////////////////////////////////////////////////////////////////////////// 376 447 unsigned int _ioc_get_block_size() 377 448 { 378 #if USE_BDV 449 450 #if ( USE_IOC_BDV ) 451 379 452 return _bdv_get_block_size(); 380 #elif USE_SPI 453 454 #elif ( USE_IOC_SPI ) 455 381 456 return _sdc_get_block_size(); 382 #elif USE_HBA 457 458 #elif ( USE_IOC_HBA ) 459 383 460 return _hba_get_block_size(); 384 #endif 461 462 #elif ( USE_IOC_RDK ) 463 464 return 512; 465 466 #endif 467 385 468 } 386 469
Note: See TracChangeset
for help on using the changeset viewer.