Changeset 189 for soft


Ignore:
Timestamp:
Aug 7, 2012, 6:37:49 PM (12 years ago)
Author:
alain
Message:

Introducing a new release where all initialisation
is done in the boot code.

Location:
soft/giet_vm
Files:
15 added
3 deleted
31 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/Makefile

    r178 r189  
    55DU=mipsel-unknown-elf-objdump
    66
    7 #current directory absolute path
    8 SOFT_PATH       = $(shell pwd)/
     7SYS_OBJS     = build/sys/vm_handler.o \
     8                       build/sys/sys_handler.o \
     9               build/sys/giet.o \
     10               build/sys/switch.o \
     11               build/sys/common.o \
     12               build/sys/ctx_handler.o \
     13               build/sys/drivers.o \
     14               build/sys/exc_handler.o \
     15               build/sys/irq_handler.o \
     16               build/sys/kernel_init.o
    917
    10 SYS_DIR    = sys
    11 LIB_DIR    = libs
    12 BOOT_DIR   = boot
     18BOOT_OBJS    = build/boot/reset.o \
     19               build/boot/boot_init.o
    1320
    14 BOOT_PATH   = $(SOFT_PATH)$(BOOT_DIR)
    15 SYS_PATH    = $(SOFT_PATH)$(SYS_DIR)
    16 LIB_PATH    = $(SOFT_PATH)$(LIB_DIR)
    17 XML_PATH    = $(SOFT_PATH)xml/
    18 MEMO_PATH   = $(SOFT_PATH)memo/
    19 BUILD_PATH      = $(SOFT_PATH)build/
    20 ELF_PATH        = $(SOFT_PATH)build/
    21 APP_PATH        = $(SOFT_PATH)apps/
     21DISPLAY_OBJS = build/display/main.o \
     22               build/libs/stdio.o \
     23               build/libs/utils.o
    2224
    23 #list of all applications directory
    24 APP_DIRS        = $(shell ls -d $(APP_PATH)/*/ )
     25ROUTER_OBJS  = build/router/main.o \
     26               build/libs/mwmr_channel.o \
     27               build/libs/stdio.o \
     28               build/libs/utils.o
    2529
    26 SYS_OBJS_LIST = \
    27         vm_handler.o \
    28                 sys_handler.o \
    29                 giet.o \
    30                 switch.o \
    31                 common.o \
    32                 ctx_handler.o \
    33                 drivers.o \
    34                 exc_handler.o \
    35                 irq_handler.o \
    36                 kernel_init.o
     30HELLO_OBJS   = build/hello/main.o \
     31               build/libs/stdio.o \
     32               build/libs/utils.o
    3733
    38 BOOT_OBJS_LIST = reset.o \
    39                                 boot_handler.o
    40 
    41 #LIB_SRCS = $(wildcard $(LIB_DIR)/*.c)
    42 LIB_OBJS_LIST = stdio.o \
    43                                 mwmr_channel.o \
    44                                 barrier.o \
    45                                 spin_lock.o
    46 
    47 LIB_OBJS        = $(patsubst %,$(LIB_DIR)/%,$(LIB_OBJS_LIST))
    48 SYS_OBJS        = $(patsubst %,$(SYS_DIR)/%,$(SYS_OBJS_LIST))
    49 BOOT_OBJS   = $(patsubst %,$(BOOT_DIR)/%,$(BOOT_OBJS_LIST))
    50 
     34PGCD_OBJS    = build/pgcd/main.o \
     35               build/libs/stdio.o \
     36               build/libs/utils.o
    5137
    5238CFLAGS=-Wall -ffreestanding -mno-gpopt -mips32 -g
    5339
    54 SYS_INCLUDE  = -I$(SYS_PATH)  -I$(XML_PATH) -I$(LIB_PATH) -I.
    55 BOOT_INCLUDE = -I$(BOOT_PATH) -I$(XML_PATH) -I$(LIB_PATH) -I.
    56 LIB_INCLUDE      = -I$(LIB_PATH)  -I$(XML_PATH) -I.
    57 APP_INCLUDE      = -I$(LIB_PATH)  -I$(XML_PATH) -I$(SOFT_PATH)
     40INCLUDE = -Iboot -Isys -Ixml -Ilibs -I.
    5841
    5942TRASH= /dev/null||true
    6043
    61 .PHONY: apps prepare
    62 
    63 all: prepare soft.elf
     44all: soft.elf
    6445       
    65 ## merge all *.elf to soft.elf
    66 soft.elf: boot.elf sys.elf map.bin apps
    67         $(MAKE) -C $(MEMO_PATH)
    68         $(MEMO_PATH)/memo.x  map.bin
    69         $(DU) -D $@ > $(BUILD_PATH)$@.txt
    70 
    71 ## prepare the environement
    72 prepare:
    73         @mkdir $(BUILD_PATH)                            2>$(TRASH)
    74         @mkdir $(ELF_PATH)                                      2>$(TRASH)
    75         @mkdir $(BUILD_PATH)/$(BOOT_DIR)        2>$(TRASH)
    76         @mkdir $(BUILD_PATH)/$(LIB_DIR)         2>$(TRASH)
    77         @mkdir $(BUILD_PATH)/$(SYS_DIR)         2>$(TRASH)
     46## merge all *.elf and map.bin to soft.elf
     47soft.elf: build/boot/boot.elf \
     48          build/sys/sys.elf \
     49          build/display/display.elf \
     50          build/router/router.elf \
     51          build/pgcd/pgcd.elf \
     52          build/hello/hello.elf \
     53          map.bin
     54        $(MAKE) -C memo
     55        memo/memo.x  map.bin
     56        $(DU) -D $@ > build$@.txt
    7857
    7958### mapping compilation
    8059map.bin: map.xml
    81         $(MAKE) -C $(XML_PATH)
    82         $(XML_PATH)/xml2bin $(SOFT_PATH)map.xml $(SOFT_PATH)map.bin
     60        $(MAKE) -C xml
     61        xml/xml2bin map.xml map.bin
    8362
    8463### system compilation
    85 sys.elf: $(SYS_OBJS) $(SYS_PATH)/sys.ld
    86         (cd $(BUILD_PATH); $(LD) -o $@ -T $(SYS_PATH)/sys.ld $(SYS_OBJS) )
    87         (cd $(BUILD_PATH); $(DU) -D $@ > $@.txt)
     64build/sys/sys.elf: $(SYS_OBJS) sys/sys.ld
     65        $(LD) -o $@ -T sys/sys.ld $(SYS_OBJS)
     66        $(DU) -D $@ > $@.txt
    8867
    89 $(SYS_DIR)/%.o: $(SYS_DIR)/%.c
    90         $(CC) $(SYS_INCLUDE) $(CFLAGS)  -c -o $(BUILD_PATH)/$@ $<
     68build/sys/%.o: sys/%.c
     69        $(CC) $(INCLUDE) $(CFLAGS)  -c -o $@ $<
    9170
    92 $(SYS_DIR)/%.o: $(SYS_DIR)/%.s
    93         $(CC) $(SYS_INCLUDE) $(CFLAGS)  -c -o $(BUILD_PATH)/$@ $<
    94 
    95 $(SYS_DIR)/%.o: $(SYS_DIR)/%.S
    96         $(CC) $(SYS_INCLUDE) $(CFLAGS)  -c -o $(BUILD_PATH)/$@ $<
     71build/sys/%.o: sys/%.s
     72        $(CC) $(INCLUDE) $(CFLAGS)  -c -o $@ $<
    9773
    9874### boot compilation
    99 boot.elf: $(BOOT_OBJS) $(BOOT_PATH)/boot.ld
    100         (cd $(BUILD_PATH); $(LD) -o $@ -T $(BOOT_PATH)/boot.ld $(BOOT_OBJS) )
    101         (cd $(BUILD_PATH); $(DU) -D $@ > $@.txt)
     75build/boot/boot.elf: $(BOOT_OBJS) boot/boot.ld
     76        $(LD) -o $@ -T boot/boot.ld $(BOOT_OBJS)
     77        $(DU) -D $@ > $@.txt
    10278
    103 $(BOOT_DIR)/%.o: $(BOOT_DIR)/%.c
    104         $(CC) $(BOOT_INCLUDE) $(CFLAGS)  -c -o $(BUILD_PATH)/$@ $<
     79build/boot/%.o: boot/%.c
     80        $(CC) $(INCLUDE) $(CFLAGS)  -c -o $@ $<
    10581
    106 $(BOOT_DIR)/%.o: $(BOOT_DIR)/%.s
    107         $(CC) $(BOOT_INCLUDE) $(CFLAGS)  -c -o $(BUILD_PATH)/$@ $<
     82build/boot/%.o: boot/%.S
     83        $(CC) $(INCLUDE) $(CFLAGS)  -c -o $@ $<
    10884
    109 $(BOOT_DIR)/%.o: $(BOOT_DIR)/%.S
    110         $(CC) $(BOOT_INCLUDE) $(CFLAGS)  -c -o $(BUILD_PATH)/$@ $<
     85### display compilation
     86build/display/display.elf: $(DISPLAY_OBJS) display/display.ld
     87        $(LD) -o $@ -T display/display.ld $(DISPLAY_OBJS)
     88        $(DU) -D $@ > $@.txt
     89
     90build/display/main.o: display/main.c
     91        $(CC) $(INCLUDE) $(CFLAGS)  -c -o $@ $<
     92
     93### router compilation
     94build/router/router.elf: $(ROUTER_OBJS) router/router.ld
     95        $(LD) -o $@ -T router/router.ld $(ROUTER_OBJS)
     96        $(DU) -D $@ > $@.txt
     97
     98build/router/main.o: router/main.c
     99        $(CC) $(INCLUDE) $(CFLAGS)  -c -o $@ $<
     100
     101### hello compilation
     102build/hello/hello.elf: $(HELLO_OBJS) hello/hello.ld
     103        $(LD) -o $@ -T hello/hello.ld $(HELLO_OBJS)
     104        $(DU) -D $@ > $@.txt
     105
     106build/hello/main.o: hello/main.c
     107        $(CC) $(INCLUDE) $(CFLAGS)  -c -o $@ $<
     108
     109### pgcd compilation
     110build/pgcd/pgcd.elf: $(PGCD_OBJS) pgcd/pgcd.ld
     111        $(LD) -o $@ -T pgcd/pgcd.ld $(PGCD_OBJS)
     112        $(DU) -D $@ > $@.txt
     113
     114build/pgcd/main.o: pgcd/main.c
     115        $(CC) $(INCLUDE) $(CFLAGS)  -c -o $@ $<
    111116
    112117### libs compilation
    113 $(LIB_DIR)/%.o: $(LIB_DIR)/%.c
    114         $(CC) $(CFLAGS) $(LIB_INCLUDE) -c -o $(BUILD_PATH)/$@ $<
     118build/libs/utils.o: libs/utils.c
     119        $(CC) $(CFLAGS) $(INCLUDE)  -c -o $@ $<
    115120
    116 ### applications
    117 apps: $(LIB_OBJS)
    118         @echo "---------------------------------------------- BUILDING APPS ---------------------------------------------------------"
    119         set -e; for d in $(APP_DIRS); do $(MAKE) -f config.mk -C $$d ; echo "Compiling $$d";  done
     121build/libs/stdio.o: libs/stdio.c
     122        $(CC) $(CFLAGS) $(INCLUDE)  -c -o $@ $<
     123
     124build/libs/mwmr_channel.o: libs/mwmr_channel.c
     125        $(CC) $(CFLAGS) $(INCLUDE)  -c -o $@ $<
     126
    120127
    121128### clean
    122129clean:
    123         rm -f *.o *.elf *.bin *.txt core *~     2>$(TRASH)
    124         $(MAKE) -s clean -C $(XML_PATH)                 2>$(TRASH)
    125         $(MAKE) -s clean -C $(MEMO_PATH)                2>$(TRASH)
    126         rm -r $(BUILD_PATH)                                     2>$(TRASH)
    127         rm -r $(ELF_PATH)                                               2>$(TRASH)
    128         set -e; for d in $(APP_DIRS); do $(MAKE) clean -f config.mk -C $$d ; done
     130        rm -f *.o *.elf *.bin *.txt core *~     2>$(TRASH)
     131        $(MAKE) -s clean -C $(XML_PATH) 2>$(TRASH)
     132        $(MAKE) -s clean -C $(MEMO_PATH) 2>$(TRASH)
     133        rm -r build/boot/* 2>$(TRASH)
     134        rm -r build/sys/* 2>$(TRASH)
     135        rm -r build/libs/* 2>$(TRASH)
     136        rm -r build/pgcd/* 2>$(TRASH)
     137        rm -r build/hello/* 2>$(TRASH)
     138        rm -r build/display/* 2>$(TRASH)
     139        rm -r build/router/* 2>$(TRASH)
  • soft/giet_vm/boot/boot.ld

    r167 r189  
    33*****************************************************************************/
    44
    5 /* The vsegs used in the boot phase must respect identity mapping:
    6    physical address = virtual address */
     5/*
     6The following (virtual) addresses are specific for the boot phase.
     7They must respect identity mapping: physical address = virtual address
     8*/
    79
    810seg_boot_base           = 0xBFC00000;   /* boot code */
     
    1214seg_mapping_base        = 0xBFC0C000;   /* boot mapping_info */
    1315
     16/*
     17The following (virtual) addresse are defined and used by the kernel.
     18They are not constrained to respect identity mapping. 
     19*/
     20
    1421seg_kernel_init_base    = 0x80090000;   /* system init entry */
    1522
    16 seg_tty_base            = 0x90000000;   /* TTY device: for debug purpose! */
     23seg_tty_base                = 0x90000000;   /* TTY device */
     24seg_timer_base              = 0x91000000;   /* Timer device */
     25seg_ioc_base                = 0x92000000;   /* Block device */
     26seg_dma_base                = 0x93000000;   /* DMA device */
     27seg_gcd_base                = 0x95000000;   /* GCD device */
     28seg_fb_base                 = 0x96000000;   /* FrameBuffer device */
     29seg_iob_base                = 0x9E000000;   /* IO Bridge device */
     30seg_icu_base                = 0x9F000000;   /* ICU or XICU device */
    1731
    1832/*
    19  * Grouping sections into segments for boot code and data
    20  */
     33Grouping sections into segments for boot code and data
     34*/
    2135
    2236SECTIONS
    2337{
    24     /** contain both data and code sections */
     38    /* contain both data and code sections */
    2539    . = seg_boot_base;
    2640    seg_boot :
  • soft/giet_vm/boot/reset.S

    r173 r189  
    77/* running one or several multi-tasks software application(s) defined in        */
    88/* the mapping_info data-structure.                                                                     */
    9 /* Procesor 0 uses the mapping_info data structure to build all page tables     */
    10 /* before jumping to the kernel_init code.                                                                              */
     9/* Procesor 0 uses the mapping_info data structure to statically initialize             */
     10/* the kernel structures:                                                                                                               */
     11/* - build page tables for all vspaces                                                                                  */
     12/* - initializes the vobjs not initialized by GCC                                                               */
     13/* - initialize the schedulers and task contexts for all processeurs                    */
     14/* - initialize the peripherals                                                                                                 */                             
    1115/* Other processors are waiting until the mapping_info signature has been       */
    12 /* modified by processor 0 (done while executing kernel_init code).             */
     16/* modified by processor 0.                                                                                                             */
     17/*                                                                                                                                                              */
    1318/* Implementation note:                                                                                                                 */
    1419/* The entry point is 0xbfc00000, but the actual boot code starts at address    */
     
    4348        .align  2
    4449    .org        EXCEP_ORG
     50
    4551boot_excep:
    46     la  a0,     boot_error_string
    47     jal boot_puts
     52
     53    # get the lock protecting TTY0
     54    la          k0, boot_tty0_lock
     55    ll          k1, 0(k0)
     56    bnez        k1, boot_excep
     57    li          k1, 1
     58    sc      k1, 0(k0)
     59    beqz        k1, boot_excep
     60    nop
     61
     62    # display error messages on TTY0 
     63    la          a0,     boot_error_string
     64    jal         boot_puts
    4865    nop
    4966    mfc0        a0,     CP0_TIME
    50         jal     boot_putw
     67        jal             boot_putw
    5168        nop
    52     la  a0,     boot_lf_string
    53     jal boot_puts
    54     nop
    55 
    56         la      a0,     boot_pid_string
    57     jal boot_puts
     69    la          a0,     boot_lf_string
     70    jal         boot_puts
     71    nop
     72
     73        la              a0,     boot_pid_string
     74    jal         boot_puts
    5875    nop
    5976    mfc0        k0,     CP0_PROCID
    6077    andi        a0,     k0,     0xFFF
    61         jal     boot_putw
    62     nop
    63     la  a0,     boot_lf_string
    64     jal boot_puts
    65     nop
    66 
    67         la      a0,     boot_epc_string
    68     jal boot_puts
     78        jal             boot_putw
     79    nop
     80    la          a0,     boot_lf_string
     81    jal         boot_puts
     82    nop
     83
     84        la              a0,     boot_epc_string
     85    jal         boot_puts
    6986    nop
    7087    mfc0        a0,     CP0_EPC
    71         jal     boot_putw
    72     nop
    73     la  a0,     boot_lf_string
    74     jal boot_puts
    75     nop
    76 
    77         la      a0,     boot_cr_string
    78     jal boot_puts
     88        jal             boot_putw
     89    nop
     90    la          a0,     boot_lf_string
     91    jal         boot_puts
     92    nop
     93
     94        la              a0,     boot_cr_string
     95    jal         boot_puts
    7996    nop
    8097    mfc0        a0,     CP0_CR
    81         jal     boot_putw
    82     nop
    83     la  a0,     boot_lf_string
    84     jal boot_puts
    85     nop
    86 
    87         la      a0,     boot_sr_string
    88     jal boot_puts
     98        jal             boot_putw
     99    nop
     100    la          a0,     boot_lf_string
     101    jal         boot_puts
     102    nop
     103
     104        la              a0,     boot_sr_string
     105    jal         boot_puts
    89106    nop
    90107    mfc0        a0,     CP0_SR
    91         jal     boot_putw
    92     nop
    93     la  a0,     boot_lf_string
    94     jal boot_puts
    95     nop
    96 
    97         la      a0,     boot_bar_string
    98     jal boot_puts
     108        jal             boot_putw
     109    nop
     110    la          a0,     boot_lf_string
     111    jal         boot_puts
     112    nop
     113
     114        la              a0,     boot_bar_string
     115    jal         boot_puts
    99116    nop
    100117    mfc0        a0,     CP0_BAR
    101         jal     boot_putw
    102     nop
    103     la  a0,     boot_lf_string
    104     jal boot_puts
    105     nop
    106 
     118        jal             boot_putw
     119    nop
     120    la          a0,     boot_lf_string
     121    jal         boot_puts
     122    nop
     123
     124    # release the lock 
     125    la          k0,     boot_tty0_lock
     126    li          k1,     0
     127    sw          k1, 0(k0)
     128
     129    # exit
    107130        j       boot_exit
    108131        nop
     
    115138
    116139boot_start:
    117     /* get the procid */
     140
     141    # get the procid
    118142    mfc0        k0,     CP0_PROCID
    119     andi        k0,     k0,     0xFFF   /* no more than 4096 processors... */
    120 
    121     /* Only processor 0 does init */
    122     bne k0,     zero,   boot_wait_signature
    123     nop
    124 
    125     /* Processor 0 get a temporary stack */
     143    andi        k0,     k0,     0xFFF   # no more than 4096 processors
     144
     145    # Only processor 0 does init
     146    bne         k0,     zero,   boot_wait_signature
     147    nop
     148
     149    # Processor 0 get a temporary stack
    126150    la      sp, seg_boot_stack_base
    127     addiu       sp,     sp,     0x3000                          /* SP <= seg_boot_stack + 12K */
    128 
    129     /* Processor 0 initialises all Page Tables */
    130     jal boot_pt_init
     151    addiu       sp,     sp,     0x3000                          # SP <= seg_boot_stack + 12K
     152
     153    # Processor 0 initialises all kernel structures
     154    jal boot_init
    131155    nop
    132156 
    133     /* jump to kernel_init */
     157    # jump to kernel_init
    134158    j           boot_to_kernel_init
    135159    nop
     
    137161boot_wait_signature:
    138162
    139     /* all other processors are waiting signature change */
    140     la  k0, seg_mapping_base
    141     cache   0x11,   0(k0)                               /* invalidate local cache copy */
    142     lw  k0, 0(k0)                                               /* k0 <= mapping_info[0]       */
    143     li  k1,    OUT_MAPPING_SIGNATURE
    144     bne k1, k0, boot_wait_signature
     163    # all other processors are waiting signature change
     164    la          k0, seg_mapping_base
     165    cache   0x11,   0(k0)                               # invalidate local cache copy
     166    lw          k0, 0(k0)                                       # k0 <= mapping_info[0]       
     167    li          k1, OUT_MAPPING_SIGNATURE
     168    bne         k1, k0, boot_wait_signature
    145169    nop
    146170       
    147     /* all other processors get a temporary stack of 256 bytes */
     171    # all other processors initialise SP register: temporary stack of 256 bytes
    148172    la      sp, seg_boot_stack_base
    149173    addiu   sp, sp, 0x3100                             
     
    151175    andi    k0, k0, 0xFFF
    152176    sll     k0, k0, 8                                   
    153     addu    sp, sp, k0          /* SP <= seg_boot_stack_base + 12K + (pid+1)*256 */
     177    addu    sp, sp, k0          # SP <= seg_boot_stack_base + 12K + (pid+1)*256
    154178
    155179boot_to_kernel_init:
    156180
    157     /* all processors initialize PTPR with PTAB[0] */
    158     la      k1, _ptabs
     181    # all processors initialise SCHED register with boot_schedulers_paddr[pid]
     182    mfc0        k0, CP0_PROCID
     183    andi    k0, k0, 0xFFF
     184    sll         k0, k0, 2               # k0 <= 4*pid
     185    la          k1, boot_schedulers_paddr
     186    addu    k1, k1, k0          # k1 <= &boot_scheduler_paddr[pid]
     187    lw          k1,     0(k1)           
     188    mtc0        k1, CP0_SCHED
     189
     190    # all processors initialize PTPR register with boot_ptabs_paddr[0]
     191    la      k1, boot_ptabs_paddr
    159192    lw      k1, 0(k1)   
    160193    srl     k1, k1, 13
    161     mtc2        k1,     CP2_PTPR                /* PTPR <= _ptabs[0]  */
    162 
    163         /* all processors activate MMU */
     194    mtc2        k1,     CP2_PTPR       
     195
     196        # all processors activate MMU
    164197    li      k1, 0xF
    165     mtc2    k1, CP2_MODE        /* MODE register */
    166 
    167     /* jump to kernel_init */
     198    mtc2    k1, CP2_MODE
     199
     200    # all processors jump to kernel_init
    168201    la      k0, seg_kernel_init_base
    169202    j       k0
    170203    nop
    171204
    172 boot_error_string:      .asciiz "\n[BOOT] Fatal Error in reset.S at cycle "
     205boot_error_string:      .asciiz "\n[BOOT] Fatal Error at cycle "
    173206boot_pid_string:        .asciiz "    PID  = "
    174207boot_sr_string:         .asciiz "    SR   = "
     
    178211boot_lf_string:         .asciiz "\n"
    179212
    180 .set    reorder
    181 
    182 
     213boot_tty0_lock:         .word   0
     214
     215        .set    reorder
     216
     217
  • soft/giet_vm/giet_config.h

    r180 r189  
    1212/* Debug parameters */
    1313
    14 #define BOOT_DEBUG_VIEW         0           /* display the mapping_info on system TTY */
    15 #define BOOT_DEBUG_PT           0           /* display the page tables after mapping */
    16 #define INIT_DEBUG_CTX          0           /* display the task contexts after mapping */
    17 #define GIET_DEBUG_SWITCH       0           /* Trace context switchs */
     14#define BOOT_DEBUG_PT           0           /* display page tables initialisation on TTY0 */
     15#define BOOT_DEBUG_VOBJS        0               /* display vobjs initialisation on TTY0 */
     16#define BOOT_DEBUG_SCHED        0               /* display schedulers initialisation on TTY0 */
     17#define BOOT_DEBUG_PERI     0       /* display peripherals initialisation on TTY0 */
     18
     19#define GIET_DEBUG_INIT         0               /* display parallel kernel initialisation on TTY0 */
     20#define GIET_DEBUG_SWITCH       0           /* display context switchs on TTY0 */
    1821
    1922
     
    2427#define NB_CLUSTERS             1           /* number of clusters */
    2528#define CLUSTER_SPAN            0           /* address increment between clusters */
    26 #define NB_PROCS                    4       /* max number of processors per cluster */
    27 #define NB_TIMERS                   4       /* number of timers per cluster */
    28 #define NB_DMAS                     1       /* total number of DMA channels */
    29 #define NB_TTYS                     8       /* total number of TTY terminals */
    30 #define NB_IOC                      1       /* total number of IOC channels */
     29#define NB_PROCS_MAX        4       /* max number of processors per cluster */
     30#define NB_TIMERS_MAX           0           /* max number of user timers per cluster */
     31#define NB_DMAS_MAX                     1           /* max number of DMA channels per cluster*/
     32#define NB_TTYS                         8           /* total number of TTY channels */
     33#define NB_IOCS                         1           /* total number of IOC channels */
     34#define NB_NICS                         1           /* total number of NIC channels */
    3135
    3236/* software parameters */
    3337
    34 #define GIET_NB_TASKS_MAX       4           /* max number of tasks per processor */
    3538#define GIET_NB_VSPACE_MAX      4           /* max number of virtual spaces */
    36 #define GIET_TICK_VALUE     16384   /* context switch period (number of cycles) */
     39#define GIET_TICK_VALUE     0x4000  /* context switch period (number of cycles) */
    3740#define GIET_IOMMU_ACTIVE   0           /* The IOMMU vspace is defined */
     41#define GIET_USE_XICU       0           /* Use the XICU interrupt controler */
    3842
    3943#endif
  • soft/giet_vm/libs/mwmr_channel.c

    r178 r189  
    3333#include <mwmr_channel.h>
    3434#include <stdio.h>
    35 #include <common.h>
    3635
    3736//////////////////////////////////////////////////////////////////////////////
     
    7473// after a random delay.
    7574//////////////////////////////////////////////////////////////////////////////
    76 void mwmr_write( mwmr_channel_t*            mwmr,
    77                  const unsigned int*    buffer,
    78                  unsigned int               nitems )
     75void mwmr_write( mwmr_channel_t*        mwmr,
     76                 unsigned int*          buffer,
     77                 unsigned int           nitems )
    7978{
    8079    unsigned int        x;
     
    8685    unsigned int    ptw;        // channel ptw
    8786
    88     if(nitems == 0)
    89         return;
    90 
    91     assert(buffer && "mwmr write: Empty buffer");
     87    if(nitems == 0) return;
     88
     89    // address virtuelle 0 is illegal...
     90    assert(buffer && "mwmr read: Empty buffer");
    9291
    9392    while(1)
     
    163162    unsigned int    ptr;        // channel ptw
    164163
    165     if(nitems == 0)
    166         return;
    167 
     164    if(nitems == 0) return;
     165
     166    // address virtuelle 0 is illegal...
    168167    assert(buffer && "mwmr read: Empty buffer");
    169168
  • soft/giet_vm/libs/mwmr_channel.h

    r179 r189  
    2020    unsigned int        sts;                    // number of words available
    2121    unsigned int        depth;                  // max number of words in the channel
    22     unsigned int        width;                  // number of word in an item   
     22    unsigned int        width;                  // number of words in an item   
    2323    unsigned int        lock;                   // exclusive access lock
    24     unsigned int        data[1];                // circular buffer
     24    unsigned int        data[1018];             // circular buffer
    2525} mwmr_channel_t;
    2626
     
    2929//////////////////////////////////////////////////////////////////////////////
    3030
    31 void mwmr_write( mwmr_channel_t*            mwmr,
    32                  const unsigned int*    buffer,
    33                  unsigned int               nitems );
     31void mwmr_write( mwmr_channel_t*        mwmr,
     32                 unsigned int*          buffer,
     33                 unsigned int           nitems );
    3434
    3535void mwmr_read( mwmr_channel_t*         mwmr,
  • soft/giet_vm/libs/spin_lock.c

    r178 r189  
    1010// It is a simple binary lock, without waiting queue.
    1111//
    12 // The lock_acquire(), lock_try_acquire() and lock_release() functions do
    13 // not require a system call.
     12// The lock_acquire() and lock_release() functions do not require a system call.
     13// The barrier itself must have been allocated in a non cacheable segment,
     14// if the platform does not provide hardwate cache coherence.
    1415//
    1516// ALL locks must be defined in the mapping_info data structure,
    1617// to be initialised by the GIET in the boot phase.
    1718// The vobj_get_vbase() system call (defined in stdio.c and stdio.h files)
    18 // can be used to get the virtual base address of the lock from it's name.
     19// can be used to get the virtual base address of the lock fro it's name.
    1920///////////////////////////////////////////////////////////////////////////////////
    2021
     
    6465}
    6566
    66 //////////////////////////////////////////////////////////////////////////////
    67 // lock_try_acquire()
    68 //////////////////////////////////////////////////////////////////////////////
    69 int lock_try_acquire( giet_lock_t* lock )
    70 {
    71         register int ret = 0;   
    72     register unsigned int*      plock = &lock->value;
    73 
    74         asm volatile ("ll   $2,    0(%1)                    \n" // $2 <= _locks_lock
    75                   "bnez $2,    _lock_done           \n" // exitif busy
    76                   "li   $3,    1                            \n" // prepare argument for sc 
    77                   "sc   $3,    0(%1)                \n" // try to set _locks_busy
    78                   "xori %0, $3, 1                   \n" // ret = !$3
    79                   "_lock_done:                          \n"
    80                   :"=r"(ret)
    81                   :"r"(plock)
    82                   :"$2","$3");
    83     return ret;
    84 }
  • soft/giet_vm/libs/spin_lock.h

    r178 r189  
    2727void lock_release( giet_lock_t* lock );
    2828
    29 // return 0 if success
    30 int lock_try_acquire( giet_lock_t* lock );
    31 
    3229#endif
    3330
  • soft/giet_vm/libs/srl.h

    r178 r189  
    1919#include "libsrl/srl_hw_helpers.h"
    2020
    21 #include "libsrl/srl_args.h"
    22 
    2321//kernel use!
    2422//#include "libsrl/srl_mwmr_sys.h"
    2523
     24/* port, APP_NAME, TASK */
     25# define GET_MWMR(port)                                                                       \
     26({                                                                                            \
     27    srl_mwmr_t  _mwmr;                                                                      \
     28    if( vobj_get_vbase( APP_NAME , #port, MWMR, (unsigned int*)&_mwmr ) )                   \
     29    {                                                                                         \
     30        srl_log_printf( NONE, "\n[ERROR] in "TASK" task :\n");                              \
     31        srl_log_printf( NONE, "          undefined <"#port"> channel: %d\n", _mwmr);           \
     32        srl_log_printf( TRACE, "*** &"#port" = %x\n\n", (unsigned int)_mwmr );                 \
     33        exit();/*srl?*/                                                                     \
     34    }else                                                                                         \
     35        srl_log_printf( TRACE, "%s:%d: arg of %s for %s,from %s; &"#port" = %x\n\n", __FILE__, __LINE__, APP_NAME, TASK,#port, (unsigned int)_mwmr ); \
     36    _mwmr;\
     37})
    2638
    2739#endif
  • soft/giet_vm/libs/stdio.h

    r178 r189  
    88#ifndef _STDIO_H
    99#define _STDIO_H
    10 
    11 #include <mapping_info.h>
    12 #include <common.h>
    1310
    1411/* MIPS32 related functions */
     
    6461void         giet_exit();
    6562unsigned int giet_rand();
    66 unsigned int ctx_switch();
     63unsigned int giet_ctx_switch();
    6764unsigned int giet_procnumber();
    6865
     66#endif
    6967
    70 #endif
  • soft/giet_vm/map.xml

    r185 r189  
    22
    33<mapping_info   signature = "0xdeadbeef"
    4                 name     = "c1_v2_G12"
     4                name     = "1C_4P_FOUR"
    55                clusters = "1"
    6                 ttys     = "8"
    7                 fbs      = "1"
    86                vspaces  = "4"
    97                globals  = "13" >
     
    119        <clusterset>
    1210                <cluster index  = "0" >
    13                         <pseg    name   = "PSEG_ROM"
    14                                  type   = "ROM"
    15                                  base   = "0xbfc00000"
    16                                  length = "0x00010000" />
    17 
    18                         <pseg    name   = "PSEG_RAU"
    19                                  type   = "RAM"
    20                                  base   = "0x00000000"
    21                                  length = "0x01000000" />
    22 
    23                         <pseg    name   = "PSEG_RAK"
    24                                  type   = "RAM"
    25                                  base   = "0x80000000"
    26                                  length = "0x00100000" />
    27 
    28                         <pseg    name   = "PSEG_TTY"
    29                                  type   = "PERI"
    30                                  base   = "0x90000000"
    31                                  length = "0x00001000" />
    32 
    33                         <pseg    name   = "PSEG_TIM"
    34                                  type   = "PERI"
    35                                  base   = "0x91000000"
    36                                  length = "0x00001000" />
    37 
    38                         <pseg    name   = "PSEG_IOC"
    39                                  type   = "PERI"
    40                                  base   = "0x92000000"
    41                                  length = "0x00001000" />
    42 
    43                         <pseg    name   = "PSEG_DMA"
    44                                  type   = "PERI"
    45                                  base   = "0x93000000"
    46                                  length = "0x00001000" />
    47 
    48                         <pseg    name   = "PSEG_FBF"
    49                                  type   = "PERI"
    50                                  base   = "0x96000000"
    51                                  length = "0x00004000" />
    52 
    53                         <pseg    name   = "PSEG_ICU"
    54                                  type   = "PERI"
    55                                  base   = "0x9F000000"
    56                                  length = "0x00001000" />
     11                         <pseg    name   = "PSEG_ROM"
     12                                  type   = "ROM"
     13                                  base   = "0xbfc00000"
     14                                  length = "0x00010000" />
     15
     16                         <pseg    name   = "PSEG_RAM"
     17                                  type   = "RAM"
     18                                  base   = "0x01000000"
     19                                  length = "0x01000000" />
     20
     21                         <pseg    name   = "PSEG_TTY"
     22                                  type   = "PERI"
     23                                  base   = "0x90000000"
     24                                  length = "0x00001000" />
     25
     26                         <pseg    name   = "PSEG_TIM"
     27                                  type   = "PERI"
     28                                  base   = "0x90100000"
     29                                  length = "0x00001000" />
     30
     31                         <pseg    name   = "PSEG_IOC"
     32                                  type   = "PERI"
     33                                  base   = "0x90200000"
     34                                  length = "0x00001000" />
     35
     36                         <pseg    name   = "PSEG_DMA"
     37                                  type   = "PERI"
     38                                  base   = "0x90300000"
     39                                  length = "0x00001000" />
     40
     41                         <pseg    name   = "PSEG_FBF"
     42                                  type   = "PERI"
     43                                  base   = "0x90600000"
     44                                  length = "0x00004000" />
     45
     46                         <pseg    name   = "PSEG_ICU"
     47                                  type   = "PERI"
     48                                  base   = "0x90700000"
     49                                  length = "0x00001000" />
     50
     51                         <pseg    name   = "PSEG_COP"
     52                                  type   = "PERI"
     53                                  base   = "0x90800000"
     54                                  length = "0x00001000" />
     55
    5756                         <proc    index  = "0" >
     57                                  <irq   type    = "HARD"
     58                                         icuid   = "0"
     59                                         isr     = "ISR_SWITCH" />
     60
     61                                  <irq   type    = "HARD"
     62                                         icuid   = "8"
     63                                         isr     = "ISR_DMA"
     64                                         channel = "0" />
     65
     66                                  <irq   type    = "HARD"
     67                                         icuid   = "9"
     68                                         isr     = "ISR_DMA"
     69                                         channel = "1" />
     70
     71                                  <irq   type    = "HARD"
     72                                         icuid   = "10"
     73                                         isr     = "ISR_DMA"
     74                                         channel = "2" />
     75
     76                                  <irq   type    = "HARD"
     77                                         icuid   = "11"
     78                                         isr     = "ISR_DMA"
     79                                         channel = "3" />
     80
     81                                  <irq   type    = "HARD"
     82                                         icuid   = "12"
     83                                         isr     = "ISR_DMA"
     84                                         channel = "4" />
     85
     86                                  <irq   type    = "HARD"
     87                                         icuid   = "13"
     88                                         isr     = "ISR_DMA"
     89                                         channel = "5" />
     90
     91                                  <irq   type    = "HARD"
     92                                         icuid   = "14"
     93                                         isr     = "ISR_DMA"
     94                                         channel = "6" />
     95
     96                                  <irq   type    = "HARD"
     97                                         icuid   = "15"
     98                                         isr     = "ISR_DMA"
     99                                         channel = "7" />
     100
     101                                  <irq   type    = "HARD"
     102                                         icuid   = "16"
     103                                         isr     = "ISR_TTY"
     104                                         channel = "0" />
     105
     106                                  <irq   type    = "HARD"
     107                                         icuid   = "17"
     108                                         isr     = "ISR_TTY"
     109                                         channel = "1" />
     110
     111                                  <irq   type    = "HARD"
     112                                         icuid   = "18"
     113                                         isr     = "ISR_TTY"
     114                                         channel = "2" />
     115
     116                                  <irq   type    = "HARD"
     117                                         icuid   = "19"
     118                                         isr     = "ISR_TTY"
     119                                         channel = "3" />
     120
     121                                  <irq   type    = "HARD"
     122                                         icuid   = "20"
     123                                         isr     = "ISR_TTY"
     124                                         channel = "4" />
     125
     126                                  <irq   type    = "HARD"
     127                                         icuid   = "21"
     128                                         isr     = "ISR_TTY"
     129                                         channel = "5" />
     130
     131                                  <irq   type    = "HARD"
     132                                         icuid   = "22"
     133                                         isr     = "ISR_TTY"
     134                                         channel = "6" />
     135
     136                                  <irq   type    = "HARD"
     137                                         icuid   = "23"
     138                                         isr     = "ISR_TTY"
     139                                         channel = "7" />
     140
     141                                  <irq   type    = "HARD"
     142                                         icuid   = "24"
     143                                         isr     = "ISR_TTY"
     144                                         channel = "8" />
     145
     146                                  <irq   type    = "HARD"
     147                                         icuid   = "25"
     148                                         isr     = "ISR_TTY"
     149                                         channel = "9" />
     150
     151                                  <irq   type    = "HARD"
     152                                         icuid   = "26"
     153                                         isr     = "ISR_TTY"
     154                                         channel = "10" />
     155
     156                                  <irq   type    = "HARD"
     157                                         icuid   = "27"
     158                                         isr     = "ISR_TTY"
     159                                         channel = "11" />
     160
     161                                  <irq   type    = "HARD"
     162                                         icuid   = "28"
     163                                         isr     = "ISR_TTY"
     164                                         channel = "12" />
     165
     166                                  <irq   type    = "HARD"
     167                                         icuid   = "29"
     168                                         isr     = "ISR_TTY"
     169                                         channel = "13" />
     170
     171                                  <irq   type    = "HARD"
     172                                         icuid   = "30"
     173                                         isr     = "ISR_TTY"
     174                                         channel = "14" />
     175
     176                                  <irq   type    = "HARD"
     177                                         icuid   = "31"
     178                                         isr     = "ISR_IOC" />
    58179                         </proc>
     180
    59181                         <proc    index  = "1" >
     182                                  <irq   type    = "HARD"
     183                                         icuid   = "1"
     184                                         isr     = "ISR_SWITCH" />
    60185                         </proc>
     186
    61187                         <proc    index  = "2" >
     188                                  <irq   type    = "HARD"
     189                                         icuid   = "2"
     190                                         isr     = "ISR_SWITCH" />
    62191                         </proc>
     192
    63193                         <proc    index  = "3" >
     194                                  <irq   type    = "HARD"
     195                                         icuid   = "3"
     196                                         isr     = "ISR_SWITCH" />
    64197                         </proc>
     198
     199                         <periph  type      = "IOC"
     200                                  psegname  = "PSEG_IOC"
     201                                  channels  = "1" />
     202
     203                         <periph  type      = "TTY"
     204                                  psegname  = "PSEG_TTY"
     205                                  channels  = "2" />
     206   
     207                         <periph  type      = "DMA"
     208                                  psegname  = "PSEG_DMA"
     209                                  channels  = "1" />
     210   
     211                         <periph  type      = "TIM"
     212                                  psegname  = "PSEG_TIM"
     213                                  channels  = "8" />
     214
     215                         <periph  type      = "FBF"
     216                                  psegname  = "PSEG_FBF" />
     217
     218                         <coproc  name     = "COP0"
     219                                  psegname = "PSEG_COP" >
     220
     221                                  <port    direction  = "TO_COPROC"
     222                                           vspacename = "router"
     223                                           vobjname   = "mwmr_in" />
     224
     225                                  <port    direction  = "FROM_COPROC"
     226                                           vspacename = "router"
     227                                           vobjname   = "mwmr_out" />
     228                         </coproc>
    65229                </cluster>
    66230        </clusterset>
     
    69233                <vseg   name      = "seg_boot_code_data"
    70234                        vbase     = "0xbfc00000"
    71                         mode      = "CX__"
    72                                                 clusterid = "0"
     235                        mode      = "CXW_"
     236                        clusterid = "0"
    73237                        psegname  = "PSEG_ROM"
    74238                        ident     = "1" >
     
    76240                                                        type    = "ELF"
    77241                                                        length  = "0x00008000"
    78                                                         binpath = "build/boot.elf" />
     242                                                        binpath = "build/boot/boot.elf" />
    79243                                </vseg>
    80244
     
    82246                        vbase     = "0xbfc08000"
    83247                        mode      = "C_W_"
    84                                                 clusterid = "0"
     248                        clusterid = "0"
    85249                        psegname  = "PSEG_ROM"
    86250                        ident     = "1" >
     
    93257                        vbase     = "0xbfc0c000"
    94258                        mode      = "C_W_"
    95                                                 clusterid = "0"
     259                        clusterid = "0"
    96260                        psegname  = "PSEG_ROM"
    97261                        ident     = "1" >
     
    105269                        vbase     = "0x80000000"
    106270                        mode      = "CX__"
    107                                                 clusterid = "0"
    108                         psegname  = "PSEG_RAU"
    109                         ident     = "0" >
    110                                         <vobj   name    = "seg_kernel_code"
    111                                                         type    = "ELF"
    112                                                         length  = "0x00010000"
    113                                                         binpath = "build/sys.elf"
    114                                                         />
     271                        clusterid = "0"
     272                        psegname  = "PSEG_RAM" >
     273                                            <vobj   name        = "seg_kernel_code"
     274                                                        type    = "ELF"
     275                                                            length  = "0x00010000"
     276                                                            binpath     = "build/sys/sys.elf" />
    115277                                </vseg>
    116278
     
    118280                        vbase     = "0x80010000"
    119281                        mode      = "C_W_"
    120                                                 clusterid = "0"
    121                         psegname  = "PSEG_RAU"
    122                         ident     = "O" >
     282                        clusterid = "0"
     283                        psegname  = "PSEG_RAM" >
    123284                                        <vobj   name    = "seg_kernel_data"
    124285                                                        type    = "ELF"
    125286                                                        length  = "0x00040000"
    126                                                         binpath = "build/sys.elf" />
     287                                                        binpath = "build/sys/sys.elf" />
    127288                                </vseg>
    128289
     
    130291                        vbase     = "0x80080000"
    131292                        mode      = "__W_"
    132                                                 clusterid = "0"
    133                         psegname  = "PSEG_RAU"
    134                         ident     = "0" >
     293                        clusterid = "0"
     294                        psegname  = "PSEG_RAM" >
    135295                                            <vobj   name        = "seg_kernel_uncdata"
    136296                                                        type    = "ELF"
    137297                                                            length  = "0x00010000"
    138                                                         binpath = "build/sys.elf" />
     298                                                        binpath = "build/sys/sys.elf" />
    139299                                </vseg>
    140300
     
    142302                        vbase     = "0x80090000"
    143303                        mode      = "CX__"
    144                                                 clusterid = "0"
    145                         psegname  = "PSEG_RAU"
    146                         ident     = "0" >
     304                        clusterid = "0"
     305                        psegname  = "PSEG_RAM" >
    147306                                        <vobj   name    = "seg_kernel_init"
    148307                                                        type    = "ELF"
    149308                                                        length  = "0x00010000"
    150                                                         binpath = "build/sys.elf" />
     309                                                        binpath = "build/sys/sys.elf" />
    151310                                </vseg>
    152311
     
    155314                        vbase     = "0x90000000"
    156315                        mode      = "__W_"
    157                                                 clusterid = "0"
    158                         psegname  = "PSEG_TTY"
    159                         ident     = "1" >
     316                        clusterid = "0"
     317                        psegname  = "PSEG_TTY" >
    160318                                        <vobj   name    = "tty"
    161319                                                        type    = "PERI"
     
    166324                        vbase     = "0x91000000"
    167325                        mode      = "__W_"
    168                                                 clusterid = "0"
    169                         psegname  = "PSEG_TIM"
    170                         ident     = "1" >
     326                        clusterid = "0"
     327                        psegname  = "PSEG_TIM" >
    171328                                        <vobj   name    = "timer"
    172329                                                        type    = "PERI"
     
    177334                        vbase     = "0x92000000"
    178335                        mode      = "__W_"
    179                                                 clusterid = "0"
    180                         psegname  = "PSEG_IOC"
    181                         ident     = "1" >
     336                        clusterid = "0"
     337                        psegname  = "PSEG_IOC" >
    182338                                        <vobj   name    = "ioc"
    183339                                                        type    = "PERI"
     
    188344                        vbase     = "0x93000000"
    189345                        mode      = "__W_"
    190                                                 clusterid = "0"
    191                         psegname  = "PSEG_DMA"
    192                         ident     = "1" >
     346                        clusterid = "0"
     347                        psegname  = "PSEG_DMA" >
    193348                                        <vobj   name    = "dma"
    194349                                                        type    = "PERI"
     
    199354                        vbase     = "0x96000000"
    200355                        mode      = "__W_"
    201                                                 clusterid = "0"
    202                         psegname  = "PSEG_FBF"
    203                         ident     = "1" >
     356                        clusterid = "0"
     357                        psegname  = "PSEG_FBF" >
    204358                                        <vobj   name    = "fb"
    205359                                                        type    = "PERI"
     
    210364                        vbase     = "0x9F000000"
    211365                        mode      = "__W_"
    212                                                 clusterid = "0"
    213                         psegname  = "PSEG_ICU"
    214                         ident     = "1" >
     366                        clusterid = "0"
     367                        psegname  = "PSEG_ICU" >
    215368                                        <vobj   name    = "icu"
    216369                                                        type    = "PERI"
     
    226379                                vbase     = "0x00800000"
    227380                                mode      = "__WU"
    228                                                                 clusterid = "0"
    229                                 psegname  = "PSEG_RAU" >
     381                                clusterid = "0"
     382                                psegname  = "PSEG_RAM" >
    230383                                                            <vobj   name        = "seg_data_router"
    231384                                                                        type    = "ELF"
    232385                                                                        length  = "0x00010000"
    233                                         binpath = "build/router.elf" />
     386                                        binpath = "build/router/router.elf" />
    234387                                                </vseg>
    235388
     
    237390                                vbase     = "0x00400000"
    238391                                mode      = "CX_U"
    239                                                                 clusterid = "0"
    240                                 psegname  = "PSEG_RAU" >
     392                                clusterid = "0"
     393                                psegname  = "PSEG_RAM" >
    241394                                                            <vobj   name        = "seg_code_router"
    242395                                                                        type    = "ELF"
    243396                                                                            length  = "0x00010000"
    244                                         binpath = "build/router.elf" />
     397                                        binpath = "build/router/router.elf" />
    245398                                                </vseg>
    246399
     
    248401                                vbase     = "0x00300000"
    249402                                mode      = "C___"
    250                                                                 clusterid = "0"
    251                                 psegname  = "PSEG_RAU" >
     403                                clusterid = "0"
     404                                psegname  = "PSEG_RAM" >
    252405                                <vobj   name    = "ptab_router"
    253406                                        type    = "PTAB"
     
    259412                                                vbase     = "0x00010000"
    260413                                mode      = "C_WU"
    261                                                                 clusterid = "0"
    262                                 psegname  = "PSEG_RAU" >
     414                                clusterid = "0"
     415                                psegname  = "PSEG_RAM" >
    263416                                                            <vobj   name        = "stack_producer"
    264417                                                                        type    = "BUFFER"
     
    269422                                                vbase     = "0x00020000"
    270423                                mode      = "C_WU"
    271                                                                 clusterid = "0"
    272                                 psegname  = "PSEG_RAU" >
     424                                clusterid = "0"
     425                                psegname  = "PSEG_RAM" >
    273426                                                            <vobj   name        = "stack_consumer"
    274427                                                                        type    = "BUFFER"
     
    279432                                                vbase     = "0x00030000"
    280433                                mode      = "C_WU"
    281                                                                 clusterid = "0"
    282                                 psegname  = "PSEG_RAU" >
     434                                clusterid = "0"
     435                                psegname  = "PSEG_RAM" >
    283436                                                            <vobj   name        = "stack_router_A"
    284437                                                                        type    = "BUFFER"
     
    289442                                                vbase     = "0x00040000"
    290443                                mode      = "C_WU"
    291                                                                 clusterid = "0"
    292                                 psegname  = "PSEG_RAU" >
     444                                clusterid = "0"
     445                                psegname  = "PSEG_RAM" >
    293446                                                            <vobj   name        = "stack_router_B"
    294447                                                                        type    = "BUFFER"
     
    299452                                vbase     = "0x00050000"
    300453                                mode      = "__WU"
    301                                                                 clusterid = "0"
    302                                 psegname  = "PSEG_RAU" >
     454                                clusterid = "0"
     455                                psegname  = "PSEG_RAM" >
    303456                                                            <vobj   name        = "mwmr_in"
    304457                                                                        type    = "MWMR"
    305                                                                             length  = "0x00000020" 
    306                                                                             init    = "1" />
     458                                                                            length  = "0x00000020"
     459                                        init    = "1" />
    307460                                                            <vobj   name        = "mwmr_out"
    308461                                                                        type    = "MWMR"
    309                                                                             length  = "0x00000020" 
    310                                                                             init    = "1" />
     462                                                                            length  = "0x00000020"
     463                                        init    = "1" />
    311464                                                </vseg>
    312465
     
    346499                                vbase     = "0x00800000"
    347500                                mode      = "C_WU"
    348                                                                 clusterid = "0"
    349                                 psegname  = "PSEG_RAU" >
     501                                clusterid = "0"
     502                                psegname  = "PSEG_RAM" >
    350503                                                            <vobj   name        = "seg_data_hello"
    351504                                                                        type    = "ELF"
    352505                                                                            length    = "0x00010000"
    353                                         binpath = "build/hello.elf" />
     506                                        binpath = "build/hello/hello.elf" />
    354507                                                </vseg>
    355508
     
    357510                                vbase     = "0x00400000"
    358511                                mode      = "CX_U"
    359                                                                 clusterid = "0"
    360                                 psegname  = "PSEG_RAU" >
     512                                clusterid = "0"
     513                                psegname  = "PSEG_RAM" >
    361514                                                            <vobj   name        = "seg_code_hello"
    362515                                                                        type    = "ELF"
    363516                                                                            length    = "0x00010000"
    364                                         binpath = "build/hello.elf" />
     517                                        binpath = "build/hello/hello.elf" />
    365518                                                </vseg>
    366519
     
    368521                                vbase     = "0x00300000"
    369522                                mode      = "C___"
    370                                                                 clusterid = "0"
    371                                 psegname  = "PSEG_RAU" >
     523                                clusterid = "0"
     524                                psegname  = "PSEG_RAM" >
    372525                                <vobj   name    = "ptab"
    373526                                        type    = "PTAB"
     
    379532                                vbase     = "0x00000000"
    380533                                mode      = "C_WU"
    381                                                                 clusterid = "0"
    382                                 psegname  = "PSEG_RAU" >
     534                                clusterid = "0"
     535                                psegname  = "PSEG_RAM" >
    383536                                                            <vobj   name        = "stack"
    384537                                                                        type    = "BUFFER"
     
    401554                                vbase     = "0x00800000"
    402555                                mode      = "C_WU"
    403                                                                 clusterid = "0"
    404                                 psegname  = "PSEG_RAU" >
     556                                clusterid = "0"
     557                                psegname  = "PSEG_RAM" >
    405558                                                            <vobj   name        = "seg_data_pgcd"
    406559                                                                        type    = "ELF"
    407560                                                                            length  = "0x00010000"
    408                                         binpath = "build/pgcd.elf" />
     561                                        binpath = "build/pgcd/pgcd.elf" />
    409562                                                </vseg>
    410563
     
    412565                                vbase     = "0x00300000"
    413566                                mode      = "C___"
    414                                                                 clusterid = "0"
    415                                 psegname  = "PSEG_RAU" >
     567                                clusterid = "0"
     568                                psegname  = "PSEG_RAM" >
    416569                                <vobj   name    = "ptab"
    417570                                        type    = "PTAB"
     
    423576                                vbase     = "0x00400000"
    424577                                mode      = "CX_U"
    425                                                                 clusterid = "0"
    426                                 psegname  = "PSEG_RAU" >
     578                                clusterid = "0"
     579                                psegname  = "PSEG_RAM" >
    427580                                                            <vobj   name        = "seg_code_pgcd"
    428581                                                                        type    = "ELF"
    429582                                                                            length  = "0x00010000"
    430                                         binpath = "build/pgcd.elf" />
     583                                        binpath = "build/pgcd/pgcd.elf" />
    431584                                                </vseg>
    432585
     
    434587                                vbase     = "0x00000000"
    435588                                mode      = "C_WU"
    436                                                                 clusterid = "0"
    437                                 psegname  = "PSEG_RAU" >
     589                                clusterid = "0"
     590                                psegname  = "PSEG_RAM" >
    438591                                                            <vobj   name        = "stack"
    439592                                                                        type    = "BUFFER"
     
    455608                                vbase     = "0x00800000"
    456609                                mode      = "C_WU"
    457                                                                 clusterid = "0"
    458                                 psegname  = "PSEG_RAU" >
     610                                clusterid = "0"
     611                                psegname  = "PSEG_RAM" >
    459612                                                            <vobj   name        = "seg_data_display"
    460613                                                                        type    = "ELF"
    461614                                                                            length  = "0x00010000"
    462                                         binpath = "build/display.elf" />
     615                                        binpath = "build/display/display.elf" />
    463616                                                </vseg>
    464617
     
    466619                                vbase     = "0x00300000"
    467620                                mode      = "C___"
    468                                                                 clusterid = "0"
    469                                 psegname  = "PSEG_RAU" >
     621                                clusterid = "0"
     622                                psegname  = "PSEG_RAM" >
    470623                                <vobj   name    = "ptab"
    471624                                        type    = "PTAB"
     
    477630                                vbase     = "0x00400000"
    478631                                mode      = "CX_U"
    479                                                                 clusterid = "0"
    480                                 psegname  = "PSEG_RAU" >
     632                                clusterid = "0"
     633                                psegname  = "PSEG_RAM" >
    481634                                                            <vobj   name        = "seg_code_display"
    482635                                                                        type    = "ELF"
    483636                                                                            length  = "0x00010000"
    484                                         binpath = "build/display.elf" />
     637                                        binpath = "build/display/display.elf" />
    485638                                                </vseg>
    486639
     
    488641                                vbase     = "0x00000000"
    489642                                mode      = "C_WU"
    490                                                                 clusterid = "0"
    491                                 psegname  = "PSEG_RAU" >
     643                                clusterid = "0"
     644                                psegname  = "PSEG_RAM" >
    492645                                                            <vobj   name        = "stack_display"
    493646                                                                        type    = "BUFFER"
     
    501654                                startid   = "0"
    502655                                usetty    = "1"
    503                                 usefb     = "1" />
     656                                usefbdma  = "1" />
    504657                </vspace>
    505658
  • soft/giet_vm/sys/common.c

    r166 r189  
    1111#include <sys_handler.h>
    1212#include <common.h>
     13#include <ctx_handler.h>
    1314#include <drivers.h>
    1415#include <stdarg.h>
    1516
    16 ////////////////////////////////////////////////////////////////////////////
    17 // _get_lock()
     17///////////////////////////////////////////////////////////////////////////////////
     18//      Global variables
     19///////////////////////////////////////////////////////////////////////////////////
     20
     21// current context cache TODO
     22
     23// SR save (used by _it_mask() / it_restore()
     24unsigned int    _status_register_save;
     25
     26///////////////////////////////////////////////////////////////////////////////////
     27//        _get_sched()
     28// Access CP0 and returns scheduler physical address.
     29///////////////////////////////////////////////////////////////////////////////////
     30inline unsigned int _get_sched()
     31{
     32    unsigned int ret;
     33    asm volatile (      "mfc0   %0,             $22"
     34                                        : "=r"(ret) );
     35    return ret;
     36}
     37///////////////////////////////////////////////////////////////////////////////////
     38//        _get_ptpr()
     39// Access CP2 and returns PTPR register.
     40///////////////////////////////////////////////////////////////////////////////////
     41inline unsigned int _get_ptpr()
     42{
     43    unsigned int ret;
     44    asm volatile (      "mfc2   %0,             $0"
     45                                        : "=r"(ret) );
     46    return ret;
     47}
     48///////////////////////////////////////////////////////////////////////////////////
     49//        _get_epc()
     50// Access CP0 and returns EPC register.
     51///////////////////////////////////////////////////////////////////////////////////
     52inline unsigned int _get_epc()
     53{
     54    unsigned int ret;
     55    asm volatile (      "mfc0   %0,             $14"
     56                                        : "=r"(ret) );
     57    return ret;
     58}
     59///////////////////////////////////////////////////////////////////////////////////
     60//        _get_bar()
     61// Access CP0 and returns BAR register.
     62///////////////////////////////////////////////////////////////////////////////////
     63inline unsigned int _get_bvar()
     64{
     65    unsigned int ret;
     66    asm volatile (      "mfc0   %0,             $8"
     67                                        : "=r"(ret) );
     68    return ret;
     69}
     70///////////////////////////////////////////////////////////////////////////////////
     71//        _get_cr()
     72// Access CP0 and returns CR register.
     73///////////////////////////////////////////////////////////////////////////////////
     74inline unsigned int _get_cause()
     75{
     76    unsigned int ret;
     77    asm volatile (      "mfc0   %0,             $13"
     78                                        : "=r"(ret) );
     79    return ret;
     80}
     81///////////////////////////////////////////////////////////////////////////////////
     82//        _get_sr()
     83// Access CP0 and returns SR register.
     84///////////////////////////////////////////////////////////////////////////////////
     85inline unsigned int _get_sr()
     86{
     87    unsigned int ret;
     88    asm volatile (      "mfc0   %0,             $12"
     89                                        : "=r"(ret) );
     90    return ret;
     91}
     92///////////////////////////////////////////////////////////////////////////////////
     93//    _it_mask()
     94// Access CP0 and mask IRQs
     95///////////////////////////////////////////////////////////////////////////////////
     96inline void _it_mask()
     97{
     98    unsigned int        sr_value;
     99    asm volatile(       "li             $3,             0xFFFFFFFE      \n"
     100                                        "mfc0   %0,             $12                     \n"
     101                                        "and    $3,             $3, %0          \n"
     102                                        "mtc0   $3,             $12                     \n"
     103                                        : "=r"(sr_value) : : "$3" );
     104    _status_register_save = sr_value;
     105}
     106///////////////////////////////////////////////////////////////////////////////////
     107//    _it_enable()
     108// Access CP0 and enable IRQs
     109///////////////////////////////////////////////////////////////////////////////////
     110inline void _it_restore()
     111{
     112    unsigned int        sr_value = _status_register_save;
     113    asm volatile(       "mtc0  %0,              $12                     \n"
     114                                        : : "r"(sr_value) );
     115}
     116////////////////////////////////////////////////////////////////////////////
     117//    _get_lock()
     118// Takes a lock with an ll/sc atomic access.
     119// A pseudo random delay is introduced before retry in case of miss
     120// (delay average value = 100 cycles)
    18121////////////////////////////////////////////////////////////////////////////
    19122inline void _get_lock( unsigned int* plock )
    20123{
    21     register unsigned int  delay = (_proctime() & 0xF) << 4;
     124    register unsigned int  delay = ( _proctime() ^ _procid()<<4 ) & 0xFF;
    22125
    23126    asm volatile (
     
    49152
    50153////////////////////////////////////////////////////////////////////////////
    51 // _puts()
    52 // used for system code debug / it uses TTY0
     154//    _puts()
     155// display a string on TTY0 / used for system code debugand log
    53156////////////////////////////////////////////////////////////////////////////
    54157void _puts(char *buffer)
     
    64167}
    65168////////////////////////////////////////////////////////////////////////////
    66 // _putw()
    67 // used for system code debug / it uses TTY0
     169//    _putw()
     170// display an int (hexa) on TTY0 / used for system code debug and log
    68171////////////////////////////////////////////////////////////////////////////
    69172void _putw(unsigned int val)
     
    85188}
    86189////////////////////////////////////////////////////////////////////////////
    87 // _strncmp()
     190//    _putd()
     191// display an int (decimal) on TTY0 / used for system code debug and log
     192////////////////////////////////////////////////////////////////////////////
     193void _putd(unsigned int val)
     194{
     195    static const char   DecTab[] = "0123456789";
     196    char                                buf[11];
     197    unsigned int                i;
     198    unsigned int                first;
     199
     200    buf[10] = 0;
     201
     202    for (i = 0; i < 10; i++)
     203    {
     204        if ((val != 0) || (i == 0))
     205        {
     206            buf[9-i] = DecTab[val % 10];
     207            first    = 9-i;
     208        }
     209        else
     210        {
     211            break;
     212        }
     213        val /= 10;
     214    }
     215    _puts( &buf[first] );
     216}
     217////////////////////////////////////////////////////////////////////////////
     218//    _strncmp()
    88219// compare two strings s1 & s2 (no more than n characters)
    89220////////////////////////////////////////////////////////////////////////////
     
    101232}
    102233////////////////////////////////////////////////////////////////////////////
    103 //      _dcache_buf_invalidate()
     234//         _dcache_buf_invalidate()
    104235// Invalidate all data cache lines corresponding to a memory
    105236// buffer (identified by an address and a size).
     
    126257    }
    127258}
    128 ///////////////////////////////////////////////////////////////////////////////////
    129 //      _itoa_dec()
    130 // Convert a 32-bit unsigned integer to a string of ten decimal characters.
    131 ///////////////////////////////////////////////////////////////////////////////////
    132 void _itoa_dec(unsigned int val, char *buf)
    133 {
    134     const static char dectab[] = "0123456789";
    135     unsigned int i;
    136 
    137     for (i = 0; i < 10; i++)
    138     {
    139         if ((val != 0) || (i == 0))
    140             buf[9-i] = dectab[val % 10];
    141         else
    142             buf[9-i] = 0x20;
    143         val /= 10;
    144     }
    145 }
    146 ///////////////////////////////////////////////////////////////////////////////////
    147 //      _itoa_hex()
    148 // Convert a 32-bit unsigned integer to a string of eight hexadecimal characters.
    149 ///////////////////////////////////////////////////////////////////////////////////
    150 void _itoa_hex(unsigned int val, char *buf)
    151 {
    152     const static char hexatab[] = "0123456789ABCD";
    153     unsigned int i;
    154 
    155     for (i = 0; i < 8; i++)
    156     {
    157         buf[7-i] = hexatab[val % 16];
    158         val /= 16;
    159     }
    160 }
    161 ///////////////////////////////////////////////////////////////////////////////////
    162 //      _get_ptpr()
    163 // Access CP2 and returns PTPR register.
    164 ///////////////////////////////////////////////////////////////////////////////////
    165 inline unsigned int _get_ptpr()
    166 {
    167     unsigned int ret;
    168     asm volatile("mfc2 %0, $0" : "=r"(ret));
    169     return ret;
    170 }
    171 ///////////////////////////////////////////////////////////////////////////////////
    172 //      _get_epc()
    173 // Access CP0 and returns EPC register.
    174 ///////////////////////////////////////////////////////////////////////////////////
    175 inline unsigned int _get_epc()
    176 {
    177     unsigned int ret;
    178     asm volatile("mfc0 %0, $14" : "=r"(ret));
    179     return ret;
    180 }
    181 ///////////////////////////////////////////////////////////////////////////////////
    182 //      _get_bar()
    183 // Access CP0 and returns BAR register.
    184 ///////////////////////////////////////////////////////////////////////////////////
    185 inline unsigned int _get_bar()
    186 {
    187     unsigned int ret;
    188     asm volatile("mfc0 %0, $8" : "=r"(ret));
    189     return ret;
    190 }
    191 ///////////////////////////////////////////////////////////////////////////////////
    192 //      _get_cr()
    193 // Access CP0 and returns CR register.
    194 ///////////////////////////////////////////////////////////////////////////////////
    195 inline unsigned int _get_cause()
    196 {
    197     unsigned int ret;
    198     asm volatile("mfc0 %0, $13" : "=r"(ret));
    199     return ret;
    200 }
    201 
    202 ///////////////////////////////////////////////////////////////////////////////////
    203 //      _it_mask()
    204 // Access CP0 and mask IRQs
    205 ///////////////////////////////////////////////////////////////////////////////////
    206 inline void _it_mask()
    207 {
    208     asm volatile(
    209             "lui   $27,      0xFFFF   \n"
    210             "ori   $27, $27, 0xFFFE   \n"
    211             "mfc0  $26, $12           \n"
    212             "and   $26, $26, $27      \n"
    213             "mtc0  $26, $12           \n"
    214             ::: "$26", "$27"
    215             );
    216 }
    217 ///////////////////////////////////////////////////////////////////////////////////
    218 //      _it_enable()
    219 // Access CP0 and enable IRQs
    220 ///////////////////////////////////////////////////////////////////////////////////
    221 inline void _it_enable()
    222 {
    223     asm volatile(
    224             "mfc0  $26, $12      \n"
    225             "ori   $26, $26, 1   \n"
    226             "mtc0  $26, $12      \n"
    227             ::: "$26"
    228             );
     259////////////////////////////////////////////////////////////////////////////
     260//    _physical_read_access()
     261// This function makes a physical read access to a 32 bits word in memory,
     262// after a temporary DTLB desactivation.
     263////////////////////////////////////////////////////////////////////////////
     264unsigned int _physical_read_access(unsigned int* paddr)
     265{
     266    unsigned int value;
     267
     268    asm volatile(   "li     $3,     0xFFFFFFFE          \n"
     269                    "mfc0   $2,     $12                         \n"             /* $2 <= SR        */
     270                    "and    $3,     $3,         $2              \n"
     271                    "mtc0   $3,     $12                         \n"             /* interrupt masked */
     272                    "li         $3,             0xB                             \n"
     273                    "mtc2       $3,             $1                              \n"             /* DTLB off                     */     
     274
     275                    "lw         %0,             0(%1)                   \n"             /* entry <= *pslot      */
     276
     277                    "li         $3,             0xF                             \n"
     278                    "mtc2       $3,             $1                              \n"             /* DTLB on                      */     
     279                    "mtc0       $2,             $12                             \n"             /* restore SR           */
     280                    : "=r"(value)
     281                    : "r"(paddr)
     282                    : "$2", "$3" );
     283    return value;
     284}
     285////////////////////////////////////////////////////////////////////////////
     286//    _physical_write_access()
     287// This function makes a physical write access to a 32 bits word in memory,
     288// after a temporary DTLB desactivation.
     289////////////////////////////////////////////////////////////////////////////
     290void _physical_write_access(unsigned int* paddr, unsigned int value)
     291{
     292    asm volatile(   "li     $3,     0xFFFFFFFE          \n"
     293                    "mfc0   $2,     $12                         \n"             /* $26 <= SR        */
     294                    "and    $3,     $3,         $2              \n"
     295                    "mtc0   $3,     $12                         \n"             /* interrupt masked */
     296                    "li         $3,             0xB                             \n"
     297                    "mtc2       $3,             $1                              \n"             /* DTLB off                     */
     298       
     299                    "sw         %0,             0(%1)                   \n"             /* entry <= *pslot      */
     300
     301                    "li         $3,             0xF                             \n"
     302                    "mtc2       $3,             $1                              \n"             /* DTLB on                      */     
     303                    "mtc0       $2,             $12                             \n"             /* restore SR           */
     304                    :
     305                    : "r"(value), "r"(paddr)
     306                    : "$2", "$3" );
     307}
     308////////////////////////////////////////////////////////////////////////////
     309//    _get_tasks_number()
     310// This function returns the number of tasks allocated to processor.
     311////////////////////////////////////////////////////////////////////////////
     312unsigned int _get_tasks_number()
     313{
     314    static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
     315    return _physical_read_access( &(psched->tasks) );
     316}
     317////////////////////////////////////////////////////////////////////////////
     318//    _get_current_task_id()
     319// This function returns the index of the currently running task.
     320////////////////////////////////////////////////////////////////////////////
     321unsigned int _get_current_task_id()
     322{
     323    static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
     324    return _physical_read_access( &(psched->current) );
     325}
     326///////////////////////////////////////////////////////////////////////////////
     327//    _get_current_context_slot()
     328// This function returns the global TTY index for the currently running task.
     329///////////////////////////////////////////////////////////////////////////////
     330unsigned int _get_current_context_slot(unsigned int slot_id)
     331{
     332    static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
     333    unsigned int                        current = _physical_read_access( &(psched->current) );
     334    return _physical_read_access( &(psched->context[current][slot_id]) );
     335}
     336/////////////////////////////////////////////i//////////////////////////////////
     337//    _get_interrupt_vector_entry()
     338// This function returns the interrupt_vector entry defined by argument index.
     339////////////////////////////////////////////////////////////////////////////////
     340unsigned int _get_interrupt_vector_entry( unsigned int index )
     341{
     342    static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
     343    return _physical_read_access( &(psched->interrupt_vector[index]) );
     344}
     345////////////////////////////////////////////////////////////////////////////
     346//    _set_current_task_id()
     347// This function returns the index of the currently running task.
     348////////////////////////////////////////////////////////////////////////////
     349void _set_current_task_id( unsigned int value )
     350{
     351    static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
     352    _physical_write_access( &(psched->current), value );
    229353}
    230354
     
    283407}
    284408
    285 
  • soft/giet_vm/sys/common.h

    r166 r189  
    3232///////////////////////////////////////////////////////////////////////////////////
    3333
    34 void _puts(char *string);
    35 void _putw(unsigned int val);
     34void                            _puts(char *string);
     35void                            _putw(unsigned int val);
     36void                            _putd(unsigned int val);
    3637
    37 unsigned int _strncmp(const char* s1, const char* s2, unsigned int n);
     38unsigned int            _strncmp(const char* s1, const char* s2, unsigned int n);
    3839
    39 void _dcache_buf_invalidate(const void *buffer, unsigned int size);
     40void                            _dcache_buf_invalidate(const void *buffer, unsigned int size);
    4041
    41 void _itoa_dec(unsigned int val, char* buf);
    42 void _itoa_hex(unsigned int val, char* buf);
     42void                            _itoa_dec(unsigned int val, char* buf);
     43void                            _itoa_hex(unsigned int val, char* buf);
    4344
    44 unsigned int _get_epc();
    45 unsigned int _get_ptpr();
    46 unsigned int _get_bar();
    47 unsigned int _get_cr();
     45void                            _dtlb_off(void);
     46void                            _dtlb_on(void);
    4847
    49 void _get_lock(unsigned int* lock);
    50 void _release_lock(unsigned int* lock);
     48void                            _it_mask(void);
     49void                            _it_enable(void);
     50
     51unsigned int            _get_epc(void);
     52unsigned int            _get_ptpr(void);
     53unsigned int            _get_bvar(void);
     54unsigned int            _get_cr(void);
     55unsigned int            _get_sched(void);
     56
     57unsigned int            _get_current_context_slot(unsigned int index);
     58unsigned int            _get_interrupt_vector_entry(unsigned int index);
     59unsigned int            _get_current_task_id(void);
     60unsigned int            _get_tasks_number(void);
     61
     62void                            _set_current_task_id( unsigned int value);
     63
     64void                            _get_lock(unsigned int* lock);
     65void                            _release_lock(unsigned int* lock);
    5166
    5267mapping_cluster_t*  _get_cluster_base( mapping_header_t* header );
  • soft/giet_vm/sys/ctx_handler.c

    r167 r189  
    1 ///////////////////////////////////////////////////////////////////////////////////
     1///////////////////////////////////////////////////////////////////////////////////////
    22// File     : ctx_handler.c
    33// Date     : 01/04/2012
    44// Authors  : alain greiner & joel porquet
    55// Copyright (c) UPMC-LIP6
    6 ////////////////////////////////////////////////////////////////////////////////////
    7 // The ctx_handler.h and ctx_handler.c files are part of the GIET nano-kernel.
     6///////////////////////////////////////////////////////////////////////////////////////
     7// The ctx_handler.h and ctx_handler.c files are part of the GIET-VM nano-kernel.
    88// This code is used to support context switch when several tasks are executing
    99// in time multiplexing on a single processor.
    1010// The tasks must be statically allocated to a processor in the boot phase, and
    11 // there is one private scheduler per processor:  NB_CLUSTERS * NB_PROCS
    12 // Each sheduler contains up to NB_TASKS_MAX contexts.
    13 ////////////////////////////////////////////////////////////////////////////////////
    14 // A task context is an array of 64 words = 256 bytes.
    15 // It contains copies of processor registers, when the task is not running,
    16 // and some general informations associated to the task.
    17 //
    18 // - It contains GPR[i], generally stored in slot (i). $0, *26 & $27 are not saved.
    19 // - It contains HI & LO registers.
    20 // - It contains CP0 registers: EPC, SR, CR.
    21 // - It contains CP2 registers : PTPR and MODE.
    22 // - It contains the TTY global index, the FBDMA global index, the virtual base
    23 //   address of the page table (PTAB), and the task global index (TASK).
    24 //
    25 // ctx[0]<- SR|ctx[8] <- $8 |ctx[16]<- $16|ctx[24]<- $24|ctx[32]<- EPC |ctx[40]<- TTY
    26 // ctx[1]<- $1|ctx[9] <- $9 |ctx[17]<- $17|ctx[25]<- $25|ctx[33]<- CR  |ctx[41]<- FBDMA
    27 // ctx[2]<- $2|ctx[10]<- $10|ctx[18]<- $18|ctx[26]<- LO |ctx[34]<- *** |ctx[42]<- PTAB
    28 // ctx[3]<- $3|ctx[11]<- $11|ctx[19]<- $19|ctx[27]<- HI |ctx[35]<- PTPR|ctx[43]<- TASK
    29 // ctx[4]<- $4|ctx[12]<- $12|ctx[20]<- $20|ctx[28]<- $28|ctx[36]<- MODE|ctx[44]<- ***
    30 // ctx[5]<- $5|ctx[13]<- $13|ctx[21]<- $21|ctx[29]<- SP |ctx[37]<- *** |ctx[45]<- ***
    31 // ctx[6]<- $6|ctx[14]<- $14|ctx[22]<- $22|ctx[30]<- $30|ctx[38]<- *** |ctx[46]<- ***
    32 // ctx[7]<- $7|ctx[15]<- $15|ctx[23]<- $23|ctx[31]<- RA |ctx[39]<- *** |ctx[47]<- ***
    33 /////////////////////////////////////////////////////////////////////////////////////
     11// there is one private scheduler per processor.
     12// Each sheduler contains up to 15 task contexts.
     13///////////////////////////////////////////////////////////////////////////////////////
    3414
    3515#include <giet_config.h>
     
    4020#include <sys_handler.h>
    4121
    42 extern void _task_switch(unsigned int *, unsigned int *);
    43 
    44 /////////////////////////////////////////////////////////////////////////////////
    45 //      Global variables : array of schedulers (one scheduler per processor)
    46 /////////////////////////////////////////////////////////////////////////////////
    47 
    48 __attribute__((section (".kdata"))) static_scheduler_t _scheduler[NB_CLUSTERS * NB_PROCS];
     22///////////////////////////////////////////////////////////////////////////////////////
     23// A task context is an array of 64 words = 256 bytes.
     24// It contains copies of processor registers (when the task is preempted),
     25// and some general informations associated to the task.
     26//
     27// - It contains GPR[i], generally stored in slot (i). $0, *26 & $27 are not saved.
     28// - It contains HI & LO registers.
     29// - It contains CP0 registers: EPC, SR, CR, SCHED
     30// - It contains CP2 registers : PTPR and MODE.
     31// - It contains TTY global index, the FBDMA global index, the virtual base
     32//   address of the page table (PTAB), and the task global index (TASK).
     33//
     34// ctx[0]<- SR|ctx[8] <- $8 |ctx[16]<- $16|ctx[24]<- $24|ctx[32]<- EPC |ctx[40]<- TTY
     35// ctx[1]<- $1|ctx[9] <- $9 |ctx[17]<- $17|ctx[25]<- $25|ctx[33]<- CR  |ctx[41]<- FBDMA
     36// ctx[2]<- $2|ctx[10]<- $10|ctx[18]<- $18|ctx[26]<- LO |ctx[34]<- *** |ctx[42]<- PTAB
     37// ctx[3]<- $3|ctx[11]<- $11|ctx[19]<- $19|ctx[27]<- HI |ctx[35]<- PTPR|ctx[43]<- TASK
     38// ctx[4]<- $4|ctx[12]<- $12|ctx[20]<- $20|ctx[28]<- $28|ctx[36]<- MODE|ctx[44]<- SCHED
     39// ctx[5]<- $5|ctx[13]<- $13|ctx[21]<- $21|ctx[29]<- SP |ctx[37]<- *** |ctx[45]<- TIMER
     40// ctx[6]<- $6|ctx[14]<- $14|ctx[22]<- $22|ctx[30]<- $30|ctx[38]<- *** |ctx[46]<- ***
     41// ctx[7]<- $7|ctx[15]<- $15|ctx[23]<- $23|ctx[31]<- RA |ctx[39]<- *** |ctx[47]<- ***
     42////////////////////////////////////////////////////////////////////////////////////////
     43
     44extern void _task_switch(unsigned int*, unsigned int*);
    4945
    5046/////////////////////////////////////////////////////////////////////////////////
     
    5248// This function performs a context switch between the running task
    5349// and  another task, using a round-robin sheduling policy.
    54 // It use the global variable scheduler[] : array indexed by the procid,
    55 // that contains NB_CLUSTERS * NB_PROCS entries.
    56 // The return address contained in $31 is saved in the _current task context
     50//
     51// It desactivate the DTLB, to directly access the scheduler using
     52// the physical address stored in register CP0_SCHED.
     53// All the context switch procedure is executed with interrupts masked.
     54//
     55// The return address contained in $31 is saved in the current task context
    5756// (in the ctx[31] slot), and the function actually returns to the address
    58 // contained in the ctx[31] slot of the new task context. To perform the
    59 // actual switch, it calls the _task_switch function written in assembly language.
     57// contained in the ctx[31] slot of the next task context.
    6058/////////////////////////////////////////////////////////////////////////////////
    6159void _ctx_switch()
    6260{
    63     unsigned char curr_task_id;
    64     unsigned char next_task_id;
    65 
    66     unsigned int *curr_context;
    67     unsigned int *next_context;
    68 
    69     unsigned int proc_id   = _procid();
    70     unsigned int tasks     = _scheduler[proc_id].tasks;
    71 
    72     // return if only one task  */
    73     if ( tasks <= 1) return;
    74  
    75     // compute the task context base address for the current task
    76     curr_task_id = _scheduler[proc_id].current;
    77     curr_context = &(_scheduler[proc_id].context[curr_task_id][0]);
     61    unsigned int                        tasks;
     62    unsigned int                        curr_task_id;
     63    unsigned int                        next_task_id;
     64    unsigned int                        *curr_ctx_paddr;
     65    unsigned int                        *next_ctx_paddr;
     66
     67    // get scheduler physical address
     68    static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
     69
     70    // get number of tasks allocated to scheduler
     71    tasks = _get_tasks_number();
     72
     73    // no switch if only one task
     74    if ( tasks > 1)
     75    {
     76        // compute the context physical address for the current task
     77        curr_task_id = _get_current_task_id();
     78        curr_ctx_paddr = &(psched->context[curr_task_id][0]);
    7879   
    79     // select the next task using a round-robin scheduling policy
    80     next_task_id = (curr_task_id + 1) % tasks;
     80        // select the next task using a round-robin policy
     81        next_task_id = (curr_task_id + 1) % tasks;
    8182   
    82     // compute the task context base address for the next task
    83     next_context = &(_scheduler[proc_id].context[next_task_id][0]);
     83        // compute the context physical address for the next task
     84        next_ctx_paddr = &(psched->context[next_task_id][0]);
     85
     86        // update the scheduler state
     87        _set_current_task_id( next_task_id );
    8488
    8589#if GIET_DEBUG_SWITCH
    8690_get_lock( &_tty_put_lock );
    8791_puts( "\n[GIET] Context switch for processor ");
    88 _putw( proc_id );
     92_putw( _procid() );
    8993_puts( " at cycle ");
    9094_putw( _proctime() );
     
    102106#endif
    103107
    104     //  update the scheduler state, and makes the task switch
    105     _scheduler[proc_id].current = next_task_id;
    106     _task_switch( curr_context, next_context );
    107 
     108        // makes the task switch
     109        _task_switch( curr_ctx_paddr, next_ctx_paddr );
     110
     111/*
     112        asm volatile( "ori              $27,    $0,             0xB     \n"
     113                      "mtc2             $27,    $1                      \n"             // desactivate DTLB
     114
     115                      "add      $27,    %0,     $0  \n"         // $27 <= &curr_ctx
     116
     117                      "mfc0     $26,    $12         \n"         // $26 <= SR
     118                      "sw       $26,    0*4($27)    \n"         // ctx[0] <= SR
     119                      ".set noat                    \n"
     120                      "sw       $1,     1*4($27)    \n"         // ctx[1] <= $1
     121                      ".set at                      \n"
     122                      "sw       $2,     2*4($27)    \n"         // ctx[2] <= $2
     123                      "sw       $3,     3*4($27)    \n"         // ctx[3] <= $3
     124                      "sw       $4,     4*4($27)    \n"         // ctx[4] <= $4
     125                      "sw       $5,     5*4($27)    \n"         // ctx[5] <= $5
     126                      "sw       $6,     6*4($27)    \n"         // ctx[6] <= $6
     127                      "sw       $7,     7*4($27)    \n"         // ctx[7] <= $7
     128                      "sw       $8,     8*4($27)    \n"         // ctx[8] <= $8
     129                      "sw       $9,     9*4($27)    \n"         // ctx[9] <= $9
     130                      "sw       $10,    10*4($27)   \n"         // ctx[10] <= $10
     131                      "sw       $11,    11*4($27)   \n"         // ctx[11] <= $11
     132                      "sw       $12,    12*4($27)   \n"         // ctx[12] <= $12
     133                      "sw       $13,    13*4($27)   \n"         // ctx[13] <= $13
     134                      "sw       $14,    14*4($27)   \n"         // ctx[14] <= $14
     135                      "sw       $15,    15*4($27)   \n"         // ctx[15] <= $15
     136                      "sw       $16,    16*4($27)   \n"         // ctx[16] <= $16
     137                      "sw       $17,    17*4($27)   \n"         // ctx[17] <= $17
     138                      "sw       $18,    18*4($27)   \n"         // ctx[18] <= $18
     139                      "sw       $19,    19*4($27)   \n"         // ctx[19] <= $19
     140                      "sw       $20,    20*4($27)   \n"         // ctx[20] <= $20
     141                      "sw       $21,    21*4($27)   \n"         // ctx[21] <= $21
     142                      "sw       $22,    22*4($27)   \n"         // ctx[22] <= $22
     143                      "sw       $23,    23*4($27)   \n"         // ctx[23] <= $23
     144                      "sw       $24,    24*4($27)   \n"         // ctx[24] <= $24
     145                      "sw       $25,    25*4($27)   \n"         // ctx[25] <= $25
     146                      "mflo     $26                 \n"
     147                      "sw       $26,    26*4($27)   \n"         // ctx[26] <= LO
     148                      "mfhi     $26                 \n"
     149                      "sw       $26,    27*4($27)   \n"         // ctx[27] <= H1
     150                      "sw       $28,    28*4($27)   \n"         // ctx[28] <= $28
     151                      "sw       $29,    29*4($27)   \n"         // ctx[29] <= $29
     152                      "sw       $30,    30*4($27)   \n"         // ctx[30] <= $30
     153                      "sw       $31,    31*4($27)   \n"         // ctx[31] <= $31
     154                      "mfc0     $26,    $14         \n"
     155                      "sw       $26,    32*4($27)   \n"         // ctx[32] <= EPC
     156                      "mfc0     $26,    $13         \n"
     157                      "sw       $26,    33*4($27)   \n"         // ctx[33] <= CR
     158                      "mfc2     $26,    $0          \n"
     159                      "sw       $26,    35*4($27)   \n"         // ctx[35] <= PTPR
     160
     161                      "add      $27,    %1,     $0      \n"             // $27<= &next_ctx
     162
     163                      "lw       $26,    35*4($27)       \n"
     164                      "mtc2     $26,    $0          \n"         // restore PTPR
     165                      "lw       $26,    0*4($27)        \n"
     166                      "mtc0     $26,    $12                     \n"             // restore SR
     167                      ".set noat                    \n"
     168                      "lw       $1,     1*4($27)        \n"             // restore $1
     169                      ".set at                      \n"
     170                          "lw       $2,     2*4($27)    \n"             // restore $2
     171                      "lw       $3,     3*4($27)    \n"         // restore $3
     172                      "lw       $4,     4*4($27)    \n"         // restore $4
     173                      "lw       $5,     5*4($27)    \n"         // restore $5
     174                      "lw       $6,     6*4($27)    \n"         // restore $6
     175                      "lw       $7,     7*4($27)    \n"         // restore $7
     176                      "lw       $8,     8*4($27)    \n"         // restore $8
     177                      "lw       $9,     9*4($27)    \n"         // restore $9
     178                      "lw       $10,    10*4($27)   \n"         // restore $10
     179                      "lw       $11,    11*4($27)   \n"         // restore $11
     180                      "lw       $12,    12*4($27)   \n"         // restore $12
     181                      "lw       $13,    13*4($27)   \n"         // restore $13
     182                      "lw       $14,    14*4($27)   \n"         // restore $14
     183                      "lw       $15,    15*4($27)   \n"         // restore $15
     184                      "lw       $16,    16*4($27)   \n"         // restore $16
     185                      "lw       $17,    17*4($27)   \n"         // restore $17
     186                      "lw       $18,    18*4($27)   \n"         // restore $18
     187                      "lw       $19,    19*4($27)   \n"         // restore $19
     188                      "lw       $20,    20*4($27)   \n"         // restore $20
     189                      "lw       $21,    21*4($27)   \n"         // restore $21
     190                      "lw       $22,    22*4($27)   \n"         // restore $22
     191                      "lw       $23,    23*4($27)   \n"         // restore $23
     192                      "lw       $24,    24*4($27)   \n"         // restore $24
     193                      "lw       $25,    25*4($27)   \n"         // restore $25
     194                      "lw       $26,    26*4($27)   \n"
     195                      "mtlo     $26                 \n"         // restore LO
     196                      "lw       $26,    27*4($27)   \n"
     197                      "mthi     $26                 \n"         // restore HI
     198                      "lw       $28,    28*4($27)   \n"         // restore $28
     199                      "lw       $29,    29*4($27)   \n"         // restore $29
     200                      "lw       $30,    30*4($27)   \n"         // restore $30
     201                      "lw       $31,    31*4($27)   \n"         // restore $31
     202                      "lw       $26,    32*4($27)   \n"
     203                      "mtc0     $26,    $14         \n"         // restore EPC
     204                      "lw       $26,    33*4($27)   \n"
     205                      "mtc0     $26,    $13         \n"         // restore CR
     206
     207                      "ori              $27,    $0,             0xF \n"
     208                      "mtc2             $27,    $1          \n"         // activate DTLB
     209                      :
     210                      : "r"(curr_ctx_paddr), "r"(next_ctx_paddr)
     211                      : "$1" ,            "$4" ,"$5" ,"$6" ,"$7" ,"$8" ,"$9" ,"$10",
     212                        "$11","$12","$13","$14","$15","$16","$17","$18","$19","$20",
     213                        "$21","$22","$23","$24","$25","$26","$27",      "$29",
     214                        "$31" );
     215*/
     216    }
    108217} // end _ctx_switch
    109218
  • soft/giet_vm/sys/ctx_handler.h

    r167 r189  
    1010typedef struct static_scheduler_s
    1111{
    12     unsigned int        context[GIET_NB_TASKS_MAX][64];   // task contexts
    13     unsigned int        tasks;                                        // actual number of tasks
    14     unsigned int        current;                                      // current task index
     12    unsigned int        context[15][64];                // at most 15 task contexts
     13    unsigned int        tasks;                                  // actual number of tasks
     14    unsigned int        current;                                // current task index
     15    unsigned int        interrupt_vector[32];   // interrupt vector
    1516} static_scheduler_t;
    1617
     
    3233#define CTX_PTAB_ID             42
    3334#define CTX_TASK_ID             43
    34 
     35#define CTX_SCHED_ID    44
     36#define CTX_TIMER_ID    45
    3537
    3638//////////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/sys/drivers.c

    r169 r189  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The drivers.c and drivers.h files are part ot the GIET nano kernel.
     7// The drivers.c and drivers.h files are part ot the GIET-VM nano kernel.
    88// They contains the drivers for the peripherals available in the SoCLib library:
    99// - vci_multi_tty
     
    1111// - vci_multi_dma
    1212// - vci_multi_icu
     13// - vci_xicu
    1314// - vci_gcd
    1415// - vci_frame_buffer
     
    1617//
    1718// The following global parameters must be defined in the giet_config.h file:
    18 // - NB_CLUSTERS  : number of clusters
    19 // - NB_PROCS     : number of PROCS per cluster
    20 // - NB_TIMERS    : number of TIMERS per cluster
    21 // - NB_DMAS      : number of DMA channels
    22 // - NB_TTYS      : number of TTY terminals
    23 // - NB_TIMERS    : number of TIMERS per cluster
    24 // - CLUSTER_SPAN : address increment between clusters
     19// - NB_CLUSTERS   
     20// - NB_PROCS_MAX 
     21// - NB_TIMERS_MAX   
     22// - NB_DMAS_MAX     
     23// - NB_TTYS   
    2524//
    2625// The following base addresses must be defined in the sys.ld file:
     
    4342#include <ctx_handler.h>
    4443
    45 #if !defined(NB_PROCS)
    46 # error: You must define NB_PROCS in 'giet_config.h' file!
    47 #endif
    4844#if !defined(NB_CLUSTERS)
    49 # error: You must define NB_CLUSTERS in 'giet_config.h' file!
    50 #endif
     45# error: You must define NB_CLUSTERS in 'giet_config.h' file
     46#endif
     47
     48#if !defined(NB_PROCS_MAX)
     49# error: You must define NB_PROCS_MAX in 'giet_config.h' file
     50#endif
     51
     52#if (NB_PROCS_MAX > 8)
     53# error: NB_PROCS_MAX cannot be larger than 8!
     54#endif
     55
    5156#if !defined(CLUSTER_SPAN)
    52 # error: You must define CLUSTER_SPAN in 'giet_config.h' file!
    53 #endif
     57# error: You must define CLUSTER_SPAN in 'giet_config.h' file
     58#endif
     59
    5460#if !defined(NB_TTYS)
    55 # error: You must define NB_TTYS in 'giet_config.h' file!
    56 #endif
    57 #if !defined(NB_DMAS)
    58 # error: You must define NB_DMAS in 'giet_config.h' file!
    59 #endif
    60 #if !defined(NB_TIMERS)
    61 # error: You must define NB_TIMERS in 'giet_config.h' file!
     61# error: You must define NB_TTYS in 'giet_config.h' file
    6262#endif
    6363
     
    6666#endif
    6767
    68 #if (NB_TIMERS < NB_PROCS)
    69 # error: NB_TIMERS must be larger or equal to NB_PROCS!
    70 #endif
    71 
    72 #if (NB_PROCS > 8)
    73 # error: NB_PROCS cannot be larger than 8!
    74 #endif
    75 
    76 #if (NB_DMAS < 1)
    77 # error: NB_DMAS cannot be 0!
    78 #endif
    79 
    80 
    81 /////////////////////////////////////////////////////////////////////////////
    82 //      Global (uncachable) variables
    83 /////////////////////////////////////////////////////////////////////////////
     68#if !defined(NB_DMAS_MAX)
     69# error: You must define NB_DMAS_MAX in 'giet_config.h' file
     70#endif
     71
     72#if (NB_DMAS_MAX < 1)
     73# error: NB_DMAS_MAX cannot be 0!
     74#endif
     75
     76#if !defined(NB_TIMERS_MAX)
     77# error: You must define NB_TIMERS_MAX in 'giet_config.h' file
     78#endif
     79
     80#if ( (NB_TIMERS_MAX + NB_PROCS_MAX) > 32 )
     81# error: NB_TIMERS_MAX + NB_PROCS_MAX cannot be larger than 32
     82#endif
     83
     84#if !defined(NB_IOCS)
     85# error: You must define NB_IOCS in 'giet_config.h' file
     86#endif
     87
     88#if ( NB_IOCS > 1 )
     89# error: NB_IOCS cannot be larger than 1
     90#endif
     91
    8492
    8593#define in_unckdata __attribute__((section (".unckdata")))
    8694
    87 // IOC variables
    88 in_unckdata volatile unsigned char _ioc_status       = 0;
    89 in_unckdata volatile unsigned char _ioc_done         = 0;
    90 in_unckdata unsigned int                   _ioc_lock         = 0;
    91 in_unckdata unsigned int                   _ioc_iommu_ix1    = 0;
    92 in_unckdata unsigned int                   _ioc_iommu_npages;
    93 
    94 // DMA variables
    95 in_unckdata volatile unsigned int  _dma_status[NB_DMAS];
    96 in_unckdata volatile unsigned char _dma_busy[NB_DMAS] = { [0 ... NB_DMAS-1] = 0 };
    97 in_unckdata volatile unsigned char _dma_iommu_ix1     = 1;
    98 in_unckdata volatile unsigned char _dma_iommu_npages[NB_DMAS];
     95
     96//////////////////////////////////////////////////////////////////////////////
     97//      VciMultiTimer driver
     98//////////////////////////////////////////////////////////////////////////////
     99// There is one multi_timer (or xicu) component per cluster.
     100// The global index is cluster_id*(NB_PROCS_MAX+NB_TIMERS_MAX) + local_id
     101// There is two types of timers:
     102// - "system" timers : one per processor, used for context switch.
     103//   local_id in [0, NB_PROCS_MAX-1],
     104// - "user" timers : requested by the task in the mapping_info data structure.
     105//   local_id in [NB_PROC_MAX, NB_PROCS_MAX+NB_TIMERS_MAX-1],
     106//   For each user timer, the tty_id is stored in the context of the task
     107//   and must be explicitely defined in the boot code.
     108// These timers can be implemented in a vci_multi_timer component
     109// or in a vci_xicu component (depending on the GIET_USE_XICU parameter).
     110//////////////////////////////////////////////////////////////////////////////
     111
     112// User Timer signaling variables
     113
     114#if (NB_TIMERS_MAX > 0)
     115in_unckdata volatile unsigned char _user_timer_event[NB_CLUSTERS*NB_TIMERS_MAX]
     116         = { [0 ... ((NB_CLUSTERS*NB_TIMERS_MAX)-1)] = 0 };
     117#endif
     118
     119//////////////////////////////////////////////////////////////////////////////
     120//     _timer_access()
     121// This function is the only way to access a timer device.
     122// It can be a multi-timer component or an xicu component.
     123// It can be used by the kernel to initialise a "system" timer,
     124// or by a task (through a system call) to configure an "user" timer.
     125// Returns 0 if success, > 0 if error.
     126//////////////////////////////////////////////////////////////////////////////
     127unsigned int _timer_access( unsigned int        read,
     128                            unsigned int        cluster_id,
     129                            unsigned int        local_id,
     130                            unsigned int        register_id,
     131                            unsigned int*       buffer )
     132{
     133    // parameters checking
     134    if ( register_id >= TIMER_SPAN)                                     return 1;
     135    if ( cluster_id >= NB_CLUSTERS)                                     return 1;
     136    if ( local_id >= NB_TIMERS_MAX + NB_PROCS_MAX ) return 1;
     137
     138#if GIET_USE_XICU
     139
     140    unsigned int* timer_address = //TODO
     141
     142#else
     143
     144    unsigned int* timer_address = (unsigned int*)&seg_timer_base +
     145                                  (cluster_id * CLUSTER_SPAN)  +
     146                                  (local_id * TIMER_SPAN);
     147#endif
     148
     149    if (read)   *buffer = timer_address[register_id]; // read word
     150    else                timer_address[register_id] = *buffer; // write word
     151    return 0;
     152}
     153//////////////////////////////////////////////////////////////////////////////
     154//     _timer_write()
     155// This function implements a write access to a "user" timer register.
     156// It gets the cluster_id and local_id from the global index stored in
     157// the task context and use the timer_access() function to make the write.
     158// Returns 0 if success, > 0 if error.
     159//////////////////////////////////////////////////////////////////////////////
     160unsigned int _timer_write( unsigned int register_id,
     161                           unsigned int value )
     162{
     163    unsigned int buffer     = value;
     164    unsigned int timer_id   = _get_current_context_slot(CTX_TIMER_ID);
     165    unsigned int cluster_id = timer_id / (NB_PROCS_MAX + NB_TIMERS_MAX);
     166    unsigned int local_id   = timer_id % (NB_PROCS_MAX + NB_TIMERS_MAX);
     167
     168    // checking user timer
     169    if ( local_id < NB_PROCS_MAX )
     170    {
     171        return 2;
     172    }
     173    else
     174    {
     175        return _timer_access ( 0,                               // write access
     176                               cluster_id,
     177                               local_id,
     178                               register_id,
     179                               &buffer );
     180    }
     181}
     182//////////////////////////////////////////////////////////////////////////////
     183//     _timer_read()
     184// This function implements a read access to a "user" timer register.
     185// It gets the cluster_id and local_id from the global index stored in
     186// the task context and use the timer_access() function to make the read.
     187// Returns 0 if success, > 0 if error.
     188//////////////////////////////////////////////////////////////////////////////
     189unsigned int _timer_read( unsigned int  register_id,
     190                          unsigned int* buffer )
     191{
     192    unsigned int timer_id   = _get_current_context_slot(CTX_TIMER_ID);
     193    unsigned int cluster_id = timer_id / (NB_PROCS_MAX + NB_TIMERS_MAX);
     194    unsigned int local_id   = timer_id % (NB_PROCS_MAX + NB_TIMERS_MAX);
     195
     196    // checking user timer
     197    if ( local_id < NB_PROCS_MAX )
     198    {
     199        return 2;
     200    }
     201    else
     202    {
     203        return _timer_access ( 1,                               // read access
     204                               cluster_id,
     205                               local_id,
     206                               register_id,
     207                               buffer );
     208    }
     209}
     210/////////////////////////////////////////////////////////////////////////////////
     211//     _timer_check()
     212/////////////////////////////////////////////////////////////////////////////////
     213
     214/////////////////////////////////////////////////////////////////////////////////
     215//      VciMultiTty driver
     216/////////////////////////////////////////////////////////////////////////////////
     217// There is only one multi_tty controler in the architecture.
     218// The total number of TTYs is defined by the configuration parameter NB_TTYS.
     219// The "system" terminal is TTY[0].
     220// The "user" TTYs are allocated to applications by the GIET in the boot phase,
     221// as defined in the mapping_info data structure. The corresponding tty_id must
     222// be stored in the context of the task by the boot code.
     223// The TTY address is : seg_tty_base + tty_id*TTY_SPAN
     224/////////////////////////////////////////////////////////////////////////////////
    99225
    100226// TTY variables
    101227in_unckdata volatile unsigned char _tty_get_buf[NB_TTYS];
    102228in_unckdata volatile unsigned char _tty_get_full[NB_TTYS] = { [0 ... NB_TTYS-1] = 0 };
    103 in_unckdata unsigned int           _tty_put_lock          = 0;
    104 
    105 //////////////////////////////////////////////////////////////////////////////
    106 //      VciMultiTimer driver
    107 //////////////////////////////////////////////////////////////////////////////
    108 // There is one MULTI-TIMER component per cluster.
    109 // The number of timers per cluster must be larger or equal to the number
    110 // processors (NB_TIMERS >= NB_PROCS), because each processor uses a private
    111 // yimer for context switch.
    112 // The total number of timers is NB_CLUSTERS * NB_TIMERS
    113 // The global timer index = cluster_id*NB_TIMERS + timer_id
    114 //////////////////////////////////////////////////////////////////////////////
    115 
    116 //////////////////////////////////////////////////////////////////////////////
    117 // _timer_write()
    118 //
    119 // Write a 32-bit word in a memory mapped register of a timer device,
    120 // identified by the cluster index and the local timer index.
    121 // Returns 0 if success, > 0 if error.
    122 //////////////////////////////////////////////////////////////////////////////
    123 unsigned int _timer_write( unsigned int cluster_index,
    124                            unsigned int timer_index,
    125                            unsigned int register_index,
    126                            unsigned int value )
    127 {
    128     unsigned int*       timer_address;
    129 
    130     // parameters checking
    131     if ( register_index >= TIMER_SPAN)          return 1;
    132     if ( cluster_index >= NB_CLUSTERS)          return 1;
    133     if ( timer_index >= NB_TIMERS )         return 1;
    134 
    135     timer_address = (unsigned int*)&seg_timer_base +
    136                     ( cluster_index * CLUSTER_SPAN )  +
    137                     ( timer_index * TIMER_SPAN );
    138 
    139     timer_address[register_index] = value; // write word
    140 
    141     return 0;
    142 }
    143 
    144 //////////////////////////////////////////////////////////////////////////////
    145 // _timer_read()
    146 //
    147 // Read a 32-bit word in a memory mapped register of a timer device,
    148 // identified by the cluster index and the local timer index.
    149 // Returns 0 if success, > 0 if error.
    150 //////////////////////////////////////////////////////////////////////////////
    151 unsigned int _timer_read(unsigned int cluster_index,
    152                          unsigned int timer_index,
    153                          unsigned int register_index,
    154                          unsigned int *buffer)
    155 {
    156     unsigned int *timer_address;
    157 
    158     // parameters checking
    159     if ( register_index >= TIMER_SPAN)          return 1;
    160     if ( cluster_index >= NB_CLUSTERS)          return 1;
    161     if ( timer_index >= NB_TIMERS )         return 1;
    162 
    163     timer_address = (unsigned int*)&seg_timer_base +
    164                     ( cluster_index * CLUSTER_SPAN )  +
    165                     ( timer_index * TIMER_SPAN );
    166 
    167     *buffer = timer_address[register_index]; // read word
    168 
    169     return 0;
    170 }
    171 
     229in_unckdata unsigned int           _tty_put_lock = 0;  // protect kernel TTY[0]
     230
     231////////////////////////////////////////////////////////////////////////////////
     232//      _tty_error()
     233////////////////////////////////////////////////////////////////////////////////
     234void _tty_error()
     235{
     236    unsigned int task_id = _get_current_task_id();
     237    unsigned int proc_id = _procid();
     238
     239    _get_lock(&_tty_put_lock);
     240    _puts("\n[GIET ERROR] TTY index too large for task ");
     241    _putw( task_id );
     242    _puts(" on processor ");
     243    _putw( proc_id );
     244    _puts("\n");
     245    _release_lock(&_tty_put_lock);
     246}
    172247/////////////////////////////////////////////////////////////////////////////////
    173 //      VciMultiTty driver
    174 /////////////////////////////////////////////////////////////////////////////////
    175 // The total number of TTYs is defined by the configuration parameter NB_TTYS.
    176 // The system terminal is TTY[0].
    177 // The TTYs are allocated to applications by the GIET in the boot phase.
    178 // The nummber of TTYs allocated to each application, and used by each
    179 // task can be defined in the mapping_info data structure.
    180 // For each user task, the tty_id is stored in the context of the task (slot 34),
    181 // and must be explicitely defined in the boot code.
    182 // The TTY address is always computed as : seg_tty_base + tty_id*TTY_SPAN
    183 ///////////////////////////////////////////////////////////////////////////////////
    184 
    185 //////////////////////////////////////////////////////////////////////////////
    186 // _tty_write()
    187 //
     248//      _tty_write()
    188249// Write one or several characters directly from a fixed-length user buffer to
    189250// the TTY_WRITE register of the TTY controler.
     
    192253// the transfer as soon as the TTY_STATUS[WRITE] bit is set.
    193254// The function returns  the number of characters that have been written.
    194 //////////////////////////////////////////////////////////////////////////////
     255/////////////////////////////////////////////////////////////////////////////////
    195256unsigned int _tty_write( const char             *buffer,
    196257                         unsigned int   length)
    197258{
    198     volatile unsigned int *tty_address;
    199 
    200     unsigned int proc_id;
    201     unsigned int task_id;
    202     unsigned int tty_id;
    203     unsigned int nwritten;
    204 
    205     proc_id = _procid();
    206    
    207     task_id = _scheduler[proc_id].current;
    208     tty_id  = _scheduler[proc_id].context[task_id][CTX_TTY_ID];
    209 
    210     tty_address = (unsigned int*)&seg_tty_base + tty_id*TTY_SPAN;
     259    unsigned int        nwritten;
     260
     261    unsigned int        tty_id = _get_current_context_slot(CTX_TTY_ID);
     262    if ( tty_id >= NB_TTYS )
     263    {
     264        _tty_error();
     265        return 0;
     266    }
     267
     268    unsigned int*       tty_address = (unsigned int*)&seg_tty_base + tty_id*TTY_SPAN;
    211269
    212270    for (nwritten = 0; nwritten < length; nwritten++)
     
    221279    return nwritten;
    222280}
    223 
    224281//////////////////////////////////////////////////////////////////////////////
    225 // _tty_read_irq()
    226 //
     282//      _tty_read_irq()
    227283// This non-blocking function uses the TTY_GET_IRQ[tty_id] interrupt and
    228284// the associated kernel buffer, that has been written by the ISR.
     
    235291                            unsigned int        length)
    236292{
    237     unsigned int proc_id;
    238     unsigned int task_id;
    239     unsigned int tty_id;
    240     unsigned int ret;
    241 
    242     proc_id = _procid();
    243     task_id = _scheduler[proc_id].current;
    244     tty_id  = _scheduler[proc_id].context[task_id][CTX_TTY_ID];
     293    unsigned int        tty_id = _get_current_context_slot(CTX_TTY_ID);
     294
     295    if ( tty_id >= NB_TTYS )
     296    {
     297        _tty_error();
     298        return 0;
     299    }
    245300
    246301    if (_tty_get_full[tty_id] == 0)
    247302    {
    248         ret = 0;
     303        return 0;
    249304    }
    250305    else
     
    252307        *buffer = _tty_get_buf[tty_id];
    253308        _tty_get_full[tty_id] = 0;
    254         ret = 1;
    255     }
    256     return ret;
    257 }
    258 
    259 ////////////////////////////////////////////////////////////////////////////////
    260 // _tty_read()
    261 //
     309        return 1;
     310    }
     311}
     312////////////////////////////////////////////////////////////////////////////////
     313//     _tty_read()
    262314// This non-blocking function fetches one character directly from the TTY_READ
    263315// register of the TTY controler, and writes this character to the user buffer.
     
    268320                        unsigned int    length)
    269321{
    270     volatile unsigned int *tty_address;
    271 
    272     unsigned int proc_id;
    273     unsigned int task_id;
    274     unsigned int tty_id;
    275 
    276     proc_id = _procid();
    277     task_id = _scheduler[proc_id].current;
    278     tty_id  = _scheduler[proc_id].context[task_id][CTX_TTY_ID];
    279 
    280     tty_address = (unsigned int*)&seg_tty_base + tty_id*TTY_SPAN;
    281 
    282     if ((tty_address[TTY_STATUS] & 0x1) != 0x1) return 0;
    283 
    284     *buffer = (char)tty_address[TTY_READ];
    285     return 1;
    286 }
    287 
    288 ////////////////////////////////////////////////////////////////////////////////
    289 //      VciMultiIcu driver
    290 ////////////////////////////////////////////////////////////////////////////////
    291 // There is in principle one MULTI-ICU component per cluster, and the
    292 // number of independant ICUs is equal to NB_PROCS, because there is
    293 // one ICU per processor.
    294 ////////////////////////////////////////////////////////////////////////////////
    295 
    296 ////////////////////////////////////////////////////////////////////////////////
    297 // _icu_write()
    298 //
     322    unsigned int        tty_id = _get_current_context_slot(CTX_TTY_ID);
     323    if ( tty_id >= NB_TTYS )
     324    {
     325        _tty_error();
     326        return 0;
     327    }
     328
     329    unsigned int*       tty_address = (unsigned int*)&seg_tty_base + tty_id*TTY_SPAN;
     330
     331    if ((tty_address[TTY_STATUS] & 0x1) != 0x1)
     332    {
     333        return 0;
     334    }
     335    else
     336    {
     337        *buffer = (char)tty_address[TTY_READ];
     338        return 1;
     339    }
     340}
     341
     342////////////////////////////////////////////////////////////////////////////////
     343//      VciMultiIcu and VciXicu drivers
     344////////////////////////////////////////////////////////////////////////////////
     345// There is in principle one vci_multi_icu (or vci_xicu) component per cluster,
     346// and the number of independant ICUs is equal to NB_PROCS_MAX, because there is
     347// one private interrupr controler per processor.
     348////////////////////////////////////////////////////////////////////////////////
     349
     350////////////////////////////////////////////////////////////////////////////////
     351//     _icu_write()
    299352// Write a 32-bit word in a memory mapped register of the MULTI_ICU device,
    300353// identified by the cluster index, and a processor local index.
     
    306359                         unsigned int value )
    307360{
    308     unsigned int *icu_address;
     361#if GIET_USE_XICU
     362
     363#else
    309364
    310365    // parameters checking
    311366    if ( register_index >= ICU_SPAN)            return 1;
    312367    if ( cluster_index >= NB_CLUSTERS)          return 1;
    313     if ( proc_index >= NB_PROCS )           return 1;
    314 
    315     icu_address = (unsigned int*)&seg_icu_base +
    316                   ( cluster_index * CLUSTER_SPAN )  +
    317                   ( proc_index * ICU_SPAN );
     368    if ( proc_index >= NB_PROCS_MAX )       return 1;
     369
     370    unsigned int *icu_address = (unsigned int*)&seg_icu_base +
     371                                (cluster_index * CLUSTER_SPAN)  +
     372                                (proc_index * ICU_SPAN);
    318373
    319374    icu_address[register_index] = value;   // write word
    320375    return 0;
    321 }
    322 
    323 ////////////////////////////////////////////////////////////////////////////////
    324 // _icu_read()
    325 //
     376
     377#endif
     378}
     379////////////////////////////////////////////////////////////////////////////////
     380//     _icu_read()
    326381// Read a 32-bit word in a memory mapped register of the MULTI_ICU device,
    327382// identified by the cluster index and a processor local index.
     
    333388                         unsigned int* buffer )
    334389{
    335     unsigned int *icu_address;
     390#if GIET_USE_XICU
     391
     392#else
    336393
    337394    // parameters checking
    338395    if ( register_index >= ICU_SPAN)            return 1;
    339396    if ( cluster_index >= NB_CLUSTERS)          return 1;
    340     if ( proc_index >= NB_PROCS )           return 1;
    341 
    342     icu_address = (unsigned int*)&seg_icu_base +
    343                   ( cluster_index * CLUSTER_SPAN )  +
    344                   ( proc_index * ICU_SPAN );
     397    if ( proc_index >= NB_PROCS_MAX )       return 1;
     398
     399    unsigned int *icu_address = (unsigned int*)&seg_icu_base +
     400                                (cluster_index * CLUSTER_SPAN)  +
     401                                (proc_index * ICU_SPAN);
    345402
    346403    *buffer = icu_address[register_index]; // read word
    347404    return 0;
     405
     406#endif
    348407}
    349408
     
    357416
    358417////////////////////////////////////////////////////////////////////////////////
    359 // _gcd_write()
    360 //
     418//     _gcd_write()
    361419// Write a 32-bit word in a memory mapped register of the GCD coprocessor.
    362420// Returns 0 if success, > 0 if error.
     
    376434    return 0;
    377435}
    378 
    379 ////////////////////////////////////////////////////////////////////////////////
    380 // _gcd_read()
    381 //
     436////////////////////////////////////////////////////////////////////////////////
     437//     _gcd_read()
    382438// Read a 32-bit word in a memory mapped register of the GCD coprocessor.
    383439// Returns 0 if success, > 0 if error.
     
    448504///////////////////////////////////////////////////////////////////////////////
    449505
     506// IOC global variables
     507in_unckdata volatile unsigned int       _ioc_status       = 0;
     508in_unckdata volatile unsigned int       _ioc_done         = 0;
     509in_unckdata unsigned int                        _ioc_lock         = 0;
     510in_unckdata unsigned int                        _ioc_iommu_ix1    = 0;
     511in_unckdata unsigned int                        _ioc_iommu_npages;
     512
    450513///////////////////////////////////////////////////////////////////////////////
    451 // _ioc_get_lock()
    452 //
    453 // This blocking helper is used by '_ioc_read()' and '_ioc_write()' functions
    454 // to get _ioc_lock using atomic LL/SC.
    455 ///////////////////////////////////////////////////////////////////////////////
    456 static inline void _ioc_get_lock()
    457 {
    458     register unsigned int delay = (_proctime() & 0xF) << 4;
    459     register unsigned int *plock = (unsigned int*)&_ioc_lock;
    460 
    461     asm volatile (
    462             "_ioc_llsc:             \n"
    463             "ll   $2,    0(%0)      \n" /* $2 <= _ioc_lock current value */
    464             "bnez $2,    _ioc_delay \n" /* delay if _ioc_lock already taken */
    465             "li   $3,    1          \n" /* $3 <= argument for sc */
    466             "sc   $3,    0(%0)      \n" /* try to set _ioc_lock */
    467             "bnez $3,    _ioc_ok    \n" /* exit if atomic */
    468             "_ioc_delay:            \n"
    469             "move $4,    %1         \n" /* $4 <= delay */
    470             "_ioc_loop:             \n"
    471             "beqz $4,    _ioc_loop  \n" /* test end delay */
    472             "addi $4,    $4,    -1  \n" /* $4 <= $4 - 1 */
    473             "j           _ioc_llsc  \n" /* retry ll */
    474             "nop                    \n"
    475             "_ioc_ok:               \n"
    476             :
    477             :"r"(plock), "r"(delay)
    478             :"$2", "$3", "$4");
    479 }
    480 
    481 ///////////////////////////////////////////////////////////////////////////////
    482 //  _ioc_access()
     514//      _ioc_access()
    483515// This function transfer data between a memory buffer and the block device.
    484516// The buffer lentgth is (count*block_size) bytes.
    485 //
    486517// Arguments are:
    487518// - to_mem     : from external storage to memory when non 0
     
    503534    unsigned int                ix2;                    // page index in IOMMU PT1 page table
    504535    unsigned int                addr;                   // buffer address for IOC peripheral
    505     unsigned int                user_ptp;               // page table pointer in user space
    506     unsigned int                ko;                             // bool returned by _v2p_translate()
    507536    unsigned int                ppn_first;              // first physical page number for user buffer
    508     unsigned int                ltid;                   // current task local index
    509     static_scheduler_t* psched;                 // pointer on the current task scheduler
    510537       
    511538    // check buffer alignment
     
    517544
    518545    // get user space page table virtual address
    519     psched   = &_scheduler[_procid()];
    520     ltid     = psched->current;
    521     user_ptp = psched->context[ltid][CTX_PTAB_ID];
     546    unsigned int user_pt_vbase = _get_current_context_slot(CTX_PTAB_ID);
    522547   
    523548    user_vpn_min = user_vaddr >> 12;
     
    529554    {
    530555        // get ppn and flags for each vpn
    531         ko = _v2p_translate( (page_table_t*)user_ptp,
    532                              vpn,
    533                              &ppn,
    534                              &flags );
     556        unsigned int ko = _v2p_translate( (page_table_t*)user_pt_vbase,
     557                                           vpn,
     558                                           &ppn,
     559                                           &flags );
    535560
    536561        // check access rights
     
    573598
    574599    // get the lock on ioc device
    575     _ioc_get_lock();
     600    _get_lock( &_ioc_lock );
    576601
    577602    // peripheral configuration 
     
    584609    return 0;
    585610}
    586 
    587611/////////////////////////////////////////////////////////////////////////////////
    588612// _ioc_completed()
     
    630654    return ret;
    631655}
    632 
    633656///////////////////////////////////////////////////////////////////////////////
    634 // _ioc_read()
     657//     _ioc_read()
    635658// Transfer data from the block device to a memory buffer in user space.
    636659// - lba    : first block index on the block device
     
    643666                        unsigned int    count )
    644667{
    645     return _ioc_access( 1,              // read
     668    return _ioc_access( 1,              // read access
    646669                        lba,
    647670                        (unsigned int)buffer,
    648671                        count );
    649672}
    650 
    651673///////////////////////////////////////////////////////////////////////////////
    652 // _ioc_write()
     674//     _ioc_write()
    653675// Transfer data from a memory buffer in user space to the block device.
    654676// - lba    : first block index on the block device
     
    661683                         unsigned int   count )
    662684{
    663     return _ioc_access( 0,              // write
     685    return _ioc_access( 0,              // write access
    664686                        lba,
    665687                        (unsigned int)buffer,
     
    668690
    669691//////////////////////////////////////////////////////////////////////////////////
     692// VciMultiDma driver
     693//////////////////////////////////////////////////////////////////////////////////
     694// The DMA controllers are physically distributed in the clusters.
     695// There is  (NB_CLUSTERS * NB_DMAS_MAX) channels, indexed by a global index:
     696//        dma_id = cluster_id * NB_DMA_MAX + loc_id
     697//
     698// As a DMA channel can be used by several tasks, each DMA channel is protected
     699// by a specific lock: _dma_lock[dma_id]
     700// The signalisation between the OS and the DMA uses the _dma_done[dma_id]
     701// synchronisation variables  (set by the ISR, and reset by the OS).
     702// The transfer status is copied by the ISR in the _dma_status[dma_id] variables.
     703//
     704// These DMA channels can be used by the FB driver, or by the NIC driver.
     705//////////////////////////////////////////////////////////////////////////////////
     706
     707#if  (NB_DMAS_MAX > 0)
     708in_unckdata unsigned int                        _dma_lock[NB_DMAS_MAX * NB_CLUSTERS]
     709                                       = { [0 ... (NB_DMAS_MAX * NB_CLUSTERS)-1] = 0 };
     710
     711in_unckdata volatile unsigned int       _dma_done[NB_DMAS_MAX * NB_CLUSTERS]
     712                                       = { [0 ... (NB_DMAS_MAX * NB_CLUSTERS)-1] = 0 };
     713
     714in_unckdata volatile unsigned int       _dma_status[NB_DMAS_MAX * NB_CLUSTERS];
     715
     716in_unckdata unsigned int                        _dma_iommu_ix1 = 1;
     717
     718in_unckdata unsigned int            _dma_iommu_npages[NB_DMAS_MAX * NB_CLUSTERS];
     719#endif
     720
     721//////////////////////////////////////////////////////////////////////////////////
    670722//      VciFrameBuffer driver
    671723//////////////////////////////////////////////////////////////////////////////////
     724// The vci_frame_buffer device can be accessed directly by software with memcpy(),
     725// or it can be accessed through a multi-channels DMA component:
     726// 
    672727// The '_fb_sync_write' and '_fb_sync_read' functions use a memcpy strategy to
    673728// implement the transfer between a data buffer (user space) and the frame
     
    675730//
    676731// The '_fb_write()', '_fb_read()' and '_fb_completed()' functions use the DMA
    677 // coprocessor to transfer data between the user buffer and the frame buffer.
    678 // These  functions use a polling policy to test the global variables _dma_busy[i]
    679 // and detect the transfer completion. 
    680 // There is  NB_DMA channels, that are indexed by the dma_id stored in the
    681 // task context.
    682 // The _dma_busy[i] synchronisation variables (one per channel) are set by the OS,
    683 // and reset by the DMA ISR.
     732// controlers (distributed in the clusters) to transfer data
     733// between the user buffer and the frame buffer. A  DMA channel is
     734// allocated to each task requesting it in the mapping_info data structure.
    684735//////////////////////////////////////////////////////////////////////////////////
    685736
     
    697748                             unsigned int       length )
    698749{
    699     volatile unsigned char *fb_address;
    700750
    701751    // buffer must be mapped in user space
    702752    if ( ((unsigned int)buffer + length ) >= 0x80000000 )
     753    {
    703754        return 1;
    704 
    705     fb_address = (unsigned char*)&seg_fb_base + offset;
    706 
    707     // buffer copy
    708     memcpy((void*)fb_address, (void*)buffer, length);
    709 
    710     return 0;
     755    }
     756    else
     757    {
     758        unsigned char *fb_address = (unsigned char*)&seg_fb_base + offset;
     759        memcpy((void*)fb_address, (void*)buffer, length);
     760        return 0;
     761    }
    711762}
    712763
     
    724775                            unsigned int        length )
    725776{
    726     volatile unsigned char *fb_address;
    727 
    728777    // buffer must be mapped in user space
    729778    if ( ((unsigned int)buffer + length ) >= 0x80000000 )
     779    {
    730780        return 1;
    731 
    732     fb_address = (unsigned char*)&seg_fb_base + offset;
    733 
    734     // buffer copy
    735     memcpy((void*)buffer, (void*)fb_address, length);
    736 
    737     return 0;
    738 }
    739 
    740 //////////////////////////////////////////////////////////////////////////////////
    741 // _fb_access()
    742 // Transfer data between a memory buffer and the frame_buffer device using DMA.
    743 // - to_mem     : from frame buffer to memory when true.
     781    }
     782    else
     783    {
     784        unsigned char *fb_address = (unsigned char*)&seg_fb_base + offset;
     785        memcpy((void*)buffer, (void*)fb_address, length);
     786        return 0;
     787    }
     788}
     789
     790//////////////////////////////////////////////////////////////////////////////////
     791// _fb_dma_access()
     792// Transfer data between a user buffer and the frame_buffer using DMA.
     793// - to_user    : from frame buffer to user buffer when true.
    744794// - offset     : offset (in bytes) in the frame buffer.
    745795// - user_vaddr : virtual base address of the memory buffer.
     
    747797// The memory buffer must be mapped in user address space and word-aligned.
    748798// The user buffer length must be multiple of 4 bytes.
    749 // Returns 0 if success, > 0 if error.
    750 //////////////////////////////////////////////////////////////////////////////////
    751 unsigned int _fb_access( unsigned int   to_mem,
    752                          unsigned int   offset,
    753                          unsigned int   user_vaddr,
    754                          unsigned int   length )
    755 {
    756     static_scheduler_t* psched;         // pointer on the current task scheduler
    757     unsigned char*              fb_base;        // frame buffer base address
    758     unsigned int*               dma_base;       // dma component base address
    759     unsigned int                task_id;        // task local index (for scheduler)
    760     unsigned int                dma_id;         // DMA channel index
    761     unsigned int                vpn;            // current virtual page number
    762     unsigned int                flags;          // protection flags
    763     unsigned int                ppn;            // current physical page number
    764     unsigned int                buf_base;       // buffer base address for DMA access
    765     unsigned int                ppn_first;      // first physical page index for user buffer
    766 
    767     fb_base  = (unsigned char*)&seg_fb_base + offset;
    768 
    769     psched   = &_scheduler[_procid()];
    770     task_id  = psched->current;
    771     dma_id   = psched->context[task_id][CTX_FBDMA_ID];
    772     dma_base = (unsigned int*)&seg_dma_base + (dma_id * DMA_SPAN);
    773 
    774     // check buffer address and ength alignment
    775     if ( user_vaddr & 0x3 ) return 1;
    776     if ( length     & 0x3 ) return 1;
     799// Me must compute the physical base addresses for both the frame buffer
     800// and the user buffer before programming the DMA transfer.
     801// The GIET being fully static, we don't need to split the transfer in 4Kbytes
     802// pages, because the user buffer is contiguous in physical space.
     803// Returns 0 if success, > 0 if error.
     804//////////////////////////////////////////////////////////////////////////////////
     805unsigned int _fb_dma_access( unsigned int       to_user,
     806                             unsigned int   offset,
     807                             unsigned int   user_vaddr,
     808                             unsigned int   length )
     809{
     810    unsigned int        ko;                             // unsuccessfull V2P translation
     811    unsigned int        flags;                  // protection flags
     812    unsigned int        ppn;                    // physical page number
     813    unsigned int    user_pbase;         // user buffer pbase address
     814    unsigned int    fb_pbase;           // frame buffer pbase address
     815
     816    // get DMA channel and compute DMA vbase address
     817    unsigned int        dma_id     = _get_current_context_slot(CTX_FBDMA_ID);
     818    unsigned int    cluster_id = dma_id / NB_DMAS_MAX;
     819    unsigned int    loc_id     = dma_id % NB_DMAS_MAX;
     820    unsigned int*       dma_base   = (unsigned int*)&seg_dma_base +
     821                                 (cluster_id * CLUSTER_SPAN) +
     822                                 (loc_id * DMA_SPAN);
     823
     824    // check user buffer address and length alignment
     825    if ( (user_vaddr & 0x3) || (length & 0x3) )
     826    {
     827        _puts("[GIET ERROR] in _fbdma_access() : user buffer not word aligned\n");
     828        return 1;
     829    }
    777830
    778831    // get user space page table virtual address
    779     unsigned int user_ptp = psched->context[task_id][CTX_PTAB_ID];
    780 
     832    unsigned int        user_ptab = _get_current_context_slot(CTX_PTAB_ID);
     833
     834    // compute frame buffer pbase address
     835    unsigned int fb_vaddr = (unsigned int)&seg_fb_base + offset;
     836
     837    ko = _v2p_translate( (page_table_t*)user_ptab,
     838                         (fb_vaddr >> 12),
     839                         &ppn,
     840                         &flags );
     841    fb_pbase = (ppn << 12) | (fb_vaddr & 0x00000FFF);
     842
     843    if ( ko )
     844    {
     845        _puts("[GIET ERROR] in _fbdma_access() : frame buffer unmapped\n");
     846        return 2;
     847    }
     848
     849    // Compute user buffer pbase address
     850    ko = _v2p_translate( (page_table_t*)user_ptab,
     851                         (user_vaddr >> 12),
     852                         &ppn,
     853                         &flags );
     854    user_pbase = (ppn << 12) | (user_vaddr & 0x00000FFF);
     855
     856    if ( ko )
     857    {
     858        _puts("[GIET ERROR] in _fbdma_access() : user buffer unmapped\n");
     859        return 3;
     860    }
     861    if ( (flags & PTE_U) == 0 )
     862    {
     863        _puts("[GIET ERROR] in _fbdma_access() : user buffer not in user space\n");
     864        return 4;
     865    }
     866    if ( ( (flags & PTE_W) == 0 ) && to_user )
     867    {
     868        _puts("[GIET ERROR] in _fbdma_access() : user buffer not writable\n");
     869        return 5;
     870    }
     871
     872
     873
     874/*
     875    // loop on all virtual pages covering the user buffer
    781876    unsigned int user_vpn_min = user_vaddr >> 12;
    782877    unsigned int user_vpn_max = (user_vaddr + length - 1) >> 12;
    783878    unsigned int ix2          = 0;
    784879    unsigned int ix1          = _dma_iommu_ix1 + dma_id;
    785     unsigned int ko;
    786     unsigned int i;
    787 
    788     // loop on all virtual pages covering the user buffer
     880
    789881    for ( vpn = user_vpn_min ; vpn <= user_vpn_max ; vpn++ )
    790882    {
    791883        // get ppn and flags for each vpn
    792         ko = _v2p_translate( (page_table_t*)user_ptp,
    793                              vpn,
    794                              &ppn,
    795                              &flags );
     884        unsigned int ko = _v2p_translate( (page_table_t*)user_pt_vbase,
     885                                          vpn,
     886                                          &ppn,
     887                                          &flags );
    796888
    797889        // check access rights
    798         if ( ko )                                 return 2;     // unmapped
    799         if ( (flags & PTE_U) == 0 )               return 3;     // not in user space
    800         if ( ( (flags & PTE_W) == 0 ) && to_mem ) return 4;     // not writable
     890        if ( ko )                                 return 3;     // unmapped
     891        if ( (flags & PTE_U) == 0 )               return 4;     // not in user space
     892        if ( ( (flags & PTE_W) == 0 ) && to_user ) return 5;     // not writable
    801893
    802894        // save first ppn value
     
    816908        else            // no IOMMU : check that physical pages are contiguous
    817909        {
    818             if ( (ppn - ppn_first) != ix2 )       return 5;     // split physical buffer 
     910            if ( (ppn - ppn_first) != ix2 )       return 6;     // split physical buffer 
    819911        }
    820912
     
    823915    } // end for vpn
    824916
    825     // register the number of pages to be unmapped
     917    // register the number of pages to be unmapped if iommu activated
    826918    _dma_iommu_npages[dma_id] = (user_vpn_max - user_vpn_min) + 1;
    827919
     920*/
    828921    // invalidate data cache in case of memory write
    829     if ( to_mem ) _dcache_buf_invalidate( (void*)user_vaddr, length );
    830 
    831     // compute buffer base address for DMA depending on IOMMU activation
    832     if ( GIET_IOMMU_ACTIVE ) buf_base = ( ix1 ) << 21 | (user_vaddr & 0xFFF);
    833     else                     buf_base = (ppn_first << 12) | (user_vaddr & 0xFFF);
    834 
    835 
    836     // waiting until DMA device is available
    837     while (_dma_busy[dma_id] != 0)
    838     {
    839         // busy wait with a pseudo random delay between bus access
    840         unsigned int delay = (_proctime() & 0xF) << 4;
    841         for (i = 0; i < delay; i++)
    842             asm volatile("nop");
    843     }
    844 
    845     _dma_busy[dma_id] = 1;
     922    if ( to_user ) _dcache_buf_invalidate( (void*)user_vaddr, length );
     923
     924    // get the lock
     925    _get_lock( &_dma_lock[dma_id] );
    846926
    847927    // DMA configuration
    848     dma_base[DMA_IRQ_DISABLE] = 0;
    849     if ( to_mem )
    850     {
    851         dma_base[DMA_SRC] = (unsigned int)fb_base;
    852         dma_base[DMA_DST] = (unsigned int)buf_base;
     928    if ( to_user )
     929    {
     930        dma_base[DMA_SRC] = (unsigned int)fb_pbase;
     931        dma_base[DMA_DST] = (unsigned int)user_pbase;
    853932    }
    854933    else
    855934    {
    856         dma_base[DMA_SRC] = (unsigned int)buf_base;
    857         dma_base[DMA_DST] = (unsigned int)fb_base;
     935        dma_base[DMA_SRC] = (unsigned int)user_pbase;
     936        dma_base[DMA_DST] = (unsigned int)fb_pbase;
    858937    }
    859938    dma_base[DMA_LEN] = (unsigned int)length;
     
    873952                        unsigned int    length )
    874953{
    875     return _fb_access( 0,                                               // write to frame buffer
    876                        offset,
    877                        (unsigned int)buffer,
    878                        length );       
     954    return _fb_dma_access( 0,                                           // write to frame buffer
     955                           offset,
     956                           (unsigned int)buffer,
     957                           length );   
    879958}
    880959
     
    891970                       unsigned int     length )
    892971{
    893     return _fb_access( 1,                                               // read from frame buffer
    894                        offset,
    895                        (unsigned int)buffer,
    896                        length );       
     972    return _fb_dma_access( 1,                                           // read from frame buffer
     973                           offset,
     974                           (unsigned int)buffer,
     975                           length );   
    897976}
    898977
     
    906985unsigned int _fb_completed()
    907986{
    908     static_scheduler_t* psched  = &_scheduler[_procid()];
    909     unsigned int        task_id = psched->current;
    910 
    911     volatile unsigned int   dma_id  = psched->context[task_id][CTX_FBDMA_ID];
     987    unsigned int dma_id = _get_current_context_slot(CTX_FBDMA_ID);
    912988
    913989    // busy waiting with a pseudo random delay between bus access
    914     while (_dma_busy[dma_id] != 0)
     990    while (_dma_done[dma_id] == 0)
    915991    {
    916992            unsigned int i;
    917         unsigned int delay = (_proctime() & 0xF) << 4;
     993        unsigned int delay = ( _proctime() ^ _procid()<<4 ) & 0xFF;
    918994        for (i = 0; i < delay; i++)
    919995            asm volatile("nop");
     
    9381014    }
    9391015
     1016    // reset synchronization variables
     1017    _dma_lock[dma_id] = 0;
     1018    _dma_done[dma_id] = 0;
     1019
    9401020    return _dma_status[dma_id];
    9411021}
  • soft/giet_vm/sys/drivers.h

    r166 r189  
    1010
    1111///////////////////////////////////////////////////////////////////////////////////
    12 //      Global variables for interaction with ISRs
     12// Timer access functions (used for both vci_multi_timer and vci_xicu)
    1313///////////////////////////////////////////////////////////////////////////////////
    1414
    15 extern volatile unsigned int _dma_status[];
    16 extern volatile unsigned char _dma_busy[];
     15extern volatile unsigned char _timer_event[];
    1716
    18 extern volatile unsigned char _ioc_status;
    19 extern volatile unsigned char _ioc_done;
    20 extern unsigned int           _ioc_lock;
     17unsigned int _timer_access( unsigned int        read,           // reas if non 0
     18                            unsigned int        cluster_id,
     19                            unsigned int        local_id,
     20                            unsigned int        register_id,
     21                            unsigned int*       buffer);
     22
     23unsigned int _timer_read(   unsigned int        register_id,
     24                            unsigned int*       buffer);
     25
     26unsigned int _timer_write(  unsigned int        register_id,
     27                            unsigned int        value);
     28
     29///////////////////////////////////////////////////////////////////////////////////
     30// TTY access functions and variables
     31///////////////////////////////////////////////////////////////////////////////////
    2132
    2233extern volatile unsigned char _tty_get_buf[];
    2334extern volatile unsigned char _tty_get_full[];
    2435extern unsigned int           _tty_put_lock;
    25 
    26 ///////////////////////////////////////////////////////////////////////////////////
    27 // Prototypes of the external functions.
    28 ///////////////////////////////////////////////////////////////////////////////////
    29 
    30 unsigned int _timer_write(  unsigned int        cluster_id,
    31                             unsigned int        timer_id,
    32                             unsigned int        register_id,
    33                             unsigned int        value);
    34 
    35 unsigned int _timer_read(   unsigned int        cluster_id,
    36                             unsigned int        timer_id,
    37                             unsigned int        register_id,
    38                             unsigned int*       buffer);
    39 
    40 unsigned int _icu_write(    unsigned int        cluster_id,
    41                             unsigned int        proc_id,
    42                             unsigned int        register_id,
    43                             unsigned int        value);
    44 
    45 unsigned int _icu_read(     unsigned int        cluster_id,
    46                             unsigned int        proc_id,
    47                             unsigned int        register_id,
    48                             unsigned int*       buffer);
    4936
    5037unsigned int _tty_write(    const char*         buffer,
     
    5643unsigned int _tty_read_irq( char*                       buffer,
    5744                            unsigned int        length);
     45
     46///////////////////////////////////////////////////////////////////////////////////
     47// ICU access functions (both vci_multi_icu and vci_xicu)
     48///////////////////////////////////////////////////////////////////////////////////
     49
     50unsigned int _icu_read(     unsigned int        cluster_id,
     51                            unsigned int        proc_id,
     52                            unsigned int        register_id,
     53                            unsigned int*       buffer);
     54
     55unsigned int _icu_write(        unsigned int    cluster_id,
     56                                                        unsigned int    proc_id,
     57                                                        unsigned int    register_id,
     58                                                        unsigned int    value );
     59
     60///////////////////////////////////////////////////////////////////////////////////
     61// IOC access functions and variables (vci_block_device)
     62///////////////////////////////////////////////////////////////////////////////////
     63
     64extern volatile unsigned int    _ioc_status;
     65extern volatile unsigned int    _ioc_done;
     66extern unsigned int                             _ioc_lock;
     67extern unsigned int                             _ioc_iommu_ix1;
     68extern unsigned int                             _ioc_iommu_npages;
     69
    5870
    5971unsigned int _ioc_write(    unsigned int        lba,
     
    6779unsigned int _ioc_completed();
    6880
    69 unsigned int _gcd_write(    unsigned int        register_index,
    70                             unsigned int        value);
     81///////////////////////////////////////////////////////////////////////////////////
     82// Multi DMA variables                  (vci_multi_dma)
     83///////////////////////////////////////////////////////////////////////////////////
     84 
     85extern volatile unsigned int    _dma_status[];
     86extern volatile unsigned int    _dma_done[];
     87extern unsigned int                             _dma_lock[];
     88extern unsigned int                             _dma_iommu_ix1;
     89extern unsigned int                             _dma_iommu_npages[];
    7190
    72 unsigned int _gcd_read(     unsigned int        register_index,
    73                             unsigned int*       buffer);
    74 
     91///////////////////////////////////////////////////////////////////////////////////
     92// Frame Buffer access functions  (vci_frame_buffer)
     93///////////////////////////////////////////////////////////////////////////////////
     94 
    7595unsigned int _fb_sync_write(unsigned int        offset,
    7696                            const void*         buffer,
     
    91111unsigned int _fb_completed();
    92112
     113///////////////////////////////////////////////////////////////////////////////////
     114// GCD access functions
     115///////////////////////////////////////////////////////////////////////////////////
     116
     117unsigned int _gcd_write(    unsigned int        register_index,
     118                            unsigned int        value);
     119
     120unsigned int _gcd_read(     unsigned int        register_index,
     121                            unsigned int*       buffer);
     122
     123
    93124#endif
    94125
  • soft/giet_vm/sys/exc_handler.c

    r158 r189  
    3232
    3333///////////////////////////////////////////////////////////////////////////////////
    34 // Initialize the exception vector according to CR code
     34// Initialize the exception vector indexed by the CR XCODE field
    3535///////////////////////////////////////////////////////////////////////////////////
    3636const _exc_func_t _cause_vector[16] = {
     
    6767static void _cause(unsigned int msg_cause)
    6868{
    69     unsigned int        epc;
    70     unsigned int        bar;
    71     unsigned int        cause;
    72 
    73     asm volatile("mfc0 %0, $14" : "=r"(epc));
    74     asm volatile("mfc0 %0, $8 " : "=r"(bar));
    75     asm volatile("mfc0 %0, $13" : "=r"(cause));
    76 
    7769    _puts( (char*)(exc_message_causes[msg_cause]) );
    78     _puts("\nEPC   = ");
    79     _putw( epc );
    80     _puts("\nBAR   = ");
    81     _putw( bar );
    82     _puts("\nCAUSE = ");
    83     _putw( cause );
     70    _puts("\n - Cycle     : ");
     71    _putd( _proctime() );
     72    _puts("\n - Processor : ");
     73    _putd( _procid() );
     74    _puts("\n - Task      : ");
     75    _putd( _get_current_task_id() );
     76    _puts("\n - EPC       : ");
     77    _putw( _get_epc() );
     78    _puts("\n - BVAR      : ");
     79    _putw( _get_bvar() );
    8480    _puts("\n");
    85 
    8681    _exit();
    8782}
  • soft/giet_vm/sys/giet.s

    r165 r189  
    126126    sw      $27,    22*4($29)       /* save EPC */
    127127
    128     la      $26,    _int_demux
     128    la      $26,    _irq_demux
    129129    jalr    $26                     /* jump to a C function to find the proper ISR */
    130130
  • soft/giet_vm/sys/irq_handler.c

    r169 r189  
    22// File     : irq_handler.c
    33// Date     : 01/04/2012
    4 // Author   : alain greiner and joel porquet
     4// Author   : alain greiner
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The irq_handler.c and irq_handler.h files are part of the GIET nano-kernel.
    8 // They contain the code of the _int_demux function that handle
    9 // the ICU (Interupt Controler Unit), and the various ISRs associated
    10 // to the CoCLib peripherals.
     7// The irq_handler.c and irq_handler.h files are part of the GIET-VM nano-kernel.
     8// They contain the code of the _irq_demux() function that access the XICU or
     9// ICU component (Interupt Controler Unit), and the various ISRs (Interrupt
     10// Service Routine) associated to the peripherals.
    1111///////////////////////////////////////////////////////////////////////////////////
    1212
     
    2020
    2121///////////////////////////////////////////////////////////////////////////////////
    22 // Initialize the whole interrupt vector with the default ISR
    23 ///////////////////////////////////////////////////////////////////////////////////
    24 
    25 __attribute__((section (".kdata"))) _isr_func_t _interrupt_vector[32] =
    26                                                   { [0 ... 31] = &_isr_default };
    27 
    28 ///////////////////////////////////////////////////////////////////////////////////
    29 //      _int_demux()
    30 // This functions uses an external ICU component (Interrupt Controler Unit)
    31 // that concentrates up to 32 input interrupts lines. This component
    32 // can support up to NB_PROCS output IRQ.
     22//      _irq_demux()
     23// This function uses the ICU or XICU component (Interrupt Controler Unit)
     24// to get the interrupt vector entry. There is one ICU or XICU component per
     25// cluster, and this component can support up to NB_PROCS_MAX output IRQs.
     26// It returns the highest priority active interrupt index (smaller
     27// indexes have the highest priority).
     28// Any value larger than 31 means "no active interrupt", and no ISR is executed.
    3329//
    34 // This component returns the highest priority active interrupt index (smaller
    35 // indexes have the highest priority) by reading the ICU_IT_VECTOR register.
    36 // Any value larger than 31 means "no active interrupt", and the default ISR
    37 // (that does nothing) is executed.
     30// There is one interrupt vector per processor (stored in the scheduler associated
     31// to the processor. Each interrupt vector entry contains two 16 bits fields:
     32// - isr_id : defines the type of ISR to be executed.
     33// - channel_id : defines the specific channel for multi-channels peripherals.
    3834//
    39 // The interrupt vector (32 ISR addresses array stored at _interrupt_vector
    40 // address) is initialised with the default ISR address. The actual ISR
    41 // addresses are supposed to be written in the interrupt vector array
    42 // during system initialisation.
    43 ///////////////////////////////////////////////////////////////////////////////////
    44 void _int_demux(void)
    45 {
    46     int                         interrupt_index;
    47     _isr_func_t         isr;
    48     unsigned int        pid = _procid();
    49 
    50     // retrieves the highest priority active interrupt index
    51     if (!_icu_read( pid / NB_PROCS,
    52                     pid % NB_PROCS,
     35// If the peripheral is replicated in clusters (TIMER or DMA), the channel_id is
     36// a global index : channel_id = cluster_id * NB_CHANNELS_MAX + loc_id   
     37///////////////////////////////////////////////////////////////////////////////////
     38void _irq_demux()
     39{
     40    unsigned int    pid = _procid();
     41    unsigned int        irq_id;
     42
     43    // get the highest priority active IRQ index
     44
     45#if GIET_USE_XICU
     46
     47#else
     48
     49    if ( _icu_read( pid / NB_PROCS_MAX,
     50                    pid % NB_PROCS_MAX,
    5351                    ICU_IT_VECTOR,
    54                     (unsigned int*)&interrupt_index ) )
     52                    &irq_id ) )
    5553    {
    56         if (interrupt_index == -1)      // no interrupt is active
    57             return;
    58 
    59         isr = _interrupt_vector[interrupt_index];
    60         isr();
    61     }
    62     else
    63     {
    64         _puts("\n[GIET ERROR] In _demux function : wrong arguments in _icu_read()\n");
     54        _puts("\n[GIET ERROR] wrong _icu_read in _irq_demux() function\n");
    6555        _exit();
    6656    }
     57
     58#endif
     59
     60    if ( irq_id < 32 )  // do nothing if no interrupt active
     61    {
     62        unsigned int entry      = _get_interrupt_vector_entry(irq_id);
     63        unsigned int isr_id     = entry & 0x000000FF;
     64        unsigned int channel_id = (entry>>16) & 0x0000FFFF;
     65        if      ( isr_id == ISR_SWITCH  ) _isr_switch();
     66        else if ( isr_id == ISR_IOC     ) _isr_ioc();
     67        else if ( isr_id == ISR_DMA     ) _isr_dma( channel_id );
     68        else if ( isr_id == ISR_TTY     ) _isr_tty( channel_id );
     69        else if ( isr_id == ISR_TIMER   ) _isr_timer( channel_id );
     70        else                              _isr_default();
     71    }
    6772}
    6873///////////////////////////////////////////////////////////////////////////////////
    6974//      _isr_default()
    7075// The default ISR is called when no specific ISR has been installed in the
    71 // interrupt vector. It simply displays a message on TTY0.
     76// interrupt vector. It simply displays a message on kernel TTY[0].
    7277///////////////////////////////////////////////////////////////////////////////////
    7378void _isr_default()
    7479{
    75     _puts("\n\n!!! Default ISR !!!\n");
     80    _puts("\n\n!!! Strange... Default ISR activated !!!\n");
    7681}
    7782
    7883///////////////////////////////////////////////////////////////////////////////////
    7984//      _isr_dma()
    80 // This ISR handles up to 8 IRQs generated by 8 independant channels of the
    81 // multi_dma component. It acknowledges the interrupt and reset the synchronisation
    82 // variable _dma_busy[i], after copying the status into the _dma_status[i] variable.
    83 ///////////////////////////////////////////////////////////////////////////////////
    84 void _isr_dma_indexed( unsigned int dma_id )
    85 {
    86     volatile unsigned int* dma_address;
     85// This ISR handles all IRQs generated by the multi-channels DMA controlers.
     86// The multi_dma components can be distributed in the clusters.
     87// The channel_id argument is the global DMA channel index.
     88//     channel_id = cluster_id*NB_DMAS_MAX + loc_id
     89// - The ISR saves the transfert status in _dma_status[channel_id].
     90// - It acknowledges the interrupt to reinitialize the DMA controler.
     91// - it resets the synchronisation variable _dma_busy[channel_id].
     92///////////////////////////////////////////////////////////////////////////////////
     93void _isr_dma( unsigned int channel_id )
     94{
     95    // compute cluster_id and loc_id
     96    unsigned int cluster_id = channel_id / NB_DMAS_MAX;
     97    unsigned int loc_id     = channel_id % NB_DMAS_MAX;
    8798
    8899    // compute DMA channel address
    89     dma_address = (unsigned int*)&seg_dma_base + (dma_id * DMA_SPAN);
     100    unsigned int*       dma_address = (unsigned int*)&seg_dma_base +
     101                                  (loc_id * DMA_SPAN) +
     102                                  (cluster_id * CLUSTER_SPAN);
    90103
    91104    // save DMA channel status 
    92     _dma_status[dma_id] = dma_address[DMA_LEN]; /* save status */
     105    _dma_status[channel_id] = dma_address[DMA_LEN];
    93106
    94107    // reset DMA channel
    95     dma_address[DMA_RESET] = 0;                                 /* reset IRQ */
     108    dma_address[DMA_RESET] = 0;                 
    96109
    97110    // release DMA channel
    98     _dma_busy[dma_id] = 0;                      /* release DMA */
    99 }
    100 
    101 void _isr_dma_0() { _isr_dma_indexed(0); }
    102 void _isr_dma_1() { _isr_dma_indexed(1); }
    103 void _isr_dma_2() { _isr_dma_indexed(2); }
    104 void _isr_dma_3() { _isr_dma_indexed(3); }
    105 void _isr_dma_4() { _isr_dma_indexed(4); }
    106 void _isr_dma_5() { _isr_dma_indexed(5); }
    107 void _isr_dma_6() { _isr_dma_indexed(6); }
    108 void _isr_dma_7() { _isr_dma_indexed(7); }
     111    _dma_done[channel_id] = 1; 
     112}
    109113
    110114///////////////////////////////////////////////////////////////////////////////////
    111115//      _isr_ioc()
    112 // There is only one IOC controler shared by all tasks. It acknowledge the IRQ
    113 // using the ioc base address, save the status, and set the _ioc_done variable
    114 // to signal completion.
     116// There is only one IOC controler shared by all tasks.
     117// - The ISR save the status and acknowledge the IRQ.
     118// - It sets the _ioc_done variable to signal completion.
    115119///////////////////////////////////////////////////////////////////////////////////
    116120void _isr_ioc()
    117121{
    118     volatile unsigned int* ioc_address;
    119 
    120     ioc_address = (unsigned int*)&seg_ioc_base;
     122    unsigned int* ioc_address = (unsigned int*)&seg_ioc_base;
    121123
    122124    _ioc_status = ioc_address[BLOCK_DEVICE_STATUS]; /* save status & reset IRQ */
     
    125127
    126128///////////////////////////////////////////////////////////////////////////////////
    127 //      _isr_timer_* (* = 0,1,2,3,4,5,6,7)
    128 // This ISR handles up to 8 IRQs generated by 8 independant timers.
    129 // It acknowledges the IRQ on TIMER[*] and displays a message on TTY0
    130 ///////////////////////////////////////////////////////////////////////////////////
    131 void _isr_timer_indexed(unsigned int timer_id)
    132 {
    133     volatile unsigned int *timer_address;
    134 
    135     timer_address = (unsigned int*)&seg_timer_base + (timer_id * TIMER_SPAN);
    136 
    137     timer_address[TIMER_RESETIRQ] = 0; /* reset IRQ */
    138 
    139     _puts("\n\n!!! Interrupt timer received from timer ");
    140     _putw( timer_id );
    141     _puts(" at cycle ");
    142     _putw( _proctime() );
    143     _puts("\n\n");
    144 }
    145 
    146 void _isr_timer_0()  { _isr_timer_indexed(0);  }
    147 void _isr_timer_1()  { _isr_timer_indexed(1);  }
    148 void _isr_timer_2()  { _isr_timer_indexed(2);  }
    149 void _isr_timer_3()  { _isr_timer_indexed(3);  }
    150 void _isr_timer_4()  { _isr_timer_indexed(4);  }
    151 void _isr_timer_5()  { _isr_timer_indexed(5);  }
    152 void _isr_timer_6()  { _isr_timer_indexed(6);  }
    153 void _isr_timer_7()  { _isr_timer_indexed(7);  }
    154 
    155 ///////////////////////////////////////////////////////////////////////////////////
    156 // _isr_tty_get_* (* = 0,1,2,3,4,5,6,7,9,10,11,12,13,14,15)
    157 // The Giet supports up to 16 TTY terminals.
    158 // These 16 ISRs handle the up to 16 IRQs associated to 16 independant
    159 // terminals, signaling that a character is available.
    160 // There is one communication buffer _tty_get_buf[tty_id] per terminal.
    161 // The sychronisation variable _tty_get_full[tty_id], is set by the ISR,
     129//         _isr_timer()
     130// This ISR handles the IRQs generated by the "user" timers (the IRQs
     131// generated by the "system" timers should be handled by the _isr_switch().
     132// These timers are distributed in all clusters, and can be implemented
     133// in a vci_multi_timer component, or in a vci_xicu component.
     134// The channel_id argument is the global channel index:
     135//     channel_id = cluster_id*(NB_TIMERS_MAX+NB_PROCS_MAX) + loc_id
     136// The user timer local index is (loc_id - NB_PROCS_MAX).
     137//
     138// The ISR acknowledges the IRQ and registers the event in the proper entry
     139// of the _timer_event[] array.
     140// A log message is displayed on the kernel terminal.
     141///////////////////////////////////////////////////////////////////////////////////
     142void _isr_timer(unsigned int channel_id)
     143{
     144
     145    unsigned int cluster_id = channel_id / (NB_TIMERS_MAX + NB_PROCS_MAX);
     146    unsigned int loc_id     = channel_id % (NB_TIMERS_MAX + NB_PROCS_MAX);
     147
     148    if (loc_id < NB_PROCS_MAX )
     149    {
     150        _puts("[GIET ERROR] Receiving a user timer IRQ for a system timer\n");
     151        _puts("             cluster = ");
     152        _putw(cluster_id);
     153        _puts(" / local_id = ");
     154        _putw(loc_id);
     155    }
     156
     157#if GIET_USE_XICU
     158
     159// TODO
     160
     161#else
     162
     163    // compute Timer address
     164    unsigned int* timer_address = (unsigned int*)&seg_timer_base +
     165                                  (loc_id * TIMER_SPAN) +
     166                                  (cluster_id * CLUSTER_SPAN);
     167
     168    // reset IRQ
     169    timer_address[TIMER_RESETIRQ] = 0;
     170
     171#endif
     172
     173#if NB_TIMERS_MAX
     174    // register the event
     175    _timer_event[(cluster_id*NB_TIMERS_MAX) + (loc_id - NB_PROCS_MAX)] = 1;
     176#endif
     177
     178    // display a message on TTY 0
     179    _puts("[GIET] User Timer IRQ / cluster = ");
     180    _putw(cluster_id);
     181    _puts(" / timer = ");
     182    _putw(loc_id - NB_PROCS_MAX);
     183    _puts("\n");
     184}
     185
     186///////////////////////////////////////////////////////////////////////////////////
     187//  _isr_tty()
     188// This ISR handles the IRQs generated by the multi_tty controler,
     189// signaling that a character is available.
     190// There is one single multi_tty component controling all TTYs, and the tty_id
     191// argument is the global TTY index.
     192// There is one communication buffer _tty_buf[tty_id] per terminal.
     193// The sychronisation variable _tty_full[tty_id], is set by the ISR,
    162194// and reset by the OS.
    163195// A character is lost if the buffer is full when the ISR is executed.
    164196///////////////////////////////////////////////////////////////////////////////////
    165 void _isr_tty_get_indexed(unsigned int tty_id)
    166 {
    167     volatile unsigned int *tty_address;
    168 
    169     /* compute terminal base address */
    170     tty_address = (unsigned int*)&seg_tty_base + (tty_id * TTY_SPAN);
    171 
    172     /* save character and reset IRQ */
     197void _isr_tty(unsigned int tty_id)
     198{
     199    // compute terminal base address
     200    unsigned int *tty_address = (unsigned int*)&seg_tty_base + (tty_id * TTY_SPAN);
     201
     202    // save character and reset IRQ
    173203    _tty_get_buf[tty_id] = (unsigned char)tty_address[TTY_READ];
    174204
    175     /* signals character available */
     205    // signals character available
    176206    _tty_get_full[tty_id] = 1;
    177207}
    178 
    179 void _isr_tty_get_0()  { _isr_tty_get_indexed(0);  }
    180 void _isr_tty_get_1()  { _isr_tty_get_indexed(1);  }
    181 void _isr_tty_get_2()  { _isr_tty_get_indexed(2);  }
    182 void _isr_tty_get_3()  { _isr_tty_get_indexed(3);  }
    183 void _isr_tty_get_4()  { _isr_tty_get_indexed(4);  }
    184 void _isr_tty_get_5()  { _isr_tty_get_indexed(5);  }
    185 void _isr_tty_get_6()  { _isr_tty_get_indexed(6);  }
    186 void _isr_tty_get_7()  { _isr_tty_get_indexed(7);  }
    187 void _isr_tty_get_8()  { _isr_tty_get_indexed(8);  }
    188 void _isr_tty_get_9()  { _isr_tty_get_indexed(9);  }
    189 void _isr_tty_get_10() { _isr_tty_get_indexed(10); }
    190 void _isr_tty_get_11() { _isr_tty_get_indexed(11); }
    191 void _isr_tty_get_12() { _isr_tty_get_indexed(12); }
    192 void _isr_tty_get_13() { _isr_tty_get_indexed(13); }
    193 void _isr_tty_get_14() { _isr_tty_get_indexed(14); }
    194 void _isr_tty_get_15() { _isr_tty_get_indexed(15); }
    195208
    196209/////////////////////////////////////////////////////////////////////////////////////
    197210// _isr_switch
    198 // This ISR is in charge of context switch.
    199 // It acknowledges the IRQ on TIMER[proc_id] and calls the _ctx_switch() function.
     211// This ISR is in charge of context switch, and handle the IRQs generated by
     212// the "system" timers.
     213// The IRQs can be generated by the MULTI_TIMER component or by the XICU component,
     214// that are distributed in all clusters.
     215// The ISR acknowledges the IRQ and calls the _ctx_switch() function.
    200216/////////////////////////////////////////////////////////////////////////////////////
    201217void _isr_switch()
    202218{
    203     volatile unsigned int *timer_address;
    204     unsigned int proc_id;
    205 
    206     proc_id = _procid();
    207     timer_address = (unsigned int*)&seg_timer_base + (proc_id * TIMER_SPAN);
    208 
    209     timer_address[TIMER_RESETIRQ] = 0; /* reset IRQ */
     219    // get cluster index and proc local index
     220    unsigned int pid        = _procid();
     221    unsigned int loc_id     = pid % NB_PROCS_MAX;
     222    unsigned int cluster_id = pid / NB_PROCS_MAX;
     223
     224#if GIET_USE_XICU
     225
     226    unsigned int* timer_address = // TODO
     227
     228#else
     229
     230    // compute Timer address
     231    unsigned int* timer_address = (unsigned int*)&seg_timer_base +
     232                                  (loc_id * TIMER_SPAN) +
     233                                  (cluster_id * CLUSTER_SPAN);
     234
     235    // reset IRQ
     236    timer_address[TIMER_RESETIRQ] = 0;
     237
     238#endif
     239
     240    // performs the context switch
    210241    _ctx_switch();
    211 }
    212 
     242
     243}
     244
  • soft/giet_vm/sys/irq_handler.h

    r165 r189  
    22#define _IRQ_HANDLER_H
    33
    4 /*
    5  * Interrupt Vector Table (indexed by interrupt index)
    6  *
    7  * 32 entries corresponding to 32 ISR addresses
    8  */
     4enum
     5{
     6    ISR_DEFAULT = 0,
     7    ISR_SWITCH  = 1,
     8    ISR_TTY     = 2,
     9    ISR_DMA     = 3,
     10    ISR_IOC     = 4,
     11    ISR_TIMER   = 5,
     12};
    913
    10 typedef void (*_isr_func_t)(void);
    11 extern _isr_func_t _interrupt_vector[32];
    1214
    13 /*
    14  * Prototypes of the Interrupt Service Routines (ISRs) supported by the GIET.
    15  * - they must be installed in reset.s
    16  */
     15///////////////////////////////////////////////////////////////////////////////
     16// Prototypes of the Interrupt Service Routines (ISRs) supported by the GIET.
     17///////////////////////////////////////////////////////////////////////////////
     18
     19void _irq_demux();
    1720
    1821void _isr_default();
    19 
    20 void _isr_dma_0();
    21 void _isr_dma_1();
    22 void _isr_dma_2();
    23 void _isr_dma_3();
    24 void _isr_dma_4();
    25 void _isr_dma_5();
    26 void _isr_dma_6();
    27 void _isr_dma_7();
    28 
    2922void _isr_ioc();
    30 
    31 void _isr_timer_0();
    32 void _isr_timer_1();
    33 void _isr_timer_2();
    34 void _isr_timer_3();
    35 void _isr_timer_4();
    36 void _isr_timer_5();
    37 void _isr_timer_6();
    38 void _isr_timer_7();
    39 
    40 void _isr_tty_get();
    41 void _isr_tty_get_0();
    42 void _isr_tty_get_1();
    43 void _isr_tty_get_2();
    44 void _isr_tty_get_3();
    45 void _isr_tty_get_4();
    46 void _isr_tty_get_5();
    47 void _isr_tty_get_6();
    48 void _isr_tty_get_7();
    49 void _isr_tty_get_8();
    50 void _isr_tty_get_9();
    51 void _isr_tty_get_10();
    52 void _isr_tty_get_11();
    53 void _isr_tty_get_12();
    54 void _isr_tty_get_13();
    55 void _isr_tty_get_14();
    56 void _isr_tty_get_15();
    57 
     23void _isr_timer( unsigned int channel );
     24void _isr_dma( unsigned int channel );
     25void _isr_tty( unsigned int channel );
    5826void _isr_switch();
    5927
  • soft/giet_vm/sys/kernel_init.c

    r185 r189  
    55// Copyright (c) UPMC-LIP6
    66////////////////////////////////////////////////////////////////////////////////////
    7 // FIXME
    87// The kernel_init.c files is part of the GIET-VM nano-kernel.
    9 // It contains the kernel entry point for the second phase of system initialisation:
    10 // all processors are jumping to _kernel_init, but P[0] is first because other
    11 // processors are blocked until P[0] complete initilisation of task contexts,
    12 // vobjs and peripherals.
    13 // All procs in this phase have their MMU activated, because each processor P[i]
    14 // must initialise registers SP, SR, PTPR and EPC with informations stored
    15 // in _scheduler[i].
     8// It contains the kernel entry point for the last step of system initialisation.
     9// All procs in this phase have their MMU activated, and are running in parallel.
     10// - each processor updates its own scheduler, to replace the ISR index
     11//   by the actual ISR virtual address, and set its own entry in the
     12//   kernel _schedulers_paddr[] array.
     13// - each processor initialises the SP, SR, PTPR, EPC registers, and starts
     14//   its private Timer, before jumping to the user code with an eret.
    1615////////////////////////////////////////////////////////////////////////////////////
    1716
    1817#include <common.h>
     18#include <irq_handler.h>
    1919#include <ctx_handler.h>
    2020#include <sys_handler.h>
     
    2929#include <drivers.h>
    3030
    31 #define in_kinit __attribute__((section (".kinit")))
    32  
    3331///////////////////////////////////////////////////////////////////////////////////
    34 // array of pointers on the page tables
    35 // (both physical and virtual addresses)
     32// Kernel Global variables
    3633///////////////////////////////////////////////////////////////////////////////////
    3734
    38 __attribute__((section (".kdata"))) unsigned int _kernel_ptabs_paddr[GIET_NB_VSPACE_MAX];
    39 __attribute__((section (".kdata"))) unsigned int _kernel_ptabs_vaddr[GIET_NB_VSPACE_MAX];
     35__attribute__((section (".kdata")))
     36page_table_t* _ptabs_paddr[GIET_NB_VSPACE_MAX];
    4037
    41 ///////////////////////////////////////////////////////////////////////////////////
    42 // declarations required to avoid forward references
    43 ///////////////////////////////////////////////////////////////////////////////////
     38__attribute__((section (".kdata")))
     39page_table_t* _ptabs_vaddr[GIET_NB_VSPACE_MAX];
    4440
    45 void    _kernel_ptabs_init(void);
    46 void    _kernel_vobjs_init(void);
    47 void    _kernel_tasks_init(void);
    48 void    _kernel_peripherals_init(void);
    49 void    _kernel_interrupt_vector_init(void);
    50 void    _kernel_start_all_procs(void);
     41__attribute__((section (".kdata")))
     42static_scheduler_t*     _schedulers_paddr[NB_CLUSTERS*NB_PROCS_MAX];
    5143
    5244//////////////////////////////////////////////////////////////////////////////////
    53 // This function is the entry point for the second step of the boot sequence.
     45// This function is the entry point for the last step of the boot sequence.
    5446//////////////////////////////////////////////////////////////////////////////////
    55 in_kinit void _kernel_init()
     47__attribute__((section (".kinit"))) void _kernel_init()
    5648{
    5749    // values to be written in registers
     
    6153    unsigned int        epc_value;
    6254
    63     unsigned int        pid =   _procid();
     55    unsigned int        proc_id    = _procid();
     56    unsigned int    cluster_id = proc_id / NB_PROCS_MAX;
     57    unsigned int    lpid       = proc_id % NB_PROCS_MAX;
    6458
    65     // only processor 0 executes system initialisation
    66     if ( pid == 0 )
     59    // step 1 : Initialise scheduler physical addresses array
     60
     61    // get scheduler physical address from register
     62    static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
     63    _schedulers_paddr[proc_id]     = psched;
     64
     65#if GIET_DEBUG_INIT
     66_get_lock(&_tty_put_lock);
     67_puts("\n[GIET DEBUG] step 1 for processor ");
     68_putw( proc_id );
     69_puts("\n");
     70_puts("- scheduler pbase = ");
     71_putw( (unsigned int)psched );
     72_puts("\n");
     73_release_lock(&_tty_put_lock);
     74#endif
     75
     76    // step 2 : compute and set ICU mask
     77    unsigned int irq_id;
     78    unsigned int mask = 0;
     79    for ( irq_id = 0 ; irq_id < 32 ; irq_id++ )
    6780    {
    68         _kernel_ptabs_init();
    69         /* must be called after the initialisation of ptabs */
    70         _kernel_vobjs_init();
    71         _kernel_tasks_init();
    72         _kernel_interrupt_vector_init();
    73         _kernel_peripherals_init();
    74         _kernel_start_all_procs();
     81        unsigned int entry   = _get_interrupt_vector_entry(irq_id);
     82        if ( entry ) mask = mask | 0x1<< irq_id;
    7583    }
     84    _icu_write( cluster_id,
     85                lpid,
     86                ICU_MASK_SET,
     87                mask );
     88   
     89#if GIET_DEBUG_INIT
     90_get_lock(&_tty_put_lock);
     91_puts("\n[GIET DEBUG] step 2 for processor ");
     92_putw( proc_id );
     93_puts("\n");
     94_puts("- ICU mask = ");
     95_putw( mask );
     96_puts("\n");
     97_release_lock(&_tty_put_lock);
     98#endif
    7699
    77     // each processor initialises it's SP, SR, PTPR, and EPC registers
    78     // from values defined in _scheduler[pid], starts it's private
    79     // context switch timer (if there is more than one task allocated)
    80     // and jumps to user code.
    81     // It does nothing, and keep idle if no task allocated.
    82100
    83     static_scheduler_t*  sched = &_scheduler[pid];
     101    // step 3 : TODO initialise page table addresse arrays
    84102
    85     if ( sched->tasks )         // at leat one task allocated
     103
     104    // step 4 : start TICK timer if more than one task
     105    unsigned int tasks = _get_tasks_number();
     106    if ( tasks > 1 )
     107    {
     108        unsigned int period     = GIET_TICK_VALUE;
     109        unsigned int mode       = 0x3;
     110        _timer_access( 0,                       // write access
     111                       cluster_id,
     112                       proc_id,
     113                       TIMER_PERIOD,
     114                       &period );
     115        _timer_access( 0,                       // write access
     116                       cluster_id,
     117                       proc_id,
     118                       TIMER_MODE,
     119                       &mode );
     120       
     121#if GIET_DEBUG_INIT
     122_get_lock(&_tty_put_lock);
     123_puts("\n[GIET DEBUG] Step 4 for processor ");
     124_putw( proc_id );
     125_puts("\n");
     126_puts("- TICK period = ");
     127_putd( period );
     128_puts("\n");
     129_release_lock(&_tty_put_lock);
     130#endif
     131   
     132    }
     133
     134    // step 5 : each processor initialises SP, SR, PTPR, EPC, registers
     135    //          with the values corresponding to the first allocated task,
     136    //          It does nothing, and keep idle if no task allocated.
     137
     138    if ( tasks )                // at leat one task allocated
    86139    {
    87140        // initialise registers
    88         sp_value   = sched->context[0][CTX_SP_ID];
    89         sr_value   = sched->context[0][CTX_SR_ID];
    90         ptpr_value = sched->context[0][CTX_PTPR_ID];
    91         epc_value  = sched->context[0][CTX_EPC_ID];
     141        sp_value   = _get_current_context_slot(CTX_SP_ID);
     142        sr_value   = _get_current_context_slot(CTX_SR_ID);
     143        ptpr_value = _get_current_context_slot(CTX_PTPR_ID);
     144        epc_value  = _get_current_context_slot(CTX_EPC_ID);
    92145
    93         // start TICK timer
    94         if ( sched->tasks > 1 )
    95         {
    96             unsigned int cluster_id = pid / NB_PROCS;
    97             unsigned int proc_id    = pid % NB_PROCS;
    98            _timer_write( cluster_id, proc_id, TIMER_PERIOD, GIET_TICK_VALUE );
    99            _timer_write( cluster_id, proc_id, TIMER_MODE  , 0x3 );
    100         }
     146#if GIET_DEBUG_INIT
     147_get_lock(&_tty_put_lock);
     148_puts("\n[GIET DEBUG] step 5 for processor ");
     149_putw( proc_id );
     150_puts("\n");
     151_puts("- sp   = ");
     152_putw( sp_value );
     153_puts("\n");
     154_puts("- sr   = ");
     155_putw( sr_value );
     156_puts("\n");
     157_puts("- ptpr = ");
     158_putw( ptpr_value<<13 );
     159_puts("\n");
     160_puts("- epc  = ");
     161_putw( epc_value );
     162_puts("\n");
     163_release_lock(&_tty_put_lock);
     164#endif
    101165    }
    102166    else                                        // no task allocated
     
    104168        _get_lock( &_tty_put_lock );
    105169        _puts("\n No task allocated to processor ");
    106         _putw( pid );
     170        _putw( proc_id );
    107171        _puts(" => keep idle\n");
    108172        _release_lock ( &_tty_put_lock );
     
    117181    }
    118182
     183    // set critical registers and jump to user code
    119184    asm volatile (
    120185       "move    $29,    %0              \n"             /* SP <= ctx[CTX_SP_ID] */
     
    128193
    129194} // end _kernel_init()
    130 
    131 //////////////////////////////////////////////////////////////////////////////////
    132 // This function wakeup all processors.
    133 // It should be executed by P[0] when the kernel initialisation is done.
    134 //////////////////////////////////////////////////////////////////////////////////
    135 in_kinit void _kernel_start_all_procs()
    136 {
    137     mapping_header_t*   header = (mapping_header_t*)&seg_mapping_base; 
    138 
    139     _puts("\n[INIT] Starting parallel execution at cycle : ");
    140     _putw( _proctime() );
    141     _puts("\n");
    142 
    143     header->signature = OUT_MAPPING_SIGNATURE;
    144 }
    145 
    146 //////////////////////////////////////////////////////////////////////////////////
    147 // _eret()
    148 // The address of this function is used to initialise the return address (RA)
    149 // in all task contexts (when the task has never been executed.
    150 //////////////////////////////////////////////////////////////////////////////////
    151 in_kinit void _eret()
    152 {
    153     asm volatile("eret \n"
    154                  "nop");
    155 }
    156 
    157 ///////////////////////////////////////////////////////////////////////////////
    158 // used to access user space
    159 ///////////////////////////////////////////////////////////////////////////////
    160 void _set_ptpr(unsigned int vspace_id)
    161 {
    162         unsigned int ptpr = ((unsigned int)_kernel_ptabs_paddr[vspace_id]) >> 13;
    163         asm volatile("mtc2 %0, $0"::"r"(ptpr));
    164 }
    165 
    166 ///////////////////////////////////////////////////////////////////////////////
    167 // This function initialises the _kernel_ptabs_paddr[] array indexed by the vspace_id,
    168 // and containing the base addresses of all page tables.
    169 // This _kernel_ptabs_paddr[] array is used to initialise the task contexts.
    170 ///////////////////////////////////////////////////////////////////////////////
    171 in_kinit void _kernel_ptabs_init()
    172 {
    173     mapping_header_t*   header  = (mapping_header_t*)&seg_mapping_base; 
    174     mapping_vspace_t*   vspace  = _get_vspace_base( header );     
    175     mapping_vobj_t*     vobj    = _get_vobj_base( header );
    176 
    177     unsigned int        vspace_id; 
    178     unsigned int        vobj_id;
    179 
    180     // loop on the vspaces
    181     for ( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )
    182     {
    183         char ptab_found = 0;
    184 
    185 #if INIT_DEBUG_CTX
    186 _puts("[INIT] --- ptabs initialisation in vspace ");
    187 _puts(vspace[vspace_id].name);
    188 _puts("\n");
    189 #endif
    190         // loop on the vobjs and get the ptpr
    191             for(vobj_id= vspace[vspace_id].vobj_offset;
    192                         vobj_id < (vspace[vspace_id].vobj_offset+ vspace[vspace_id].vobjs);
    193                         vobj_id++)
    194             {
    195             if(vobj[vobj_id].type == VOBJ_TYPE_PTAB)
    196             {
    197                 if( ptab_found )
    198                 {
    199                     _puts("\n[INIT ERROR] Only one PTAB for by vspace ");
    200                     _putw( vspace_id );
    201                     _exit();
    202                 }
    203 
    204                 ptab_found = 1;
    205                 _kernel_ptabs_paddr[vspace_id] = vobj[vobj_id].paddr;
    206                 _kernel_ptabs_vaddr[vspace_id] = vobj[vobj_id].vaddr;
    207 
    208 #if INIT_DEBUG_CTX
    209 _puts("[INIT]   PTAB address = ");
    210 _putw(_kernel_ptabs_paddr[vspace_id]);
    211 _puts("\n");
    212 #endif
    213             }
    214 
    215         }
    216 
    217         if( !ptab_found )
    218         {
    219             _puts("\n[INIT ERROR] Missing PTAB for vspace ");
    220             _putw( vspace_id );
    221             _exit();
    222         }
    223     }
    224        
    225     _puts("\n[INIT] Ptabs initialisation completed at cycle : ");
    226     _putw( _proctime() );
    227     _puts("\n");
    228 
    229 } // end kernel_ptabs_init()
    230 
    231 ///////////////////////////////////////////////////////////////////////////////
    232 // This function initializes all private vobjs defined in the vspaces,
    233 // such as mwmr channels, barriers and locks, depending on the vobj type.
    234 // (Most of the vobjs are not known, and not initialised by the compiler).
    235 ///////////////////////////////////////////////////////////////////////////////
    236 in_kinit void _kernel_vobjs_init()
    237 {
    238     mapping_header_t*   header  = (mapping_header_t*)&seg_mapping_base; 
    239     mapping_vspace_t*   vspace  = _get_vspace_base( header );     
    240     mapping_vobj_t*     vobj    = _get_vobj_base( header );
    241 
    242     unsigned int        vspace_id; 
    243     unsigned int        vobj_id;
    244 
    245     // loop on the vspaces
    246     for ( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )
    247     {
    248 
    249 #if INIT_DEBUG_CTX
    250 _puts("[INIT] --- vobjs initialisation in vspace ");
    251 _puts(vspace[vspace_id].name);
    252 _puts("\n");
    253 #endif
    254         /** Set the current vspace ptpr to initialise the vobjs */
    255                 _set_ptpr(vspace_id);
    256 
    257         // loop on the vobjs and get the ptpr
    258             for(vobj_id= vspace[vspace_id].vobj_offset;
    259                         vobj_id < (vspace[vspace_id].vobj_offset+ vspace[vspace_id].vobjs);
    260                         vobj_id++)
    261             {
    262             switch( vobj[vobj_id].type )
    263             {
    264                 case VOBJ_TYPE_PTAB:    // initialise page table pointers array
    265                 {
    266                     break;//already handled
    267                 }
    268                 case VOBJ_TYPE_MWMR:    // storage capacity is (vobj.length/4 - 5) words
    269                         {
    270                     mwmr_channel_t* mwmr = (mwmr_channel_t*)(vobj[vobj_id].vaddr);
    271                     mwmr->ptw   = 0;
    272                     mwmr->ptr   = 0;
    273                     mwmr->sts   = 0;
    274                     mwmr->depth = ((vobj[vobj_id].length>>2) - 6);//6= number of entry in the strucure
    275                     mwmr->width = vobj[vobj_id].init;
    276                     mwmr->lock  = 0;
    277 #if INIT_DEBUG_CTX
    278 _puts("[INIT]   MWMR channel ");
    279 _puts( vobj[vobj_id].name);
    280 _puts(" / depth = ");
    281 _putw( mwmr->depth );
    282 _puts("\n");
    283 #endif
    284                     break;
    285                 }
    286                 case VOBJ_TYPE_ELF:             // initialisation done by the loader
    287                 {
    288 
    289 #if INIT_DEBUG_CTX
    290 _puts("[INIT]   ELF section ");
    291 _puts( vobj[vobj_id].name);
    292 _puts(" / length = ");
    293 _putw( vobj[vobj_id].length );
    294 _puts("\n");
    295 #endif
    296                      break;
    297                 }
    298                 case VOBJ_TYPE_BARRIER: // init is the number of participants
    299                 {
    300                     giet_barrier_t* barrier = (giet_barrier_t*)(vobj[vobj_id].vaddr);
    301                     barrier->count = 0;
    302                     barrier->init  = vobj[vobj_id].init;
    303 #if INIT_DEBUG_CTX
    304 _puts("   BARRIER ");
    305 _puts( vobj[vobj_id].name);
    306 _puts(" / init_value = ");
    307 _putw( barrier->init );
    308 _puts("\n");
    309 #endif
    310                     break;
    311                 }
    312                 case VOBJ_TYPE_LOCK:    // init is "not taken"
    313                 {
    314                     unsigned int* lock = (unsigned int*)(vobj[vobj_id].vaddr);
    315                     *lock = 0;
    316 #if INIT_DEBUG_CTX
    317 _puts("   LOCK ");
    318 _puts( vobj[vobj_id].name);
    319 _puts("\n");
    320 #endif
    321                     break;
    322                 }
    323                 case VOBJ_TYPE_BUFFER:  // nothing to do
    324                 {
    325 
    326 #if INIT_DEBUG_CTX
    327 _puts("   BUFFER ");
    328 _puts( vobj[vobj_id].name);
    329 _puts(" / length = ");
    330 _putw( vobj[vobj_id].length );
    331 _puts("\n");
    332 #endif
    333                     break;
    334                 }
    335                 default:
    336                 {
    337                     _puts("\n[INIT ERROR] illegal vobj of name ");
    338                     _puts(vobj[vobj_id].name);
    339                     _puts(" / in vspace = ");
    340                     _puts(vobj[vobj_id].name);
    341                     _puts("\n ");
    342                     _exit();
    343                 }
    344             } // end switch type
    345         } // end loop on vobjs
    346     } // end loop on vspaces
    347 
    348     _puts("\n[INIT] Vobjs initialisation completed at cycle : ");
    349     _putw( _proctime() );
    350     _puts("\n");
    351 
    352 } // end kernel_vobjs_init()
    353 
    354 ///////////////////////////////////////////////////////////////////////////////
    355 // This function maps a given task, defined in a given vspace
    356 // on the processor allocated in the mapping_info structure,
    357 // and initialises the task context.
    358 // There is one scheduler per processor, and processor can be shared
    359 // by several applications running in different vspaces.
    360 // There is one private context array handled by each scheduler.
    361 //
    362 // The following values must be initialised in all task contexts:
    363 // - sp     stack pointer = stack_base + stack_length
    364 // - ra     return address = &_eret
    365 // - epc    start address = start_vector[task->startid]
    366 // - sr     status register = OxFF13
    367 // - tty    TTY terminal index (global index)
    368 // - fb     FB_DMA channel index (global index)
    369 // - ptpr   page table base address / 8K
    370 // - mode   mmu_mode = 0xF (TLBs and caches activated)
    371 // - ptab   page table virtual address
    372 ////////////////////////////////////////////////////////////////////////////////
    373 in_kinit void _task_map( unsigned int   task_id,    // global index
    374                                          unsigned int   vspace_id,  // global index
    375                          unsigned int   tty_id,         // TTY index
    376                          unsigned int   fbdma_id )  // FBDMA index
    377 {
    378     mapping_header_t*   header = (mapping_header_t*)&seg_mapping_base; 
    379 
    380     mapping_task_t*     task   = _get_task_base(header);
    381     mapping_vspace_t*   vspace = _get_vspace_base(header);
    382     mapping_vobj_t*     vobj   = _get_vobj_base( header );
    383 
    384     /** Set the current vspace ptpr before acessing the memory */
    385     _set_ptpr(vspace_id);
    386    
    387     // values to be initialised in task context
    388     unsigned int                ra   = (unsigned int)&_eret;
    389     unsigned int                sr   = 0x0000FF13;
    390     unsigned int                tty  = tty_id;
    391     unsigned int                fb   = fbdma_id;         
    392     unsigned int                ptpr = _kernel_ptabs_paddr[vspace_id] >> 13;
    393     unsigned int                ptab = _kernel_ptabs_vaddr[vspace_id];
    394     unsigned int                mode = 0xF;
    395     unsigned int                sp;
    396     unsigned int                epc;     
    397 
    398     // EPC : Get the (virtual) base address of the start_vector containing
    399     // the start addresses for all tasks defined in a vspace.
    400     mapping_vobj_t* vobj_data = &vobj[vspace[vspace_id].vobj_offset +
    401                                       vspace[vspace_id].start_offset];
    402     unsigned int* start_vector = (unsigned int*)vobj_data->vaddr;
    403     epc  = start_vector[task[task_id].startid];
    404 
    405     // SP :  Get the vobj containing the stack
    406     unsigned int vobj_id = task[task_id].vobjlocid + vspace[vspace_id].vobj_offset;
    407     sp = vobj[vobj_id].vaddr + vobj[vobj_id].length;
    408 
    409     // compute global processor index
    410     unsigned int proc_id = task[task_id].clusterid * NB_PROCS + task[task_id].proclocid;
    411 
    412     // compute and check local task index
    413     unsigned int ltid = _scheduler[proc_id].tasks;
    414     if ( ltid >= GIET_NB_TASKS_MAX )
    415     {
    416         _puts("\n[INIT ERROR] : too much tasks allocated to processor ");
    417         _putw( proc_id );
    418         _puts("\n");
    419         _exit();
    420     }
    421    
    422     // update number of tasks allocated to scheduler
    423     _scheduler[proc_id].tasks = ltid + 1;
    424 
    425     // initializes the task context
    426     _scheduler[proc_id].context[ltid][CTX_SR_ID]    = sr;
    427     _scheduler[proc_id].context[ltid][CTX_SP_ID]    = sp;
    428     _scheduler[proc_id].context[ltid][CTX_RA_ID]    = ra;
    429     _scheduler[proc_id].context[ltid][CTX_EPC_ID]   = epc;
    430     _scheduler[proc_id].context[ltid][CTX_PTPR_ID]  = ptpr;
    431     _scheduler[proc_id].context[ltid][CTX_MODE_ID]  = mode;
    432     _scheduler[proc_id].context[ltid][CTX_TTY_ID]   = tty;
    433         _scheduler[proc_id].context[ltid][CTX_FBDMA_ID] = fb;
    434     _scheduler[proc_id].context[ltid][CTX_PTAB_ID]  = ptab;
    435     _scheduler[proc_id].context[ltid][CTX_TASK_ID]  = task_id;
    436    
    437 #if INIT_DEBUG_CTX
    438 _puts("Task ");
    439 _puts( task[task_id].name );
    440 _puts(" allocated to processor ");
    441 _putw( proc_id );
    442 _puts(" / ltid = ");
    443 _putw( ltid );
    444 _puts("\n");
    445 
    446 _puts("  - SR          = ");
    447 _putw( sr );
    448 _puts("  saved at ");
    449 _putw( (unsigned int)&_scheduler[proc_id].context[ltid][CTX_SR_ID] );
    450 _puts("\n");
    451 
    452 _puts("  - RA          = ");
    453 _putw( ra );
    454 _puts("  saved at ");
    455 _putw( (unsigned int)&_scheduler[proc_id].context[ltid][CTX_RA_ID] );
    456 _puts("\n");
    457 
    458 _puts("  - SP          = ");
    459 _putw( sp );
    460 _puts("  saved at ");
    461 _putw( (unsigned int)&_scheduler[proc_id].context[ltid][CTX_SP_ID] );
    462 _puts("\n");
    463 
    464 _puts("  - EPC         = ");
    465 _putw( epc );
    466 _puts("  saved at ");
    467 _putw( (unsigned int)&_scheduler[proc_id].context[ltid][CTX_EPC_ID] );
    468 _puts("\n");
    469 
    470 _puts("  - PTPR        = ");
    471 _putw( ptpr<<13 );
    472 _puts("  saved at ");
    473 _putw( (unsigned int)&_scheduler[proc_id].context[ltid][CTX_PTPR_ID] );
    474 _puts("\n");
    475 
    476 _puts("  - TTY         = ");
    477 _putw( tty );
    478 _puts("  saved at ");
    479 _putw( (unsigned int)&_scheduler[proc_id].context[ltid][CTX_TTY_ID] );
    480 _puts("\n");
    481 
    482 _puts("  - FB          = ");
    483 _putw( fb );
    484 _puts("  saved at ");
    485 _putw( (unsigned int)&_scheduler[proc_id].context[ltid][CTX_FBDMA_ID] );
    486 _puts("\n");
    487 
    488 _puts("  - PTAB        = ");
    489 _putw( ptab );
    490 _puts("  saved at ");
    491 _putw( (unsigned int)&_scheduler[proc_id].context[ltid][CTX_PTAB_ID] );
    492 _puts("\n");
    493 #endif
    494 
    495 } // end _task_map()
    496 
    497 ///////////////////////////////////////////////////////////////////////////////
    498 // This function initialises all task contexts and processors schedulers.
    499 // It sets the default values for all schedulers (tasks <= 0, current <= 0).
    500 // Finally, it scan all tasks in all vspaces to initialise the schedulers,
    501 // and the tasks contexts, as defined in the mapping_info data structure.
    502 // A global TTY index and a global FB channel are allocated if required.
    503 // TTY[0] is reserved for the kernel.
    504 ///////////////////////////////////////////////////////////////////////////////
    505 in_kinit void _kernel_tasks_init()
    506 {
    507     mapping_header_t*   header  = (mapping_header_t*)&seg_mapping_base; 
    508     mapping_cluster_t*  cluster = _get_cluster_base( header );
    509     mapping_vspace_t*   vspace  = _get_vspace_base( header );     
    510     mapping_task_t*     task    = _get_task_base( header );
    511 
    512     unsigned int        base_tty_id = 1;     // TTY index allocator
    513     unsigned int        base_fb_id  = 0;     // FB channel index allocator
    514 
    515     unsigned int        cluster_id; 
    516     unsigned int        proc_id; 
    517     unsigned int        vspace_id; 
    518     unsigned int        task_id;
    519 
    520     // initialise the schedulers (not done by the compiler)
    521     for ( cluster_id = 0 ; cluster_id < header->clusters ; cluster_id++ )
    522     {
    523         for ( proc_id = 0 ; proc_id < cluster[cluster_id].procs ; proc_id++ )
    524         {
    525             if ( proc_id >= NB_PROCS )
    526             {
    527                 _puts("\n[INIT ERROR] The number of processors in cluster ");
    528                 _putw( cluster_id );
    529                 _puts(" is larger than NB_PROCS \n");
    530                 _exit();
    531             }
    532             _scheduler[cluster_id*NB_PROCS+proc_id].tasks   = 0;
    533             _scheduler[cluster_id*NB_PROCS+proc_id].current = 0;
    534         }
    535     }
    536 
    537     // loop on the virtual spaces
    538     for ( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )
    539     {
    540 
    541 #if INIT_DEBUG_CTX
    542 _puts("\n[INIT] mapping tasks in vspace ");
    543 _puts(vspace[vspace_id].name);
    544 _puts("\n");
    545 #endif
    546         // loop on the tasks
    547         for ( task_id = vspace[vspace_id].task_offset ;
    548               task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks) ;
    549               task_id++ )
    550         {
    551             unsigned int        tty_id = 0xFFFFFFFF;
    552             unsigned int        fb_id  = 0xFFFFFFFF;
    553             if ( task[task_id].use_tty )
    554             {
    555                 tty_id = base_tty_id;
    556                 base_tty_id++;
    557             }
    558             if ( task[task_id].use_fb  )
    559             {
    560                 fb_id = base_fb_id;
    561                 base_fb_id++;
    562             }
    563             _task_map( task_id,                         // global task index
    564                        vspace_id,                       // vspace index
    565                        tty_id,                          // global tty index
    566                        fb_id );                         // global fbdma index
    567         } // end loop on tasks
    568     } // end oop on vspaces
    569 
    570     _puts("\n[INIT] Task Contexts initialisation completed at cycle ");
    571     _putw( _proctime() );
    572     _puts("\n");
    573 
    574 #if INIT_DEBUG_CTX
    575 for ( cluster_id = 0 ; cluster_id < header->clusters ; cluster_id++ )
    576 {
    577     _puts("\nCluster ");
    578     _putw( cluster_id );
    579     _puts("\n");
    580     for ( proc_id = 0 ; proc_id < cluster[cluster_id].procs ; proc_id++ )
    581     {
    582         unsigned int ltid;              // local task index
    583         unsigned int gtid;              // global task index
    584         unsigned int pid = cluster_id * NB_PROCS + proc_id;
    585        
    586         _puts(" - processor ");
    587         _putw( pid );
    588         _puts("\n");
    589         for ( ltid = 0 ; ltid < _scheduler[pid].tasks ; ltid++ )
    590         {
    591             gtid = _scheduler[pid].context[ltid][CTX_TASK_ID];
    592             _puts("    task : ");
    593             _puts( task[gtid].name );
    594             _puts("\n");
    595         }
    596     }
    597 }
    598 #endif
    599 
    600 } // end _kernel_task_init()
    601 
    602 ////////////////////////////////////////////////////////////////////////////////
    603 // This function intializes the external periherals such as the IOB component
    604 // (I/O bridge, containing the IOMMU, the IOC (external disk controller),
    605 // the NIC (external network controller), the FBDMA (frame buffer controller),
    606 ////////////////////////////////////////////////////////////////////////////////
    607 in_kinit void _kernel_peripherals_init()
    608 {
    609     /////////////////////
    610     // IOC peripheral
    611     // we simply activate the IOC interrupts...
    612     if ( NB_IOC )
    613     {
    614         unsigned int*   ioc_address = (unsigned int*)&seg_ioc_base;
    615         ioc_address[BLOCK_DEVICE_IRQ_ENABLE] = 1;
    616     }
    617    
    618     /////////////////////
    619     // FBDMA peripheral
    620     // we simply activate the DMA interrupts...
    621     if ( NB_DMAS )
    622     {
    623         unsigned int*   dma_address = (unsigned int*)&seg_dma_base;
    624         dma_address[DMA_IRQ_DISABLE] = 0;
    625     }
    626 
    627     /////////////////////
    628     // IOB peripheral
    629     // must be initialised in case of IOMMU
    630     if ( GIET_IOMMU_ACTIVE )
    631     {
    632         unsigned int*   iob_address = (unsigned int*)&seg_iob_base;
    633 
    634         // define IPI address mapping the IOC interrupt ...TODO...
    635 
    636         // set IOMMU page table address
    637         iob_address[IOB_IOMMU_PTPR] = (unsigned int)(&_iommu_ptab);   
    638 
    639         // activate IOMMU
    640         iob_address[IOB_IOMMU_ACTIVE] = 1;   
    641     }
    642 
    643     _puts("\n[INIT] Peripherals initialisation completed at cycle ");
    644     _putw( _proctime() );
    645     _puts("\n");
    646 
    647 } // end _kernel_peripherals_init()
    648 
    649 ////////////////////////////////////////////////////////////////////////////////
    650 // This function intialises the interrupt vector, and initialises
    651 // the ICU mask registers for all processors in all clusters.
    652 // It strongly depends on the actual peripheral hardware wiring.
    653 // In this peculiar version, all clusters are identical,
    654 // the number of processors per cluster cannot be larger than 8.
    655 // Processor 0 handle all interrupts corresponding to TTYs, DMAs and IOC
    656 // (ICU inputs from from IRQ[8] to IRQ[31]). Only the 8 TIMER interrupts
    657 // (ICU iputs IRQ[0] to IRQ[7]), that are used for context switching
    658 // are distributed to the 8 processors.
    659 ////////////////////////////////////////////////////////////////////////////////
    660 in_kinit void _kernel_interrupt_vector_init()
    661 {
    662     mapping_header_t*   header  = (mapping_header_t*)&seg_mapping_base; 
    663     mapping_cluster_t*  cluster = _get_cluster_base( header );
    664 
    665     unsigned int cluster_id;
    666     unsigned int proc_id;
    667 
    668     // ICU mask values (up to 8 processors per cluster)
    669     unsigned int icu_mask[8] = { 0xFFFFFF01,
    670                                  0x00000002,
    671                                  0x00000004,
    672                                  0x00000008,
    673                                  0x00000010,
    674                                  0x00000020,
    675                                  0x00000040,
    676                                  0x00000080 };
    677 
    678     // initialise ICUs for each processor in each cluster
    679     for ( cluster_id = 0 ; cluster_id < header->clusters ; cluster_id++ )
    680     {
    681         for ( proc_id = 0 ; proc_id < cluster[cluster_id].procs ; proc_id++ )
    682         {
    683             _icu_write( cluster_id, proc_id, ICU_MASK_SET, icu_mask[proc_id] );
    684         }
    685     }
    686 
    687     // initialize Interrupt vector
    688 
    689     _interrupt_vector[0]   = &_isr_switch;
    690     _interrupt_vector[1]   = &_isr_switch;
    691     _interrupt_vector[2]   = &_isr_switch;
    692     _interrupt_vector[3]   = &_isr_switch;
    693     _interrupt_vector[4]   = &_isr_switch;
    694     _interrupt_vector[5]   = &_isr_switch;
    695     _interrupt_vector[6]   = &_isr_switch;
    696     _interrupt_vector[7]   = &_isr_switch;
    697 
    698     _interrupt_vector[8]   = &_isr_dma_0;
    699     _interrupt_vector[9]   = &_isr_dma_1;
    700     _interrupt_vector[10]  = &_isr_dma_2;
    701     _interrupt_vector[11]  = &_isr_dma_3;
    702     _interrupt_vector[12]  = &_isr_dma_4;
    703     _interrupt_vector[13]  = &_isr_dma_5;
    704     _interrupt_vector[14]  = &_isr_dma_6;
    705     _interrupt_vector[15]  = &_isr_dma_7;
    706 
    707     _interrupt_vector[16]  = &_isr_tty_get_0;
    708     _interrupt_vector[17]  = &_isr_tty_get_1;
    709     _interrupt_vector[18]  = &_isr_tty_get_2;
    710     _interrupt_vector[19]  = &_isr_tty_get_3;
    711     _interrupt_vector[20]  = &_isr_tty_get_4;
    712     _interrupt_vector[21]  = &_isr_tty_get_5;
    713     _interrupt_vector[22]  = &_isr_tty_get_6;
    714     _interrupt_vector[23]  = &_isr_tty_get_7;
    715     _interrupt_vector[24]  = &_isr_tty_get_8;
    716     _interrupt_vector[25]  = &_isr_tty_get_9;
    717     _interrupt_vector[26]  = &_isr_tty_get_10;
    718     _interrupt_vector[27]  = &_isr_tty_get_11;
    719     _interrupt_vector[28]  = &_isr_tty_get_12;
    720     _interrupt_vector[29]  = &_isr_tty_get_13;
    721     _interrupt_vector[30]  = &_isr_tty_get_14;
    722 
    723     _interrupt_vector[31]  = &_isr_ioc;
    724 
    725     _puts("\n[INIT] Interrupt vector initialisation completed at cycle ");
    726     _putw( _proctime() );
    727     _puts("\n");
    728 
    729 } // end _kernel_interrup_vector_init()
  • soft/giet_vm/sys/mips32_registers.h

    r167 r189  
    5353#define CP0_EPC                 $14
    5454#define CP0_PROCID              $15,1
     55#define CP0_SCHED               $22
    5556
    5657/* CP2 registers */
  • soft/giet_vm/sys/switch.s

    r158 r189  
    11/******************************************************************************
    2 * This function receives two arguments representing addresses of task
    3 * contexts, respectively for the current running task to be descheduled and
    4 * for the next task to be scheduled.
     2* This function receives two arguments that are the current task context
     3* physical addresses and the next task context physical address.
    54******************************************************************************/
    65
     
    1110_task_switch:
    1211
     12    /* desactivate DTLB */
     13    ori         $27,    $0,             0xB
     14    mtc2        $27,    $1                      /* DTLB desactivated */
     15
    1316    /* save _current task context */
    14 
    1517    add     $27,    $4,     $0  /* $27 <= &context[curr_task_id] */
    1618
     
    5860    mfc2    $26,    $0
    5961    sw      $26,    35*4($27)   /* ctx[35] <= PTPR */
    60     mfc2    $26,    $1
    61     sw      $26,    36*4($27)   /* ctx[36] <= MODE */
    6262
    6363    /* restore next task context */
    64 
    6564    add     $27,    $5,     $0  /* $27<= &context[next_task_id] */
    6665
    6766    lw      $26,    35*4($27)
    6867    mtc2    $26,    $0          /* restore PTPR */
    69     lw      $26,    36*4($27)
    70     mtc2    $26,    $1          /* restore MODE */
    7168    lw      $26,    0*4($27)
    7269    mtc0    $26,    $12         /* restore SR */
     
    111108    mtc0    $26,    $13         /* restore CR */
    112109
    113     jr      $31                 /* returns to caller */
     110    /* activate DTLB */
     111    ori         $27,    $0,             0xF
     112    mtc2        $27,    $1     
     113
     114    /* returns to caller */
     115    jr      $31
    114116
    115117    .endfunc
  • soft/giet_vm/sys/sys_handler.c

    r167 r189  
    7575void _exit()
    7676{
     77/*
    7778    unsigned int date    = _proctime();
     79
    7880    unsigned int proc_id = _procid();
    79     unsigned int task_id = _scheduler[proc_id].current;
     81
     82    unsigned int task_id = _get_current_task_id();
    8083
    8184     // print death message
     85    _get_lock(&_tty_put_lock);
    8286    _puts("\n\n!!! Exit task ");
    8387    _putw( task_id );
     
    8791    _putw( date );
    8892    _puts("\n\n");
    89 
     93    _release_lock(&_tty_put_lock);
     94*/
     95   
    9096    /* infinite loop */
    9197    while (1) asm volatile("nop");
  • soft/giet_vm/sys/vm_handler.c

    r184 r189  
    118118
    119119        // gets ppn_value and flags_value, after temporary DTLB desactivation
    120         asm volatile (
    121                        "li      $27,    0xFFFFFFFE  \n"     /* Mask for IE bits     */
    122                        "mfc0    $8,     $12         \n"     /* $8 <= SR             */
    123                        "and     $26,    $8,    $27 \n"      /* $26 <= SR && 0xFFFFFFE */
    124                        "mtc0    $26,    $12         \n"     /* disable Interrupts   */
     120        asm volatile ( "li      $27,    0xFFFFFFFE  \n"     /* Mask for IE bits     */
     121                       "mfc0    $26,    $12         \n"     /* save SR              */
     122                       "and     $27,    $26,    $27 \n"
     123                       "mtc0    $27,    $12         \n"     /* disable Interrupts   */
     124
     125                       "li      $27,    0xB         \n"     
     126                       "mtc2    $27,    $1          \n"     /* DTLB unactivated     */
    125127
    126128                       "move    $27,    %2          \n"     /* $27 <= pte2          */
    127                        "li      $26,    0xB         \n"     /* DTLB unactivated     */
    128                        "mtc2    $26,    $1          \n"
    129129                       "lw      %0,     0($27)      \n"     /* read flags           */
    130130                       "lw      %1,     4($27)      \n"     /* read ppn             */
    131                        "li      $26,    0xF         \n"
    132                        "mtc2    $26,    $1          \n"     /* DTLB activated       */
    133131
    134                        "or     $26,     $8,    $0   \n"     /* SR previous state    */
     132                       "li      $27,    0xF         \n"
     133                       "mtc2    $27,    $1          \n"     /* DTLB activated       */
     134
     135                       "mtc0    $26,    $12         \n"     /* restore SR           */
    135136                        :"=r"(flags_value), "=r"(ppn_value)
    136137                        :"r"(pte2)
  • soft/giet_vm/sys/vm_handler.h

    r180 r189  
    5353typedef struct PageTable
    5454{
    55         unsigned int    pt1[PT1_SIZE/4];        // PT1 (index is ix1)
    56         unsigned int    pt2[1][PT2_SIZE/4];     // PT2s (index is 2*ix2)
    57     /*  The number `1` is onmy here to indicate to the compiler that this is a table
    58      ** of two dimension and the actual value is computed dynamically(see boot_handler.c)*/
     55        unsigned int    pt1[PT1_SIZE/4];                      // PT1 (index is ix1)
     56        unsigned int    pt2[GIET_NB_PT2_MAX][PT2_SIZE/4];     // PT2s (index is 2*ix2)
    5957} page_table_t;
    6058
  • soft/giet_vm/xml/Makefile

    r181 r189  
    33
    44bin2xml: xml_driver.c mapping_info.h
    5         gcc -Wall -g -I. xml_driver.c -o bin2xml
     5        gcc -Wall -g -I. -I../sys xml_driver.c -o bin2xml
    66
    77xml2bin: xml_parser.c mapping_info.h
    8         gcc -Wall -g -I. -I/usr/include/libxml2 xml_parser.c -o xml2bin -lxml2
     8        gcc -Wall -g -I. -I../sys -I/usr/include/libxml2 xml_parser.c -o xml2bin -lxml2
    99
    1010test:
  • soft/giet_vm/xml/mapping_info.h

    r181 r189  
    1313// a fixed size header, and 6 variable size arrays:
    1414//
    15 // - mapping_header_t   header              (MAPPING_HEADER_SIZE)
    16 // - mapping_cluster_t  cluster[clusters]   (MAPPING_CLUSTER_SIZE * clusters)
    17 // - mapping_pseg_t     pseg[psegs]         (MAPPING_PSEG_SIZE * psegs)
    18 // - mapping_vspace_t   vspace[vspaces]     (MAPPING_VSPACE_SIZE * vspaces)
    19 // - mapping_vseg_t     vseg[vsegs]         (MAPPING_VSEG_SIZE * vsegs)
    20 // - mapping_vseg_t     vobj[vsegs]         (MAPPING_VOBJ_SIZE * vsegs)
    21 // - mapping_task_t     task[tasks]         (MAPPING_TASK_SIZE * tasks)
    22 //
    23 // The number of clusters and the number of vspaces are defined in the header.
    24 // The number of psegs are defined in each cluster.
    25 // The number of vsegs, tasks ans mwmrs are defined in each vspace.
     15// - mapping_cluster_t  cluster[] 
     16// - mapping_pseg_t     pseg[]       
     17// - mapping_vspace_t   vspace[] 
     18// - mapping_vseg_t     vseg[]     
     19// - mapping_vseg_t     vobj[]   
     20// - mapping_task_t     task[] 
     21// - mapping_irq_t      irq[irqs]   
     22// - mapping_coproc_t   coproc[]
     23// - mapping_cp_port_t  cp_port[]
     24// - mapping_periph_t   periph[]
    2625//
    2726// It is intended to be stored in the boot ROM at address MAPPING_BOOT_BASE.
    28 // For each cluster, the base address of the first pseg descriptor
    29 // is defined by a pseg_offset relative to MAPPING_BOOT_BASE.
    30 // For each vspace, the base address of the first vseg descriptor
    31 // is defined by a vseg_offset relative to MAPPING_BOOT_BASE.
    32 // For each vspace, the base address of the first task desciptor
    33 // is defined by a task_offset relative to MAPPING_BOOT_BASE.
    34 // For each vspace, the base address of the first mwmr desciptor
    35 // is defined by a mwmr_offset relative to MAPPING_BOOT_BASE.
    3627////////////////////////////////////////////////////////////////////////////
    3728
     
    4940#define MAPPING_IRQ_SIZE            sizeof(mapping_irq_t)
    5041#define MAPPING_COPROC_SIZE         sizeof(mapping_coproc_t)
    51 #define MAPPING_CP_PORT_SIZE    sizeof(mapping_coproc_port_t)
    52 #define MAPPING_CP_REG_SIZE         sizeof(mapping_coproc_reg_t)
     42#define MAPPING_CP_PORT_SIZE    sizeof(mapping_cp_port_t)
    5343
    5444#define C_MODE_MASK     0b1000      // cacheable
     
    8171enum
    8272{
    83     IRQ_TYPE_HARD     = 0,          // hardware interrupt (peripheral)
    84     IRQ_TYPE_SOFT     = 1,          // software interrupt (IPI)
    85 };
    86 
    87 enum
    88 {
    89     ISR_SWITCH        = 0,
    90     ISR_IOC           = 1,
    91     ISR_FBDMA         = 2,
    92     ISR_TTY           = 3,
    93 };
    94 
    95 enum
    96 {
    97     REG_TYPE_STATUS   = 0,          // status register
    98     REG_TYPE_CONFIG   = 1,          // config register
     73    PERIPH_TYPE_IOC   = 0,
     74    PERIPH_TYPE_TTY   = 1,
     75    PERIPH_TYPE_TIM   = 2,
     76    PERIPH_TYPE_DMA   = 3,
     77    PERIPH_TYPE_FBF   = 4,
     78    PERIPH_TYPE_NIC   = 5,
     79    PERIPH_TYPE_IOB   = 6,
    9980};
    10081
     
    10687
    10788///////////////////////////////
     89
    10890typedef struct mapping_header_s
    10991{
    11092    unsigned int    signature;      // must contain MAPPING_SIGNATURE
    11193        unsigned int    clusters;           // number of clusters
    112     unsigned int    ttys;           // number of TTY terminals
    113     unsigned int    fbs;            // number of FBDMA channels
    11494        unsigned int    globals;                // number of vsegs mapped in all vspaces
    11595        unsigned int    vspaces;                // number of virtual spaces
     96
     97    unsigned int    tty_clusterid;  // index of cluster containing TTY controler
     98    unsigned int    ioc_clusterid;  // index of cluster containing IOC controler
     99    unsigned int    nic_clusterid;  // index of cluster containing NIC controler
     100    unsigned int    fbf_clusterid;  // index of cluster containing FBF controler
     101
    116102    unsigned int    psegs;          // total number of physical segments (for all clusters)
    117103        unsigned int    vsegs;                  // total number of virtual segments (for all vspaces)
    118104        unsigned int    vobjs;                  // total number of virtual objects (for all vspaces)
    119105        unsigned int    tasks;                  // total number of tasks (for all vspaces)
    120         unsigned int    procs;                  // total number of procs
    121         unsigned int    irqs;           // total number of irqs
    122         unsigned int    coprocs;                // total number of coprocs
    123         unsigned int    cp_ports;               // total number of cp_ports
    124         unsigned int    cp_regs;                // total number of cp_regss
     106        unsigned int    procs;                  // total number of procs (for all clusters)
     107        unsigned int    irqs;           // total number of irqs (for all processors)
     108        unsigned int    coprocs;                // total number of coprocs (for all clusters)
     109        unsigned int    cp_ports;               // total number of cp_ports (for all coprocs)
     110    unsigned int    periphs;        // total number of peripherals (for all clusters)
     111
    125112    char            name[32];       // mapping name
    126113} mapping_header_t;
     
    129116typedef struct mapping_cluster_s
    130117{
     118    unsigned int    psegs;          // number of psegs in cluster
     119    unsigned int    pseg_offset;    // index of first pseg in pseg set
     120
    131121    unsigned int    procs;          // number of processors in cluster
    132122    unsigned int    proc_offset;    // index of first proc in proc set
     123
    133124    unsigned int    coprocs;        // number of coprocessors in cluster
    134125    unsigned int    coproc_offset;  // index of first coproc in coproc set
    135     unsigned int    psegs;          // number of psegs in cluster
    136     unsigned int    pseg_offset;    // index of first pseg in pseg set
     126
     127    unsigned int    periphs;        // number of peripherals in cluster
     128    unsigned int    periph_offset;  // index of first coproc in coproc set
    137129} mapping_cluster_t;
    138130
     
    183175    unsigned int    vobjlocid;      // stack vobj index in vspace
    184176    unsigned int    startid;        // index in start_vector
    185     unsigned int    use_tty;        // TTY terminal required
    186     unsigned int    use_fb;         // DMA channel to frame buffer required
     177    unsigned int    use_tty;        // TTY terminal required (global)
     178    unsigned int    use_nic;        // NIC channel required (global)
     179    unsigned int    use_timer;      // user timer required (local)
     180    unsigned int    use_fbdma;      // DMA channel to frame buffer required (local)
    187181} mapping_task_t;
    188182
     
    210204typedef struct mapping_irq_s
    211205{
    212     unsigned int    type;           // HW_IRQ  / SW_IRQ
     206    unsigned int    type;           // 0 => HW_IRQ  / 1 => SW_IRQ
    213207    unsigned int    icuid;          // IRQ Index for the ICU component
    214208    unsigned int    isr;            // Interrupt Service Routine Index
    215209    unsigned int    channel;        // Channel Index (for multi-cannels peripherals)
    216 
    217     unsigned int    cluster_id;     // physical cluster index
    218         unsigned int    proclocid;      // processor local index (inside cluster)
    219210} mapping_irq_t;
    220211
     
    226217    unsigned int    ports;          // number of MWMR ports used by coprocessor
    227218    unsigned int    port_offset;    // index of first MWMR port used by coprocessor
    228     unsigned int    regs;           // number of config/status registers
    229     unsigned int    reg_offset;     // index of first register
    230219} mapping_coproc_t;
    231220
    232 ///////////////////////////////////////
    233 typedef struct mapping_coproc_port_s
     221////////////////////////////////
     222typedef struct mapping_cp_port_s
    234223{
    235224    unsigned int    direction;      // TO_COPROC == 0 / FROM_COPROC == 1
    236     unsigned int    vspaceid;      // global index of the vspace containing the MWMR channel
    237     unsigned int    vobjlocid;        // local(to vspace) index of the vobj containing the MWMR channel
    238 } mapping_coproc_port_t;
    239 
    240 ///////////////////////////////////
    241 typedef struct mapping_coproc_reg_s
    242 {
    243     char            name[32];       // register name
    244     unsigned int    type;           // STATUS = 0 / CONFIG == 1
    245     unsigned int    loc_id;         // register index in coprocessor (word offset)
    246     unsigned int    channel_id;     // channel index in coprocessor (page offset)
    247     unsigned int    value;          // initialisation value
    248 }  mapping_coproc_reg_t;
     225    unsigned int    vspaceid;       // index of the vspace containing the MWMR channel
     226    unsigned int    vobjlocid;      // local index of the vobj containing the MWMR channel
     227} mapping_cp_port_t;
     228
     229///////////////////////////////
     230typedef struct mapping_periph_s
     231{
     232    unsigned int    type;           // IOC / TTY / TIM / DMA / FBF / NIC / IOB
     233    unsigned int    psegid;         // pseg index in cluster
     234    unsigned int    channels;       // number of channels
     235} mapping_periph_t;
     236
    249237
    250238#endif
  • soft/giet_vm/xml/xml_driver.c

    r181 r189  
    1717#include  <mapping_info.h>
    1818
    19 /////////////////////////////////////////////////////
    20 void buildXml( mapping_header_t* header, FILE* fpout)
     19//////////////////////////////////////////////////////
     20void buildXml( mapping_header_t* header, FILE* fpout )
    2121{
    22 
    2322    const char* vobj_type[] =
    2423    {
     
    3029        "LOCK",         // Spin-Lock
    3130        "BUFFER",       // Any "no intialiasation needed" objects (stacks...)
    32         "BARRIER"       // Barrier
     31        "BARRIER",      // Barrier
    3332    };
    3433
     
    3736        "RAM",
    3837        "ROM",
    39         "PERI"
     38        "PERI",
    4039    };
    4140
     
    4342    {
    4443        "HARD",
    45         "SOFT"
     44        "SOFT",
    4645    };
    4746
    4847    const char* isr_type[] =
    4948    {
     49        "ISR_DEFAULT",
     50        "ISR_SWITCH",
     51        "ISR_TTY",
     52        "ISR_DMA",
    5053        "ISR_IOC",
    51         "ISR_FBDMA",
    52         "ISR_TTY"
    53     };
    54 
    55     const char* reg_type[] =
    56     {
    57         "STATUS",
    58         "CONFIG"
     54        "ISR_TIMER",
     55    };
     56
     57    const char* periph_type[] =
     58    {
     59        "IOC",
     60        "TTY",
     61        "TIM",
     62        "DMA",
     63        "FBF",
     64        "NIC",
     65        "IOB",
    5966    };
    6067
     
    6269    {
    6370        "TO_COPROC",
    64         "FROM_COPROC"
     71        "FROM_COPROC",
    6572    };
    6673
     
    8188      "CX_U",
    8289      "CXW_",
    83       "CXWU"
     90      "CXWU",
    8491    };
    8592
     
    94101    unsigned int                coproc_id;
    95102    unsigned int                port_id;
    96     unsigned int                reg_id;
    97 
    98     mapping_cluster_t*      cluster;
    99     mapping_pseg_t*             pseg;
    100     mapping_vspace_t*       vspace;
    101     mapping_vseg_t*             vseg;
    102     mapping_vobj_t*             vobj;
    103     mapping_task_t*             task;
    104     mapping_proc_t*             proc;
    105     mapping_irq_t*              irq;   
    106     mapping_coproc_t*       coproc;
    107     mapping_coproc_port_t*      cp_port;
    108     mapping_coproc_reg_t*   cp_reg;
     103    unsigned int                periph_id;
     104
     105    mapping_cluster_t*  cluster;
     106    mapping_pseg_t*         pseg;
     107    mapping_vspace_t*   vspace;
     108    mapping_vseg_t*         vseg;
     109    mapping_vobj_t*         vobj;
     110    mapping_task_t*         task;
     111    mapping_proc_t*         proc;
     112    mapping_irq_t*          irq;       
     113    mapping_coproc_t*   coproc;
     114    mapping_cp_port_t*  cp_port;
     115    mapping_periph_t*   periph;
    109116
    110117    // computes the base adresss for clusters array,
     
    147154                                  MAPPING_VSEG_SIZE*header->vsegs );
    148155
    149     // computes the base address the array
     156    // computes the base address for procs array
    150157    proc    = (mapping_proc_t*)   ((char*)header +
    151158                                  MAPPING_HEADER_SIZE +
     
    157164                                  MAPPING_TASK_SIZE*header->tasks);
    158165
    159     // computes the base address the array
    160     irq    = (mapping_irq_t*)   ((char*)header +
    161                                   MAPPING_HEADER_SIZE +
    162                                   MAPPING_CLUSTER_SIZE*header->clusters +
    163                                   MAPPING_PSEG_SIZE*header->psegs +
    164                                   MAPPING_VSPACE_SIZE*header->vspaces +
    165                                   MAPPING_VOBJ_SIZE*header->vobjs +
    166                                   MAPPING_VSEG_SIZE*header->vsegs+
    167                                   MAPPING_TASK_SIZE*header->tasks+
    168                                   MAPPING_PROC_SIZE*header->procs
    169                                     );
    170 
    171     // computes the base address the array
    172     coproc    = (mapping_coproc_t*)   ((char*)header +
    173                                   MAPPING_HEADER_SIZE +
    174                                   MAPPING_CLUSTER_SIZE*header->clusters +
    175                                   MAPPING_PSEG_SIZE*header->psegs +
    176                                   MAPPING_VSPACE_SIZE*header->vspaces +
    177                                   MAPPING_VOBJ_SIZE*header->vobjs +
    178                                   MAPPING_VSEG_SIZE*header->vsegs+
    179                                   MAPPING_TASK_SIZE*header->tasks+
    180                                   MAPPING_PROC_SIZE*header->procs+
    181                                   MAPPING_IRQ_SIZE*header->irqs
    182                                     );
    183 
    184     // computes the base address the array
    185     cp_port    = (mapping_coproc_port_t*)   ((char*)header +
    186                                   MAPPING_HEADER_SIZE +
    187                                   MAPPING_CLUSTER_SIZE*header->clusters +
    188                                   MAPPING_PSEG_SIZE*header->psegs +
    189                                   MAPPING_VSPACE_SIZE*header->vspaces +
    190                                   MAPPING_VOBJ_SIZE*header->vobjs +
    191                                   MAPPING_VSEG_SIZE*header->vsegs+
    192                                   MAPPING_TASK_SIZE*header->tasks+
    193                                   MAPPING_PROC_SIZE*header->procs+
    194                                   MAPPING_IRQ_SIZE*header->irqs+
    195                                   MAPPING_COPROC_SIZE*header->coprocs
    196                                     );
    197 
    198     // computes the base address the array
    199     cp_reg    = (mapping_coproc_reg_t*)   ((char*)header +
    200                                   MAPPING_HEADER_SIZE +
    201                                   MAPPING_CLUSTER_SIZE*header->clusters +
    202                                   MAPPING_PSEG_SIZE*header->psegs +
    203                                   MAPPING_VSPACE_SIZE*header->vspaces +
    204                                   MAPPING_VOBJ_SIZE*header->vobjs +
    205                                   MAPPING_VSEG_SIZE*header->vsegs+
    206                                   MAPPING_TASK_SIZE*header->tasks+
    207                                   MAPPING_PROC_SIZE*header->procs+
    208                                   MAPPING_IRQ_SIZE*header->irqs+
    209                                   MAPPING_COPROC_SIZE*header->coprocs+
    210                                   MAPPING_CP_PORT_SIZE*header->cp_ports
    211                                     );
     166    // computes the base address for irqs array
     167    irq    = (mapping_irq_t*)    ((char*)header +
     168                                  MAPPING_HEADER_SIZE +
     169                                  MAPPING_CLUSTER_SIZE*header->clusters +
     170                                  MAPPING_PSEG_SIZE*header->psegs +
     171                                  MAPPING_VSPACE_SIZE*header->vspaces +
     172                                  MAPPING_VOBJ_SIZE*header->vobjs +
     173                                  MAPPING_VSEG_SIZE*header->vsegs +
     174                                  MAPPING_TASK_SIZE*header->tasks +
     175                                  MAPPING_PROC_SIZE*header->procs);
     176
     177    // computes the base address for coprocs array
     178    coproc = (mapping_coproc_t*)  ((char*)header +
     179                                  MAPPING_HEADER_SIZE +
     180                                  MAPPING_CLUSTER_SIZE*header->clusters +
     181                                  MAPPING_PSEG_SIZE*header->psegs +
     182                                  MAPPING_VSPACE_SIZE*header->vspaces +
     183                                  MAPPING_VOBJ_SIZE*header->vobjs +
     184                                  MAPPING_VSEG_SIZE*header->vsegs +
     185                                  MAPPING_TASK_SIZE*header->tasks +
     186                                  MAPPING_PROC_SIZE*header->procs +
     187                                  MAPPING_IRQ_SIZE*header->irqs);
     188
     189    // computes the base address for cp_ports array
     190    cp_port = (mapping_cp_port_t*)((char*)header +
     191                                  MAPPING_HEADER_SIZE +
     192                                  MAPPING_CLUSTER_SIZE*header->clusters +
     193                                  MAPPING_PSEG_SIZE*header->psegs +
     194                                  MAPPING_VSPACE_SIZE*header->vspaces +
     195                                  MAPPING_VOBJ_SIZE*header->vobjs +
     196                                  MAPPING_VSEG_SIZE*header->vsegs +
     197                                  MAPPING_TASK_SIZE*header->tasks +
     198                                  MAPPING_PROC_SIZE*header->procs +
     199                                  MAPPING_IRQ_SIZE*header->irqs +
     200                                  MAPPING_COPROC_SIZE*header->coprocs);
     201
     202    // computes the base address for periphs array
     203    periph = (mapping_periph_t*)  ((char*)header +
     204                                  MAPPING_HEADER_SIZE +
     205                                  MAPPING_CLUSTER_SIZE*header->clusters +
     206                                  MAPPING_PSEG_SIZE*header->psegs +
     207                                  MAPPING_VSPACE_SIZE*header->vspaces +
     208                                  MAPPING_VOBJ_SIZE*header->vobjs +
     209                                  MAPPING_VSEG_SIZE*header->vsegs +
     210                                  MAPPING_TASK_SIZE*header->tasks +
     211                                  MAPPING_PROC_SIZE*header->procs +
     212                                  MAPPING_IRQ_SIZE*header->irqs +
     213                                  MAPPING_COPROC_SIZE*header->coprocs +
     214                                  MAPPING_CP_PORT_SIZE*header->cp_ports);
     215
     216    ///////////////////////// header /////////////////////////////////////////////
    212217
    213218    fprintf( fpout, "<?xml version = \"1.0\"?>\n\n");
    214 
    215     ///////////////////////// header /////////////////////////////////////////////
    216219
    217220    fprintf( fpout, "<mapping_info signature = \"0x%x\"\n", header->signature);
    218221    fprintf( fpout, "              name      = \"%s\"\n", header->name);
    219222    fprintf( fpout, "              clusters  = \"%d\"\n", header->clusters);
    220     fprintf( fpout, "              ttys      = \"%d\"\n", header->ttys);
    221     fprintf( fpout, "              fbs       = \"%d\"\n", header->fbs);
    222223    fprintf( fpout, "              vspaces   = \"%d\"\n", header->vspaces);
    223224    fprintf( fpout, "              globals   = \"%d\" >\n\n", header->globals);
     
    238239            fprintf( fpout, "                          length = \"0x%x\" />\n",   pseg[pseg_id].length);
    239240        }
     241
     242    ///////////////////// processors /////////////////////////////////////////////
     243
    240244        for ( proc_id = cluster[cluster_id].proc_offset ;
    241245                proc_id < cluster[cluster_id].proc_offset + cluster[cluster_id].procs ;
     
    253257        }
    254258
     259
     260    ///////////////////// coprocessors ///////////////////////////////////////////
     261
    255262        for ( coproc_id = cluster[cluster_id].coproc_offset ;
    256263                coproc_id < cluster[cluster_id].coproc_offset + cluster[cluster_id].coprocs ;
     
    266273                fprintf( fpout, "                                   vobjname     = \"%s\" />\n",  vobj[vobj_id].name);
    267274            }
    268             for ( reg_id = coproc[coproc_id].reg_offset ;
    269                     reg_id < coproc[coproc_id].reg_offset+coproc[coproc_id].regs ;
    270                         reg_id++ )
    271             {
    272                 fprintf( fpout, "                           <reg    name        = \"%s\"\n",        cp_reg[reg_id].name);
    273                 fprintf( fpout, "                                   type        = \"%s\"\n",        reg_type[cp_reg[reg_id].type]);
    274                 fprintf( fpout, "                                   value       = \"0x%x\"\n",      cp_reg[reg_id].value);
    275                 fprintf( fpout, "                                   channel     = \"0x%x\"\n",      cp_reg[reg_id].channel_id);
    276                 fprintf( fpout, "                                   index       = \"0x%x\" />\n",   cp_reg[reg_id].loc_id);
    277             }
    278275            fprintf( fpout, "                   </coproc>\n" );
     276        }
     277
     278    ///////////////////// periphs  ///////////////////////////////////////////////
     279
     280        for ( periph_id = cluster[cluster_id].periph_offset ;
     281                periph_id < cluster[cluster_id].periph_offset + cluster[cluster_id].periphs ;
     282                    periph_id++ )
     283        {
     284            fprintf( fpout, "                   <periph type       = \"%s\"\n",     periph_type[periph[periph_id].type]);
     285            fprintf( fpout, "                           psegname   = \"%s\"\n",     pseg[periph[periph_id].psegid].name);
     286            fprintf( fpout, "                           channels   = \"%d\" />\n",  periph[periph_id].channels);
    279287        }
    280288        fprintf( fpout, "        </cluster>\n" );
     
    356364            fprintf( fpout, "                       startid   = \"%d\"\n",      task[task_id].startid);
    357365            fprintf( fpout, "                       usetty    = \"%d\"\n",      task[task_id].use_tty);
    358             fprintf( fpout, "                       usefb     = \"%d\" />\n\n", task[task_id].use_fb);
     366            fprintf( fpout, "                       usenic    = \"%d\"\n",      task[task_id].use_nic);
     367            fprintf( fpout, "                       usetimer  = \"%d\"\n",      task[task_id].use_timer);
     368            fprintf( fpout, "                       usefbma   = \"%d\" />\n\n", task[task_id].use_fbdma);
    359369        }
    360370        fprintf( fpout, "        </vspace>\n\n");
  • soft/giet_vm/xml/xml_parser.c

    r188 r189  
    2020#include  <libxml/xmlreader.h>
    2121#include  <mapping_info.h>
     22#include  <irq_handler.h>
    2223
    2324#define MAX_CLUSTERS    1024
     
    3233#define MAX_COPROCS             4096
    3334#define MAX_CP_PORTS    8192
    34 #define MAX_CP_REGS             8192
     35#define MAX_PERIPHS             8192
    3536
    3637#define XML_PARSER_DEBUG        0
     
    4950mapping_proc_t*         proc[MAX_PROCS];                // proc array
    5051mapping_irq_t*          irq[MAX_IRQS];                  // irq array
    51 mapping_coproc_t*       coproc[MAX_COPROCS];            // coproc array
    52 mapping_coproc_port_t*  cp_port[MAX_CP_PORTS];  // coproc port array
    53 mapping_coproc_reg_t*   cp_reg[MAX_CP_REGS];     // coproc reg array
    54 
    55 typedef struct vobj_ref_s
    56 {
    57     char vspace_name[32];
    58     char vobj_name[32];
    59 }vobj_ref_t;
    60 
    61 // This arrray is useful to temporary save the a vobj referece
    62 // formed by a vspace_name and a vobj_name (struct vobj_ref_s).
    63 // This arry will be used to set the attribute vobj_id of coproc_port
    64 // once all the vspace have been parsed.
    65 vobj_ref_t*                 cp_port_vobj_ref[MAX_CP_PORTS];     
     52mapping_coproc_t*       coproc[MAX_COPROCS];    // coproc array
     53mapping_cp_port_t*          cp_port[MAX_CP_PORTS];      // coproc port array
     54mapping_periph_t*       periph[MAX_PERIPHS];    // peripheral array
     55
     56// Index for the various arrays
    6657
    6758unsigned int            cluster_index  = 0;
     
    8273unsigned int            cp_port_loc_index = 0;
    8374
    84 unsigned int            cp_reg_index     = 0;
    85 unsigned int            cp_reg_loc_index = 0;
     75unsigned int            periph_index     = 0;
     76unsigned int            periph_loc_index = 0;
    8677
    8778unsigned int            vseg_index     = 0;
    8879unsigned int            vseg_loc_index = 0;
     80
    8981unsigned int            task_index     = 0;
    9082unsigned int            task_loc_index = 0;
     83
    9184unsigned int            vobj_index     = 0;
    9285unsigned int            vobj_loc_index = 0;
    9386unsigned int            vobj_count     = 0;
    9487
    95 unsigned int            tty_index      = 1;
    96 unsigned int            fb_index       = 0;
    97            
     88///////////////////////////////////////////////////////////////////////
     89// This arrray is useful to build a temporary list of vobj references.
     90// The struct vobj_ref_s is formed by a vspace_name and a vobj_name.
     91// This array is used to set the attribute vobj_id of a cp_port
     92// once all the vspace have been parsed.
     93
     94typedef struct vobj_ref_s
     95{
     96    char vspace_name[32];
     97    char vobj_name[32];
     98}vobj_ref_t;
     99
     100vobj_ref_t*             cp_port_vobj_ref[MAX_CP_PORTS];
     101
     102
    98103//////////////////////////////////////////////////
    99104unsigned int getIntValue( xmlTextReaderPtr reader,
     
    183188////////////////////////////////////////////
    184189int getVspaceId( char*         vspace_name)
    185 ////////////////////////////////////////////
    186190{
    187191    unsigned int vspace_id;
     
    201205                  char*             vobj_name,
    202206                  unsigned int  vspace_max)
    203 ////////////////////////////////////////////
    204207{
    205208    unsigned int vobj_id;
     
    235238#endif
    236239
    237     cp_port[cp_port_index] = (mapping_coproc_port_t*)malloc(sizeof(mapping_coproc_port_t));
     240    cp_port[cp_port_index] = (mapping_cp_port_t*)malloc(sizeof(mapping_cp_port_t));
    238241    cp_port_vobj_ref[cp_port_index] = (vobj_ref_t*)malloc(sizeof(vobj_ref_t));
    239242
     
    251254        else
    252255        {
    253             printf("[XML ERROR] illegal <direction> for coproc_port %d in cluster %d\n",
     256            printf("[XML ERROR] illegal <direction> for cp_port %d in cluster %d\n",
    254257                   cp_port_index, cluster_index);
    255258            exit(1);
     
    258261    else
    259262    {
    260         printf("[XML ERROR] missing <direction> for coproc_port %d in cluster %d\n",
     263        printf("[XML ERROR] missing <direction> for cp_port %d in cluster %d\n",
    261264               cp_port_index, cluster_index);
    262265        exit(1);
     
    274277    else
    275278    {
    276         printf("[XML ERROR] missing <vspacename> for coproc_port %d in cluster %d\n",
     279        printf("[XML ERROR] missing <vspacename> for cp_port %d in cluster %d\n",
    277280               cp_port_index, cluster_index);
    278281        exit(1);
     
    290293    else
    291294    {
    292         printf("[XML ERROR] missing <vobjname> for coproc_port %d in cluster %d\n",
     295        printf("[XML ERROR] missing <vobjname> for cp_port %d in cluster %d\n",
    293296               cp_port_index, cluster_index);
    294297        exit(1);
     
    300303} // end cpPortNode()
    301304
    302 /////////////////////////////////////////
    303 void cpRegNode ( xmlTextReaderPtr reader )
    304 /////////////////////////////////////////
     305///////////////////////////////////////////
     306void periphNode ( xmlTextReaderPtr reader )
     307///////////////////////////////////////////
    305308{
    306309    char*           str;
    307310    unsigned int    value;
    308     unsigned int    ok;
     311    unsigned int        ok;
    309312
    310313    if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
    311314
    312     /* TWO: check source file consistency if possible */
    313     if ( cp_reg_index >= MAX_CP_REGS )
    314     {
    315         printf("[XML ERROR] The number of regs (for coprocs) is larger than %d\n", MAX_CP_REGS);
    316     }
    317 
    318 #if XML_PARSER_DEBUG
    319 printf("\n  reg %d\n", cp_reg_index);
    320 #endif
    321 
    322     /* THIRD*/
    323     cp_reg[cp_reg_index] = (mapping_coproc_reg_t*)malloc(sizeof(mapping_coproc_reg_t));
    324 
    325     /* FOURTH: read all attribute*/
    326 
    327     /////////// get name attribute
    328     str = getStringValue( reader, "name", &ok );
    329 #if XML_PARSER_DEBUG
    330 printf("      name = %s\n", str);
    331 #endif
     315    if ( periph_index >= MAX_PERIPHS )
     316    {
     317        printf("[XML ERROR] The number of periphs is larger than %d\n", MAX_PERIPHS);
     318    }
     319
     320#if XML_PARSER_DEBUG
     321printf("\n  periph %d\n", periph_index);
     322#endif
     323
     324    periph[periph_index] = (mapping_periph_t*)malloc(sizeof(mapping_periph_t));
     325
     326    /////////// get type attribute
     327    str = getStringValue( reader, "type", &ok );
    332328    if ( ok )
    333329    {
    334         strncpy(cp_reg[cp_reg_index]->name, str, 31);
    335     }
    336     else
    337     {
    338         printf("[XML ERROR] illegal or missing <name> for coproc_reg %d in cluster %d\n",
    339                cp_reg_index, cluster_index);
    340         exit(1);
    341     }
     330#if XML_PARSER_DEBUG
     331printf("      type     = %s\n", str);
     332#endif
     333        unsigned int error = 0;
     334 
     335        // The TTY, IOC, NIC, FBF and IOB peripherals cannot be replicated
     336        if      ( strcmp( str, "IOC" ) == 0 )
     337        {
     338            periph[periph_index]->type = PERIPH_TYPE_IOC;
     339            if ( header->ioc_clusterid == 0xFFFFFFFF) header->ioc_clusterid = cluster_index;
     340            else  error = 1;
     341        }
     342        else if ( strcmp( str, "TTY" ) == 0 )
     343        {
     344            periph[periph_index]->type = PERIPH_TYPE_TTY;
     345            if ( header->ioc_clusterid == 0xFFFFFFFF) header->ioc_clusterid = cluster_index;
     346            else  error = 1;
     347        }
     348        else if ( strcmp( str, "FBF" ) == 0 )
     349        {
     350            periph[periph_index]->type = PERIPH_TYPE_FBF;
     351            if ( header->ioc_clusterid == 0xFFFFFFFF) header->ioc_clusterid = cluster_index;
     352            else  error = 1;
     353        }
     354        else if ( strcmp( str, "NIC" ) == 0 )
     355        {
     356            periph[periph_index]->type = PERIPH_TYPE_NIC;
     357            if ( header->ioc_clusterid == 0xFFFFFFFF) header->ioc_clusterid = cluster_index;
     358            else  error = 1;
     359        }
     360        // The TIM, DMA and IOB peripherals can be replicated in several clusters
     361        else if ( strcmp( str, "TIM" ) == 0 )
     362        {
     363            periph[periph_index]->type = PERIPH_TYPE_TIM;
     364        }
     365        else if ( strcmp( str, "DMA" ) == 0 )
     366        {
     367            periph[periph_index]->type = PERIPH_TYPE_DMA;
     368        }
     369        else if ( strcmp( str, "IOB" ) == 0 )
     370        {
     371            periph[periph_index]->type = PERIPH_TYPE_IOB;
     372        }
     373        else
     374        {
     375            printf("[XML ERROR] illegal <type> for peripheral %d in cluster %d\n",
     376                   periph_loc_index, cluster_index);
     377            exit(1);
     378        }
     379    }
     380    else
     381    {
     382        printf("[XML ERROR] missing <type> for peripheral  %d in cluster %d\n",
     383               periph_loc_index, cluster_index);
     384        exit(1);
     385    }
     386
     387    ///////// get channels attribute (optionnal : 1 if missing)
     388    value = getIntValue( reader, "channels", &ok );
     389    if ( ok )
     390    {
     391#if XML_PARSER_DEBUG
     392printf("      channels = %d\n", value);
     393#endif
     394        periph[periph_index]->channels = value;
     395    }
     396    else
     397    {
     398        periph[periph_index]->channels = 1;
     399    }
     400
     401    /////////// get psegname attribute
     402    str = getStringValue(reader,"psegname", &ok);
     403    if ( ok == 0 )
     404    {
     405        printf("[XML ERROR] illegal or missing <psegname> for coproc %d in cluster %d\n",
     406                 coproc_index, cluster_index);
     407        exit(1);
     408    }
     409
     410    /////////// set psegid attribute
     411    int index = getPsegId( cluster_index, str );
     412    if ( index >= 0 )
     413    {
     414#if XML_PARSER_DEBUG
     415printf("      clusterid = %d\n", cluster_index);
     416printf("      psegname  = %s\n", str);
     417printf("      psegid    = %d\n", index);
     418#endif
     419        periph[periph_index]->psegid = index;
     420        assert(pseg[index]->type == PSEG_TYPE_PERI &&
     421        "peripheral psegname attribute must refer to a pseg of type PERI" );
     422    }
     423    else             
     424    {
     425        printf("[XML ERROR] pseg not found for periph %d / clusterid = %d / psegname = %s\n",
     426                   periph_loc_index, cluster_index, str );
     427        exit(1);
     428    } 
    342429   
    343     ///////// get type attribute
    344     str = getStringValue( reader, "type", &ok );
    345     if ( ok )
    346     {
    347 #if XML_PARSER_DEBUG
    348 printf("      type = %s\n", str);
    349 #endif
    350         if      ( strcmp(str, "STATUS")   ) cp_reg[cp_reg_index]->type = REG_TYPE_STATUS;
    351         else if ( strcmp(str, "CONFIG")   ) cp_reg[cp_reg_index]->type = REG_TYPE_CONFIG;
    352         else
    353         {
    354             printf("[XML ERROR] illegal <type> for coproc_reg %d in cluster %d\n",
    355                    cp_reg_index, cluster_index);
    356             exit(1);
    357         }
    358     } 
    359     else
    360     {
    361         printf("[XML ERROR] missing <type> for coproc_reg %d in cluster %d\n",
    362                cp_reg_index, cluster_index);
    363         exit(1);
    364     }
    365 
    366     ///////// get value attribute
    367     value = getIntValue(reader, "value", &ok);
    368     if ( ok )
    369     {
    370 #if XML_PARSER_DEBUG
    371 printf("        value   = %d\n", value);
    372 #endif
    373         cp_reg[cp_reg_index]->value = value;
    374     }
    375     else
    376     {
    377         printf("[XML ERROR] illegal or missing <value> for coproc_reg %d in cluster %d\n",
    378                cp_reg_index, cluster_index);
    379         exit(1);
    380     }
    381 
    382     ///////// get channel attribute
    383     value = getIntValue(reader, "channel", &ok);
    384     if ( ok )
    385     {
    386 #if XML_PARSER_DEBUG
    387 printf("        channel   = %d\n", value);
    388 #endif
    389         cp_reg[cp_reg_index]->channel_id = value;
    390     }
    391     else
    392     {
    393         printf("[XML ERROR] illegal or missing <channel> for coproc_reg %d in cluster %d\n",
    394                cp_reg_index, cluster_index);
    395         exit(1);
    396     }
    397 
    398     ///////// get index attribute
    399     value = getIntValue(reader, "index", &ok);
    400     if ( ok )
    401     {
    402 #if XML_PARSER_DEBUG
    403 printf("        index   = %d\n", value);
    404 #endif
    405         cp_reg[cp_reg_index]->loc_id = value;
    406     }
    407     else
    408     {
    409         printf("[XML ERROR] illegal or missing <index> for coproc_reg %d in cluster %d\n",
    410                cp_reg_index, cluster_index);
    411         exit(1);
    412     }
    413    
    414     cp_reg_index++;
    415     cp_reg_loc_index++;
    416 
    417 } // end cpRegNode()
     430    periph_index++;
     431    periph_loc_index++;
     432
     433} // end periphNode
    418434
    419435/////////////////////////////////////////
     
    425441
    426442    cp_port_loc_index = 0;
    427     cp_reg_loc_index = 0;
    428443
    429444    if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
     
    439454
    440455    coproc[coproc_index] = (mapping_coproc_t*)malloc(sizeof(mapping_coproc_t));
    441 
    442456
    443457    /////////// get name attribute
     
    485499    } 
    486500
    487     ////////// set port_offset and reg_offset attribute
     501    ////////// set port_offset
    488502    coproc[coproc_index]->port_offset = cp_port_index;
    489     coproc[coproc_index]->reg_offset = cp_reg_index;
    490 
    491 #if XML_PARSER_DEBUG
    492 printf("    port_offset = %d\n", cp_port_index);
    493 printf("    reg_offset = %d\n", cp_reg_index);
     503
     504#if XML_PARSER_DEBUG
     505printf("      port_offset = %d\n", cp_port_index);
    494506#endif
    495507
     
    499511        const char* tag = (const char*)xmlTextReaderConstName(reader);
    500512
    501         if      ( strcmp(tag,"port")    == 0 ) cpPortNode(reader);
    502         else if ( strcmp(tag,"reg")   == 0 ) cpRegNode(reader);
    503         else if ( strcmp(tag,"#text"  ) == 0 ) { }
    504         else if ( strcmp(tag,"#comment") == 0 );
    505         else if ( strcmp(tag,"coproc")  == 0 )
     513        if      ( strcmp(tag, "port")     == 0 ) cpPortNode(reader);
     514        else if ( strcmp(tag, "#text")    == 0 ) { }
     515        else if ( strcmp(tag, "#comment") == 0 ) { }
     516        else if ( strcmp(tag, "coproc")   == 0 )
    506517        {
    507518            coproc[coproc_index]->ports = cp_port_loc_index;
    508             coproc[coproc_index]->regs = cp_reg_loc_index;
    509519            coproc_loc_index++;
    510520            coproc_index++;
     
    548558printf("        type    = %s\n", str);
    549559#endif
    550         if      ( strcmp(str, "HARD") ) irq[irq_index]->type = IRQ_TYPE_HARD;
    551         else if ( strcmp(str, "SOFT") ) irq[irq_index]->type = IRQ_TYPE_SOFT;
     560        if      ( strcmp(str, "HARD") == 0 ) irq[irq_index]->type = 0;
     561        else if ( strcmp(str, "SOFT") == 0 ) irq[irq_index]->type = 1;
    552562        else
    553563        {
     
    564574    }
    565575
    566     ///////// get irqid attribute
     576    ///////// get icuid attribute
    567577    value = getIntValue(reader, "icuid", &ok);
    568578    if ( ok )
     
    593603printf("        isr     = %s\n", str);
    594604#endif
    595         if      ( strcmp(str, "ISR_SWITCH") ) irq[irq_index]->isr = ISR_SWITCH;
    596         else if ( strcmp(str, "ISR_IOC")    ) irq[irq_index]->isr = ISR_IOC;
    597         else if ( strcmp(str, "ISR_FBDMA")  ) irq[irq_index]->isr = ISR_FBDMA;
    598         else if ( strcmp(str, "ISR_TTY")    ) irq[irq_index]->isr = ISR_TTY;
     605        if      ( strcmp(str, "ISR_SWITCH" ) == 0 ) irq[irq_index]->isr = ISR_SWITCH;
     606        else if ( strcmp(str, "ISR_IOC"    ) == 0 ) irq[irq_index]->isr = ISR_IOC;
     607        else if ( strcmp(str, "ISR_DMA"    ) == 0 ) irq[irq_index]->isr = ISR_DMA;
     608        else if ( strcmp(str, "ISR_TTY"    ) == 0 ) irq[irq_index]->isr = ISR_TTY;
     609        else if ( strcmp(str, "ISR_TIMER"  ) == 0 ) irq[irq_index]->isr = ISR_TIMER;
    599610        else
    600611        {
     
    603614            exit(1);
    604615        }
     616#if XML_PARSER_DEBUG
     617printf("        isrnum  = %d\n", irq[irq_index]->isr);
     618#endif
    605619    } 
    606620    else
     
    664678    ////////// set irq_offset attribute
    665679    proc[proc_index]->irq_offset = irq_index;
     680
    666681#if XML_PARSER_DEBUG
    667682printf("    irq_offset = %d\n", irq_index);
     
    673688        const char* tag = (const char*)xmlTextReaderConstName(reader);
    674689
    675         if      ( strcmp(tag,"irq")    == 0 ) irqNode(reader);
    676         else if ( strcmp(tag,"#text")   == 0 ) { }
    677         else if ( strcmp(tag,"#comment") == 0 );
    678         else if ( strcmp(tag,"proc")  == 0 )
     690        if      ( strcmp(tag, "irq")      == 0 ) irqNode(reader);
     691        else if ( strcmp(tag, "#text")    == 0 ) { }
     692        else if ( strcmp(tag, "#comment") == 0 ) { }
     693        else if ( strcmp(tag, "proc")     == 0 )
    679694        {
    680695            proc[proc_index]->irqs = irq_loc_index;
     
    817832    }
    818833
    819     /////////// get use_tty  attribute (optionnal : 0 if missing)
     834    /////////// get usetty  attribute (optionnal : 0 if missing)
    820835    value = getIntValue(reader,"usetty", &ok);
    821836    if ( ok )
     
    824839printf("      usetty = %x\n", value);
    825840#endif
    826         if ( (value != 0) && (tty_index >= header->ttys) )
    827         {
    828             printf("[XML ERROR] The tty index is too large for task (%d,%d)\n",
    829                 vspace_index, task_loc_index);
    830             exit(1);
    831         }
    832841        task[task_index]->use_tty = value;
    833         if (value != 0) tty_index++;
    834842    } 
    835843    else
     
    838846    }
    839847
    840     /////////// get use_fb  attribute (optionnal : 0 if missing)
    841     value = getIntValue(reader,"usefb", &ok);
    842     if ( ok )
    843     {
    844 #if XML_PARSER_DEBUG
    845 printf("      usefb = %x\n", value);
    846 #endif
    847         if ( (value != 0) && (fb_index >= header->fbs) )
    848         {
    849             printf("[XML ERROR] The fb channel index is too large for task (%d,%d)\n",
    850                 vspace_index, task_loc_index);
    851             exit(1);
    852         }
    853         task[task_index]->use_fb = value;
    854         if (value != 0) fb_index++;
     848    /////////// get usenic  attribute (optionnal : 0 if missing)
     849    value = getIntValue(reader,"usenic", &ok);
     850    if ( ok )
     851    {
     852#if XML_PARSER_DEBUG
     853printf("      usenic = %x\n", value);
     854#endif
     855        task[task_index]->use_nic = value;
    855856    } 
    856857    else
    857858    {
    858         task[task_index]->use_fb = 0;
     859        task[task_index]->use_nic = 0;
     860    }
     861
     862    /////////// get usetimer attribute (optionnal : 0 if missing)
     863    value = getIntValue(reader,"usetimer", &ok);
     864    if ( ok )
     865    {
     866#if XML_PARSER_DEBUG
     867printf("      usetimer = %x\n", value);
     868#endif
     869        task[task_index]->use_timer = value;
     870    } 
     871    else
     872    {
     873        task[task_index]->use_timer = 0;
     874    }
     875
     876    /////////// get usefbdma  attribute (optionnal : 0 if missing)
     877    value = getIntValue(reader,"usefbdma", &ok);
     878    if ( ok )
     879    {
     880#if XML_PARSER_DEBUG
     881printf("      usefbdma = %x\n", value);
     882#endif
     883        task[task_index]->use_fbdma = value;
     884    } 
     885    else
     886    {
     887        task[task_index]->use_fbdma = 0;
    859888    }
    860889
     
    865894//////////////////////////////////////////
    866895void  vobjNode ( xmlTextReaderPtr reader )
     896//////////////////////////////////////////
    867897{
    868898    unsigned int        ok;
     
    9861016    else
    9871017    {
    988         if((vobj[vobj_index]->type == VOBJ_TYPE_MWMR || vobj[vobj_index]->type == VOBJ_TYPE_BARRIER ))
     1018        if( (vobj[vobj_index]->type == VOBJ_TYPE_MWMR) ||
     1019            (vobj[vobj_index]->type == VOBJ_TYPE_BARRIER) )
    9891020        {
    9901021            printf("[XML ERROR] illegal or missing <value> attribute for vobj (%d,%d). \
     
    10031034//////////////////////////////////////////
    10041035void  vsegNode ( xmlTextReaderPtr reader )
     1036//////////////////////////////////////////
    10051037{
    10061038    unsigned int        ok;
     
    11441176        const char* tag = (const char*)xmlTextReaderConstName(reader);
    11451177
    1146         if      ( strcmp(tag,"vobj")    == 0 ) vobjNode(reader);
    1147         else if ( strcmp(tag,"#text"  ) == 0 ) { }
    1148         else if ( strcmp(tag,"vseg")    == 0 )
     1178        if      ( strcmp(tag, "vobj")     == 0 ) vobjNode(reader);
     1179        else if ( strcmp(tag, "#text"  )  == 0 ) { }
     1180        else if ( strcmp(tag, "#comment") == 0 ) { }
     1181        else if ( strcmp(tag, "vseg")     == 0 )
    11491182        {
    11501183            vseg[vseg_index]->vobjs = vobj_count;
     
    11641197//////////////////////////////////////////
    11651198void vspaceNode( xmlTextReaderPtr reader )
     1199//////////////////////////////////////////
    11661200{
    11671201    char*               str;
     
    12331267        const char* tag = (const char*)xmlTextReaderConstName(reader);
    12341268
    1235         if      ( strcmp(tag,"vseg")    == 0 ) vsegNode(reader);
    1236         else if ( strcmp(tag,"task")    == 0 ) taskNode(reader);
    1237         else if ( strcmp(tag,"#text")   == 0 ) { }
    1238         else if ( strcmp(tag,"#comment") == 0 );
    1239         else if ( strcmp(tag,"vspace")  == 0 )
     1269        if      ( strcmp(tag, "vseg")     == 0 ) vsegNode(reader);
     1270        else if ( strcmp(tag, "task")     == 0 ) taskNode(reader);
     1271        else if ( strcmp(tag, "#text")    == 0 ) { }
     1272        else if ( strcmp(tag, "#comment") == 0 ) { }
     1273        else if ( strcmp(tag, "vspace")   == 0 )
    12401274        {
    12411275            vspace[vspace_index]->vobjs = vobj_loc_index;
     
    12881322//////////////////////////////////////////
    12891323void  psegNode ( xmlTextReaderPtr reader )
     1324//////////////////////////////////////////
    12901325{
    12911326    unsigned int        ok;
     
    13791414/////////////////////////////////////////////
    13801415void  clusterNode ( xmlTextReaderPtr reader )
     1416/////////////////////////////////////////////
    13811417{
    13821418    unsigned int ok;
     
    13851421    proc_loc_index = 0;
    13861422    coproc_loc_index = 0;
    1387     cluster[cluster_index] = 0;
     1423    periph_loc_index = 0;
    13881424
    13891425    if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
     
    14021438    cluster[cluster_index] = (mapping_cluster_t*)malloc(sizeof(mapping_cluster_t));
    14031439
    1404     /////////// get index attribute (optional)
     1440    /////////// check cluster index attribute (optional)
    14051441    value = getIntValue(reader,"index",&ok);
    14061442    if ( ok && (value != cluster_index) )
     
    14111447    }
    14121448
    1413 
    1414     ////////// set pseg_offset attribute
    1415     cluster[cluster_index]->pseg_offset = pseg_index;
    1416     cluster[cluster_index]->proc_offset = proc_index;
     1449    ////////// set offsets
     1450    cluster[cluster_index]->pseg_offset   = pseg_index;
     1451    cluster[cluster_index]->proc_offset   = proc_index;
    14171452    cluster[cluster_index]->coproc_offset = coproc_index;
    1418 #if XML_PARSER_DEBUG
    1419 printf("    pseg_offset = %d\n", pseg_index);
    1420 printf("    proc_offset = %d\n", proc_index);
     1453    cluster[cluster_index]->periph_offset = periph_index;
     1454
     1455#if XML_PARSER_DEBUG
     1456printf("    pseg_offset   = %d\n", pseg_index);
     1457printf("    proc_offset   = %d\n", proc_index);
    14211458printf("    coproc_offset = %d\n", coproc_index);
    1422 #endif
    1423 
    1424     ////////// get psegs, coproc and/or procs
     1459printf("    periph_offset = %d\n", coproc_index);
     1460#endif
     1461
     1462    ////////// get psegs, procs, coprocs and periphs
    14251463    int status = xmlTextReaderRead(reader);
    14261464
     
    14291467        const char* tag = (const char*)xmlTextReaderConstName(reader);
    14301468
    1431         if      ( strcmp(tag, "pseg")    == 0 ) psegNode(reader);
    1432         else if ( strcmp(tag, "proc")    == 0 ) procNode(reader);
    1433         else if ( strcmp(tag, "coproc")    == 0 ) coprocNode(reader);
    1434         else if ( strcmp(tag, "#text")   == 0 ) { }
    1435         else if ( strcmp(tag,"#comment") == 0 );
    1436         else if ( strcmp(tag, "cluster") == 0 )
    1437         {
    1438 #if XML_PARSER_DEBUG
     1469        if      ( strcmp(tag, "pseg")     == 0 ) psegNode(reader);
     1470        else if ( strcmp(tag, "proc")     == 0 ) procNode(reader);
     1471        else if ( strcmp(tag, "coproc")   == 0 ) coprocNode(reader);
     1472        else if ( strcmp(tag, "periph")   == 0 ) periphNode(reader);
     1473        else if ( strcmp(tag, "#text")    == 0 ) { }
     1474        else if ( strcmp(tag, "#comment") == 0 ) { }
     1475        else if ( strcmp(tag, "cluster")  == 0 )
     1476        {
     1477            cluster[cluster_index]->procs   = proc_loc_index;
     1478            cluster[cluster_index]->coprocs = coproc_loc_index;
     1479            cluster[cluster_index]->periphs = periph_loc_index;
     1480
     1481            // cluster[cluster_index]psegs update is done in psegNode(),
     1482            // because the coprocNode() call to getPsegId() need it
     1483
     1484#if XML_PARSER_DEBUG
     1485printf("    psegs   = %d\n", cluster[cluster_index]->psegs);
     1486printf("    procs   = %d\n", cluster[cluster_index]->procs);
     1487printf("    coprocs = %d\n", cluster[cluster_index]->coprocs);
     1488printf("    periphs = %d\n", cluster[cluster_index]->periphs);
    14391489printf("  end cluster %d\n", cluster_index);
    14401490#endif
    1441             cluster[cluster_index]->procs = proc_loc_index;
    1442             cluster[cluster_index]->coprocs = coproc_loc_index;
    1443             //psegs = pseg_loc_index is done in psegNode(), so coprocNode() call to getPsegId() success
    14441491            cluster_index++;
    14451492            return;
     
    14511498//////////////////////////////////////////////
    14521499void clusterSetNode( xmlTextReaderPtr reader )
     1500//////////////////////////////////////////////
    14531501{
    14541502    if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
     
    14631511        const char* tag = (const char*)xmlTextReaderConstName(reader);
    14641512
    1465         if      ( strcmp(tag,"cluster") == 0 ) clusterNode(reader);
    1466         else if ( strcmp(tag,"#text") == 0 ) { }
    1467         else if ( strcmp(tag,"#comment") == 0 );
    1468         else if ( strcmp(tag,"clusterset") == 0 )
     1513        if      ( strcmp(tag, "cluster")    == 0 ) clusterNode(reader);
     1514        else if ( strcmp(tag, "#text")      == 0 ) { }
     1515        else if ( strcmp(tag, "#comment")   == 0 ) { }
     1516        else if ( strcmp(tag, "clusterset") == 0 )
    14691517        {
    14701518            // checking source file consistency
     
    14791527printf("  end cluster set\n\n");
    14801528#endif
    1481                 header->psegs = pseg_index;
    1482                 header->procs = proc_index;
    1483                 header->irqs  = irq_index;
    1484                 header->coprocs = coproc_index;
     1529                header->psegs    = pseg_index;
     1530                header->procs    = proc_index;
     1531                header->irqs     = irq_index;
     1532                header->coprocs  = coproc_index;
    14851533                header->cp_ports = cp_port_index;
    1486                 header->cp_regs = cp_reg_index;
    14871534                return;
    14881535            }
     
    14991546/////////////////////////////////////////////
    15001547void globalSetNode( xmlTextReaderPtr reader )
     1548/////////////////////////////////////////////
    15011549{
    15021550    if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
     
    15111559        const char* tag = (const char*)xmlTextReaderConstName(reader);
    15121560
    1513         if      ( strcmp(tag,"vseg") == 0    ) vsegNode(reader);
    1514         else if ( strcmp(tag,"#text"  ) == 0 ) { }
    1515         else if ( strcmp(tag,"#comment") == 0 );
    1516         else if ( strcmp(tag,"globalset") == 0 )
     1561        if      ( strcmp(tag, "vseg")      == 0 ) vsegNode(reader);
     1562        else if ( strcmp(tag, "#text"  )  == 0 ) { }
     1563        else if ( strcmp(tag, "#comment")  == 0 ) { }
     1564        else if ( strcmp(tag, "globalset") == 0 )
    15171565        {
    15181566            // checking source file consistency
     
    15421590/////////////////////////////////////////////
    15431591void vspaceSetNode( xmlTextReaderPtr reader )
     1592/////////////////////////////////////////////
    15441593{
    15451594    if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
     
    15541603        const char* tag = (const char*)xmlTextReaderConstName(reader);
    15551604
    1556         if      ( strcmp(tag,"vspace") == 0    ) vspaceNode(reader);
    1557         else if ( strcmp(tag,"#text"  ) == 0 ) { }
    1558         else if ( strcmp(tag,"#comment") == 0 );
    1559         else if ( strcmp(tag,"vspaceset") == 0 )
     1605        if      ( strcmp(tag, "vspace"   ) == 0 ) vspaceNode(reader);
     1606        else if ( strcmp(tag, "#text"    ) == 0 ) { }
     1607        else if ( strcmp(tag, "#comment" ) == 0 ) { }
     1608        else if ( strcmp(tag, "vspaceset") == 0 )
    15601609        {
    15611610            // checking source file consistency
     
    15841633//////////////////////////////////////////
    15851634void headerNode(xmlTextReaderPtr reader )
     1635//////////////////////////////////////////
    15861636{
    15871637    char*               name;
     
    16321682    }
    16331683
    1634     ///////// get ttys attribute
    1635     value = getIntValue(reader, "ttys", &ok);
    1636     if ( ok )
    1637     {
    1638 #if XML_PARSER_DEBUG
    1639 printf("  ttys = %d\n", value);
    1640 #endif
    1641         header->ttys  = value;
    1642     }
    1643     else
    1644     {
    1645         printf("[XML ERROR] illegal or missing <ttys> attribute in header\n");
    1646         exit(1);
    1647     }
    1648 
    1649     ///////// get fbs attribute
    1650     value = getIntValue(reader, "fbs", &ok);
    1651     if ( ok )
    1652     {
    1653 #if XML_PARSER_DEBUG
    1654 printf("  fbs = %d\n", value);
    1655 #endif
    1656         header->fbs  = value;
    1657     }
    1658     else
    1659     {
    1660         printf("[XML ERROR] illegal or missing <fbs> attribute in header\n");
    1661         exit(1);
    1662     }
    1663 
    16641684    ///////// get vspaces attribute
    16651685    value = getIntValue(reader, "vspaces", &ok);
     
    17021722    }
    17031723
     1724    //////// initialise non replicated peripherals cluster_id
     1725    header->tty_clusterid = 0xFFFFFFFF;
     1726    header->nic_clusterid = 0xFFFFFFFF;
     1727    header->ioc_clusterid = 0xFFFFFFFF;
     1728    header->fbf_clusterid = 0xFFFFFFFF;
     1729
     1730    ///////// set signature
    17041731    header->signature = IN_MAPPING_SIGNATURE;
    17051732
     
    17091736        const char* tag = (const char*)xmlTextReaderConstName(reader);
    17101737
    1711         if      ( strcmp(tag,"clusterset")   == 0 ) clusterSetNode(reader);
    1712         else if ( strcmp(tag,"globalset")    == 0 ) globalSetNode(reader);
    1713         else if ( strcmp(tag,"vspaceset")    == 0 ) vspaceSetNode(reader);
    1714         else if ( strcmp(tag,"#text")        == 0 ) ;
    1715         else if ( strcmp(tag,"#comment")     == 0 ) ;
    1716         else if ( strcmp(tag,"mapping_info") == 0 )
     1738        if      ( strcmp(tag, "clusterset")   == 0 ) clusterSetNode(reader);
     1739        else if ( strcmp(tag, "globalset")    == 0 ) globalSetNode(reader);
     1740        else if ( strcmp(tag, "vspaceset")    == 0 ) vspaceSetNode(reader);
     1741        else if ( strcmp(tag, "#text")        == 0 ) { }
     1742        else if ( strcmp(tag, "#comment")     == 0 ) { }
     1743        else if ( strcmp(tag, "mapping_info") == 0 )
    17171744        {
    17181745#if XML_PARSER_DEBUG
     
    17301757} // end headerNode()
    17311758   
     1759///////////////////////////////////////
    17321760void BuildTable( int fdout,
    17331761               const char* type,
     
    17351763               unsigned int elem_size,
    17361764               char** table)       
     1765////////////////////////////////////////
    17371766{
    17381767    unsigned int i;
     
    17581787///////////////////////////
    17591788void  buildBin( int fdout )
     1789///////////////////////////
    17601790{
    17611791    unsigned int    vspace_id;
     
    18231853    }
    18241854
    1825     // write tasks
     1855    // write tasks array
    18261856    BuildTable(fdout, "task", task_index, sizeof(mapping_task_t), (char**) task);
    1827     //building proc
     1857    //building procs array
    18281858    BuildTable(fdout, "proc", proc_index, sizeof(mapping_proc_t), (char**) proc);
    1829     //building irq
     1859    //building irqs array
    18301860    BuildTable(fdout, "irq", irq_index, sizeof(mapping_irq_t), (char**)irq);
    1831     //building coproc
     1861    //building coprocs array
    18321862    BuildTable(fdout, "coproc", coproc_index, sizeof(mapping_coproc_t), (char**)coproc);
    1833     //building cp_port
    1834     BuildTable(fdout, "cp_port", cp_port_index, sizeof(mapping_coproc_port_t),(char**) cp_port);
    1835     //building cp_reg
    1836     BuildTable(fdout, "cp_reg", cp_reg_index, sizeof(mapping_coproc_reg_t), (char**)cp_reg);
     1863    //building cp_ports array
     1864    BuildTable(fdout, "cp_port", cp_port_index, sizeof(mapping_cp_port_t),(char**) cp_port);
     1865    //building periphs array
     1866    BuildTable(fdout, "periph", periph_index, sizeof(mapping_periph_t), (char**)periph);
    18371867
    18381868} // end buildBin()
    18391869
    1840 /////////////////////////////////////////
    1841 // this function set the value of vobj_id
    1842 // of the coproc_ports.
    1843 ///////////////////
     1870///////////////////////////////////////////////////////////////////////
     1871// this function set the value the vobj_id fiels of all cp_ports
     1872///////////////////////////////////////////////////////////////////////
    18441873void prepareBuild()
    18451874{
     
    18501879        if ( vspace_id < 0 )
    18511880        {
    1852             printf("[XML ERROR] illegal  <vspacename> for coproc_port %d,\n",
     1881            printf("[XML ERROR] illegal  <vspacename> for cp_port %d,\n",
    18531882                    i);
    18541883            exit(1);
     
    18561885        cp_port[i]->vspaceid = vspace_id;
    18571886       
    1858         int vobj_id = getVobjLocId( vspace_id, cp_port_vobj_ref[i]->vobj_name, vspace[vspace_id]->vobjs );
     1887        int vobj_id = getVobjLocId( vspace_id,
     1888                                    cp_port_vobj_ref[i]->vobj_name,
     1889                                    vspace[vspace_id]->vobjs );
    18591890        if ( vobj_id >= 0 )
    18601891        {
    1861 #if XML_PARSER_DEBUG
    1862 printf("coproc_port = %d\n", i);
     1892
     1893#if XML_PARSER_DEBUG
     1894printf("\ncp_port = %d\n", i);
    18631895printf("      vspace_name  = %s\n", cp_port_vobj_ref[i]->vspace_name);
    18641896printf("      vobj_name    = %s\n", cp_port_vobj_ref[i]->vobj_name);
     
    18661898#endif
    18671899            cp_port[i]->vobjlocid = vobj_id;
    1868             assert((vobj[ vspace[vspace_id]->vobj_offset + vobj_id]->type == VOBJ_TYPE_MWMR) && "coproc ports has to refere to a vobj of type MWMR");
     1900
     1901            assert((vobj[ vspace[vspace_id]->vobj_offset + vobj_id]->type == VOBJ_TYPE_MWMR)
     1902            && "coproc ports has to refere to a vobj of type MWMR");
    18691903        }
    18701904        else             
    18711905        {
    1872             printf("[XML ERROR] illegal  <vobjname> for coproc_port %d,\n",
     1906            printf("[XML ERROR] illegal  <vobjname> for cp_port %d,\n",
    18731907                    i);
    18741908            exit(1);
    18751909        }
    1876        
    18771910    }
    18781911}
     
    18801913/////////////////////////////////////
    18811914int  main ( int argc, char* argv[] )
     1915/////////////////////////////////////
    18821916{
    18831917    if ( argc < 3 )
     
    19131947            }
    19141948            else
    1915             if ( strcmp(tag,"#comment") == 0 );// a way to skips comment
    1916             else
    19171949            {
    19181950                printf("[XML ERROR] Wrong file type: \"%s\"\n", argv[1]);
Note: See TracChangeset for help on using the changeset viewer.