Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

781 lines
18 KiB

  1. /*--------------------------------------------------------------------------
  2. *
  3. * Copyright (C) Cyclades Corporation, 1997-2001.
  4. * All rights reserved.
  5. *
  6. * Cyclades-Z Enumerator Driver
  7. *
  8. * This file: cyzload.c
  9. *
  10. * Description: This is the firmware loader for the Cyclades-Z series
  11. * of multiport serial cards.
  12. *
  13. * Notes: This code supports Windows 2000 and Windows XP,
  14. * x86 and ia64 processors.
  15. *
  16. * Complies with Cyclades SW Coding Standard rev 1.3.
  17. *
  18. *--------------------------------------------------------------------------
  19. */
  20. /*-------------------------------------------------------------------------
  21. *
  22. * Change History
  23. *
  24. *--------------------------------------------------------------------------
  25. *
  26. *
  27. *--------------------------------------------------------------------------
  28. */
  29. #include "pch.h"
  30. /*-------------------------------
  31. *
  32. * Prototypes
  33. *
  34. *--------------------------------
  35. */
  36. ULONG
  37. z_ident( Z_BOARD_IDENT board );
  38. VOID
  39. z_block_copy( Z_BOARD_IDENT board, PVOID ptr, ULONG offset, ULONG size );
  40. VOID
  41. z_fpga_copy( Z_BOARD_IDENT board, PVOID ptr, ULONG size );
  42. VOID
  43. z_start_cpu( Z_BOARD_IDENT board );
  44. //VOID
  45. //z_stop_cpu(
  46. // Z_BOARD_IDENT board
  47. //);
  48. //
  49. //int
  50. //z_fpga_check(
  51. // Z_BOARD_IDENT board
  52. //);
  53. //
  54. //VOID
  55. //z_reset_board( Z_BOARD_IDENT board );
  56. HANDLE
  57. zl_fopen( PCWSTR file_name );
  58. VOID
  59. zl_fclose( IN Z_STREAM NtFileHandle );
  60. ULONG
  61. zl_fread( IN PVOID ptr,
  62. IN ULONG size,
  63. IN ULONG count,
  64. IN Z_STREAM stream,
  65. IN ULONG Uoffset );
  66. VOID
  67. zl_delay( LONG number_of_ms );
  68. #ifdef CHANGE_FOR_Z
  69. //#ifdef ALLOC_PRAGMA
  70. //#pragma alloc_text(INIT,z_load)
  71. //#pragma alloc_text(INIT,z_ident)
  72. //#pragma alloc_text(INIT,z_block_copy)
  73. //#pragma alloc_text(INIT,z_fpga_copy)
  74. //#pragma alloc_text(INIT,z_start_cpu)
  75. //#pragma alloc_text(INIT,zl_fopen)
  76. //#pragma alloc_text(INIT,zl_fclose)
  77. //#pragma alloc_text(INIT,zl_fread)
  78. //#pragma alloc_text(INIT,zl_delay)
  79. //#ifdef RESET_BOARD
  80. //#pragma alloc_text(PAGESER,z_reset_board)
  81. //#else
  82. //#pragma alloc_text(INIT,z_reset_board)
  83. //#endif
  84. //#pragma alloc_text(PAGESER,z_fpga_check)
  85. //#pragma alloc_text(PAGESER,z_stop_cpu)
  86. //#endif
  87. #endif
  88. #ifndef ZBUF_STACK
  89. static struct ZFILE_HEADER header;
  90. static struct ZFILE_CONFIG config;
  91. static struct ZFILE_BLOCK block;
  92. static char data[ZBUF_SIZE];
  93. #endif
  94. /*------------------------------------------------------------------------
  95. *
  96. * z_load( IN Z_BOARD_IDENT board,
  97. * IN UINT32 function,
  98. * IN PCWSTR filename )
  99. *
  100. *-------------------------------------------------------------------------
  101. *
  102. * Description: Loads the Cyclades-Z Firmware. Returns a non-zero on error.
  103. *
  104. *-------------------------------------------------------------------------
  105. */
  106. int
  107. z_load (
  108. Z_BOARD_IDENT board, UINT32 function, PCWSTR filename)
  109. {
  110. unsigned long i;
  111. unsigned long dpmem;
  112. unsigned long count;
  113. Z_STREAM file;
  114. //*********************
  115. //size_t s, s2;
  116. //*********************
  117. unsigned long s,s2;
  118. unsigned long mailbox;
  119. unsigned long load_fpga_flag = TRUE;
  120. unsigned long first_time = TRUE;
  121. #ifdef ZBUF_STACK
  122. struct ZFILE_HEADER header;
  123. struct ZFILE_CONFIG config;
  124. struct ZFILE_BLOCK block;
  125. char data[ZBUF_SIZE];
  126. #endif
  127. mailbox = z_ident(board);
  128. file = zl_fopen (filename);
  129. if (file!=NULL)
  130. {
  131. /* Read the header */
  132. zl_fread (&header, sizeof(header), 1, file, 0);
  133. /* Find the correct configuration */
  134. for (i=0; i<header.n_config; i++)
  135. {
  136. zl_fread (&config, sizeof(config), 1, file,
  137. header.config_offset + (sizeof(config)*i));
  138. if (config.mailbox==mailbox && config.function==function)
  139. break;
  140. }
  141. /* Return error: No matching configuration */
  142. if (i>=header.n_config)
  143. {
  144. zl_fclose (file);
  145. return (ZL_RET_NO_MATCHING_FW_CONFIG);
  146. }
  147. #ifndef DEBUG_LOAD
  148. if ((mailbox == 0) || (z_fpga_check(board))) {
  149. load_fpga_flag = FALSE;
  150. z_stop_cpu(board);
  151. }
  152. #endif
  153. #ifdef RESET_BOARD
  154. load_fpga_flag = TRUE;
  155. /* Reset the board */
  156. z_reset_board (board);
  157. #endif
  158. /* Load each block */
  159. for (i=0; i<config.n_blocks; i++)
  160. {
  161. /* Load block struct */
  162. zl_fread (&block, sizeof(block), 1, file,
  163. header.block_offset+(sizeof(block)*config.block_list[i]));
  164. /* Load and Copy the data block */
  165. count=0;
  166. s = block.size;
  167. while (s>0)
  168. {
  169. s2 = zl_min(ZBUF_SIZE,s);
  170. if (zl_fread (data, 1, s2, file, block.file_offset + count)!=0) {
  171. /* Call the copy function */
  172. if (block.type==ZBLOCK_FPGA) {
  173. if (load_fpga_flag) {
  174. z_fpga_copy (board, data, s2);
  175. }
  176. } else {
  177. if (first_time) {
  178. CYZ_WRITE_ULONG(&((board->Runtime)->loc_addr_base),
  179. WIN_RAM);
  180. //Code added to debug pentium II
  181. //RtlFillMemory( (PUCHAR)board->BoardMemory,
  182. // board->DPMemSize, 0x00 );
  183. for (dpmem=0; dpmem<board->BoardMemoryLength; dpmem++) {
  184. CYZ_WRITE_UCHAR(board->BoardMemory+dpmem,0x00);
  185. }
  186. first_time = FALSE;
  187. }
  188. z_block_copy (board, data, block.ram_offset + count, s2);
  189. }
  190. count += s2;
  191. s -= s2;
  192. } else {
  193. zl_fclose (file);
  194. return (ZL_RET_FILE_READ_ERROR);
  195. }
  196. } // end for (reading every ZBUF_SIZE)
  197. if (block.type==ZBLOCK_FPGA) {
  198. /* Delay for around for 1ms */
  199. zl_delay(1); /* Is this needed? */
  200. if (!z_fpga_check(board)) {
  201. zl_fclose(file);
  202. return(ZL_RET_FPGA_ERROR);
  203. }
  204. }
  205. } // end for (reading every block)
  206. zl_fclose (file);
  207. z_start_cpu(board);
  208. return (ZL_RET_SUCCESS);
  209. } else {
  210. /* Return error: Error opening file */
  211. return (ZL_RET_FILE_OPEN_ERROR);
  212. }
  213. }
  214. /*------------------------------------------------------------------------
  215. *
  216. * z_ident( IN Z_BOARD_IDENT board )
  217. *
  218. *-------------------------------------------------------------------------
  219. *
  220. * Description: Returns the ID number (the mailbox reg)
  221. *
  222. *-------------------------------------------------------------------------
  223. */
  224. ULONG
  225. z_ident( Z_BOARD_IDENT board )
  226. {
  227. ULONG mailbox;
  228. mailbox = CYZ_READ_ULONG(&(board->Runtime)->mail_box_0);
  229. return (mailbox);
  230. }
  231. /*------------------------------------------------------------------------
  232. *
  233. * z_reset_board( IN Z_BOARD_IDENT board )
  234. *
  235. *-------------------------------------------------------------------------
  236. *
  237. * Description: Resets the board using the PLX registers.
  238. *
  239. *-------------------------------------------------------------------------
  240. */
  241. VOID
  242. z_reset_board( Z_BOARD_IDENT board )
  243. {
  244. ULONG sav_buf[12];
  245. PULONG loc_reg;
  246. ULONG j;
  247. ULONG init_ctrl;
  248. LARGE_INTEGER d100ms = RtlConvertLongToLargeInteger(-100*10000);
  249. // Prepare board for reset.
  250. // The PLX9060 seems to destroy the local registers
  251. // when there is a hard reset. So, we save all
  252. // important registers before resetting the board.
  253. loc_reg = (ULONG *) board->Runtime;
  254. for (j=0; j<12; j++) {
  255. sav_buf[j] = CYZ_READ_ULONG(&loc_reg[j]);
  256. }
  257. // Reset board
  258. init_ctrl = CYZ_READ_ULONG(&(board->Runtime)->init_ctrl);
  259. init_ctrl |= 0x40000000;
  260. CYZ_WRITE_ULONG(&(board->Runtime)->init_ctrl,init_ctrl);
  261. KeDelayExecutionThread(KernelMode,FALSE,&d100ms);
  262. init_ctrl &= ~(0x40000000);
  263. CYZ_WRITE_ULONG(&(board->Runtime)->init_ctrl,init_ctrl);
  264. KeDelayExecutionThread(KernelMode,FALSE,&d100ms);
  265. // Restore loc conf registers
  266. for (j=0; j<12; j++) {
  267. CYZ_WRITE_ULONG(&loc_reg[j],sav_buf[j]);
  268. }
  269. }
  270. /*------------------------------------------------------------------------
  271. *
  272. * z_block_copy( IN Z_BOARD_IDENT board,
  273. * IN PVOID ptr,
  274. * IN ULONG offset,
  275. * IN ULONG size )
  276. *
  277. *-------------------------------------------------------------------------
  278. *
  279. * Description: This function should copy size bytes of data from the
  280. * buffer pointed to by ptr into the Cyclades-Z's memory starting at
  281. * offset.
  282. *
  283. *-------------------------------------------------------------------------
  284. */
  285. VOID
  286. z_block_copy (Z_BOARD_IDENT board, PVOID ptr, ULONG offset, ULONG size)
  287. {
  288. //Code added to debug Pentium II
  289. // RtlCopyMemory( (PUCHAR)board->BoardMemory + offset, ptr, size );
  290. ULONG numOfLongs;
  291. ULONG numOfBytes;
  292. numOfLongs = size/sizeof(ULONG);
  293. numOfBytes = size%sizeof(ULONG);
  294. while (numOfLongs--) {
  295. CYZ_WRITE_ULONG((PULONG)(board->BoardMemory + offset), *((PULONG)ptr));
  296. //offset++;
  297. offset += sizeof(ULONG);
  298. ((PULONG)ptr)++;
  299. }
  300. while (numOfBytes--) {
  301. CYZ_WRITE_UCHAR((PUCHAR)board->BoardMemory + offset, *((PUCHAR)ptr));
  302. offset++;
  303. ((PUCHAR)ptr)++;
  304. }
  305. }
  306. /*------------------------------------------------------------------------
  307. *
  308. * z_fpga_copy( IN Z_BOARD_IDENT board,
  309. * IN PVOID ptr,
  310. * IN ULONG size )
  311. *
  312. *-------------------------------------------------------------------------
  313. *
  314. * Description: This function is the same as z_block_copy, except the
  315. * offset is assumed to always be zero (and not increment) and the copy
  316. * is done one byte at a time. Essentially, this is the same as writing
  317. * a buffer to a byte-wide FIFO.
  318. *
  319. *-------------------------------------------------------------------------
  320. */
  321. VOID
  322. z_fpga_copy (Z_BOARD_IDENT board, PVOID ptr, ULONG size)
  323. {
  324. int i;
  325. char *data;
  326. char *fpga;
  327. fpga = board->BoardMemory;
  328. data = (char *)ptr;
  329. while (size>0)
  330. {
  331. CYZ_WRITE_UCHAR(fpga,*data);
  332. KeStallExecutionProcessor(10); // wait 10 microseconds
  333. size--;
  334. data++;
  335. }
  336. }
  337. /*------------------------------------------------------------------------
  338. *
  339. * z_fpga_check( IN Z_BOARD_IDENT board )
  340. *
  341. *-------------------------------------------------------------------------
  342. *
  343. * Description: Returns 1 if FPGA is configured.
  344. *
  345. *-------------------------------------------------------------------------
  346. */
  347. int
  348. z_fpga_check( Z_BOARD_IDENT board )
  349. {
  350. if (CYZ_READ_ULONG(&(board->Runtime)->init_ctrl) & 0x00020000) {
  351. return 1;
  352. } else {
  353. return 0;
  354. }
  355. }
  356. /*------------------------------------------------------------------------
  357. *
  358. * z_start_cpu( IN Z_BOARD_IDENT board )
  359. *
  360. *-------------------------------------------------------------------------
  361. *
  362. * Description: Starts CPU.
  363. *
  364. *-------------------------------------------------------------------------
  365. */
  366. VOID
  367. z_start_cpu( Z_BOARD_IDENT board )
  368. {
  369. CYZ_WRITE_ULONG(&(board->Runtime)->loc_addr_base,WIN_CREG);
  370. CYZ_WRITE_ULONG(&((struct CUSTOM_REG *) board->BoardMemory)->cpu_start,
  371. 0x00000000);
  372. CYZ_WRITE_ULONG(&(board->Runtime)->loc_addr_base,WIN_RAM);
  373. }
  374. /*------------------------------------------------------------------------
  375. *
  376. * z_stop_cpu( IN Z_BOARD_IDENT board )
  377. *
  378. *-------------------------------------------------------------------------
  379. *
  380. * Description: Stops CPU.
  381. *
  382. *-------------------------------------------------------------------------
  383. */
  384. VOID
  385. z_stop_cpu( Z_BOARD_IDENT board )
  386. {
  387. CYZ_WRITE_ULONG(&(board->Runtime)->loc_addr_base,WIN_CREG);
  388. CYZ_WRITE_ULONG(&((struct CUSTOM_REG *) board->BoardMemory)->cpu_stop,
  389. 0x00000000);
  390. CYZ_WRITE_ULONG(&(board->Runtime)->loc_addr_base,WIN_RAM);
  391. }
  392. /****************************************************************
  393. *
  394. * In David's code, the below functions were macros.
  395. *
  396. *****************************************************************/
  397. /*------------------------------------------------------------------------
  398. *
  399. * zl_fopen(PCWSTR file_name)
  400. *
  401. *-------------------------------------------------------------------------
  402. *
  403. * Description: This routine opens a file, and returns the file handle
  404. * if successful. Otherwise, it returns NULL.
  405. *
  406. *-------------------------------------------------------------------------
  407. */
  408. HANDLE zl_fopen( PCWSTR file_name )
  409. {
  410. UNICODE_STRING fileName;
  411. NTSTATUS ntStatus;
  412. IO_STATUS_BLOCK IoStatus;
  413. HANDLE NtFileHandle;
  414. OBJECT_ATTRIBUTES ObjectAttributes;
  415. ULONG LengthOfFile;
  416. //WCHAR PathPrefix[] = L"\\SystemRoot\\system32\\drivers\\";
  417. WCHAR PathPrefix[] = L"\\SystemRoot\\system32\\cyclad-z\\";
  418. UNICODE_STRING FullFileName;
  419. ULONG FullFileNameLength;
  420. FILE_STANDARD_INFORMATION StandardInfo;
  421. RtlInitUnicodeString( &fileName, file_name );
  422. FullFileNameLength = sizeof(PathPrefix) + fileName.MaximumLength;
  423. FullFileName.Buffer = ExAllocatePool (NonPagedPool,FullFileNameLength);
  424. if (FullFileName.Buffer == NULL) {
  425. return NULL;
  426. }
  427. FullFileName.Length = sizeof(PathPrefix) - sizeof(WCHAR);
  428. FullFileName.MaximumLength = (USHORT)FullFileNameLength;
  429. RtlMoveMemory (FullFileName.Buffer, PathPrefix, sizeof(PathPrefix));
  430. RtlAppendUnicodeStringToString (&FullFileName, &fileName);
  431. InitializeObjectAttributes ( &ObjectAttributes,
  432. &FullFileName,
  433. OBJ_CASE_INSENSITIVE,
  434. NULL,
  435. NULL );
  436. ntStatus = ZwCreateFile( &NtFileHandle,
  437. SYNCHRONIZE | FILE_READ_DATA,
  438. &ObjectAttributes,
  439. &IoStatus,
  440. NULL, // alloc size = none
  441. FILE_ATTRIBUTE_NORMAL,
  442. FILE_SHARE_READ,
  443. FILE_OPEN,
  444. FILE_SYNCHRONOUS_IO_NONALERT,
  445. NULL, // eabuffer
  446. 0 ); // ealength
  447. if ( !NT_SUCCESS( ntStatus ) )
  448. {
  449. ExFreePool(FullFileName.Buffer);
  450. return NULL;
  451. }
  452. ExFreePool(FullFileName.Buffer);
  453. //
  454. // Query the object to determine its length.
  455. //
  456. ntStatus = ZwQueryInformationFile( NtFileHandle,
  457. &IoStatus,
  458. &StandardInfo,
  459. sizeof(FILE_STANDARD_INFORMATION),
  460. FileStandardInformation );
  461. if (!NT_SUCCESS(ntStatus)) {
  462. ZwClose( NtFileHandle );
  463. return NULL;
  464. }
  465. LengthOfFile = StandardInfo.EndOfFile.LowPart;
  466. //
  467. // Might be corrupted.
  468. //
  469. if( LengthOfFile < 1 )
  470. {
  471. ZwClose( NtFileHandle );
  472. return NULL;
  473. }
  474. return NtFileHandle;
  475. }
  476. /*------------------------------------------------------------------------
  477. *
  478. * zl_fclose(IN Z_STREAM NtFileHandle)
  479. *
  480. *-------------------------------------------------------------------------
  481. *
  482. * Description: This routine closes a file.
  483. *
  484. *-------------------------------------------------------------------------
  485. */
  486. VOID zl_fclose(IN Z_STREAM NtFileHandle)
  487. {
  488. ZwClose(NtFileHandle);
  489. }
  490. /*------------------------------------------------------------------------
  491. *
  492. * zl_fread( IN PVOID ptr,
  493. * IN ULONG size,
  494. * IN ULONG count,
  495. * IN Z_STREAM stream,
  496. * IN ULONG Uoffset
  497. *
  498. *-------------------------------------------------------------------------
  499. *
  500. * Description: This routine opens a file, and returns the file handle
  501. * if successful. Otherwise, it returns NULL.
  502. *
  503. *-------------------------------------------------------------------------
  504. */
  505. ULONG zl_fread( IN PVOID ptr,
  506. IN ULONG size,
  507. IN ULONG count,
  508. IN Z_STREAM stream,
  509. IN ULONG Uoffset)
  510. {
  511. IO_STATUS_BLOCK IoStatus;
  512. LARGE_INTEGER Loffset;
  513. NTSTATUS ntStatus;
  514. ULONG readsize;
  515. readsize = size*count;
  516. Loffset = RtlConvertUlongToLargeInteger(Uoffset);
  517. ntStatus = ZwReadFile (stream, NULL, NULL, NULL, &IoStatus,
  518. ptr, readsize, &Loffset, NULL);
  519. if( (!NT_SUCCESS(ntStatus)) || (IoStatus.Information != readsize) )
  520. {
  521. return 0;
  522. }
  523. return readsize;
  524. }
  525. /*------------------------------------------------------------------------
  526. *
  527. * zl_delay( number_of_ms )
  528. *
  529. *-------------------------------------------------------------------------
  530. *
  531. * Description: Delay of milliseconds.
  532. *
  533. *-------------------------------------------------------------------------
  534. */
  535. VOID
  536. zl_delay(
  537. LONG number_of_ms
  538. )
  539. {
  540. LARGE_INTEGER delaytime;
  541. delaytime = RtlConvertLongToLargeInteger(-number_of_ms*10000);
  542. KeDelayExecutionThread(KernelMode,FALSE,&delaytime);
  543. }
  544. /****************************************************************************/
  545. /****************************************************************************/
  546. /****************************************************************************/
  547. /****************************************************************************/
  548. #if 0
  549. //*******************************************************************
  550. //
  551. // Added for debug
  552. //
  553. //*******************************************************************
  554. int
  555. z_verify (
  556. Z_BOARD_IDENT board, UINT32 function, PCWSTR filename)
  557. {
  558. unsigned long i;
  559. unsigned long count;
  560. Z_STREAM file;
  561. //*********************
  562. //size_t s, s2;
  563. //*********************
  564. long s,s2;
  565. unsigned long mailbox;
  566. #ifdef ZBUF_STACK
  567. struct ZFILE_HEADER header;
  568. struct ZFILE_CONFIG config;
  569. struct ZFILE_BLOCK block;
  570. char data[ZBUF_SIZE];
  571. #endif
  572. maibox = z_ident(board);
  573. file = zl_fopen (filename);
  574. if (file!=NULL)
  575. {
  576. /* Read the header */
  577. zl_fread (&header, sizeof(header), 1, file, 0);
  578. /* Find the correct configuration */
  579. for (i=0; i<header.n_config; i++)
  580. {
  581. zl_fread (&config, sizeof(config), 1, file,
  582. header.config_offset + (sizeof(config)*i));
  583. if (config.mailbox==mailbox && config.function==function)
  584. break;
  585. }
  586. /* Return error: No matching configuration */
  587. if (i>=header.n_config)
  588. {
  589. zl_fclose (file);
  590. return (ZL_RET_NO_MATCHING_FW_CONFIG);
  591. }
  592. /* Load each block */
  593. for (i=0; i<config.n_blocks; i++)
  594. {
  595. /* Load block struct */
  596. zl_fread (&block, sizeof(block), 1, file,
  597. header.block_offset+(sizeof(block)*config.block_list[i]));
  598. /* Load and Copy the data block */
  599. count=0;
  600. for (s=block.size; s>0; s-=ZBUF_SIZE)
  601. {
  602. s2 = zl_min(ZBUF_SIZE,s);
  603. if (zl_fread (data, 1, s2, file, block.file_offset + count)!=0) {
  604. /* Call the copy function */
  605. if (block.type==ZBLOCK_FPGA)
  606. z_fpga_copy (board, data, s2);
  607. else {
  608. if (z_block_comp (board, data, block.ram_offset + count,
  609. s2)==0){
  610. zl_fclose(file);
  611. return (3);
  612. }
  613. }
  614. count += s2;
  615. } else {
  616. zl_fclose (file);
  617. return (3);
  618. }
  619. } // end for
  620. } // end for
  621. zl_fclose (file);
  622. return (0);
  623. } else {
  624. /* Return error: Error opening file */
  625. return (2);
  626. }
  627. }
  628. ULONG
  629. z_block_comp (Z_BOARD_IDENT board, PVOID ptr, UINT32 offset, long size)
  630. {
  631. return (RtlCompareMemory( (PUCHAR)board->BoardMemory + offset, ptr, size ));
  632. }
  633. #endif
  634.