• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "pcie_test.h"
10 #include "device_resource_if.h"
11 #include "hdf_base.h"
12 #include "hdf_io_service_if.h"
13 #include "hdf_log.h"
14 #include "osal_mem.h"
15 #include "osal_time.h"
16 
17 #define HDF_LOG_TAG pcie_test_c
18 
19 #define USER_LEM_MAX    8192
20 #define DMA_ALIGN_SIZE  256
21 #define DMA_TEST_LEN    256
22 #define PCIE_TEST_DISABLE_ADDR 0xB7
23 #define PCIE_TEST_UPPER_ADDR 0x28
24 #define PCIE_TEST_CMD_ADDR 0x04
25 
26 struct PcieTestFunc {
27     int cmd;
28     int32_t (*func)(struct PcieTester *tester);
29 };
30 
PcieTestGetConfig(struct PcieTestConfig * config)31 static int32_t PcieTestGetConfig(struct PcieTestConfig *config)
32 {
33     int32_t ret;
34     struct HdfSBuf *reply = NULL;
35     struct HdfIoService *service = NULL;
36 
37     service = HdfIoServiceBind("PCIE_TEST");
38     if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
39         HDF_LOGE("PcieTestGetConfig: bind service fail!");
40         return HDF_ERR_NOT_SUPPORT;
41     }
42 
43     reply = HdfSbufObtainDefaultSize();
44     if (reply == NULL) {
45         HDF_LOGE("PcieTestGetConfig: fail to obtain reply!");
46         HdfIoServiceRecycle(service);
47         return HDF_ERR_MALLOC_FAIL;
48     }
49 
50     ret = service->dispatcher->Dispatch(&service->object, 0, NULL, reply);
51     if (ret != HDF_SUCCESS) {
52         HDF_LOGE("PcieTestGetConfig: remote dispatch fail!");
53         HdfSbufRecycle(reply);
54         HdfIoServiceRecycle(service);
55         return ret;
56     }
57 
58     if (!HdfSbufReadUint32(reply, &config->busNum)) {
59         HDF_LOGE("PcieTestGetConfig: read busNum fail!");
60         HdfSbufRecycle(reply);
61         HdfIoServiceRecycle(service);
62         return HDF_ERR_IO;
63     }
64     HdfSbufRecycle(reply);
65     HdfIoServiceRecycle(service);
66     return ret;
67 }
68 
PcieTesterGet(void)69 static DevHandle PcieTesterGet(void)
70 {
71     int32_t ret;
72     static struct PcieTester tester = {0};
73 
74     ret = PcieTestGetConfig(&tester.config);
75     if (ret != HDF_SUCCESS) {
76         HDF_LOGE("PcieTesterGet: read config fail, ret: %d!", ret);
77         return NULL;
78     }
79     tester.handle = PcieOpen(tester.config.busNum);
80     if (tester.handle == NULL) {
81         HDF_LOGE("PcieTesterGet: open pcie %u fail!", tester.config.busNum);
82         return NULL;
83     }
84 
85     return &tester;
86 }
87 
PcieTesterPut(struct PcieTester * tester)88 static void PcieTesterPut(struct PcieTester *tester)
89 {
90     if (tester == NULL) {
91         HDF_LOGE("PcieTesterPut: tester is null!");
92         return;
93     }
94     PcieClose(tester->handle);
95     tester->handle = NULL;
96 }
97 
TestPcieReadAndWrite(struct PcieTester * tester)98 static int32_t TestPcieReadAndWrite(struct PcieTester *tester)
99 {
100     int32_t ret;
101     uint8_t disable;
102     uint32_t upper;
103     uint16_t cmd;
104 
105     ret = PcieRead(tester->handle, PCIE_CONFIG, PCIE_TEST_DISABLE_ADDR, &disable, sizeof(disable));
106     if (ret != HDF_SUCCESS) {
107         HDF_LOGE("TestPcieReadAndWrite: PcieRead fail, ret = %d!", ret);
108         return ret;
109     }
110     HDF_LOGD("TestPcieReadAndWrite: disable is %d!", disable);
111     ret = PcieWrite(tester->handle, PCIE_CONFIG, PCIE_TEST_DISABLE_ADDR, &disable, sizeof(disable));
112     if (ret != HDF_SUCCESS) {
113         HDF_LOGE("TestPcieReadAndWrite: PcieWrite fail, ret = %d!", ret);
114         return ret;
115     }
116 
117     ret = PcieRead(tester->handle, PCIE_CONFIG, PCIE_TEST_UPPER_ADDR, (uint8_t *)&upper, sizeof(upper));
118     if (ret != HDF_SUCCESS) {
119         HDF_LOGE("TestPcieReadAndWrite: PcieRead fail, ret = %d!", ret);
120         return ret;
121     }
122     HDF_LOGD("TestPcieReadAndWrite: upper is 0x%x!", upper);
123     ret = PcieWrite(tester->handle, PCIE_CONFIG, PCIE_TEST_UPPER_ADDR, (uint8_t *)&upper, sizeof(upper));
124     if (ret != HDF_SUCCESS) {
125         HDF_LOGE("TestPcieReadAndWrite: PcieWrite fail, ret = %d!", ret);
126         return ret;
127     }
128 
129     ret = PcieRead(tester->handle, PCIE_CONFIG, PCIE_TEST_CMD_ADDR, (uint8_t *)&cmd, sizeof(cmd));
130     if (ret != HDF_SUCCESS) {
131         HDF_LOGE("TestPcieReadAndWrite: PcieRead fail, ret = %d!", ret);
132         return ret;
133     }
134     HDF_LOGD("TestPcieReadAndWrite: cmd is 0x%x!", cmd);
135     ret = PcieWrite(tester->handle, PCIE_CONFIG, PCIE_TEST_CMD_ADDR, (uint8_t *)&cmd, sizeof(cmd));
136     if (ret != HDF_SUCCESS) {
137         HDF_LOGE("TestPcieReadAndWrite: PcieWrite fail, ret = %d!", ret);
138     }
139     return ret;
140 }
141 
TestPcieDmaCb(DevHandle handle)142 int32_t TestPcieDmaCb(DevHandle handle)
143 {
144     (void)handle;
145     HDF_LOGI("TestPcieDmaCb: trigger!");
146     return HDF_SUCCESS;
147 }
148 
TestPcieDmaMapAndUnmap(struct PcieTester * tester)149 static int32_t TestPcieDmaMapAndUnmap(struct PcieTester *tester)
150 {
151     int32_t ret;
152     uintptr_t buf = 0;
153 
154     if (tester->handle == NULL) {
155         HDF_LOGE("TestPcieDmaMapAndUnmap: invalid tester!");
156         return HDF_ERR_INVALID_PARAM;
157     }
158     buf = (uintptr_t)OsalMemAllocAlign(DMA_ALIGN_SIZE, DMA_TEST_LEN);
159     if (buf == 0) {
160         HDF_LOGE("TestPcieDmaMapAndUnmap: malloc fail!");
161         return HDF_ERR_MALLOC_FAIL;
162     }
163     /* dma to device */
164     ret = PcieDmaMap(tester->handle, TestPcieDmaCb, buf, DMA_TEST_LEN, PCIE_DMA_TO_DEVICE);
165     if (ret != HDF_SUCCESS) {
166         HDF_LOGE("TestPcieDmaMapAndUnmap: fail, ret = %d!", ret);
167         OsalMemFree((void *)buf);
168         return ret;
169     }
170     PcieDmaUnmap(tester->handle, buf, DMA_TEST_LEN, PCIE_DMA_TO_DEVICE);
171 
172     /* device to dma */
173     ret = PcieDmaMap(tester->handle, TestPcieDmaCb, buf, DMA_TEST_LEN, PCIE_DMA_FROM_DEVICE);
174     if (ret != HDF_SUCCESS) {
175         HDF_LOGE("TestPcieDmaMapAndUnmap: fail, ret = %d!", ret);
176         OsalMemFree((void *)buf);
177         return ret;
178     }
179     PcieDmaUnmap(tester->handle, buf, DMA_TEST_LEN, PCIE_DMA_FROM_DEVICE);
180     OsalMemFree((void *)buf);
181 
182     return HDF_SUCCESS;
183 }
184 
TestPcieIrqCb(DevHandle handle)185 int32_t TestPcieIrqCb(DevHandle handle)
186 {
187     (void)handle;
188     HDF_LOGI("TestPcieIrqCb: trigger!");
189     return HDF_SUCCESS;
190 }
191 
TestPcieRegAndUnregIrq(struct PcieTester * tester)192 static int32_t TestPcieRegAndUnregIrq(struct PcieTester *tester)
193 {
194     int32_t ret;
195     ret = PcieRegisterIrq(tester->handle, TestPcieIrqCb);
196     if (ret != HDF_SUCCESS) {
197         HDF_LOGE("TestPcieRegAndUnregIrq: register irq fail!");
198         return ret;
199     }
200 
201     PcieUnregisterIrq(tester->handle);
202     return HDF_SUCCESS;
203 }
204 
205 static struct PcieTestFunc g_entry[] = {
206     { PCIE_READ_AND_WRITE_01, TestPcieReadAndWrite },
207     { PCIE_DMA_MAP_AND_UNMAP_01, TestPcieDmaMapAndUnmap },
208     { PCIE_REG_AND_UNREG_IRQ_01, TestPcieRegAndUnregIrq },
209 };
210 
PcieTestExecute(int cmd)211 int32_t PcieTestExecute(int cmd)
212 {
213     uint32_t i;
214     int32_t ret = HDF_ERR_NOT_SUPPORT;
215     struct PcieTester *tester = NULL;
216 
217     if (cmd > PCIE_TEST_MAX) {
218         HDF_LOGE("PcieTestExecute: invalid cmd: %d!", cmd);
219         return ret;
220     }
221 
222     tester = PcieTesterGet();
223     if (tester == NULL) {
224         HDF_LOGE("PcieTestExecute: get tester fail!");
225         return HDF_ERR_INVALID_OBJECT;
226     }
227 
228     for (i = 0; i < sizeof(g_entry) / sizeof(g_entry[0]); i++) {
229         if (g_entry[i].cmd == cmd && g_entry[i].func != NULL) {
230             ret = g_entry[i].func(tester);
231             break;
232         }
233     }
234 
235     HDF_LOGI("[PcieTestExecute][======cmd:%d====ret:%d======]", cmd, ret);
236     PcieTesterPut(tester);
237     return ret;
238 }
239