Staging: sep: Put all the ARM bits together
[deliverable/linux.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 function that is activated on the succesfull probe of the SEP device
175 */
176 static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
177
178 static struct pci_device_id sep_pci_id_tbl[] = {
179 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)},
180 {0}
181 };
182
183 MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl);
184
185 /* field for registering driver to PCI device */
186 static struct pci_driver sep_pci_driver = {
187 .name = "sep_sec_driver",
188 .id_table = sep_pci_id_tbl,
189 .probe = sep_probe
190 };
191
192 /*
193 This functions locks the area of the resisnd and cache sep code
194 */
195 void sep_lock_cache_resident_area(void)
196 {
197 return;
198 }
199
200 /*
201 This functions copies the cache and resident from their source location into
202 destination memory, which is external to Linux VM and is given as
203 physical address
204 */
205 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)
206 {
207 unsigned long resident_addr;
208 unsigned long cache_addr;
209 const struct firmware *fw;
210
211 char *cache_name = "cache.image.bin";
212 char *res_name = "resident.image.bin";
213
214 /* error */
215 int error;
216
217 /*--------------------------------
218 CODE
219 -------------------------------------*/
220 error = 0;
221
222 edbg("SEP Driver:rar_virtual is %p\n", sep_dev->rar_virtual_address);
223 edbg("SEP Driver:rar_physical is %08lx\n", sep_dev->rar_physical_address);
224
225 sep_dev->rar_region_addr = (unsigned long) sep_dev->rar_virtual_address;
226
227 sep_dev->cache_physical_address = sep_dev->rar_physical_address;
228 sep_dev->cache_virtual_address = sep_dev->rar_virtual_address;
229
230 /* load cache */
231 error = request_firmware(&fw, cache_name, &sep_dev->sep_pci_dev_ptr->dev);
232 if (error) {
233 edbg("SEP Driver:cant request cache fw\n");
234 goto end_function;
235 }
236
237 edbg("SEP Driver:cache data loc is %p\n", (void *) fw->data);
238 edbg("SEP Driver:cache data size is %08Zx\n", fw->size);
239
240 memcpy((void *) sep_dev->cache_virtual_address, (void *) fw->data, fw->size);
241
242 sep_dev->cache_size = fw->size;
243
244 cache_addr = (unsigned long) sep_dev->cache_virtual_address;
245
246 release_firmware(fw);
247
248 sep_dev->resident_physical_address = sep_dev->cache_physical_address + sep_dev->cache_size;
249 sep_dev->resident_virtual_address = sep_dev->cache_virtual_address + sep_dev->cache_size;
250
251 /* load resident */
252 error = request_firmware(&fw, res_name, &sep_dev->sep_pci_dev_ptr->dev);
253 if (error) {
254 edbg("SEP Driver:cant request res fw\n");
255 goto end_function;
256 }
257
258 edbg("SEP Driver:res data loc is %p\n", (void *) fw->data);
259 edbg("SEP Driver:res data size is %08Zx\n", fw->size);
260
261 memcpy((void *) sep_dev->resident_virtual_address, (void *) fw->data, fw->size);
262
263 sep_dev->resident_size = fw->size;
264
265 release_firmware(fw);
266
267 resident_addr = (unsigned long) sep_dev->resident_virtual_address;
268
269 edbg("SEP Driver:resident_addr (physical )is %08lx\n", sep_dev->resident_physical_address);
270 edbg("SEP Driver:cache_addr (physical) is %08lx\n", sep_dev->cache_physical_address);
271
272 edbg("SEP Driver:resident_addr (logical )is %08lx\n", resident_addr);
273 edbg("SEP Driver:cache_addr (logical) is %08lx\n", cache_addr);
274
275 edbg("SEP Driver:resident_size is %08lx\n", sep_dev->resident_size);
276 edbg("SEP Driver:cache_size is %08lx\n", sep_dev->cache_size);
277
278
279
280 /* physical addresses */
281 *dst_new_cache_addr_ptr = sep_dev->cache_physical_address;
282 *dst_new_resident_addr_ptr = sep_dev->resident_physical_address;
283 end_function:
284 return error;
285 }
286
287 /*
288 This functions maps and allocates the
289 shared area on the external RAM (device)
290 The input is shared_area_size - the size of the memory to
291 allocate. The outputs
292 are kernel_shared_area_addr_ptr - the kerenl
293 address of the mapped and allocated
294 shared area, and phys_shared_area_addr_ptr
295 - the physical address of the shared area
296 */
297 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)
298 {
299 // shared_virtual_address = ioremap_nocache(0xda00000,shared_area_size);
300 sep_dev->shared_virtual_address = kmalloc(shared_area_size, GFP_KERNEL);
301 if (!sep_dev->shared_virtual_address) {
302 edbg("sep_driver:shared memory kmalloc failed\n");
303 return -1;
304 }
305 /* FIXME */
306 sep_dev->shared_physical_address = __pa(sep_dev->shared_virtual_address);
307 /* shared_physical_address = 0xda00000; */
308 *kernel_shared_area_addr_ptr = (unsigned long) sep_dev->shared_virtual_address;
309 /* set the physical address of the shared area */
310 *phys_shared_area_addr_ptr = sep_dev->shared_physical_address;
311 edbg("SEP Driver:shared_virtual_address is %p\n", sep_dev->shared_virtual_address);
312 edbg("SEP Driver:shared_region_size is %08lx\n", shared_area_size);
313 edbg("SEP Driver:shared_physical_addr is %08lx\n", *phys_shared_area_addr_ptr);
314
315 return 0;
316 }
317
318 /*
319 This functions unmaps and deallocates the shared area
320 on the external RAM (device)
321 The input is shared_area_size - the size of the memory to deallocate,kernel_
322 shared_area_addr_ptr - the kernel address of the mapped and allocated
323 shared area,phys_shared_area_addr_ptr - the physical address of
324 the shared area
325 */
326 void sep_unmap_and_free_shared_area(unsigned long shared_area_size, unsigned long kernel_shared_area_addr, unsigned long phys_shared_area_addr)
327 {
328 kfree((void *) kernel_shared_area_addr);
329 }
330
331 /*
332 This functions returns the physical address inside shared area according
333 to the virtual address. It can be either on the externa RAM device
334 (ioremapped), or on the system RAM
335 This implementation is for the external RAM
336 */
337 unsigned long sep_shared_area_virt_to_phys(unsigned long virt_address)
338 {
339 edbg("SEP Driver:sh virt to phys v %08lx\n", virt_address);
340 edbg("SEP Driver:sh virt to phys p %08lx\n", sep_dev->shared_physical_address + (virt_address - (unsigned long) sep_dev->shared_virtual_address));
341
342 return (unsigned long) sep_dev->shared_physical_address + (virt_address - (unsigned long) sep_dev->shared_virtual_address);
343 }
344
345 /*
346 This functions returns the virtual address inside shared area
347 according to the physical address. It can be either on the
348 externa RAM device (ioremapped), or on the system RAM This implementation
349 is for the external RAM
350 */
351 unsigned long sep_shared_area_phys_to_virt(unsigned long phys_address)
352 {
353 return (unsigned long) sep_dev->shared_virtual_address + (phys_address - sep_dev->shared_physical_address);
354 }
355
356
357 /*
358 function that is activaed on the succesfull probe of the SEP device
359 */
360 static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
361 {
362 int error = 0;
363
364 edbg("Sep pci probe starting\n");
365
366 /* enable the device */
367 error = pci_enable_device(pdev);
368 if (error) {
369 edbg("error enabling pci device\n");
370 goto end_function;
371 }
372
373 /* set the pci dev pointer */
374 sep_dev->sep_pci_dev_ptr = pdev;
375
376 /* get the io memory start address */
377 sep_dev->io_memory_start_physical_address = pci_resource_start(pdev, 0);
378 if (!sep_dev->io_memory_start_physical_address) {
379 edbg("SEP Driver error pci resource start\n");
380 goto end_function;
381 }
382
383 /* get the io memory end address */
384 sep_dev->io_memory_end_physical_address = pci_resource_end(pdev, 0);
385 if (!sep_dev->io_memory_end_physical_address) {
386 edbg("SEP Driver error pci resource end\n");
387 goto end_function;
388 }
389
390 sep_dev->io_memory_size = sep_dev->io_memory_end_physical_address - sep_dev->io_memory_start_physical_address + 1;
391
392 edbg("SEP Driver:io_memory_start_physical_address is %08lx\n", sep_dev->io_memory_start_physical_address);
393
394 edbg("SEP Driver:io_memory_end_phyaical_address is %08lx\n", sep_dev->io_memory_end_physical_address);
395
396 edbg("SEP Driver:io_memory_size is %08lx\n", sep_dev->io_memory_size);
397
398 sep_dev->io_memory_start_virtual_address = ioremap_nocache(sep_dev->io_memory_start_physical_address, sep_dev->io_memory_size);
399 if (!sep_dev->io_memory_start_virtual_address) {
400 edbg("SEP Driver error ioremap of io memory\n");
401 goto end_function;
402 }
403
404 edbg("SEP Driver:io_memory_start_virtual_address is %p\n", sep_dev->io_memory_start_virtual_address);
405
406 sep_dev->reg_base_address = (void __iomem *) sep_dev->io_memory_start_virtual_address;
407
408
409 /* set up system base address and shared memory location */
410
411 sep_dev->rar_virtual_address = kmalloc(2 * SEP_RAR_IO_MEM_REGION_SIZE, GFP_KERNEL);
412
413 if (!sep_dev->rar_virtual_address) {
414 edbg("SEP Driver:cant kmalloc rar\n");
415 goto end_function;
416 }
417 /* FIXME */
418 sep_dev->rar_physical_address = __pa(sep_dev->rar_virtual_address);
419
420 edbg("SEP Driver:rar_physical is %08lx\n", sep_dev->rar_physical_address);
421 edbg("SEP Driver:rar_virtual is %p\n", sep_dev->rar_virtual_address);
422
423 #if !SEP_DRIVER_POLLING_MODE
424
425 edbg("SEP Driver: about to write IMR and ICR REG_ADDR\n");
426
427 /* clear ICR register */
428 sep_write_reg(sep_dev, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
429
430 /* set the IMR register - open only GPR 2 */
431 sep_write_reg(sep_dev, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
432
433 /* figure out our irq */
434 /* FIXME: */
435 error = pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, (u8 *) & sep_dev->sep_irq);
436
437 edbg("SEP Driver: my irq is %d\n", sep_irq);
438
439 edbg("SEP Driver: about to call request_irq\n");
440 /* get the interrupt line */
441 error = request_irq(sep_irq, sep_inthandler, IRQF_SHARED, "sep_driver", &sep_dev->reg_base_address);
442 if (error)
443 goto end_function;
444
445 goto end_function;
446 edbg("SEP Driver: about to write IMR REG_ADDR");
447
448 /* set the IMR register - open only GPR 2 */
449 sep_write_reg(sep_dev, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
450
451 #endif /* SEP_DRIVER_POLLING_MODE */
452 end_function:
453 return error;
454 }
455
456 /*
457 this function registers th driver to
458 the device subsystem( either PCI, USB, etc)
459 */
460 int sep_register_driver_to_device(void)
461 {
462 return pci_register_driver(&sep_pci_driver);
463 }
464
465
466
This page took 0.055012 seconds and 5 git commands to generate.