| 301 | |
| 302 | Read about score - libcpu - split can be in the preceding section. |
| 303 | The implementation can be found in [https://github.com/phipse/rtems/tree/virt-bsp/c/src/lib/libcpu/i386 my github repo]. All changes to RTEMS reside in the virt-bsp branch. |
| 304 | |
| 305 | '''ISSUE:''' The split isn't final, as it is not allowed to include files from outside cpukit in the cpukit files. |
| 306 | libcpu is in c/src/ and not in cpukit/ so this is due to change. |
| 307 | Currently, a new configuration option is discussed. |
| 308 | This moves parts of this back to cpukit and branches conditionally on the configure option. |
| 309 | |
| 310 | = virtualpok BoardSupportPackage = |
| 311 | |
| 312 | |
| 313 | The virtualpok BSP is located in c/src/lib/libbsp/i386/ and is based on the BSP of the 2012 project. |
| 314 | The BSP brings with it a console driver, a clock driver, special interrupt functions and custom startup code. |
| 315 | == Configuration == |
| 316 | |
| 317 | |
| 318 | The command line to configure RTEMS using this BSP is: |
| 319 | |
| 320 | $ ../rtems/configure --target=i386-rtems4.11 --enable-rtemsbsp=virtualpok --disable-cxx --disable-networking --enable-posix --enable-maintainter-mode --enable-tests --disable-multiprocessing USE_COM1_AS_CONSOLE=1 BSP_PRESS_KEY_FOR_RESET=0 |
| 321 | |
| 322 | virtualpok/make/custom/virtualpok.cfg defines the CPU model to be used with this BSP. |
| 323 | The configuration file of libcpu/i386/ checks for this CPU model and builds the corresponding makefile. |
| 324 | This way one target architecture can have several BSPs with distinctive CPUs. |
| 325 | |
| 326 | == Startup == |
| 327 | |
| 328 | virtualpok/start/_start.S defines the standard GNU entry point "start", which is called by POK. |
| 329 | Normally, there would be some hardware checks and initialization, but as we run virtually, we can directly switch to the standard RTEMS startup procedure "boot_card()". |
| 330 | When boot_card() returns, it is time to clean up and reset/shut down the board. |
| 331 | |
| 332 | Bootcard is initializing RTEMS core structures and then proceeds with the BSP specific start up by calling bsp_start(), which is located in virtualpok/startup/bspstart.c. |
| 333 | This function is responsible to load initialize the interrupt management and all other board specifics, e.g. the clock driver. |
| 334 | |
| 335 | One special thing about this BSP are the two virtualization layer files: virtualizationlayercpu.h virtualizationlayerbsp.h in virtualpok/include. |
| 336 | They define the virtualization layer described above. |
| 337 | |
| 338 | == Drivers == |
| 339 | |
| 340 | |
| 341 | The BSP brings a console and clock driver with it. |
| 342 | Both drivers are dependent on calls to the virtualization layer, but fit into the default RTEMS structures. |
| 343 | |
| 344 | The console driver defines inbyte() and outbyte(), which call the virtualization layer. |
| 345 | Termios functions are "supported", meaning the functions calling termios are either stubs or forward to inbyte/outbyte. |
| 346 | The implementation of the virtualization layer is hypervisor dependent. |
| 347 | In this case it is POK and POK doesn't support reading from a console, so inbyte won't be of use. |
| 348 | |
| 349 | The clock driver is based upon the pc386 implementation, but omits all calibrating functionality, as we require the host to do this with the normal clock tick. A timer driver is not implemented (see the interrupt issue below). The driver registers it's ISR with RTEMS and is called, when C_dispatch_isr is looking for an driver to deliver the interrupt to. This drivers ISR will then call the default RTEMS clock ISR. |
| 350 | |
| 351 | == Interrupts == |
| 352 | |
| 353 | |
| 354 | The interrupt functionality is not exactly part of the BSP. |
| 355 | They are implemented in libcpu/i386/[virtual|native]/. |
| 356 | To RTEMS is looks alike, but the implementation of i386_enable/disable_interrupts is calling the virtualization layer instead of performing sti/cli. |
| 357 | |
| 358 | Additionally, there are functions to directly open and close interrupts in _CPU_ISR_Set_level(). |
| 359 | This was necessary as the virtualization layer behaves slightly different, than normal hardware. |
| 360 | I observed the _level variable taking obscure values, most likely due to the address space switch (user space -> kernel space). |
| 361 | Therefore, the hypervisor counts the enable/disable calls and decreases/increases an internal counter, opposed to setting the counter to to the value defined by _level. |
| 362 | Open and close will set this internal counter value to 0 or 1 (see https://github.com/phipse/pok/blob/master/kernel/arch/x86/x86-qemu/bsp.c bsp.c). |