]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/sep/sep_ext_with_pci_driver.c
d8591f59e7867401e92bb29a0faa9cf0ba28f041
[mv-sheeva.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
60 #define  CRYS_SEP_ROM_start_address           0x8000C000UL
61
62 #define  CRYS_SEP_ROM_start_address_offset    0xC000UL
63
64 #define  SEP_ROM_BANK_register                0x80008420UL
65
66 #define  SEP_ROM_BANK_register_offset         0x8420UL
67
68 #define SEP_RAR_IO_MEM_REGION_START_ADDRESS   0x82000000
69
70 /* 2M size */
71 /* #define SEP_RAR_IO_MEM_REGION_SIZE            (1024*1024*2)
72
73 static unsigned long CRYS_SEP_ROM[] = {
74         #include "SEP_ROM_image.h"
75 };
76
77 #else
78 */
79
80 /*-------------
81  THOSE 2 definitions are specific to the board - must be
82  defined during integration
83 ---------------*/
84 #define SEP_RAR_IO_MEM_REGION_START_ADDRESS   0xFF0D0000
85
86 /* 2M size */
87
88 #endif                          /* SEP_DRIVER_ARM_DEBUG_MODE */
89
90 #define BASE_ADDRESS_FOR_SYSTEM 0xfffc0000
91 #define SEP_RAR_IO_MEM_REGION_SIZE 0x40000
92
93 irqreturn_t sep_inthandler(int irq, void *dev_id);
94
95 /* Keep this a single static object for now to keep the conversion easy */
96
97 static struct sep_device sep_instance;
98 struct sep_device *sep_dev = &sep_instance;
99
100 /* temporary */
101 unsigned long jiffies_future;
102
103 /*-----------------------------
104     private functions
105 --------------------------------*/
106
107 /*
108   function that is activated on the succesfull probe of the SEP device
109 */
110 static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
111
112 static struct pci_device_id sep_pci_id_tbl[] = {
113         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)},
114         {0}
115 };
116
117 MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl);
118
119 /* field for registering driver to PCI device */
120 static struct pci_driver sep_pci_driver = {
121         .name = "sep_sec_driver",
122         .id_table = sep_pci_id_tbl,
123         .probe = sep_probe
124 };
125
126 /*
127   This functions locks the area of the resisnd and cache sep code
128 */
129 void sep_lock_cache_resident_area(void)
130 {
131         return;
132 }
133
134 /*
135   This functions copies the cache and resident from their source location into
136   destination memory, which is external to Linux VM and is given as
137    physical address
138 */
139 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)
140 {
141         unsigned long resident_addr;
142         unsigned long cache_addr;
143         const struct firmware *fw;
144
145         char *cache_name = "cache.image.bin";
146         char *res_name = "resident.image.bin";
147
148         /* error */
149         int error;
150
151         /*--------------------------------
152             CODE
153         -------------------------------------*/
154         error = 0;
155
156         edbg("SEP Driver:rar_virtual is %p\n", sep_dev->rar_virtual_address);
157         edbg("SEP Driver:rar_physical is %08lx\n", sep_dev->rar_physical_address);
158
159         sep_dev->rar_region_addr = (unsigned long) sep_dev->rar_virtual_address;
160
161         sep_dev->cache_physical_address = sep_dev->rar_physical_address;
162         sep_dev->cache_virtual_address = sep_dev->rar_virtual_address;
163
164         /* load cache */
165         error = request_firmware(&fw, cache_name, &sep_dev->sep_pci_dev_ptr->dev);
166         if (error) {
167                 edbg("SEP Driver:cant request cache fw\n");
168                 goto end_function;
169         }
170
171         edbg("SEP Driver:cache data loc is %p\n", (void *) fw->data);
172         edbg("SEP Driver:cache data size is %08Zx\n", fw->size);
173
174         memcpy((void *) sep_dev->cache_virtual_address, (void *) fw->data, fw->size);
175
176         sep_dev->cache_size = fw->size;
177
178         cache_addr = (unsigned long) sep_dev->cache_virtual_address;
179
180         release_firmware(fw);
181
182         sep_dev->resident_physical_address = sep_dev->cache_physical_address + sep_dev->cache_size;
183         sep_dev->resident_virtual_address = sep_dev->cache_virtual_address + sep_dev->cache_size;
184
185         /* load resident */
186         error = request_firmware(&fw, res_name, &sep_dev->sep_pci_dev_ptr->dev);
187         if (error) {
188                 edbg("SEP Driver:cant request res fw\n");
189                 goto end_function;
190         }
191
192         edbg("SEP Driver:res data loc is %p\n", (void *) fw->data);
193         edbg("SEP Driver:res data size is %08Zx\n", fw->size);
194
195         memcpy((void *) sep_dev->resident_virtual_address, (void *) fw->data, fw->size);
196
197         sep_dev->resident_size = fw->size;
198
199         release_firmware(fw);
200
201         resident_addr = (unsigned long) sep_dev->resident_virtual_address;
202
203         edbg("SEP Driver:resident_addr (physical )is %08lx\n", sep_dev->resident_physical_address);
204         edbg("SEP Driver:cache_addr (physical) is %08lx\n", sep_dev->cache_physical_address);
205
206         edbg("SEP Driver:resident_addr (logical )is %08lx\n", resident_addr);
207         edbg("SEP Driver:cache_addr (logical) is %08lx\n", cache_addr);
208
209         edbg("SEP Driver:resident_size is %08lx\n", sep_dev->resident_size);
210         edbg("SEP Driver:cache_size is %08lx\n", sep_dev->cache_size);
211
212
213
214         /* physical addresses */
215         *dst_new_cache_addr_ptr = sep_dev->cache_physical_address;
216         *dst_new_resident_addr_ptr = sep_dev->resident_physical_address;
217 end_function:
218         return error;
219 }
220
221 /*
222   This functions maps and allocates the
223   shared area on the  external RAM (device)
224   The input is shared_area_size - the size of the memory to
225   allocate. The outputs
226   are kernel_shared_area_addr_ptr - the kerenl
227   address of the mapped and allocated
228   shared area, and phys_shared_area_addr_ptr
229   - the physical address of the shared area
230 */
231 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)
232 {
233         // shared_virtual_address = ioremap_nocache(0xda00000,shared_area_size);
234         sep_dev->shared_virtual_address = kmalloc(shared_area_size, GFP_KERNEL);
235         if (!sep_dev->shared_virtual_address) {
236                 edbg("sep_driver:shared memory kmalloc failed\n");
237                 return -1;
238         }
239         /* FIXME */
240         sep_dev->shared_physical_address = __pa(sep_dev->shared_virtual_address);
241         /* shared_physical_address = 0xda00000; */
242         *kernel_shared_area_addr_ptr = (unsigned long) sep_dev->shared_virtual_address;
243         /* set the physical address of the shared area */
244         *phys_shared_area_addr_ptr = sep_dev->shared_physical_address;
245         edbg("SEP Driver:shared_virtual_address is %p\n", sep_dev->shared_virtual_address);
246         edbg("SEP Driver:shared_region_size is %08lx\n", shared_area_size);
247         edbg("SEP Driver:shared_physical_addr is %08lx\n", *phys_shared_area_addr_ptr);
248
249         return 0;
250 }
251
252 /*
253   This functions unmaps and deallocates the shared area
254   on the  external RAM (device)
255   The input is shared_area_size - the size of the memory to deallocate,kernel_
256   shared_area_addr_ptr - the kernel address of the mapped and allocated
257   shared area,phys_shared_area_addr_ptr - the physical address of
258   the shared area
259 */
260 void sep_unmap_and_free_shared_area(unsigned long shared_area_size, unsigned long kernel_shared_area_addr, unsigned long phys_shared_area_addr)
261 {
262         kfree((void *) kernel_shared_area_addr);
263 }
264
265 /*
266   This functions returns the physical address inside shared area according
267   to the virtual address. It can be either on the externa RAM device
268   (ioremapped), or on the system RAM
269   This implementation is for the external RAM
270 */
271 unsigned long sep_shared_area_virt_to_phys(unsigned long virt_address)
272 {
273         edbg("SEP Driver:sh virt to phys v %08lx\n", virt_address);
274         edbg("SEP Driver:sh virt to phys p %08lx\n", sep_dev->shared_physical_address + (virt_address - (unsigned long) sep_dev->shared_virtual_address));
275
276         return (unsigned long) sep_dev->shared_physical_address + (virt_address - (unsigned long) sep_dev->shared_virtual_address);
277 }
278
279 /*
280   This functions returns the virtual address inside shared area
281   according to the physical address. It can be either on the
282   externa RAM device (ioremapped), or on the system RAM This implementation
283   is for the external RAM
284 */
285 unsigned long sep_shared_area_phys_to_virt(unsigned long phys_address)
286 {
287         return (unsigned long) sep_dev->shared_virtual_address + (phys_address - sep_dev->shared_physical_address);
288 }
289
290
291 /*
292   function that is activaed on the succesfull probe of the SEP device
293 */
294 static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
295 {
296         int error = 0;
297
298         edbg("Sep pci probe starting\n");
299
300         /* enable the device */
301         error = pci_enable_device(pdev);
302         if (error) {
303                 edbg("error enabling pci device\n");
304                 goto end_function;
305         }
306
307         /* set the pci dev pointer */
308         sep_dev->sep_pci_dev_ptr = pdev;
309
310         /* get the io memory start address */
311         sep_dev->io_memory_start_physical_address = pci_resource_start(pdev, 0);
312         if (!sep_dev->io_memory_start_physical_address) {
313                 edbg("SEP Driver error pci resource start\n");
314                 goto end_function;
315         }
316
317         /* get the io memory end address */
318         sep_dev->io_memory_end_physical_address = pci_resource_end(pdev, 0);
319         if (!sep_dev->io_memory_end_physical_address) {
320                 edbg("SEP Driver error pci resource end\n");
321                 goto end_function;
322         }
323
324         sep_dev->io_memory_size = sep_dev->io_memory_end_physical_address - sep_dev->io_memory_start_physical_address + 1;
325
326         edbg("SEP Driver:io_memory_start_physical_address is %08lx\n", sep_dev->io_memory_start_physical_address);
327
328         edbg("SEP Driver:io_memory_end_phyaical_address is %08lx\n", sep_dev->io_memory_end_physical_address);
329
330         edbg("SEP Driver:io_memory_size is %08lx\n", sep_dev->io_memory_size);
331
332         sep_dev->io_memory_start_virtual_address = ioremap_nocache(sep_dev->io_memory_start_physical_address, sep_dev->io_memory_size);
333         if (!sep_dev->io_memory_start_virtual_address) {
334                 edbg("SEP Driver error ioremap of io memory\n");
335                 goto end_function;
336         }
337
338         edbg("SEP Driver:io_memory_start_virtual_address is %p\n", sep_dev->io_memory_start_virtual_address);
339
340         sep_dev->reg_base_address = (void __iomem *) sep_dev->io_memory_start_virtual_address;
341
342
343         /* set up system base address and shared memory location */
344
345         sep_dev->rar_virtual_address = kmalloc(2 * SEP_RAR_IO_MEM_REGION_SIZE, GFP_KERNEL);
346
347         if (!sep_dev->rar_virtual_address) {
348                 edbg("SEP Driver:cant kmalloc rar\n");
349                 goto end_function;
350         }
351         /* FIXME */
352         sep_dev->rar_physical_address = __pa(sep_dev->rar_virtual_address);
353
354         edbg("SEP Driver:rar_physical is %08lx\n", sep_dev->rar_physical_address);
355         edbg("SEP Driver:rar_virtual is %p\n", sep_dev->rar_virtual_address);
356
357 #if !SEP_DRIVER_POLLING_MODE
358
359         edbg("SEP Driver: about to write IMR and ICR REG_ADDR\n");
360
361         /* clear ICR register */
362         sep_write_reg(sep_dev, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
363
364         /* set the IMR register - open only GPR 2 */
365         sep_write_reg(sep_dev, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
366
367         /* figure out our irq */
368         /* FIXME: */
369         error = pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, (u8 *) & sep_dev->sep_irq);
370
371         edbg("SEP Driver: my irq is %d\n", sep_irq);
372
373         edbg("SEP Driver: about to call request_irq\n");
374         /* get the interrupt line */
375         error = request_irq(sep_irq, sep_inthandler, IRQF_SHARED, "sep_driver", &sep_dev->reg_base_address);
376         if (error)
377                 goto end_function;
378
379         goto end_function;
380         edbg("SEP Driver: about to write IMR REG_ADDR");
381
382         /* set the IMR register - open only GPR 2 */
383         sep_write_reg(sep_dev, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
384
385 #endif                          /* SEP_DRIVER_POLLING_MODE */
386 end_function:
387         return error;
388 }
389
390 /*
391   this function registers th driver to
392   the device subsystem( either PCI, USB, etc)
393 */
394 int sep_register_driver_to_device(void)
395 {
396         return pci_register_driver(&sep_pci_driver);
397 }
398
399
400
401 void sep_load_rom_code(void)
402 {
403 #if SEP_DRIVER_ARM_DEBUG_MODE
404         /* Index variables */
405         unsigned long i, k, j;
406         unsigned long regVal;
407         unsigned long Error;
408         unsigned long warning;
409
410         /* Loading ROM from SEP_ROM_image.h file */
411         k = sizeof(CRYS_SEP_ROM);
412
413         edbg("SEP Driver: DX_CC_TST_SepRomLoader start\n");
414
415         edbg("SEP Driver: k is %lu\n", k);
416         edbg("SEP Driver: sep_dev->reg_base_address is %p\n", sep_dev->reg_base_address);
417         edbg("SEP Driver: CRYS_SEP_ROM_start_address_offset is %p\n", CRYS_SEP_ROM_start_address_offset);
418
419         for (i = 0; i < 4; i++) {
420                 /* write bank */
421                 sep_write_reg(sep_dev, SEP_ROM_BANK_register_offset, i);
422
423                 for (j = 0; j < CRYS_SEP_ROM_length / 4; j++) {
424                         sep_write_reg(sep_dev, CRYS_SEP_ROM_start_address_offset + 4 * j, CRYS_SEP_ROM[i * 0x1000 + j]);
425
426                         k = k - 4;
427
428                         if (k == 0) {
429                                 j = CRYS_SEP_ROM_length;
430                                 i = 4;
431                         }
432                 }
433         }
434
435         /* reset the SEP */
436         sep_write_reg(sep_dev, HW_HOST_SEP_SW_RST_REG_ADDR, 0x1);
437
438         /* poll for SEP ROM boot finish */
439         do {
440                 retVal = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
441         } while (!regVal);
442
443         edbg("SEP Driver: ROM polling ended\n");
444
445         switch (regVal) {
446         case 0x1:
447                 /* fatal error - read erro status from GPRO */
448                 Error = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
449                 edbg("SEP Driver: ROM polling case 1\n");
450                 break;
451         case 0x2:
452                 /* Boot First Phase ended  */
453                 warning = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
454                 edbg("SEP Driver: ROM polling case 2\n");
455                 break;
456         case 0x4:
457                 /* Cold boot ended successfully  */
458                 warning = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
459                 edbg("SEP Driver: ROM polling case 4\n");
460                 Error = 0;
461                 break;
462         case 0x8:
463                 /* Warmboot ended successfully */
464                 warning = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
465                 edbg("SEP Driver: ROM polling case 8\n");
466                 Error = 0;
467                 break;
468         case 0x10:
469                 /* ColdWarm boot ended successfully */
470                 warning = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
471                 edbg("SEP Driver: ROM polling case 16\n");
472                 Error = 0;
473                 break;
474         case 0x20:
475                 edbg("SEP Driver: ROM polling case 32\n");
476                 break;
477         }
478
479 #endif
480 }