Initial commit
commit
7ace64ba9f
@ -0,0 +1,112 @@
|
|||||||
|
AArch64 Kereszt-Fordító
|
||||||
|
=======================
|
||||||
|
|
||||||
|
Mielőtt nekiugranál az oktatóanyagoknak, szükséged lesz néhány szerszámra. Nevezetesen egy fordítóra, ami
|
||||||
|
képes AArch64-re fordítani, és a hozzá kapcsolódó programokra.
|
||||||
|
|
||||||
|
Build renszer
|
||||||
|
-------------
|
||||||
|
|
||||||
|
A fordítás levezénylésére a GNU make-t fogjuk használni. Ezt nem kell kereszt-fordítani, mivel csak az asztali gépen
|
||||||
|
fogjuk futtatni, nem a céleszközön. Azért választottam ezt az oktatóanyagokhoz, mert a GNU make-re a fordító
|
||||||
|
lefordításához is szükséged lesz, szóval ígyis-úgyis kelleni fog.
|
||||||
|
|
||||||
|
Források letöltése és kicsomagolása
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
Legelőször is, töltsd le a binutils és gcc forrásait. Ebben a példában az íráskor legfrissebb verziókat használtam.
|
||||||
|
Javaslom, hogy nézd meg a szervereket, és a legfrissebbre módosítsd a fájlneveket.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
wget http://ftpmirror.gnu.org/binutils/binutils-2.29.tar.gz
|
||||||
|
wget http://ftpmirror.gnu.org/gcc/gcc-7.2.0/gcc-7.2.0.tar.gz
|
||||||
|
wget http://ftpmirror.gnu.org/mpfr/mpfr-3.1.6.tar.gz
|
||||||
|
wget http://ftpmirror.gnu.org/gmp/gmp-6.1.2.tar.bz2
|
||||||
|
wget http://ftpmirror.gnu.org/mpc/mpc-1.0.3.tar.gz
|
||||||
|
wget ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.18.tar.bz2
|
||||||
|
wget ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-0.18.1.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
Miután végezett a letöltés, csomagold ki a tömörített fájlokat:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
for i in *.tar.gz; do tar -xzf $i; done
|
||||||
|
for i in *.tar.bz2; do tar -xjf $i; done
|
||||||
|
```
|
||||||
|
|
||||||
|
Szükség lesz még néhány symlink-re mielőtt a fordtást elkezdhetnénk, hozzuk létre ezeket:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd binutils-*
|
||||||
|
ln -s ../isl-* isl
|
||||||
|
cd ..
|
||||||
|
cd gcc-*
|
||||||
|
ln -s ../mpfr-* mpfr
|
||||||
|
ln -s ../gmp-* gmp
|
||||||
|
ln -s ../mpc-* mpc
|
||||||
|
ln -s ../cloog-* cloog
|
||||||
|
cd ..
|
||||||
|
```
|
||||||
|
|
||||||
|
Források lefordítása
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Oké, két csomagot kell fordítanunk. Az egyik a *binutils*, ami tartalmazza a linker-t, assembler-t és még pár
|
||||||
|
hasznos parancsot.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd binutils-*
|
||||||
|
configure --prefix=/usr/local/cross-compiler --target=aarch64-elf \
|
||||||
|
--enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit \
|
||||||
|
--disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-plugin \
|
||||||
|
--disable-linker-build-id --enable-lto --enable-install-libiberty --with-linker-hash-style=gnu --with-gnu-ld\
|
||||||
|
--enable-gnu-indirect-function --disable-multilib --disable-werror --enable-checking=release --enable-default-pie \
|
||||||
|
--enable-default-ssp --enable-gnu-unique-object
|
||||||
|
make -j4
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
|
Az első paraméter megmondja a configure szkriptnek, hogy a `/usr/local/cross-compiler` mappába telepítsen. A második
|
||||||
|
megadja a célarchítektúrát, amire a most fordítandó eszközök fordítanak majd. A maradék paramétek ki és bekapcsolgat
|
||||||
|
bizonyos funkciókat, ne foglalkozz velük. Elég annyit tudni, hogy ezek egy beágyazott fordítóhoz vannak optimalizálva.
|
||||||
|
|
||||||
|
A második csomag, természetesen maga a *gcc* fordító.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd gcc-*
|
||||||
|
configure --prefix=/usr/local/cross-compiler --target=aarch64-elf --enable-languages=c \
|
||||||
|
--enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit \
|
||||||
|
--disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-plugin \
|
||||||
|
--disable-linker-build-id --enable-lto --enable-install-libiberty --with-linker-hash-style=gnu --with-gnu-ld\
|
||||||
|
--enable-gnu-indirect-function --disable-multilib --disable-werror --enable-checking=release --enable-default-pie \
|
||||||
|
--enable-default-ssp --enable-gnu-unique-object
|
||||||
|
make -j4
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
|
Itt ugyanúgy megadjuk a könyvtárat és a célarchitektúrát, mint az előbb. Megadjuk azt is, hogy csak C fordítót kérünk,
|
||||||
|
mivel a gcc rengeteg nyelvet ismer, amire nem lesz szükség. Ez jelentősen lecsökkenti a fordítási időt. A fennmaradó
|
||||||
|
kapcsolók ugyan azok, mint a binutils esetében.
|
||||||
|
|
||||||
|
Ha végzett, nézd meg a `bin` mappát a `/usr/local/cross-compiler` könyvtárban. Egy rakás futtatható programot kell
|
||||||
|
ott találnod. Meggyőződésem, hogy ezt a mappát hozzá akarod adni a PATH-odhoz is.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ ls /usr/local/cross-compiler/bin
|
||||||
|
aarch64-elf-addr2line aarch64-elf-elfedit aarch64-elf-gcc-ranlib aarch64-elf-ld aarch64-elf-ranlib
|
||||||
|
aarch64-elf-ar aarch64-elf-gcc aarch64-elf-gcov aarch64-elf-ld.bfd aarch64-elf-readelf
|
||||||
|
aarch64-elf-as aarch64-elf-gcc-7.2.0 aarch64-elf-gcov-dump aarch64-elf-nm aarch64-elf-size
|
||||||
|
aarch64-elf-c++filt aarch64-elf-gcc-ar aarch64-elf-gcov-tool aarch64-elf-objcopy aarch64-elf-strings
|
||||||
|
aarch64-elf-cpp aarch64-elf-gcc-nm aarch64-elf-gprof aarch64-elf-objdump aarch64-elf-strip
|
||||||
|
```
|
||||||
|
|
||||||
|
Amik ezek közül számunkra érdekesek:
|
||||||
|
- aarch64-elf-as - az assembler
|
||||||
|
- aarch64-elf-gcc - a C fordító
|
||||||
|
- aarch64-elf-ld - a linker
|
||||||
|
- aarch64-elf-objcopy - az ELF futtathatók IMG-re való konvertálásához kell
|
||||||
|
- aarch64-elf-objdump - futtathatók disassemblálásához (debuggolásnál)
|
||||||
|
- aarch64-elf-readelf - hasznos eszköz a futtathatókban lévő szekciók és szegmensek listázáshoz (debuggolásnál)
|
||||||
|
|
||||||
|
Ha mind az öt fenti futtahatót látod, és hibaüzenet nélkül le is futnak, gratulálok!
|
||||||
|
Minden eszköz a rendelkezésedre áll, ami ehhez az oktatóanyaghoz kelleni fog.
|
@ -0,0 +1,112 @@
|
|||||||
|
AArch64 Cross Compiler
|
||||||
|
======================
|
||||||
|
|
||||||
|
Before we could start our tutorials, you'll need some tools. Namely a compiler that compiles for the AArch64
|
||||||
|
architecture and it's companion utilities.
|
||||||
|
|
||||||
|
Build system
|
||||||
|
------------
|
||||||
|
|
||||||
|
To orchestrate compilation, we'll use GNU make. No need for cross-compiling this, as we are about to use it on the
|
||||||
|
host computer only, and not on the target machine. The reason I choosed this build system for the tutorials is that
|
||||||
|
GNU make is also required to compile the compiler, so you'll need it anyway.
|
||||||
|
|
||||||
|
Download and unpack sources
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
First of all, download binutils and gcc sources. In this example I've used the latest versions as of writing.
|
||||||
|
You are advised to check the mirrors and modify filenames accordly.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
wget http://ftpmirror.gnu.org/binutils/binutils-2.29.tar.gz
|
||||||
|
wget http://ftpmirror.gnu.org/gcc/gcc-7.2.0/gcc-7.2.0.tar.gz
|
||||||
|
wget http://ftpmirror.gnu.org/mpfr/mpfr-3.1.6.tar.gz
|
||||||
|
wget http://ftpmirror.gnu.org/gmp/gmp-6.1.2.tar.bz2
|
||||||
|
wget http://ftpmirror.gnu.org/mpc/mpc-1.0.3.tar.gz
|
||||||
|
wget ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.18.tar.bz2
|
||||||
|
wget ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-0.18.1.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
Once the download finished, unpack the tarballs with these commands:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
for i in *.tar.gz; do tar -xzf $i; done
|
||||||
|
for i in *.tar.bz2; do tar -xjf $i; done
|
||||||
|
```
|
||||||
|
|
||||||
|
You'll need some symbolic links before you could start the compilation, so let's create them:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd binutils-*
|
||||||
|
ln -s ../isl-* isl
|
||||||
|
cd ..
|
||||||
|
cd gcc-*
|
||||||
|
ln -s ../mpfr-* mpfr
|
||||||
|
ln -s ../gmp-* gmp
|
||||||
|
ln -s ../mpc-* mpc
|
||||||
|
ln -s ../cloog-* cloog
|
||||||
|
cd ..
|
||||||
|
```
|
||||||
|
|
||||||
|
Compiling the sources
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Okay, now we have to build two packages. One is called *binutils*, which includes linker, assembler and other
|
||||||
|
usefull commands.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd binutils-*
|
||||||
|
configure --prefix=/usr/local/cross-compiler --target=aarch64-elf \
|
||||||
|
--enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit \
|
||||||
|
--disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-plugin \
|
||||||
|
--disable-linker-build-id --enable-lto --enable-install-libiberty --with-linker-hash-style=gnu --with-gnu-ld\
|
||||||
|
--enable-gnu-indirect-function --disable-multilib --disable-werror --enable-checking=release --enable-default-pie \
|
||||||
|
--enable-default-ssp --enable-gnu-unique-object
|
||||||
|
make -j4
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
|
The first argument tells the configure script to install the build in `/usr/local/cross-compiler`. The second
|
||||||
|
specifies the target architecture, for which we want the tools to be compiled. The other arguments turn specific
|
||||||
|
options on and off, don't bother. It's enough to know they are appropriately tweeked for an embedded system compiler.
|
||||||
|
|
||||||
|
And the second package, of course we'll need the *gcc compiler* itself.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd gcc-*
|
||||||
|
configure --prefix=/usr/local/cross-compiler --target=aarch64-elf --enable-languages=c \
|
||||||
|
--enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit \
|
||||||
|
--disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-plugin \
|
||||||
|
--disable-linker-build-id --enable-lto --enable-install-libiberty --with-linker-hash-style=gnu --with-gnu-ld\
|
||||||
|
--enable-gnu-indirect-function --disable-multilib --disable-werror --enable-checking=release --enable-default-pie \
|
||||||
|
--enable-default-ssp --enable-gnu-unique-object
|
||||||
|
make -j4
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
|
Here we specify the same directory and architecture as before. We also tell to compile only the C compiler, as gcc
|
||||||
|
otherwise would support tons of languages we don't need. This reduces the compilation time significantly. The remaining
|
||||||
|
arguments are the same as with binutils.
|
||||||
|
|
||||||
|
Now check `bin` folder in your `/usr/local/cross-compiler` directory. You should see a lot of executables there. You
|
||||||
|
probably also want to add this directory to your PATH environment variable.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ ls /usr/local/cross-compiler/bin
|
||||||
|
aarch64-elf-addr2line aarch64-elf-elfedit aarch64-elf-gcc-ranlib aarch64-elf-ld aarch64-elf-ranlib
|
||||||
|
aarch64-elf-ar aarch64-elf-gcc aarch64-elf-gcov aarch64-elf-ld.bfd aarch64-elf-readelf
|
||||||
|
aarch64-elf-as aarch64-elf-gcc-7.2.0 aarch64-elf-gcov-dump aarch64-elf-nm aarch64-elf-size
|
||||||
|
aarch64-elf-c++filt aarch64-elf-gcc-ar aarch64-elf-gcov-tool aarch64-elf-objcopy aarch64-elf-strings
|
||||||
|
aarch64-elf-cpp aarch64-elf-gcc-nm aarch64-elf-gprof aarch64-elf-objdump aarch64-elf-strip
|
||||||
|
```
|
||||||
|
|
||||||
|
The executables we are interested in:
|
||||||
|
- aarch64-elf-as - the assembler
|
||||||
|
- aarch64-elf-gcc - the C compiler
|
||||||
|
- aarch64-elf-ld - the linker
|
||||||
|
- aarch64-elf-objcopy - to convert ELF executable into IMG format
|
||||||
|
- aarch64-elf-objdump - utility to disassemble executables (for debugging)
|
||||||
|
- aarch64-elf-readelf - an useful utility to dump sections and segments in executables (for debugging)
|
||||||
|
|
||||||
|
If you have all of the above five executables and you can also run them without error messages, congrats!
|
||||||
|
You have all the tools needed for this tutorial series.
|
@ -0,0 +1,38 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person
|
||||||
|
# obtaining a copy of this software and associated documentation
|
||||||
|
# files (the "Software"), to deal in the Software without
|
||||||
|
# restriction, including without limitation the rights to use, copy,
|
||||||
|
# modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
# of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be
|
||||||
|
# included in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
start.o: start.S
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c start.S -o start.o
|
||||||
|
|
||||||
|
kernel8.img: start.o
|
||||||
|
aarch64-elf-ld -nostdlib -nostartfiles start.o -T link.ld -o kernel8.elf
|
||||||
|
aarch64-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm kernel8.elf *.o >/dev/null 2>/dev/null || true
|
@ -0,0 +1,35 @@
|
|||||||
|
Oktatóanyag 01 - A legszükségesebbek
|
||||||
|
====================================
|
||||||
|
|
||||||
|
Rendben, nem fogunk semmi érdekeset csinálni, csak kipróbáljuk a környezetet. A keletkezett kernel8.img-nek
|
||||||
|
be kell tudnia bootolni a Raspberry Pi-n, ahol végtelen ciklusban várakoztatja a CPU magokat. Ezt ellenőrizheted a
|
||||||
|
következő paranccsal:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ qemu-system-aarch64 -M raspi3 -kernel kernel8.img -d in_asm
|
||||||
|
... kimenet törölve az átláthatóság miatt, utolsó sor: ...
|
||||||
|
0x0000000000080004: 17ffffff b #-0x4 (addr 0x80000)
|
||||||
|
```
|
||||||
|
|
||||||
|
Start
|
||||||
|
-----
|
||||||
|
|
||||||
|
Amikor a vezérlés átadódik a kernel8.img-nek, a környezet még nem alkalmas C kód futtatására. Ezért mindenképp
|
||||||
|
szükség van egy kis Assembly bevezetőre. Mivel ez az első oktatóanyag nagyon egyszerű, nem is lesz más, nincs
|
||||||
|
még C kódunk.
|
||||||
|
|
||||||
|
Ne feledkezzünk meg róla, hogy 4 CPU magunk van. Most mind ugyanazt a végtelen ciklust hajtja végre.
|
||||||
|
|
||||||
|
|
||||||
|
Makefile
|
||||||
|
--------
|
||||||
|
|
||||||
|
A Makefile-unk végtelenü legyszerű. Lefordítjuk a start.S-t, ez az egyetlen forrás fájlunk. Aztán a szerkesztési
|
||||||
|
fázisban a linker.ld szrkript segítségével linkeljük. Végezetül pedig a keletkező elf futtahatót nyers programfájllá
|
||||||
|
kovertáljuk.
|
||||||
|
|
||||||
|
Linker szkript
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Nem túl meglepő módon ez is egyszerű. Be kell állítanunk a bázis címet, ahová a kernel8.img töltődik, és mindent
|
||||||
|
ide rakunk, mivel csak egy szekciónk van.
|
@ -0,0 +1,32 @@
|
|||||||
|
Tutorial 01 - Bare Minimum
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Okay, we're not going to do anything here, just test our toolchain. The resulting kernel8.img should
|
||||||
|
boot on Raspberry Pi, and stop the CPU cores in an infinite loop. You can check that by running
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ qemu-system-aarch64 -M raspi3 -kernel kernel8.img -d in_asm
|
||||||
|
... output removed for clearity, last line: ...
|
||||||
|
0x0000000000080004: 17ffffff b #-0x4 (addr 0x80000)
|
||||||
|
```
|
||||||
|
|
||||||
|
Start
|
||||||
|
-----
|
||||||
|
|
||||||
|
When the control is passed to kernel8.img, the environment is not ready for C. Therefore we must
|
||||||
|
implement a small preambule in Assembly. As this first tutorial is very simple, that's all we have, no C
|
||||||
|
for now.
|
||||||
|
|
||||||
|
Note that CPU has 4 cores. All of them are running the same infinite loop for now.
|
||||||
|
|
||||||
|
Makefile
|
||||||
|
--------
|
||||||
|
|
||||||
|
Our Makefile is very simple. We compile start.S, as this is our only source. Then in linker phase we
|
||||||
|
link it using the linker.ld script. Finaly we convert the resulting elf executable into a raw image.
|
||||||
|
|
||||||
|
Linker script
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Not surpisingly simple too. We just set the base address where our kernel8.img will be loaded, and we
|
||||||
|
put the only section we have there.
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x80000;
|
||||||
|
.text : { *(.text.boot) }
|
||||||
|
|
||||||
|
/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section ".text.boot"
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
1: wfe
|
||||||
|
b 1b
|
@ -0,0 +1,43 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person
|
||||||
|
# obtaining a copy of this software and associated documentation
|
||||||
|
# files (the "Software"), to deal in the Software without
|
||||||
|
# restriction, including without limitation the rights to use, copy,
|
||||||
|
# modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
# of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be
|
||||||
|
# included in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
SRCS = $(wildcard *.c)
|
||||||
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
start.o: start.S
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c start.S -o start.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: start.o $(OBJS)
|
||||||
|
aarch64-elf-ld -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf
|
||||||
|
aarch64-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm kernel8.elf *.o >/dev/null 2>/dev/null || true
|
@ -0,0 +1,36 @@
|
|||||||
|
Oktatóanyag 02 - Többmagos C
|
||||||
|
============================
|
||||||
|
|
||||||
|
Próbáljunk valami összetettebbet, mit szóltok? Összetettebb alatt azt értem, hogy most is megállítjuk a CPU magokat,
|
||||||
|
akárcsak az első oktatóanyagban, de most az egyik magot C-ből!
|
||||||
|
|
||||||
|
Start
|
||||||
|
-----
|
||||||
|
|
||||||
|
Most már meg kell különböztetnünk a magokat. Ehhez kiolvassuk a *mpidr_el1* rendszer regisztert. Ha nem nulla, akkor
|
||||||
|
a korábbi végtelen ciklus következik. Ha nulla, akkor meg fogunk hívni egy C eljárást. De ehhez előbb be állítanunk
|
||||||
|
egy megfelelő vermet, ki kell nulláznunk a bss szegmenst mielőtt kiadhatnánk az ugrás parancsot. Hozzáadtam néhány
|
||||||
|
Assembly sort, amik mindezt elvégzik. Arra az esetre, ha a C eljárás visszatérne (nem szabadna), ugyanarra a
|
||||||
|
végtelen ciklusra ugrunk, mint amit a többi CPU mag is épp végrehajt.
|
||||||
|
|
||||||
|
Makefile
|
||||||
|
--------
|
||||||
|
|
||||||
|
Egy kisit trükkösebb lett. Hozzáadtam parancsokat a C fordításhoz, de akkor már általánosan. Mostantól ugyanazt
|
||||||
|
a Makefile-t használhatjuk minden oktatóanyaghoz, függetlenül attól, hány C forrásfájlunk van, és a továbbiakban
|
||||||
|
nem is szerepeltetem.
|
||||||
|
|
||||||
|
Linker script
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Hasonlóan, a linker szkript is bonyolultabbá vált, mivel a C-hez adat és bss szekciókra is szükség van. Hozzáadtam
|
||||||
|
továbbá egy számolást a bss szegmens méretének megállapítására, így egyszerűen hivatkozhatunk rá Assembly-ben, és
|
||||||
|
nem kell ott molyolni vele.
|
||||||
|
|
||||||
|
Fontos, hogy a text szegmens az Assembly kóddal kezdődjön, mivel ez elé raktuk a vermet, ezért kell a KEEP().
|
||||||
|
Íly módon mind a betöltési címünk 0x80000, akárcsak a `_start` cimke címe és a verem teteje.
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
Végezetül, az első C kódunk. Csak egy végtelen ciklus, de akkor is! :-)
|
@ -0,0 +1,34 @@
|
|||||||
|
Tutorial 02 - Multicore C
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Now let's try something more complex, shall we? By complex I mean stop the CPU cures just like in the first tutorial,
|
||||||
|
but this time stop one of them from C!
|
||||||
|
|
||||||
|
Start
|
||||||
|
-----
|
||||||
|
|
||||||
|
Now we have to distinguish the cores. For that, we read the *mpidr_el1* system register. If it's not zero, we'll
|
||||||
|
do the former infinite loop. If it's zero, then we'll call a C function. But for that, we need a proper stack, and a
|
||||||
|
zerod out bss segment in memory before the call instruction. I've added some more code to the Assembly to do all of
|
||||||
|
that. In case the C code returns (shouldn't), we also jump to the same infinite loop the other CPU cores running.
|
||||||
|
|
||||||
|
Makefile
|
||||||
|
--------
|
||||||
|
|
||||||
|
It became a bit trickier. I've added commands for compiling C sources, but in a comform way. From now on, we
|
||||||
|
can use the same Makefile for every tutorial, regardless of the number of C sources, and I won't discuss it any
|
||||||
|
further.
|
||||||
|
|
||||||
|
Linker script
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Likewise, the linker script became more complex too, as C needs data and bss sections. I've also added a calculation
|
||||||
|
for the bss size, so that we can refer to it from the Assembly without any further hassle.
|
||||||
|
|
||||||
|
It is important to start the text segment with the Assembly code, because we set the stack right before it, hence
|
||||||
|
the KEEP(). This way our load address is 0x80000, the same as `_start` label and stack top.
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
Finaly, our first C code. Just an empty loop, but still! :-)
|
Binary file not shown.
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x80000;
|
||||||
|
.text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) }
|
||||||
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) }
|
||||||
|
PROVIDE(_data = .);
|
||||||
|
.data : { *(.data .data.* .gnu.linkonce.d*) }
|
||||||
|
.bss (NOLOAD) : {
|
||||||
|
. = ALIGN(16);
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
__bss_end = .;
|
||||||
|
}
|
||||||
|
_end = .;
|
||||||
|
|
||||||
|
/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
|
||||||
|
}
|
||||||
|
__bss_size = (__bss_end - __bss_start)>>3;
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
while(1);
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section ".text.boot"
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
// read cpu id, stop slave cores
|
||||||
|
mrs x1, mpidr_el1
|
||||||
|
and x1, x1, #3
|
||||||
|
cbz x1, 2f
|
||||||
|
// cpu id > 0, stop
|
||||||
|
1: wfe
|
||||||
|
b 1b
|
||||||
|
2: // cpu id == 0
|
||||||
|
|
||||||
|
// set stack before our code
|
||||||
|
ldr x1, =_start
|
||||||
|
mov sp, x1
|
||||||
|
|
||||||
|
// clear bss
|
||||||
|
ldr x1, =__bss_start
|
||||||
|
ldr w2, =__bss_size
|
||||||
|
3: cbz w2, 4f
|
||||||
|
str xzr, [x1], #8
|
||||||
|
sub w2, w2, #1
|
||||||
|
cbnz w2, 3b
|
||||||
|
|
||||||
|
// jump to C code, should not return
|
||||||
|
4: bl main
|
||||||
|
// for failsafe, halt this core too
|
||||||
|
b 1b
|
@ -0,0 +1,43 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person
|
||||||
|
# obtaining a copy of this software and associated documentation
|
||||||
|
# files (the "Software"), to deal in the Software without
|
||||||
|
# restriction, including without limitation the rights to use, copy,
|
||||||
|
# modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
# of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be
|
||||||
|
# included in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
SRCS = $(wildcard *.c)
|
||||||
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
start.o: start.S
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c start.S -o start.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: start.o $(OBJS)
|
||||||
|
aarch64-elf-ld -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf
|
||||||
|
aarch64-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm kernel8.elf *.o >/dev/null 2>/dev/null || true
|
@ -0,0 +1,33 @@
|
|||||||
|
Oktatóanyag 03 - UART1, Auxilary mini UART
|
||||||
|
==========================================
|
||||||
|
|
||||||
|
Ezúttal a hírhedt Helló Világ példát vesszük elő. Előbb az UART1-re írjuk meg, mivel azt egyszerűbb programozni.
|
||||||
|
NOTE: qemu nem irányítja át alapból az UART1-et a terminálra, csak az UART0-át!
|
||||||
|
|
||||||
|
Gpio.h
|
||||||
|
------
|
||||||
|
|
||||||
|
Van egy új fejléc fájlunk. Ebben definiáljuk az MMIO címét, és a GPIO vezérlő szavainak címeit. Ez egy nagyon
|
||||||
|
népszerű fejléc lesz, majd minden eszközhöz kelleni fog.
|
||||||
|
|
||||||
|
Uart.h, uart.c
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Egy nagyon minimális változat.
|
||||||
|
|
||||||
|
`uart_init()` inicializálja az UART csipet, és soros vonalat leképezi a GPIO lábakra.
|
||||||
|
|
||||||
|
`uart_send(c)` kiküld egy karatert a soros vonalra.
|
||||||
|
|
||||||
|
`uart_getc()` fogad egy karatert. A kocsivissza karakter (13) automatikusan újsor karakterré (10) konvertálódik.
|
||||||
|
|
||||||
|
`uart_puts(s)` kiír egy szöveget. Újsor karakternél kiküld egy kocsivissza karatert is (13 + 10).
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
Először is meg kell hívni az uart inicializáló kódját. Aztán kiküldjük, "Helló Világ!". Ha beszereztél USB
|
||||||
|
soros kábelt, akkor ennek meg kell jelennie a minicom ablakában. Ezután minden, minicom-ban leütött karaktert
|
||||||
|
visszaküld és kiír. Ha nem kapcsoltad ki a helyi visszhangot (local echo), akkor ez azt jelenti, hogy minden
|
||||||
|
leütött karaktert duplán fog kiírni a minicom.
|
||||||
|
|
@ -0,0 +1,32 @@
|
|||||||
|
Tutorial 03 - UART1, Auxilary mini UART
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
It is time for the famous Hello World example. We're going to write on the UART1 first, as it's easier to program.
|
||||||
|
NOTE: qemu does not redirect UART1 to terminal by default, only UART0!
|
||||||
|
|
||||||
|
Gpio.h
|
||||||
|
------
|
||||||
|
|
||||||
|
We have a new header file. This defines the base MMIO address, and the GPIO controller's addresses. This file
|
||||||
|
going to be very popular, as many device needs it.
|
||||||
|
|
||||||
|
Uart.h, uart.c
|
||||||
|
--------------
|
||||||
|
|
||||||
|
A very minimal implementation.
|
||||||
|
|
||||||
|
`uart_init()` initializes the device and maps it to the GPIO ports.
|
||||||
|
|
||||||
|
`uart_send(c)` sends a character over the serial line.
|
||||||
|
|
||||||
|
`uart_getc()` receives a character. The carrige return character (13) will be converted into a newline character (10).
|
||||||
|
|
||||||
|
`uart_puts(s)` prints out a string. On newline, a carrige return character will also be sent (13 + 10).
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
First we have to call the uart initialization code. Then we say "Hello World!". If you've purchased an USB
|
||||||
|
serial cable, you should see it on minicom's screen. After that every character typed in minicom will be
|
||||||
|
echoed back. If you haven't turned off local echo, that means you'll see every pressed key twice.
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MMIO_BASE 0x3F000000
|
||||||
|
|
||||||
|
#define GPFSEL0 ((volatile unsigned int*)(MMIO_BASE+0x00200000))
|
||||||
|
#define GPFSEL1 ((volatile unsigned int*)(MMIO_BASE+0x00200004))
|
||||||
|
#define GPFSEL2 ((volatile unsigned int*)(MMIO_BASE+0x00200008))
|
||||||
|
#define GPFSEL3 ((volatile unsigned int*)(MMIO_BASE+0x0020000C))
|
||||||
|
#define GPFSEL4 ((volatile unsigned int*)(MMIO_BASE+0x00200010))
|
||||||
|
#define GPFSEL5 ((volatile unsigned int*)(MMIO_BASE+0x00200014))
|
||||||
|
#define GPSET0 ((volatile unsigned int*)(MMIO_BASE+0x0020001C))
|
||||||
|
#define GPSET1 ((volatile unsigned int*)(MMIO_BASE+0x00200020))
|
||||||
|
#define GPCLR0 ((volatile unsigned int*)(MMIO_BASE+0x00200028))
|
||||||
|
#define GPLEV0 ((volatile unsigned int*)(MMIO_BASE+0x00200034))
|
||||||
|
#define GPLEV1 ((volatile unsigned int*)(MMIO_BASE+0x00200038))
|
||||||
|
#define GPEDS0 ((volatile unsigned int*)(MMIO_BASE+0x00200040))
|
||||||
|
#define GPEDS1 ((volatile unsigned int*)(MMIO_BASE+0x00200044))
|
||||||
|
#define GPHEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200064))
|
||||||
|
#define GPHEN1 ((volatile unsigned int*)(MMIO_BASE+0x00200068))
|
||||||
|
#define GPPUD ((volatile unsigned int*)(MMIO_BASE+0x00200094))
|
||||||
|
#define GPPUDCLK0 ((volatile unsigned int*)(MMIO_BASE+0x00200098))
|
||||||
|
#define GPPUDCLK1 ((volatile unsigned int*)(MMIO_BASE+0x0020009C))
|
Binary file not shown.
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x80000;
|
||||||
|
.text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) }
|
||||||
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) }
|
||||||
|
PROVIDE(_data = .);
|
||||||
|
.data : { *(.data .data.* .gnu.linkonce.d*) }
|
||||||
|
.bss (NOLOAD) : {
|
||||||
|
. = ALIGN(16);
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
__bss_end = .;
|
||||||
|
}
|
||||||
|
_end = .;
|
||||||
|
|
||||||
|
/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
|
||||||
|
}
|
||||||
|
__bss_size = (__bss_end - __bss_start)>>3;
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// set up serial console
|
||||||
|
uart_init();
|
||||||
|
|
||||||
|
// say hello
|
||||||
|
uart_puts("Hello World!\n");
|
||||||
|
|
||||||
|
// echo everything back
|
||||||
|
while(1) {
|
||||||
|
uart_send(uart_getc());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section ".text.boot"
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
// read cpu id, stop slave cores
|
||||||
|
mrs x1, mpidr_el1
|
||||||
|
and x1, x1, #3
|
||||||
|
cbz x1, 2f
|
||||||
|
// cpu id > 0, stop
|
||||||
|
1: wfe
|
||||||
|
b 1b
|
||||||
|
2: // cpu id == 0
|
||||||
|
|
||||||
|
// set stack before our code
|
||||||
|
ldr x1, =_start
|
||||||
|
mov sp, x1
|
||||||
|
|
||||||
|
// clear bss
|
||||||
|
ldr x1, =__bss_start
|
||||||
|
ldr w2, =__bss_size
|
||||||
|
3: cbz w2, 4f
|
||||||
|
str xzr, [x1], #8
|
||||||
|
sub w2, w2, #1
|
||||||
|
cbnz w2, 3b
|
||||||
|
|
||||||
|
// jump to C code, should not return
|
||||||
|
4: bl main
|
||||||
|
// for failsafe, halt this core too
|
||||||
|
b 1b
|
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
/* Auxilary mini UART registers */
|
||||||
|
#define AUX_ENABLE ((volatile unsigned int*)(MMIO_BASE+0x00215004))
|
||||||
|
#define AUX_MU_IO ((volatile unsigned int*)(MMIO_BASE+0x00215040))
|
||||||
|
#define AUX_MU_IER ((volatile unsigned int*)(MMIO_BASE+0x00215044))
|
||||||
|
#define AUX_MU_IIR ((volatile unsigned int*)(MMIO_BASE+0x00215048))
|
||||||
|
#define AUX_MU_LCR ((volatile unsigned int*)(MMIO_BASE+0x0021504C))
|
||||||
|
#define AUX_MU_MCR ((volatile unsigned int*)(MMIO_BASE+0x00215050))
|
||||||
|
#define AUX_MU_LSR ((volatile unsigned int*)(MMIO_BASE+0x00215054))
|
||||||
|
#define AUX_MU_MSR ((volatile unsigned int*)(MMIO_BASE+0x00215058))
|
||||||
|
#define AUX_MU_SCRATCH ((volatile unsigned int*)(MMIO_BASE+0x0021505C))
|
||||||
|
#define AUX_MU_CNTL ((volatile unsigned int*)(MMIO_BASE+0x00215060))
|
||||||
|
#define AUX_MU_STAT ((volatile unsigned int*)(MMIO_BASE+0x00215064))
|
||||||
|
#define AUX_MU_BAUD ((volatile unsigned int*)(MMIO_BASE+0x00215068))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set baud rate and characteristics (115200 8N1) and map to GPIO
|
||||||
|
*/
|
||||||
|
void uart_init()
|
||||||
|
{
|
||||||
|
register unsigned int r;
|
||||||
|
|
||||||
|
/* initialize UART */
|
||||||
|
*AUX_ENABLE |=1; // enable UART1, AUX mini uart
|
||||||
|
*AUX_MU_IER = 0;
|
||||||
|
*AUX_MU_CNTL = 0;
|
||||||
|
*AUX_MU_LCR = 3; // 8 bits
|
||||||
|
*AUX_MU_MCR = 0;
|
||||||
|
*AUX_MU_IER = 0;
|
||||||
|
*AUX_MU_IIR = 0xc6; // disable interrupts
|
||||||
|
*AUX_MU_BAUD = 270; // 115200 baud
|
||||||
|
/* map UART1 to GPIO pins */
|
||||||
|
r=*GPFSEL1;
|
||||||
|
r&=~((7<<12)|(7<<15)); // gpio14, gpio15
|
||||||
|
r|=(2<<12)|(2<<15); // alt5
|
||||||
|
*GPFSEL1 = r;
|
||||||
|
*GPPUD = 0; // enable pins 14 and 15
|
||||||
|
r=150; while(r--) { asm volatile("nop"); }
|
||||||
|
*GPPUDCLK0 = (1<<14)|(1<<15);
|
||||||
|
r=150; while(r--) { asm volatile("nop"); }
|
||||||
|
*GPPUDCLK0 = 0; // flush GPIO setup
|
||||||
|
*AUX_MU_CNTL = 3; // enable Tx, Rx
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a character
|
||||||
|
*/
|
||||||
|
void uart_send(unsigned int c) {
|
||||||
|
/* wait until we can send */
|
||||||
|
do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x20));
|
||||||
|
/* write the carachter to the buffer */
|
||||||
|
*AUX_MU_IO=c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receive a character
|
||||||
|
*/
|
||||||
|
char uart_getc() {
|
||||||
|
char r;
|
||||||
|
/* wait until something is in the buffer */
|
||||||
|
do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x01));
|
||||||
|
/* read it and return */
|
||||||
|
r=(char)(*AUX_MU_IO);
|
||||||
|
/* convert carrige return to newline */
|
||||||
|
return r=='\r'?'\n':r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a string
|
||||||
|
*/
|
||||||
|
void uart_puts(char *s) {
|
||||||
|
while(*s) {
|
||||||
|
/* convert newline to carrige return + newline */
|
||||||
|
if(*s=='\n')
|
||||||
|
uart_send('\r');
|
||||||
|
uart_send(*s++);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void uart_init();
|
||||||
|
void uart_send(unsigned int c);
|
||||||
|
char uart_getc();
|
||||||
|
void uart_puts(char *s);
|
@ -0,0 +1,43 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person
|
||||||
|
# obtaining a copy of this software and associated documentation
|
||||||
|
# files (the "Software"), to deal in the Software without
|
||||||
|
# restriction, including without limitation the rights to use, copy,
|
||||||
|
# modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
# of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be
|
||||||
|
# included in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
SRCS = $(wildcard *.c)
|
||||||
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
start.o: start.S
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c start.S -o start.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: start.o $(OBJS)
|
||||||
|
aarch64-elf-ld -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf
|
||||||
|
aarch64-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm kernel8.elf *.o >/dev/null 2>/dev/null || true
|
@ -0,0 +1,34 @@
|
|||||||
|
Oktatóanyag 04 - Levelesládák
|
||||||
|
=============================
|
||||||
|
|
||||||
|
Mielőtt nekiugranánk az UART0-ának, szükségünk lesz a levelesládára. Ezért ebben az oktatóanyagban bemutatom a
|
||||||
|
mailbox interfészt. Arra használjuk, hogy lekérdezzük az alaplap egyedi sorszámát, majd kiírjuk azt.
|
||||||
|
NOTE: qemu nem irányítja át alapból az UART1-et a terminálra, csak az UART0-át!
|
||||||
|
|
||||||
|
Uart.h, uart.c
|
||||||
|
--------------
|
||||||
|
|
||||||
|
`uart_hex(d)` kiír egy bináris értéket hexadecimális formátumban.
|
||||||
|
|
||||||
|
Mbox.h, mbox.c
|
||||||
|
--------------
|
||||||
|
|
||||||
|
A levelesláda interfésze. Először értékekkel feltöltjük az `mbox` tömböt, aztán meghívjuk a `mbox_call(ch)`-t,
|
||||||
|
hogy értesüljön róla a GPU, megadva közben a levelesláda csatornáját.
|
||||||
|
Ebben a példában a [property csatornát](https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface)
|
||||||
|
használtam, aminek az üzenete a következőképp néz ki:
|
||||||
|
0. üzenet teljes hossza bájtban, (x+1)*4
|
||||||
|
1. MBOX_REQUEST mágikus szám, kérés típusú üzenetet jelent
|
||||||
|
2-x. parancsok
|
||||||
|
x+1. MBOX_TAG_LAST mágikus szám, nincs további parancs jelölése
|
||||||
|
|
||||||
|
Ahol minden egyes parancs szerkezete a következő:
|
||||||
|
n+0. parancs azonosító
|
||||||
|
n+1. adatterület mérete bájtban
|
||||||
|
n+2. nulla
|
||||||
|
n+3. opcionális adatterület
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
Lekérjük az alaplap egyedi szériaszámát, majd kiírjuk a soros konzolra.
|
@ -0,0 +1,34 @@
|
|||||||
|
Tutorial 04 - Mailboxes
|
||||||
|
=======================
|
||||||
|
|
||||||
|
Before we could go on with UART0, we need mailboxes. So in this tutorial we introduce the mailbox interface.
|
||||||
|
We'll use it to query the board's serial number and print that out on UART1.
|
||||||
|
NOTE: qemu does not redirect UART1 to terminal by default, only UART0!
|
||||||
|
|
||||||
|
Uart.h, uart.c
|
||||||
|
--------------
|
||||||
|
|
||||||
|
`uart_hex(d)` prints out a binary value in hexadecimal format.
|
||||||
|
|
||||||
|
Mbox.h, mbox.c
|
||||||
|
--------------
|
||||||
|
|
||||||
|
The mailbox interface. First we fill up the message in `mbox` array, then we call
|
||||||
|
`mbox_call(ch)` to pass it to the GPU, specifying the mailbox channel.
|
||||||
|
In this example we have used the [property channel](https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface),
|
||||||
|
which requires the message to be formatted as:
|
||||||
|
0. size of the message in bytes, (x+1)*4
|
||||||
|
1. MBOX_REQUEST magic value, indicates request message
|
||||||
|
2-x. tags
|
||||||
|
x+1. MBOX_TAG_LAST magic value, indicates no more tags
|
||||||
|
|
||||||
|
Where each tag looks like:
|
||||||
|
n+0. tag identifier
|
||||||
|
n+1. value buffer size in bytes
|
||||||
|
n+2. must be zero
|
||||||
|
n+3. optional value buffer
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
We query the board's serial number and then we display it on the serial console.
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MMIO_BASE 0x3F000000
|
||||||
|
|
||||||
|
#define GPFSEL0 ((volatile unsigned int*)(MMIO_BASE+0x00200000))
|
||||||
|
#define GPFSEL1 ((volatile unsigned int*)(MMIO_BASE+0x00200004))
|
||||||
|
#define GPFSEL2 ((volatile unsigned int*)(MMIO_BASE+0x00200008))
|
||||||
|
#define GPFSEL3 ((volatile unsigned int*)(MMIO_BASE+0x0020000C))
|
||||||
|
#define GPFSEL4 ((volatile unsigned int*)(MMIO_BASE+0x00200010))
|
||||||
|
#define GPFSEL5 ((volatile unsigned int*)(MMIO_BASE+0x00200014))
|
||||||
|
#define GPSET0 ((volatile unsigned int*)(MMIO_BASE+0x0020001C))
|
||||||
|
#define GPSET1 ((volatile unsigned int*)(MMIO_BASE+0x00200020))
|
||||||
|
#define GPCLR0 ((volatile unsigned int*)(MMIO_BASE+0x00200028))
|
||||||
|
#define GPLEV0 ((volatile unsigned int*)(MMIO_BASE+0x00200034))
|
||||||
|
#define GPLEV1 ((volatile unsigned int*)(MMIO_BASE+0x00200038))
|
||||||
|
#define GPEDS0 ((volatile unsigned int*)(MMIO_BASE+0x00200040))
|
||||||
|
#define GPEDS1 ((volatile unsigned int*)(MMIO_BASE+0x00200044))
|
||||||
|
#define GPHEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200064))
|
||||||
|
#define GPHEN1 ((volatile unsigned int*)(MMIO_BASE+0x00200068))
|
||||||
|
#define GPPUD ((volatile unsigned int*)(MMIO_BASE+0x00200094))
|
||||||
|
#define GPPUDCLK0 ((volatile unsigned int*)(MMIO_BASE+0x00200098))
|
||||||
|
#define GPPUDCLK1 ((volatile unsigned int*)(MMIO_BASE+0x0020009C))
|
Binary file not shown.
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x80000;
|
||||||
|
.text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) }
|
||||||
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) }
|
||||||
|
PROVIDE(_data = .);
|
||||||
|
.data : { *(.data .data.* .gnu.linkonce.d*) }
|
||||||
|
.bss (NOLOAD) : {
|
||||||
|
. = ALIGN(16);
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
__bss_end = .;
|
||||||
|
}
|
||||||
|
_end = .;
|
||||||
|
|
||||||
|
/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
|
||||||
|
}
|
||||||
|
__bss_size = (__bss_end - __bss_start)>>3;
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uart.h"
|
||||||
|
#include "mbox.h"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// set up serial console
|
||||||
|
uart_init();
|
||||||
|
|
||||||
|
// get the command line with a mailbox call
|
||||||
|
mbox[0] = 8*4; // length of the message
|
||||||
|
mbox[1] = MBOX_REQUEST; // this is a request message
|
||||||
|
|
||||||
|
mbox[2] = MBOX_TAG_GETSERIAL; // get serial number command
|
||||||
|
mbox[3] = 0; // no input arguments
|
||||||
|
mbox[4] = 0;
|
||||||
|
mbox[5] = 0; // clear output buffer
|
||||||
|
mbox[6] = 0;
|
||||||
|
|
||||||
|
mbox[7] = MBOX_TAG_LAST;
|
||||||
|
|
||||||
|
// send the message to the GPU and receive answer
|
||||||
|
if (mbox_call(MBOX_CH_PROP)) {
|
||||||
|
uart_puts("My serial number is: ");
|
||||||
|
uart_hex(mbox[6]);
|
||||||
|
uart_hex(mbox[5]);
|
||||||
|
uart_puts("\n");
|
||||||
|
} else {
|
||||||
|
uart_puts("Unable to query serial!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// echo everything back
|
||||||
|
while(1) {
|
||||||
|
uart_send(uart_getc());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
/* mailbox message buffer */
|
||||||
|
volatile unsigned int __attribute__((aligned(16))) mbox[36];
|
||||||
|
|
||||||
|
#define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880)
|
||||||
|
#define MBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0))
|
||||||
|
#define MBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10))
|
||||||
|
#define MBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14))
|
||||||
|
#define MBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18))
|
||||||
|
#define MBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C))
|
||||||
|
#define MBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20))
|
||||||
|
#define MBOX_RESPONSE 0x80000000
|
||||||
|
#define MBOX_FULL 0x80000000
|
||||||
|
#define MBOX_EMPTY 0x40000000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a mailbox call. Returns 0 on failure, non-zero on success
|
||||||
|
*/
|
||||||
|
int mbox_call(unsigned char ch)
|
||||||
|
{
|
||||||
|
unsigned int r;
|
||||||
|
/* wait until we can write to the mailbox */
|
||||||
|
do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_FULL);
|
||||||
|
/* write the address of our message to the mailbox with channel identifier */
|
||||||
|
*MBOX_WRITE = (((unsigned int)((unsigned long)&mbox)&~0xF) | (ch&0xF));
|
||||||
|
/* now wait for the response */
|
||||||
|
while(1) {
|
||||||
|
/* is there a response? */
|
||||||
|
do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_EMPTY);
|
||||||
|
r=*MBOX_READ;
|
||||||
|
/* is it a response to our message? */
|
||||||
|
if((unsigned char)(r&0xF)==ch && (r&~0xF)==(unsigned int)((unsigned long)&mbox))
|
||||||
|
/* is it a valid successful response? */
|
||||||
|
return mbox[1]==MBOX_RESPONSE;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* a properly aligned buffer */
|
||||||
|
extern volatile unsigned int mbox[36];
|
||||||
|
|
||||||
|
#define MBOX_REQUEST 0
|
||||||
|
|
||||||
|
/* channels */
|
||||||
|
#define MBOX_CH_POWER 0
|
||||||
|
#define MBOX_CH_FB 1
|
||||||
|
#define MBOX_CH_VUART 2
|
||||||
|
#define MBOX_CH_VCHIQ 3
|
||||||
|
#define MBOX_CH_LEDS 4
|
||||||
|
#define MBOX_CH_BTNS 5
|
||||||
|
#define MBOX_CH_TOUCH 6
|
||||||
|
#define MBOX_CH_COUNT 7
|
||||||
|
#define MBOX_CH_PROP 8
|
||||||
|
|
||||||
|
/* tags */
|
||||||
|
#define MBOX_TAG_GETSERIAL 0x10004
|
||||||
|
#define MBOX_TAG_LAST 0
|
||||||
|
|
||||||
|
int mbox_call(unsigned char ch);
|
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section ".text.boot"
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
// read cpu id, stop slave cores
|
||||||
|
mrs x1, mpidr_el1
|
||||||
|
and x1, x1, #3
|
||||||
|
cbz x1, 2f
|
||||||
|
// cpu id > 0, stop
|
||||||
|
1: wfe
|
||||||
|
b 1b
|
||||||
|
2: // cpu id == 0
|
||||||
|
|
||||||
|
// set stack before our code
|
||||||
|
ldr x1, =_start
|
||||||
|
mov sp, x1
|
||||||
|
|
||||||
|
// clear bss
|
||||||
|
ldr x1, =__bss_start
|
||||||
|
ldr w2, =__bss_size
|
||||||
|
3: cbz w2, 4f
|
||||||
|
str xzr, [x1], #8
|
||||||
|
sub w2, w2, #1
|
||||||
|
cbnz w2, 3b
|
||||||
|
|
||||||
|
// jump to C code, should not return
|
||||||
|
4: bl main
|
||||||
|
// for failsafe, halt this core too
|
||||||
|
b 1b
|
@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
/* Auxilary mini UART registers */
|
||||||
|
#define AUX_ENABLE ((volatile unsigned int*)(MMIO_BASE+0x00215004))
|
||||||
|
#define AUX_MU_IO ((volatile unsigned int*)(MMIO_BASE+0x00215040))
|
||||||
|
#define AUX_MU_IER ((volatile unsigned int*)(MMIO_BASE+0x00215044))
|
||||||
|
#define AUX_MU_IIR ((volatile unsigned int*)(MMIO_BASE+0x00215048))
|
||||||
|
#define AUX_MU_LCR ((volatile unsigned int*)(MMIO_BASE+0x0021504C))
|
||||||
|
#define AUX_MU_MCR ((volatile unsigned int*)(MMIO_BASE+0x00215050))
|
||||||
|
#define AUX_MU_LSR ((volatile unsigned int*)(MMIO_BASE+0x00215054))
|
||||||
|
#define AUX_MU_MSR ((volatile unsigned int*)(MMIO_BASE+0x00215058))
|
||||||
|
#define AUX_MU_SCRATCH ((volatile unsigned int*)(MMIO_BASE+0x0021505C))
|
||||||
|
#define AUX_MU_CNTL ((volatile unsigned int*)(MMIO_BASE+0x00215060))
|
||||||
|
#define AUX_MU_STAT ((volatile unsigned int*)(MMIO_BASE+0x00215064))
|
||||||
|
#define AUX_MU_BAUD ((volatile unsigned int*)(MMIO_BASE+0x00215068))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set baud rate and characteristics (115200 8N1) and map to GPIO
|
||||||
|
*/
|
||||||
|
void uart_init()
|
||||||
|
{
|
||||||
|
register unsigned int r;
|
||||||
|
|
||||||
|
/* initialize UART */
|
||||||
|
*AUX_ENABLE |=1; // enable UART1, AUX mini uart
|
||||||
|
*AUX_MU_IER = 0;
|
||||||
|
*AUX_MU_CNTL = 0;
|
||||||
|
*AUX_MU_LCR = 3; // 8 bits
|
||||||
|
*AUX_MU_MCR = 0;
|
||||||
|
*AUX_MU_IER = 0;
|
||||||
|
*AUX_MU_IIR = 0xc6; // disable interrupts
|
||||||
|
*AUX_MU_BAUD = 270; // 115200 baud
|
||||||
|
/* map UART1 to GPIO pins */
|
||||||
|
r=*GPFSEL1;
|
||||||
|
r&=~((7<<12)|(7<<15)); // gpio14, gpio15
|
||||||
|
r|=(2<<12)|(2<<15); // alt5
|
||||||
|
*GPFSEL1 = r;
|
||||||
|
*GPPUD = 0; // enable pins 14 and 15
|
||||||
|
r=150; while(r--) { asm volatile("nop"); }
|
||||||
|
*GPPUDCLK0 = (1<<14)|(1<<15);
|
||||||
|
r=150; while(r--) { asm volatile("nop"); }
|
||||||
|
*GPPUDCLK0 = 0; // flush GPIO setup
|
||||||
|
*AUX_MU_CNTL = 3; // enable Tx, Rx
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a character
|
||||||
|
*/
|
||||||
|
void uart_send(unsigned int c) {
|
||||||
|
/* wait until we can send */
|
||||||
|
do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x20));
|
||||||
|
/* write the carachter to the buffer */
|
||||||
|
*AUX_MU_IO=c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receive a character
|
||||||
|
*/
|
||||||
|
char uart_getc() {
|
||||||
|
char r;
|
||||||
|
/* wait until something is in the buffer */
|
||||||
|
do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x01));
|
||||||
|
/* read it and return */
|
||||||
|
r=(char)(*AUX_MU_IO);
|
||||||
|
/* convert carrige return to newline */
|
||||||
|
return r=='\r'?'\n':r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a string
|
||||||
|
*/
|
||||||
|
void uart_puts(char *s) {
|
||||||
|
while(*s) {
|
||||||
|
/* convert newline to carrige return + newline */
|
||||||
|
if(*s=='\n')
|
||||||
|
uart_send('\r');
|
||||||
|
uart_send(*s++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a binary value in hexadecimal
|
||||||
|
*/
|
||||||
|
void uart_hex(unsigned int d) {
|
||||||
|
unsigned int n;
|
||||||
|
int c;
|
||||||
|
for(c=28;c>=0;c-=4) {
|
||||||
|
// get highest tetrad
|
||||||
|
n=(d>>c)&0xF;
|
||||||
|
// 0-9 => '0'-'9', 10-15 => 'A'-'F'
|
||||||
|
n+=n>9?0x37:0x30;
|
||||||
|
uart_send(n);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void uart_init();
|
||||||
|
void uart_send(unsigned int c);
|
||||||
|
char uart_getc();
|
||||||
|
void uart_puts(char *s);
|
||||||
|
void uart_hex(unsigned int d);
|
@ -0,0 +1,43 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person
|
||||||
|
# obtaining a copy of this software and associated documentation
|
||||||
|
# files (the "Software"), to deal in the Software without
|
||||||
|
# restriction, including without limitation the rights to use, copy,
|
||||||
|
# modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
# of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be
|
||||||
|
# included in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
SRCS = $(wildcard *.c)
|
||||||
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
start.o: start.S
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c start.S -o start.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: start.o $(OBJS)
|
||||||
|
aarch64-elf-ld -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf
|
||||||
|
aarch64-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm kernel8.elf *.o >/dev/null 2>/dev/null || true
|
@ -0,0 +1,22 @@
|
|||||||
|
Oktatóanyag 05 - UART0, PL011
|
||||||
|
=============================
|
||||||
|
|
||||||
|
Ebben az okatatóanyagban ugyanazt csináljuk, mint a 4-esben, de most a szériaszámot az UART0-ra küldjük ki.
|
||||||
|
Emiatt ez a példa könnyen használható qemu-val is:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial stdio
|
||||||
|
My serial number is: 0000000000000000
|
||||||
|
```
|
||||||
|
|
||||||
|
Uart.h, uart.c
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Mielőtt a frekvenciaosztót megadhatnánk, be kell állítanunk egy fix órajelet a PL011 csipben. Ezt levelesládán
|
||||||
|
keresztül tehetjük meg, ugyanazon a property csatornán keresztül, amit már korábban is használtunk. Ettől eltekintve
|
||||||
|
ez az interfész teljesen azonos az UART1-ével.
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
Lekérjük az alaplap egyedi szériaszámát, majd kiírjuk a soros konzolra.
|
@ -0,0 +1,22 @@
|
|||||||
|
Tutorial 05 - UART0, PL011
|
||||||
|
==========================
|
||||||
|
|
||||||
|
This tutorial does the same as tutorial 04, but it prints the serial number on UART0. As such, it can be used
|
||||||
|
easily with qemu, like
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial stdio
|
||||||
|
My serial number is: 0000000000000000
|
||||||
|
```
|
||||||
|
|
||||||
|
Uart.h, uart.c
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Before we could use a rate divisor value, we must establish a valid clock rate for the PL011. It's done
|
||||||
|
via mailboxes, with the same property channel we used earlier. Otherwise this interface is identical to the
|
||||||
|
UART1 one.
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
We query the board's serial number and then we display it on the serial console.
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MMIO_BASE 0x3F000000
|
||||||
|
|
||||||
|
#define GPFSEL0 ((volatile unsigned int*)(MMIO_BASE+0x00200000))
|
||||||
|
#define GPFSEL1 ((volatile unsigned int*)(MMIO_BASE+0x00200004))
|
||||||
|
#define GPFSEL2 ((volatile unsigned int*)(MMIO_BASE+0x00200008))
|
||||||
|
#define GPFSEL3 ((volatile unsigned int*)(MMIO_BASE+0x0020000C))
|
||||||
|
#define GPFSEL4 ((volatile unsigned int*)(MMIO_BASE+0x00200010))
|
||||||
|
#define GPFSEL5 ((volatile unsigned int*)(MMIO_BASE+0x00200014))
|
||||||
|
#define GPSET0 ((volatile unsigned int*)(MMIO_BASE+0x0020001C))
|
||||||
|
#define GPSET1 ((volatile unsigned int*)(MMIO_BASE+0x00200020))
|
||||||
|
#define GPCLR0 ((volatile unsigned int*)(MMIO_BASE+0x00200028))
|
||||||
|
#define GPLEV0 ((volatile unsigned int*)(MMIO_BASE+0x00200034))
|
||||||
|
#define GPLEV1 ((volatile unsigned int*)(MMIO_BASE+0x00200038))
|
||||||
|
#define GPEDS0 ((volatile unsigned int*)(MMIO_BASE+0x00200040))
|
||||||
|
#define GPEDS1 ((volatile unsigned int*)(MMIO_BASE+0x00200044))
|
||||||
|
#define GPHEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200064))
|
||||||
|
#define GPHEN1 ((volatile unsigned int*)(MMIO_BASE+0x00200068))
|
||||||
|
#define GPPUD ((volatile unsigned int*)(MMIO_BASE+0x00200094))
|
||||||
|
#define GPPUDCLK0 ((volatile unsigned int*)(MMIO_BASE+0x00200098))
|
||||||
|
#define GPPUDCLK1 ((volatile unsigned int*)(MMIO_BASE+0x0020009C))
|
Binary file not shown.
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x80000;
|
||||||
|
.text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) }
|
||||||
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) }
|
||||||
|
PROVIDE(_data = .);
|
||||||
|
.data : { *(.data .data.* .gnu.linkonce.d*) }
|
||||||
|
.bss (NOLOAD) : {
|
||||||
|
. = ALIGN(16);
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
__bss_end = .;
|
||||||
|
}
|
||||||
|
_end = .;
|
||||||
|
|
||||||
|
/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
|
||||||
|
}
|
||||||
|
__bss_size = (__bss_end - __bss_start)>>3;
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uart.h"
|
||||||
|
#include "mbox.h"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// set up serial console
|
||||||
|
uart_init();
|
||||||
|
|
||||||
|
// get the command line with a mailbox call
|
||||||
|
mbox[0] = 8*4; // length of the message
|
||||||
|
mbox[1] = MBOX_REQUEST; // this is a request message
|
||||||
|
|
||||||
|
mbox[2] = MBOX_TAG_GETSERIAL; // get serial number command
|
||||||
|
mbox[3] = 0; // no input arguments
|
||||||
|
mbox[4] = 0;
|
||||||
|
mbox[5] = 0; // clear output buffer
|
||||||
|
mbox[6] = 0;
|
||||||
|
|
||||||
|
mbox[7] = MBOX_TAG_LAST;
|
||||||
|
|
||||||
|
// send the message to the GPU and receive answer
|
||||||
|
if (mbox_call(MBOX_CH_PROP)) {
|
||||||
|
uart_puts("My serial number is: ");
|
||||||
|
uart_hex(mbox[6]);
|
||||||
|
uart_hex(mbox[5]);
|
||||||
|
uart_puts("\n");
|
||||||
|
} else {
|
||||||
|
uart_puts("Unable to query serial!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// echo everything back
|
||||||
|
while(1) {
|
||||||
|
uart_send(uart_getc());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
/* mailbox message buffer */
|
||||||
|
volatile unsigned int __attribute__((aligned(16))) mbox[36];
|
||||||
|
|
||||||
|
#define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880)
|
||||||
|
#define MBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0))
|
||||||
|
#define MBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10))
|
||||||
|
#define MBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14))
|
||||||
|
#define MBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18))
|
||||||
|
#define MBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C))
|
||||||
|
#define MBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20))
|
||||||
|
#define MBOX_RESPONSE 0x80000000
|
||||||
|
#define MBOX_FULL 0x80000000
|
||||||
|
#define MBOX_EMPTY 0x40000000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a mailbox call. Returns 0 on failure, non-zero on success
|
||||||
|
*/
|
||||||
|
int mbox_call(unsigned char ch)
|
||||||
|
{
|
||||||
|
unsigned int r;
|
||||||
|
/* wait until we can write to the mailbox */
|
||||||
|
do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_FULL);
|
||||||
|
/* write the address of our message to the mailbox with channel identifier */
|
||||||
|
*MBOX_WRITE = (((unsigned int)((unsigned long)&mbox)&~0xF) | (ch&0xF));
|
||||||
|
/* now wait for the response */
|
||||||
|
while(1) {
|
||||||
|
/* is there a response? */
|
||||||
|
do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_EMPTY);
|
||||||
|
r=*MBOX_READ;
|
||||||
|
/* is it a response to our message? */
|
||||||
|
if((unsigned char)(r&0xF)==ch && (r&~0xF)==(unsigned int)((unsigned long)&mbox))
|
||||||
|
/* is it a valid successful response? */
|
||||||
|
return mbox[1]==MBOX_RESPONSE;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* a properly aligned buffer */
|
||||||
|
extern volatile unsigned int mbox[36];
|
||||||
|
|
||||||
|
#define MBOX_REQUEST 0
|
||||||
|
|
||||||
|
/* channels */
|
||||||
|
#define MBOX_CH_POWER 0
|
||||||
|
#define MBOX_CH_FB 1
|
||||||
|
#define MBOX_CH_VUART 2
|
||||||
|
#define MBOX_CH_VCHIQ 3
|
||||||
|
#define MBOX_CH_LEDS 4
|
||||||
|
#define MBOX_CH_BTNS 5
|
||||||
|
#define MBOX_CH_TOUCH 6
|
||||||
|
#define MBOX_CH_COUNT 7
|
||||||
|
#define MBOX_CH_PROP 8
|
||||||
|
|
||||||
|
/* tags */
|
||||||
|
#define MBOX_TAG_GETSERIAL 0x10004
|
||||||
|
#define MBOX_TAG_SETCLKRATE 0x38002
|
||||||
|
#define MBOX_TAG_LAST 0
|
||||||
|
|
||||||
|
int mbox_call(unsigned char ch);
|
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section ".text.boot"
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
// read cpu id, stop slave cores
|
||||||
|
mrs x1, mpidr_el1
|
||||||
|
and x1, x1, #3
|
||||||
|
cbz x1, 2f
|
||||||
|
// cpu id > 0, stop
|
||||||
|
1: wfe
|
||||||
|
b 1b
|
||||||
|
2: // cpu id == 0
|
||||||
|
|
||||||
|
// set stack before our code
|
||||||
|
ldr x1, =_start
|
||||||
|
mov sp, x1
|
||||||
|
|
||||||
|
// clear bss
|
||||||
|
ldr x1, =__bss_start
|
||||||
|
ldr w2, =__bss_size
|
||||||
|
3: cbz w2, 4f
|
||||||
|
str xzr, [x1], #8
|
||||||
|
sub w2, w2, #1
|
||||||
|
cbnz w2, 3b
|
||||||
|
|
||||||
|
// jump to C code, should not return
|
||||||
|
4: bl main
|
||||||
|
// for failsafe, halt this core too
|
||||||
|
b 1b
|
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
#include "mbox.h"
|
||||||
|
|
||||||
|
/* PL011 UART registers */
|
||||||
|
#define UART0_DR ((volatile unsigned int*)(MMIO_BASE+0x00201000))
|
||||||
|
#define UART0_FR ((volatile unsigned int*)(MMIO_BASE+0x00201018))
|
||||||
|
#define UART0_IBRD ((volatile unsigned int*)(MMIO_BASE+0x00201024))
|
||||||
|
#define UART0_FBRD ((volatile unsigned int*)(MMIO_BASE+0x00201028))
|
||||||
|
#define UART0_LCRH ((volatile unsigned int*)(MMIO_BASE+0x0020102C))
|
||||||
|
#define UART0_CR ((volatile unsigned int*)(MMIO_BASE+0x00201030))
|
||||||
|
#define UART0_IMSC ((volatile unsigned int*)(MMIO_BASE+0x00201038))
|
||||||
|
#define UART0_ICR ((volatile unsigned int*)(MMIO_BASE+0x00201044))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set baud rate and characteristics (115200 8N1) and map to GPIO
|
||||||
|
*/
|
||||||
|
void uart_init()
|
||||||
|
{
|
||||||
|
register unsigned int r;
|
||||||
|
|
||||||
|
/* initialize UART */
|
||||||
|
*UART0_CR = 0; // turn off UART0
|
||||||
|
|
||||||
|
/* set up clock for consistent divisor values */
|
||||||
|
mbox[0] = 8*4;
|
||||||
|
mbox[1] = MBOX_REQUEST;
|
||||||
|
mbox[2] = MBOX_TAG_SETCLKRATE; // set clock rate
|
||||||
|
mbox[3] = 12;
|
||||||
|
mbox[4] = 8;
|
||||||
|
mbox[5] = 2; // UART clock
|
||||||
|
mbox[6] = 4000000; // 4Mhz
|
||||||
|
mbox[7] = MBOX_TAG_LAST;
|
||||||
|
mbox_call(MBOX_CH_PROP);
|
||||||
|
|
||||||
|
/* map UART0 to GPIO pins */
|
||||||
|
r=*GPFSEL1;
|
||||||
|
r&=~((7<<12)|(7<<15)); // gpio14, gpio15
|
||||||
|
r|=(2<<12)|(2<<15); // alt5
|
||||||
|
*GPFSEL1 = r;
|
||||||
|
*GPPUD = 0; // enable pins 14 and 15
|
||||||
|
r=150; while(r--) { asm volatile("nop"); }
|
||||||
|
*GPPUDCLK0 = (1<<14)|(1<<15);
|
||||||
|
r=150; while(r--) { asm volatile("nop"); }
|
||||||
|
*GPPUDCLK0 = 0; // flush GPIO setup
|
||||||
|
|
||||||
|
*UART0_ICR = 0x7FF; // clear interrupts
|
||||||
|
*UART0_IBRD = 2; // 115200 baud
|
||||||
|
*UART0_FBRD = 0xB;
|
||||||
|
*UART0_LCRH = 0b11<<5; // 8n1
|
||||||
|
*UART0_CR = 0x301; // enable Tx, Rx, FIFO
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a character
|
||||||
|
*/
|
||||||
|
void uart_send(unsigned int c) {
|
||||||
|
/* wait until we can send */
|
||||||
|
do{asm volatile("nop");}while(*UART0_FR&0x20);
|
||||||
|
/* write the carachter to the buffer */
|
||||||
|
*UART0_DR=c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receive a character
|
||||||
|
*/
|
||||||
|
char uart_getc() {
|
||||||
|
char r;
|
||||||
|
/* wait until something is in the buffer */
|
||||||
|
do{asm volatile("nop");}while(*UART0_FR&0x10);
|
||||||
|
/* read it and return */
|
||||||
|
r=(char)(*UART0_DR);
|
||||||
|
/* convert carrige return to newline */
|
||||||
|
return r=='\r'?'\n':r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a string
|
||||||
|
*/
|
||||||
|
void uart_puts(char *s) {
|
||||||
|
while(*s) {
|
||||||
|
/* convert newline to carrige return + newline */
|
||||||
|
if(*s=='\n')
|
||||||
|
uart_send('\r');
|
||||||
|
uart_send(*s++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a binary value in hexadecimal
|
||||||
|
*/
|
||||||
|
void uart_hex(unsigned int d) {
|
||||||
|
unsigned int n;
|
||||||
|
int c;
|
||||||
|
for(c=28;c>=0;c-=4) {
|
||||||
|
// get highest tetrad
|
||||||
|
n=(d>>c)&0xF;
|
||||||
|
// 0-9 => '0'-'9', 10-15 => 'A'-'F'
|
||||||
|
n+=n>9?0x37:0x30;
|
||||||
|
uart_send(n);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void uart_init();
|
||||||
|
void uart_send(unsigned int c);
|
||||||
|
char uart_getc();
|
||||||
|
void uart_puts(char *s);
|
||||||
|
void uart_hex(unsigned int d);
|
@ -0,0 +1,43 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person
|
||||||
|
# obtaining a copy of this software and associated documentation
|
||||||
|
# files (the "Software"), to deal in the Software without
|
||||||
|
# restriction, including without limitation the rights to use, copy,
|
||||||
|
# modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
# of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be
|
||||||
|
# included in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
SRCS = $(wildcard *.c)
|
||||||
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
start.o: start.S
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c start.S -o start.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: start.o $(OBJS)
|
||||||
|
aarch64-elf-ld -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf
|
||||||
|
aarch64-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm kernel8.elf *.o >/dev/null 2>/dev/null || true
|
@ -0,0 +1,19 @@
|
|||||||
|
Oktatóanyag 06 - Hardveres Véletlenszám Generátor
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
Ez egy egyszerű okatatóanyag lesz. Lekérjük az aktuális értéket (az egyéként nem dokumentált)
|
||||||
|
hardveres véletlenszám generátorból. Ez arra használható többek között, hogy egy egyszerű, megfelelő
|
||||||
|
kockadobást szimuláljunk bármilyen játékban. Ez azért fontos, mert hardveres támogatás nélkül csak
|
||||||
|
kizárólag pszeudo-véletlen állítható elő.
|
||||||
|
|
||||||
|
Rand.h, rand.c
|
||||||
|
--------------
|
||||||
|
|
||||||
|
`rand_init()` inicializálja a hardvert.
|
||||||
|
|
||||||
|
`rand(min,max)` visszaad egy min és max közötti véletlen számot.
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
Lekérjük a véletlen számot, és kiírjuk a soros konzolra.
|
@ -0,0 +1,18 @@
|
|||||||
|
Tutorial 06 - Hardware Random Number Generator
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
This going to be an easy tutorial. We query a number from the (undocumented) hardware random
|
||||||
|
number generator. You can use this to implement a simple, but accurate dice throw in any game.
|
||||||
|
It is important as without hardware support you can only generate pseudo-random numbers.
|
||||||
|
|
||||||
|
Rand.h, rand.c
|
||||||
|
--------------
|
||||||
|
|
||||||
|
`rand_init()` initializes the hardware.
|
||||||
|
|
||||||
|
`rand(min,max)` returns a random number between min and max.
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
We query a random value and then we display it on the serial console.
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MMIO_BASE 0x3F000000
|
||||||
|
|
||||||
|
#define GPFSEL0 ((volatile unsigned int*)(MMIO_BASE+0x00200000))
|
||||||
|
#define GPFSEL1 ((volatile unsigned int*)(MMIO_BASE+0x00200004))
|
||||||
|
#define GPFSEL2 ((volatile unsigned int*)(MMIO_BASE+0x00200008))
|
||||||
|
#define GPFSEL3 ((volatile unsigned int*)(MMIO_BASE+0x0020000C))
|
||||||
|
#define GPFSEL4 ((volatile unsigned int*)(MMIO_BASE+0x00200010))
|
||||||
|
#define GPFSEL5 ((volatile unsigned int*)(MMIO_BASE+0x00200014))
|
||||||
|
#define GPSET0 ((volatile unsigned int*)(MMIO_BASE+0x0020001C))
|
||||||
|
#define GPSET1 ((volatile unsigned int*)(MMIO_BASE+0x00200020))
|
||||||
|
#define GPCLR0 ((volatile unsigned int*)(MMIO_BASE+0x00200028))
|
||||||
|
#define GPLEV0 ((volatile unsigned int*)(MMIO_BASE+0x00200034))
|
||||||
|
#define GPLEV1 ((volatile unsigned int*)(MMIO_BASE+0x00200038))
|
||||||
|
#define GPEDS0 ((volatile unsigned int*)(MMIO_BASE+0x00200040))
|
||||||
|
#define GPEDS1 ((volatile unsigned int*)(MMIO_BASE+0x00200044))
|
||||||
|
#define GPHEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200064))
|
||||||
|
#define GPHEN1 ((volatile unsigned int*)(MMIO_BASE+0x00200068))
|
||||||
|
#define GPPUD ((volatile unsigned int*)(MMIO_BASE+0x00200094))
|
||||||
|
#define GPPUDCLK0 ((volatile unsigned int*)(MMIO_BASE+0x00200098))
|
||||||
|
#define GPPUDCLK1 ((volatile unsigned int*)(MMIO_BASE+0x0020009C))
|
Binary file not shown.
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x80000;
|
||||||
|
.text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) }
|
||||||
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) }
|
||||||
|
PROVIDE(_data = .);
|
||||||
|
.data : { *(.data .data.* .gnu.linkonce.d*) }
|
||||||
|
.bss (NOLOAD) : {
|
||||||
|
. = ALIGN(16);
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
__bss_end = .;
|
||||||
|
}
|
||||||
|
_end = .;
|
||||||
|
|
||||||
|
/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
|
||||||
|
}
|
||||||
|
__bss_size = (__bss_end - __bss_start)>>3;
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uart.h"
|
||||||
|
#include "rand.h"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// set up serial console and random number generator
|
||||||
|
uart_init();
|
||||||
|
rand_init();
|
||||||
|
|
||||||
|
uart_puts("Here goes a random number: ");
|
||||||
|
uart_hex(rand(0,4294967295));
|
||||||
|
uart_puts("\n");
|
||||||
|
|
||||||
|
// echo everything back
|
||||||
|
while(1) {
|
||||||
|
uart_send(uart_getc());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
/* mailbox message buffer */
|
||||||
|
volatile unsigned int __attribute__((aligned(16))) mbox[36];
|
||||||
|
|
||||||
|
#define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880)
|
||||||
|
#define MBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0))
|
||||||
|
#define MBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10))
|
||||||
|
#define MBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14))
|
||||||
|
#define MBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18))
|
||||||
|
#define MBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C))
|
||||||
|
#define MBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20))
|
||||||
|
#define MBOX_RESPONSE 0x80000000
|
||||||
|
#define MBOX_FULL 0x80000000
|
||||||
|
#define MBOX_EMPTY 0x40000000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a mailbox call. Returns 0 on failure, non-zero on success
|
||||||
|
*/
|
||||||
|
int mbox_call(unsigned char ch)
|
||||||
|
{
|
||||||
|
unsigned int r;
|
||||||
|
/* wait until we can write to the mailbox */
|
||||||
|
do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_FULL);
|
||||||
|
/* write the address of our message to the mailbox with channel identifier */
|
||||||
|
*MBOX_WRITE = (((unsigned int)((unsigned long)&mbox)&~0xF) | (ch&0xF));
|
||||||
|
/* now wait for the response */
|
||||||
|
while(1) {
|
||||||
|
/* is there a response? */
|
||||||
|
do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_EMPTY);
|
||||||
|
r=*MBOX_READ;
|
||||||
|
/* is it a response to our message? */
|
||||||
|
if((unsigned char)(r&0xF)==ch && (r&~0xF)==(unsigned int)((unsigned long)&mbox))
|
||||||
|
/* is it a valid successful response? */
|
||||||
|
return mbox[1]==MBOX_RESPONSE;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* a properly aligned buffer */
|
||||||
|
extern volatile unsigned int mbox[36];
|
||||||
|
|
||||||
|
#define MBOX_REQUEST 0
|
||||||
|
|
||||||
|
/* channels */
|
||||||
|
#define MBOX_CH_POWER 0
|
||||||
|
#define MBOX_CH_FB 1
|
||||||
|
#define MBOX_CH_VUART 2
|
||||||
|
#define MBOX_CH_VCHIQ 3
|
||||||
|
#define MBOX_CH_LEDS 4
|
||||||
|
#define MBOX_CH_BTNS 5
|
||||||
|
#define MBOX_CH_TOUCH 6
|
||||||
|
#define MBOX_CH_COUNT 7
|
||||||
|
#define MBOX_CH_PROP 8
|
||||||
|
|
||||||
|
/* tags */
|
||||||
|
#define MBOX_TAG_SETCLKRATE 0x38002
|
||||||
|
#define MBOX_TAG_LAST 0
|
||||||
|
|
||||||
|
int mbox_call(unsigned char ch);
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
#define RNG_CTRL ((volatile unsigned int*)(MMIO_BASE+0x00104000))
|
||||||
|
#define RNG_STATUS ((volatile unsigned int*)(MMIO_BASE+0x00104004))
|
||||||
|
#define RNG_DATA ((volatile unsigned int*)(MMIO_BASE+0x00104008))
|
||||||
|
#define RNG_INT_MASK ((volatile unsigned int*)(MMIO_BASE+0x00104010))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the RNG
|
||||||
|
*/
|
||||||
|
void rand_init()
|
||||||
|
{
|
||||||
|
*RNG_STATUS=0x40000;
|
||||||
|
// mask interrupt
|
||||||
|
*RNG_INT_MASK|=1;
|
||||||
|
// enable
|
||||||
|
*RNG_CTRL|=1;
|
||||||
|
// wait for gaining some entropy
|
||||||
|
while(!((*RNG_STATUS)>>24)) asm volatile("nop");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a random number between [min..max]
|
||||||
|
*/
|
||||||
|
unsigned int rand(unsigned int min, unsigned int max)
|
||||||
|
{
|
||||||
|
return *RNG_DATA % (max-min) + min;
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void rand_init();
|
||||||
|
unsigned int rand(unsigned int min, unsigned int max);
|
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section ".text.boot"
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
// read cpu id, stop slave cores
|
||||||
|
mrs x1, mpidr_el1
|
||||||
|
and x1, x1, #3
|
||||||
|
cbz x1, 2f
|
||||||
|
// cpu id > 0, stop
|
||||||
|
1: wfe
|
||||||
|
b 1b
|
||||||
|
2: // cpu id == 0
|
||||||
|
|
||||||
|
// set stack before our code
|
||||||
|
ldr x1, =_start
|
||||||
|
mov sp, x1
|
||||||
|
|
||||||
|
// clear bss
|
||||||
|
ldr x1, =__bss_start
|
||||||
|
ldr w2, =__bss_size
|
||||||
|
3: cbz w2, 4f
|
||||||
|
str xzr, [x1], #8
|
||||||
|
sub w2, w2, #1
|
||||||
|
cbnz w2, 3b
|
||||||
|
|
||||||
|
// jump to C code, should not return
|
||||||
|
4: bl main
|
||||||
|
// for failsafe, halt this core too
|
||||||
|
b 1b
|
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
#include "mbox.h"
|
||||||
|
|
||||||
|
/* PL011 UART registers */
|
||||||
|
#define UART0_DR ((volatile unsigned int*)(MMIO_BASE+0x00201000))
|
||||||
|
#define UART0_FR ((volatile unsigned int*)(MMIO_BASE+0x00201018))
|
||||||
|
#define UART0_IBRD ((volatile unsigned int*)(MMIO_BASE+0x00201024))
|
||||||
|
#define UART0_FBRD ((volatile unsigned int*)(MMIO_BASE+0x00201028))
|
||||||
|
#define UART0_LCRH ((volatile unsigned int*)(MMIO_BASE+0x0020102C))
|
||||||
|
#define UART0_CR ((volatile unsigned int*)(MMIO_BASE+0x00201030))
|
||||||
|
#define UART0_IMSC ((volatile unsigned int*)(MMIO_BASE+0x00201038))
|
||||||
|
#define UART0_ICR ((volatile unsigned int*)(MMIO_BASE+0x00201044))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set baud rate and characteristics (115200 8N1) and map to GPIO
|
||||||
|
*/
|
||||||
|
void uart_init()
|
||||||
|
{
|
||||||
|
register unsigned int r;
|
||||||
|
|
||||||
|
/* initialize UART */
|
||||||
|
*UART0_CR = 0; // turn off UART0
|
||||||
|
|
||||||
|
/* set up clock for consistent divisor values */
|
||||||
|
mbox[0] = 8*4;
|
||||||
|
mbox[1] = MBOX_REQUEST;
|
||||||
|
mbox[2] = MBOX_TAG_SETCLKRATE; // set clock rate
|
||||||
|
mbox[3] = 12;
|
||||||
|
mbox[4] = 8;
|
||||||
|
mbox[5] = 2; // UART clock
|
||||||
|
mbox[6] = 4000000; // 4Mhz
|
||||||
|
mbox[7] = MBOX_TAG_LAST;
|
||||||
|
mbox_call(MBOX_CH_PROP);
|
||||||
|
|
||||||
|
/* map UART0 to GPIO pins */
|
||||||
|
r=*GPFSEL1;
|
||||||
|
r&=~((7<<12)|(7<<15)); // gpio14, gpio15
|
||||||
|
r|=(2<<12)|(2<<15); // alt5
|
||||||
|
*GPFSEL1 = r;
|
||||||
|
*GPPUD = 0; // enable pins 14 and 15
|
||||||
|
r=150; while(r--) { asm volatile("nop"); }
|
||||||
|
*GPPUDCLK0 = (1<<14)|(1<<15);
|
||||||
|
r=150; while(r--) { asm volatile("nop"); }
|
||||||
|
*GPPUDCLK0 = 0; // flush GPIO setup
|
||||||
|
|
||||||
|
*UART0_ICR = 0x7FF; // clear interrupts
|
||||||
|
*UART0_IBRD = 2; // 115200 baud
|
||||||
|
*UART0_FBRD = 0xB;
|
||||||
|
*UART0_LCRH = 0b11<<5; // 8n1
|
||||||
|
*UART0_CR = 0x301; // enable Tx, Rx, FIFO
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a character
|
||||||
|
*/
|
||||||
|
void uart_send(unsigned int c) {
|
||||||
|
/* wait until we can send */
|
||||||
|
do{asm volatile("nop");}while(*UART0_FR&0x20);
|
||||||
|
/* write the carachter to the buffer */
|
||||||
|
*UART0_DR=c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receive a character
|
||||||
|
*/
|
||||||
|
char uart_getc() {
|
||||||
|
char r;
|
||||||
|
/* wait until something is in the buffer */
|
||||||
|
do{asm volatile("nop");}while(*UART0_FR&0x10);
|
||||||
|
/* read it and return */
|
||||||
|
r=(char)(*UART0_DR);
|
||||||
|
/* convert carrige return to newline */
|
||||||
|
return r=='\r'?'\n':r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a string
|
||||||
|
*/
|
||||||
|
void uart_puts(char *s) {
|
||||||
|
while(*s) {
|
||||||
|
/* convert newline to carrige return + newline */
|
||||||
|
if(*s=='\n')
|
||||||
|
uart_send('\r');
|
||||||
|
uart_send(*s++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a binary value in hexadecimal
|
||||||
|
*/
|
||||||
|
void uart_hex(unsigned int d) {
|
||||||
|
unsigned int n;
|
||||||
|
int c;
|
||||||
|
for(c=28;c>=0;c-=4) {
|
||||||
|
// get highest tetrad
|
||||||
|
n=(d>>c)&0xF;
|
||||||
|
// 0-9 => '0'-'9', 10-15 => 'A'-'F'
|
||||||
|
n+=n>9?0x37:0x30;
|
||||||
|
uart_send(n);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void uart_init();
|
||||||
|
void uart_send(unsigned int c);
|
||||||
|
char uart_getc();
|
||||||
|
void uart_puts(char *s);
|
||||||
|
void uart_hex(unsigned int d);
|
@ -0,0 +1,43 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person
|
||||||
|
# obtaining a copy of this software and associated documentation
|
||||||
|
# files (the "Software"), to deal in the Software without
|
||||||
|
# restriction, including without limitation the rights to use, copy,
|
||||||
|
# modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
# of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be
|
||||||
|
# included in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
SRCS = $(wildcard *.c)
|
||||||
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
start.o: start.S
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c start.S -o start.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: start.o $(OBJS)
|
||||||
|
aarch64-elf-ld -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf
|
||||||
|
aarch64-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm kernel8.elf *.o >/dev/null 2>/dev/null || true
|
@ -0,0 +1,20 @@
|
|||||||
|
Oktatóanyag 07 - Késleltetések
|
||||||
|
==============================
|
||||||
|
|
||||||
|
Roppant fontos, hogy a megfelelő időtartamot késleltessünk, amikor alacsony szintű hardverrel bánunk.
|
||||||
|
Ebben az okatatóanyagban három megközelítést nézünk meg. Az egyik CPU órajel függő (akkor hasznos, ha
|
||||||
|
a várakozási idő óraciklusban van megadva), a másik kettő mikroszekundum (másodperc milliomod része) alapú.
|
||||||
|
|
||||||
|
Delays.h, delays.c
|
||||||
|
------------------
|
||||||
|
|
||||||
|
`wait_cycles(n)` ez nagyon faék, n-szer lefuttatjuk a `nop` (nincs utasítás) utasítást.
|
||||||
|
|
||||||
|
`wait_msec(n)` ez a megvalósítás ARM rendszer regisztereket használ (minden AArch64 CPU-n elérhető).
|
||||||
|
|
||||||
|
`wait_msec_st(n)` ez pedig BCM specifikus, ami a Rendszer Időzítő perifériát használja (nincs emulálva qemu-n).
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
Különböző implementációkkal várakozunk a konzolra írások között.
|
@ -0,0 +1,20 @@
|
|||||||
|
Tutorial 07 - Delays
|
||||||
|
====================
|
||||||
|
|
||||||
|
It is very important to wait precise amounts of time while you're interfacing with low level hardware.
|
||||||
|
In this tutorial we'll cover there ways. One is CPU frequency dependent (and useful if wait time is given
|
||||||
|
in CPU clock cycles), the other two are are microsec (millionth of a second) based.
|
||||||
|
|
||||||
|
Delays.h, delays.c
|
||||||
|
------------------
|
||||||
|
|
||||||
|
`wait_cycles(n)` this is a very straightforward thing, we execute the 'nop' instruction n times.
|
||||||
|
|
||||||
|
`wait_msec(n)` this implementation uses ARM system registers (available on all AArch64 CPUs).
|
||||||
|
|
||||||
|
`wait_msec_st(n)` is a BCM specific implementation, which uses the System Timer peripheral (not available on qemu).
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
We use different wait implementations between printing strings on serial console.
|
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
#define SYSTMR_LO ((volatile unsigned int*)(MMIO_BASE+0x00003004))
|
||||||
|
#define SYSTMR_HI ((volatile unsigned int*)(MMIO_BASE+0x00003008))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait N CPU cycles (ARM CPU only)
|
||||||
|
*/
|
||||||
|
void wait_cycles(unsigned int n)
|
||||||
|
{
|
||||||
|
if(n) while(n--) { asm volatile("nop"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait N microsec (ARM CPU only)
|
||||||
|
*/
|
||||||
|
void wait_msec(unsigned int n)
|
||||||
|
{
|
||||||
|
register unsigned long f, t, r;
|
||||||
|
// get the current counter frequency
|
||||||
|
asm volatile ("mrs %0, cntfrq_el0" : "=r"(f));
|
||||||
|
// read the current counter
|
||||||
|
asm volatile ("mrs %0, cntpct_el0" : "=r"(t));
|
||||||
|
// calculate expire value for counter
|
||||||
|
t+=((f/1000)*n)/1000;
|
||||||
|
do{asm volatile ("mrs %0, cntpct_el0" : "=r"(r));}while(r<t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get System Timer's counter
|
||||||
|
*/
|
||||||
|
unsigned long get_system_timer()
|
||||||
|
{
|
||||||
|
unsigned int h=-1, l;
|
||||||
|
// we must read MMIO area as two separate 32 bit reads
|
||||||
|
h=*SYSTMR_HI;
|
||||||
|
l=*SYSTMR_LO;
|
||||||
|
// we have to repeat it if high word changed during read
|
||||||
|
if(h!=*SYSTMR_HI) {
|
||||||
|
h=*SYSTMR_HI;
|
||||||
|
l=*SYSTMR_LO;
|
||||||
|
}
|
||||||
|
// compose long int value
|
||||||
|
return ((unsigned long) h << 32) | l;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait N microsec (with BCM System Timer)
|
||||||
|
*/
|
||||||
|
void wait_msec_st(unsigned int n)
|
||||||
|
{
|
||||||
|
unsigned long t=get_system_timer();
|
||||||
|
// we must check if it's non-zero, because qemu does not emulate
|
||||||
|
// system timer, and returning constant zero would mean infinite loop
|
||||||
|
if(t) while(get_system_timer() < t+n);
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void wait_cycles(unsigned int n);
|
||||||
|
void wait_msec(unsigned int n);
|
||||||
|
unsigned long get_system_timer();
|
||||||
|
void wait_msec_st(unsigned int n);
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MMIO_BASE 0x3F000000
|
||||||
|
|
||||||
|
#define GPFSEL0 ((volatile unsigned int*)(MMIO_BASE+0x00200000))
|
||||||
|
#define GPFSEL1 ((volatile unsigned int*)(MMIO_BASE+0x00200004))
|
||||||
|
#define GPFSEL2 ((volatile unsigned int*)(MMIO_BASE+0x00200008))
|
||||||
|
#define GPFSEL3 ((volatile unsigned int*)(MMIO_BASE+0x0020000C))
|
||||||
|
#define GPFSEL4 ((volatile unsigned int*)(MMIO_BASE+0x00200010))
|
||||||
|
#define GPFSEL5 ((volatile unsigned int*)(MMIO_BASE+0x00200014))
|
||||||
|
#define GPSET0 ((volatile unsigned int*)(MMIO_BASE+0x0020001C))
|
||||||
|
#define GPSET1 ((volatile unsigned int*)(MMIO_BASE+0x00200020))
|
||||||
|
#define GPCLR0 ((volatile unsigned int*)(MMIO_BASE+0x00200028))
|
||||||
|
#define GPLEV0 ((volatile unsigned int*)(MMIO_BASE+0x00200034))
|
||||||
|
#define GPLEV1 ((volatile unsigned int*)(MMIO_BASE+0x00200038))
|
||||||
|
#define GPEDS0 ((volatile unsigned int*)(MMIO_BASE+0x00200040))
|
||||||
|
#define GPEDS1 ((volatile unsigned int*)(MMIO_BASE+0x00200044))
|
||||||
|
#define GPHEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200064))
|
||||||
|
#define GPHEN1 ((volatile unsigned int*)(MMIO_BASE+0x00200068))
|
||||||
|
#define GPPUD ((volatile unsigned int*)(MMIO_BASE+0x00200094))
|
||||||
|
#define GPPUDCLK0 ((volatile unsigned int*)(MMIO_BASE+0x00200098))
|
||||||
|
#define GPPUDCLK1 ((volatile unsigned int*)(MMIO_BASE+0x0020009C))
|
Binary file not shown.
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x80000;
|
||||||
|
.text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) }
|
||||||
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) }
|
||||||
|
PROVIDE(_data = .);
|
||||||
|
.data : { *(.data .data.* .gnu.linkonce.d*) }
|
||||||
|
.bss (NOLOAD) : {
|
||||||
|
. = ALIGN(16);
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
__bss_end = .;
|
||||||
|
}
|
||||||
|
_end = .;
|
||||||
|
|
||||||
|
/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
|
||||||
|
}
|
||||||
|
__bss_size = (__bss_end - __bss_start)>>3;
|
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uart.h"
|
||||||
|
#include "delays.h"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// set up serial console
|
||||||
|
uart_init();
|
||||||
|
|
||||||
|
uart_puts("Waiting 1000000 CPU cycles (ARM CPU): ");
|
||||||
|
wait_cycles(1000000);
|
||||||
|
uart_puts("OK\n");
|
||||||
|
|
||||||
|
uart_puts("Waiting 1000000 microsec (ARM CPU): ");
|
||||||
|
wait_msec(1000000);
|
||||||
|
uart_puts("OK\n");
|
||||||
|
|
||||||
|
uart_puts("Waiting 1000000 microsec (BCM System Timer): ");
|
||||||
|
if(get_system_timer()==0) {
|
||||||
|
uart_puts("Not available\n");
|
||||||
|
} else {
|
||||||
|
wait_msec_st(1000000);
|
||||||
|
uart_puts("OK\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// echo everything back
|
||||||
|
while(1) {
|
||||||
|
uart_send(uart_getc());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
/* mailbox message buffer */
|
||||||
|
volatile unsigned int __attribute__((aligned(16))) mbox[36];
|
||||||
|
|
||||||
|
#define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880)
|
||||||
|
#define MBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0))
|
||||||
|
#define MBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10))
|
||||||
|
#define MBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14))
|
||||||
|
#define MBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18))
|
||||||
|
#define MBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C))
|
||||||
|
#define MBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20))
|
||||||
|
#define MBOX_RESPONSE 0x80000000
|
||||||
|
#define MBOX_FULL 0x80000000
|
||||||
|
#define MBOX_EMPTY 0x40000000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a mailbox call. Returns 0 on failure, non-zero on success
|
||||||
|
*/
|
||||||
|
int mbox_call(unsigned char ch)
|
||||||
|
{
|
||||||
|
unsigned int r;
|
||||||
|
/* wait until we can write to the mailbox */
|
||||||
|
do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_FULL);
|
||||||
|
/* write the address of our message to the mailbox with channel identifier */
|
||||||
|
*MBOX_WRITE = (((unsigned int)((unsigned long)&mbox)&~0xF) | (ch&0xF));
|
||||||
|
/* now wait for the response */
|
||||||
|
while(1) {
|
||||||
|
/* is there a response? */
|
||||||
|
do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_EMPTY);
|
||||||
|
r=*MBOX_READ;
|
||||||
|
/* is it a response to our message? */
|
||||||
|
if((unsigned char)(r&0xF)==ch && (r&~0xF)==(unsigned int)((unsigned long)&mbox))
|
||||||
|
/* is it a valid successful response? */
|
||||||
|
return mbox[1]==MBOX_RESPONSE;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* a properly aligned buffer */
|
||||||
|
extern volatile unsigned int mbox[36];
|
||||||
|
|
||||||
|
#define MBOX_REQUEST 0
|
||||||
|
|
||||||
|
/* channels */
|
||||||
|
#define MBOX_CH_POWER 0
|
||||||
|
#define MBOX_CH_FB 1
|
||||||
|
#define MBOX_CH_VUART 2
|
||||||
|
#define MBOX_CH_VCHIQ 3
|
||||||
|
#define MBOX_CH_LEDS 4
|
||||||
|
#define MBOX_CH_BTNS 5
|
||||||
|
#define MBOX_CH_TOUCH 6
|
||||||
|
#define MBOX_CH_COUNT 7
|
||||||
|
#define MBOX_CH_PROP 8
|
||||||
|
|
||||||
|
/* tags */
|
||||||
|
#define MBOX_TAG_SETCLKRATE 0x38002
|
||||||
|
#define MBOX_TAG_LAST 0
|
||||||
|
|
||||||
|
int mbox_call(unsigned char ch);
|
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section ".text.boot"
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
// read cpu id, stop slave cores
|
||||||
|
mrs x1, mpidr_el1
|
||||||
|
and x1, x1, #3
|
||||||
|
cbz x1, 2f
|
||||||
|
// cpu id > 0, stop
|
||||||
|
1: wfe
|
||||||
|
b 1b
|
||||||
|
2: // cpu id == 0
|
||||||
|
|
||||||
|
// set stack before our code
|
||||||
|
ldr x1, =_start
|
||||||
|
mov sp, x1
|
||||||
|
|
||||||
|
// clear bss
|
||||||
|
ldr x1, =__bss_start
|
||||||
|
ldr w2, =__bss_size
|
||||||
|
3: cbz w2, 4f
|
||||||
|
str xzr, [x1], #8
|
||||||
|
sub w2, w2, #1
|
||||||
|
cbnz w2, 3b
|
||||||
|
|
||||||
|
// jump to C code, should not return
|
||||||
|
4: bl main
|
||||||
|
// for failsafe, halt this core too
|
||||||
|
b 1b
|
@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
#include "mbox.h"
|
||||||
|
#include "delays.h"
|
||||||
|
|
||||||
|
/* PL011 UART registers */
|
||||||
|
#define UART0_DR ((volatile unsigned int*)(MMIO_BASE+0x00201000))
|
||||||
|
#define UART0_FR ((volatile unsigned int*)(MMIO_BASE+0x00201018))
|
||||||
|
#define UART0_IBRD ((volatile unsigned int*)(MMIO_BASE+0x00201024))
|
||||||
|
#define UART0_FBRD ((volatile unsigned int*)(MMIO_BASE+0x00201028))
|
||||||
|
#define UART0_LCRH ((volatile unsigned int*)(MMIO_BASE+0x0020102C))
|
||||||
|
#define UART0_CR ((volatile unsigned int*)(MMIO_BASE+0x00201030))
|
||||||
|
#define UART0_IMSC ((volatile unsigned int*)(MMIO_BASE+0x00201038))
|
||||||
|
#define UART0_ICR ((volatile unsigned int*)(MMIO_BASE+0x00201044))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set baud rate and characteristics (115200 8N1) and map to GPIO
|
||||||
|
*/
|
||||||
|
void uart_init()
|
||||||
|
{
|
||||||
|
register unsigned int r;
|
||||||
|
|
||||||
|
/* initialize UART */
|
||||||
|
*UART0_CR = 0; // turn off UART0
|
||||||
|
|
||||||
|
/* set up clock for consistent divisor values */
|
||||||
|
mbox[0] = 8*4;
|
||||||
|
mbox[1] = MBOX_REQUEST;
|
||||||
|
mbox[2] = MBOX_TAG_SETCLKRATE; // set clock rate
|
||||||
|
mbox[3] = 12;
|
||||||
|
mbox[4] = 8;
|
||||||
|
mbox[5] = 2; // UART clock
|
||||||
|
mbox[6] = 4000000; // 4Mhz
|
||||||
|
mbox[7] = MBOX_TAG_LAST;
|
||||||
|
mbox_call(MBOX_CH_PROP);
|
||||||
|
|
||||||
|
/* map UART0 to GPIO pins */
|
||||||
|
r=*GPFSEL1;
|
||||||
|
r&=~((7<<12)|(7<<15)); // gpio14, gpio15
|
||||||
|
r|=(2<<12)|(2<<15); // alt5
|
||||||
|
*GPFSEL1 = r;
|
||||||
|
*GPPUD = 0; // enable pins 14 and 15
|
||||||
|
wait_cycles(150);
|
||||||
|
*GPPUDCLK0 = (1<<14)|(1<<15);
|
||||||
|
wait_cycles(150);
|
||||||
|
*GPPUDCLK0 = 0; // flush GPIO setup
|
||||||
|
|
||||||
|
*UART0_ICR = 0x7FF; // clear interrupts
|
||||||
|
*UART0_IBRD = 2; // 115200 baud
|
||||||
|
*UART0_FBRD = 0xB;
|
||||||
|
*UART0_LCRH = 0b11<<5; // 8n1
|
||||||
|
*UART0_CR = 0x301; // enable Tx, Rx, FIFO
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a character
|
||||||
|
*/
|
||||||
|
void uart_send(unsigned int c) {
|
||||||
|
/* wait until we can send */
|
||||||
|
do{asm volatile("nop");}while(*UART0_FR&0x20);
|
||||||
|
/* write the carachter to the buffer */
|
||||||
|
*UART0_DR=c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receive a character
|
||||||
|
*/
|
||||||
|
char uart_getc() {
|
||||||
|
char r;
|
||||||
|
/* wait until something is in the buffer */
|
||||||
|
do{asm volatile("nop");}while(*UART0_FR&0x10);
|
||||||
|
/* read it and return */
|
||||||
|
r=(char)(*UART0_DR);
|
||||||
|
/* convert carrige return to newline */
|
||||||
|
return r=='\r'?'\n':r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a string
|
||||||
|
*/
|
||||||
|
void uart_puts(char *s) {
|
||||||
|
while(*s) {
|
||||||
|
/* convert newline to carrige return + newline */
|
||||||
|
if(*s=='\n')
|
||||||
|
uart_send('\r');
|
||||||
|
uart_send(*s++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a binary value in hexadecimal
|
||||||
|
*/
|
||||||
|
void uart_hex(unsigned int d) {
|
||||||
|
unsigned int n;
|
||||||
|
int c;
|
||||||
|
for(c=28;c>=0;c-=4) {
|
||||||
|
// get highest tetrad
|
||||||
|
n=(d>>c)&0xF;
|
||||||
|
// 0-9 => '0'-'9', 10-15 => 'A'-'F'
|
||||||
|
n+=n>9?0x37:0x30;
|
||||||
|
uart_send(n);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void uart_init();
|
||||||
|
void uart_send(unsigned int c);
|
||||||
|
char uart_getc();
|
||||||
|
void uart_puts(char *s);
|
||||||
|
void uart_hex(unsigned int d);
|
@ -0,0 +1,43 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person
|
||||||
|
# obtaining a copy of this software and associated documentation
|
||||||
|
# files (the "Software"), to deal in the Software without
|
||||||
|
# restriction, including without limitation the rights to use, copy,
|
||||||
|
# modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
# of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be
|
||||||
|
# included in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
SRCS = $(wildcard *.c)
|
||||||
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
start.o: start.S
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c start.S -o start.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: start.o $(OBJS)
|
||||||
|
aarch64-elf-ld -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf
|
||||||
|
aarch64-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm kernel8.elf *.o >/dev/null 2>/dev/null || true
|
@ -0,0 +1,24 @@
|
|||||||
|
Oktatóanyag 08 - Energiagazdálkodás
|
||||||
|
===================================
|
||||||
|
|
||||||
|
Beépített rendszerek esetén nagyon fontos az energiafogyasztás. A Raspberry Pi 3-on ezért roppant szofisztikált
|
||||||
|
interfészt találunk. Az egyes eszközöket külön-külön ki be kapcsolgathatjuk. Van egy hátulütő azonban, a GPIO
|
||||||
|
VCC lábai direktbe vannak kötve az áramforrásra, magyarán nem lehet programból vezérelni őket. Ez azt jelenti,
|
||||||
|
ha eszközöket kötsz rá, akkor neked kell megoldanod ezen eszközök kikapcsolását (mondjuk egy tranzisztorral,
|
||||||
|
amit egy másik GPIO adatláb vezérel).
|
||||||
|
|
||||||
|
Power.h, power.c
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Az energiagazdálkodás az egyik periféria, amit a qemu egyáltalán nem emulál. Igazi vason szépen megy.
|
||||||
|
|
||||||
|
`power_off()` leállítja az alaplapot egy, majdnem nulla energiafogyasztási szintre.
|
||||||
|
|
||||||
|
`reset()` újraindítja a gépet. Ezt is a PMC kezeli, és mivel nincs a Raspberry-n fizikai reset gomb, roppant
|
||||||
|
hasznos tud lenni.
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
Megjelenítünk egy egyszerű menüt, majd várunk a felhasználóra. A válaszától függően vagy újraindítjuk a gépet,
|
||||||
|
vagy kikapcsoljuk.
|
@ -0,0 +1,25 @@
|
|||||||
|
Tutorial 08 - Power management
|
||||||
|
==============================
|
||||||
|
|
||||||
|
For embedded systems, power consumption is critical. The Raspberry Pi 3 has a very sophisticated
|
||||||
|
PM interface. You can turn each device on and off idependently. There's a catch though, the GPIO
|
||||||
|
VCC pins are hardwired, there's no way to turn them off programatically. This means if you connect
|
||||||
|
some devices to them, you'll have to implement a way to turn those devices off (with a transistor
|
||||||
|
connected to a data GPIO pin for example).
|
||||||
|
|
||||||
|
Power.h, power.c
|
||||||
|
----------------
|
||||||
|
|
||||||
|
The power management controller is one of the periphels that are not emulated properly by qemu.
|
||||||
|
Works on real hardware though.
|
||||||
|
|
||||||
|
`power_off()` shutdowns the board to a almost zero power consumption state.
|
||||||
|
|
||||||
|
`reset()` reboots the machine. Also handled by the PMC, and since the Raspberry Pi does not have
|
||||||
|
a hardware reset button, it's very useful.
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
We display a simple menu, and wait for user input. Depending on the input, we reboot the system or
|
||||||
|
power it off.
|
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
#define SYSTMR_LO ((volatile unsigned int*)(MMIO_BASE+0x00003004))
|
||||||
|
#define SYSTMR_HI ((volatile unsigned int*)(MMIO_BASE+0x00003008))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait N CPU cycles (ARM CPU only)
|
||||||
|
*/
|
||||||
|
void wait_cycles(unsigned int n)
|
||||||
|
{
|
||||||
|
if(n) while(n--) { asm volatile("nop"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait N microsec (ARM CPU only)
|
||||||
|
*/
|
||||||
|
void wait_msec(unsigned int n)
|
||||||
|
{
|
||||||
|
register unsigned long f, t, r;
|
||||||
|
// get the current counter frequency
|
||||||
|
asm volatile ("mrs %0, cntfrq_el0" : "=r"(f));
|
||||||
|
// read the current counter
|
||||||
|
asm volatile ("mrs %0, cntpct_el0" : "=r"(t));
|
||||||
|
// calculate expire value for counter
|
||||||
|
t+=((f/1000)*n)/1000;
|
||||||
|
do{asm volatile ("mrs %0, cntpct_el0" : "=r"(r));}while(r<t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get System Timer's counter
|
||||||
|
*/
|
||||||
|
unsigned long get_system_timer()
|
||||||
|
{
|
||||||
|
unsigned int h=-1, l;
|
||||||
|
// we must read MMIO area as two separate 32 bit reads
|
||||||
|
h=*SYSTMR_HI;
|
||||||
|
l=*SYSTMR_LO;
|
||||||
|
// we have to repeat it if high word changed during read
|
||||||
|
if(h!=*SYSTMR_HI) {
|
||||||
|
h=*SYSTMR_HI;
|
||||||
|
l=*SYSTMR_LO;
|
||||||
|
}
|
||||||
|
// compose long int value
|
||||||
|
return ((unsigned long) h << 32) | l;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait N microsec (with BCM System Timer)
|
||||||
|
*/
|
||||||
|
void wait_msec_st(unsigned int n)
|
||||||
|
{
|
||||||
|
unsigned long t=get_system_timer();
|
||||||
|
// we must check if it's non-zero, because qemu does not emulate
|
||||||
|
// system timer, and returning constant zero would mean infinite loop
|
||||||
|
if(t) while(get_system_timer() < t+n);
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void wait_cycles(unsigned int n);
|
||||||
|
void wait_msec(unsigned int n);
|
||||||
|
unsigned long get_system_timer();
|
||||||
|
void wait_msec_st(unsigned int n);
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MMIO_BASE 0x3F000000
|
||||||
|
|
||||||
|
#define GPFSEL0 ((volatile unsigned int*)(MMIO_BASE+0x00200000))
|
||||||
|
#define GPFSEL1 ((volatile unsigned int*)(MMIO_BASE+0x00200004))
|
||||||
|
#define GPFSEL2 ((volatile unsigned int*)(MMIO_BASE+0x00200008))
|
||||||
|
#define GPFSEL3 ((volatile unsigned int*)(MMIO_BASE+0x0020000C))
|
||||||
|
#define GPFSEL4 ((volatile unsigned int*)(MMIO_BASE+0x00200010))
|
||||||
|
#define GPFSEL5 ((volatile unsigned int*)(MMIO_BASE+0x00200014))
|
||||||
|
#define GPSET0 ((volatile unsigned int*)(MMIO_BASE+0x0020001C))
|
||||||
|
#define GPSET1 ((volatile unsigned int*)(MMIO_BASE+0x00200020))
|
||||||
|
#define GPCLR0 ((volatile unsigned int*)(MMIO_BASE+0x00200028))
|
||||||
|
#define GPLEV0 ((volatile unsigned int*)(MMIO_BASE+0x00200034))
|
||||||
|
#define GPLEV1 ((volatile unsigned int*)(MMIO_BASE+0x00200038))
|
||||||
|
#define GPEDS0 ((volatile unsigned int*)(MMIO_BASE+0x00200040))
|
||||||
|
#define GPEDS1 ((volatile unsigned int*)(MMIO_BASE+0x00200044))
|
||||||
|
#define GPHEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200064))
|
||||||
|
#define GPHEN1 ((volatile unsigned int*)(MMIO_BASE+0x00200068))
|
||||||
|
#define GPPUD ((volatile unsigned int*)(MMIO_BASE+0x00200094))
|
||||||
|
#define GPPUDCLK0 ((volatile unsigned int*)(MMIO_BASE+0x00200098))
|
||||||
|
#define GPPUDCLK1 ((volatile unsigned int*)(MMIO_BASE+0x0020009C))
|
Binary file not shown.
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x80000;
|
||||||
|
.text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) }
|
||||||
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) }
|
||||||
|
PROVIDE(_data = .);
|
||||||
|
.data : { *(.data .data.* .gnu.linkonce.d*) }
|
||||||
|
.bss (NOLOAD) : {
|
||||||
|
. = ALIGN(16);
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
__bss_end = .;
|
||||||
|
}
|
||||||
|
_end = .;
|
||||||
|
|
||||||
|
/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
|
||||||
|
}
|
||||||
|
__bss_size = (__bss_end - __bss_start)>>3;
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uart.h"
|
||||||
|
#include "power.h"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
|
||||||
|
// set up serial console
|
||||||
|
uart_init();
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
uart_puts(" 1 - power off\n 2 - reset\nChoose one: ");
|
||||||
|
c=uart_getc();
|
||||||
|
uart_send(c);
|
||||||
|
uart_puts("\n\n");
|
||||||
|
if(c=='1') power_off();
|
||||||
|
if(c=='2') reset();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
/* mailbox message buffer */
|
||||||
|
volatile unsigned int __attribute__((aligned(16))) mbox[36];
|
||||||
|
|
||||||
|
#define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880)
|
||||||
|
#define MBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0))
|
||||||
|
#define MBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10))
|
||||||
|
#define MBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14))
|
||||||
|
#define MBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18))
|
||||||
|
#define MBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C))
|
||||||
|
#define MBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20))
|
||||||
|
#define MBOX_RESPONSE 0x80000000
|
||||||
|
#define MBOX_FULL 0x80000000
|
||||||
|
#define MBOX_EMPTY 0x40000000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a mailbox call. Returns 0 on failure, non-zero on success
|
||||||
|
*/
|
||||||
|
int mbox_call(unsigned char ch)
|
||||||
|
{
|
||||||
|
unsigned int r;
|
||||||
|
/* wait until we can write to the mailbox */
|
||||||
|
do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_FULL);
|
||||||
|
/* write the address of our message to the mailbox with channel identifier */
|
||||||
|
*MBOX_WRITE = (((unsigned int)((unsigned long)&mbox)&~0xF) | (ch&0xF));
|
||||||
|
/* now wait for the response */
|
||||||
|
while(1) {
|
||||||
|
/* is there a response? */
|
||||||
|
do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_EMPTY);
|
||||||
|
r=*MBOX_READ;
|
||||||
|
/* is it a response to our message? */
|
||||||
|
if((unsigned char)(r&0xF)==ch && (r&~0xF)==(unsigned int)((unsigned long)&mbox))
|
||||||
|
/* is it a valid successful response? */
|
||||||
|
return mbox[1]==MBOX_RESPONSE;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* a properly aligned buffer */
|
||||||
|
extern volatile unsigned int mbox[36];
|
||||||
|
|
||||||
|
#define MBOX_REQUEST 0
|
||||||
|
|
||||||
|
/* channels */
|
||||||
|
#define MBOX_CH_POWER 0
|
||||||
|
#define MBOX_CH_FB 1
|
||||||
|
#define MBOX_CH_VUART 2
|
||||||
|
#define MBOX_CH_VCHIQ 3
|
||||||
|
#define MBOX_CH_LEDS 4
|
||||||
|
#define MBOX_CH_BTNS 5
|
||||||
|
#define MBOX_CH_TOUCH 6
|
||||||
|
#define MBOX_CH_COUNT 7
|
||||||
|
#define MBOX_CH_PROP 8
|
||||||
|
|
||||||
|
/* tags */
|
||||||
|
#define MBOX_TAG_SETPOWER 0x28001
|
||||||
|
#define MBOX_TAG_SETCLKRATE 0x38002
|
||||||
|
#define MBOX_TAG_LAST 0
|
||||||
|
|
||||||
|
int mbox_call(unsigned char ch);
|
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
#include "mbox.h"
|
||||||
|
#include "delays.h"
|
||||||
|
|
||||||
|
#define PM_RSTC ((volatile unsigned int*)(MMIO_BASE+0x0010001c))
|
||||||
|
#define PM_RSTS ((volatile unsigned int*)(MMIO_BASE+0x00100020))
|
||||||
|
#define PM_WDOG ((volatile unsigned int*)(MMIO_BASE+0x00100024))
|
||||||
|
#define PM_WDOG_MAGIC 0x5a000000
|
||||||
|
#define PM_RSTC_FULLRST 0x00000020
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shutdown the board
|
||||||
|
*/
|
||||||
|
void power_off()
|
||||||
|
{
|
||||||
|
unsigned long r;
|
||||||
|
|
||||||
|
// power off devices one by one
|
||||||
|
for(r=0;r<16;r++) {
|
||||||
|
mbox[0]=8*4;
|
||||||
|
mbox[1]=MBOX_REQUEST;
|
||||||
|
mbox[2]=MBOX_TAG_SETPOWER; // set power state
|
||||||
|
mbox[3]=8;
|
||||||
|
mbox[4]=8;
|
||||||
|
mbox[5]=(unsigned int)r; // device id
|
||||||
|
mbox[6]=0; // bit 0: off, bit 1: no wait
|
||||||
|
mbox[7]=MBOX_TAG_LAST;
|
||||||
|
mbox_call(MBOX_CH_PROP);
|
||||||
|
}
|
||||||
|
|
||||||
|
// power off gpio pins (but not VCC pins)
|
||||||
|
*GPFSEL0 = 0; *GPFSEL1 = 0; *GPFSEL2 = 0; *GPFSEL3 = 0; *GPFSEL4 = 0; *GPFSEL5 = 0;
|
||||||
|
*GPPUD = 0;
|
||||||
|
wait_cycles(150);
|
||||||
|
*GPPUDCLK0 = 0xffffffff; *GPPUDCLK1 = 0xffffffff;
|
||||||
|
wait_cycles(150);
|
||||||
|
*GPPUDCLK0 = 0; *GPPUDCLK1 = 0; // flush GPIO setup
|
||||||
|
|
||||||
|
// power off the SoC (GPU + CPU)
|
||||||
|
r = *PM_RSTS; r &= ~0xfffffaaa;
|
||||||
|
r |= 0x555; // partition 63 used to indicate halt
|
||||||
|
*PM_RSTS = PM_WDOG_MAGIC | r;
|
||||||
|
*PM_WDOG = PM_WDOG_MAGIC | 10;
|
||||||
|
*PM_RSTC = PM_WDOG_MAGIC | PM_RSTC_FULLRST;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reboot
|
||||||
|
*/
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
unsigned int r;
|
||||||
|
// trigger a restart by instructing the GPU to boot from partition 0
|
||||||
|
r = *PM_RSTS; r &= ~0xfffffaaa;
|
||||||
|
*PM_RSTS = PM_WDOG_MAGIC | r; // boot from partition 0
|
||||||
|
*PM_WDOG = PM_WDOG_MAGIC | 10;
|
||||||
|
*PM_RSTC = PM_WDOG_MAGIC | PM_RSTC_FULLRST;
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void power_off();
|
||||||
|
void reset();
|
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section ".text.boot"
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
// read cpu id, stop slave cores
|
||||||
|
mrs x1, mpidr_el1
|
||||||
|
and x1, x1, #3
|
||||||
|
cbz x1, 2f
|
||||||
|
// cpu id > 0, stop
|
||||||
|
1: wfe
|
||||||
|
b 1b
|
||||||
|
2: // cpu id == 0
|
||||||
|
|
||||||
|
// set stack before our code
|
||||||
|
ldr x1, =_start
|
||||||
|
mov sp, x1
|
||||||
|
|
||||||
|
// clear bss
|
||||||
|
ldr x1, =__bss_start
|
||||||
|
ldr w2, =__bss_size
|
||||||
|
3: cbz w2, 4f
|
||||||
|
str xzr, [x1], #8
|
||||||
|
sub w2, w2, #1
|
||||||
|
cbnz w2, 3b
|
||||||
|
|
||||||
|
// jump to C code, should not return
|
||||||
|
4: bl main
|
||||||
|
// for failsafe, halt this core too
|
||||||
|
b 1b
|
@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
#include "mbox.h"
|
||||||
|
#include "delays.h"
|
||||||
|
|
||||||
|
/* PL011 UART registers */
|
||||||
|
#define UART0_DR ((volatile unsigned int*)(MMIO_BASE+0x00201000))
|
||||||
|
#define UART0_FR ((volatile unsigned int*)(MMIO_BASE+0x00201018))
|
||||||
|
#define UART0_IBRD ((volatile unsigned int*)(MMIO_BASE+0x00201024))
|
||||||
|
#define UART0_FBRD ((volatile unsigned int*)(MMIO_BASE+0x00201028))
|
||||||
|
#define UART0_LCRH ((volatile unsigned int*)(MMIO_BASE+0x0020102C))
|
||||||
|
#define UART0_CR ((volatile unsigned int*)(MMIO_BASE+0x00201030))
|
||||||
|
#define UART0_IMSC ((volatile unsigned int*)(MMIO_BASE+0x00201038))
|
||||||
|
#define UART0_ICR ((volatile unsigned int*)(MMIO_BASE+0x00201044))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set baud rate and characteristics (115200 8N1) and map to GPIO
|
||||||
|
*/
|
||||||
|
void uart_init()
|
||||||
|
{
|
||||||
|
register unsigned int r;
|
||||||
|
|
||||||
|
/* initialize UART */
|
||||||
|
*UART0_CR = 0; // turn off UART0
|
||||||
|
|
||||||
|
/* set up clock for consistent divisor values */
|
||||||
|
mbox[0] = 8*4;
|
||||||
|
mbox[1] = MBOX_REQUEST;
|
||||||
|
mbox[2] = MBOX_TAG_SETCLKRATE; // set clock rate
|
||||||
|
mbox[3] = 12;
|
||||||
|
mbox[4] = 8;
|
||||||
|
mbox[5] = 2; // UART clock
|
||||||
|
mbox[6] = 4000000; // 4Mhz
|
||||||
|
mbox[7] = MBOX_TAG_LAST;
|
||||||
|
mbox_call(MBOX_CH_PROP);
|
||||||
|
|
||||||
|
/* map UART0 to GPIO pins */
|
||||||
|
r=*GPFSEL1;
|
||||||
|
r&=~((7<<12)|(7<<15)); // gpio14, gpio15
|
||||||
|
r|=(2<<12)|(2<<15); // alt5
|
||||||
|
*GPFSEL1 = r;
|
||||||
|
*GPPUD = 0; // enable pins 14 and 15
|
||||||
|
wait_cycles(150);
|
||||||
|
*GPPUDCLK0 = (1<<14)|(1<<15);
|
||||||
|
wait_cycles(150);
|
||||||
|
*GPPUDCLK0 = 0; // flush GPIO setup
|
||||||
|
|
||||||
|
*UART0_ICR = 0x7FF; // clear interrupts
|
||||||
|
*UART0_IBRD = 2; // 115200 baud
|
||||||
|
*UART0_FBRD = 0xB;
|
||||||
|
*UART0_LCRH = 0b11<<5; // 8n1
|
||||||
|
*UART0_CR = 0x301; // enable Tx, Rx, FIFO
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a character
|
||||||
|
*/
|
||||||
|
void uart_send(unsigned int c) {
|
||||||
|
/* wait until we can send */
|
||||||
|
do{asm volatile("nop");}while(*UART0_FR&0x20);
|
||||||
|
/* write the carachter to the buffer */
|
||||||
|
*UART0_DR=c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receive a character
|
||||||
|
*/
|
||||||
|
char uart_getc() {
|
||||||
|
char r;
|
||||||
|
/* wait until something is in the buffer */
|
||||||
|
do{asm volatile("nop");}while(*UART0_FR&0x10);
|
||||||
|
/* read it and return */
|
||||||
|
r=(char)(*UART0_DR);
|
||||||
|
/* convert carrige return to newline */
|
||||||
|
return r=='\r'?'\n':r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a string
|
||||||
|
*/
|
||||||
|
void uart_puts(char *s) {
|
||||||
|
while(*s) {
|
||||||
|
/* convert newline to carrige return + newline */
|
||||||
|
if(*s=='\n')
|
||||||
|
uart_send('\r');
|
||||||
|
uart_send(*s++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a binary value in hexadecimal
|
||||||
|
*/
|
||||||
|
void uart_hex(unsigned int d) {
|
||||||
|
unsigned int n;
|
||||||
|
int c;
|
||||||
|
for(c=28;c>=0;c-=4) {
|
||||||
|
// get highest tetrad
|
||||||
|
n=(d>>c)&0xF;
|
||||||
|
// 0-9 => '0'-'9', 10-15 => 'A'-'F'
|
||||||
|
n+=n>9?0x37:0x30;
|
||||||
|
uart_send(n);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void uart_init();
|
||||||
|
void uart_send(unsigned int c);
|
||||||
|
char uart_getc();
|
||||||
|
void uart_puts(char *s);
|
||||||
|
void uart_hex(unsigned int d);
|
@ -0,0 +1,43 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person
|
||||||
|
# obtaining a copy of this software and associated documentation
|
||||||
|
# files (the "Software"), to deal in the Software without
|
||||||
|
# restriction, including without limitation the rights to use, copy,
|
||||||
|
# modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
# of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be
|
||||||
|
# included in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
SRCS = $(wildcard *.c)
|
||||||
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
start.o: start.S
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c start.S -o start.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: start.o $(OBJS)
|
||||||
|
aarch64-elf-ld -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf
|
||||||
|
aarch64-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm kernel8.elf *.o >/dev/null 2>/dev/null || true
|
@ -0,0 +1,36 @@
|
|||||||
|
Oktatóanyag 09 - Framebuffer
|
||||||
|
============================
|
||||||
|
|
||||||
|
Rendben, végre valami csicsa-picsa :-) Eddig a képernyő sötét volt. Most be fogjuk állítani a felbontását
|
||||||
|
egy csomó parancsot tartalmazó üzenettel és egyetlen egy mbox_call hívással, majd kirakunk egy képet. Teleraktam
|
||||||
|
kommenttel az lfb.c forrást (igaz, angol nyelvűek), hogy segítsenek eligazodni a parancsokban. De végeredményben
|
||||||
|
nem tesz mást, mint feltölt egy int tömböt és meghívja az mbox_call-t, igazán egyszerű. Ha gondolod, megpróbálhatsz
|
||||||
|
hozzáadni vagy elvenni parancsokat, hogy lásd, mi történik. Használhattam volna az MBOX_CH_FB (FrameBuffer csatornát)
|
||||||
|
is, de az MBOX_CH_PROP sokkal több mindent tesz lehetővé és sokkal rugalmasabb.
|
||||||
|
|
||||||
|
Fontos tudnivaló a pitch-ről: talán nem tudod, de a video képernyő rasztersorai nem feltétlenül vannak sorfolytonosan
|
||||||
|
tárolva a memóriában. Például lehetséges, hogy 800 pixelnél (800x4=3200 bájt helyett) 4096 bájton tárolódik minden
|
||||||
|
sor. Ezért fontos, hogy mindig a dinamikusan lekért pitch értékével számoljuk width*4 helyett a képernyő Y
|
||||||
|
koordinátáját.
|
||||||
|
|
||||||
|
Arra is érdemes figyelni, hogy a GPU a Raspberry Pi-n nagyon combos. Létrehozhatsz például egy hatalmas virtuális
|
||||||
|
képernyőt (mondjuk 65536x768), amiből egyszerre csak 1024x768 lesz megjelenítve. Levelesláda üzenetekkel piszok
|
||||||
|
gyorsan mozgathatod ezt az ablakot, annélkül, hogy pixelbuffereket kéne másolgatni, ezáltal egy nagyon sima
|
||||||
|
szkrollozó hatást hozva létre. Ebben a példában mind a virtuális, mind a fizikai képméretet 1024x768-ra állítottam.
|
||||||
|
|
||||||
|
Lfb.h, lfb.c
|
||||||
|
------------
|
||||||
|
|
||||||
|
`lfb_init()` beállítja a felbontást, színmélységet, színcsatorna sorrendjét. Lekéri továbbá a framebuffer címét.
|
||||||
|
|
||||||
|
`lfb_showpicture()` a framebuffer-be direkt pixelek írásával megjelenít egy képet a képernyő közepén.
|
||||||
|
|
||||||
|
Homer.h
|
||||||
|
-------
|
||||||
|
|
||||||
|
A kép, Gimp-el C header formátumban lementve. Nincs tömörítve, a pixelek egymás után következnek.
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
Nagyon egyszerű. Beállítjuk a felbontást, és kirajzoljuk a képet, ennyi.
|
@ -0,0 +1,35 @@
|
|||||||
|
Tutorial 09 - Framebuffer
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Okay, finaly some eyecandy :-) So far the screen was blank. Now we're about to change the resolution with
|
||||||
|
several tags in a single mbox_call, then display a pixmap. I've put a lot of comments for each tag and
|
||||||
|
argument to help you, see lfb.c. But at the end of the day it's nothing more than filling up an int array
|
||||||
|
and call mbox_call, really simple. If you wish, you can try to remove or add more tags to the message and
|
||||||
|
see what happens. Could have used MBOX_CH_FB (FrameBuffer channel), but MBOX_CH_PROP gives us more flexibility.
|
||||||
|
|
||||||
|
Important note on pitch: maybe you don't know, but video screens does not necessairly map raster lines
|
||||||
|
continously in memory. For example it is possible that 800 pixels (800*4=3200 bytes) are stored in 4096
|
||||||
|
bytes for every line. Therefore it's important to use the queried pitch value instead of width*4 when
|
||||||
|
calculating the postition for the Y coordinate.
|
||||||
|
|
||||||
|
Also note that the GPU on the Raspberry Pi is very powerful. You can create a large virtual screen (let's say
|
||||||
|
65536x768) but display only 1024x768 pixels at once. With mailbox messages you can move that window very fast
|
||||||
|
without the need of copying pixel buffers, thus creating a smooth scrolling effect. In this tutorial both
|
||||||
|
virtual screen and physical screen is set to 1024x768.
|
||||||
|
|
||||||
|
Lfb.h, lfb.c
|
||||||
|
------------
|
||||||
|
|
||||||
|
`lfb_init()` sets up resolution, depth, and color channel order. Also queries framebuffer's address.
|
||||||
|
|
||||||
|
`lfb_showpicture()` displays a picture in the center of the screen by drawing pixels to the framebuffer.
|
||||||
|
|
||||||
|
Homer.h
|
||||||
|
-------
|
||||||
|
|
||||||
|
The pixmap, saved with the Gimp as C header file. No compression, pixels are stored one-by-one.
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
Very simple. We set the resolution and display the picture, that's all.
|
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
#define SYSTMR_LO ((volatile unsigned int*)(MMIO_BASE+0x00003004))
|
||||||
|
#define SYSTMR_HI ((volatile unsigned int*)(MMIO_BASE+0x00003008))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait N CPU cycles (ARM CPU only)
|
||||||
|
*/
|
||||||
|
void wait_cycles(unsigned int n)
|
||||||
|
{
|
||||||
|
if(n) while(n--) { asm volatile("nop"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait N microsec (ARM CPU only)
|
||||||
|
*/
|
||||||
|
void wait_msec(unsigned int n)
|
||||||
|
{
|
||||||
|
register unsigned long f, t, r;
|
||||||
|
// get the current counter frequency
|
||||||
|
asm volatile ("mrs %0, cntfrq_el0" : "=r"(f));
|
||||||
|
// read the current counter
|
||||||
|
asm volatile ("mrs %0, cntpct_el0" : "=r"(t));
|
||||||
|
// calculate expire value for counter
|
||||||
|
t+=((f/1000)*n)/1000;
|
||||||
|
do{asm volatile ("mrs %0, cntpct_el0" : "=r"(r));}while(r<t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get System Timer's counter
|
||||||
|
*/
|
||||||
|
unsigned long get_system_timer()
|
||||||
|
{
|
||||||
|
unsigned int h=-1, l;
|
||||||
|
// we must read MMIO area as two separate 32 bit reads
|
||||||
|
h=*SYSTMR_HI;
|
||||||
|
l=*SYSTMR_LO;
|
||||||
|
// we have to repeat it if high word changed during read
|
||||||
|
if(h!=*SYSTMR_HI) {
|
||||||
|
h=*SYSTMR_HI;
|
||||||
|
l=*SYSTMR_LO;
|
||||||
|
}
|
||||||
|
// compose long int value
|
||||||
|
return ((unsigned long) h << 32) | l;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait N microsec (with BCM System Timer)
|
||||||
|
*/
|
||||||
|
void wait_msec_st(unsigned int n)
|
||||||
|
{
|
||||||
|
unsigned long t=get_system_timer();
|
||||||
|
// we must check if it's non-zero, because qemu does not emulate
|
||||||
|
// system timer, and returning constant zero would mean infinite loop
|
||||||
|
if(t) while(get_system_timer() < t+n);
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void wait_cycles(unsigned int n);
|
||||||
|
void wait_msec(unsigned int n);
|
||||||
|
unsigned long get_system_timer();
|
||||||
|
void wait_msec_st(unsigned int n);
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MMIO_BASE 0x3F000000
|
||||||
|
|
||||||
|
#define GPFSEL0 ((volatile unsigned int*)(MMIO_BASE+0x00200000))
|
||||||
|
#define GPFSEL1 ((volatile unsigned int*)(MMIO_BASE+0x00200004))
|
||||||
|
#define GPFSEL2 ((volatile unsigned int*)(MMIO_BASE+0x00200008))
|
||||||
|
#define GPFSEL3 ((volatile unsigned int*)(MMIO_BASE+0x0020000C))
|
||||||
|
#define GPFSEL4 ((volatile unsigned int*)(MMIO_BASE+0x00200010))
|
||||||
|
#define GPFSEL5 ((volatile unsigned int*)(MMIO_BASE+0x00200014))
|
||||||
|
#define GPSET0 ((volatile unsigned int*)(MMIO_BASE+0x0020001C))
|
||||||
|
#define GPSET1 ((volatile unsigned int*)(MMIO_BASE+0x00200020))
|
||||||
|
#define GPCLR0 ((volatile unsigned int*)(MMIO_BASE+0x00200028))
|
||||||
|
#define GPLEV0 ((volatile unsigned int*)(MMIO_BASE+0x00200034))
|
||||||
|
#define GPLEV1 ((volatile unsigned int*)(MMIO_BASE+0x00200038))
|
||||||
|
#define GPEDS0 ((volatile unsigned int*)(MMIO_BASE+0x00200040))
|
||||||
|
#define GPEDS1 ((volatile unsigned int*)(MMIO_BASE+0x00200044))
|
||||||
|
#define GPHEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200064))
|
||||||
|
#define GPHEN1 ((volatile unsigned int*)(MMIO_BASE+0x00200068))
|
||||||
|
#define GPPUD ((volatile unsigned int*)(MMIO_BASE+0x00200094))
|
||||||
|
#define GPPUDCLK0 ((volatile unsigned int*)(MMIO_BASE+0x00200098))
|
||||||
|
#define GPPUDCLK1 ((volatile unsigned int*)(MMIO_BASE+0x0020009C))
|
@ -0,0 +1,399 @@
|
|||||||
|
/* GIMP header image file format (RGB) */
|
||||||
|
|
||||||
|
static unsigned int homer_width = 96;
|
||||||
|
static unsigned int homer_height = 64;
|
||||||
|
|
||||||
|
/* Call this macro repeatedly. After each use, the pixel data can be extracted */
|
||||||
|
|
||||||
|
#define HEADER_PIXEL(data,pixel) {\
|
||||||
|
pixel[0] = (((data[0] - 33) << 2) | ((data[1] - 33) >> 4)); \
|
||||||
|
pixel[1] = ((((data[1] - 33) & 0xF) << 4) | ((data[2] - 33) >> 2)); \
|
||||||
|
pixel[2] = ((((data[2] - 33) & 0x3) << 6) | ((data[3] - 33))); \
|
||||||
|
data += 4; \
|
||||||
|
}
|
||||||
|
static char *homer_data =
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!1)$!Q5*$2=C$\"9B#!U5%BUM'3R((#Z-%S%T#!Y7!A-&!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!#R-?$REJ%2YP%C%W'3F%$BAI$2AM*DJ:#B%7$\"%9%2YR(#^*!A-&"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!#B5A%B]Y$BMK\"1I0'4*+\"B)B!!!!\"1];$\"QV$3>#$C9`$2]T#R9F(D&1"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!#\"1D%S=\\!19,#B)A$B-?(C9N+CMI34Q=?'9>BWY>?75=75E7.T)I'\"E="
|
||||||
|
")4)]!!!\"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!1-%%S-X\"QY9#R)>(\"QD=6=FJHUHY\\-L`_1J`_E?`_9A`_AA`_IH`^YIVLM@"
|
||||||
|
"F9%O5&*#!1I9\"QQ3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!%3!\\'2=BFXEU:UU?QJ%VW;EI_^-B`^EA`^EA`^IB`^IB`^IA`^IB`^QA"
|
||||||
|
"`^EB\\^%^K*NK!QQC\"AI2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!$BUR'BI7P:1ZV+-I<F9CQ*=L\\]9A`^U@`^IB`^IB`^IB`^IB`^IB`^IB`^IB"
|
||||||
|
"`^IC`.I;`_.#O[^\\\"QQ;!!!\"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!1E1+DB(>6IKV*UOT;%JL9!NU[=K`^QD`^I@`^IB`^IB`^IB`^IB`^IB`^IB`^IB"
|
||||||
|
"`^MA`^IC`N9<_^^3A(RD%2IG!!!!!!!!!!!!!!!!!!!#!!!!!!-*!!!%!!!!!!9,"
|
||||||
|
"!!!$!!!'!!%\"!!5/$\"-=!!!%!!!!!!!!!!!&#\"!9!!5.!!!!!!!!!!%\"!!!$!!!$"
|
||||||
|
"!!%'!!!!!!!$!!!!!!=1#A]:!!!&!!!!!!!\"!!50#!Y8!!)*!!!!!!!$!!!+!!-*"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"#RANE7QKS*=NUJQOT;!LT:UM\\M1F`^M@`^I@`^IB`^IB`^IB`^IB`^IB`^IB`^IB"
|
||||||
|
"`^IB`^IB`^ED`NIH[>2V.%*/!!!!!!!!!!!!\"1A+=Y'.O<`$8WJ^DZGCP-,)3&NN"
|
||||||
|
"G;7MK\\;])$64I\\#ZQ]H-J\\#U(CU_$C-PH[KRR-P1LLH\"(DB0!!!!(#Y^I+WXL,;^"
|
||||||
|
";(\"]OM$'=([/(D\"&KLD!QML/I[SR'3M['#M]JL+`R-H*K<3\\&SV&=Y?:PM@-78+("
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!QU:"
|
||||||
|
".CU?WKAUT;%JU*YOTK!MTJQK_N-G`^E>`^IB`^IB`^IB`^IB`^IB`^IB`^IB`^IB"
|
||||||
|
"`^IB`^IB`NMA_^I?`_^<B(R2\"B9K!!!!!!!!\"AA+DZG@````DZ?=U^@9````=8B]"
|
||||||
|
"[OXOW.D;GJ[@````^0,S````HKOYH[[\\````^00T```^N](%!!M8&#%PX/(D_`T["
|
||||||
|
"EJ35````G[7PI\\3[```_]P0S````H;GXG;GW```_]`,S````K<<!AJ#;````>)/9"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1%\"!R)G"
|
||||||
|
"FX5OV;)NTJYMTJ]LTJ]LT[%I_N5E`^IB`^IB`^IB`^IB`^IB`^IB`^IB`^IB`^IB"
|
||||||
|
"`^IB`^IB`^M@`^AC`.US`_W6%\"QO!!!!!!!!!Q5(?I3/`@\\_LL#Q[?@H````F*/4"
|
||||||
|
"````J[?HY?,B\\/XOH;#@```_R=D,P=$\"````J+;I\\O\\P[/PO!!U;'3)OX/,H_`PZ"
|
||||||
|
"HJ[?````F:C=X?$C]P,SH*[@_PL[S=L,Q-$%````G:K<\\O`OZ/DL>H[%````9XC1"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-((31P"
|
||||||
|
"R*=QU*YJTJ]LTJ]LTJ]LU+)K_N5E`^EA`^IB`^IB`^IB`^IB`^IB`^IB`^IB`^IB"
|
||||||
|
"`^IB`^IB`^IB`^EC`>AB``/\"8&R1!AQ=!!!!!1)$9W^[_@L]S]X/^P<W````P,S]"
|
||||||
|
"````C)K.Z/DK\\O\\OIK3E```_S=H+QM4&````K+OM\\_`PZ?HM!R%?'3-OX/,H```^"
|
||||||
|
"\\?\\O````F*?=X?(D]`0TIK3E_PL[T-\\1Q-4$````HK#A\\`(OZ?HM:X2]````5'6^"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-)1U-Z"
|
||||||
|
"T*MLT:YNTJ]LTJ]LU*]MU*]I_N5D`^IB`^IB`^IB`^IB`^IB`^IB`^IB`^IB`^IB"
|
||||||
|
"`^IB`^IB`^IB`^IB`NA9`_:JGZ2Q!!!*!!!!!!!!5FVI^`DZ\\`$Q_`P\\`P\\_Z?8F"
|
||||||
|
"````:(;$Z_@D\\?\\OI[3G`@`_R]L+QM0%````K+OM\\_`PZ?DM\"\"!@'#-OW_0F```_"
|
||||||
|
"^P@X````EZC<X?,D]`0TIK3G_PL[S]\\1Q=4%````HK#B\\`$PZODJ9H'\"````/U^D"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&4%5S"
|
||||||
|
"U:UKT:]NTJ]LTJ]LU*]LTZYK_N1F`^IA`^IB`^IB`^IB`^IB`^IC`^IB`^IB`^IB"
|
||||||
|
"`^IB`^IB`^IC`^IB`^E=`>^,T-+6$BAK!1)%!!!!0UJ6]@0V````Z/0DYO,B````"
|
||||||
|
"````6'W$ZO@G\\?XNHJ_B`P``RML,Q-0&````J+?I\\O\\PZOHM!!U<'#)NX?,G_PT["
|
||||||
|
"E*#1````F*C<XO,E]P,SHJ_B_PL[SMT0Q=0&````G:S>\\_`O[?TM77S!^`4S+TV4"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!AA.4%=Y"
|
||||||
|
"TZUMT+!NTJ]LTJ]LTZ]LT*QI_.%H`NM?`NE@`^MA`_9@`_=B`_%9`NE?`^EC`^E>"
|
||||||
|
"`^AB`NAA`^Q:`_-=`_1B`^YA^.RCDIRO&2YJ!!!!,TF$Z?DH`P``R=<'R=8(````"
|
||||||
|
"`0PX7XS>PM@,_0HYT-\\/````N,X$M<L#````T^(2^`@WWNX>!!51'CEXX/0E_@P["
|
||||||
|
"EZ+6````G*[HR]X0_PL[T=T/````NLX!L\\?`````S]T._@HVV.L>8X'+\\_\\J1V6N"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-*1U9^"
|
||||||
|
"TJMKTZ]MTZ]LTJ]LTJ]KSZQJ[M)J`^I@_.ABW-%OE(IMAG]JO+%W^N5N_>A@`.I;"
|
||||||
|
"`.AC_>=CZ=9VIY]QG9-OS,)T_>ARS<6L+$2#!!!!(CEUU^D;^`DYJL3]GKCW_@LY"
|
||||||
|
"Y/4I0%60.6:N]@,V_@L[\\@$S2VJH0&\"=\\?`S_PPY_PX]4G;\"!!!!(#Z\"W>`@]P4T"
|
||||||
|
"DZ+4`0X^F+/T3GO%^P8V_PP[]0(R37\"W1&>K[OXQ_@LW_@H[06NZ>YG6```_5GC&"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-(*#QO"
|
||||||
|
"S:ERTJ]KTJ]LTJ]LTJ]LT:QMY<=GPKAHD96EDYW;Q]84T.(<K+GYB8^\\HYY\\\\MUJ"
|
||||||
|
"TL!?C8V5BY32P,\\+RMD7FZ?LAHNR=X\".'S9T!!!!!QA.%C1VX$BUK$2UK%S5W"
|
||||||
|
"%\"]Q!Q=-!!!\"'CZ#15^>&CAX!!%'!!!&&CE[0%F:(#V!!!)'!!!!\"1I0%2]N%\"]P"
|
||||||
|
"%\"QH%\"]P$2MH!!!$'CI\\15Z<&SI_!!!\"!!)'&S5W0%F8(#U_!A5+$\"EE&CA^#B5B"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)$#2-A"
|
||||||
|
"P:-YTK!ITJ]LTJ]LTJ]KWK=T?6I<L;CI]`4W`````````````````P``TMX566%F"
|
||||||
|
"CY2Y[OPP````````````````_@L\\IK+G)4.'!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!\"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!\"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1%#!!!\"!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1]D"
|
||||||
|
"CWYSV+1JTJ]LTJ]LU+%KGX1@DIS.`````@\\]`P\\_`P\\_`P\\_`P\\_`P\\_```_RM0,"
|
||||||
|
"<'RJ`````P\\_`P\\_`P\\_`P\\_`P\\_````8'\"H\"B%<!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\"!1)$!1)$"
|
||||||
|
"!1)$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!&!!)*\"QU5(BY>1%1^,C]C$\"%6!!)(!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\"\"!?"
|
||||||
|
"4$QCX+ERT:]MTJYNTJYJ=&UX]P,T``T_]P,T[OLK`````P\\_`P\\_`P\\^`@X\\````"
|
||||||
|
">H:Y[?HK```_`P\\_`P\\_````\\?TNXN\\AV^45%#B#!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1)'&S-O4V&*8&F("
|
||||||
|
"0%&\"#QY4!!%'!!-)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!)$!!E@,#5D,#UN-#]MOJ)VRZIIXM)EI:%J%BQL!!!#!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
")C=QSJENU;!LUK%MRZ=KCY\"K_PL\\`@X^@8N^(2U>`````````P\\_`P\\_`P\\_````"
|
||||||
|
"L[_QR]@)```_`@X^`@X^````KKCK35J,_P8P#\"Q\\!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)$&C1QDH!WRJ9ISJIH"
|
||||||
|
"TK5P/$-J-4%O*#EN\"2-F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!1-&%BQOFXYR]MEB^^EHD(9FAW!FY<%N_NAD`>I>C(QQ$29E!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"%#!TGX9FV+5TOI]JRZAOF)NY`@T^```_RM0'H*S=`````P\\_`P\\_`P\\_`P\\_````"
|
||||||
|
"L+SMR]@)`````@X^_`P\\`@X^^P4W^`8ZR=$!$SJ%!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\"AU2;6=YTK%OVK%I^>)G"
|
||||||
|
"DX=IE()NT:QMTZIO:65Q$REL!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!\"QU9=6MP]=1H`?!>`^A@``!G@W9EJH]MW\\5IY--?RKIH+T9^!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)$\"B%?"
|
||||||
|
"!AY>>6UKL)-M.3AAG8=GC8B7^@8W`0X^`````````@X^`P\\_`P\\_`P\\_`P\\^````"
|
||||||
|
":72HM\\#UM<#KHZO1CY.SE)J`Q]8&````5FJI&3-R!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!QM3)3QX;&!A?W!KJI]DMJIL"
|
||||||
|
"A'!DW[=UZLUD^^-B_N-K5F%R!AA.!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!1E4!!UJ+SQM=F1DWK9O]N!A`^ME`NI7[=MX/#9:?W)EEXM>F(QH/DAM!!UB"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!A5*&3>\""
|
||||||
|
"#S\"\"7V!Y>6ECL)5X;6!A@V]FT=L.`````@X_`P\\_`P\\_`P\\_`P\\``P\\`````KK?T"
|
||||||
|
"9VUXQL\"@TLB4X=B6]>FAZ^S';'&8AI;0(3E\\!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!AQ8/4=PLYAOV;]FX])FS;]B9V5A"
|
||||||
|
"FX-K[,QI`NM?`_1FK:-A9F)H%BQM!A]?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!%%)35HQKEQ]MY@MZQI6U!BW+EO^^1D`^]O3DM9N:5K_>1D`^ED`^AB_^9S7V5Z"
|
||||||
|
"\"1QB!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!A5)#BUT"
|
||||||
|
"$#![04=U;6)FTZMR<F9DMIQM4T]O]0$T```^`@X^`0`]`@\\]`0`V``\\YS=T5:VIN"
|
||||||
|
"`_-O`^QB`^A<`NE?`.I>`^YWFY^E)#=Q#!Y3!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$RAEJ9!RV[5G`.AA`^EF`^I=_.5I"
|
||||||
|
">'%HWLIJ_^AH8%Q9D7UORZ9PN)QX.T5Q!15-!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"$\");D8YI`^U=`^I@`_1DT\\9J75A:S+)Q9EU=Q:QR`^Y@`^IA`NI?`^M>`NI8Y-R4"
|
||||||
|
"\"1U=!!%$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1-'$2YX"
|
||||||
|
"$\"AJ%R5:85MHUZYNF8-EI8=LRZIS;FIUO<KQZ/0G\\?PR\\?POY.\\EOL;MCHMY^NAF"
|
||||||
|
"`>=?`>AB`^AA`NIC`^AD[=-D:6MSI*2>%\"5;!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11(,T!OR:=PYLUD^.%G`NI>`^EA`^Q@"
|
||||||
|
"X]-I@'YI?GAEK)%VY;]J[<]C_^-?W,MJ*#QL!!%$!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"'C%LMY]E`^MJ`.Q:`>EC`^YAV\\EM44I>FH)K_^9F`^M@`NE<`.MP]>-[_^=<\\^%["
|
||||||
|
"/$U`!!%%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%#$\"MS"
|
||||||
|
"!A1(#B5E?7!FV*YNS*IOQJ-MT[!JX,-CR+QGIZ-_I9^3K*F0OK:&W<UQ^N5KZ]!G"
|
||||||
|
"Z\\MV\\]-WZ<AMRZYGDX!=9V%U4E1S?'^&$B-7!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1)355WS:IG]MYIE8YE^N1C`^A>`NE;"
|
||||||
|
"`_E^?WV.CGAIX,!F^N)D`^QA_.AEY]9F;'5Y!!)'!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"*C]XGGUJI9EP`^]D`^AB`>M=^N=>?W=GP:9E`^M?`N=<_^=LZNO\"B8!L_^A=]^5Y"
|
||||||
|
"3EJ#!!!\"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1%\"$\"Q["
|
||||||
|
"!1-)#B%?EX%RV*]OT;!JTJ]LT:ULYL9J`^IC`^U;__%HP+-P8UQ41#]40SY@/SI>"
|
||||||
|
"/3E7-C1/.31:7U=TDX.;S;2]SL32?8\"G'#V&$R9>!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-'5UIYU:QK_.=>RKAIB8-W`_:$`.9O"
|
||||||
|
"``6\\=WR,M9AH_MYI`NI>_NYH;FQAWLYKA(J(!!%'!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"(#-GIHYI*BA3J)MN^N)A`^EE`>I=FHYCJIQE^.=Z]NN=VM:\\:&9SX]=A`NE=^.J)"
|
||||||
|
"55V$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"\"QY:.DIN8UY@E8)LSZUOT[!LTJYKZ<EF^.1CM:AO75-Q9%M_HI*FPJJPQ:JOQ*BQ"
|
||||||
|
"Q*FRQ*JPQ*NQQZRPU[VZV,&_U\\\"]ZM+4N:_!0%2.$\"5A\"1Q6#B!:\"!A/!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9.4EIUT*QH_.)J`^Y?J:%A?8&3Q<2_"
|
||||||
|
"L:^Q04-=QZYP`^]@^.)JBX!H0DA=^.1T<'Z6!!-(!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"$2)8D'YQ7U-A;F5JR:UQ^]IC]=QI@75GC']EDI-`?G^1@H!L[-EG`^]C`>A>_N^B"
|
||||||
|
"8V^7!Q=/!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!QU?"
|
||||||
|
"<7)MX\\]HZMIKT,!AS*MNTJ]KT:YKWKUN@GEH?&Z+M)ZHT;F[U+R\\U+Z_U;^_U+Z_"
|
||||||
|
"U+Z_U+^^UL\"_U\\'!U\\'!U\\\"_UL#\"U;^`WL7$R+O&2%.':':EC9*Y-DR+!A5)!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-.(31OH(QNTJQK_-]D`^Q@\\^!E8&-=P+)G"
|
||||||
|
"T\\)BU,5J?71GL:5>MJEH>'-IN*MC]NJ3,TF#!A1'!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!15)6EQMRJIQ955E9%I=@'!I2D)8CWYJ]=MI]=UMOK!>KJ)F`^]?`^I@`>M>_NR)"
|
||||||
|
"QLC#(3UY!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%#$2-D"
|
||||||
|
"P*-N<VIQ+3!1PZUPT[%ITJ]LU;)P@'-K>V^%QJFMV,\"`UL##UL#!UL#!UL&_UL#!"
|
||||||
|
"UL#!UL#\"UL#\"UL#!UL#!UL#!UL#!UL#\"V,'!SKZ[P;6`V<C$V\\;*A(2N\"QM2!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!)(&\"YHL)1OV;!QT:YI_.%D`_!CF9%BR+=K`^Q>"
|
||||||
|
"`^AA`^ICZ]ADL:9SM:IJX<UH`_6\"F)FA\"R)B!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!%\"-=HXMRV[EQLY9SFH=IQZAWV;%J[]!E`.]9Q;=KMZEE`^UC`^IB`^AB`>I;"
|
||||||
|
"`_>GFZ\"K(T&)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%##R-?"
|
||||||
|
"QJAZD'AGH(1RDX%HW;1PU+!JNY]P3TALNZ&IU\\&_U,'\"UL\"`UL\"`UL\"`UL&^UL\"_"
|
||||||
|
"UL#!UL##UL##UL\"`UL'!UL#!UL#!U\\#\"U<'\"UL&YPJZTS[:[SL#\"4V\"3!Q=-!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!AA0+4%VKI%LVK)NSZYKW[]I`NEA`NICKJ!LZ=9A`^MC"
|
||||||
|
"`NIA`.MC`^MC`_!<`^Y@`_1`T,^])S]_!!%%!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!9.(S1MMIAKW;EPU[-LU+!KT:QLY\\5J`^M@U\\9FZ]9F`^IA`^IB`NIC`NM?"
|
||||||
|
"`.IB`_BCHJ:R$BML!A-$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1Q:"
|
||||||
|
"6UINR*5QWK9XU;-WP*!IW+AN:UIEBGB2S[6XU<*^U<&`UL&`UL&_UL&_UL&_UL&_"
|
||||||
|
"UL\"`UL#!UL'!UL&_UL&_UL#!UL#!UL#\"UL3!O*>K3DQPPJNPIZ'\"$2AJ!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!97,D)RKY%MV+%OTZYMV;1K^M]B`^MB`^EA_>9C`>A>`^ID"
|
||||||
|
"`^IB`^IB`^A>_>II`_NHR\\FZ.U.-!A=0!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!19,+3YVMYALU+!MTJ]LTJUMW;IM`^Q<`^M@_^I@`^IB`^IB`^IB`^IC"
|
||||||
|
"`NIC_NA?`>Z2H*>Q%3!S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"\"B!<,41W4$A72D-<MYIOV[=V/SE9P*2MT;F]U<'#U<&_UL*^UL&_UL&_UL'!UL#!"
|
||||||
|
"UL#!UL#!UL'!UL&_UL&_UL#!UL#!UL#!VL6`FX>=#!5&R;7(&#-Q$2AE!A5*!!!!"
|
||||||
|
"!!!!!!!!!!!!!!=71$=OQ*5SUK!LSK%MU:YI^-QF`^IB`^IB`^ED`^I@`NMC`^EA"
|
||||||
|
"`^IB`^EA_^EM`_[*JJBS*$.\"\"1E0!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!A=.-$)PN)]NUZ]MTZ]NT:MH^]YI`^M?`^IA`^IB`^IB`^IB`^IB"
|
||||||
|
"`^IA`^M?`>AA`O.5EYRC)$\"%!!-'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!\"1M>&UKX;EKPJ)M54QKQ*:MT;R]UL&_UL&_UL'!UL#!UL#!UL#!UL#!"
|
||||||
|
"UL'!UL'!UL##UL#!UL#!UL#!UL#!UL#!V<3\"R+\"VNJ*ML*:U\"2%G!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!\"Q];4UI[QZEQUZ]LT:YMUK9H^-YD`^M@`^IB`^IB`^IB`^IB`^IB`^MA"
|
||||||
|
"`^ID_^M?`O:YA8BF!2-J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!E90DAKVK-QU:]LU*UQV[AE`>=D`^IB`^IB`^IB`^IB`^IB"
|
||||||
|
"`^IB`^IB`^E?`>E@`_20M[FV*D%^!QE2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!1U=75ADX;IMOIYK75-TQ*BKU+Z\\UL&_UL&_UL&_UL&_UL&_UL#!UL#!"
|
||||||
|
"UL'!UL'!UL##UL#!UL#!UL#!U\\#\"KYZHK)VMXLO+[];56V2-$2QO!!!!!!!!!!!!"
|
||||||
|
"!!!%\"!YA;6=QS*ANUK!KTJQRV[MF^N%C`^QB`^IB`^IB`^EA`^IB`^IB`^IB`^IB"
|
||||||
|
"`>A=`_*>K;\"U&#-U!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!\"B-K651AW[ATT+%LU*]IZ\\QH`^IA`^ID`^IA`^IA`^IB"
|
||||||
|
"`^IA`^IB`^EB`^IB`^A?`^V!S\\^[+$6\"\"1M4!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!922DIAXKQOTK!Q0SUCQZNLT[V]UL#!UL\"`UL&`UL&^UL&_UL#!UL#!"
|
||||||
|
"UL#!UL#!UL'\"U<'!U<'!U<'\"U,*_U,##2$5P1%B11UF7(#Z$!!!!!!!!!!!!!!)&"
|
||||||
|
"&#%QDH!QUK%QTZ]KTJQPW+MF_^5E`^IB`^IB`^IB`^IB`^IB`^IB`^MA`NEE`NE;"
|
||||||
|
"_^Z%Z.33)T%_\"1Q0!1-&!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!%2YMCGIPT[%NTJYNU;)I]]EE`^IA`^I?`^IB`^IB"
|
||||||
|
"`^IB`^IB`^IB`^IB`^IB`NA<`_%[X=NS36.9#2-A!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!9/.3A7X[USV[=R7$]?GXRAU;N]UL#\"UL#!UL&`UL&_UL&_UL#!UL#!"
|
||||||
|
"UL#!UL#!UL'!U<'!U<'!U,'\"W,'#HY:E)T\"#!!!!!!!!!!!!!!!!!!!!!!9.)SUU"
|
||||||
|
"GX1HU[-ITJYLT:UMX<!G`NAE`^E@`^IB`^IB`^IB`^IB`^IB`^IB`^IC`^E@_^QU"
|
||||||
|
"^?+.1%B%\"R-?!!!!!!%\"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!)%*#9DNIUPU+!KT:YNV+)J^=MG`^MB`^EC`^IB"
|
||||||
|
"`^IB`^IB`^IB`^IB`^IB`^IA`>A>`^]Q[N6C=(\"C#REM!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!AA2,C5;X[UWUK%KM)ET5T]RRK*VUL&`UL##UL&`UL&`UL&`UL\"`UL\"`"
|
||||||
|
"UL\"`UL\"`U\\&`UL'!U<'!XLS)KI^G,$-`!!)&!!!!!!!!!!!!!!!!\"21H4E9TN)IN"
|
||||||
|
"V[1PTZ]LT*UNYL=D`.9C`^EA`^EB`^IB`^IB`^IB`^IB`^IC`^I@`^E@`>IE_O:["
|
||||||
|
"<'N9\"B%B!A1%!!!!!1)$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!50/3]CU;=WU*YNTZ]MU;-H]]UF`^I@`^IA"
|
||||||
|
"`^IC`^IB`^IB`^IB`^EA`^IB`^IB`^I@`>MA_/\"8F:\"H%35^#B%;!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!AE2,C=;Y+UXTZ]NUK%OA'%MA'6-U\\/!UL&\\UL&`UL#!UL#!UL&_UL&_"
|
||||||
|
"UL&_UL&_U\\&_U,+\"Y<S'CH\"2*$6*!A9-!!!!!!!!!!!!\"QE*#\"QY=&QKTJQLU*]K"
|
||||||
|
"U*YOSZMHZ\\YF`>EC`^IB`^IB`^IB`^IB`^IB`^IB`^IA`NMC`^AE_^=B`/:GFJ\"Q"
|
||||||
|
"&SE\\!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!E<651BT[-LT[!LTJYOV+=J^]]G`^I?"
|
||||||
|
"`^IC`^IB`^IB`^IB`^IB`^IB`^IB`^IB`^EA`>A<`_6-P+VH*T%Z\"!I3!!!!!!%$"
|
||||||
|
"!!!!!!!!!!9//#M;X[QTT;!LTK!LTJ]M9UAABX\"7SKS!V,+#V,+\"U\\'!U\\&`U\\*`"
|
||||||
|
"V,*`V,.`U\\&`P*ZW9VB+%S1X!!!!!!!!!A9/%#%T\"R-C'S-MGH)GW+9RT;!KU*YM"
|
||||||
|
"U;!I\\-)F`^I?`^I@`^IB`^IB`^IB`^IB`^IB`^IB`^IB`>ED`>A=`_22R\\O('35Z"
|
||||||
|
"!!%#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!Y<=&UOU:]NTZ]JT*]MVK=I^]]D"
|
||||||
|
"`^QA`^IA`^IB`^IB`^IB`^IB`^IB`^IB`^IB`^IB`.E@`^]OVL^+6F5V#AU=)39T"
|
||||||
|
"!!M9!!!!!!E64$QCWKIOT:]JU;%LV+)NW;MOJI]B=&YWDH6:N*6TSKF]U\\#&S[NY"
|
||||||
|
"O*BXG9\"E?7B+9&F'#B5E!!!!!!!!!!1//U\".J+'E=(\"U6%IYH8AJU+%NTJULT[)M"
|
||||||
|
"\\=-E`^EB`^EB`^IC`^IB`^IB`^IB`^IB`^MB`^IA`^IB`N=>`_&-U-#!,$R+\"!Y7"
|
||||||
|
"!!%\"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%#$R5@H(ASU[!NTJ]OTJ]LV;9G"
|
||||||
|
"^^!C`^IA`^EB`^ID`^IB`^IB`^IB`^IB`^IB`^IB`NMA`^IB`^EC_>=BH9QI3%\"!"
|
||||||
|
";WFN\"\"!I!1Y>;F1EZ\\1[V;9ZR:AQLY9KK))ER;IBP[5AC(5D<W)J>7)]9%YU6UMQ"
|
||||||
|
"='1SI)I@XM:3T<[-!QA/!!!!!A1'-4Z0Q],#Y.@;Y^L8V=L(B9*`<6-KTK%L]MQE"
|
||||||
|
"`^IB`^IC`^IB`^IB`^IB`^IB`^IB`^IB`^MC`>MB`N=?`>MZZ^7,/52)\"QY7!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!))&\"9@LI9VV;)JU*]MTZUP"
|
||||||
|
"V[EF_>%E`^I=`^EB`^IB`^IB`^IB`^IB`^IB`^IB`^ID`^IA`^MB`NAB^>A><W6)"
|
||||||
|
"Z.X?@(N]`1$EK34QR049R5UZ/:G.BB)7*FJ7>G:CAFZ/2@8W\"<7.(S,!M_NAE"
|
||||||
|
"`^U>`^Y?`?&0R\\K((SZ*.5JE.%.8A8R\\WN<4Y^82X>@7XND9Z.H:JKCL@W]^\\-QF"
|
||||||
|
"`^Q>`^IA`^IB`^IB`^IB`^IB`^IB`^IB`^IB`>E>_NQT]_/,87&8#2-B!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1.(#%EKI-OU;)LTJ]N"
|
||||||
|
"T:UMW;II_>%D`^M@`^IA`^ID`^IB`^IB`^IB`^IB`^IB`^IB`^IC`^M<W<YIB9.`"
|
||||||
|
"_`L[[O0C;G2C?H>XY.T<ZO$?Z_(?]/LJ````````````````````P,P\"CY6VUL9F"
|
||||||
|
"`^]B`NA>`>M[TM#,E9W.Q,KUWND7D)O/R,[]Y.<6Y.<5X.44Z?(C````V.4=?8*8"
|
||||||
|
"U,1=`^Q?`^M@`^IC`^IB`^IB`^IB`^IB`^EB`.QS`OG,=8\"@#B-H!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1-',CYFPZ%TTZ]L"
|
||||||
|
"TK!LTZQOV[=G_>%G`^I@`^IC`^IB`^IB`^IB`^IB`^IB`^IB`^EB`_)BCHEAQ]8+"
|
||||||
|
"`````0T\\Z?(A7665M[SLZ>P;XN85^`4R`P`_`P\\_`P\\_````GZK=K+?J^@D[559\\"
|
||||||
|
"Z]ML`^Q>`.AKV=;-F)_/;'2H````PLW_J+'>X^L8W^<5\\?LK`PX``P\\_`P\\_\\_`P"
|
||||||
|
"@H28Y--H`.MA`^MB`^IB`^IB`^IB`^EA`.AC`?K&>X:@%C!S!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1./D1HRZAO"
|
||||||
|
"U;!JTJ]LT:]LV[MI_>5A`^MC`^IB`^IB`^IB`^IB`^IB`^IB`^QC]>!A<72-_0DZ"
|
||||||
|
"`P\\_`@X^_`LYT]T*96R;V-\\,YN\\<`````P\\_`P\\_`P\\_````/DA\\````````\\/TQ"
|
||||||
|
"5%AA^>5A`>AEWMS&3%6&V^@9````^P<X8VZA[O4C]@$P`@\\_`P\\_`P\\_`P\\_```_"
|
||||||
|
"X>\\E=7J+]N1B`^MA`^IB`^IB`NE?_^AD__:\\H:6S%3-[!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!95149F"
|
||||||
|
"QJ1OU+%LTJ]LT:YMW+UH_N1B`^MA`^IB`^IB`^IB`^IB`^EB`_!AIYQAL;WR````"
|
||||||
|
"`P\\_`P\\_````_@@VGZC7G:75^@,S`````P\\_`P\\_````XNX?='ZR`````@X^````"
|
||||||
|
"QM(\"H)=I_NA;W=G$6VB6R]@(````````5V25ZO4E`````P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"````V>0=<G!O^^AC`^MB`^IB`>EG`_VYK;*Y'CQ[!1)#!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!AE3"
|
||||||
|
"24IKSJIOTK%IT:]PT:YKW+MG_^5C`^M@`^IA`^IA`^EC`>M>\\-UG<GB2`````P\\^"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_YO(@?8>W]`,S``\\```X```X`````J+/EQM($`````P\\_`P\\_"
|
||||||
|
"_PP\\E)K!X=N#>'F(Z/8J8FV?\\OXO````N\\7WDI[1`````P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_````S]X&FI-B`NQC`.E:`_FQJ*VV%S%R\"R%5!!%#!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!1I84$UJSJMTU;!JTJ]LT:UMW[QH_^5F`^IB`^IB`^I@`^IED(MKX.T=`````P`^"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\__`PYC);&SMH*XN\\?W^P<W^L<X.T>B)3'[OLK`P\\^`P\\_`P\\_"
|
||||||
|
"```_^P<Z7F6-PLK`````^`@Y5V*5````````4ER/`````P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\```\\\\_PTZFJ\"_YM)D_/:JP,\"`(3Y^!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!951TQIQZ9NU+%LT[!KTZUMX+]G`.9A`^EB`^YBQ[IEG:?5`@X^`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_```_Z?8E04M^L;SOI;#CJ++FIK'DL[[Q^`@Y`P\\^`P\\_`P\\_"
|
||||||
|
"`P\\_`P`]```````__`X[````O,;Z;':JDYS1BI7(`````P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`@\\_`P\\]T=\\0IJ6GR<[%+TF+\"!E0!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!\"1U90$1IRZAMU;!NTJ]LT*UJW[UJ`^I>YM->>'N?_0@[`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_``\\`````:W:I^`@X`````P\\``P\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_\\/TNEZ+8\\/TM_`P\\`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P``<7RE*$B-\"QY4!!!\"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!=4.3]GPJ1PU+!MTJ]LTZUKT[IK;F]]Y_DH```^`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_``\\`````O,;YO,GY`````P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`0T]GZK?XNTA``\\```\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_````BY3($2QK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!92-CEEKI-PV;5PRZ=O:F)XS=H/`````@\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_````[OHKQ=(\"`````P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_````O\\K]K;?K`````P\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\``P\\]```]<XC\"\"R!9!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!\"QQ7.SQIF(5P6U9HMKSS\\OPH```^`P`_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`@X^`0T]`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`0T^4UV1`````P\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`PX_`@T^````GJ[D(C^#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!\"QM15&.9/TA[OL3VZ.T:X>86\\/DH`PX^`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_````='ZQT-P-`````P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"````^P8VG:O?&39^!Q5)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!Q9)$\"9EIJW?[_$?X^H6Y.@6X><4Z_4B_`PZ`````P\\`"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_````Z/0E76>;`````P\\_`P\\_```_``````\\\\"
|
||||||
|
"S-L*8':U#\"1H!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!$%\"IL?XK\"XN@2YNP:Y.<5X><5Y>P:^@8T`P``"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_````3%6*```````````````_P\\[_=(K)"
|
||||||
|
"'35V!A9+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1/.4>#KK3EV>(0YNH7XND5X>H8\\/HG"
|
||||||
|
"`0T\\`P```P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_````\\/TMA9#$Q,`\"V>8:CIO30UJ9%3!R!!-*"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%&!!A4-DB%=H.]J:_CT-<%UMX-"
|
||||||
|
"W^87[/<H^P<W`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_````N<7W56*6&\"YO$\"]P\"2!?#\"AG\"R)8!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!19-#25F(3!J9VZ;"
|
||||||
|
";'6D=X\"QSML+`````P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_````\\/PM>XO$&#-X\"A9'!1-&!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!%\"!A1'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!QQ>@8W$\\/8C"
|
||||||
|
"Z_(>^P0Q`````P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_```_````D:'5%CE\\!Q5&\"!M2!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!%\"!A5)!!!!!!!!!!%#!A1'!!%#!!!!!!!!!!!!!!9/15>6Y><5Y.85"
|
||||||
|
"Z.X=`@X]`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`@`_````LK[W'SE`#\"!;!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!%\"\"AQ4!!!!!!!!!!!!!A9+)T2.RLW_Y>D:W^85"
|
||||||
|
"^`4T`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_"
|
||||||
|
"`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`@X^`@X\\G*_H&SI`!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
"";
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue