/////////////////////////////////////////////////////////////////////////////////// // File : utils.h // Date : 18/10/2013 // Author : alain greiner // Copyright (c) UPMC-LIP6 /////////////////////////////////////////////////////////////////////////////////// // The utils.c and utils.h files are part of the GIET-VM nano-kernel. // They define more or less the GIET-VM Hardware Abstraction Layer, // and contains various utility functions, that can be used by both the // boot code and the kernel code (but not by the user applications). /////////////////////////////////////////////////////////////////////////////////// #ifndef GIET_UTILS_H #define GIET_UTILS_H #include #include ////////////////////////////////////////////////////////////////////////////////// // NULL pointer definition ////////////////////////////////////////////////////////////////////////////////// #define NULL (void *)0 /////////////////////////////////////////////////////////////////////////////////// // This structure is used to have one single lock in a cache line /////////////////////////////////////////////////////////////////////////////////// typedef struct giet_lock_s { unsigned int value; unsigned int padding[15]; } giet_lock_t; /////////////////////////////////////////////////////////////////////////////////// // To access the virtual addresses defined in the giet_vsegs.ld file. /////////////////////////////////////////////////////////////////////////////////// typedef struct _ld_symbol_s _ld_symbol_t; extern _ld_symbol_t boot_code_vbase; extern _ld_symbol_t boot_data_vbase; extern _ld_symbol_t kernel_code_vbase; extern _ld_symbol_t kernel_data_vbase; extern _ld_symbol_t kernel_uncdata_vbase; extern _ld_symbol_t kernel_init_vbase; /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// // CP0 registers access functions /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// // Returns CP0_SCHED register content // (virtual base address of the processor scheduler) /////////////////////////////////////////////////////////////////////////////////// extern unsigned int _get_sched(void); /////////////////////////////////////////////////////////////////////////////////// // Returns CP0_EPC register content. /////////////////////////////////////////////////////////////////////////////////// extern unsigned int _get_epc(void); /////////////////////////////////////////////////////////////////////////////////// // Returns CP0_BVAR register content. /////////////////////////////////////////////////////////////////////////////////// extern unsigned int _get_bvar(void); /////////////////////////////////////////////////////////////////////////////////// // Returns CP0_CR register content. /////////////////////////////////////////////////////////////////////////////////// extern unsigned int _get_cr(void); /////////////////////////////////////////////////////////////////////////////////// // Returns CP0_SR register content. /////////////////////////////////////////////////////////////////////////////////// extern unsigned int _get_sr(void); /////////////////////////////////////////////////////////////////////////////////// // Returns CP0_PROCID register content. // Processor identifier (12 bits) /////////////////////////////////////////////////////////////////////////////////// extern unsigned int _get_procid(void); /////////////////////////////////////////////////////////////////////////////////// // Returns CP0_TIME register content. // Processor local time (32 bits) /////////////////////////////////////////////////////////////////////////////////// extern unsigned int _get_proctime(void); /////////////////////////////////////////////////////////////////////////////////// // Save CP0_SR value to variable pointed by save_sr_ptr and disable IRQs. /////////////////////////////////////////////////////////////////////////////////// extern void _it_disable( unsigned int* save_sr_ptr ); /////////////////////////////////////////////////////////////////////////////////// // Restore CP0_SR register from variable pointed by save_sr_ptr. /////////////////////////////////////////////////////////////////////////////////// extern void _it_restore( unsigned int* save_sr_ptr ); /////////////////////////////////////////////////////////////////////////////////// // Set a new value in CP0_SCHED register. // (virtual base address of the processor scheduler) /////////////////////////////////////////////////////////////////////////////////// extern void _set_sched(unsigned int value); /////////////////////////////////////////////////////////////////////////////////// // Set a new value in CP0_SR register. /////////////////////////////////////////////////////////////////////////////////// extern void _set_sr(unsigned int value); /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// // CP2 registers access functions /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// // Returns CP2_PTPR register value. // Page table physical base address for the running context. // Contains only the 27 MSB bits, right justified. /////////////////////////////////////////////////////////////////////////////////// extern unsigned int _get_mmu_ptpr(void); /////////////////////////////////////////////////////////////////////////////////// // Returns CP2_MODE register value. // MMU current mode, defined by 4 bits, right justified: ITLB/DTLB/ICACHE/DCACHE /////////////////////////////////////////////////////////////////////////////////// extern unsigned int _get_mmu_mode(void); /////////////////////////////////////////////////////////////////////////////////// // Set a new value in CP2_PTPR register. /////////////////////////////////////////////////////////////////////////////////// extern void _set_mmu_ptpr(unsigned int value); /////////////////////////////////////////////////////////////////////////////////// // Set a new value in CP2_MODE register. /////////////////////////////////////////////////////////////////////////////////// extern void _set_mmu_mode(unsigned int value); /////////////////////////////////////////////////////////////////////////////////// // Set a value in CP2_DCACHE_INVAL register. // It invalidates the data cache line, if the virtual address defined by the // value argument hit in DCACHE. /////////////////////////////////////////////////////////////////////////////////// extern void _set_mmu_dcache_inval(unsigned int value); /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// // Physical addressing functions /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// // This function makes a physical read access to a 32 bits word in memory, // after a temporary DTLB de-activation and paddr extension. //////////////////////////////////////////////////////////////////////////// extern unsigned int _physical_read( unsigned long long paddr ); //////////////////////////////////////////////////////////////////////////// // This function makes a physical write access to a 32 bits word in memory, // after a temporary DTLB de-activation and paddr extension. //////////////////////////////////////////////////////////////////////////// extern void _physical_write( unsigned long long paddr, unsigned int value ); //////////////////////////////////////////////////////////////////////////// // This function makes a physical read access to a 64 bits word in memory, // after a temporary DTLB de-activation and paddr extension. //////////////////////////////////////////////////////////////////////////// extern unsigned long long _physical_read_ull( unsigned long long paddr ); //////////////////////////////////////////////////////////////////////////// // This function makes a physical write access to a 64 bits word in memory, // after a temporary DTLB de-activation and paddr extension. //////////////////////////////////////////////////////////////////////////// extern void _physical_write_ull( unsigned long long paddr, unsigned long long value ); /////////////////////////////////////////////////////////////////////////////////// // This function makes a memcpy from a source buffer to a destination buffer, // using physical addresses, after a temporary DTLB de-activation. // The source and destination buffers must be word aligned, and size must be // multiple of 4 bytes. /////////////////////////////////////////////////////////////////////////////////// extern void _physical_memcpy( unsigned long long dst_paddr, unsigned long long src_paddr, unsigned int size ); /////////////////////////////////////////////////////////////////////////////////// // This function set a data value in all words of a destination buffer, // using physical addresses, after a temporary DTLB de-activation. // The destination buffer must be word aligned, and size multiple of 4 bytes. /////////////////////////////////////////////////////////////////////////////////// extern void _physical_memset( unsigned long long buf_paddr, unsigned int size, unsigned int data ); /////////////////////////////////////////////////////////////////////////////////// // This function is used by several drivers (_xxx_get_register() function). // If the MMU is not activated, the virtual address is extended using // X_IO and Y_IO to reach the cluster_io. /////////////////////////////////////////////////////////////////////////////////// extern unsigned int _io_extended_read( unsigned int* vaddr ); /////////////////////////////////////////////////////////////////////////////////// // This function is used by all drivers (_xxx_set_register() function) // If the MMU is not activated, the virtual address is extended using // X_IO and Y_IO to reach the cluster_io. /////////////////////////////////////////////////////////////////////////////////// extern void _io_extended_write( unsigned int* vaddr, unsigned int value ); /////////////////////////////////////////////////////////////////////////////////// // Locks access functions /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// // Takes a lock with a blocking ll/sc atomic access. // - When the cache coherence is granted by the hardware, // the first read is a standard (cacheable) lw, as the local copy // can be polled when the lock is already taken by another task, reducing // trafic on the interconnect. When the lock is released by the owner task, // the local copy is updated or invalidated by the coherence protocol. // - If there is no hardware cache coherence a random delay is introduced // between two successive retry. /////////////////////////////////////////////////////////////////////////////////// extern void _get_lock(giet_lock_t* lock); /////////////////////////////////////////////////////////////////////////////////// // Release a previouly taken lock. /////////////////////////////////////////////////////////////////////////////////// extern void _release_lock(giet_lock_t* lock); /////////////////////////////////////////////////////////////////////////////////// // TTY0 access functions /////////////////////////////////////////////////////////////////////////////////// extern void _puts( char* string ); extern void _putx( unsigned int val ); extern void _putd( unsigned int val ); extern void _putl( unsigned long long val ); extern void _printf(char* format, ...); extern void _getc( char* byte ); /////////////////////////////////////////////////////////////////////////////////// // Scheduler and task context access functions /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// // Returns index of the currently running task from the processor scheduler. /////////////////////////////////////////////////////////////////////////////////// extern unsigned int _get_current_task_id(void); //////////////////////////////////////////////////////////////////////////////////// // This function returns the content of a context slot // for a task identified by the ltid argument (local task index), // and a processor identified by the (x,y,p) arguments. //////////////////////////////////////////////////////////////////////////////////// extern unsigned int _get_task_slot( unsigned int x, unsigned int y, unsigned int p, unsigned int ltid, unsigned int slot ); //////////////////////////////////////////////////////////////////////////////////// // This function updates the content of a context slot // for any task identified by the ltid argument (local task index), // and a processor identified by the (x,y,p) arguments. //////////////////////////////////////////////////////////////////////////////////// extern void _set_task_slot( unsigned int x, unsigned int y, unsigned int p, unsigned int ltid, unsigned int slot, unsigned int value ); //////////////////////////////////////////////////////////////////////////////////// // This function returns the content of a context slot for the running task. //////////////////////////////////////////////////////////////////////////////////// extern unsigned int _get_context_slot( unsigned int slot ); //////////////////////////////////////////////////////////////////////////////////// // This function updates the content of a context slot for the running task. //////////////////////////////////////////////////////////////////////////////////// extern void _set_context_slot( unsigned int slot, unsigned int value ); /////////////////////////////////////////////////////////////////////////////////// // Mapping access functions /////////////////////////////////////////////////////////////////////////////////// extern mapping_cluster_t * _get_cluster_base(mapping_header_t* header); extern mapping_pseg_t * _get_pseg_base(mapping_header_t* header); extern mapping_vspace_t * _get_vspace_base(mapping_header_t* header); extern mapping_vseg_t * _get_vseg_base(mapping_header_t* header); extern mapping_vobj_t * _get_vobj_base(mapping_header_t* header); extern mapping_task_t * _get_task_base(mapping_header_t* header); extern mapping_proc_t * _get_proc_base(mapping_header_t* header); extern mapping_irq_t * _get_irq_base(mapping_header_t* header); extern mapping_coproc_t * _get_coproc_base(mapping_header_t* header); extern mapping_cp_port_t * _get_cp_port_base(mapping_header_t* header); extern mapping_periph_t * _get_periph_base(mapping_header_t* header); /////////////////////////////////////////////////////////////////////////////////// // Miscelaneous functions /////////////////////////////////////////////////////////////////////////////////// extern void _exit(void); extern void _random_wait( unsigned int value ); extern void _break( char* str); extern unsigned int _strncmp(const char* s1, const char* s2, unsigned int n); extern char* _strcpy( char* dest, char* source ); extern void _dcache_buf_invalidate( unsigned int buf_vbase, unsigned int buf_size ); extern unsigned int _heap_info( unsigned int* vaddr, unsigned int* length, unsigned int x, unsigned int y ); /////////////////////////////////////////////////////////////////////////////////// // Required by GCC /////////////////////////////////////////////////////////////////////////////////// extern void* memcpy( void* _dst, const void* _src, unsigned int size ); extern void* memset( void* dst, int s, unsigned int count ); #endif // Local Variables: // tab-width: 4 // c-basic-offset: 4 // c-file-offsets:((innamespace . 0)(inline-open . 0)) // indent-tabs-mode: nil // End: // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4