50 | | A core is identified by two indexes[cxy][lid] : ''cxy'' is the cluster identifier, an ''lid'' is the core local index in cluster cxy. |
| 50 | All cores contribute to the boot procedure, but all cores are not simultaneously activated. |
| 51 | A core is identified by two indexes[cxy][lid] : ''cxy'' is the cluster identifier, an ''lid'' is the core local index in cluster: |
| 52 | * in a first phase, only core[0][0] is running (core 0 in cluster 0). |
| 53 | * In a second phase, only core[cxy][0] are running (one core per cluster). |
| 54 | * in last phase, all core[cxy][lid] are running. |
| 55 | |
| 56 | We describe below the four phases of the TSAR boot-loader: |
| 57 | |
| 58 | === B1. Preloader phase === |
| 59 | |
| 60 | At reset, the MMU is de-activated (for both data and instructions), and the extension address registers supporting direct access to remote memory banks (for both data and instructions) in all cores[cxy][lid] contain the 0 value. |
| 61 | Therefore, all cores can only access the physical address space of cluster 0. |
| 62 | * In the TSAR_LETI architecture, the preloader is loaded in the first 16 kbytes of the physical address space in cluster 0. |
| 63 | * In the TSAR_IOB architecture, the preloader is stored in an external ROM, that is accessed throug the IO_bridge located in cluster 0. |
| 64 | |
| 65 | All cores execute the same preloader code (stored in cluster 0, but the work done depends on the core identifier: |
| 66 | * The core[0][0] load in the BOOT_CODE zone of cluster 0, the boot-loader code. |
| 67 | * All other cores do only one task before going to sleep (i.e. low-power state): each core activates its private WTI channel in the local ICU (Interrupt Controller Unit) to be later activated by an IPI (Inter Processor Interrupt). |
| 68 | |
| 69 | This shows the memory content after this pre-loader phase. |
| 70 | [[Image(Phys_Mem1.svg)]] |
| 71 | |
| 72 | === B2. Boot-loader Sequencial phase === |
| 73 | |
| 74 | The first instructions of the boot-loader are defined in the ''boot_entry.S'' file. This assembly code is executed by all cores entering the boot loader, |
| 75 | but not at the same time, because in this phase, only core [0][0] is running, while all other cores are blocked in the preloaded, waiting to be activated by an IPI. |
| 76 | |
| 77 | This assembly code makes the assuption that the CP0 register containing the core gid (global hardware identifier) has a fixed format: * |
52 | | |
53 | | We describe below the four phases for the TSAR boot-loader: |
54 | | |
55 | | === B1. Preloader phase === |
56 | | |
57 | | At reset, the MMU is de-activated, and the extension address registers (for both data and instructions) in all cores[cxy][lid] contain the 0 value. |
58 | | Therefore, all cores can only access the physical address space of cluster 0. |
59 | | * In the TSAR_LETI architecture, the preloader is loaded in the first 16 kbytes of the RAM located in cluster 0. |
60 | | * In the TSAR_IOB architecture, the preloader is stored in an external ROM, that is accessed throug the IO_bridge located in cluster 0. |
61 | | |
62 | | All cores execute the same preloader code, but the work done depends on the core identifier. The core[0][0] (i.e. Core0 in cluster 0) load |
63 | | in local memory of cluster 0, the boot-loader code. All other cores do only one task before going to sleep (low-power) state: |
64 | | each core activates its private WTI channel in the local ICU (Interrupt Controller Unit) to be wake-up by core [0][0], using an |
65 | | IPI (Inter Processor Interrupt). |
66 | | |
67 | | This shows the memory content after this first phase. |
68 | | [[Image(Phys_Mem1.svg)]] |
69 | | |
70 | | === B2. Sequencial phase === |
71 | | |
72 | | In this second phase the work is entirely done by core[0][0]. |
73 | | |
74 | | * The core[0][0] initializes the stack pointer. The boot stack size is a configuration parameter. |
75 | | * The core[0][0] initializes 2 peripherals: The '''TTY''' terminal (channel 0) to display log info, and the '''IOC''' to access the disk. |
76 | | * The core[0][0] loads in cluster 0 the '''arch_info.bin''' file and the '''kernel.elf''' file at addresses ARCHINFO_BASE and KERN_BASE respectively. |
77 | | * The core[0][0] uses the '''arch_info.bin'''structure to initialize the local '''boot_info_t''' structure in cluster 0. |
| 79 | '''gid == (((x << Y_WIDTH) + y) << P_WIDTH) + lid''' * |
| 80 | * |
| 81 | Each core running this code makes the 3 following actions: * |
| 82 | * It initializes the core stack pointer depending on the '''lid''' value extracted from the '''gid''', using the BOOT_STACK_BASE and BOOT_STACK_SIZE parameters defined in the ''boot_config.h'' file, * |
| 83 | * It changes the value of the DATA address extension CP2 register, using the '''cxy''' value extracted from the '''gid''' |
| 84 | * It jumps to the boot_loader() C function defined in the ''boot.c'' file, passing the two (cxy , lid) arguments. |
| 85 | |
| 86 | In this sequencial phase, the core[0][0] executes the following actions: |
| 87 | |
| 88 | * The core[0][0] initializes 2 peripherals: The '''TTY''' terminal (channel 0) to display log messages, and the '''IOC''' peripheral to access the disk. |
| 89 | * The core[0][0] initializes the boot-loader private FAT32 structure, allowing the boot loader to access files stored in the FAT32 file system on disk. |
| 90 | * The core[0][0] load in the KERNEL_ELF zone the ''kernel.elf'' file from the disk file system.. |
| 91 | * Then it copies in the KERNEL_CORE zone the ''kcode'' and ''data'' segments, using the addresses contained in the .elf file (identity mapping). |
| 92 | * The core[0][0] load in the ARCH_INFO zone the ''arch_info.bin'' file from the disk file system. |
| 93 | * Then it builds from this ''arch_info.bin'' file the specific ''boot_info_t'' structure for cluster 0, and stores it in the ''kdata'' segment. |