Remove pending C tutorials
Presence of these files caused github to show the project as a C project.pull/4/head
parent
6266cd38c6
commit
907f8dc75c
@ -1,43 +0,0 @@
|
||||
#
|
||||
# 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
|
@ -1,36 +0,0 @@
|
||||
Oktatóanyag 09 - Framebuffer
|
||||
============================
|
||||
|
||||
Rendben, végre valami parasztvakítás :-) Eddig a képernyőn csak a szivárvány doboz 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 (800 * 4=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.
|
@ -1,35 +0,0 @@
|
||||
Tutorial 09 - Framebuffer
|
||||
=========================
|
||||
|
||||
Okay, finaly some eyecandy :-) So far the screen showed the rainbow splash. 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.
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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);
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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))
|
@ -1,399 +0,0 @@
|
||||
/* 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`!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
"";
|
Binary file not shown.
@ -1,111 +0,0 @@
|
||||
/*
|
||||
* 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"
|
||||
#include "homer.h"
|
||||
|
||||
unsigned int width, height, pitch;
|
||||
unsigned char *lfb;
|
||||
|
||||
/**
|
||||
* Set screen resolution to 1024x768
|
||||
*/
|
||||
void lfb_init()
|
||||
{
|
||||
mbox[0] = 35*4;
|
||||
mbox[1] = MBOX_REQUEST;
|
||||
|
||||
mbox[2] = 0x48003; //set phy wh
|
||||
mbox[3] = 8;
|
||||
mbox[4] = 8;
|
||||
mbox[5] = 1024; //FrameBufferInfo.width
|
||||
mbox[6] = 768; //FrameBufferInfo.height
|
||||
|
||||
mbox[7] = 0x48004; //set virt wh
|
||||
mbox[8] = 8;
|
||||
mbox[9] = 8;
|
||||
mbox[10] = 1024; //FrameBufferInfo.virtual_width
|
||||
mbox[11] = 768; //FrameBufferInfo.virtual_height
|
||||
|
||||
mbox[12] = 0x48009; //set virt offset
|
||||
mbox[13] = 8;
|
||||
mbox[14] = 8;
|
||||
mbox[15] = 0; //FrameBufferInfo.x_offset
|
||||
mbox[16] = 0; //FrameBufferInfo.y.offset
|
||||
|
||||
mbox[17] = 0x48005; //set depth
|
||||
mbox[18] = 4;
|
||||
mbox[19] = 4;
|
||||
mbox[20] = 32; //FrameBufferInfo.depth
|
||||
|
||||
mbox[21] = 0x48006; //set pixel order
|
||||
mbox[22] = 4;
|
||||
mbox[23] = 4;
|
||||
mbox[24] = 1; //RGB, not BGR preferably
|
||||
|
||||
mbox[25] = 0x40001; //get framebuffer, gets alignment on request
|
||||
mbox[26] = 8;
|
||||
mbox[27] = 8;
|
||||
mbox[28] = 4096; //FrameBufferInfo.pointer
|
||||
mbox[29] = 0; //FrameBufferInfo.size
|
||||
|
||||
mbox[30] = 0x40008; //get pitch
|
||||
mbox[31] = 4;
|
||||
mbox[32] = 4;
|
||||
mbox[33] = 0; //FrameBufferInfo.pitch
|
||||
|
||||
mbox[34] = MBOX_TAG_LAST;
|
||||
|
||||
if(mbox_call(MBOX_CH_PROP) && mbox[20]==32 && mbox[28]!=0) {
|
||||
mbox[28]&=0x3FFFFFFF;
|
||||
width=mbox[5];
|
||||
height=mbox[6];
|
||||
pitch=mbox[33];
|
||||
lfb=(void*)((unsigned long)mbox[28]);
|
||||
} else {
|
||||
uart_puts("Unable to set screen resolution to 1024x768x32\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a picture
|
||||
*/
|
||||
void lfb_showpicture()
|
||||
{
|
||||
int x,y;
|
||||
unsigned char *ptr=lfb;
|
||||
char *data=homer_data, pixel[4];
|
||||
|
||||
ptr += (height-homer_height)/2*pitch + (width-homer_width)*2;
|
||||
for(y=0;y<homer_height;y++) {
|
||||
for(x=0;x<homer_width;x++) {
|
||||
HEADER_PIXEL(data, pixel);
|
||||
*((unsigned int*)ptr)=*((unsigned int *)&pixel);
|
||||
ptr+=4;
|
||||
}
|
||||
ptr+=pitch-homer_width*4;
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* 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 lfb_init();
|
||||
void lfb_showpicture();
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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;
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* 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 "lfb.h"
|
||||
|
||||
void main()
|
||||
{
|
||||
// set up serial console and linear frame buffer
|
||||
uart_init();
|
||||
lfb_init();
|
||||
|
||||
// display a pixmap
|
||||
lfb_showpicture();
|
||||
|
||||
// echo everything back
|
||||
while(1) {
|
||||
uart_send(uart_getc());
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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);
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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
|
@ -1,127 +0,0 @@
|
||||
/*
|
||||
* 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|=(4<<12)|(4<<15); // alt0
|
||||
*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 character 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);
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* 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);
|
@ -1,46 +0,0 @@
|
||||
#
|
||||
# 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 $@
|
||||
|
||||
font.o: font.psf
|
||||
aarch64-elf-ld -r -b binary -o font.o font.psf
|
||||
|
||||
kernel8.img: start.o font.o $(OBJS)
|
||||
aarch64-elf-ld -nostdlib -nostartfiles start.o font.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
|
@ -1,40 +0,0 @@
|
||||
Oktatóanyag 0A - PC Screen Font
|
||||
===============================
|
||||
|
||||
Képeket kirakni poénos, de mindenképpen szükség van többre, karakterek megjelenítésére is. Alapvetően
|
||||
a fontok nem mások, mint képek minden karakterhez (glyphek). Ehhez az oktatóanyaghoz azt a PC Screen Font
|
||||
formátumot választottam, amit a Linux Console csomag is használ.
|
||||
|
||||
Lfb.h, lfb.c
|
||||
------------
|
||||
|
||||
`lfb_init()` beállítja a felbontást, mélységet, színcsatornákat és visszaadja a framebuffer címét.
|
||||
|
||||
`lfb_print(x,y,s)` megjelenít egy szöveget a képernyőn.
|
||||
|
||||
Font.psf
|
||||
--------
|
||||
|
||||
A font fájl. Bármelyik használható a /usr/share/kbd/consolefonts mappából. Unicode táblákat nem támogatja.
|
||||
A karakterek glypehnek való megfeleltetése ezen táblázat által (a meglévő egy-az-egyhez megfeleltetés helyett)
|
||||
házi feladat, Rád van bízva. Ezt a fontot az eredeti IBM PC VGA ROM-jában található 8x16 fontkészletből generáltam,
|
||||
és 127 glyphet tartalmaz.
|
||||
|
||||
Makefile
|
||||
--------
|
||||
|
||||
Egy új object-et adtam hozzá, ami a psf-ből generálódik. Jó példa arra, hogyan kell bináris fájlt behúzni és
|
||||
hivatkozni C forrásból. A következő parancsot használtam a cimke nevének kiderítésére:
|
||||
|
||||
```sh
|
||||
$ aarch64-elf-readelf -s font.o
|
||||
... kimenet törölve az átláthatóság miatt ...
|
||||
2: 0000000000000820 0 NOTYPE GLOBAL DEFAULT 1 _binary_font_psf_end
|
||||
3: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 1 _binary_font_psf_start
|
||||
4: 0000000000000820 0 NOTYPE GLOBAL DEFAULT ABS _binary_font_psf_size
|
||||
```
|
||||
|
||||
Main
|
||||
----
|
||||
|
||||
Nagyon egyszerű. Beállítjuk a felbontást és megjelenítjük a szöveget.
|
@ -1,39 +0,0 @@
|
||||
Tutorial 0A - PC Screen Font
|
||||
============================
|
||||
|
||||
Drawing pixmaps is fun, but definitely there's a need to display characters as well. Basicaly fonts
|
||||
are nothing more than bitmaps for each character. For this tutorial I choosed PC Screen Font format,
|
||||
the same Linux Console uses.
|
||||
|
||||
Lfb.h, lfb.c
|
||||
------------
|
||||
|
||||
`lfb_init()` sets up resolution, depth, and color channel order. Also queries framebuffer's address.
|
||||
|
||||
`lfb_print(x,y,s)` displays a string on screen.
|
||||
|
||||
Font.psf
|
||||
--------
|
||||
|
||||
The font file. Use any file from /usr/share/kbd/consolefonts. Unicode table is not supported. Translating
|
||||
characters to glyph index using that table (instead of one-to-one relation) is a homework for you. This font
|
||||
is generated from the original IBM PC VGA 8x16 Font ROM, and includes 127 glyphs.
|
||||
|
||||
Makefile
|
||||
--------
|
||||
|
||||
I've added a new object file, generated from the psf. It's a good example of how to include and reference
|
||||
a binary file in C. I've used the following command to find out the label:
|
||||
|
||||
```sh
|
||||
$ aarch64-elf-readelf -s font.o
|
||||
... output removed for clearity ...
|
||||
2: 0000000000000820 0 NOTYPE GLOBAL DEFAULT 1 _binary_font_psf_end
|
||||
3: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 1 _binary_font_psf_start
|
||||
4: 0000000000000820 0 NOTYPE GLOBAL DEFAULT ABS _binary_font_psf_size
|
||||
```
|
||||
|
||||
Main
|
||||
----
|
||||
|
||||
Very simple. We set the resolution and display the string.
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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);
|
Binary file not shown.
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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.
@ -1,150 +0,0 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
/* PC Screen Font as used by Linux Console */
|
||||
typedef struct {
|
||||
unsigned int magic;
|
||||
unsigned int version;
|
||||
unsigned int headersize;
|
||||
unsigned int flags;
|
||||
unsigned int numglyph;
|
||||
unsigned int bytesperglyph;
|
||||
unsigned int height;
|
||||
unsigned int width;
|
||||
unsigned char glyphs;
|
||||
} __attribute__((packed)) psf_t;
|
||||
extern volatile unsigned char _binary_font_psf_start;
|
||||
|
||||
unsigned int width, height, pitch;
|
||||
unsigned char *lfb;
|
||||
|
||||
/**
|
||||
* Set screen resolution to 1024x768
|
||||
*/
|
||||
void lfb_init()
|
||||
{
|
||||
mbox[0] = 35*4;
|
||||
mbox[1] = MBOX_REQUEST;
|
||||
|
||||
mbox[2] = 0x48003; //set phy wh
|
||||
mbox[3] = 8;
|
||||
mbox[4] = 8;
|
||||
mbox[5] = 1024; //FrameBufferInfo.width
|
||||
mbox[6] = 768; //FrameBufferInfo.height
|
||||
|
||||
mbox[7] = 0x48004; //set virt wh
|
||||
mbox[8] = 8;
|
||||
mbox[9] = 8;
|
||||
mbox[10] = 1024; //FrameBufferInfo.virtual_width
|
||||
mbox[11] = 768; //FrameBufferInfo.virtual_height
|
||||
|
||||
mbox[12] = 0x48009; //set virt offset
|
||||
mbox[13] = 8;
|
||||
mbox[14] = 8;
|
||||
mbox[15] = 0; //FrameBufferInfo.x_offset
|
||||
mbox[16] = 0; //FrameBufferInfo.y.offset
|
||||
|
||||
mbox[17] = 0x48005; //set depth
|
||||
mbox[18] = 4;
|
||||
mbox[19] = 4;
|
||||
mbox[20] = 32; //FrameBufferInfo.depth
|
||||
|
||||
mbox[21] = 0x48006; //set pixel order
|
||||
mbox[22] = 4;
|
||||
mbox[23] = 4;
|
||||
mbox[24] = 1; //RGB, not BGR preferably
|
||||
|
||||
mbox[25] = 0x40001; //get framebuffer, gets alignment on request
|
||||
mbox[26] = 8;
|
||||
mbox[27] = 8;
|
||||
mbox[28] = 4096; //FrameBufferInfo.pointer
|
||||
mbox[29] = 0; //FrameBufferInfo.size
|
||||
|
||||
mbox[30] = 0x40008; //get pitch
|
||||
mbox[31] = 4;
|
||||
mbox[32] = 4;
|
||||
mbox[33] = 0; //FrameBufferInfo.pitch
|
||||
|
||||
mbox[34] = MBOX_TAG_LAST;
|
||||
|
||||
if(mbox_call(MBOX_CH_PROP) && mbox[20]==32 && mbox[28]!=0) {
|
||||
mbox[28]&=0x3FFFFFFF;
|
||||
width=mbox[5];
|
||||
height=mbox[6];
|
||||
pitch=mbox[33];
|
||||
lfb=(void*)((unsigned long)mbox[28]);
|
||||
} else {
|
||||
uart_puts("Unable to set screen resolution to 1024x768x32\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a string
|
||||
*/
|
||||
void lfb_print(int x, int y, char *s)
|
||||
{
|
||||
// get our font
|
||||
psf_t *font = (psf_t*)&_binary_font_psf_start;
|
||||
// draw next character if it's not zero
|
||||
while(*s) {
|
||||
// get the offset of the glyph. Need to adjust this to support unicode table
|
||||
unsigned char *glyph = (unsigned char*)&_binary_font_psf_start +
|
||||
font->headersize + (*((unsigned char*)s)<font->numglyph?*s:0)*font->bytesperglyph;
|
||||
// calculate the offset on screen
|
||||
int offs = (y * font->height * pitch) + (x * (font->width+1) * 4);
|
||||
// variables
|
||||
int i,j, line,mask, bytesperline=(font->width+7)/8;
|
||||
// handle carrige return
|
||||
if(*s=='\r') {
|
||||
x=0;
|
||||
} else
|
||||
// new line
|
||||
if(*s=='\n') {
|
||||
x=0; y++;
|
||||
} else {
|
||||
// display a character
|
||||
for(j=0;j<font->height;j++){
|
||||
// display one row
|
||||
line=offs;
|
||||
mask=1<<(font->width-1);
|
||||
for(i=0;i<font->width;i++){
|
||||
// if bit set, we use white color, otherwise black
|
||||
*((unsigned int*)(lfb + line))=((int)*glyph) & mask?0xFFFFFF:0;
|
||||
mask>>=1;
|
||||
line+=4;
|
||||
}
|
||||
// adjust to next line
|
||||
glyph+=bytesperline;
|
||||
offs+=pitch;
|
||||
}
|
||||
x++;
|
||||
}
|
||||
// next character
|
||||
s++;
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* 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 lfb_init();
|
||||
void lfb_print(int x, int y, char *s);
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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;
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* 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 "lfb.h"
|
||||
|
||||
void main()
|
||||
{
|
||||
// set up serial console and linear frame buffer
|
||||
uart_init();
|
||||
lfb_init();
|
||||
|
||||
// display a string on screen
|
||||
lfb_print(10, 5, "Hello World!");
|
||||
|
||||
// echo everything back
|
||||
while(1) {
|
||||
uart_send(uart_getc());
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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);
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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
|
@ -1,127 +0,0 @@
|
||||
/*
|
||||
* 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|=(4<<12)|(4<<15); // alt0
|
||||
*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 character 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);
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* 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);
|
@ -1,43 +0,0 @@
|
||||
#
|
||||
# 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
|
@ -1,22 +0,0 @@
|
||||
Oktatóanyag 0B - Szektor Beolvasás
|
||||
==================================
|
||||
|
||||
Ezidáig minden adatot (kép, font) hozzálinkeltünk a kernelhez. Itt az ideje, hogy adatot olvassunk be
|
||||
az SD kártyáról. Ebben az oktatóanyagban egy igazi meghajtót implementálunk a szektor beolvasásához.
|
||||
|
||||
Sd.h, sd.c
|
||||
------------
|
||||
|
||||
Nos, jó lenne, ha lenne levelesláda szektorok olvasására és írására, de nincs. Ezért nekünk kell direktben
|
||||
beszélni az EMMC-vel, ami trükkös és unalmas feladat. Különböző kártyákkal is törődnünk kell. De végül,
|
||||
rendelkezésre áll két funkció.
|
||||
|
||||
`sd_init()` inicializálja az EMMC-t SD kártya olvasáshoz.
|
||||
|
||||
`sd_readblock(lba,buffer,num)` beolvas num blokkot (szektort) az SD kártyáról a buffer-be lba-tól kezdve.
|
||||
|
||||
Main
|
||||
----
|
||||
|
||||
A blokkot a bss szegmens utánra töltjük be, majd kidumpoljuk a konzolra. A beolvasás funkció részletes
|
||||
üzeneteket ír ki arról, hogy épp mit kommunikál az EMMC vezérlővel.
|
@ -1,22 +0,0 @@
|
||||
Tutorial 0B - Read Sector
|
||||
=========================
|
||||
|
||||
So far we have linked our data (pixmap, font) to the kernel image. It is time to read data from the
|
||||
SD card. For this tutorial we're implementing a real driver for read sector function.
|
||||
|
||||
Sd.h, sd.c
|
||||
------------
|
||||
|
||||
Well, it would be nice to have a mailbox for reading and writing sectors, but there isn't. So we have to
|
||||
talk directly to the EMMC, which is tricky and boring. We have to handle all kinds of cards. But finally,
|
||||
we have two function.
|
||||
|
||||
`sd_init()` initialize EMMC for SD card read.
|
||||
|
||||
`sd_readblock(lba,buffer,num)` read num blocks (sectors) from the SD card into buffer starting at sector lba.
|
||||
|
||||
Main
|
||||
----
|
||||
|
||||
We read a block after the bss segment in memory, and then we dump it to the console. The read function will
|
||||
display detailed information on the EMMC communication.
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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);
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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.
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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;
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* 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 "sd.h"
|
||||
|
||||
// get the end of bss segment from linker
|
||||
extern unsigned char _end;
|
||||
|
||||
void main()
|
||||
{
|
||||
// set up serial console
|
||||
uart_init();
|
||||
|
||||
// initialize EMMC and detect SD card type
|
||||
if(sd_init()==SD_OK) {
|
||||
// read the master boot record after our bss segment
|
||||
if(sd_readblock(0,&_end,1)) {
|
||||
// dump it to serial console
|
||||
uart_dump(&_end);
|
||||
}
|
||||
}
|
||||
|
||||
// echo everything back
|
||||
while(1) {
|
||||
uart_send(uart_getc());
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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);
|
@ -1,355 +0,0 @@
|
||||
/*
|
||||
* 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 "uart.h"
|
||||
#include "delays.h"
|
||||
#include "sd.h"
|
||||
|
||||
#define EMMC_ARG2 ((volatile unsigned int*)(MMIO_BASE+0x00300000))
|
||||
#define EMMC_BLKSIZECNT ((volatile unsigned int*)(MMIO_BASE+0x00300004))
|
||||
#define EMMC_ARG1 ((volatile unsigned int*)(MMIO_BASE+0x00300008))
|
||||
#define EMMC_CMDTM ((volatile unsigned int*)(MMIO_BASE+0x0030000C))
|
||||
#define EMMC_RESP0 ((volatile unsigned int*)(MMIO_BASE+0x00300010))
|
||||
#define EMMC_RESP1 ((volatile unsigned int*)(MMIO_BASE+0x00300014))
|
||||
#define EMMC_RESP2 ((volatile unsigned int*)(MMIO_BASE+0x00300018))
|
||||
#define EMMC_RESP3 ((volatile unsigned int*)(MMIO_BASE+0x0030001C))
|
||||
#define EMMC_DATA ((volatile unsigned int*)(MMIO_BASE+0x00300020))
|
||||
#define EMMC_STATUS ((volatile unsigned int*)(MMIO_BASE+0x00300024))
|
||||
#define EMMC_CONTROL0 ((volatile unsigned int*)(MMIO_BASE+0x00300028))
|
||||
#define EMMC_CONTROL1 ((volatile unsigned int*)(MMIO_BASE+0x0030002C))
|
||||
#define EMMC_INTERRUPT ((volatile unsigned int*)(MMIO_BASE+0x00300030))
|
||||
#define EMMC_INT_MASK ((volatile unsigned int*)(MMIO_BASE+0x00300034))
|
||||
#define EMMC_INT_EN ((volatile unsigned int*)(MMIO_BASE+0x00300038))
|
||||
#define EMMC_CONTROL2 ((volatile unsigned int*)(MMIO_BASE+0x0030003C))
|
||||
#define EMMC_SLOTISR_VER ((volatile unsigned int*)(MMIO_BASE+0x003000FC))
|
||||
|
||||
// command flags
|
||||
#define CMD_NEED_APP 0x80000000
|
||||
#define CMD_RSPNS_48 0x00020000
|
||||
#define CMD_ERRORS_MASK 0xfff9c004
|
||||
#define CMD_RCA_MASK 0xffff0000
|
||||
|
||||
// COMMANDs
|
||||
#define CMD_GO_IDLE 0x00000000
|
||||
#define CMD_ALL_SEND_CID 0x02010000
|
||||
#define CMD_SEND_REL_ADDR 0x03020000
|
||||
#define CMD_CARD_SELECT 0x07030000
|
||||
#define CMD_SEND_IF_COND 0x08020000
|
||||
#define CMD_STOP_TRANS 0x0C030000
|
||||
#define CMD_READ_SINGLE 0x11220010
|
||||
#define CMD_READ_MULTI 0x12220032
|
||||
#define CMD_SET_BLOCKCNT 0x17020000
|
||||
#define CMD_APP_CMD 0x37000000
|
||||
#define CMD_SET_BUS_WIDTH (0x06020000|CMD_NEED_APP)
|
||||
#define CMD_SEND_OP_COND (0x29020000|CMD_NEED_APP)
|
||||
#define CMD_SEND_SCR (0x33220010|CMD_NEED_APP)
|
||||
|
||||
// STATUS register settings
|
||||
#define SR_READ_AVAILABLE 0x00000800
|
||||
#define SR_DAT_INHIBIT 0x00000002
|
||||
#define SR_CMD_INHIBIT 0x00000001
|
||||
#define SR_APP_CMD 0x00000020
|
||||
|
||||
// INTERRUPT register settings
|
||||
#define INT_DATA_TIMEOUT 0x00100000
|
||||
#define INT_CMD_TIMEOUT 0x00010000
|
||||
#define INT_READ_RDY 0x00000020
|
||||
#define INT_CMD_DONE 0x00000001
|
||||
|
||||
#define INT_ERROR_MASK 0x017E8000
|
||||
|
||||
// CONTROL register settings
|
||||
#define C0_SPI_MODE_EN 0x00100000
|
||||
#define C0_HCTL_HS_EN 0x00000004
|
||||
#define C0_HCTL_DWITDH 0x00000002
|
||||
|
||||
#define C1_SRST_DATA 0x04000000
|
||||
#define C1_SRST_CMD 0x02000000
|
||||
#define C1_SRST_HC 0x01000000
|
||||
#define C1_TOUNIT_DIS 0x000f0000
|
||||
#define C1_TOUNIT_MAX 0x000e0000
|
||||
#define C1_CLK_GENSEL 0x00000020
|
||||
#define C1_CLK_EN 0x00000004
|
||||
#define C1_CLK_STABLE 0x00000002
|
||||
#define C1_CLK_INTLEN 0x00000001
|
||||
|
||||
// SLOTISR_VER values
|
||||
#define HOST_SPEC_NUM 0x00ff0000
|
||||
#define HOST_SPEC_NUM_SHIFT 16
|
||||
#define HOST_SPEC_V3 2
|
||||
#define HOST_SPEC_V2 1
|
||||
#define HOST_SPEC_V1 0
|
||||
|
||||
// SCR flags
|
||||
#define SCR_SD_BUS_WIDTH_4 0x00000400
|
||||
#define SCR_SUPP_SET_BLKCNT 0x02000000
|
||||
// added by my driver
|
||||
#define SCR_SUPP_CCS 0x00000001
|
||||
|
||||
#define ACMD41_VOLTAGE 0x00ff8000
|
||||
#define ACMD41_CMD_COMPLETE 0x80000000
|
||||
#define ACMD41_CMD_CCS 0x40000000
|
||||
#define ACMD41_ARG_HC 0x51ff8000
|
||||
|
||||
unsigned long sd_scr[2], sd_ocr, sd_rca, sd_err, sd_hv;
|
||||
|
||||
/**
|
||||
* Wait for data or command ready
|
||||
*/
|
||||
int sd_status(unsigned int mask)
|
||||
{
|
||||
int cnt = 500000; while((*EMMC_STATUS & mask) && !(*EMMC_INTERRUPT & INT_ERROR_MASK) && cnt--) wait_msec(1);
|
||||
return (cnt <= 0 || (*EMMC_INTERRUPT & INT_ERROR_MASK)) ? SD_ERROR : SD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for interrupt
|
||||
*/
|
||||
int sd_int(unsigned int mask)
|
||||
{
|
||||
unsigned int r, m=mask | INT_ERROR_MASK;
|
||||
int cnt = 1000000; while(!(*EMMC_INTERRUPT & m) && cnt--) wait_msec(1);
|
||||
r=*EMMC_INTERRUPT;
|
||||
if(cnt<=0 || (r & INT_CMD_TIMEOUT) || (r & INT_DATA_TIMEOUT) ) { *EMMC_INTERRUPT=r; return SD_TIMEOUT; } else
|
||||
if(r & INT_ERROR_MASK) { *EMMC_INTERRUPT=r; return SD_ERROR; }
|
||||
*EMMC_INTERRUPT=mask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a command
|
||||
*/
|
||||
int sd_cmd(unsigned int code, unsigned int arg)
|
||||
{
|
||||
int r=0;
|
||||
sd_err=SD_OK;
|
||||
if(code&CMD_NEED_APP) {
|
||||
r=sd_cmd(CMD_APP_CMD|(sd_rca?CMD_RSPNS_48:0),sd_rca);
|
||||
if(sd_rca && !r) { uart_puts("ERROR: failed to send SD APP command\n"); sd_err=SD_ERROR;return 0;}
|
||||
code &= ~CMD_NEED_APP;
|
||||
}
|
||||
if(sd_status(SR_CMD_INHIBIT)) { uart_puts("ERROR: EMMC busy\n"); sd_err= SD_TIMEOUT;return 0;}
|
||||
uart_puts("EMMC: Sending command ");uart_hex(code);uart_puts(" arg ");uart_hex(arg);uart_send('\n');
|
||||
*EMMC_INTERRUPT=*EMMC_INTERRUPT; *EMMC_ARG1=arg; *EMMC_CMDTM=code;
|
||||
if(code==CMD_SEND_OP_COND) wait_msec(1000); else
|
||||
if(code==CMD_SEND_IF_COND || code==CMD_APP_CMD) wait_msec(100);
|
||||
if((r=sd_int(INT_CMD_DONE))) {uart_puts("ERROR: failed to send EMMC command\n");sd_err=r;return 0;}
|
||||
r=*EMMC_RESP0;
|
||||
if(code==CMD_GO_IDLE || code==CMD_APP_CMD) return 0; else
|
||||
if(code==(CMD_APP_CMD|CMD_RSPNS_48)) return r&SR_APP_CMD; else
|
||||
if(code==CMD_SEND_OP_COND) return r; else
|
||||
if(code==CMD_SEND_IF_COND) return r==arg? SD_OK : SD_ERROR; else
|
||||
if(code==CMD_ALL_SEND_CID) {r|=*EMMC_RESP3; r|=*EMMC_RESP2; r|=*EMMC_RESP1; return r; } else
|
||||
if(code==CMD_SEND_REL_ADDR) {
|
||||
sd_err=(((r&0x1fff))|((r&0x2000)<<6)|((r&0x4000)<<8)|((r&0x8000)<<8))&CMD_ERRORS_MASK;
|
||||
return r&CMD_RCA_MASK;
|
||||
}
|
||||
return r&CMD_ERRORS_MASK;
|
||||
// make gcc happy
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* read a block from sd card and return the number of bytes read
|
||||
* returns 0 on error.
|
||||
*/
|
||||
int sd_readblock(unsigned int lba, unsigned char *buffer, unsigned int num)
|
||||
{
|
||||
int r,c=0,d;
|
||||
if(num<1) num=1;
|
||||
uart_puts("sd_readblock lba ");uart_hex(lba);uart_puts(" num ");uart_hex(num);uart_send('\n');
|
||||
if(sd_status(SR_DAT_INHIBIT)) {sd_err=SD_TIMEOUT; return 0;}
|
||||
unsigned int *buf=(unsigned int *)buffer;
|
||||
if(sd_scr[0] & SCR_SUPP_CCS) {
|
||||
if(num > 1 && (sd_scr[0] & SCR_SUPP_SET_BLKCNT)) {
|
||||
sd_cmd(CMD_SET_BLOCKCNT,num);
|
||||
if(sd_err) return 0;
|
||||
}
|
||||
*EMMC_BLKSIZECNT = (num << 16) | 512;
|
||||
sd_cmd(num == 1 ? CMD_READ_SINGLE : CMD_READ_MULTI,lba);
|
||||
if(sd_err) return 0;
|
||||
} else {
|
||||
*EMMC_BLKSIZECNT = (1 << 16) | 512;
|
||||
}
|
||||
while( c < num ) {
|
||||
if(!(sd_scr[0] & SCR_SUPP_CCS)) {
|
||||
sd_cmd(CMD_READ_SINGLE,(lba+c)*512);
|
||||
if(sd_err) return 0;
|
||||
}
|
||||
if((r=sd_int(INT_READ_RDY))){uart_puts("\rERROR: Timeout waiting for ready to read\n");sd_err=r;return 0;}
|
||||
for(d=0;d<128;d++) buf[d] = *EMMC_DATA;
|
||||
c++; buf+=128;
|
||||
}
|
||||
if( num > 1 && !(sd_scr[0] & SCR_SUPP_SET_BLKCNT) && (sd_scr[0] & SCR_SUPP_CCS)) sd_cmd(CMD_STOP_TRANS,0);
|
||||
return sd_err!=SD_OK || c!=num? 0 : num*512;
|
||||
}
|
||||
|
||||
/**
|
||||
* set SD clock to frequency in Hz
|
||||
*/
|
||||
int sd_clk(unsigned int f)
|
||||
{
|
||||
unsigned int d,c=41666666/f,x,s=32,h=0;
|
||||
int cnt = 100000;
|
||||
while((*EMMC_STATUS & (SR_CMD_INHIBIT|SR_DAT_INHIBIT)) && cnt--) wait_msec(1);
|
||||
if(cnt<=0) {
|
||||
uart_puts("ERROR: timeout waiting for inhibit flag\n");
|
||||
return SD_ERROR;
|
||||
}
|
||||
|
||||
*EMMC_CONTROL1 &= ~C1_CLK_EN; wait_msec(10);
|
||||
x=c-1; if(!x) s=0; else {
|
||||
if(!(x & 0xffff0000u)) { x <<= 16; s -= 16; }
|
||||
if(!(x & 0xff000000u)) { x <<= 8; s -= 8; }
|
||||
if(!(x & 0xf0000000u)) { x <<= 4; s -= 4; }
|
||||
if(!(x & 0xc0000000u)) { x <<= 2; s -= 2; }
|
||||
if(!(x & 0x80000000u)) { x <<= 1; s -= 1; }
|
||||
if(s>0) s--;
|
||||
if(s>7) s=7;
|
||||
}
|
||||
if(sd_hv>HOST_SPEC_V2) d=c; else d=(1<<s);
|
||||
if(d<=2) {d=2;s=0;}
|
||||
uart_puts("sd_clk divisor ");uart_hex(d);uart_puts(", shift ");uart_hex(s);uart_send('\n');
|
||||
if(sd_hv>HOST_SPEC_V2) h=(d&0x300)>>2;
|
||||
d=(((d&0x0ff)<<8)|h);
|
||||
*EMMC_CONTROL1=(*EMMC_CONTROL1&0xffff003f)|d; wait_msec(10);
|
||||
*EMMC_CONTROL1 |= C1_CLK_EN; wait_msec(10);
|
||||
cnt=10000; while(!(*EMMC_CONTROL1 & C1_CLK_STABLE) && cnt--) wait_msec(10);
|
||||
if(cnt<=0) {
|
||||
uart_puts("ERROR: failed to get stable clock\n");
|
||||
return SD_ERROR;
|
||||
}
|
||||
return SD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize EMMC to read SDHC card
|
||||
*/
|
||||
int sd_init()
|
||||
{
|
||||
long r,cnt,ccs=0;
|
||||
// GPIO_CD
|
||||
r=*GPFSEL4; r&=~(7<<(7*3)); *GPFSEL4=r;
|
||||
*GPPUD=2; wait_cycles(150); *GPPUDCLK1=(1<<15); wait_cycles(150); *GPPUD=0; *GPPUDCLK1=0;
|
||||
r=*GPHEN1; r|=1<<15; *GPHEN1=r;
|
||||
|
||||
// GPIO_CLK, GPIO_CMD
|
||||
r=*GPFSEL4; r|=(7<<(8*3))|(7<<(9*3)); *GPFSEL4=r;
|
||||
*GPPUD=2; wait_cycles(150); *GPPUDCLK1=(1<<16)|(1<<17); wait_cycles(150); *GPPUD=0; *GPPUDCLK1=0;
|
||||
|
||||
// GPIO_DAT0, GPIO_DAT1, GPIO_DAT2, GPIO_DAT3
|
||||
r=*GPFSEL5; r|=(7<<(0*3)) | (7<<(1*3)) | (7<<(2*3)) | (7<<(3*3)); *GPFSEL5=r;
|
||||
*GPPUD=2; wait_cycles(150);
|
||||
*GPPUDCLK1=(1<<18) | (1<<19) | (1<<20) | (1<<21);
|
||||
wait_cycles(150); *GPPUD=0; *GPPUDCLK1=0;
|
||||
|
||||
sd_hv = (*EMMC_SLOTISR_VER & HOST_SPEC_NUM) >> HOST_SPEC_NUM_SHIFT;
|
||||
uart_puts("EMMC: GPIO set up\n");
|
||||
// Reset the card.
|
||||
*EMMC_CONTROL0 = 0; *EMMC_CONTROL1 |= C1_SRST_HC;
|
||||
cnt=10000; do{wait_msec(10);} while( (*EMMC_CONTROL1 & C1_SRST_HC) && cnt-- );
|
||||
if(cnt<=0) {
|
||||
uart_puts("ERROR: failed to reset EMMC\n");
|
||||
return SD_ERROR;
|
||||
}
|
||||
uart_puts("EMMC: reset OK\n");
|
||||
*EMMC_CONTROL1 |= C1_CLK_INTLEN | C1_TOUNIT_MAX;
|
||||
wait_msec(10);
|
||||
// Set clock to setup frequency.
|
||||
if((r=sd_clk(400000))) return r;
|
||||
*EMMC_INT_EN = 0xffffffff;
|
||||
*EMMC_INT_MASK = 0xffffffff;
|
||||
sd_scr[0]=sd_scr[1]=sd_rca=sd_err=0;
|
||||
sd_cmd(CMD_GO_IDLE,0);
|
||||
if(sd_err) return sd_err;
|
||||
|
||||
sd_cmd(CMD_SEND_IF_COND,0x000001AA);
|
||||
if(sd_err) return sd_err;
|
||||
cnt=6; r=0; while(!(r&ACMD41_CMD_COMPLETE) && cnt--) {
|
||||
wait_cycles(400);
|
||||
r=sd_cmd(CMD_SEND_OP_COND,ACMD41_ARG_HC);
|
||||
uart_puts("EMMC: CMD_SEND_OP_COND returned ");
|
||||
if(r&ACMD41_CMD_COMPLETE)
|
||||
uart_puts("COMPLETE ");
|
||||
if(r&ACMD41_VOLTAGE)
|
||||
uart_puts("VOLTAGE ");
|
||||
if(r&ACMD41_CMD_CCS)
|
||||
uart_puts("CCS ");
|
||||
uart_hex(r>>32);
|
||||
uart_hex(r);
|
||||
uart_send('\n');
|
||||
if(sd_err!=SD_TIMEOUT && sd_err!=SD_OK ) {
|
||||
uart_puts("ERROR: EMMC ACMD41 returned error\n");
|
||||
return sd_err;
|
||||
}
|
||||
}
|
||||
if(!(r&ACMD41_CMD_COMPLETE) || !cnt ) return SD_TIMEOUT;
|
||||
if(!(r&ACMD41_VOLTAGE)) return SD_ERROR;
|
||||
if(r&ACMD41_CMD_CCS) ccs=SCR_SUPP_CCS;
|
||||
|
||||
sd_cmd(CMD_ALL_SEND_CID,0);
|
||||
|
||||
sd_rca = sd_cmd(CMD_SEND_REL_ADDR,0);
|
||||
uart_puts("EMMC: CMD_SEND_REL_ADDR returned ");
|
||||
uart_hex(sd_rca>>32);
|
||||
uart_hex(sd_rca);
|
||||
uart_send('\n');
|
||||
if(sd_err) return sd_err;
|
||||
|
||||
if((r=sd_clk(25000000))) return r;
|
||||
|
||||
sd_cmd(CMD_CARD_SELECT,sd_rca);
|
||||
if(sd_err) return sd_err;
|
||||
|
||||
if(sd_status(SR_DAT_INHIBIT)) return SD_TIMEOUT;
|
||||
*EMMC_BLKSIZECNT = (1<<16) | 8;
|
||||
sd_cmd(CMD_SEND_SCR,0);
|
||||
if(sd_err) return sd_err;
|
||||
if(sd_int(INT_READ_RDY)) return SD_TIMEOUT;
|
||||
|
||||
r=0; cnt=100000; while(r<2 && cnt) {
|
||||
if( *EMMC_STATUS & SR_READ_AVAILABLE )
|
||||
sd_scr[r++] = *EMMC_DATA;
|
||||
else
|
||||
wait_msec(1);
|
||||
}
|
||||
if(r!=2) return SD_TIMEOUT;
|
||||
if(sd_scr[0] & SCR_SD_BUS_WIDTH_4) {
|
||||
sd_cmd(CMD_SET_BUS_WIDTH,sd_rca|2);
|
||||
if(sd_err) return sd_err;
|
||||
*EMMC_CONTROL0 |= C0_HCTL_DWITDH;
|
||||
}
|
||||
// add software flag
|
||||
uart_puts("EMMC: supports ");
|
||||
if(sd_scr[0] & SCR_SUPP_SET_BLKCNT)
|
||||
uart_puts("SET_BLKCNT ");
|
||||
if(ccs)
|
||||
uart_puts("CCS ");
|
||||
uart_send('\n');
|
||||
sd_scr[0]&=~SCR_SUPP_CCS;
|
||||
sd_scr[0]|=ccs;
|
||||
return SD_OK;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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 SD_OK 0
|
||||
#define SD_TIMEOUT -1
|
||||
#define SD_ERROR -2
|
||||
|
||||
int sd_init();
|
||||
int sd_readblock(unsigned int lba, unsigned char *buffer, unsigned int num);
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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
|
@ -1,153 +0,0 @@
|
||||
/*
|
||||
* 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|=(4<<12)|(4<<15); // alt0
|
||||
*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 character 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump memory
|
||||
*/
|
||||
void uart_dump(void *ptr)
|
||||
{
|
||||
unsigned long a,b,d;
|
||||
unsigned char c;
|
||||
for(a=(unsigned long)ptr;a<(unsigned long)ptr+512;a+=16) {
|
||||
uart_hex(a); uart_puts(": ");
|
||||
for(b=0;b<16;b++) {
|
||||
c=*((unsigned char*)(a+b));
|
||||
d=(unsigned int)c;d>>=4;d&=0xF;d+=d>9?0x37:0x30;uart_send(d);
|
||||
d=(unsigned int)c;d&=0xF;d+=d>9?0x37:0x30;uart_send(d);
|
||||
uart_send(' ');
|
||||
if(b%4==3)
|
||||
uart_send(' ');
|
||||
}
|
||||
for(b=0;b<16;b++) {
|
||||
c=*((unsigned char*)(a+b));
|
||||
uart_send(c<32||c>=127?'.':c);
|
||||
}
|
||||
uart_send('\r');
|
||||
uart_send('\n');
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
void uart_dump(void *ptr);
|
@ -1,43 +0,0 @@
|
||||
#
|
||||
# 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
|
@ -1,42 +0,0 @@
|
||||
Oktatóanyag 0C - Könyvtárak
|
||||
===========================
|
||||
|
||||
Most hogy már tudunk szektort beolvasni, ideje értelmezni a fájlrendszert. Ez az oktatóanyag megtanítja,
|
||||
hogy hogyan listázzuk ki egy FAT16 vagy FAT32 partíció gyökérkönyvtárát.
|
||||
|
||||
```sh
|
||||
$ qemu-system-aarch64 -M raspi3 -drive file=test.dd,if=sd,format=raw -serial stdio
|
||||
... kimenet törölve az átláthatóság miatt ...
|
||||
MBR disk identifier: 12345678
|
||||
FAT partition starts at: 00000008
|
||||
... kimenet törölve az átláthatóság miatt ...
|
||||
FAT type: FAT16
|
||||
FAT number of root diretory entries: 00000200
|
||||
FAT root directory LBA: 00000034
|
||||
... kimenet törölve az átláthatóság miatt ...
|
||||
Attrib Cluster Size Name
|
||||
...L.. 00000000 00000000 EFI System
|
||||
....D. 00000003 00000000 FOLDER
|
||||
.....A 00000171 0000C448 BOOTCODEBIN
|
||||
.....A 0000018A 000019B3 FIXUP DAT
|
||||
.....A 0000018E 00001B10 KERNEL8 IMG
|
||||
.....A 00000192 000005D6 LICENC~1BRO
|
||||
.....A 00000193 002B2424 START ELF
|
||||
```
|
||||
|
||||
Fat.h, fat.c
|
||||
------------
|
||||
|
||||
Ez elég egyszerű és jól dokumentált művelet. Beolvassuk az MBR-t, megkeressük a partíciónkat, majd
|
||||
betöltjük az első szektorát (Volume Boot Record). Ebben van az ún. BIOS Parameter Block, ami leírja
|
||||
a FAT fájlrendszert.
|
||||
|
||||
`fat_getpartition()` betölti és értelmezi a partíció első szektorát.
|
||||
|
||||
`fat_listdirectory()` kilistázza a fájlrendszer gyökérkönyvtárának tartalmát.
|
||||
|
||||
Main
|
||||
----
|
||||
|
||||
Miután inicializájuk az EMMC-t szektorok olvasásához, beolvassuk az első szektort a partícióról. Ha a BPB
|
||||
egy érvényes FAT fájlrendszert ír le, akkor kilistázzuk a fájlrendszer gyükérkönyvtárát.
|
@ -1,42 +0,0 @@
|
||||
Tutorial 0C - Directory
|
||||
=======================
|
||||
|
||||
Now that we can load a sector from the storage, it is time to parse it as a file system. This
|
||||
tutorial will show you how to list the root directory entries of a FAT16 or FAT32 partition.
|
||||
|
||||
```sh
|
||||
$ qemu-system-aarch64 -M raspi3 -drive file=test.dd,if=sd,format=raw -serial stdio
|
||||
... output removed for clearity ...
|
||||
MBR disk identifier: 12345678
|
||||
FAT partition starts at: 00000008
|
||||
... output removed for clearity ...
|
||||
FAT type: FAT16
|
||||
FAT number of root diretory entries: 00000200
|
||||
FAT root directory LBA: 00000034
|
||||
... output removed for clearity ...
|
||||
Attrib Cluster Size Name
|
||||
...L.. 00000000 00000000 EFI System
|
||||
....D. 00000003 00000000 FOLDER
|
||||
.....A 00000171 0000C448 BOOTCODEBIN
|
||||
.....A 0000018A 000019B3 FIXUP DAT
|
||||
.....A 0000018E 00001B10 KERNEL8 IMG
|
||||
.....A 00000192 000005D6 LICENC~1BRO
|
||||
.....A 00000193 002B2424 START ELF
|
||||
```
|
||||
|
||||
Fat.h, fat.c
|
||||
------------
|
||||
|
||||
This is easy and pretty well documented. We have to read the MBR, locate our partition, and load
|
||||
it's first sector (Volume Boot Record). That has the BIOS Parameter Block, which describes the FAT
|
||||
file system.
|
||||
|
||||
`fat_getpartition()` load and check the boot record of the first MBR partition.
|
||||
|
||||
`fat_listdirectory()` list root directory entries on the volume.
|
||||
|
||||
Main
|
||||
----
|
||||
|
||||
Once we initialize EMMC to read sectors, we load the boot record of the first partition. If the BPB
|
||||
describes a valid FAT partition, we list the root directory entries in it.
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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);
|
@ -1,172 +0,0 @@
|
||||
/*
|
||||
* 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 "sd.h"
|
||||
#include "uart.h"
|
||||
|
||||
// get the end of bss segment from linker
|
||||
extern unsigned char _end;
|
||||
unsigned int partitionlba;
|
||||
|
||||
// the BIOS Parameter Block (in Volume Boot Record)
|
||||
typedef struct {
|
||||
char jmp[3];
|
||||
char oem[8];
|
||||
unsigned short bps;
|
||||
unsigned char spc;
|
||||
unsigned short rsc;
|
||||
unsigned char nf;
|
||||
unsigned short nr;
|
||||
unsigned short ts16;
|
||||
unsigned char media;
|
||||
unsigned short spf16;
|
||||
unsigned short spt;
|
||||
unsigned short nh;
|
||||
unsigned int hs;
|
||||
unsigned int ts32;
|
||||
unsigned int spf32;
|
||||
unsigned int flg;
|
||||
unsigned int rc;
|
||||
char vol[6];
|
||||
char fst[8];
|
||||
char dmy[20];
|
||||
char fst2[8];
|
||||
} __attribute__((packed)) bpb_t;
|
||||
|
||||
// directory entry structure
|
||||
typedef struct {
|
||||
char name[8];
|
||||
char ext[3];
|
||||
char attr[9];
|
||||
unsigned short ch;
|
||||
unsigned int attr2;
|
||||
unsigned short cl;
|
||||
unsigned int size;
|
||||
} __attribute__((packed)) fatdir_t;
|
||||
|
||||
/**
|
||||
* Get the starting LBA address of the first partition
|
||||
* so that we know where our FAT file system starts, and
|
||||
* read that volume's BIOS Parameter Block
|
||||
*/
|
||||
int fat_getpartition()
|
||||
{
|
||||
unsigned char *mbr=&_end;
|
||||
bpb_t *bpb=(bpb_t*)&_end;
|
||||
// read the partitioning table
|
||||
if(sd_readblock(0,&_end,1)) {
|
||||
// check magic
|
||||
if(mbr[510]!=0x55 || mbr[511]!=0xAA) {
|
||||
uart_puts("ERROR: Bad magic in MBR\n");
|
||||
return 0;
|
||||
}
|
||||
// check partition type
|
||||
if(mbr[0x1C2]!=0xE/*FAT16 LBA*/ && mbr[0x1C2]!=0xC/*FAT32 LBA*/) {
|
||||
uart_puts("ERROR: Wrong partition type\n");
|
||||
return 0;
|
||||
}
|
||||
uart_puts("MBR disk identifier: ");
|
||||
uart_hex(*((unsigned int*)((unsigned long)&_end+0x1B8)));
|
||||
uart_puts("\nFAT partition starts at: ");
|
||||
partitionlba=*((unsigned int*)((unsigned long)&_end+0x1C6));
|
||||
uart_hex(partitionlba);
|
||||
uart_puts("\n");
|
||||
// read the boot record
|
||||
if(!sd_readblock(partitionlba,&_end,1)) {
|
||||
uart_puts("ERROR: Unable to read boot record\n");
|
||||
return 0;
|
||||
}
|
||||
// check file system type. We don't use cluster numbers for that, but magic bytes
|
||||
if( !(bpb->fst[0]=='F' && bpb->fst[1]=='A' && bpb->fst[2]=='T') &&
|
||||
!(bpb->fst2[0]=='F' && bpb->fst2[1]=='A' && bpb->fst2[2]=='T')) {
|
||||
uart_puts("ERROR: Unknown file system type\n");
|
||||
return 0;
|
||||
}
|
||||
uart_puts("FAT type: ");
|
||||
// if 16 bit sector per fat is zero, then it's a FAT32
|
||||
uart_puts(bpb->spf16>0?"FAT16":"FAT32");
|
||||
uart_puts("\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* List root directory entries in a FAT file system
|
||||
*/
|
||||
void fat_listdirectory()
|
||||
{
|
||||
bpb_t *bpb=(bpb_t*)&_end;
|
||||
fatdir_t *dir=(fatdir_t*)&_end;
|
||||
unsigned int root_sec, s;
|
||||
// find the root directory's LBA
|
||||
root_sec=((bpb->spf16?bpb->spf16:bpb->spf32)*bpb->nf)+bpb->rsc;
|
||||
//WARNING gcc generates bad code for bpb->nr, causing unaligned exception
|
||||
s=*((unsigned int*)&bpb->nf);
|
||||
s>>=8;
|
||||
s&=0xFFFF;
|
||||
uart_puts("FAT number of root diretory entries: ");
|
||||
uart_hex(s);
|
||||
s<<=5;
|
||||
// now s=bpb->nr*sizeof(fatdir_t));
|
||||
if(bpb->spf16==0) {
|
||||
// adjust for FAT32
|
||||
root_sec+=(bpb->rc-2)*bpb->spc;
|
||||
}
|
||||
// add partition LBA
|
||||
root_sec+=partitionlba;
|
||||
uart_puts("\nFAT root directory LBA: ");
|
||||
uart_hex(root_sec);
|
||||
uart_puts("\n");
|
||||
// load the root directory
|
||||
if(sd_readblock(root_sec,(unsigned char*)&_end,s/512+1)) {
|
||||
uart_puts("\nAttrib Cluster Size Name\n");
|
||||
// iterate on each entry and print out
|
||||
for(;dir->name[0]!=0;dir++) {
|
||||
// is it a valid entry?
|
||||
if(dir->name[0]==0xE5 || dir->attr[0]==0xF) continue;
|
||||
// decode attributes
|
||||
uart_send(dir->attr[0]& 1?'R':'.'); // read-only
|
||||
uart_send(dir->attr[0]& 2?'H':'.'); // hidden
|
||||
uart_send(dir->attr[0]& 4?'S':'.'); // system
|
||||
uart_send(dir->attr[0]& 8?'L':'.'); // volume label
|
||||
uart_send(dir->attr[0]&16?'D':'.'); // directory
|
||||
uart_send(dir->attr[0]&32?'A':'.'); // archive
|
||||
uart_send(' ');
|
||||
// staring cluster
|
||||
uart_hex(((unsigned int)dir->ch)<<16|dir->cl);
|
||||
uart_send(' ');
|
||||
// size
|
||||
uart_hex(dir->size);
|
||||
uart_send(' ');
|
||||
// filename
|
||||
dir->attr[0]=0;
|
||||
uart_puts(dir->name);
|
||||
uart_puts("\n");
|
||||
}
|
||||
} else {
|
||||
uart_puts("ERROR: Unable to load root directory\n");
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
int fat_getpartition();
|
||||
void fat_listdirectory();
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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.
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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;
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* 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 "sd.h"
|
||||
#include "fat.h"
|
||||
|
||||
void main()
|
||||
{
|
||||
// set up serial console
|
||||
uart_init();
|
||||
|
||||
// initialize EMMC and detect SD card type
|
||||
if(sd_init()==SD_OK) {
|
||||
// read the master boot record and find our partition
|
||||
if(fat_getpartition()) {
|
||||
// list root directory entries
|
||||
fat_listdirectory();
|
||||
} else {
|
||||
uart_puts("FAT partition not found???\n");
|
||||
}
|
||||
}
|
||||
|
||||
// echo everything back
|
||||
while(1) {
|
||||
uart_send(uart_getc());
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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);
|
@ -1,355 +0,0 @@
|
||||
/*
|
||||
* 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 "uart.h"
|
||||
#include "delays.h"
|
||||
#include "sd.h"
|
||||
|
||||
#define EMMC_ARG2 ((volatile unsigned int*)(MMIO_BASE+0x00300000))
|
||||
#define EMMC_BLKSIZECNT ((volatile unsigned int*)(MMIO_BASE+0x00300004))
|
||||
#define EMMC_ARG1 ((volatile unsigned int*)(MMIO_BASE+0x00300008))
|
||||
#define EMMC_CMDTM ((volatile unsigned int*)(MMIO_BASE+0x0030000C))
|
||||
#define EMMC_RESP0 ((volatile unsigned int*)(MMIO_BASE+0x00300010))
|
||||
#define EMMC_RESP1 ((volatile unsigned int*)(MMIO_BASE+0x00300014))
|
||||
#define EMMC_RESP2 ((volatile unsigned int*)(MMIO_BASE+0x00300018))
|
||||
#define EMMC_RESP3 ((volatile unsigned int*)(MMIO_BASE+0x0030001C))
|
||||
#define EMMC_DATA ((volatile unsigned int*)(MMIO_BASE+0x00300020))
|
||||
#define EMMC_STATUS ((volatile unsigned int*)(MMIO_BASE+0x00300024))
|
||||
#define EMMC_CONTROL0 ((volatile unsigned int*)(MMIO_BASE+0x00300028))
|
||||
#define EMMC_CONTROL1 ((volatile unsigned int*)(MMIO_BASE+0x0030002C))
|
||||
#define EMMC_INTERRUPT ((volatile unsigned int*)(MMIO_BASE+0x00300030))
|
||||
#define EMMC_INT_MASK ((volatile unsigned int*)(MMIO_BASE+0x00300034))
|
||||
#define EMMC_INT_EN ((volatile unsigned int*)(MMIO_BASE+0x00300038))
|
||||
#define EMMC_CONTROL2 ((volatile unsigned int*)(MMIO_BASE+0x0030003C))
|
||||
#define EMMC_SLOTISR_VER ((volatile unsigned int*)(MMIO_BASE+0x003000FC))
|
||||
|
||||
// command flags
|
||||
#define CMD_NEED_APP 0x80000000
|
||||
#define CMD_RSPNS_48 0x00020000
|
||||
#define CMD_ERRORS_MASK 0xfff9c004
|
||||
#define CMD_RCA_MASK 0xffff0000
|
||||
|
||||
// COMMANDs
|
||||
#define CMD_GO_IDLE 0x00000000
|
||||
#define CMD_ALL_SEND_CID 0x02010000
|
||||
#define CMD_SEND_REL_ADDR 0x03020000
|
||||
#define CMD_CARD_SELECT 0x07030000
|
||||
#define CMD_SEND_IF_COND 0x08020000
|
||||
#define CMD_STOP_TRANS 0x0C030000
|
||||
#define CMD_READ_SINGLE 0x11220010
|
||||
#define CMD_READ_MULTI 0x12220032
|
||||
#define CMD_SET_BLOCKCNT 0x17020000
|
||||
#define CMD_APP_CMD 0x37000000
|
||||
#define CMD_SET_BUS_WIDTH (0x06020000|CMD_NEED_APP)
|
||||
#define CMD_SEND_OP_COND (0x29020000|CMD_NEED_APP)
|
||||
#define CMD_SEND_SCR (0x33220010|CMD_NEED_APP)
|
||||
|
||||
// STATUS register settings
|
||||
#define SR_READ_AVAILABLE 0x00000800
|
||||
#define SR_DAT_INHIBIT 0x00000002
|
||||
#define SR_CMD_INHIBIT 0x00000001
|
||||
#define SR_APP_CMD 0x00000020
|
||||
|
||||
// INTERRUPT register settings
|
||||
#define INT_DATA_TIMEOUT 0x00100000
|
||||
#define INT_CMD_TIMEOUT 0x00010000
|
||||
#define INT_READ_RDY 0x00000020
|
||||
#define INT_CMD_DONE 0x00000001
|
||||
|
||||
#define INT_ERROR_MASK 0x017E8000
|
||||
|
||||
// CONTROL register settings
|
||||
#define C0_SPI_MODE_EN 0x00100000
|
||||
#define C0_HCTL_HS_EN 0x00000004
|
||||
#define C0_HCTL_DWITDH 0x00000002
|
||||
|
||||
#define C1_SRST_DATA 0x04000000
|
||||
#define C1_SRST_CMD 0x02000000
|
||||
#define C1_SRST_HC 0x01000000
|
||||
#define C1_TOUNIT_DIS 0x000f0000
|
||||
#define C1_TOUNIT_MAX 0x000e0000
|
||||
#define C1_CLK_GENSEL 0x00000020
|
||||
#define C1_CLK_EN 0x00000004
|
||||
#define C1_CLK_STABLE 0x00000002
|
||||
#define C1_CLK_INTLEN 0x00000001
|
||||
|
||||
// SLOTISR_VER values
|
||||
#define HOST_SPEC_NUM 0x00ff0000
|
||||
#define HOST_SPEC_NUM_SHIFT 16
|
||||
#define HOST_SPEC_V3 2
|
||||
#define HOST_SPEC_V2 1
|
||||
#define HOST_SPEC_V1 0
|
||||
|
||||
// SCR flags
|
||||
#define SCR_SD_BUS_WIDTH_4 0x00000400
|
||||
#define SCR_SUPP_SET_BLKCNT 0x02000000
|
||||
// added by my driver
|
||||
#define SCR_SUPP_CCS 0x00000001
|
||||
|
||||
#define ACMD41_VOLTAGE 0x00ff8000
|
||||
#define ACMD41_CMD_COMPLETE 0x80000000
|
||||
#define ACMD41_CMD_CCS 0x40000000
|
||||
#define ACMD41_ARG_HC 0x51ff8000
|
||||
|
||||
unsigned long sd_scr[2], sd_ocr, sd_rca, sd_err, sd_hv;
|
||||
|
||||
/**
|
||||
* Wait for data or command ready
|
||||
*/
|
||||
int sd_status(unsigned int mask)
|
||||
{
|
||||
int cnt = 500000; while((*EMMC_STATUS & mask) && !(*EMMC_INTERRUPT & INT_ERROR_MASK) && cnt--) wait_msec(1);
|
||||
return (cnt <= 0 || (*EMMC_INTERRUPT & INT_ERROR_MASK)) ? SD_ERROR : SD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for interrupt
|
||||
*/
|
||||
int sd_int(unsigned int mask)
|
||||
{
|
||||
unsigned int r, m=mask | INT_ERROR_MASK;
|
||||
int cnt = 1000000; while(!(*EMMC_INTERRUPT & m) && cnt--) wait_msec(1);
|
||||
r=*EMMC_INTERRUPT;
|
||||
if(cnt<=0 || (r & INT_CMD_TIMEOUT) || (r & INT_DATA_TIMEOUT) ) { *EMMC_INTERRUPT=r; return SD_TIMEOUT; } else
|
||||
if(r & INT_ERROR_MASK) { *EMMC_INTERRUPT=r; return SD_ERROR; }
|
||||
*EMMC_INTERRUPT=mask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a command
|
||||
*/
|
||||
int sd_cmd(unsigned int code, unsigned int arg)
|
||||
{
|
||||
int r=0;
|
||||
sd_err=SD_OK;
|
||||
if(code&CMD_NEED_APP) {
|
||||
r=sd_cmd(CMD_APP_CMD|(sd_rca?CMD_RSPNS_48:0),sd_rca);
|
||||
if(sd_rca && !r) { uart_puts("ERROR: failed to send SD APP command\n"); sd_err=SD_ERROR;return 0;}
|
||||
code &= ~CMD_NEED_APP;
|
||||
}
|
||||
if(sd_status(SR_CMD_INHIBIT)) { uart_puts("ERROR: EMMC busy\n"); sd_err= SD_TIMEOUT;return 0;}
|
||||
uart_puts("EMMC: Sending command ");uart_hex(code);uart_puts(" arg ");uart_hex(arg);uart_send('\n');
|
||||
*EMMC_INTERRUPT=*EMMC_INTERRUPT; *EMMC_ARG1=arg; *EMMC_CMDTM=code;
|
||||
if(code==CMD_SEND_OP_COND) wait_msec(1000); else
|
||||
if(code==CMD_SEND_IF_COND || code==CMD_APP_CMD) wait_msec(100);
|
||||
if((r=sd_int(INT_CMD_DONE))) {uart_puts("ERROR: failed to send EMMC command\n");sd_err=r;return 0;}
|
||||
r=*EMMC_RESP0;
|
||||
if(code==CMD_GO_IDLE || code==CMD_APP_CMD) return 0; else
|
||||
if(code==(CMD_APP_CMD|CMD_RSPNS_48)) return r&SR_APP_CMD; else
|
||||
if(code==CMD_SEND_OP_COND) return r; else
|
||||
if(code==CMD_SEND_IF_COND) return r==arg? SD_OK : SD_ERROR; else
|
||||
if(code==CMD_ALL_SEND_CID) {r|=*EMMC_RESP3; r|=*EMMC_RESP2; r|=*EMMC_RESP1; return r; } else
|
||||
if(code==CMD_SEND_REL_ADDR) {
|
||||
sd_err=(((r&0x1fff))|((r&0x2000)<<6)|((r&0x4000)<<8)|((r&0x8000)<<8))&CMD_ERRORS_MASK;
|
||||
return r&CMD_RCA_MASK;
|
||||
}
|
||||
return r&CMD_ERRORS_MASK;
|
||||
// make gcc happy
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* read a block from sd card and return the number of bytes read
|
||||
* returns 0 on error.
|
||||
*/
|
||||
int sd_readblock(unsigned int lba, unsigned char *buffer, unsigned int num)
|
||||
{
|
||||
int r,c=0,d;
|
||||
if(num<1) num=1;
|
||||
uart_puts("sd_readblock lba ");uart_hex(lba);uart_puts(" num ");uart_hex(num);uart_send('\n');
|
||||
if(sd_status(SR_DAT_INHIBIT)) {sd_err=SD_TIMEOUT; return 0;}
|
||||
unsigned int *buf=(unsigned int *)buffer;
|
||||
if(sd_scr[0] & SCR_SUPP_CCS) {
|
||||
if(num > 1 && (sd_scr[0] & SCR_SUPP_SET_BLKCNT)) {
|
||||
sd_cmd(CMD_SET_BLOCKCNT,num);
|
||||
if(sd_err) return 0;
|
||||
}
|
||||
*EMMC_BLKSIZECNT = (num << 16) | 512;
|
||||
sd_cmd(num == 1 ? CMD_READ_SINGLE : CMD_READ_MULTI,lba);
|
||||
if(sd_err) return 0;
|
||||
} else {
|
||||
*EMMC_BLKSIZECNT = (1 << 16) | 512;
|
||||
}
|
||||
while( c < num ) {
|
||||
if(!(sd_scr[0] & SCR_SUPP_CCS)) {
|
||||
sd_cmd(CMD_READ_SINGLE,(lba+c)*512);
|
||||
if(sd_err) return 0;
|
||||
}
|
||||
if((r=sd_int(INT_READ_RDY))){uart_puts("\rERROR: Timeout waiting for ready to read\n");sd_err=r;return 0;}
|
||||
for(d=0;d<128;d++) buf[d] = *EMMC_DATA;
|
||||
c++; buf+=128;
|
||||
}
|
||||
if( num > 1 && !(sd_scr[0] & SCR_SUPP_SET_BLKCNT) && (sd_scr[0] & SCR_SUPP_CCS)) sd_cmd(CMD_STOP_TRANS,0);
|
||||
return sd_err!=SD_OK || c!=num? 0 : num*512;
|
||||
}
|
||||
|
||||
/**
|
||||
* set SD clock to frequency in Hz
|
||||
*/
|
||||
int sd_clk(unsigned int f)
|
||||
{
|
||||
unsigned int d,c=41666666/f,x,s=32,h=0;
|
||||
int cnt = 100000;
|
||||
while((*EMMC_STATUS & (SR_CMD_INHIBIT|SR_DAT_INHIBIT)) && cnt--) wait_msec(1);
|
||||
if(cnt<=0) {
|
||||
uart_puts("ERROR: timeout waiting for inhibit flag\n");
|
||||
return SD_ERROR;
|
||||
}
|
||||
|
||||
*EMMC_CONTROL1 &= ~C1_CLK_EN; wait_msec(10);
|
||||
x=c-1; if(!x) s=0; else {
|
||||
if(!(x & 0xffff0000u)) { x <<= 16; s -= 16; }
|
||||
if(!(x & 0xff000000u)) { x <<= 8; s -= 8; }
|
||||
if(!(x & 0xf0000000u)) { x <<= 4; s -= 4; }
|
||||
if(!(x & 0xc0000000u)) { x <<= 2; s -= 2; }
|
||||
if(!(x & 0x80000000u)) { x <<= 1; s -= 1; }
|
||||
if(s>0) s--;
|
||||
if(s>7) s=7;
|
||||
}
|
||||
if(sd_hv>HOST_SPEC_V2) d=c; else d=(1<<s);
|
||||
if(d<=2) {d=2;s=0;}
|
||||
uart_puts("sd_clk divisor ");uart_hex(d);uart_puts(", shift ");uart_hex(s);uart_send('\n');
|
||||
if(sd_hv>HOST_SPEC_V2) h=(d&0x300)>>2;
|
||||
d=(((d&0x0ff)<<8)|h);
|
||||
*EMMC_CONTROL1=(*EMMC_CONTROL1&0xffff003f)|d; wait_msec(10);
|
||||
*EMMC_CONTROL1 |= C1_CLK_EN; wait_msec(10);
|
||||
cnt=10000; while(!(*EMMC_CONTROL1 & C1_CLK_STABLE) && cnt--) wait_msec(10);
|
||||
if(cnt<=0) {
|
||||
uart_puts("ERROR: failed to get stable clock\n");
|
||||
return SD_ERROR;
|
||||
}
|
||||
return SD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize EMMC to read SDHC card
|
||||
*/
|
||||
int sd_init()
|
||||
{
|
||||
long r,cnt,ccs=0;
|
||||
// GPIO_CD
|
||||
r=*GPFSEL4; r&=~(7<<(7*3)); *GPFSEL4=r;
|
||||
*GPPUD=2; wait_cycles(150); *GPPUDCLK1=(1<<15); wait_cycles(150); *GPPUD=0; *GPPUDCLK1=0;
|
||||
r=*GPHEN1; r|=1<<15; *GPHEN1=r;
|
||||
|
||||
// GPIO_CLK, GPIO_CMD
|
||||
r=*GPFSEL4; r|=(7<<(8*3))|(7<<(9*3)); *GPFSEL4=r;
|
||||
*GPPUD=2; wait_cycles(150); *GPPUDCLK1=(1<<16)|(1<<17); wait_cycles(150); *GPPUD=0; *GPPUDCLK1=0;
|
||||
|
||||
// GPIO_DAT0, GPIO_DAT1, GPIO_DAT2, GPIO_DAT3
|
||||
r=*GPFSEL5; r|=(7<<(0*3)) | (7<<(1*3)) | (7<<(2*3)) | (7<<(3*3)); *GPFSEL5=r;
|
||||
*GPPUD=2; wait_cycles(150);
|
||||
*GPPUDCLK1=(1<<18) | (1<<19) | (1<<20) | (1<<21);
|
||||
wait_cycles(150); *GPPUD=0; *GPPUDCLK1=0;
|
||||
|
||||
sd_hv = (*EMMC_SLOTISR_VER & HOST_SPEC_NUM) >> HOST_SPEC_NUM_SHIFT;
|
||||
uart_puts("EMMC: GPIO set up\n");
|
||||
// Reset the card.
|
||||
*EMMC_CONTROL0 = 0; *EMMC_CONTROL1 |= C1_SRST_HC;
|
||||
cnt=10000; do{wait_msec(10);} while( (*EMMC_CONTROL1 & C1_SRST_HC) && cnt-- );
|
||||
if(cnt<=0) {
|
||||
uart_puts("ERROR: failed to reset EMMC\n");
|
||||
return SD_ERROR;
|
||||
}
|
||||
uart_puts("EMMC: reset OK\n");
|
||||
*EMMC_CONTROL1 |= C1_CLK_INTLEN | C1_TOUNIT_MAX;
|
||||
wait_msec(10);
|
||||
// Set clock to setup frequency.
|
||||
if((r=sd_clk(400000))) return r;
|
||||
*EMMC_INT_EN = 0xffffffff;
|
||||
*EMMC_INT_MASK = 0xffffffff;
|
||||
sd_scr[0]=sd_scr[1]=sd_rca=sd_err=0;
|
||||
sd_cmd(CMD_GO_IDLE,0);
|
||||
if(sd_err) return sd_err;
|
||||
|
||||
sd_cmd(CMD_SEND_IF_COND,0x000001AA);
|
||||
if(sd_err) return sd_err;
|
||||
cnt=6; r=0; while(!(r&ACMD41_CMD_COMPLETE) && cnt--) {
|
||||
wait_cycles(400);
|
||||
r=sd_cmd(CMD_SEND_OP_COND,ACMD41_ARG_HC);
|
||||
uart_puts("EMMC: CMD_SEND_OP_COND returned ");
|
||||
if(r&ACMD41_CMD_COMPLETE)
|
||||
uart_puts("COMPLETE ");
|
||||
if(r&ACMD41_VOLTAGE)
|
||||
uart_puts("VOLTAGE ");
|
||||
if(r&ACMD41_CMD_CCS)
|
||||
uart_puts("CCS ");
|
||||
uart_hex(r>>32);
|
||||
uart_hex(r);
|
||||
uart_send('\n');
|
||||
if(sd_err!=SD_TIMEOUT && sd_err!=SD_OK ) {
|
||||
uart_puts("ERROR: EMMC ACMD41 returned error\n");
|
||||
return sd_err;
|
||||
}
|
||||
}
|
||||
if(!(r&ACMD41_CMD_COMPLETE) || !cnt ) return SD_TIMEOUT;
|
||||
if(!(r&ACMD41_VOLTAGE)) return SD_ERROR;
|
||||
if(r&ACMD41_CMD_CCS) ccs=SCR_SUPP_CCS;
|
||||
|
||||
sd_cmd(CMD_ALL_SEND_CID,0);
|
||||
|
||||
sd_rca = sd_cmd(CMD_SEND_REL_ADDR,0);
|
||||
uart_puts("EMMC: CMD_SEND_REL_ADDR returned ");
|
||||
uart_hex(sd_rca>>32);
|
||||
uart_hex(sd_rca);
|
||||
uart_send('\n');
|
||||
if(sd_err) return sd_err;
|
||||
|
||||
if((r=sd_clk(25000000))) return r;
|
||||
|
||||
sd_cmd(CMD_CARD_SELECT,sd_rca);
|
||||
if(sd_err) return sd_err;
|
||||
|
||||
if(sd_status(SR_DAT_INHIBIT)) return SD_TIMEOUT;
|
||||
*EMMC_BLKSIZECNT = (1<<16) | 8;
|
||||
sd_cmd(CMD_SEND_SCR,0);
|
||||
if(sd_err) return sd_err;
|
||||
if(sd_int(INT_READ_RDY)) return SD_TIMEOUT;
|
||||
|
||||
r=0; cnt=100000; while(r<2 && cnt) {
|
||||
if( *EMMC_STATUS & SR_READ_AVAILABLE )
|
||||
sd_scr[r++] = *EMMC_DATA;
|
||||
else
|
||||
wait_msec(1);
|
||||
}
|
||||
if(r!=2) return SD_TIMEOUT;
|
||||
if(sd_scr[0] & SCR_SD_BUS_WIDTH_4) {
|
||||
sd_cmd(CMD_SET_BUS_WIDTH,sd_rca|2);
|
||||
if(sd_err) return sd_err;
|
||||
*EMMC_CONTROL0 |= C0_HCTL_DWITDH;
|
||||
}
|
||||
// add software flag
|
||||
uart_puts("EMMC: supports ");
|
||||
if(sd_scr[0] & SCR_SUPP_SET_BLKCNT)
|
||||
uart_puts("SET_BLKCNT ");
|
||||
if(ccs)
|
||||
uart_puts("CCS ");
|
||||
uart_send('\n');
|
||||
sd_scr[0]&=~SCR_SUPP_CCS;
|
||||
sd_scr[0]|=ccs;
|
||||
return SD_OK;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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 SD_OK 0
|
||||
#define SD_TIMEOUT -1
|
||||
#define SD_ERROR -2
|
||||
|
||||
int sd_init();
|
||||
int sd_readblock(unsigned int lba, unsigned char *buffer, unsigned int num);
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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
|
@ -1,153 +0,0 @@
|
||||
/*
|
||||
* 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|=(4<<12)|(4<<15); // alt0
|
||||
*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 character 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump memory
|
||||
*/
|
||||
void uart_dump(void *ptr)
|
||||
{
|
||||
unsigned long a,b,d;
|
||||
unsigned char c;
|
||||
for(a=(unsigned long)ptr;a<(unsigned long)ptr+512;a+=16) {
|
||||
uart_hex(a); uart_puts(": ");
|
||||
for(b=0;b<16;b++) {
|
||||
c=*((unsigned char*)(a+b));
|
||||
d=(unsigned int)c;d>>=4;d&=0xF;d+=d>9?0x37:0x30;uart_send(d);
|
||||
d=(unsigned int)c;d&=0xF;d+=d>9?0x37:0x30;uart_send(d);
|
||||
uart_send(' ');
|
||||
if(b%4==3)
|
||||
uart_send(' ');
|
||||
}
|
||||
for(b=0;b<16;b++) {
|
||||
c=*((unsigned char*)(a+b));
|
||||
uart_send(c<32||c>=127?'.':c);
|
||||
}
|
||||
uart_send('\r');
|
||||
uart_send('\n');
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
void uart_dump(void *ptr);
|
@ -1,43 +0,0 @@
|
||||
#
|
||||
# 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
|
@ -1,45 +0,0 @@
|
||||
Oktatóanyag 0D - Fájl Beolvasása
|
||||
================================
|
||||
|
||||
Megtanultuk, hogy kell beolvasni és értelmezni a gyökérkönyvtárat. Ebben az oktatóanyagban fogunk egy fájlt
|
||||
a gyökérkönyvtárból, és a kluszterláncát végigjárva teljes egészében betöltjük a memóriába.
|
||||
|
||||
```sh
|
||||
$ qemu-system-aarch64 -M raspi3 -drive file=test.dd,if=sd,format=raw -serial stdio
|
||||
... kimenet törölve az átláthatóság miatt ...
|
||||
FAT File LICENC~1BRO starts at cluster: 00000192
|
||||
FAT Bytes per Sector: 00000200
|
||||
FAT Sectors per Cluster: 00000004
|
||||
FAT Number of FAT: 00000002
|
||||
FAT Sectors per FAT: 00000014
|
||||
FAT Reserved Sectors Count: 00000004
|
||||
FAT First data sector: 00000054
|
||||
... kimenet törölve az átláthatóság miatt ...
|
||||
00085020: 43 6F 70 79 72 69 67 68 74 20 28 63 29 20 32 30 Copyright (c) 20
|
||||
00085030: 30 36 2C 20 42 72 6F 61 64 63 6F 6D 20 43 6F 72 06, Broadcom Cor
|
||||
00085040: 70 6F 72 61 74 69 6F 6E 2E 0A 43 6F 70 79 72 69 poration..Copyri
|
||||
00085050: 67 68 74 20 28 63 29 20 32 30 31 35 2C 20 52 61 ght (c) 2015, Ra
|
||||
00085060: 73 70 62 65 72 72 79 20 50 69 20 28 54 72 61 64 spberry Pi (Trad
|
||||
00085070: 69 6E 67 29 20 4C 74 64 0A 41 6C 6C 20 72 69 67 ing) Ltd.All rig
|
||||
... kimenet törölve az átláthatóság miatt ...
|
||||
```
|
||||
|
||||
Fat.h, fat.c
|
||||
------------
|
||||
|
||||
Ez is elég egyszerű és jól dokumentált. Megkeressük a fájlukhoz tartozó könyvtárbejegyzést, és kivesszük
|
||||
belóle az induló kluszter számát. Ezután minden egyes klusztert betöltünk miközben végigjárjuk a láncot.
|
||||
|
||||
`fat_getpartition()` betölti és értelmezi a partíció első szektorát.
|
||||
|
||||
`fat_getcluster(fn)` visszaadja egy adott fájlnévhez tartozó kluszterlánc első tagját.
|
||||
|
||||
`fat_readfile(clu)` rbeolvas egy fájlt a memóriába. Visszatérési értéke egy mutató a legelső beolvasott bájtra.
|
||||
|
||||
Main
|
||||
----
|
||||
|
||||
Miután inicializájuk az EMMC-t szektorok olvasásához, beolvassuk az első szektort a partícióról. Ha a BPB
|
||||
egy érvényes FAT fájlrendszert ír le, akkor megkeressük a 'LICENCE.broadcom'-hoz tartozó első kluszter számát.
|
||||
Ha ilyent nem találunk, akkor a 'kernel8.img'-t keresünk. Ha bármelyiket megtaláltuk, akkor betöltjük és
|
||||
kidumpoljuk a fájl első 512 bájtját.
|
@ -1,44 +0,0 @@
|
||||
Tutorial 0D - Read File
|
||||
=======================
|
||||
|
||||
We learned how to read and parse the root directory. In this tutorial we'll get one file from the
|
||||
root directory, and walk through the cluster chain to load it entirely into memory.
|
||||
|
||||
```sh
|
||||
$ qemu-system-aarch64 -M raspi3 -drive file=test.dd,if=sd,format=raw -serial stdio
|
||||
... output removed for clearity ...
|
||||
FAT File LICENC~1BRO starts at cluster: 00000192
|
||||
FAT Bytes per Sector: 00000200
|
||||
FAT Sectors per Cluster: 00000004
|
||||
FAT Number of FAT: 00000002
|
||||
FAT Sectors per FAT: 00000014
|
||||
FAT Reserved Sectors Count: 00000004
|
||||
FAT First data sector: 00000054
|
||||
... output removed for clearity ...
|
||||
00085020: 43 6F 70 79 72 69 67 68 74 20 28 63 29 20 32 30 Copyright (c) 20
|
||||
00085030: 30 36 2C 20 42 72 6F 61 64 63 6F 6D 20 43 6F 72 06, Broadcom Cor
|
||||
00085040: 70 6F 72 61 74 69 6F 6E 2E 0A 43 6F 70 79 72 69 poration..Copyri
|
||||
00085050: 67 68 74 20 28 63 29 20 32 30 31 35 2C 20 52 61 ght (c) 2015, Ra
|
||||
00085060: 73 70 62 65 72 72 79 20 50 69 20 28 54 72 61 64 spberry Pi (Trad
|
||||
00085070: 69 6E 67 29 20 4C 74 64 0A 41 6C 6C 20 72 69 67 ing) Ltd.All rig
|
||||
... output removed for clearity ...
|
||||
```
|
||||
|
||||
Fat.h, fat.c
|
||||
------------
|
||||
|
||||
This is also easy and pretty well documented. We locate the directory entry for our file, and get
|
||||
the starting cluster number. Then we load each cluster into memory as we walk the cluster chain.
|
||||
|
||||
`fat_getpartition()` load and check the boot record of the first MBR partition.
|
||||
|
||||
`fat_getcluster(fn)` return the starting cluster for the given filename.
|
||||
|
||||
`fat_readfile(clu)` reads a file into memory, returns pointer to the first byte.
|
||||
|
||||
Main
|
||||
----
|
||||
|
||||
Once we initialize EMMC to read sectors, we load the boot record of the first partition. If the BPB
|
||||
describes a valid FAT partition, we find the starting cluster for the file 'LICENCE.broadcom'. If that
|
||||
not found, we'll look for 'kernel8.img'. If any of these found, we load it and dump it's first 512 bytes.
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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);
|
@ -1,208 +0,0 @@
|
||||
/*
|
||||
* 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 "sd.h"
|
||||
#include "uart.h"
|
||||
|
||||
// get the end of bss segment from linker
|
||||
extern unsigned char _end;
|
||||
unsigned int partitionlba;
|
||||
|
||||
// the BIOS Parameter Block (in Volume Boot Record)
|
||||
typedef struct {
|
||||
char jmp[3];
|
||||
char oem[8];
|
||||
unsigned short bps;
|
||||
unsigned char spc;
|
||||
unsigned short rsc;
|
||||
unsigned char nf;
|
||||
unsigned short nr;
|
||||
unsigned short ts16;
|
||||
unsigned char media;
|
||||
unsigned short spf16;
|
||||
unsigned short spt;
|
||||
unsigned short nh;
|
||||
unsigned int hs;
|
||||
unsigned int ts32;
|
||||
unsigned int spf32;
|
||||
unsigned int flg;
|
||||
unsigned int rc;
|
||||
char vol[6];
|
||||
char fst[8];
|
||||
char dmy[20];
|
||||
char fst2[8];
|
||||
} __attribute__((packed)) bpb_t;
|
||||
|
||||
// directory entry structure
|
||||
typedef struct {
|
||||
char name[8];
|
||||
char ext[3];
|
||||
char attr[9];
|
||||
unsigned short ch;
|
||||
unsigned int attr2;
|
||||
unsigned short cl;
|
||||
unsigned int size;
|
||||
} __attribute__((packed)) fatdir_t;
|
||||
|
||||
/**
|
||||
* Get the starting LBA address of the first partition
|
||||
* so that we know where our FAT file system starts, and
|
||||
* read that volume's BIOS Parameter Block
|
||||
*/
|
||||
int fat_getpartition()
|
||||
{
|
||||
unsigned char *mbr=&_end;
|
||||
bpb_t *bpb=(bpb_t*)&_end;
|
||||
// read the partitioning table
|
||||
if(sd_readblock(0,&_end,1)) {
|
||||
// check magic
|
||||
if(mbr[510]!=0x55 || mbr[511]!=0xAA) {
|
||||
uart_puts("ERROR: Bad magic in MBR\n");
|
||||
return 0;
|
||||
}
|
||||
// check partition type
|
||||
if(mbr[0x1C2]!=0xE/*FAT16 LBA*/ && mbr[0x1C2]!=0xC/*FAT32 LBA*/) {
|
||||
uart_puts("ERROR: Wrong partition type\n");
|
||||
return 0;
|
||||
}
|
||||
partitionlba=*((unsigned int*)((unsigned long)&_end+0x1C6));
|
||||
// read the boot record
|
||||
if(!sd_readblock(partitionlba,&_end,1)) {
|
||||
uart_puts("ERROR: Unable to read boot record\n");
|
||||
return 0;
|
||||
}
|
||||
// check file system type. We don't use cluster numbers for that, but magic bytes
|
||||
if( !(bpb->fst[0]=='F' && bpb->fst[1]=='A' && bpb->fst[2]=='T') &&
|
||||
!(bpb->fst2[0]=='F' && bpb->fst2[1]=='A' && bpb->fst2[2]=='T')) {
|
||||
uart_puts("ERROR: Unknown file system type\n");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a file in root directory entries
|
||||
*/
|
||||
unsigned int fat_getcluster(char *fn)
|
||||
{
|
||||
bpb_t *bpb=(bpb_t*)&_end;
|
||||
fatdir_t *dir=(fatdir_t*)(&_end+512);
|
||||
unsigned int root_sec, s;
|
||||
// find the root directory's LBA
|
||||
root_sec=((bpb->spf16?bpb->spf16:bpb->spf32)*bpb->nf)+bpb->rsc;
|
||||
//WARNING gcc generates bad code for bpb->nr, causing unaligned exception
|
||||
s=*((unsigned int*)&bpb->nf);
|
||||
s>>=8;
|
||||
s&=0xFFFF;
|
||||
s<<=5;
|
||||
// now s=bpb->nr*sizeof(fatdir_t));
|
||||
if(bpb->spf16==0) {
|
||||
// adjust for FAT32
|
||||
root_sec+=(bpb->rc-2)*bpb->spc;
|
||||
}
|
||||
// add partition LBA
|
||||
root_sec+=partitionlba;
|
||||
// load the root directory
|
||||
if(sd_readblock(root_sec,(unsigned char*)dir,s/512+1)) {
|
||||
// iterate on each entry and check if it's the one we're looking for
|
||||
for(;dir->name[0]!=0;dir++) {
|
||||
// is it a valid entry?
|
||||
if(dir->name[0]==0xE5 || dir->attr[0]==0xF) continue;
|
||||
// filename match?
|
||||
if(!__builtin_memcmp(dir->name,fn,11)) {
|
||||
uart_puts("FAT File ");
|
||||
uart_puts(fn);
|
||||
uart_puts(" starts at cluster: ");
|
||||
uart_hex(((unsigned int)dir->ch)<<16|dir->cl);
|
||||
uart_puts("\n");
|
||||
// if so, return starting cluster
|
||||
return ((unsigned int)dir->ch)<<16|dir->cl;
|
||||
}
|
||||
}
|
||||
uart_puts("ERROR: file not found\n");
|
||||
} else {
|
||||
uart_puts("ERROR: Unable to load root directory\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a file into memory
|
||||
*/
|
||||
char *fat_readfile(unsigned int cluster)
|
||||
{
|
||||
// BIOS Parameter Block
|
||||
bpb_t *bpb=(bpb_t*)&_end;
|
||||
// File allocation tables. We choose between FAT16 and FAT32 dynamically
|
||||
unsigned int *fat32=(unsigned int*)(&_end+bpb->rsc*512);
|
||||
unsigned short *fat16=(unsigned short*)fat32;
|
||||
// Data pointers
|
||||
unsigned int data_sec, s;
|
||||
unsigned char *data, *ptr;
|
||||
// find the LBA of the first data sector
|
||||
data_sec=((bpb->spf16?bpb->spf16:bpb->spf32)*bpb->nf)+bpb->rsc;
|
||||
//WARNING gcc generates bad code for bpb->nr, causing unaligned exception
|
||||
s=*((unsigned int*)&bpb->nf);
|
||||
s>>=8;
|
||||
s&=0xFFFF;
|
||||
s<<=5;
|
||||
if(bpb->spf16>0) {
|
||||
// adjust for FAT16
|
||||
data_sec+=(s+511)>>9;
|
||||
}
|
||||
// add partition LBA
|
||||
data_sec+=partitionlba;
|
||||
// dump important properties
|
||||
uart_puts("FAT Bytes per Sector: ");
|
||||
uart_hex(bpb->bps);
|
||||
uart_puts("\nFAT Sectors per Cluster: ");
|
||||
uart_hex(bpb->spc);
|
||||
uart_puts("\nFAT Number of FAT: ");
|
||||
uart_hex(bpb->nf);
|
||||
uart_puts("\nFAT Sectors per FAT: ");
|
||||
uart_hex((bpb->spf16?bpb->spf16:bpb->spf32));
|
||||
uart_puts("\nFAT Reserved Sectors Count: ");
|
||||
uart_hex(bpb->rsc);
|
||||
uart_puts("\nFAT First data sector: ");
|
||||
uart_hex(data_sec);
|
||||
uart_puts("\n");
|
||||
// load FAT table
|
||||
s=sd_readblock(partitionlba+1,(unsigned char*)&_end+512,(bpb->spf16?bpb->spf16:bpb->spf32)+bpb->rsc);
|
||||
// end of FAT in memory
|
||||
data=ptr=&_end+512+s;
|
||||
// iterate on cluster chain
|
||||
while(cluster>1 && cluster<0xFFF8) {
|
||||
// load all sectors in a cluster
|
||||
sd_readblock((cluster-2)*bpb->spc+data_sec,ptr,bpb->spc);
|
||||
// move pointer, sector per cluster * bytes per sector
|
||||
ptr+=bpb->spc*bpb->bps;
|
||||
// get the next cluster in chain
|
||||
cluster=bpb->spf16>0?fat16[cluster]:fat32[cluster];
|
||||
}
|
||||
return (char*)data;
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
int fat_getpartition();
|
||||
unsigned int fat_getcluster(char *fn);
|
||||
char *fat_readfile(unsigned int cluster);
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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.
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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;
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* 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 "sd.h"
|
||||
#include "fat.h"
|
||||
|
||||
void main()
|
||||
{
|
||||
unsigned int cluster;
|
||||
// set up serial console
|
||||
uart_init();
|
||||
|
||||
// initialize EMMC and detect SD card type
|
||||
if(sd_init()==SD_OK) {
|
||||
// read the master boot record and find our partition
|
||||
if(fat_getpartition()) {
|
||||
// find out file in root directory entries
|
||||
cluster=fat_getcluster("LICENC~1BRO");
|
||||
if(cluster==0)
|
||||
cluster=fat_getcluster("KERNEL8 IMG");
|
||||
if(cluster) {
|
||||
// read into memory
|
||||
uart_dump(fat_readfile(cluster));
|
||||
}
|
||||
} else {
|
||||
uart_puts("FAT partition not found???\n");
|
||||
}
|
||||
}
|
||||
|
||||
// echo everything back
|
||||
while(1) {
|
||||
uart_send(uart_getc());
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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);
|
@ -1,355 +0,0 @@
|
||||
/*
|
||||
* 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 "uart.h"
|
||||
#include "delays.h"
|
||||
#include "sd.h"
|
||||
|
||||
#define EMMC_ARG2 ((volatile unsigned int*)(MMIO_BASE+0x00300000))
|
||||
#define EMMC_BLKSIZECNT ((volatile unsigned int*)(MMIO_BASE+0x00300004))
|
||||
#define EMMC_ARG1 ((volatile unsigned int*)(MMIO_BASE+0x00300008))
|
||||
#define EMMC_CMDTM ((volatile unsigned int*)(MMIO_BASE+0x0030000C))
|
||||
#define EMMC_RESP0 ((volatile unsigned int*)(MMIO_BASE+0x00300010))
|
||||
#define EMMC_RESP1 ((volatile unsigned int*)(MMIO_BASE+0x00300014))
|
||||
#define EMMC_RESP2 ((volatile unsigned int*)(MMIO_BASE+0x00300018))
|
||||
#define EMMC_RESP3 ((volatile unsigned int*)(MMIO_BASE+0x0030001C))
|
||||
#define EMMC_DATA ((volatile unsigned int*)(MMIO_BASE+0x00300020))
|
||||
#define EMMC_STATUS ((volatile unsigned int*)(MMIO_BASE+0x00300024))
|
||||
#define EMMC_CONTROL0 ((volatile unsigned int*)(MMIO_BASE+0x00300028))
|
||||
#define EMMC_CONTROL1 ((volatile unsigned int*)(MMIO_BASE+0x0030002C))
|
||||
#define EMMC_INTERRUPT ((volatile unsigned int*)(MMIO_BASE+0x00300030))
|
||||
#define EMMC_INT_MASK ((volatile unsigned int*)(MMIO_BASE+0x00300034))
|
||||
#define EMMC_INT_EN ((volatile unsigned int*)(MMIO_BASE+0x00300038))
|
||||
#define EMMC_CONTROL2 ((volatile unsigned int*)(MMIO_BASE+0x0030003C))
|
||||
#define EMMC_SLOTISR_VER ((volatile unsigned int*)(MMIO_BASE+0x003000FC))
|
||||
|
||||
// command flags
|
||||
#define CMD_NEED_APP 0x80000000
|
||||
#define CMD_RSPNS_48 0x00020000
|
||||
#define CMD_ERRORS_MASK 0xfff9c004
|
||||
#define CMD_RCA_MASK 0xffff0000
|
||||
|
||||
// COMMANDs
|
||||
#define CMD_GO_IDLE 0x00000000
|
||||
#define CMD_ALL_SEND_CID 0x02010000
|
||||
#define CMD_SEND_REL_ADDR 0x03020000
|
||||
#define CMD_CARD_SELECT 0x07030000
|
||||
#define CMD_SEND_IF_COND 0x08020000
|
||||
#define CMD_STOP_TRANS 0x0C030000
|
||||
#define CMD_READ_SINGLE 0x11220010
|
||||
#define CMD_READ_MULTI 0x12220032
|
||||
#define CMD_SET_BLOCKCNT 0x17020000
|
||||
#define CMD_APP_CMD 0x37000000
|
||||
#define CMD_SET_BUS_WIDTH (0x06020000|CMD_NEED_APP)
|
||||
#define CMD_SEND_OP_COND (0x29020000|CMD_NEED_APP)
|
||||
#define CMD_SEND_SCR (0x33220010|CMD_NEED_APP)
|
||||
|
||||
// STATUS register settings
|
||||
#define SR_READ_AVAILABLE 0x00000800
|
||||
#define SR_DAT_INHIBIT 0x00000002
|
||||
#define SR_CMD_INHIBIT 0x00000001
|
||||
#define SR_APP_CMD 0x00000020
|
||||
|
||||
// INTERRUPT register settings
|
||||
#define INT_DATA_TIMEOUT 0x00100000
|
||||
#define INT_CMD_TIMEOUT 0x00010000
|
||||
#define INT_READ_RDY 0x00000020
|
||||
#define INT_CMD_DONE 0x00000001
|
||||
|
||||
#define INT_ERROR_MASK 0x017E8000
|
||||
|
||||
// CONTROL register settings
|
||||
#define C0_SPI_MODE_EN 0x00100000
|
||||
#define C0_HCTL_HS_EN 0x00000004
|
||||
#define C0_HCTL_DWITDH 0x00000002
|
||||
|
||||
#define C1_SRST_DATA 0x04000000
|
||||
#define C1_SRST_CMD 0x02000000
|
||||
#define C1_SRST_HC 0x01000000
|
||||
#define C1_TOUNIT_DIS 0x000f0000
|
||||
#define C1_TOUNIT_MAX 0x000e0000
|
||||
#define C1_CLK_GENSEL 0x00000020
|
||||
#define C1_CLK_EN 0x00000004
|
||||
#define C1_CLK_STABLE 0x00000002
|
||||
#define C1_CLK_INTLEN 0x00000001
|
||||
|
||||
// SLOTISR_VER values
|
||||
#define HOST_SPEC_NUM 0x00ff0000
|
||||
#define HOST_SPEC_NUM_SHIFT 16
|
||||
#define HOST_SPEC_V3 2
|
||||
#define HOST_SPEC_V2 1
|
||||
#define HOST_SPEC_V1 0
|
||||
|
||||
// SCR flags
|
||||
#define SCR_SD_BUS_WIDTH_4 0x00000400
|
||||
#define SCR_SUPP_SET_BLKCNT 0x02000000
|
||||
// added by my driver
|
||||
#define SCR_SUPP_CCS 0x00000001
|
||||
|
||||
#define ACMD41_VOLTAGE 0x00ff8000
|
||||
#define ACMD41_CMD_COMPLETE 0x80000000
|
||||
#define ACMD41_CMD_CCS 0x40000000
|
||||
#define ACMD41_ARG_HC 0x51ff8000
|
||||
|
||||
unsigned long sd_scr[2], sd_ocr, sd_rca, sd_err, sd_hv;
|
||||
|
||||
/**
|
||||
* Wait for data or command ready
|
||||
*/
|
||||
int sd_status(unsigned int mask)
|
||||
{
|
||||
int cnt = 500000; while((*EMMC_STATUS & mask) && !(*EMMC_INTERRUPT & INT_ERROR_MASK) && cnt--) wait_msec(1);
|
||||
return (cnt <= 0 || (*EMMC_INTERRUPT & INT_ERROR_MASK)) ? SD_ERROR : SD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for interrupt
|
||||
*/
|
||||
int sd_int(unsigned int mask)
|
||||
{
|
||||
unsigned int r, m=mask | INT_ERROR_MASK;
|
||||
int cnt = 1000000; while(!(*EMMC_INTERRUPT & m) && cnt--) wait_msec(1);
|
||||
r=*EMMC_INTERRUPT;
|
||||
if(cnt<=0 || (r & INT_CMD_TIMEOUT) || (r & INT_DATA_TIMEOUT) ) { *EMMC_INTERRUPT=r; return SD_TIMEOUT; } else
|
||||
if(r & INT_ERROR_MASK) { *EMMC_INTERRUPT=r; return SD_ERROR; }
|
||||
*EMMC_INTERRUPT=mask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a command
|
||||
*/
|
||||
int sd_cmd(unsigned int code, unsigned int arg)
|
||||
{
|
||||
int r=0;
|
||||
sd_err=SD_OK;
|
||||
if(code&CMD_NEED_APP) {
|
||||
r=sd_cmd(CMD_APP_CMD|(sd_rca?CMD_RSPNS_48:0),sd_rca);
|
||||
if(sd_rca && !r) { uart_puts("ERROR: failed to send SD APP command\n"); sd_err=SD_ERROR;return 0;}
|
||||
code &= ~CMD_NEED_APP;
|
||||
}
|
||||
if(sd_status(SR_CMD_INHIBIT)) { uart_puts("ERROR: EMMC busy\n"); sd_err= SD_TIMEOUT;return 0;}
|
||||
uart_puts("EMMC: Sending command ");uart_hex(code);uart_puts(" arg ");uart_hex(arg);uart_send('\n');
|
||||
*EMMC_INTERRUPT=*EMMC_INTERRUPT; *EMMC_ARG1=arg; *EMMC_CMDTM=code;
|
||||
if(code==CMD_SEND_OP_COND) wait_msec(1000); else
|
||||
if(code==CMD_SEND_IF_COND || code==CMD_APP_CMD) wait_msec(100);
|
||||
if((r=sd_int(INT_CMD_DONE))) {uart_puts("ERROR: failed to send EMMC command\n");sd_err=r;return 0;}
|
||||
r=*EMMC_RESP0;
|
||||
if(code==CMD_GO_IDLE || code==CMD_APP_CMD) return 0; else
|
||||
if(code==(CMD_APP_CMD|CMD_RSPNS_48)) return r&SR_APP_CMD; else
|
||||
if(code==CMD_SEND_OP_COND) return r; else
|
||||
if(code==CMD_SEND_IF_COND) return r==arg? SD_OK : SD_ERROR; else
|
||||
if(code==CMD_ALL_SEND_CID) {r|=*EMMC_RESP3; r|=*EMMC_RESP2; r|=*EMMC_RESP1; return r; } else
|
||||
if(code==CMD_SEND_REL_ADDR) {
|
||||
sd_err=(((r&0x1fff))|((r&0x2000)<<6)|((r&0x4000)<<8)|((r&0x8000)<<8))&CMD_ERRORS_MASK;
|
||||
return r&CMD_RCA_MASK;
|
||||
}
|
||||
return r&CMD_ERRORS_MASK;
|
||||
// make gcc happy
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* read a block from sd card and return the number of bytes read
|
||||
* returns 0 on error.
|
||||
*/
|
||||
int sd_readblock(unsigned int lba, unsigned char *buffer, unsigned int num)
|
||||
{
|
||||
int r,c=0,d;
|
||||
if(num<1) num=1;
|
||||
uart_puts("sd_readblock lba ");uart_hex(lba);uart_puts(" num ");uart_hex(num);uart_send('\n');
|
||||
if(sd_status(SR_DAT_INHIBIT)) {sd_err=SD_TIMEOUT; return 0;}
|
||||
unsigned int *buf=(unsigned int *)buffer;
|
||||
if(sd_scr[0] & SCR_SUPP_CCS) {
|
||||
if(num > 1 && (sd_scr[0] & SCR_SUPP_SET_BLKCNT)) {
|
||||
sd_cmd(CMD_SET_BLOCKCNT,num);
|
||||
if(sd_err) return 0;
|
||||
}
|
||||
*EMMC_BLKSIZECNT = (num << 16) | 512;
|
||||
sd_cmd(num == 1 ? CMD_READ_SINGLE : CMD_READ_MULTI,lba);
|
||||
if(sd_err) return 0;
|
||||
} else {
|
||||
*EMMC_BLKSIZECNT = (1 << 16) | 512;
|
||||
}
|
||||
while( c < num ) {
|
||||
if(!(sd_scr[0] & SCR_SUPP_CCS)) {
|
||||
sd_cmd(CMD_READ_SINGLE,(lba+c)*512);
|
||||
if(sd_err) return 0;
|
||||
}
|
||||
if((r=sd_int(INT_READ_RDY))){uart_puts("\rERROR: Timeout waiting for ready to read\n");sd_err=r;return 0;}
|
||||
for(d=0;d<128;d++) buf[d] = *EMMC_DATA;
|
||||
c++; buf+=128;
|
||||
}
|
||||
if( num > 1 && !(sd_scr[0] & SCR_SUPP_SET_BLKCNT) && (sd_scr[0] & SCR_SUPP_CCS)) sd_cmd(CMD_STOP_TRANS,0);
|
||||
return sd_err!=SD_OK || c!=num? 0 : num*512;
|
||||
}
|
||||
|
||||
/**
|
||||
* set SD clock to frequency in Hz
|
||||
*/
|
||||
int sd_clk(unsigned int f)
|
||||
{
|
||||
unsigned int d,c=41666666/f,x,s=32,h=0;
|
||||
int cnt = 100000;
|
||||
while((*EMMC_STATUS & (SR_CMD_INHIBIT|SR_DAT_INHIBIT)) && cnt--) wait_msec(1);
|
||||
if(cnt<=0) {
|
||||
uart_puts("ERROR: timeout waiting for inhibit flag\n");
|
||||
return SD_ERROR;
|
||||
}
|
||||
|
||||
*EMMC_CONTROL1 &= ~C1_CLK_EN; wait_msec(10);
|
||||
x=c-1; if(!x) s=0; else {
|
||||
if(!(x & 0xffff0000u)) { x <<= 16; s -= 16; }
|
||||
if(!(x & 0xff000000u)) { x <<= 8; s -= 8; }
|
||||
if(!(x & 0xf0000000u)) { x <<= 4; s -= 4; }
|
||||
if(!(x & 0xc0000000u)) { x <<= 2; s -= 2; }
|
||||
if(!(x & 0x80000000u)) { x <<= 1; s -= 1; }
|
||||
if(s>0) s--;
|
||||
if(s>7) s=7;
|
||||
}
|
||||
if(sd_hv>HOST_SPEC_V2) d=c; else d=(1<<s);
|
||||
if(d<=2) {d=2;s=0;}
|
||||
uart_puts("sd_clk divisor ");uart_hex(d);uart_puts(", shift ");uart_hex(s);uart_send('\n');
|
||||
if(sd_hv>HOST_SPEC_V2) h=(d&0x300)>>2;
|
||||
d=(((d&0x0ff)<<8)|h);
|
||||
*EMMC_CONTROL1=(*EMMC_CONTROL1&0xffff003f)|d; wait_msec(10);
|
||||
*EMMC_CONTROL1 |= C1_CLK_EN; wait_msec(10);
|
||||
cnt=10000; while(!(*EMMC_CONTROL1 & C1_CLK_STABLE) && cnt--) wait_msec(10);
|
||||
if(cnt<=0) {
|
||||
uart_puts("ERROR: failed to get stable clock\n");
|
||||
return SD_ERROR;
|
||||
}
|
||||
return SD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize EMMC to read SDHC card
|
||||
*/
|
||||
int sd_init()
|
||||
{
|
||||
long r,cnt,ccs=0;
|
||||
// GPIO_CD
|
||||
r=*GPFSEL4; r&=~(7<<(7*3)); *GPFSEL4=r;
|
||||
*GPPUD=2; wait_cycles(150); *GPPUDCLK1=(1<<15); wait_cycles(150); *GPPUD=0; *GPPUDCLK1=0;
|
||||
r=*GPHEN1; r|=1<<15; *GPHEN1=r;
|
||||
|
||||
// GPIO_CLK, GPIO_CMD
|
||||
r=*GPFSEL4; r|=(7<<(8*3))|(7<<(9*3)); *GPFSEL4=r;
|
||||
*GPPUD=2; wait_cycles(150); *GPPUDCLK1=(1<<16)|(1<<17); wait_cycles(150); *GPPUD=0; *GPPUDCLK1=0;
|
||||
|
||||
// GPIO_DAT0, GPIO_DAT1, GPIO_DAT2, GPIO_DAT3
|
||||
r=*GPFSEL5; r|=(7<<(0*3)) | (7<<(1*3)) | (7<<(2*3)) | (7<<(3*3)); *GPFSEL5=r;
|
||||
*GPPUD=2; wait_cycles(150);
|
||||
*GPPUDCLK1=(1<<18) | (1<<19) | (1<<20) | (1<<21);
|
||||
wait_cycles(150); *GPPUD=0; *GPPUDCLK1=0;
|
||||
|
||||
sd_hv = (*EMMC_SLOTISR_VER & HOST_SPEC_NUM) >> HOST_SPEC_NUM_SHIFT;
|
||||
uart_puts("EMMC: GPIO set up\n");
|
||||
// Reset the card.
|
||||
*EMMC_CONTROL0 = 0; *EMMC_CONTROL1 |= C1_SRST_HC;
|
||||
cnt=10000; do{wait_msec(10);} while( (*EMMC_CONTROL1 & C1_SRST_HC) && cnt-- );
|
||||
if(cnt<=0) {
|
||||
uart_puts("ERROR: failed to reset EMMC\n");
|
||||
return SD_ERROR;
|
||||
}
|
||||
uart_puts("EMMC: reset OK\n");
|
||||
*EMMC_CONTROL1 |= C1_CLK_INTLEN | C1_TOUNIT_MAX;
|
||||
wait_msec(10);
|
||||
// Set clock to setup frequency.
|
||||
if((r=sd_clk(400000))) return r;
|
||||
*EMMC_INT_EN = 0xffffffff;
|
||||
*EMMC_INT_MASK = 0xffffffff;
|
||||
sd_scr[0]=sd_scr[1]=sd_rca=sd_err=0;
|
||||
sd_cmd(CMD_GO_IDLE,0);
|
||||
if(sd_err) return sd_err;
|
||||
|
||||
sd_cmd(CMD_SEND_IF_COND,0x000001AA);
|
||||
if(sd_err) return sd_err;
|
||||
cnt=6; r=0; while(!(r&ACMD41_CMD_COMPLETE) && cnt--) {
|
||||
wait_cycles(400);
|
||||
r=sd_cmd(CMD_SEND_OP_COND,ACMD41_ARG_HC);
|
||||
uart_puts("EMMC: CMD_SEND_OP_COND returned ");
|
||||
if(r&ACMD41_CMD_COMPLETE)
|
||||
uart_puts("COMPLETE ");
|
||||
if(r&ACMD41_VOLTAGE)
|
||||
uart_puts("VOLTAGE ");
|
||||
if(r&ACMD41_CMD_CCS)
|
||||
uart_puts("CCS ");
|
||||
uart_hex(r>>32);
|
||||
uart_hex(r);
|
||||
uart_send('\n');
|
||||
if(sd_err!=SD_TIMEOUT && sd_err!=SD_OK ) {
|
||||
uart_puts("ERROR: EMMC ACMD41 returned error\n");
|
||||
return sd_err;
|
||||
}
|
||||
}
|
||||
if(!(r&ACMD41_CMD_COMPLETE) || !cnt ) return SD_TIMEOUT;
|
||||
if(!(r&ACMD41_VOLTAGE)) return SD_ERROR;
|
||||
if(r&ACMD41_CMD_CCS) ccs=SCR_SUPP_CCS;
|
||||
|
||||
sd_cmd(CMD_ALL_SEND_CID,0);
|
||||
|
||||
sd_rca = sd_cmd(CMD_SEND_REL_ADDR,0);
|
||||
uart_puts("EMMC: CMD_SEND_REL_ADDR returned ");
|
||||
uart_hex(sd_rca>>32);
|
||||
uart_hex(sd_rca);
|
||||
uart_send('\n');
|
||||
if(sd_err) return sd_err;
|
||||
|
||||
if((r=sd_clk(25000000))) return r;
|
||||
|
||||
sd_cmd(CMD_CARD_SELECT,sd_rca);
|
||||
if(sd_err) return sd_err;
|
||||
|
||||
if(sd_status(SR_DAT_INHIBIT)) return SD_TIMEOUT;
|
||||
*EMMC_BLKSIZECNT = (1<<16) | 8;
|
||||
sd_cmd(CMD_SEND_SCR,0);
|
||||
if(sd_err) return sd_err;
|
||||
if(sd_int(INT_READ_RDY)) return SD_TIMEOUT;
|
||||
|
||||
r=0; cnt=100000; while(r<2 && cnt) {
|
||||
if( *EMMC_STATUS & SR_READ_AVAILABLE )
|
||||
sd_scr[r++] = *EMMC_DATA;
|
||||
else
|
||||
wait_msec(1);
|
||||
}
|
||||
if(r!=2) return SD_TIMEOUT;
|
||||
if(sd_scr[0] & SCR_SD_BUS_WIDTH_4) {
|
||||
sd_cmd(CMD_SET_BUS_WIDTH,sd_rca|2);
|
||||
if(sd_err) return sd_err;
|
||||
*EMMC_CONTROL0 |= C0_HCTL_DWITDH;
|
||||
}
|
||||
// add software flag
|
||||
uart_puts("EMMC: supports ");
|
||||
if(sd_scr[0] & SCR_SUPP_SET_BLKCNT)
|
||||
uart_puts("SET_BLKCNT ");
|
||||
if(ccs)
|
||||
uart_puts("CCS ");
|
||||
uart_send('\n');
|
||||
sd_scr[0]&=~SCR_SUPP_CCS;
|
||||
sd_scr[0]|=ccs;
|
||||
return SD_OK;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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 SD_OK 0
|
||||
#define SD_TIMEOUT -1
|
||||
#define SD_ERROR -2
|
||||
|
||||
int sd_init();
|
||||
int sd_readblock(unsigned int lba, unsigned char *buffer, unsigned int num);
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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
|
@ -1,153 +0,0 @@
|
||||
/*
|
||||
* 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|=(4<<12)|(4<<15); // alt0
|
||||
*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 character 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump memory
|
||||
*/
|
||||
void uart_dump(void *ptr)
|
||||
{
|
||||
unsigned long a,b,d;
|
||||
unsigned char c;
|
||||
for(a=(unsigned long)ptr;a<(unsigned long)ptr+512;a+=16) {
|
||||
uart_hex(a); uart_puts(": ");
|
||||
for(b=0;b<16;b++) {
|
||||
c=*((unsigned char*)(a+b));
|
||||
d=(unsigned int)c;d>>=4;d&=0xF;d+=d>9?0x37:0x30;uart_send(d);
|
||||
d=(unsigned int)c;d&=0xF;d+=d>9?0x37:0x30;uart_send(d);
|
||||
uart_send(' ');
|
||||
if(b%4==3)
|
||||
uart_send(' ');
|
||||
}
|
||||
for(b=0;b<16;b++) {
|
||||
c=*((unsigned char*)(a+b));
|
||||
uart_send(c<32||c>=127?'.':c);
|
||||
}
|
||||
uart_send('\r');
|
||||
uart_send('\n');
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
void uart_dump(void *ptr);
|
@ -1,52 +0,0 @@
|
||||
#
|
||||
# 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 $@
|
||||
|
||||
tar:
|
||||
tar -cf ramdisk *.md *.c *.h
|
||||
|
||||
cpio:
|
||||
ls *.md *.c *.h | cpio -H hpodc -o >ramdisk
|
||||
|
||||
rd.o: ramdisk
|
||||
aarch64-elf-ld -r -b binary -o rd.o ramdisk
|
||||
|
||||
kernel8.img: start.o rd.o $(OBJS)
|
||||
aarch64-elf-ld -nostdlib -nostartfiles start.o rd.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
|
@ -1,60 +0,0 @@
|
||||
Oktatóanyag 0E - Kezdeti memória lemez
|
||||
======================================
|
||||
|
||||
Sok OS használ kezdeti memória lemezt (initrd) hogy fájlokat töltsön be induláskor. Szükségét éreztem egy
|
||||
ilyen oktatóanyagnak, mivel a legtöbb hobby OS fejlesztőnek fingja sincs, hogy kell ezt rendesen csinálni.
|
||||
|
||||
Először is, nem fogjuk újra feltalálni a spanyol viaszt és kiagyalni egy új formátumot, amihez aztán egy
|
||||
szörnyű kreátor programot heggesztünk. Helyette a POSIX szabvány `tar` archíválót és a `cpio` parancsot
|
||||
fogjuk használni. Előbbi egyértelműbb, utúbbit a Linux is használja.
|
||||
|
||||
A tar formátuma pofonegyszerű, először jön egy 512 bájtos fejléc a fájl adataival, majd ezt követi a fájl
|
||||
tartalma nullákkal kiegészítve, hogy a hossza 512-vel osztható legyen. Ez ismétlődik minden egyes fájlra az archívban.
|
||||
|
||||
A cpio nagyon hasonló, csak változó hosszúságú fejléccel operál, és nincs a fájl tartalma kiegészítve.
|
||||
|
||||
Ha szeretnél tömörített initrd-t, akkor javaslom például a [tinf](https://bitbucket.org/jibsen/tinf) könyvtárat
|
||||
a kicsomagoláshoz. A kitömörített adatot az itt ismertetett módszerrel olvashatod.
|
||||
|
||||
Másodszor, a betöltéshez több lehetőségünk is van:
|
||||
|
||||
### Betöltjük a fájlt saját magunk
|
||||
Ehhez használhatod a `fat_readfile()` funkciót az előző oktatóanyagból. Ebben az esetben az initrd címét visszaadja
|
||||
a függvény.
|
||||
|
||||
### Megkéred a GPU-t hogy töltse be neked
|
||||
Aztán használhatod a `config.txt`-t hogy utasítsd a start.elf-et az initrd betöltésére. Ez azért jó, mert ehhez
|
||||
nem kell SD kártya olvasó és FAT értelmező, így a kerneled jóval kissebb lesz. Ami a
|
||||
[config.txt](https://www.raspberrypi.org/documentation/configuration/config-txt/boot.md) parancsait illeti,
|
||||
két lehetőséged is van:
|
||||
|
||||
`ramfsfile=(fájlnév)` - ez betölti a (fájlnév) nevű fájlt mindjárt a kerneled után. Az initrd-d kezdőcíme
|
||||
ekkor a *&_end* cimke lesz, amit a linker szkriptben definiáltunk.
|
||||
|
||||
`initramfs (fájlnév) (cím)` - a megadott címre tölti be a (fájlnév) nevű fájlt. A kezdőcíme ekkor *(cím)* lesz.
|
||||
|
||||
### Statikus linkelés
|
||||
Nem túl praktikus, mivel mindig újra kell fordítani a kernelt, ha változtatni akarsz az initrd tartalmán. Azonban
|
||||
ez a legegyszerűbb módszer, és hogy átlátható legyen az oktatóanyag, ezért ezt választottam. Az initrd-d
|
||||
kezdőcímét ez esetben a *_binary_ramdisk_start* cimke szolgáltatja.
|
||||
|
||||
Makefile
|
||||
--------
|
||||
Hozzáadtam egy rd.o-t létrehozó szabályt, ami object fájllá konvertálja az archívot. Ezen kívül lett két
|
||||
új szabály:
|
||||
|
||||
`make tar` ami *tar* formátumban hozza létre az archívumot
|
||||
|
||||
`make cpio` ami pedig *cpio hpodc* formátumot használ.
|
||||
|
||||
Ezért amikor fordítani szeretnél, vagy a `make tar all`, vagy a `make cpio all` parancsot kell használnod.
|
||||
|
||||
Initrd.h, initrd.c
|
||||
------------------
|
||||
|
||||
`initrd_list(buf)` kilistázza a bufferben lévő archív tartalmát. A formátumát automatikusan detektálja.
|
||||
|
||||
Main
|
||||
----
|
||||
|
||||
Inicializáljuk a konzolt, majd átadjuk az initrd kezdőcímét a listázónak.
|
@ -1,59 +0,0 @@
|
||||
Tutorial 0E - Initial RamDisk
|
||||
=============================
|
||||
|
||||
Many OS uses initial ramdisk to load files into memory during boot. I felt the need for such
|
||||
a tutorial as most hobby OS developer's never learned how to do this properly.
|
||||
|
||||
First of all, we're not going to reinvent the wheel and come up with a new format and an awful
|
||||
image creator tool. We're going to use the POSIX standard `tar` utility and the `cpio` utility
|
||||
to create our initrd. The former is more straightforward, the latter is used by Linux.
|
||||
|
||||
Tar's format is really simple, first comes an 512 bytes long header with file meta information, followed by the
|
||||
file contents padded with zeros to round up to be multiple of 512 bytes. This repeats for every file in the archive.
|
||||
|
||||
Cpio is very similar but it has a variable length header and file content is not padded.
|
||||
|
||||
If you want a compressed initrd, you can use for example the [tinf](https://bitbucket.org/jibsen/tinf) library to
|
||||
inflate. The uncompressed buffer can be parsed by the method described here.
|
||||
|
||||
Second, about loading your ramdisk into memory, we have several options:
|
||||
|
||||
### Load a file on our own
|
||||
You can use the `fat_readfile()` from the previous tutorial. In that case your initrd's address
|
||||
will be returned by the function.
|
||||
|
||||
### Ask the GPU to do so
|
||||
You can use `config.txt` to tell start.elf to load the initrd for you. With this you won't need
|
||||
any SD card reader or FAT parser at all, resulting in a much smaller kernel. As for the
|
||||
[config.txt](https://www.raspberrypi.org/documentation/configuration/config-txt/boot.md),
|
||||
you have two options:
|
||||
|
||||
`ramfsfile=(filename)` - this will load (filename) after your kernel. You can access it at the label
|
||||
*&_end* defined by our linker script.
|
||||
|
||||
`initramfs (filename) (address)` - load (filename) into a specified location. You can access it at *(address)*.
|
||||
|
||||
### Statically link
|
||||
This is not very practical because you have to build your kernel every time you want to change the initrd. But
|
||||
it is the simplest method, and to keep this tutorial simple we'll use this method. You can access the initrd by
|
||||
the label *_binary_ramdisk_start*.
|
||||
|
||||
Makefile
|
||||
--------
|
||||
I've added an rd.o rule to convert the archive into an object file. I've also added
|
||||
|
||||
`make tar` which will create an archive in *tar* format
|
||||
|
||||
`make cpio` which will create a *cpio hpodc* archive.
|
||||
|
||||
So when you compile, you either have to use `make tar all` or `make cpio all`.
|
||||
|
||||
Initrd.h, initrd.c
|
||||
------------------
|
||||
|
||||
`initrd_list(buf)` list the contents of an archive in the buffer. Detects the format automatically.
|
||||
|
||||
Main
|
||||
----
|
||||
|
||||
We initialize console and then pass the initrd buffer to lister.
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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);
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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))
|
@ -1,136 +0,0 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
/* POSIX ustar header format */
|
||||
typedef struct { /* byte offset */
|
||||
char name[100]; /* 0 */
|
||||
char mode[8]; /* 100 */
|
||||
char uid[8]; /* 108 */
|
||||
char gid[8]; /* 116 */
|
||||
char size[12]; /* 124 */
|
||||
char mtime[12]; /* 136 */
|
||||
char chksum[8]; /* 148 */
|
||||
char typeflag; /* 156 */
|
||||
char linkname[100]; /* 157 */
|
||||
char magic[6]; /* 257 */
|
||||
char version[2]; /* 263 */
|
||||
char uname[32]; /* 265 */
|
||||
char gname[32]; /* 297 */
|
||||
char devmajor[8]; /* 329 */
|
||||
char devminor[8]; /* 337 */
|
||||
char prefix[167]; /* 345 */
|
||||
} __attribute__((packed)) tar_t;
|
||||
|
||||
/* cpio hpodc format */
|
||||
typedef struct {
|
||||
char magic[6]; /* Magic header '070707'. */
|
||||
char dev[6]; /* device number. */
|
||||
char ino[6]; /* "i-node" number. */
|
||||
char mode[6]; /* Permisions. */
|
||||
char uid[6]; /* User ID. */
|
||||
char gid[6]; /* Group ID. */
|
||||
char nlink[6]; /* Number of hard links. */
|
||||
char rdev[6]; /* device major/minor number. */
|
||||
char mtime[11]; /* Modification time. */
|
||||
char namesize[6]; /* Length of filename in bytes. */
|
||||
char filesize[11]; /* File size. */
|
||||
} __attribute__((packed)) cpio_t;
|
||||
|
||||
/**
|
||||
* Helper function to convert ASCII octal number into binary
|
||||
* s string
|
||||
* n number of digits
|
||||
*/
|
||||
int oct2bin(char *s, int n)
|
||||
{
|
||||
int r=0;
|
||||
while(n-->0) {
|
||||
r<<=3;
|
||||
r+=*s++-'0';
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* List the contents of an archive
|
||||
*/
|
||||
void initrd_list(char *buf)
|
||||
{
|
||||
char *types[]={"regular", "link ", "symlnk", "chrdev", "blkdev", "dircty", "fifo ", "??? "};
|
||||
|
||||
uart_puts("Type Offset Size Access rights\tFilename\n");
|
||||
|
||||
// iterate on archive's contents
|
||||
while(!__builtin_memcmp(buf+257,"ustar",5)) {
|
||||
// if it's an ustar archive
|
||||
tar_t *header=(tar_t*)buf;
|
||||
int fs=oct2bin(header->size,11);
|
||||
// print out meta information
|
||||
uart_puts(types[header->typeflag-'0']);
|
||||
uart_send(' ');
|
||||
uart_send(' ');
|
||||
uart_hex((unsigned int)((unsigned long)buf)+sizeof(tar_t));
|
||||
uart_send(' ');
|
||||
uart_hex(fs); // file size in hex
|
||||
uart_send(' ');
|
||||
uart_puts(header->mode); // access bits in octal
|
||||
uart_send(' ');
|
||||
uart_puts(header->uname); // owner
|
||||
uart_send('.');
|
||||
uart_puts(header->gname); // group
|
||||
uart_send('\t');
|
||||
uart_puts(buf); // filename
|
||||
if(header->typeflag=='2') {
|
||||
uart_puts(" -> "); // symlink target
|
||||
uart_puts(header->linkname);
|
||||
}
|
||||
uart_puts("\n");
|
||||
// jump to the next file
|
||||
buf+=(((fs+511)/512)+1)*512;
|
||||
}
|
||||
// if it's a cpio archive. Cpio also has a trailer entry
|
||||
while(!__builtin_memcmp(buf,"070707",6) && __builtin_memcmp(buf+sizeof(cpio_t),"TRAILER!!",9)) {
|
||||
cpio_t *header = (cpio_t*)buf;
|
||||
int ns=oct2bin(header->namesize,6);
|
||||
int fs=oct2bin(header->filesize,11);
|
||||
// print out meta information
|
||||
uart_hex(oct2bin(header->mode,6)); // mode (access rights + type)
|
||||
uart_send(' ');
|
||||
uart_hex((unsigned int)((unsigned long)buf)+sizeof(cpio_t)+ns);
|
||||
uart_send(' ');
|
||||
uart_hex(fs); // file size in hex
|
||||
uart_send(' ');
|
||||
uart_hex(oct2bin(header->uid,6)); // user id in hex
|
||||
uart_send('.');
|
||||
uart_hex(oct2bin(header->gid,6)); // group id in hex
|
||||
uart_send('\t');
|
||||
uart_puts(buf+sizeof(cpio_t)); // filename
|
||||
uart_puts("\n");
|
||||
// jump to the next file
|
||||
buf+=(sizeof(cpio_t)+ns+fs);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* 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 initrd_list(char *buf);
|
Binary file not shown.
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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;
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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 "initrd.h"
|
||||
|
||||
// import our bitchunk from rd.o
|
||||
extern volatile unsigned char _binary_ramdisk_start;
|
||||
|
||||
void main()
|
||||
{
|
||||
// set up serial console
|
||||
uart_init();
|
||||
|
||||
// list contents of an archive
|
||||
initrd_list((char*)&_binary_ramdisk_start);
|
||||
|
||||
// echo everything back
|
||||
while(1) {
|
||||
uart_send(uart_getc());
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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);
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue