Staging: sep: kill lock wrapper
[firefly-linux-kernel-4.4.55.git] / drivers / staging / sep / sep_ext_with_pci_driver.c
1 /*
2  *
3  *  sep_ext_with_pci_driver.c - Security Processor Driver
4  *  pci initialization functions
5  *
6  *  Copyright(c) 2009 Intel Corporation. All rights reserved.
7  *  Copyright(c) 2009 Discretix. All rights reserved.
8  *
9  *  This program is free software; you can redistribute it and/or modify it
10  *  under the terms of the GNU General Public License as published by the Free
11  *  Software Foundation; either version 2 of the License, or (at your option)
12  *  any later version.
13  *
14  *  This program is distributed in the hope that it will be useful, but WITHOUT
15  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17  *  more details.
18  *
19  *  You should have received a copy of the GNU General Public License along with
20  *  this program; if not, write to the Free Software Foundation, Inc., 59
21  *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  *  CONTACTS:
24  *
25  *  Mark Allyn          mark.a.allyn@intel.com
26  *
27  *  CHANGES:
28  *
29  *  2009.06.26  Initial publish
30  *
31  */
32
33 #include <linux/init.h>
34 #include <linux/module.h>
35 #include <linux/fs.h>
36 #include <linux/cdev.h>
37 #include <linux/kdev_t.h>
38 #include <linux/semaphore.h>
39 #include <linux/mm.h>
40 #include <linux/poll.h>
41 #include <linux/wait.h>
42 #include <linux/ioctl.h>
43 #include <linux/ioport.h>
44 #include <linux/io.h>
45 #include <linux/interrupt.h>
46 #include <linux/pagemap.h>
47 #include <linux/pci.h>
48 #include <linux/firmware.h>
49 #include <linux/sched.h>
50 #include "sep_driver_hw_defs.h"
51 #include "sep_driver_config.h"
52 #include "sep_driver_api.h"
53 #include "sep_driver_ext_api.h"
54 #include "sep_dev.h"
55
56 #if SEP_DRIVER_ARM_DEBUG_MODE
57
58 #define  CRYS_SEP_ROM_length                  0x4000
59 #define  CRYS_SEP_ROM_start_address           0x8000C000UL
60 #define  CRYS_SEP_ROM_start_address_offset    0xC000UL
61 #define  SEP_ROM_BANK_register                0x80008420UL
62 #define  SEP_ROM_BANK_register_offset         0x8420UL
63 #define SEP_RAR_IO_MEM_REGION_START_ADDRESS   0x82000000
64
65 /*
66  * THESE 2 definitions are specific to the board - must be
67  * defined during integration
68  */
69 #define SEP_RAR_IO_MEM_REGION_START_ADDRESS   0xFF0D0000
70
71 /* 2M size */
72
73 void sep_load_rom_code(void)
74 {
75         /* Index variables */
76         unsigned long i, k, j;
77         unsigned long regVal;
78         unsigned long Error;
79         unsigned long warning;
80
81         /* Loading ROM from SEP_ROM_image.h file */
82         k = sizeof(CRYS_SEP_ROM);
83
84         edbg("SEP Driver: DX_CC_TST_SepRomLoader start\n");
85
86         edbg("SEP Driver: k is %lu\n", k);
87         edbg("SEP Driver: sep_dev->reg_base_address is %p\n", sep_dev->reg_base_address);
88         edbg("SEP Driver: CRYS_SEP_ROM_start_address_offset is %p\n", CRYS_SEP_ROM_start_address_offset);
89
90         for (i = 0; i < 4; i++) {
91                 /* write bank */
92                 sep_write_reg(sep_dev, SEP_ROM_BANK_register_offset, i);
93
94                 for (j = 0; j < CRYS_SEP_ROM_length / 4; j++) {
95                         sep_write_reg(sep_dev, CRYS_SEP_ROM_start_address_offset + 4 * j, CRYS_SEP_ROM[i * 0x1000 + j]);
96
97                         k = k - 4;
98
99                         if (k == 0) {
100                                 j = CRYS_SEP_ROM_length;
101                                 i = 4;
102                         }
103                 }
104         }
105
106         /* reset the SEP */
107         sep_write_reg(sep_dev, HW_HOST_SEP_SW_RST_REG_ADDR, 0x1);
108
109         /* poll for SEP ROM boot finish */
110         do {
111                 retVal = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
112         } while (!regVal);
113
114         edbg("SEP Driver: ROM polling ended\n");
115
116         switch (regVal) {
117         case 0x1:
118                 /* fatal error - read erro status from GPRO */
119                 Error = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
120                 edbg("SEP Driver: ROM polling case 1\n");
121                 break;
122         case 0x2:
123                 /* Boot First Phase ended  */
124                 warning = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
125                 edbg("SEP Driver: ROM polling case 2\n");
126                 break;
127         case 0x4:
128                 /* Cold boot ended successfully  */
129                 warning = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
130                 edbg("SEP Driver: ROM polling case 4\n");
131                 Error = 0;
132                 break;
133         case 0x8:
134                 /* Warmboot ended successfully */
135                 warning = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
136                 edbg("SEP Driver: ROM polling case 8\n");
137                 Error = 0;
138                 break;
139         case 0x10:
140                 /* ColdWarm boot ended successfully */
141                 warning = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
142                 edbg("SEP Driver: ROM polling case 16\n");
143                 Error = 0;
144                 break;
145         case 0x20:
146                 edbg("SEP Driver: ROM polling case 32\n");
147                 break;
148         }
149
150 }
151
152 #else
153 void sep_load_rom_code(void) { }
154 #endif                          /* SEP_DRIVER_ARM_DEBUG_MODE */
155
156 #define BASE_ADDRESS_FOR_SYSTEM 0xfffc0000
157 #define SEP_RAR_IO_MEM_REGION_SIZE 0x40000
158
159 irqreturn_t sep_inthandler(int irq, void *dev_id);
160
161 /* Keep this a single static object for now to keep the conversion easy */
162
163 static struct sep_device sep_instance;
164 struct sep_device *sep_dev = &sep_instance;
165
166 /* temporary */
167 unsigned long jiffies_future;
168
169 /*-----------------------------
170     private functions
171 --------------------------------*/
172
173 /*
174   This functions locks the area of the resisnd and cache sep code
175 */
176 void sep_lock_cache_resident_area(void)
177 {
178         return;
179 }
180
181 /*
182   This functions copies the cache and resident from their source location into
183   destination memory, which is external to Linux VM and is given as
184    physical address
185 */
186 int sep_copy_cache_resident_to_area(unsigned long src_cache_addr, unsigned long cache_size_in_bytes, unsigned long src_resident_addr, unsigned long resident_size_in_bytes, unsigned long *dst_new_cache_addr_ptr, unsigned long *dst_new_resident_addr_ptr)
187 {
188         unsigned long resident_addr;
189         unsigned long cache_addr;
190         const struct firmware *fw;
191
192         char *cache_name = "cache.image.bin";
193         char *res_name = "resident.image.bin";
194
195         /* error */
196         int error;
197
198         /*--------------------------------
199             CODE
200         -------------------------------------*/
201         error = 0;
202
203         edbg("SEP Driver:rar_virtual is %p\n", sep_dev->rar_virtual_address);
204         edbg("SEP Driver:rar_physical is %08lx\n", sep_dev->rar_physical_address);
205
206         sep_dev->rar_region_addr = (unsigned long) sep_dev->rar_virtual_address;
207
208         sep_dev->cache_physical_address = sep_dev->rar_physical_address;
209         sep_dev->cache_virtual_address = sep_dev->rar_virtual_address;
210
211         /* load cache */
212         error = request_firmware(&fw, cache_name, &sep_dev->sep_pci_dev_ptr->dev);
213         if (error) {
214                 edbg("SEP Driver:cant request cache fw\n");
215                 goto end_function;
216         }
217
218         edbg("SEP Driver:cache data loc is %p\n", (void *) fw->data);
219         edbg("SEP Driver:cache data size is %08Zx\n", fw->size);
220
221         memcpy((void *) sep_dev->cache_virtual_address, (void *) fw->data, fw->size);
222
223         sep_dev->cache_size = fw->size;
224
225         cache_addr = (unsigned long) sep_dev->cache_virtual_address;
226
227         release_firmware(fw);
228
229         sep_dev->resident_physical_address = sep_dev->cache_physical_address + sep_dev->cache_size;
230         sep_dev->resident_virtual_address = sep_dev->cache_virtual_address + sep_dev->cache_size;
231
232         /* load resident */
233         error = request_firmware(&fw, res_name, &sep_dev->sep_pci_dev_ptr->dev);
234         if (error) {
235                 edbg("SEP Driver:cant request res fw\n");
236                 goto end_function;
237         }
238
239         edbg("SEP Driver:res data loc is %p\n", (void *) fw->data);
240         edbg("SEP Driver:res data size is %08Zx\n", fw->size);
241
242         memcpy((void *) sep_dev->resident_virtual_address, (void *) fw->data, fw->size);
243
244         sep_dev->resident_size = fw->size;
245
246         release_firmware(fw);
247
248         resident_addr = (unsigned long) sep_dev->resident_virtual_address;
249
250         edbg("SEP Driver:resident_addr (physical )is %08lx\n", sep_dev->resident_physical_address);
251         edbg("SEP Driver:cache_addr (physical) is %08lx\n", sep_dev->cache_physical_address);
252
253         edbg("SEP Driver:resident_addr (logical )is %08lx\n", resident_addr);
254         edbg("SEP Driver:cache_addr (logical) is %08lx\n", cache_addr);
255
256         edbg("SEP Driver:resident_size is %08lx\n", sep_dev->resident_size);
257         edbg("SEP Driver:cache_size is %08lx\n", sep_dev->cache_size);
258
259
260
261         /* physical addresses */
262         *dst_new_cache_addr_ptr = sep_dev->cache_physical_address;
263         *dst_new_resident_addr_ptr = sep_dev->resident_physical_address;
264 end_function:
265         return error;
266 }
267
268 /*
269   This functions maps and allocates the
270   shared area on the  external RAM (device)
271   The input is shared_area_size - the size of the memory to
272   allocate. The outputs
273   are kernel_shared_area_addr_ptr - the kerenl
274   address of the mapped and allocated
275   shared area, and phys_shared_area_addr_ptr
276   - the physical address of the shared area
277 */
278 int sep_map_and_alloc_shared_area(unsigned long shared_area_size, unsigned long *kernel_shared_area_addr_ptr, unsigned long *phys_shared_area_addr_ptr)
279 {
280         // shared_virtual_address = ioremap_nocache(0xda00000,shared_area_size);
281         sep_dev->shared_virtual_address = kmalloc(shared_area_size, GFP_KERNEL);
282         if (!sep_dev->shared_virtual_address) {
283                 edbg("sep_driver:shared memory kmalloc failed\n");
284                 return -1;
285         }
286         /* FIXME */
287         sep_dev->shared_physical_address = __pa(sep_dev->shared_virtual_address);
288         /* shared_physical_address = 0xda00000; */
289         *kernel_shared_area_addr_ptr = (unsigned long) sep_dev->shared_virtual_address;
290         /* set the physical address of the shared area */
291         *phys_shared_area_addr_ptr = sep_dev->shared_physical_address;
292         edbg("SEP Driver:shared_virtual_address is %p\n", sep_dev->shared_virtual_address);
293         edbg("SEP Driver:shared_region_size is %08lx\n", shared_area_size);
294         edbg("SEP Driver:shared_physical_addr is %08lx\n", *phys_shared_area_addr_ptr);
295
296         return 0;
297 }
298
299 /*
300   This functions unmaps and deallocates the shared area
301   on the  external RAM (device)
302   The input is shared_area_size - the size of the memory to deallocate,kernel_
303   shared_area_addr_ptr - the kernel address of the mapped and allocated
304   shared area,phys_shared_area_addr_ptr - the physical address of
305   the shared area
306 */
307 void sep_unmap_and_free_shared_area(unsigned long shared_area_size, unsigned long kernel_shared_area_addr, unsigned long phys_shared_area_addr)
308 {
309         kfree((void *) kernel_shared_area_addr);
310 }
311
312 /*
313   This functions returns the physical address inside shared area according
314   to the virtual address. It can be either on the externa RAM device
315   (ioremapped), or on the system RAM
316   This implementation is for the external RAM
317 */
318 unsigned long sep_shared_area_virt_to_phys(unsigned long virt_address)
319 {
320         edbg("SEP Driver:sh virt to phys v %08lx\n", virt_address);
321         edbg("SEP Driver:sh virt to phys p %08lx\n", sep_dev->shared_physical_address + (virt_address - (unsigned long) sep_dev->shared_virtual_address));
322
323         return (unsigned long) sep_dev->shared_physical_address + (virt_address - (unsigned long) sep_dev->shared_virtual_address);
324 }
325
326 /*
327   This functions returns the virtual address inside shared area
328   according to the physical address. It can be either on the
329   externa RAM device (ioremapped), or on the system RAM This implementation
330   is for the external RAM
331 */
332 unsigned long sep_shared_area_phys_to_virt(unsigned long phys_address)
333 {
334         return (unsigned long) sep_dev->shared_virtual_address + (phys_address - sep_dev->shared_physical_address);
335 }
336
337
338 /*
339   function that is activaed on the succesfull probe of the SEP device
340 */
341 static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
342 {
343         int error = 0;
344
345         edbg("Sep pci probe starting\n");
346
347         /* enable the device */
348         error = pci_enable_device(pdev);
349         if (error) {
350                 edbg("error enabling pci device\n");
351                 goto end_function;
352         }
353
354         /* set the pci dev pointer */
355         sep_dev->sep_pci_dev_ptr = pdev;
356
357         /* get the io memory start address */
358         sep_dev->io_memory_start_physical_address = pci_resource_start(pdev, 0);
359         if (!sep_dev->io_memory_start_physical_address) {
360                 edbg("SEP Driver error pci resource start\n");
361                 goto end_function;
362         }
363
364         /* get the io memory end address */
365         sep_dev->io_memory_end_physical_address = pci_resource_end(pdev, 0);
366         if (!sep_dev->io_memory_end_physical_address) {
367                 edbg("SEP Driver error pci resource end\n");
368                 goto end_function;
369         }
370
371         sep_dev->io_memory_size = sep_dev->io_memory_end_physical_address - sep_dev->io_memory_start_physical_address + 1;
372
373         edbg("SEP Driver:io_memory_start_physical_address is %08lx\n", sep_dev->io_memory_start_physical_address);
374
375         edbg("SEP Driver:io_memory_end_phyaical_address is %08lx\n", sep_dev->io_memory_end_physical_address);
376
377         edbg("SEP Driver:io_memory_size is %08lx\n", sep_dev->io_memory_size);
378
379         sep_dev->io_memory_start_virtual_address = ioremap_nocache(sep_dev->io_memory_start_physical_address, sep_dev->io_memory_size);
380         if (!sep_dev->io_memory_start_virtual_address) {
381                 edbg("SEP Driver error ioremap of io memory\n");
382                 goto end_function;
383         }
384
385         edbg("SEP Driver:io_memory_start_virtual_address is %p\n", sep_dev->io_memory_start_virtual_address);
386
387         sep_dev->reg_base_address = (void __iomem *) sep_dev->io_memory_start_virtual_address;
388
389
390         /* set up system base address and shared memory location */
391
392         sep_dev->rar_virtual_address = kmalloc(2 * SEP_RAR_IO_MEM_REGION_SIZE, GFP_KERNEL);
393
394         if (!sep_dev->rar_virtual_address) {
395                 edbg("SEP Driver:cant kmalloc rar\n");
396                 goto end_function;
397         }
398         /* FIXME */
399         sep_dev->rar_physical_address = __pa(sep_dev->rar_virtual_address);
400
401         edbg("SEP Driver:rar_physical is %08lx\n", sep_dev->rar_physical_address);
402         edbg("SEP Driver:rar_virtual is %p\n", sep_dev->rar_virtual_address);
403
404 #if !SEP_DRIVER_POLLING_MODE
405
406         edbg("SEP Driver: about to write IMR and ICR REG_ADDR\n");
407
408         /* clear ICR register */
409         sep_write_reg(sep_dev, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
410
411         /* set the IMR register - open only GPR 2 */
412         sep_write_reg(sep_dev, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
413
414         /* figure out our irq */
415         /* FIXME: */
416         error = pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, (u8 *) & sep_dev->sep_irq);
417
418         edbg("SEP Driver: my irq is %d\n", sep_irq);
419
420         edbg("SEP Driver: about to call request_irq\n");
421         /* get the interrupt line */
422         error = request_irq(sep_irq, sep_inthandler, IRQF_SHARED, "sep_driver", &sep_dev->reg_base_address);
423         if (error)
424                 goto end_function;
425
426         goto end_function;
427         edbg("SEP Driver: about to write IMR REG_ADDR");
428
429         /* set the IMR register - open only GPR 2 */
430         sep_write_reg(sep_dev, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
431
432 #endif                          /* SEP_DRIVER_POLLING_MODE */
433 end_function:
434         return error;
435 }
436
437 static struct pci_device_id sep_pci_id_tbl[] = {
438         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)},
439         {0}
440 };
441
442 MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl);
443
444 /* field for registering driver to PCI device */
445 static struct pci_driver sep_pci_driver = {
446         .name = "sep_sec_driver",
447         .id_table = sep_pci_id_tbl,
448         .probe = sep_probe
449 };
450
451 /*
452   this function registers th driver to
453   the device subsystem( either PCI, USB, etc)
454 */
455 int sep_register_driver_to_device(void)
456 {
457         return pci_register_driver(&sep_pci_driver);
458 }
459
460