adding raspberry pi 3 64 bit examples

This commit is contained in:
dwelch
2016-03-15 01:23:52 -04:00
parent ce44fcc41f
commit 20e645321d
21 changed files with 132443 additions and 2 deletions

11
README
View File

@@ -19,6 +19,7 @@ Raspberry Pi B+
Raspberry Pi Zero
Cortex-A7 based (BCM2836)
Raspberry Pi 2 B
Raspberry Pi 3 B
There is also the compute module but I dont have one of those.
@@ -31,7 +32,9 @@ clocked the processor from 750MHz to 1000MHz, one led on gpio 16. The
A+ and B+ they moved the led (or put two) on gpio 35 and 47. The
raspberry pi 2 is B+ like but with the different chip, supposedly the
BCM2836 is BCM2835 with the ARM11 core removed and replaced with
the Cortex A7 and for the most part it appears to be.
the Cortex A7 and for the most part it appears to be. The raspberry
pi 3 is Cortex A8 based, 64 bit. And they moved the LED (the leds)
to an i2c gpio expander.
As of this writing I am adding plus and pi2 versions of the examples
as many of them are based on the early/original. No guarantees I will
@@ -42,6 +45,10 @@ three with ifdefs and such, keep it simple stupid then complicate it
as needed. The text may say kernel.img but substitute with kernel7.img
as needed.
I still have a number of raspberry pi 2 examples to port, and now a
bunch of examples to port to the raspberry pi 3. The raspberry pi 3
as of this writing, without a config.txt, is switched to 32 bit
compatibility mode. See the aarch64 directory for 64 bit ARM examples.
From what we know so far there is a gpu on chip which:
@@ -176,7 +183,7 @@ takes a bigger sd card to use, and takes forever to write to the sd card.
I use the firmware from http://github.com/raspberrypi. The minimum
configuration you need to get started at this level is:
go to http://github.com/raspberrypi, you DO NOT need to download
go to https://github.com/raspberrypi, you DO NOT need to download
the repo, they have some large files in there you will not need (for
my examples). go to the firmware directory and then the boot directory.
For each of these files, bootcode.bin and start.elf (NOT kernel.img,

31
aarch64/README Normal file
View File

@@ -0,0 +1,31 @@
Normally I prefer to not use a config.txt. The standard boot files
bootcode.bin, start.elf, and kernel7.img are how most of the raspberry
pis in the world are used, booting linux. Well tested. config.txt
creates exceptions to that, and from the early days of the raspi to
the present some of these have come and gone.
But...As of this writing in order to run 64 bit, from what the folks
on the bare metal forums say, you have to use a config.txt containing
arm_control=0x200
kernel_old=1
The bit set in arm_control indicates boot 64 bit not 32 bit.
kernel_old tells the bootloader to not provide any boot code for the
ARM (as of this writing that code is 32 bit instructions so wont work).
This means we have to build our program for address 0x0000 not address
0x8000 like we would normally. This also means we have to deal with
the other four cores. When all the affinity bits are zero in the
MPIDR_EL1 register, that is the master core.
This relies on some SBZ/RES0 bits, but works for now to put the other
cores in an infinite loop.
mrs x0,mpidr_el1
mov x1,#0xC1000000
bic x0,x0,x1
cbz x0,master
b .
master:

View File

@@ -0,0 +1,36 @@
ARMGNU ?= aarch64-none-elf
COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding
gcc : kernel7.img
all : gcc
clean :
rm -f *.o
rm -f *.bin
rm -f *.hex
rm -f *.elf
rm -f *.list
rm -f *.img
rm -f *.bc
rm -f *.clang.s
vectors.o : vectors.s
$(ARMGNU)-as vectors.s -o vectors.o
bootloader07.o : bootloader07.c
$(ARMGNU)-gcc $(COPS) -c bootloader07.c -o bootloader07.o
periph7.o : periph.c
$(ARMGNU)-gcc $(COPS) -c periph.c -o periph7.o
kernel7.img : loader vectors.o periph7.o bootloader07.o
$(ARMGNU)-ld vectors.o periph7.o bootloader07.o -T loader -o bootloader07_rpi2.elf
$(ARMGNU)-objdump -D bootloader07_rpi2.elf > bootloader07_rpi2.list
$(ARMGNU)-objcopy bootloader07_rpi2.elf -O ihex bootloader07_rpi2.hex
$(ARMGNU)-objcopy bootloader07_rpi2.elf -O binary kernel7.img

View File

@@ -0,0 +1,56 @@
See the top level README file for more information on documentation
and how to run these programs.
This is a very simple bootloader. Instead of the sd dance (see
top level README), this makes life a bit simpler and greatly reduces
physical wear and tear on the sd card socket. Do the sd card dance one
more time with this kernel.img. Get some sort of serial solution to
connect a dumb termial program with the ability to download raw/ascii
files.
bootloader01 was .hex based, this one is also .hex based but a
different way to parse it. bootloader02 through bootloader06
expect binary files, a binary image of the memory starting at
address 0x8000. I intend to release bootloader08 at the same time
and it will be .bin based but have the go feature.
This bootloader07 parses intel hex formatted files. Look that up at
wikipedia, it is very simple and historically widely used for bare
metal embedded work. (S record is another format like intel hex but
of course motorola had to have their own. Intel hex and Motorola S-
record). I felt like doing another state machine and honestly had
forgotten I did one before in bootloader01. This bootloader does
not make any of the others obsolete, it was just a fun exercise.
The thing that annoyed me the most about my bootloader is that
I use minicom and minicom spawns a separate program to do the file
transfers, xmodem, ascii, kermit, etc, and there is a delay and
a loss of data when the spawned program exits and minicom returns.
The solution is that you hit the g key when you want the program
to start so you are basically back in the terminal at that point.
I normally do not deliver binaries. In this case I have included all
of the build files so that you can at least get started without having
to build the bootloader. This is specifically for the raspberry pi 3,
compiled for aarch64.
As of this writing for this to work you must in addition to the other
files (bootcode.bin, start.elf, the kernel7.img from here) and a
config.txt containing
arm_control=0x200
kernel_old=1
The bit set in arm_control indicates boot 64 bit not 32 bit.
kernel_old tells the bootloader to not provide any boot code for the
ARM (as of this writing that code is 32 bit instructions so wont work).
This means we have to build our program for address 0x0000 not address
0x8000 like we would normally. This also means we have to deal with
the other four cores. When all the affinity bits are zero in the
MPIDR_EL1 register, that is the master core. For now I put the other
cores in an infinite loop.

View File

@@ -0,0 +1,226 @@
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// 2 outer corner
// 4
// 6
// 8 TX out
// 10 RX in
extern void PUT32 ( unsigned int, unsigned int );
extern unsigned int GET32 ( unsigned int );
extern unsigned int GETPC ( void );
extern void BRANCHTO ( unsigned int );
extern void dummy ( unsigned int );
extern void uart_init ( void );
extern unsigned int uart_lcr ( void );
extern void uart_flush ( void );
extern void uart_send ( unsigned int );
extern unsigned int uart_recv ( void );
extern unsigned int uart_check ( void );
extern void hexstring ( unsigned int );
extern void hexstrings ( unsigned int );
extern void timer_init ( void );
extern unsigned int timer_tick ( void );
extern void timer_init ( void );
extern unsigned int timer_tick ( void );
//------------------------------------------------------------------------
int notmain ( void )
{
unsigned int state;
unsigned int byte_count;
unsigned int address;
unsigned int record_type;
unsigned int segment;
unsigned int data;
unsigned int sum;
unsigned int ra;
uart_init();
hexstring(0x12345678);
hexstring(GETPC());
uart_send('I');
uart_send('H');
uart_send('E');
uart_send('X');
uart_send(0x0D);
uart_send(0x0A);
state=0;
segment=0;
sum=0;
data=0;
record_type=0;
address=0;
byte_count=0;
while(1)
{
ra=uart_recv();
if(ra==':')
{
state=1;
continue;
}
if(ra==0x0D)
{
state=0;
continue;
}
if(ra==0x0A)
{
state=0;
continue;
}
if((ra=='g')||(ra=='G'))
{
uart_send(0x0D);
uart_send('-');
uart_send('-');
uart_send(0x0D);
uart_send(0x0A);
uart_send(0x0A);
BRANCHTO(0x8000);
state=0;
break;
}
switch(state)
{
case 0:
{
break;
}
case 1:
case 2:
{
byte_count<<=4;
if(ra>0x39) ra-=7;
byte_count|=(ra&0xF);
byte_count&=0xFF;
state++;
break;
}
case 3:
case 4:
case 5:
case 6:
{
address<<=4;
if(ra>0x39) ra-=7;
address|=(ra&0xF);
address&=0xFFFF;
address|=segment;
state++;
break;
}
case 7:
{
record_type<<=4;
if(ra>0x39) ra-=7;
record_type|=(ra&0xF);
record_type&=0xFF;
state++;
break;
}
case 8:
{
record_type<<=4;
if(ra>0x39) ra-=7;
record_type|=(ra&0xF);
record_type&=0xFF;
switch(record_type)
{
case 0x00:
{
state=14;
break;
}
case 0x01:
{
hexstring(sum);
state=0;
break;
}
case 0x02:
{
state=9;
break;
}
default:
{
state=0;
break;
}
}
break;
}
case 9:
case 10:
case 11:
case 12:
{
segment<<=4;
if(ra>0x39) ra-=7;
segment|=(ra&0xF);
segment&=0xFFFF;
state++;
break;
}
case 13:
{
segment<<=4;
state=0;
break;
}
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
{
data<<=4;
if(ra>0x39) ra-=7;
data|=(ra&0xF);
if(state==21)
{
ra=(data>>24)|(data<<24);
ra|=(data>>8)&0x0000FF00;
ra|=(data<<8)&0x00FF0000;
data=ra;
PUT32(address,data);
sum+=address;
sum+=data;
address+=4;
state=14;
}
else
{
state++;
}
break;
}
}
}
return(0);
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
//
// Copyright (c) 2014 David Welch dwelch@dwelch.com
//
// 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.
//
//-------------------------------------------------------------------------

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,394 @@
bootloader07_rpi2.elf: file format elf64-littleaarch64
Disassembly of section .text:
0000000000000000 <_start>:
0: 14080000 b 200000 <skip>
...
0000000000200000 <skip>:
200000: d53800a0 mrs x0, mpidr_el1
200004: d2b82001 mov x1, #0xc1000000 // #3238002688
200008: 8a210000 bic x0, x0, x1
20000c: b4000040 cbz x0, 200014 <master>
200010: 14000003 b 20001c <hang>
0000000000200014 <master>:
200014: b26503ff mov sp, #0x8000000 // #134217728
200018: 940000b2 bl 2002e0 <notmain>
000000000020001c <hang>:
20001c: 14000000 b 20001c <hang>
0000000000200020 <PUT32>:
200020: b9000001 str w1, [x0]
200024: d65f03c0 ret
0000000000200028 <GET32>:
200028: b9400000 ldr w0, [x0]
20002c: d65f03c0 ret
0000000000200030 <GETPC>:
200030: aa1e03e0 mov x0, x30
200034: d65f03c0 ret
0000000000200038 <BRANCHTO>:
200038: 2a0003fe mov w30, w0
20003c: d65f03c0 ret
0000000000200040 <dummy>:
200040: d65f03c0 ret
200044: 00000000 .inst 0x00000000 ; undefined
0000000000200048 <uart_lcr>:
200048: 528a0a80 mov w0, #0x5054 // #20564
20004c: 72a7e420 movk w0, #0x3f21, lsl #16
200050: 17fffff6 b 200028 <GET32>
200054: d503201f nop
0000000000200058 <uart_recv>:
200058: a9bf7bfd stp x29, x30, [sp,#-16]!
20005c: 910003fd mov x29, sp
200060: 528a0a80 mov w0, #0x5054 // #20564
200064: 72a7e420 movk w0, #0x3f21, lsl #16
200068: 97fffff0 bl 200028 <GET32>
20006c: 3607ffa0 tbz w0, #0, 200060 <uart_recv+0x8>
200070: 528a0800 mov w0, #0x5040 // #20544
200074: 72a7e420 movk w0, #0x3f21, lsl #16
200078: 97ffffec bl 200028 <GET32>
20007c: 53001c00 uxtb w0, w0
200080: a8c17bfd ldp x29, x30, [sp],#16
200084: d65f03c0 ret
0000000000200088 <uart_check>:
200088: a9bf7bfd stp x29, x30, [sp,#-16]!
20008c: 528a0a80 mov w0, #0x5054 // #20564
200090: 910003fd mov x29, sp
200094: 72a7e420 movk w0, #0x3f21, lsl #16
200098: 97ffffe4 bl 200028 <GET32>
20009c: 12000000 and w0, w0, #0x1
2000a0: a8c17bfd ldp x29, x30, [sp],#16
2000a4: d65f03c0 ret
00000000002000a8 <uart_send>:
2000a8: a9be7bfd stp x29, x30, [sp,#-32]!
2000ac: 910003fd mov x29, sp
2000b0: f9000bf3 str x19, [sp,#16]
2000b4: 2a0003f3 mov w19, w0
2000b8: 528a0a80 mov w0, #0x5054 // #20564
2000bc: 72a7e420 movk w0, #0x3f21, lsl #16
2000c0: 97ffffda bl 200028 <GET32>
2000c4: 362fffa0 tbz w0, #5, 2000b8 <uart_send+0x10>
2000c8: 2a1303e1 mov w1, w19
2000cc: 528a0800 mov w0, #0x5040 // #20544
2000d0: f9400bf3 ldr x19, [sp,#16]
2000d4: 72a7e420 movk w0, #0x3f21, lsl #16
2000d8: a8c27bfd ldp x29, x30, [sp],#32
2000dc: 17ffffd1 b 200020 <PUT32>
00000000002000e0 <uart_flush>:
2000e0: a9bf7bfd stp x29, x30, [sp,#-16]!
2000e4: 910003fd mov x29, sp
2000e8: 528a0a80 mov w0, #0x5054 // #20564
2000ec: 72a7e420 movk w0, #0x3f21, lsl #16
2000f0: 97ffffce bl 200028 <GET32>
2000f4: 3747ffa0 tbnz w0, #8, 2000e8 <uart_flush+0x8>
2000f8: a8c17bfd ldp x29, x30, [sp],#16
2000fc: d65f03c0 ret
0000000000200100 <hexstrings>:
200100: a9be7bfd stp x29, x30, [sp,#-32]!
200104: 910003fd mov x29, sp
200108: a90153f3 stp x19, x20, [sp,#16]
20010c: 2a0003f4 mov w20, w0
200110: 52800413 mov w19, #0x20 // #32
200114: 51001273 sub w19, w19, #0x4
200118: 1ad32681 lsr w1, w20, w19
20011c: 12000c21 and w1, w1, #0xf
200120: 1100dc20 add w0, w1, #0x37
200124: 1100c022 add w2, w1, #0x30
200128: 7100283f cmp w1, #0xa
20012c: 1a803040 csel w0, w2, w0, cc
200130: 97ffffde bl 2000a8 <uart_send>
200134: 35ffff13 cbnz w19, 200114 <hexstrings+0x14>
200138: a94153f3 ldp x19, x20, [sp,#16]
20013c: a8c27bfd ldp x29, x30, [sp],#32
200140: 52800400 mov w0, #0x20 // #32
200144: 17ffffd9 b 2000a8 <uart_send>
0000000000200148 <hexstring>:
200148: a9bf7bfd stp x29, x30, [sp,#-16]!
20014c: 910003fd mov x29, sp
200150: 97ffffec bl 200100 <hexstrings>
200154: 528001a0 mov w0, #0xd // #13
200158: 97ffffd4 bl 2000a8 <uart_send>
20015c: a8c17bfd ldp x29, x30, [sp],#16
200160: 52800140 mov w0, #0xa // #10
200164: 17ffffd1 b 2000a8 <uart_send>
0000000000200168 <uart_init>:
200168: a9be7bfd stp x29, x30, [sp,#-32]!
20016c: 528a0080 mov w0, #0x5004 // #20484
200170: 52800021 mov w1, #0x1 // #1
200174: 910003fd mov x29, sp
200178: 72a7e420 movk w0, #0x3f21, lsl #16
20017c: f9000bf3 str x19, [sp,#16]
200180: 97ffffa8 bl 200020 <PUT32>
200184: 528a0880 mov w0, #0x5044 // #20548
200188: 52800001 mov w1, #0x0 // #0
20018c: 72a7e420 movk w0, #0x3f21, lsl #16
200190: 52800013 mov w19, #0x0 // #0
200194: 97ffffa3 bl 200020 <PUT32>
200198: 528a0c00 mov w0, #0x5060 // #20576
20019c: 52800001 mov w1, #0x0 // #0
2001a0: 72a7e420 movk w0, #0x3f21, lsl #16
2001a4: 97ffff9f bl 200020 <PUT32>
2001a8: 528a0980 mov w0, #0x504c // #20556
2001ac: 52800061 mov w1, #0x3 // #3
2001b0: 72a7e420 movk w0, #0x3f21, lsl #16
2001b4: 97ffff9b bl 200020 <PUT32>
2001b8: 528a0a00 mov w0, #0x5050 // #20560
2001bc: 52800001 mov w1, #0x0 // #0
2001c0: 72a7e420 movk w0, #0x3f21, lsl #16
2001c4: 97ffff97 bl 200020 <PUT32>
2001c8: 528a0880 mov w0, #0x5044 // #20548
2001cc: 52800001 mov w1, #0x0 // #0
2001d0: 72a7e420 movk w0, #0x3f21, lsl #16
2001d4: 97ffff93 bl 200020 <PUT32>
2001d8: 528a0900 mov w0, #0x5048 // #20552
2001dc: 528018c1 mov w1, #0xc6 // #198
2001e0: 72a7e420 movk w0, #0x3f21, lsl #16
2001e4: 97ffff8f bl 200020 <PUT32>
2001e8: 528a0d00 mov w0, #0x5068 // #20584
2001ec: 528021c1 mov w1, #0x10e // #270
2001f0: 72a7e420 movk w0, #0x3f21, lsl #16
2001f4: 97ffff8b bl 200020 <PUT32>
2001f8: 52800080 mov w0, #0x4 // #4
2001fc: 72a7e400 movk w0, #0x3f20, lsl #16
200200: 97ffff8a bl 200028 <GET32>
200204: 120e6402 and w2, w0, #0xfffc0fff
200208: 52840001 mov w1, #0x2000 // #8192
20020c: 52800080 mov w0, #0x4 // #4
200210: 72a00021 movk w1, #0x1, lsl #16
200214: 72a7e400 movk w0, #0x3f20, lsl #16
200218: 2a010041 orr w1, w2, w1
20021c: 97ffff81 bl 200020 <PUT32>
200220: 52801280 mov w0, #0x94 // #148
200224: 52800001 mov w1, #0x0 // #0
200228: 72a7e400 movk w0, #0x3f20, lsl #16
20022c: 97ffff7d bl 200020 <PUT32>
200230: 2a1303e0 mov w0, w19
200234: 11000673 add w19, w19, #0x1
200238: 97ffff82 bl 200040 <dummy>
20023c: 71025a7f cmp w19, #0x96
200240: 54ffff81 b.ne 200230 <uart_init+0xc8>
200244: 52801300 mov w0, #0x98 // #152
200248: 52980001 mov w1, #0xc000 // #49152
20024c: 72a7e400 movk w0, #0x3f20, lsl #16
200250: 52800013 mov w19, #0x0 // #0
200254: 97ffff73 bl 200020 <PUT32>
200258: 2a1303e0 mov w0, w19
20025c: 11000673 add w19, w19, #0x1
200260: 97ffff78 bl 200040 <dummy>
200264: 71025a7f cmp w19, #0x96
200268: 54ffff81 b.ne 200258 <uart_init+0xf0>
20026c: 52801300 mov w0, #0x98 // #152
200270: 52800001 mov w1, #0x0 // #0
200274: 72a7e400 movk w0, #0x3f20, lsl #16
200278: 97ffff6a bl 200020 <PUT32>
20027c: f9400bf3 ldr x19, [sp,#16]
200280: 528a0c00 mov w0, #0x5060 // #20576
200284: 52800061 mov w1, #0x3 // #3
200288: a8c27bfd ldp x29, x30, [sp],#32
20028c: 72a7e420 movk w0, #0x3f21, lsl #16
200290: 17ffff64 b 200020 <PUT32>
200294: d503201f nop
0000000000200298 <timer_init>:
200298: a9be7bfd stp x29, x30, [sp,#-32]!
20029c: 52a01f21 mov w1, #0xf90000 // #16318464
2002a0: 910003fd mov x29, sp
2002a4: f9000bf3 str x19, [sp,#16]
2002a8: 52968113 mov w19, #0xb408 // #46088
2002ac: 72a7e013 movk w19, #0x3f00, lsl #16
2002b0: 2a1303e0 mov w0, w19
2002b4: 97ffff5b bl 200020 <PUT32>
2002b8: 2a1303e0 mov w0, w19
2002bc: 52804001 mov w1, #0x200 // #512
2002c0: f9400bf3 ldr x19, [sp,#16]
2002c4: 72a01f21 movk w1, #0xf9, lsl #16
2002c8: a8c27bfd ldp x29, x30, [sp],#32
2002cc: 17ffff55 b 200020 <PUT32>
00000000002002d0 <timer_tick>:
2002d0: 52968400 mov w0, #0xb420 // #46112
2002d4: 72a7e000 movk w0, #0x3f00, lsl #16
2002d8: 17ffff54 b 200028 <GET32>
2002dc: d503201f nop
00000000002002e0 <notmain>:
2002e0: a9bb7bfd stp x29, x30, [sp,#-80]!
2002e4: 910003fd mov x29, sp
2002e8: a90153f3 stp x19, x20, [sp,#16]
2002ec: a9025bf5 stp x21, x22, [sp,#32]
2002f0: a90363f7 stp x23, x24, [sp,#48]
2002f4: a9046bf9 stp x25, x26, [sp,#64]
2002f8: 97ffff9c bl 200168 <uart_init>
2002fc: 90000015 adrp x21, 200000 <skip>
200300: 528acf00 mov w0, #0x5678 // #22136
200304: 52800018 mov w24, #0x0 // #0
200308: 72a24680 movk w0, #0x1234, lsl #16
20030c: 52800017 mov w23, #0x0 // #0
200310: 5280001a mov w26, #0x0 // #0
200314: 52800014 mov w20, #0x0 // #0
200318: 97ffff8c bl 200148 <hexstring>
20031c: 52800016 mov w22, #0x0 // #0
200320: 97ffff44 bl 200030 <GETPC>
200324: 52800013 mov w19, #0x0 // #0
200328: 97ffff88 bl 200148 <hexstring>
20032c: 52800139 mov w25, #0x9 // #9
200330: 52800920 mov w0, #0x49 // #73
200334: 911482b5 add x21, x21, #0x520
200338: 97ffff5c bl 2000a8 <uart_send>
20033c: 52800900 mov w0, #0x48 // #72
200340: 97ffff5a bl 2000a8 <uart_send>
200344: 528008a0 mov w0, #0x45 // #69
200348: 97ffff58 bl 2000a8 <uart_send>
20034c: 52800b00 mov w0, #0x58 // #88
200350: 97ffff56 bl 2000a8 <uart_send>
200354: 528001a0 mov w0, #0xd // #13
200358: 97ffff54 bl 2000a8 <uart_send>
20035c: 52800140 mov w0, #0xa // #10
200360: 97ffff52 bl 2000a8 <uart_send>
200364: 97ffff3d bl 200058 <uart_recv>
200368: 7100e81f cmp w0, #0x3a
20036c: 54000340 b.eq 2003d4 <notmain+0xf4>
200370: 7100281f cmp w0, #0xa
200374: 7a4d1804 ccmp w0, #0xd, #0x4, ne
200378: 54000360 b.eq 2003e4 <notmain+0x104>
20037c: 121a7801 and w1, w0, #0xffffffdf
200380: 71011c3f cmp w1, #0x47
200384: 54000820 b.eq 200488 <notmain+0x1a8>
200388: 51000661 sub w1, w19, #0x1
20038c: 7100503f cmp w1, #0x14
200390: 54fffea8 b.hi 200364 <notmain+0x84>
200394: 38614aa1 ldrb w1, [x21,w1,uxtw]
200398: 10000062 adr x2, 2003a4 <notmain+0xc4>
20039c: 8b218841 add x1, x2, w1, sxtb #2
2003a0: d61f0020 br x1
2003a4: d503201f nop
2003a8: 7100e81f cmp w0, #0x3a
2003ac: 51001c01 sub w1, w0, #0x7
2003b0: 1a802020 csel w0, w1, w0, cs
2003b4: 7100567f cmp w19, #0x15
2003b8: 12000c00 and w0, w0, #0xf
2003bc: 2a171017 orr w23, w0, w23, lsl #4
2003c0: 540009c0 b.eq 2004f8 <notmain+0x218>
2003c4: 97ffff25 bl 200058 <uart_recv>
2003c8: 7100e81f cmp w0, #0x3a
2003cc: 11000673 add w19, w19, #0x1
2003d0: 54fffd01 b.ne 200370 <notmain+0x90>
2003d4: 52800033 mov w19, #0x1 // #1
2003d8: 17ffffe3 b 200364 <notmain+0x84>
2003dc: d503201f nop
2003e0: 531c6f5a lsl w26, w26, #4
2003e4: 52800013 mov w19, #0x0 // #0
2003e8: 17ffffdf b 200364 <notmain+0x84>
2003ec: d503201f nop
2003f0: 51001c01 sub w1, w0, #0x7
2003f4: 7100e81f cmp w0, #0x3a
2003f8: 1a802020 csel w0, w1, w0, cs
2003fc: 11000673 add w19, w19, #0x1
200400: 12000c00 and w0, w0, #0xf
200404: 2a1a1000 orr w0, w0, w26, lsl #4
200408: 12003c1a and w26, w0, #0xffff
20040c: 17ffffd6 b 200364 <notmain+0x84>
200410: 7100e81f cmp w0, #0x3a
200414: 51001c01 sub w1, w0, #0x7
200418: 1a802020 csel w0, w1, w0, cs
20041c: 12000c00 and w0, w0, #0xf
200420: 2a141014 orr w20, w0, w20, lsl #4
200424: 12001e94 and w20, w20, #0xff
200428: 7100069f cmp w20, #0x1
20042c: 540005e0 b.eq 2004e8 <notmain+0x208>
200430: 34000594 cbz w20, 2004e0 <notmain+0x200>
200434: 71000a9f cmp w20, #0x2
200438: 1a9f0333 csel w19, w25, wzr, eq
20043c: 17ffffca b 200364 <notmain+0x84>
200440: 51001c01 sub w1, w0, #0x7
200444: 7100e81f cmp w0, #0x3a
200448: 1a802020 csel w0, w1, w0, cs
20044c: 52800113 mov w19, #0x8 // #8
200450: 12000c00 and w0, w0, #0xf
200454: 2a141014 orr w20, w0, w20, lsl #4
200458: 12001e94 and w20, w20, #0xff
20045c: 17ffffc2 b 200364 <notmain+0x84>
200460: 51001c01 sub w1, w0, #0x7
200464: 7100e81f cmp w0, #0x3a
200468: 1a802020 csel w0, w1, w0, cs
20046c: 11000673 add w19, w19, #0x1
200470: 12000c00 and w0, w0, #0xf
200474: 2a161016 orr w22, w0, w22, lsl #4
200478: 12003ed6 and w22, w22, #0xffff
20047c: 2a160356 orr w22, w26, w22
200480: 17ffffb9 b 200364 <notmain+0x84>
200484: d503201f nop
200488: 528001a0 mov w0, #0xd // #13
20048c: 97ffff07 bl 2000a8 <uart_send>
200490: 528005a0 mov w0, #0x2d // #45
200494: 97ffff05 bl 2000a8 <uart_send>
200498: 528005a0 mov w0, #0x2d // #45
20049c: 97ffff03 bl 2000a8 <uart_send>
2004a0: 528001a0 mov w0, #0xd // #13
2004a4: 97ffff01 bl 2000a8 <uart_send>
2004a8: 52800140 mov w0, #0xa // #10
2004ac: 97fffeff bl 2000a8 <uart_send>
2004b0: 52800140 mov w0, #0xa // #10
2004b4: 97fffefd bl 2000a8 <uart_send>
2004b8: 52900000 mov w0, #0x8000 // #32768
2004bc: 97fffedf bl 200038 <BRANCHTO>
2004c0: 52800000 mov w0, #0x0 // #0
2004c4: a94153f3 ldp x19, x20, [sp,#16]
2004c8: a9425bf5 ldp x21, x22, [sp,#32]
2004cc: a94363f7 ldp x23, x24, [sp,#48]
2004d0: a9446bf9 ldp x25, x26, [sp,#64]
2004d4: a8c57bfd ldp x29, x30, [sp],#80
2004d8: d65f03c0 ret
2004dc: d503201f nop
2004e0: 528001d3 mov w19, #0xe // #14
2004e4: 17ffffa0 b 200364 <notmain+0x84>
2004e8: 2a1803e0 mov w0, w24
2004ec: 52800013 mov w19, #0x0 // #0
2004f0: 97ffff16 bl 200148 <hexstring>
2004f4: 17ffff9c b 200364 <notmain+0x84>
2004f8: 5ac00af7 rev w23, w23
2004fc: 2a1603e0 mov w0, w22
200500: 2a1703e1 mov w1, w23
200504: 0b1802d8 add w24, w22, w24
200508: 528001d3 mov w19, #0xe // #14
20050c: 0b1802f8 add w24, w23, w24
200510: 97fffec4 bl 200020 <PUT32>
200514: 110012d6 add w22, w22, #0x4
200518: 17ffff93 b 200364 <notmain+0x84>
20051c: d503201f nop
Disassembly of section .rodata:
0000000000200520 <.rodata>:
200520: 2f2f0808 .word 0x2f2f0808
200524: 1b272f2f .word 0x1b272f2f
200528: 13131313 .word 0x13131313
20052c: 0101010f .word 0x0101010f
200530: 01010101 .word 0x01010101
200534: 00000001 .word 0x00000001
Disassembly of section .comment:
0000000000000000 <.comment>:
0: 3a434347 ccmn w26, w3, #0x7, mi
4: 4e472820 trn1 v0.8h, v1.8h, v7.8h
8: 35202955 cbnz w21, 40530 <_start+0x40530>
c: 302e332e adr x14, 5c671 <_start+0x5c671>
...

View File

@@ -0,0 +1,2 @@
arm_control=0x200
kernel_old=1

BIN
aarch64/bootloader07/kernel7.img Executable file

Binary file not shown.

View File

@@ -0,0 +1,12 @@
MEMORY
{
ram : ORIGIN = 0x0000, LENGTH = 0x1000000
}
SECTIONS
{
.text : { *(.text*) } > ram
.bss : { *(.bss*) } > ram
}

View File

@@ -0,0 +1,150 @@
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
#define PBASE 0x3F000000
extern void PUT32 ( unsigned int, unsigned int );
extern unsigned int GET32 ( unsigned int );
extern void dummy ( unsigned int );
#define ARM_TIMER_CTL (PBASE+0x0000B408)
#define ARM_TIMER_CNT (PBASE+0x0000B420)
#define GPFSEL1 (PBASE+0x00200004)
#define GPSET0 (PBASE+0x0020001C)
#define GPCLR0 (PBASE+0x00200028)
#define GPPUD (PBASE+0x00200094)
#define GPPUDCLK0 (PBASE+0x00200098)
#define AUX_ENABLES (PBASE+0x00215004)
#define AUX_MU_IO_REG (PBASE+0x00215040)
#define AUX_MU_IER_REG (PBASE+0x00215044)
#define AUX_MU_IIR_REG (PBASE+0x00215048)
#define AUX_MU_LCR_REG (PBASE+0x0021504C)
#define AUX_MU_MCR_REG (PBASE+0x00215050)
#define AUX_MU_LSR_REG (PBASE+0x00215054)
#define AUX_MU_MSR_REG (PBASE+0x00215058)
#define AUX_MU_SCRATCH (PBASE+0x0021505C)
#define AUX_MU_CNTL_REG (PBASE+0x00215060)
#define AUX_MU_STAT_REG (PBASE+0x00215064)
#define AUX_MU_BAUD_REG (PBASE+0x00215068)
//GPIO14 TXD0 and TXD1
//GPIO15 RXD0 and RXD1
//------------------------------------------------------------------------
unsigned int uart_lcr ( void )
{
return(GET32(AUX_MU_LSR_REG));
}
//------------------------------------------------------------------------
unsigned int uart_recv ( void )
{
while(1)
{
if(GET32(AUX_MU_LSR_REG)&0x01) break;
}
return(GET32(AUX_MU_IO_REG)&0xFF);
}
//------------------------------------------------------------------------
unsigned int uart_check ( void )
{
if(GET32(AUX_MU_LSR_REG)&0x01) return(1);
return(0);
}
//------------------------------------------------------------------------
void uart_send ( unsigned int c )
{
while(1)
{
if(GET32(AUX_MU_LSR_REG)&0x20) break;
}
PUT32(AUX_MU_IO_REG,c);
}
//------------------------------------------------------------------------
void uart_flush ( void )
{
while(1)
{
if((GET32(AUX_MU_LSR_REG)&0x100)==0) break;
}
}
//------------------------------------------------------------------------
void hexstrings ( unsigned int d )
{
//unsigned int ra;
unsigned int rb;
unsigned int rc;
rb=32;
while(1)
{
rb-=4;
rc=(d>>rb)&0xF;
if(rc>9) rc+=0x37; else rc+=0x30;
uart_send(rc);
if(rb==0) break;
}
uart_send(0x20);
}
//------------------------------------------------------------------------
void hexstring ( unsigned int d )
{
hexstrings(d);
uart_send(0x0D);
uart_send(0x0A);
}
//------------------------------------------------------------------------
void uart_init ( void )
{
unsigned int ra;
PUT32(AUX_ENABLES,1);
PUT32(AUX_MU_IER_REG,0);
PUT32(AUX_MU_CNTL_REG,0);
PUT32(AUX_MU_LCR_REG,3);
PUT32(AUX_MU_MCR_REG,0);
PUT32(AUX_MU_IER_REG,0);
PUT32(AUX_MU_IIR_REG,0xC6);
PUT32(AUX_MU_BAUD_REG,270);
ra=GET32(GPFSEL1);
ra&=~(7<<12); //gpio14
ra|=2<<12; //alt5
ra&=~(7<<15); //gpio15
ra|=2<<15; //alt5
PUT32(GPFSEL1,ra);
PUT32(GPPUD,0);
for(ra=0;ra<150;ra++) dummy(ra);
PUT32(GPPUDCLK0,(1<<14)|(1<<15));
for(ra=0;ra<150;ra++) dummy(ra);
PUT32(GPPUDCLK0,0);
PUT32(AUX_MU_CNTL_REG,3);
}
//------------------------------------------------------------------------
void timer_init ( void )
{
//0xF9+1 = 250
//250MHz/250 = 1MHz
PUT32(ARM_TIMER_CTL,0x00F90000);
PUT32(ARM_TIMER_CTL,0x00F90200);
}
//-------------------------------------------------------------------------
unsigned int timer_tick ( void )
{
return(GET32(ARM_TIMER_CNT));
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
//
// Copyright (c) 2012 David Welch dwelch@dwelch.com
//
// 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.
//
//-------------------------------------------------------------------------

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,62 @@
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
.globl _start
_start:
b skip
.space 0x200000-0x0004,0
skip:
mrs x0,mpidr_el1
mov x1,#0xC1000000
bic x0,x0,x1
cbz x0,master
b hang
master:
mov sp,#0x08000000
bl notmain
hang: b hang
.globl PUT32
PUT32:
str w1,[x0]
ret
.globl GET32
GET32:
ldr w0,[x0]
ret
.globl GETPC
GETPC:
mov x0,x30
ret
.globl BRANCHTO
BRANCHTO:
mov w30,w0
ret
.globl dummy
dummy:
ret
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
//
// Copyright (c) 2012 David Welch dwelch@dwelch.com
//
// 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.
//
//-------------------------------------------------------------------------

40
aarch64/uart02/Makefile Normal file
View File

@@ -0,0 +1,40 @@
ARMGNU ?= aarch64-none-elf
COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding
gcc : uart02.hex uart02.bin
all : gcc clang
clean :
rm -f *.o
rm -f *.bin
rm -f *.hex
rm -f *.elf
rm -f *.list
rm -f *.img
rm -f *.bc
rm -f *.clang.opt.s
vectors.o : vectors.s
$(ARMGNU)-as vectors.s -o vectors.o
uart02.o : uart02.c
$(ARMGNU)-gcc $(COPS) -c uart02.c -o uart02.o
uart02.elf : memmap vectors.o uart02.o
$(ARMGNU)-ld vectors.o uart02.o -T memmap -o uart02.elf
$(ARMGNU)-objdump -D uart02.elf > uart02.list
uart02.bin : uart02.elf
$(ARMGNU)-objcopy uart02.elf -O binary uart02.bin
uart02.hex : uart02.elf
$(ARMGNU)-objcopy uart02.elf -O ihex uart02.hex

21
aarch64/uart02/README Normal file
View File

@@ -0,0 +1,21 @@
See the top level README for information on where to find the
schematic and programmers reference manual for the ARM processor
on the raspberry pi. Also find information on how to load and run
these programs.
Based on uart01, this one enables the uart rxd1 receiver (gpio15).
It starts by printing 12345678 then whatever you type on the terminal
is echoed back.
See the top level README file for information on how to connect the
raspi uart to your host computer.
Using a dumb terminal (minicom) 115200 board No parity 8 bits 1 stop
bit, no flow control (might have to exit minicom and start again for
the flow control setting to take). What you type on the dumb terminal
comes back.
This is an aarch64 example. It is meant to be loaded using the
bootloader07 (64bit) bootloader. It is specifically for the
raspberry pi 3.

12
aarch64/uart02/memmap Normal file
View File

@@ -0,0 +1,12 @@
MEMORY
{
ram : ORIGIN = 0x8000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > ram
.bss : { *(.bss*) } > ram
}

159
aarch64/uart02/uart02.c Normal file
View File

@@ -0,0 +1,159 @@
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
extern void PUT32 ( unsigned int, unsigned int );
extern unsigned int GET32 ( unsigned int );
extern void dummy ( unsigned int );
#define GPFSEL1 0x3F200004
#define GPSET0 0x3F20001C
#define GPCLR0 0x3F200028
#define GPPUD 0x3F200094
#define GPPUDCLK0 0x3F200098
#define AUX_ENABLES 0x3F215004
#define AUX_MU_IO_REG 0x3F215040
#define AUX_MU_IER_REG 0x3F215044
#define AUX_MU_IIR_REG 0x3F215048
#define AUX_MU_LCR_REG 0x3F21504C
#define AUX_MU_MCR_REG 0x3F215050
#define AUX_MU_LSR_REG 0x3F215054
#define AUX_MU_MSR_REG 0x3F215058
#define AUX_MU_SCRATCH 0x3F21505C
#define AUX_MU_CNTL_REG 0x3F215060
#define AUX_MU_STAT_REG 0x3F215064
#define AUX_MU_BAUD_REG 0x3F215068
//GPIO14 TXD0 and TXD1
//GPIO15 RXD0 and RXD1
//alt function 5 for uart1
//alt function 0 for uart0
//((250,000,000/115200)/8)-1 = 270
//GPIO14 TXD0 and TXD1
//GPIO15 RXD0 and RXD1
//------------------------------------------------------------------------
unsigned int uart_lcr ( void )
{
return(GET32(AUX_MU_LSR_REG));
}
//------------------------------------------------------------------------
unsigned int uart_recv ( void )
{
while(1)
{
if(GET32(AUX_MU_LSR_REG)&0x01) break;
}
return(GET32(AUX_MU_IO_REG)&0xFF);
}
//------------------------------------------------------------------------
unsigned int uart_check ( void )
{
if(GET32(AUX_MU_LSR_REG)&0x01) return(1);
return(0);
}
//------------------------------------------------------------------------
void uart_send ( unsigned int c )
{
while(1)
{
if(GET32(AUX_MU_LSR_REG)&0x20) break;
}
PUT32(AUX_MU_IO_REG,c);
}
//------------------------------------------------------------------------
void uart_flush ( void )
{
while(1)
{
if((GET32(AUX_MU_LSR_REG)&0x100)==0) break;
}
}
//------------------------------------------------------------------------
void hexstrings ( unsigned int d )
{
//unsigned int ra;
unsigned int rb;
unsigned int rc;
rb=32;
while(1)
{
rb-=4;
rc=(d>>rb)&0xF;
if(rc>9) rc+=0x37; else rc+=0x30;
uart_send(rc);
if(rb==0) break;
}
uart_send(0x20);
}
//------------------------------------------------------------------------
void hexstring ( unsigned int d )
{
hexstrings(d);
uart_send(0x0D);
uart_send(0x0A);
}
//------------------------------------------------------------------------
void uart_init ( void )
{
unsigned int ra;
PUT32(AUX_ENABLES,1);
PUT32(AUX_MU_IER_REG,0);
PUT32(AUX_MU_CNTL_REG,0);
PUT32(AUX_MU_LCR_REG,3);
PUT32(AUX_MU_MCR_REG,0);
PUT32(AUX_MU_IER_REG,0);
PUT32(AUX_MU_IIR_REG,0xC6);
PUT32(AUX_MU_BAUD_REG,270);
ra=GET32(GPFSEL1);
ra&=~(7<<12); //gpio14
ra|=2<<12; //alt5
ra&=~(7<<15); //gpio15
ra|=2<<15; //alt5
PUT32(GPFSEL1,ra);
PUT32(GPPUD,0);
for(ra=0;ra<150;ra++) dummy(ra);
PUT32(GPPUDCLK0,(1<<14)|(1<<15));
for(ra=0;ra<150;ra++) dummy(ra);
PUT32(GPPUDCLK0,0);
PUT32(AUX_MU_CNTL_REG,3);
}
//------------------------------------------------------------------------
int notmain ( unsigned int pc )
{
unsigned int ra;
uart_init();
hexstring(0x12345678);
hexstring(0x87654321);
hexstring(pc);
while(1)
{
ra=uart_recv();
if(ra==0x0D) uart_send(0x0A);
uart_send(ra);
}
return(0);
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
//
// Copyright (c) 2012 David Welch dwelch@dwelch.com
//
// 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.
//
//-------------------------------------------------------------------------

43
aarch64/uart02/vectors.s Normal file
View File

@@ -0,0 +1,43 @@
.globl _start
_start:
mrs x0,mpidr_el1
mov x1,#0xC1000000
bic x0,x0,x1
cbz x0,master
b hang
master:
mov sp,#0x8000
bl skip
skip:
mov x0,x30
bl notmain
hang: b hang
.globl PUT32
PUT32:
str w1,[x0]
ret
.globl GET32
GET32:
ldr w0,[x0]
ret
.globl dummy
dummy:
ret
//-------------------------------------------------------------------------
//
// Copyright (c) 2012 David Welch dwelch@dwelch.com
//
// 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.
//
//-------------------------------------------------------------------------