1 |
11 |
ashwin_men |
/*-- Copyright (C) 2012
|
2 |
|
|
Ashwin A. Mendon
|
3 |
|
|
|
4 |
|
|
This file is part of SATA2 core.
|
5 |
|
|
|
6 |
|
|
This program is free software; you can redistribute it and/or modify
|
7 |
|
|
it under the terms of the GNU General Public License as published by
|
8 |
|
|
the Free Software Foundation; either version 3 of the License, or
|
9 |
|
|
(at your option) any later version.
|
10 |
|
|
|
11 |
|
|
This program is distributed in the hope that it will be useful,
|
12 |
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14 |
|
|
GNU General Public License for more details.
|
15 |
|
|
|
16 |
|
|
You should have received a copy of the GNU General Public License
|
17 |
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
18 |
|
|
|
19 |
|
|
#include "xparameters.h"
|
20 |
|
|
#include "xutil.h"
|
21 |
|
|
#include "stdio.h"
|
22 |
|
|
|
23 |
|
|
#define SATA_CORE_BASE XPAR_SATA_CORE_0_BASEADDR
|
24 |
|
|
#define DDR_BASE XPAR_DDR3_SDRAM_MPMC_BASEADDR
|
25 |
|
|
#define UART_BASE XPAR_RS232_UART_1_BASEADDR
|
26 |
|
|
#define SATA_LINK_READY 0x00000002
|
27 |
|
|
#define SATA_CORE_DONE 0x00000001
|
28 |
|
|
//#define NPI_DONE 0x00000008
|
29 |
|
|
#define REG_CLEAR 0x00000000
|
30 |
|
|
#define SW_RESET 0x00000001
|
31 |
|
|
#define NEW_CMD 0x00000002
|
32 |
|
|
#define WRITE_CMD 0x00000002
|
33 |
|
|
#define READ_CMD 0x00000001
|
34 |
|
|
#define WORDS_PER_SECTOR 128
|
35 |
|
|
#define NPI_BLOCKS_PER_SECTOR 8
|
36 |
|
|
#define SZ_WORD 4
|
37 |
|
|
|
38 |
|
|
#define SECTOR_ADDRESS 0x00000000
|
39 |
|
|
#define NUM_SECTORS 0x00004000
|
40 |
|
|
|
41 |
|
|
#define REVERSE(a) (((a & 0xff000000) >> 24) | ((a & 0x00ff0000) >> 8) | ((a & 0x0000ff00) << 8) | ((a & 0x000000ff) << 24))
|
42 |
|
|
|
43 |
|
|
// User Selectable Read/Write Addr Space Offset
|
44 |
|
|
#define READ_SPACE_OFFSET 0x8000 // select offset in multiples of 128 bytes (NPI core addr increments in 128 byte offsets)
|
45 |
|
|
#define WRITE_SPACE_OFFSET 0x16000 // select offset in multiples of 128 bytes
|
46 |
|
|
|
47 |
|
|
// Structure maps to Slave Registers
|
48 |
|
|
typedef struct {
|
49 |
|
|
volatile unsigned int ctrl_reg;
|
50 |
|
|
volatile unsigned int cmd_reg;
|
51 |
|
|
volatile unsigned int status_reg;
|
52 |
|
|
volatile unsigned int sector_addr_reg;
|
53 |
|
|
volatile unsigned int sector_count_reg;
|
54 |
|
|
volatile unsigned int sector_timer_reg;
|
55 |
|
|
volatile unsigned int npi_rd_addr_reg;
|
56 |
|
|
volatile unsigned int npi_wr_addr_reg;
|
57 |
|
|
} sata_core;
|
58 |
|
|
|
59 |
|
|
volatile sata_core *scp;
|
60 |
|
|
volatile u32* uartstat = (u32*)UART_BASE;
|
61 |
|
|
volatile u32* ddr3 = (u32*)DDR_BASE;
|
62 |
|
|
|
63 |
|
|
void read_sectors(int sector_addr, int sector_count);
|
64 |
|
|
void write_sectors(int sector_addr, int sector_count);
|
65 |
|
|
|
66 |
|
|
volatile unsigned int i,j;
|
67 |
|
|
|
68 |
|
|
int main (void) {
|
69 |
|
|
int cmd_key, loop, reset;
|
70 |
|
|
scp = (sata_core *)(SATA_CORE_BASE);
|
71 |
|
|
scp->ctrl_reg = REG_CLEAR;
|
72 |
|
|
scp->cmd_reg = REG_CLEAR;
|
73 |
|
|
|
74 |
|
|
xil_printf("\n\r STATUS REG : %x\r\n", scp->status_reg);
|
75 |
|
|
// SATA CORE RESET
|
76 |
|
|
while ((scp->status_reg & SATA_LINK_READY) != SATA_LINK_READY) {
|
77 |
|
|
scp->ctrl_reg = SW_RESET;
|
78 |
|
|
xil_printf("\n\r ---GTX RESET--- \r\n");
|
79 |
|
|
scp->ctrl_reg = REG_CLEAR;
|
80 |
|
|
for(i=0; i<10000000; i++);
|
81 |
|
|
j = j+i;
|
82 |
|
|
xil_printf("\n\r STATUS REG : %x\r\n", scp->status_reg);
|
83 |
|
|
}
|
84 |
|
|
// SATA CORE RESET
|
85 |
|
|
|
86 |
|
|
xil_printf("\n\r ---Testing Sata Core--- \r\n");
|
87 |
|
|
|
88 |
|
|
while (loop != 51) {
|
89 |
|
|
|
90 |
|
|
// Read/Write Command
|
91 |
|
|
xil_printf("\n\rSelect Command: Read-(1) or Write-(2): \r\n");
|
92 |
|
|
cmd_key = uartstat[0];
|
93 |
|
|
while(cmd_key < '0' || cmd_key > '9') cmd_key = uartstat[0];
|
94 |
|
|
printf("\nKey:%d", cmd_key);
|
95 |
|
|
if(cmd_key == 49)
|
96 |
|
|
read_sectors(SECTOR_ADDRESS, NUM_SECTORS);
|
97 |
|
|
else {
|
98 |
|
|
write_sectors(SECTOR_ADDRESS, NUM_SECTORS);
|
99 |
|
|
}
|
100 |
|
|
|
101 |
|
|
xil_printf("\n\n\rExit(e)?: Press '3'\r\n");
|
102 |
|
|
loop = uartstat[0];
|
103 |
|
|
while(loop < '0' || loop > '9') loop = uartstat[0];
|
104 |
|
|
//scp->ctrl_reg = REG_CLEAR;
|
105 |
|
|
}
|
106 |
|
|
|
107 |
|
|
xil_printf("\n\n\r Done ! \r\n");
|
108 |
|
|
|
109 |
|
|
return 0;
|
110 |
|
|
}
|
111 |
|
|
|
112 |
|
|
|
113 |
|
|
void read_sectors(int sector_addr, int sector_count) {
|
114 |
|
|
unsigned int i, j, ddr_data;
|
115 |
|
|
|
116 |
|
|
// DDR Read Space Start Address
|
117 |
|
|
scp->npi_wr_addr_reg = DDR_BASE + READ_SPACE_OFFSET;
|
118 |
|
|
// Clear SATA Control Register
|
119 |
|
|
scp->ctrl_reg = REG_CLEAR;
|
120 |
|
|
// Input Sector Address, Count and Command to Sata Core
|
121 |
|
|
scp->sector_addr_reg = sector_addr;
|
122 |
|
|
scp->sector_count_reg = sector_count;
|
123 |
|
|
scp->cmd_reg = (READ_CMD);
|
124 |
|
|
// Trigger SATA Core
|
125 |
|
|
scp->ctrl_reg = (NEW_CMD);
|
126 |
|
|
|
127 |
|
|
// Wait for Command Completion
|
128 |
|
|
xil_printf("\n\r STATUS REG : %x\r\n", scp->status_reg);
|
129 |
|
|
while ((scp->status_reg & SATA_CORE_DONE) != SATA_CORE_DONE);
|
130 |
|
|
|
131 |
|
|
xil_printf("\nDATA in DDR\n");
|
132 |
|
|
for(i = 0; i< (WORDS_PER_SECTOR * sector_count); i++) {
|
133 |
|
|
//xil_printf("\n\r DATA %d %d", i, ddr3[i+(READ_SPACE_OFFSET/SZ_WORD)]);
|
134 |
|
|
}
|
135 |
|
|
//Time to Read/Write Sectors from Disk
|
136 |
|
|
xil_printf("\n\r SECTOR Clock Cycles:%d\r\n",scp->sector_timer_reg);
|
137 |
|
|
}
|
138 |
|
|
|
139 |
|
|
|
140 |
|
|
void write_sectors(int sector_addr, int sector_count) {
|
141 |
|
|
int i=0, j=0;
|
142 |
|
|
|
143 |
|
|
xil_printf("\nFill DDR with DATA at DDR Write Address\n");
|
144 |
|
|
for(i = 0; i< (WORDS_PER_SECTOR * NUM_SECTORS); i++, j++)
|
145 |
|
|
{
|
146 |
|
|
if(j == (4*WORDS_PER_SECTOR))
|
147 |
|
|
j=0;
|
148 |
|
|
ddr3[i + (WRITE_SPACE_OFFSET/SZ_WORD)] = j;
|
149 |
|
|
}
|
150 |
|
|
|
151 |
|
|
// DDR Write Space Start Address
|
152 |
|
|
scp->npi_rd_addr_reg = DDR_BASE + WRITE_SPACE_OFFSET;
|
153 |
|
|
// Clear SATA Control Register
|
154 |
|
|
scp->ctrl_reg = REG_CLEAR;
|
155 |
|
|
|
156 |
|
|
|
157 |
|
|
// Input Sector Address, Count, DATA and Command to Sata Core
|
158 |
|
|
scp->sector_addr_reg = sector_addr;
|
159 |
|
|
scp->sector_count_reg = sector_count;
|
160 |
|
|
scp->cmd_reg = (WRITE_CMD);
|
161 |
|
|
// Trigger SATA Core
|
162 |
|
|
scp->ctrl_reg = (NEW_CMD);
|
163 |
|
|
|
164 |
|
|
// Wait for Command Completion
|
165 |
|
|
xil_printf("\n\r STATUS REG : %x\r\n", scp->status_reg);
|
166 |
|
|
while ((scp->status_reg & SATA_CORE_DONE) != SATA_CORE_DONE);
|
167 |
|
|
|
168 |
|
|
//Time to Read/Write Sectors from Disk
|
169 |
|
|
xil_printf("\n\r SECTOR Clock Cycles:%d\r\n", scp->sector_timer_reg);
|
170 |
|
|
}
|
171 |
|
|
|
172 |
|
|
|