| [258] | 1 | /////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 2 | // File     : iob_driver.c | 
|---|
 | 3 | // Date     : 23/05/2013 | 
|---|
 | 4 | // Author   : alain greiner | 
|---|
 | 5 | // Copyright (c) UPMC-LIP6 | 
|---|
 | 6 | /////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 7 | // The iob_driver.c and iob_driver.h files are part ot the GIET-VM kernel. | 
|---|
 | 8 | // This driver supports the TSAR vci_io_bridge, that is a bridge to access | 
|---|
 | 9 | // The external peripherals, implementing an IO_MMU. | 
|---|
| [298] | 10 | // This component can be instanciated in more than one cluster. | 
|---|
| [258] | 11 | /////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [320] | 12 | // The SEG_IOB_BASE virtual addresses must be defined in hard_config.h file. | 
|---|
 | 13 | // The physical base address is supposed to be (cluster_xy << 32) | SEG_IOB_BASE. | 
|---|
| [258] | 14 | /////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 15 |  | 
|---|
 | 16 | #include <giet_config.h> | 
|---|
 | 17 | #include <iob_driver.h> | 
|---|
 | 18 | #include <utils.h> | 
|---|
 | 19 |  | 
|---|
| [320] | 20 | #if !defined(SEG_IOB_BASE)  | 
|---|
 | 21 | # error: You must define SEG_IOB_BASE in the hard_config.h file | 
|---|
 | 22 | #endif | 
|---|
 | 23 |  | 
|---|
| [258] | 24 | #if !defined(GIET_USE_IOMMU)  | 
|---|
 | 25 | # error: You must define GIET_USE_IOMMU in the giet_config.h file | 
|---|
 | 26 | #endif | 
|---|
 | 27 |  | 
|---|
 | 28 | #if !defined( USE_IOB ) | 
|---|
 | 29 | # error: You must define USE_IOB in the hard_config.h file | 
|---|
 | 30 | #endif | 
|---|
 | 31 |  | 
|---|
| [298] | 32 |  | 
|---|
| [258] | 33 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| [298] | 34 | // This low level function returns the value contained in register "index" | 
|---|
 | 35 | // in the IOB component contained in cluster "cluster_xy" | 
|---|
| [258] | 36 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| [298] | 37 | unsigned int _iob_get_register( unsigned int cluster_xy,   // cluster index | 
|---|
 | 38 |                                 unsigned int index )       // register index | 
|---|
| [258] | 39 | { | 
|---|
| [320] | 40 |     unsigned long long paddr = (unsigned long long)SEG_IOB_BASE +  | 
|---|
| [298] | 41 |                                ((unsigned long long)cluster_xy << 32) + | 
|---|
 | 42 |                                ((unsigned long long)index << 2); | 
|---|
| [258] | 43 |  | 
|---|
| [298] | 44 |     return _physical_read( paddr ); | 
|---|
 | 45 | } | 
|---|
 | 46 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 47 | // This low level function sets a new value in register "index" | 
|---|
 | 48 | // in the IOB component contained in cluster "cluster_xy" | 
|---|
 | 49 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 50 | void _iob_set_register( unsigned int cluster_xy,       // cluster index | 
|---|
 | 51 |                         unsigned int index,            // register index | 
|---|
 | 52 |                         unsigned int value )           // value to be written | 
|---|
 | 53 | { | 
|---|
| [320] | 54 |     unsigned long long paddr = (unsigned long long)SEG_IOB_BASE +  | 
|---|
| [298] | 55 |                                ((unsigned long long)cluster_xy << 32) + | 
|---|
 | 56 |                                ((unsigned long long)index << 2); | 
|---|
| [258] | 57 |  | 
|---|
| [298] | 58 |     _physical_write( paddr, value ); | 
|---|
 | 59 | } | 
|---|
| [258] | 60 |  | 
|---|
 | 61 |  | 
|---|
| [298] | 62 |  | 
|---|
 | 63 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 64 | // This function invalidates a TLB entry identified by a virtual address. | 
|---|
 | 65 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 66 | void _iob_inval_tlb_entry( unsigned int cluster_xy, | 
|---|
 | 67 |                            unsigned int vaddr ) | 
|---|
 | 68 | { | 
|---|
 | 69 |     _iob_set_register( cluster_xy, | 
|---|
 | 70 |                        IOB_INVAL_PTE, | 
|---|
 | 71 |                        vaddr ); | 
|---|
| [258] | 72 | } | 
|---|
 | 73 |  | 
|---|
| [298] | 74 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 75 | // This function sets a new value in IOB_IOMMU_PTPR register. | 
|---|
 | 76 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 77 | void _iob_set_iommu_ptpr( unsigned int cluster_xy, | 
|---|
 | 78 |                           unsigned int value ) | 
|---|
 | 79 | { | 
|---|
 | 80 |     _iob_set_register( cluster_xy, | 
|---|
 | 81 |                        IOB_IOMMU_PTPR, | 
|---|
 | 82 |                        value ); | 
|---|
 | 83 | } | 
|---|
| [258] | 84 |  | 
|---|
 | 85 | // Local Variables: | 
|---|
 | 86 | // tab-width: 4 | 
|---|
 | 87 | // c-basic-offset: 4 | 
|---|
 | 88 | // c-file-offsets:((innamespace . 0)(inline-open . 0)) | 
|---|
 | 89 | // indent-tabs-mode: nil | 
|---|
 | 90 | // End: | 
|---|
 | 91 | // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 | 
|---|
 | 92 |  | 
|---|