Fixed typos and more tutorials
parent
22fc0181a3
commit
2fc348ba46
@ -0,0 +1,43 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person
|
||||||
|
# obtaining a copy of this software and associated documentation
|
||||||
|
# files (the "Software"), to deal in the Software without
|
||||||
|
# restriction, including without limitation the rights to use, copy,
|
||||||
|
# modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
# of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be
|
||||||
|
# included in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
SRCS = $(wildcard *.c)
|
||||||
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
start.o: start.S
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c start.S -o start.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
aarch64-elf-gcc $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: start.o $(OBJS)
|
||||||
|
aarch64-elf-ld -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf
|
||||||
|
aarch64-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm kernel8.elf *.o >/dev/null 2>/dev/null || true
|
@ -0,0 +1,46 @@
|
|||||||
|
Oktatóanyag 11 - Kivételkezelők
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Legutóbb egy nagyon egyszerű címfordítási táblát használtunk, de a mindennapi életben többre van szükség.
|
||||||
|
Nem könnyű vakon létrehozni ezt a táblát, ezért kivételkezelőket fogunk definiálni. Ez ki fogja dumpolni
|
||||||
|
a fontos rendszer regisztereket, hogy azonosíthassuk és megtalálhassuk a problémát a címfordítási táblánkban.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial stdio
|
||||||
|
Synchronous: Data abort, same EL, Translation fault at level 2:
|
||||||
|
ESR_EL1 0000000096000006 ELR_EL1 0000000000080D7C
|
||||||
|
SPSR_EL1 00000000200003C4 FAR_EL1 FFFFFFFFFF000000
|
||||||
|
```
|
||||||
|
|
||||||
|
Az ESR_EL1 elárulja, hogy Adathozzáférési probléma (Data Abort) lépett fel a táblázat második szintjén. Az
|
||||||
|
utasítás, ami okozta, a 0x80D7C címen található, és a 0xFFFFFFFFFF000000 címet szerette volna elérni.
|
||||||
|
|
||||||
|
A megadott vektor hasonló az AMD64 IDT-jéhez, két eltéréssel: először is, nincs külön utasítás (mint az sidt),
|
||||||
|
hanem egy rendszer regiszter tárolja a címét. Másodszor, nem egy címeket tartalmazó táblázat címét adjuk meg,
|
||||||
|
hanem a konkrét kód címét. Ezért minden "bejegyzés" a táblában nagyobb, kis programrészek amikkel be lehet
|
||||||
|
állítani a paramétereket és meghívni egy közös kivételkezelőt.
|
||||||
|
|
||||||
|
AMD64-en 32 belépési pont van, minden egyes kivételtípushoz egy. AArch-on ezzel szemben csak egy van, és egy
|
||||||
|
rendszer regiszterből olvasható ki, melyik kivételtípusról van szó. Figyelembe véve, hogy minden OS úgyis csak
|
||||||
|
átad egy kivételkódot egy közös kivételkezelőnek, ezzel megkönnyíti az életünket.
|
||||||
|
|
||||||
|
Exc.c
|
||||||
|
-----
|
||||||
|
|
||||||
|
`exc_handler()` egy egyszerű kivételkezelő, ami kidumpolja a regisztereket és dekódolja az ESR_EL1-t (részben).
|
||||||
|
Aztán megállítjuk a CPU-t, mert egyelőre nincs hova visszatérni a kivételkezelőből. A Kivétel Szindróma Regiszter
|
||||||
|
(Exception Syndrome Register) részletes leírása megtalálható az ARM DDI0487B_b könyv D10.2.28 fejezetében.
|
||||||
|
|
||||||
|
Start
|
||||||
|
-----
|
||||||
|
|
||||||
|
Mielőtt rendszerfelügyeleti módra váltanánk, beállítjuk a *vbar_el2*-t. Fontos, hogy az EL1 szinten fellépő
|
||||||
|
kivételeket EL2 szinten futó kód kezeli le. Minden kezelőt megfelelően kell pozicionálni a memóriában. Qemu
|
||||||
|
nem érzékeny annyira erre, de az igazi vas igen.
|
||||||
|
|
||||||
|
`_vectors` kivételkezelők vektor táblája, kis assembly programokkal, mind az `exc_handler()` nevű C függvényt hívja.
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
Beállítjuk a címfordítást, majd szándékosan egy leképezetlen címre hivatkozunk, hogy kivételt idézzünk elő.
|
@ -0,0 +1,45 @@
|
|||||||
|
Tutorial 11 - Exceptions
|
||||||
|
========================
|
||||||
|
|
||||||
|
Last time we have used a very simple translation scheme, but in real life you often need more. And it is not
|
||||||
|
easy to write the table blindly, so we're going to add exception handlers this time. This will print out some
|
||||||
|
system registers to identify the problem with our translation tables.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial stdio
|
||||||
|
Synchronous: Data abort, same EL, Translation fault at level 2:
|
||||||
|
ESR_EL1 0000000096000006 ELR_EL1 0000000000080D7C
|
||||||
|
SPSR_EL1 00000000200003C4 FAR_EL1 FFFFFFFFFF000000
|
||||||
|
```
|
||||||
|
|
||||||
|
Here ESR_EL1 tells us that it was a Data Abort, caused by a translation table error at level 2. The instruction
|
||||||
|
triggered it is at address 0x80D7C which tried to access memory at 0xFFFFFFFFFF000000.
|
||||||
|
|
||||||
|
The vector is very similar to AMD64's IDT, with two exceptions: first, there's no special instruction (like sidt),
|
||||||
|
but a system register stores the address. Second, we don't pass a table with addresses rather the address of the
|
||||||
|
actual code. Therefore each "entry" of the vector table is bigger, small stubs so that you can set up arguments
|
||||||
|
and jump to a common handler.
|
||||||
|
|
||||||
|
On AMD64 you have 32 entry points for each exception. On AArch, you only have one, and you can read the excpetion
|
||||||
|
code from a system register. Considering that all OS sets a code for the exception and jumps to a common handler,
|
||||||
|
this makes life easier.
|
||||||
|
|
||||||
|
Exc.c
|
||||||
|
-----
|
||||||
|
|
||||||
|
`exc_handler()` a simple exception handler that dumps registers and decodes ESR_EL1 (partially). We simply stop
|
||||||
|
the CPU for now, as we have no means to recover from an exception yet. The full comprehensive description of
|
||||||
|
Exception Syndrome Register can be found in ARM DDI0487B_b chapter D10.2.28.
|
||||||
|
|
||||||
|
Start
|
||||||
|
-----
|
||||||
|
|
||||||
|
Before we switch to supervisor mode, we set up *vbar_el2*. Note that exceptions triggered at EL1 will be handled
|
||||||
|
by code at EL2. All handlers must be properly aligned. Qemu is not so picky, but real hardware is.
|
||||||
|
|
||||||
|
`_vectors` the exception handler's vector table with small assembly stubs, each calling `exc_handler()` in C.
|
||||||
|
|
||||||
|
Main
|
||||||
|
----
|
||||||
|
|
||||||
|
We set up page translations, and then we deliberatly reference an unmapped address to trigger an exception.
|
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* common exception handler
|
||||||
|
*/
|
||||||
|
void exc_handler(unsigned long type, unsigned long esr, unsigned long elr, unsigned long spsr, unsigned long far)
|
||||||
|
{
|
||||||
|
// print out interruption type
|
||||||
|
switch(type) {
|
||||||
|
case 0: uart_puts("Synchronous"); break;
|
||||||
|
case 1: uart_puts("IRQ"); break;
|
||||||
|
case 2: uart_puts("FIQ"); break;
|
||||||
|
case 3: uart_puts("SError"); break;
|
||||||
|
}
|
||||||
|
uart_puts(": ");
|
||||||
|
// decode exception type (some, not all. See ARM DDI0487B_b chapter D10.2.28)
|
||||||
|
switch(esr>>26) {
|
||||||
|
case 0b000000: uart_puts("Unknown"); break;
|
||||||
|
case 0b000001: uart_puts("Trapped WFI/WFE"); break;
|
||||||
|
case 0b001110: uart_puts("Illegal execution"); break;
|
||||||
|
case 0b010101: uart_puts("System call"); break;
|
||||||
|
case 0b100000: uart_puts("Instruction abort, lower EL"); break;
|
||||||
|
case 0b100001: uart_puts("Instruction abort, same EL"); break;
|
||||||
|
case 0b100010: uart_puts("Instruction alignment fault"); break;
|
||||||
|
case 0b100100: uart_puts("Data abort, lower EL"); break;
|
||||||
|
case 0b100101: uart_puts("Data abort, same EL"); break;
|
||||||
|
case 0b100110: uart_puts("Stack alignment fault"); break;
|
||||||
|
case 0b101100: uart_puts("Floating point"); break;
|
||||||
|
default: uart_puts("Unknown"); break;
|
||||||
|
}
|
||||||
|
// decode data abort cause
|
||||||
|
if(esr>>26==0b100100 || esr>>26==0b100101) {
|
||||||
|
uart_puts(", ");
|
||||||
|
switch((esr>>2)&0x3) {
|
||||||
|
case 0: uart_puts("Address size fault"); break;
|
||||||
|
case 1: uart_puts("Translation fault"); break;
|
||||||
|
case 2: uart_puts("Access flag fault"); break;
|
||||||
|
case 3: uart_puts("Permission fault"); break;
|
||||||
|
}
|
||||||
|
switch(esr&0x3) {
|
||||||
|
case 0: uart_puts(" at level 0"); break;
|
||||||
|
case 1: uart_puts(" at level 1"); break;
|
||||||
|
case 2: uart_puts(" at level 2"); break;
|
||||||
|
case 3: uart_puts(" at level 3"); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// dump registers
|
||||||
|
uart_puts(":\n ESR_EL1 ");
|
||||||
|
uart_hex(esr>>32);
|
||||||
|
uart_hex(esr);
|
||||||
|
uart_puts(" ELR_EL1 ");
|
||||||
|
uart_hex(elr>>32);
|
||||||
|
uart_hex(elr);
|
||||||
|
uart_puts("\n SPSR_EL1 ");
|
||||||
|
uart_hex(spsr>>32);
|
||||||
|
uart_hex(spsr);
|
||||||
|
uart_puts(" FAR_EL1 ");
|
||||||
|
uart_hex(far>>32);
|
||||||
|
uart_hex(far);
|
||||||
|
uart_puts("\n");
|
||||||
|
// no return from exception for now
|
||||||
|
while(1);
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MMIO_BASE 0x3F000000
|
||||||
|
|
||||||
|
#define GPFSEL0 ((volatile unsigned int*)(MMIO_BASE+0x00200000))
|
||||||
|
#define GPFSEL1 ((volatile unsigned int*)(MMIO_BASE+0x00200004))
|
||||||
|
#define GPFSEL2 ((volatile unsigned int*)(MMIO_BASE+0x00200008))
|
||||||
|
#define GPFSEL3 ((volatile unsigned int*)(MMIO_BASE+0x0020000C))
|
||||||
|
#define GPFSEL4 ((volatile unsigned int*)(MMIO_BASE+0x00200010))
|
||||||
|
#define GPFSEL5 ((volatile unsigned int*)(MMIO_BASE+0x00200014))
|
||||||
|
#define GPSET0 ((volatile unsigned int*)(MMIO_BASE+0x0020001C))
|
||||||
|
#define GPSET1 ((volatile unsigned int*)(MMIO_BASE+0x00200020))
|
||||||
|
#define GPCLR0 ((volatile unsigned int*)(MMIO_BASE+0x00200028))
|
||||||
|
#define GPLEV0 ((volatile unsigned int*)(MMIO_BASE+0x00200034))
|
||||||
|
#define GPLEV1 ((volatile unsigned int*)(MMIO_BASE+0x00200038))
|
||||||
|
#define GPEDS0 ((volatile unsigned int*)(MMIO_BASE+0x00200040))
|
||||||
|
#define GPEDS1 ((volatile unsigned int*)(MMIO_BASE+0x00200044))
|
||||||
|
#define GPHEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200064))
|
||||||
|
#define GPHEN1 ((volatile unsigned int*)(MMIO_BASE+0x00200068))
|
||||||
|
#define GPPUD ((volatile unsigned int*)(MMIO_BASE+0x00200094))
|
||||||
|
#define GPPUDCLK0 ((volatile unsigned int*)(MMIO_BASE+0x00200098))
|
||||||
|
#define GPPUDCLK1 ((volatile unsigned int*)(MMIO_BASE+0x0020009C))
|
Binary file not shown.
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x80000;
|
||||||
|
.text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) }
|
||||||
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) }
|
||||||
|
. = ALIGN(4096);
|
||||||
|
PROVIDE(_data = .);
|
||||||
|
.data : { *(.data .data.* .gnu.linkonce.d*) }
|
||||||
|
.bss (NOLOAD) : {
|
||||||
|
. = ALIGN(16);
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
__bss_end = .;
|
||||||
|
}
|
||||||
|
. = ALIGN(4096);
|
||||||
|
_end = .;
|
||||||
|
|
||||||
|
/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
|
||||||
|
}
|
||||||
|
__bss_size = (__bss_end - __bss_start)>>3;
|
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* 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 "mmu.h"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
unsigned int r;
|
||||||
|
|
||||||
|
// set up serial console
|
||||||
|
uart_init();
|
||||||
|
|
||||||
|
// set up paging
|
||||||
|
mmu_init();
|
||||||
|
|
||||||
|
// generate a Data Abort with a bad address access
|
||||||
|
r=*((volatile unsigned int*)0xFFFFFFFFFF000000);
|
||||||
|
// make gcc happy about unused variables :-)
|
||||||
|
r++;
|
||||||
|
|
||||||
|
// echo everything back
|
||||||
|
while(1) {
|
||||||
|
uart_send(uart_getc());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
/* mailbox message buffer */
|
||||||
|
volatile unsigned int __attribute__((aligned(16))) mbox[36];
|
||||||
|
|
||||||
|
#define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880)
|
||||||
|
#define MBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0))
|
||||||
|
#define MBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10))
|
||||||
|
#define MBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14))
|
||||||
|
#define MBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18))
|
||||||
|
#define MBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C))
|
||||||
|
#define MBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20))
|
||||||
|
#define MBOX_RESPONSE 0x80000000
|
||||||
|
#define MBOX_FULL 0x80000000
|
||||||
|
#define MBOX_EMPTY 0x40000000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a mailbox call. Returns 0 on failure, non-zero on success
|
||||||
|
*/
|
||||||
|
int mbox_call(unsigned char ch)
|
||||||
|
{
|
||||||
|
unsigned int r;
|
||||||
|
/* wait until we can write to the mailbox */
|
||||||
|
do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_FULL);
|
||||||
|
/* write the address of our message to the mailbox with channel identifier */
|
||||||
|
*MBOX_WRITE = (((unsigned int)((unsigned long)&mbox)&~0xF) | (ch&0xF));
|
||||||
|
/* now wait for the response */
|
||||||
|
while(1) {
|
||||||
|
/* is there a response? */
|
||||||
|
do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_EMPTY);
|
||||||
|
r=*MBOX_READ;
|
||||||
|
/* is it a response to our message? */
|
||||||
|
if((unsigned char)(r&0xF)==ch && (r&~0xF)==(unsigned int)((unsigned long)&mbox))
|
||||||
|
/* is it a valid successful response? */
|
||||||
|
return mbox[1]==MBOX_RESPONSE;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* a properly aligned buffer */
|
||||||
|
extern volatile unsigned int mbox[36];
|
||||||
|
|
||||||
|
#define MBOX_REQUEST 0
|
||||||
|
|
||||||
|
/* channels */
|
||||||
|
#define MBOX_CH_POWER 0
|
||||||
|
#define MBOX_CH_FB 1
|
||||||
|
#define MBOX_CH_VUART 2
|
||||||
|
#define MBOX_CH_VCHIQ 3
|
||||||
|
#define MBOX_CH_LEDS 4
|
||||||
|
#define MBOX_CH_BTNS 5
|
||||||
|
#define MBOX_CH_TOUCH 6
|
||||||
|
#define MBOX_CH_COUNT 7
|
||||||
|
#define MBOX_CH_PROP 8
|
||||||
|
|
||||||
|
/* tags */
|
||||||
|
#define MBOX_TAG_GETSERIAL 0x10004
|
||||||
|
#define MBOX_TAG_SETCLKRATE 0x38002
|
||||||
|
#define MBOX_TAG_LAST 0
|
||||||
|
|
||||||
|
int mbox_call(unsigned char ch);
|
@ -0,0 +1,177 @@
|
|||||||
|
/*
|
||||||
|
* 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" // get MMIO_BASE
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
|
#define PAGESIZE 4096
|
||||||
|
|
||||||
|
// granularity
|
||||||
|
#define PT_PAGE 0b11 // 4k granule
|
||||||
|
#define PT_BLOCK 0b01 // 2M granule
|
||||||
|
// accessibility
|
||||||
|
#define PT_KERNEL (0<<6) // privileged, supervisor EL1 access only
|
||||||
|
#define PT_USER (1<<6) // unprivileged, EL0 access allowed
|
||||||
|
#define PT_RW (0<<7) // read-write
|
||||||
|
#define PT_RO (1<<7) // read-only
|
||||||
|
#define PT_AF (1<<10) // accessed flag
|
||||||
|
#define PT_NX (1UL<<54) // no execute
|
||||||
|
// shareability
|
||||||
|
#define PT_OSH (2<<8) // outter shareable
|
||||||
|
#define PT_ISH (3<<8) // inner shareable
|
||||||
|
// defined in MAIR register
|
||||||
|
#define PT_MEM (0<<2) // normal memory
|
||||||
|
#define PT_DEV (1<<2) // device MMIO
|
||||||
|
#define PT_NC (2<<2) // non-cachable
|
||||||
|
|
||||||
|
#define TTBR_ENABLE 1
|
||||||
|
|
||||||
|
// get addresses from linker
|
||||||
|
extern volatile unsigned char _data;
|
||||||
|
extern volatile unsigned char _end;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up page translation tables and enable virtual memory
|
||||||
|
*/
|
||||||
|
void mmu_init()
|
||||||
|
{
|
||||||
|
unsigned long r, b, *paging=(unsigned long*)&_end;
|
||||||
|
|
||||||
|
/* create MMU translation tables at _end */
|
||||||
|
|
||||||
|
// TTBR0, identity L1
|
||||||
|
paging[0]=(unsigned long)((unsigned char*)&_end+2*PAGESIZE) | // physical address
|
||||||
|
PT_PAGE | // it has the "Present" flag, which must be set, and we have area in it mapped by pages
|
||||||
|
PT_AF | // accessed flag. Without this we're going to have a Data Abort exception
|
||||||
|
PT_USER | // non-privileged
|
||||||
|
PT_ISH | // inner shareable
|
||||||
|
PT_MEM; // normal memory
|
||||||
|
|
||||||
|
// identity L2, first 2M block
|
||||||
|
paging[2*512]=(unsigned long)((unsigned char*)&_end+3*PAGESIZE) | // physical address
|
||||||
|
PT_PAGE | // we have area in it mapped by pages
|
||||||
|
PT_AF | // accessed flag
|
||||||
|
PT_USER | // non-privileged
|
||||||
|
PT_ISH | // inner shareable
|
||||||
|
PT_MEM; // normal memory
|
||||||
|
|
||||||
|
// identity L2 2M blocks
|
||||||
|
b=MMIO_BASE>>21;
|
||||||
|
// skip 0th, as we're about to map it by L3
|
||||||
|
for(r=1;r<512;r++)
|
||||||
|
paging[2*512+r]=(unsigned long)((r<<21)) | // physical address
|
||||||
|
PT_BLOCK | // map 2M block
|
||||||
|
PT_AF | // accessed flag
|
||||||
|
PT_NX | // no execute
|
||||||
|
PT_USER | // non-privileged
|
||||||
|
(r>=b? PT_OSH|PT_DEV : PT_ISH|PT_MEM); // different attributes for device memory
|
||||||
|
|
||||||
|
// identity L3
|
||||||
|
for(r=0;r<512;r++)
|
||||||
|
paging[3*512+r]=(unsigned long)(r*PAGESIZE) | // physical address
|
||||||
|
PT_PAGE | // map 4k
|
||||||
|
PT_AF | // accessed flag
|
||||||
|
PT_USER | // non-privileged
|
||||||
|
PT_ISH | // inner shareable
|
||||||
|
((r<0x80||r>(unsigned long)&_data/PAGESIZE)? PT_RW|PT_NX : PT_RO); // different for code and data
|
||||||
|
|
||||||
|
// TTBR1, kernel L1
|
||||||
|
paging[512+511]=(unsigned long)((unsigned char*)&_end+4*PAGESIZE) | // physical address
|
||||||
|
PT_PAGE | // we have area in it mapped by pages
|
||||||
|
PT_AF | // accessed flag
|
||||||
|
PT_KERNEL | // privileged
|
||||||
|
PT_ISH | // inner shareable
|
||||||
|
PT_MEM; // normal memory
|
||||||
|
|
||||||
|
// kernel L2
|
||||||
|
paging[4*512+511]=(unsigned long)((unsigned char*)&_end+5*PAGESIZE) | // physical address
|
||||||
|
PT_PAGE | // we have area in it mapped by pages
|
||||||
|
PT_AF | // accessed flag
|
||||||
|
PT_KERNEL | // privileged
|
||||||
|
PT_ISH | // inner shareable
|
||||||
|
PT_MEM; // normal memory
|
||||||
|
|
||||||
|
// kernel L3
|
||||||
|
paging[5*512]=(unsigned long)(MMIO_BASE+0x00201000) | // physical address
|
||||||
|
PT_PAGE | // map 4k
|
||||||
|
PT_AF | // accessed flag
|
||||||
|
PT_NX | // no execute
|
||||||
|
PT_KERNEL | // privileged
|
||||||
|
PT_OSH | // outter shareable
|
||||||
|
PT_DEV; // device memory
|
||||||
|
|
||||||
|
/* okay, now we have to set system registers to enable MMU */
|
||||||
|
|
||||||
|
// check for 4k granule and at least 36 bits physical address bus */
|
||||||
|
asm volatile ("mrs %0, id_aa64mmfr0_el1" : "=r" (r));
|
||||||
|
b=r&0xF;
|
||||||
|
if(r&(0xF<<28)/*4k*/ || b<1/*36 bits*/) {
|
||||||
|
uart_puts("ERROR: 4k granule or 36 bit address space not supported\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// first, set Memory Attributes array, indexed by PT_MEM, PT_DEV, PT_NC in our example
|
||||||
|
r= (0xFF << 0) | // AttrIdx=0: normal, IWBWA, OWBWA, NTR
|
||||||
|
(0x04 << 8) | // AttrIdx=1: device, nGnRE (must be OSH too)
|
||||||
|
(0x44 <<16); // AttrIdx=2: non cacheable
|
||||||
|
asm volatile ("msr mair_el1, %0" : : "r" (r));
|
||||||
|
|
||||||
|
// next, specify mapping characteristics in translate control register
|
||||||
|
r= (0b00LL << 37) | // TBI=0, no tagging
|
||||||
|
(b << 32) | // IPS=autodetected
|
||||||
|
(0b10LL << 30) | // TG1=4k
|
||||||
|
(0b11LL << 28) | // SH1=3 inner
|
||||||
|
(0b01LL << 26) | // ORGN1=1 write back
|
||||||
|
(0b01LL << 24) | // IRGN1=1 write back
|
||||||
|
(0b0LL << 23) | // EPD1 enable higher half
|
||||||
|
(25LL << 16) | // T1SZ=25, 3 levels (512G)
|
||||||
|
(0b00LL << 14) | // TG0=4k
|
||||||
|
(0b11LL << 12) | // SH0=3 inner
|
||||||
|
(0b01LL << 10) | // ORGN0=1 write back
|
||||||
|
(0b01LL << 8) | // IRGN0=1 write back
|
||||||
|
(0b0LL << 7) | // EPD0 enable lower half
|
||||||
|
(25LL << 0); // T0SZ=25, 3 levels (512G)
|
||||||
|
asm volatile ("msr tcr_el1, %0; isb" : : "r" (r));
|
||||||
|
|
||||||
|
// tell the MMU where our translation tables are. TTBR_ENABLE bit not documented, but required
|
||||||
|
// lower half, user space
|
||||||
|
asm volatile ("msr ttbr0_el1, %0" : : "r" ((unsigned long)&_end + TTBR_ENABLE));
|
||||||
|
// upper half, kernel space
|
||||||
|
asm volatile ("msr ttbr1_el1, %0" : : "r" ((unsigned long)&_end + TTBR_ENABLE + PAGESIZE));
|
||||||
|
|
||||||
|
// finally, toggle some bits in system control register to enable page translation
|
||||||
|
asm volatile ("dsb ish; isb; mrs %0, sctlr_el1" : "=r" (r));
|
||||||
|
r|=0xC00800; // set mandatory reserved bits
|
||||||
|
r&=~((1<<25) | // clear EE, little endian translation tables
|
||||||
|
(1<<24) | // clear E0E
|
||||||
|
(1<<19) | // clear WXN
|
||||||
|
(1<<12) | // clear I, no instruction cache
|
||||||
|
(1<<4) | // clear SA0
|
||||||
|
(1<<3) | // clear SA
|
||||||
|
(1<<2) | // clear C, no cache at all
|
||||||
|
(1<<1)); // clear A, no aligment check
|
||||||
|
r|= (1<<0); // set M, enable MMU
|
||||||
|
asm volatile ("msr sctlr_el1, %0; isb" : : "r" (r));
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* 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 mmu_init();
|
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
// set up EL1
|
||||||
|
mrs x0, CurrentEL
|
||||||
|
cmp x0, #4
|
||||||
|
beq 5f
|
||||||
|
msr sp_el1, x1
|
||||||
|
// enable CNTP for EL1
|
||||||
|
mrs x0, cnthctl_el2
|
||||||
|
orr x0, x0, #3
|
||||||
|
msr cnthctl_el2, x0
|
||||||
|
msr cntvoff_el2, xzr
|
||||||
|
// Setup SCTLR access
|
||||||
|
mov x0, #(1 << 31) // AArch64
|
||||||
|
orr x0, x0, #(1 << 1) // SWIO hardwired on Pi3
|
||||||
|
msr hcr_el2, x0
|
||||||
|
mrs x0, hcr_el2
|
||||||
|
mov x2, #0x0800
|
||||||
|
movk x2, #0x30d0, lsl #16
|
||||||
|
msr sctlr_el1, x2
|
||||||
|
// set up exception handlers
|
||||||
|
ldr x1, =_vectors
|
||||||
|
msr vbar_el1, x1
|
||||||
|
// change execution level to EL1
|
||||||
|
mov x2, #0x3c4
|
||||||
|
msr spsr_el2, x2
|
||||||
|
adr x2, 5f
|
||||||
|
msr elr_el2, x2
|
||||||
|
eret
|
||||||
|
|
||||||
|
5: 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
|
||||||
|
|
||||||
|
// important, code has to be properly aligned
|
||||||
|
.align 11
|
||||||
|
_vectors:
|
||||||
|
// synchronous
|
||||||
|
.align 7
|
||||||
|
mov x0, #0
|
||||||
|
mrs x1, esr_el1
|
||||||
|
mrs x2, elr_el1
|
||||||
|
mrs x3, spsr_el1
|
||||||
|
mrs x4, far_el1
|
||||||
|
b exc_handler
|
||||||
|
|
||||||
|
// IRQ
|
||||||
|
.align 7
|
||||||
|
mov x0, #1
|
||||||
|
mrs x1, esr_el1
|
||||||
|
mrs x2, elr_el1
|
||||||
|
mrs x3, spsr_el1
|
||||||
|
mrs x4, far_el1
|
||||||
|
b exc_handler
|
||||||
|
|
||||||
|
// FIQ
|
||||||
|
.align 7
|
||||||
|
mov x0, #2
|
||||||
|
mrs x1, esr_el1
|
||||||
|
mrs x2, elr_el1
|
||||||
|
mrs x3, spsr_el1
|
||||||
|
mrs x4, far_el1
|
||||||
|
b exc_handler
|
||||||
|
|
||||||
|
// SError
|
||||||
|
.align 7
|
||||||
|
mov x0, #3
|
||||||
|
mrs x1, esr_el1
|
||||||
|
mrs x2, elr_el1
|
||||||
|
mrs x3, spsr_el1
|
||||||
|
mrs x4, far_el1
|
||||||
|
b exc_handler
|
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
#include "mbox.h"
|
||||||
|
|
||||||
|
/* PL011 UART registers */
|
||||||
|
#define UART0_DR ((volatile unsigned int*)(MMIO_BASE+0x00201000))
|
||||||
|
#define UART0_FR ((volatile unsigned int*)(MMIO_BASE+0x00201018))
|
||||||
|
#define UART0_IBRD ((volatile unsigned int*)(MMIO_BASE+0x00201024))
|
||||||
|
#define UART0_FBRD ((volatile unsigned int*)(MMIO_BASE+0x00201028))
|
||||||
|
#define UART0_LCRH ((volatile unsigned int*)(MMIO_BASE+0x0020102C))
|
||||||
|
#define UART0_CR ((volatile unsigned int*)(MMIO_BASE+0x00201030))
|
||||||
|
#define UART0_IMSC ((volatile unsigned int*)(MMIO_BASE+0x00201038))
|
||||||
|
#define UART0_ICR ((volatile unsigned int*)(MMIO_BASE+0x00201044))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set baud rate and characteristics (115200 8N1) and map to GPIO
|
||||||
|
*/
|
||||||
|
void uart_init()
|
||||||
|
{
|
||||||
|
register unsigned int r;
|
||||||
|
|
||||||
|
/* initialize UART */
|
||||||
|
*UART0_CR = 0; // turn off UART0
|
||||||
|
|
||||||
|
/* set up clock for consistent divisor values */
|
||||||
|
mbox[0] = 8*4;
|
||||||
|
mbox[1] = MBOX_REQUEST;
|
||||||
|
mbox[2] = MBOX_TAG_SETCLKRATE; // set clock rate
|
||||||
|
mbox[3] = 12;
|
||||||
|
mbox[4] = 8;
|
||||||
|
mbox[5] = 2; // UART clock
|
||||||
|
mbox[6] = 4000000; // 4Mhz
|
||||||
|
mbox[7] = MBOX_TAG_LAST;
|
||||||
|
mbox_call(MBOX_CH_PROP);
|
||||||
|
|
||||||
|
/* map UART0 to GPIO pins */
|
||||||
|
r=*GPFSEL1;
|
||||||
|
r&=~((7<<12)|(7<<15)); // gpio14, gpio15
|
||||||
|
r|=(2<<12)|(2<<15); // alt5
|
||||||
|
*GPFSEL1 = r;
|
||||||
|
*GPPUD = 0; // enable pins 14 and 15
|
||||||
|
r=150; while(r--) { asm volatile("nop"); }
|
||||||
|
*GPPUDCLK0 = (1<<14)|(1<<15);
|
||||||
|
r=150; while(r--) { asm volatile("nop"); }
|
||||||
|
*GPPUDCLK0 = 0; // flush GPIO setup
|
||||||
|
|
||||||
|
*UART0_ICR = 0x7FF; // clear interrupts
|
||||||
|
*UART0_IBRD = 2; // 115200 baud
|
||||||
|
*UART0_FBRD = 0xB;
|
||||||
|
*UART0_LCRH = 0b11<<5; // 8n1
|
||||||
|
*UART0_CR = 0x301; // enable Tx, Rx, FIFO
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a character
|
||||||
|
*/
|
||||||
|
void uart_send(unsigned int c) {
|
||||||
|
/* wait until we can send */
|
||||||
|
do{asm volatile("nop");}while(*UART0_FR&0x20);
|
||||||
|
/* write the 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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use, copy,
|
||||||
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void uart_init();
|
||||||
|
void uart_send(unsigned int c);
|
||||||
|
char uart_getc();
|
||||||
|
void uart_puts(char *s);
|
||||||
|
void uart_hex(unsigned int d);
|
Loading…
Reference in New Issue