├── README ├── TOOLCHAIN ├── armjtag ├── Makefile ├── README ├── ft232h.cfg ├── jlink.cfg ├── memmap ├── notmain.c ├── raspi.cfg └── vectors.s ├── blinker01 ├── Makefile ├── README ├── kernel.img ├── memmap ├── notmain.c ├── notmain.elf ├── notmain.list ├── notmain.o ├── notmain.srec ├── vectors.o └── vectors.s ├── blinker02 ├── Makefile ├── README ├── memmap ├── notmain.c └── vectors.s ├── blinker03 ├── Makefile ├── README ├── memmap ├── notmain.c └── vectors.s ├── blinker04 ├── Makefile ├── README ├── memmap ├── notmain.c └── vectors.s ├── blinker05 ├── Makefile ├── README ├── memmap ├── notmain.c └── vectors.s ├── bootloader.img ├── bootloader10 ├── Makefile ├── README ├── loader ├── notmain.c ├── periph.c └── vectors.s ├── bootstrap ├── Makefile ├── README ├── bootstrap.s ├── bootstrap.txt ├── memmap ├── notmain.c ├── periph.c └── start.s ├── float01 ├── Makefile ├── README ├── fun.c ├── memmap ├── notmain.c ├── periph.c └── start.s ├── heartbeat ├── Makefile ├── README ├── memmap ├── notmain.c └── vectors.s ├── kernel.img ├── mmu ├── Makefile ├── README ├── coarse_translation.ps ├── memmap ├── notmain.c ├── novectors.s ├── periph.c ├── section_translation.ps └── start.s ├── mysetup.png ├── reset_switch1.jpg ├── reset_switch2.jpg ├── swi00 ├── Makefile ├── README ├── memmap ├── notmain.c ├── periph.c └── start.s ├── uart01 ├── Makefile ├── README ├── memmap ├── notmain.c └── vectors.s ├── uart02 ├── Makefile ├── README ├── memmap ├── notmain.c └── vectors.s ├── uart03 ├── Makefile ├── README ├── memmap ├── notmain.c └── vectors.s ├── uart04 ├── Makefile ├── README ├── memmap ├── notmain.c └── vectors.s └── uart05 ├── Makefile ├── README ├── memmap ├── notmain.c ├── periph.c └── start.s /TOOLCHAIN: -------------------------------------------------------------------------------- 1 | 2 | I run on linux, these examples are tested on linux, other than subtle 3 | differences like rm vs del in the Makefile, you should be able to use 4 | these examples on a windows or mac system. 5 | 6 | My code is written to be somewhat generic, but the assembly and in 7 | particular the linker script are specific to the gnu tools because 8 | that is how the toolchain world works unfortunately. Since everyone 9 | can get the gnu tools, they are available for Windows, Mac and Linux, 10 | but not everyone can or wants to use the pay-for tools (or free tools 11 | that are specific to one operating system) these examples are written 12 | and tested using a gnu tool chain. 13 | 14 | My personal style is such that this code tends to port across the 15 | various versions of the gnu tools also it is not specific to 16 | arm-none-eabi, arm-none-gnueabi, arm-linux-gnueabi and so on (I will 17 | often type arm-whatever- to indicate these and other flavors). You 18 | may need to change the ARMGNU line at the top of my Makefile though. 19 | 20 | So, if you are running Ubuntu Linux or a derivative you might only 21 | need to do this: 22 | 23 | apt-get install gcc-arm-linux-gnueabi binutils-arm-linux-gnueabi 24 | 25 | I am told Fedora has a similar one that you can easily install. 26 | 27 | Or you can go here and get a pre-built for your operating system 28 | 29 | https://launchpad.net/gcc-arm-embedded 30 | (which has now moved to an arm site directly) 31 | https://developer.arm.com/open-source/gnu-toolchain/gnu-rm 32 | 33 | Linaro is another well known builder of gnu tools you can download, 34 | they have a bare-metal (with a dash, same same, baremetal, bare metal, 35 | bare-metal) arm-eabi one you can download and use 36 | 37 | https://www.linaro.org/downloads/ 38 | 39 | Or in another one of my github repositories you can get a build_arm 40 | script 41 | 42 | https://github.com/dwelch67/build_gcc 43 | 44 | Which builds a cross compiler from sources. Here again tested on 45 | Linux (Ubuntu derivative) I used to use prior versions of this 46 | script on Windows, but I gave up on maintaining that...This latter 47 | build from the script is what I use as my daily driver arm toolchain. 48 | And I tend to stay on the cutting edge using the latest release. 49 | 50 | Easier to come by but you can also get the llvm/clang toolchain as 51 | an alternate compiler, it is not like gcc, one toolchain supports 52 | all targets (normally). For a few versions now llc will build to 53 | object so you dont need an assembler which I used to use binutils for 54 | but now still use binutils to link. I very rarely use clang/llvm 55 | now because they change the command line options every version and 56 | I am tired of trying to keep up. You can just apt-get it as it is a 57 | cross compiler, but I have been known to maintain my build_llvm script 58 | in the above github repo. 59 | -------------------------------------------------------------------------------- /armjtag/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | AOPS = --warn --fatal-warnings 6 | COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding 7 | 8 | all : kernel.img 9 | 10 | clean : 11 | rm -f *.o 12 | rm -f *.bin 13 | rm -f *.hex 14 | rm -f *.srec 15 | rm -f *.elf 16 | rm -f *.list 17 | rm -f *.img 18 | 19 | vectors.o : vectors.s 20 | $(ARMGNU)-as $(AOPS) vectors.s -o vectors.o 21 | 22 | notmain.o : notmain.c 23 | $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o 24 | 25 | notmain.elf : memmap vectors.o notmain.o 26 | $(ARMGNU)-ld vectors.o notmain.o -T memmap -o notmain.elf 27 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 28 | 29 | kernel.img : notmain.elf 30 | $(ARMGNU)-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 31 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 32 | 33 | -------------------------------------------------------------------------------- /armjtag/README: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /armjtag/ft232h.cfg: -------------------------------------------------------------------------------- 1 | # 2 | # FTDI FT4232H Mini Module 3 | # 4 | 5 | interface ft2232 6 | #ft2232_device_desc "FT4232H MiniModule" 7 | ft2232_layout "flyswatter" 8 | ft2232_vid_pid 0x0403 0x6014 9 | 10 | #D0 TCK 11 | #D1 TDI 12 | #D2 TDO 13 | #D3 TMS 14 | #D4 TRST (flyswatter) 15 | -------------------------------------------------------------------------------- /armjtag/jlink.cfg: -------------------------------------------------------------------------------- 1 | # 2 | # Segger J-Link 3 | # 4 | # http://www.segger.com/jlink.html 5 | # 6 | 7 | interface jlink 8 | 9 | -------------------------------------------------------------------------------- /armjtag/memmap: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x10000 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | .bss : { *(.bss*) } > ram 11 | } 12 | -------------------------------------------------------------------------------- /armjtag/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------------- 3 | //------------------------------------------------------------------------- 4 | 5 | extern void PUT32 ( unsigned int, unsigned int ); 6 | extern unsigned int GET32 ( unsigned int ); 7 | extern void dummy ( unsigned int ); 8 | 9 | #define ARM_TIMER_LOD 0x2000B400 10 | #define ARM_TIMER_VAL 0x2000B404 11 | #define ARM_TIMER_CTL 0x2000B408 12 | #define ARM_TIMER_DIV 0x2000B41C 13 | #define ARM_TIMER_CNT 0x2000B420 14 | 15 | #define SYSTIMERCLO 0x20003004 16 | #define GPFSEL0 0x20200000 17 | #define GPFSEL1 0x20200004 18 | #define GPFSEL2 0x20200008 19 | #define GPFSEL3 0x2020000C 20 | #define GPFSEL4 0x20200010 21 | #define GPSET0 0x2020001C 22 | #define GPSET1 0x20200020 23 | #define GPCLR0 0x20200028 24 | #define GPCLR1 0x2020002C 25 | #define GPPUD 0x20200094 26 | #define GPPUDCLK0 0x20200098 27 | 28 | #define TIMEOUT 1000000 29 | 30 | //------------------------------------------------------------------------- 31 | int notmain ( void ) 32 | { 33 | unsigned int ra; 34 | unsigned int rb; 35 | 36 | //for led 37 | 38 | ra=GET32(GPFSEL4); 39 | ra&=~(7<<21); 40 | ra|=1<<21; 41 | PUT32(GPFSEL4,ra); 42 | 43 | //for jtag 44 | 45 | //alt4 = 0b011 3 46 | //alt5 = 0b010 2 47 | 48 | //PUT32(GPPUD,0); 49 | //for(ra=0;ra<150;ra++) dummy(ra); 50 | //PUT32(GPPUDCLK0,(1<<4)|(1<<22)|(1<<24)|(1<<25)|(1<<27)); 51 | //for(ra=0;ra<150;ra++) dummy(ra); 52 | //PUT32(GPPUDCLK0,0); 53 | 54 | //ra=GET32(GPFSEL0); 55 | //ra&=~(7<<12); //gpio4 56 | //ra|=2<<12; //gpio4 alt5 ARM_TDI 57 | //PUT32(GPFSEL0,ra); 58 | 59 | ra=GET32(GPFSEL2); 60 | ra&=~(7<<6); //gpio22 61 | ra|= 3<<6; //alt4 ARM_TRST 62 | ra&=~(7<<12); //gpio24 63 | ra|= 3<<12; //alt4 ARM_TDO 64 | ra&=~(7<<15); //gpio25 65 | ra|= 3<<15; //alt4 ARM_TCK 66 | ra&=~(7<<18); //gpio26 67 | ra|= 3<<18; //alt4 ARM_TDI 68 | ra&=~(7<<21); //gpio27 69 | ra|= 3<<21; //alt4 ARM_TMS 70 | PUT32(GPFSEL2,ra); 71 | 72 | //ARM_TCK D0 P1-22 OUT (25 ALT4) 73 | //ARM_TDI D1 P1-37 IN (26 ALT4) 74 | //ARM_TDO D2 P1-18 OUT (24 ALT4) 75 | //ARM_TMS D3 P1-13 OUT (27 ALT4) 76 | //ARM_TRST D4 P1-15 IN (22 ALT4) 77 | //ARM_GND GND P1-39 78 | 79 | PUT32(ARM_TIMER_CTL,0x00F90000); 80 | PUT32(ARM_TIMER_CTL,0x00F90200); 81 | 82 | rb=GET32(ARM_TIMER_CNT); 83 | while(1) 84 | { 85 | PUT32(GPSET1,1<<(47-32)); 86 | while(1) 87 | { 88 | ra=GET32(ARM_TIMER_CNT); 89 | if((ra-rb)>=TIMEOUT) break; 90 | } 91 | rb+=TIMEOUT; 92 | PUT32(GPCLR1,1<<(47-32)); 93 | while(1) 94 | { 95 | ra=GET32(ARM_TIMER_CNT); 96 | if((ra-rb)>=TIMEOUT) break; 97 | } 98 | rb+=TIMEOUT; 99 | } 100 | return(0); 101 | } 102 | //------------------------------------------------------------------------- 103 | //------------------------------------------------------------------------- 104 | 105 | 106 | //------------------------------------------------------------------------- 107 | // 108 | // Copyright (c) 2012 David Welch dwelch@dwelch.com 109 | // 110 | // 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: 111 | // 112 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 113 | // 114 | // 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. 115 | // 116 | //------------------------------------------------------------------------- 117 | -------------------------------------------------------------------------------- /armjtag/raspi.cfg: -------------------------------------------------------------------------------- 1 | 2 | # Broadcom 2835 on Raspberry Pi 3 | 4 | telnet_port 4444 5 | #gdb_port 0 6 | #tcl_port 0 7 | 8 | #jtag_khz 1000 9 | adapter_khz 1000 10 | 11 | #jtag_nsrst_delay 400 12 | #jtag_ntrst_delay 400 13 | 14 | if { [info exists CHIPNAME] } { 15 | set _CHIPNAME $CHIPNAME 16 | } else { 17 | set _CHIPNAME raspi 18 | } 19 | 20 | reset_config none 21 | 22 | if { [info exists CPU_TAPID ] } { 23 | set _CPU_TAPID $CPU_TAPID 24 | } else { 25 | set _CPU_TAPID 0x07b7617F 26 | } 27 | jtag newtap $_CHIPNAME arm -irlen 5 -expected-id $_CPU_TAPID 28 | 29 | set _TARGETNAME $_CHIPNAME.arm 30 | target create $_TARGETNAME arm11 -chain-position $_TARGETNAME 31 | 32 | -------------------------------------------------------------------------------- /armjtag/vectors.s: -------------------------------------------------------------------------------- 1 | 2 | ;@ ------------------------------------------------------------------ 3 | ;@ ------------------------------------------------------------------ 4 | 5 | .globl _start 6 | _start: 7 | mov sp,#0x8000 8 | bl notmain 9 | hang: b hang 10 | 11 | .globl PUT32 12 | PUT32: 13 | str r1,[r0] 14 | bx lr 15 | 16 | .globl GET32 17 | GET32: 18 | ldr r0,[r0] 19 | bx lr 20 | 21 | .globl dummy 22 | dummy: 23 | bx lr 24 | 25 | ;@------------------------------------------------------------------------- 26 | ;@------------------------------------------------------------------------- 27 | 28 | 29 | ;@------------------------------------------------------------------------- 30 | ;@ 31 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 32 | ;@ 33 | ;@ 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: 34 | ;@ 35 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 36 | ;@ 37 | ;@ 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. 38 | ;@ 39 | ;@------------------------------------------------------------------------- 40 | -------------------------------------------------------------------------------- /blinker01/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | AOPS = --warn --fatal-warnings 6 | COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding 7 | 8 | all : kernel.img 9 | 10 | clean : 11 | rm -f *.o 12 | rm -f *.bin 13 | rm -f *.hex 14 | rm -f *.srec 15 | rm -f *.elf 16 | rm -f *.list 17 | rm -f *.img 18 | 19 | vectors.o : vectors.s 20 | $(ARMGNU)-as $(AOPS) vectors.s -o vectors.o 21 | 22 | notmain.o : notmain.c 23 | $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o 24 | 25 | notmain.elf : memmap vectors.o notmain.o 26 | $(ARMGNU)-ld vectors.o notmain.o -T memmap -o notmain.elf 27 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 28 | 29 | kernel.img : notmain.elf 30 | $(ARMGNU)-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 31 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 32 | 33 | -------------------------------------------------------------------------------- /blinker01/README: -------------------------------------------------------------------------------- 1 | 2 | See the top level README for information on where to find documentation 3 | for the raspberry pi and the ARM processor inside. Also find information 4 | on how to load and run these programs. 5 | 6 | This is an LED blinker example for the pi zero. 7 | 8 | The pi zero has one led that is tied to gpio 47. 9 | 10 | Being the first example I will spend a little more time describing it. 11 | I have some other ramblings on baremetal and the gnu tools so I will 12 | try not to duplicate that. 13 | 14 | The primary use case for the raspberry pi is to run some version of 15 | linux. The three main files to do that are bootloader.bin, start.elf 16 | and kernel.img. The first two being GPU programs the last being ARM. 17 | If you have no other files (dont have a config.txt) they (starg.elf 18 | GPU code) copy the kernel.img file to 0x8000 in RAM, place some 19 | code at address 0x0000 that is intended to prepare the ARM for booting 20 | linux, then branch to 0x8000. We simply replace the kernel.img file 21 | with our own program. I prefer to not mess with config.txt stuff 22 | because it is not the primary use case, most pis out there do not use 23 | this, so without is significantly better tested. Also over time the 24 | config.txt things you can play with come and go and change name, some 25 | of the popular ones are undocumented and so on. So I really dont want 26 | to rely on that. Simply replace the kernel.img and otherwise be stock. 27 | 28 | vectors.s is the entry point for this program, even an application on 29 | an operating system like linux has some assembly up front before 30 | calling the main function. For this processor the minimum is to to 31 | set up the stack pointer and call the main function. Because some 32 | compilers add extra stuff if they see a main() funtion I use some 33 | function name other than main() typically for embedded systems like this. 34 | I have adopted the habit of using notmain() both to not be named main() 35 | and to emphasize this is bare metal and not your average application. 36 | 37 | See my ramblings on .data and .bss, I dont need/use them so the 38 | bootstrap (little bit of assembly before calling the first C function) 39 | does not have to prepare those segments. I only need to setup the 40 | stack and call the first C function in the project. 41 | 42 | I normally would set the stack pointer at the top of ram...Well that is 43 | a lie, normaly one would do such a thing, but with code like this that 44 | mostly ports across a number of boards, it becomes a pain keeping track 45 | of who has how much ram. Instead for simple examples I set the stack 46 | somewhere where it doesnt collide with the code, but also I dont have to 47 | change every board. Because I am using the 0x8000 entry point I can 48 | set the stack at 0x8000 and it will grow down toward 0x0000, and that 49 | is more than enough for these projects. The way the ARM works it 50 | subtracts then writes stuff so the first thing on the stack will really 51 | be at 0x7FFC, you dont have to set it to 0x7FFC to avoid the code at 52 | 0x8000. 53 | 54 | The gpio pin is setup as an output to drive the LED. The blink rate 55 | appears to be around a couple-three times a second, but may vary based 56 | on your compiler and settings. This program does not attempt to use 57 | any other peripherals (a timer) it relies on simply wasting time in a 58 | loop then changing the state of the LED. If you were to use this line 59 | of code: 60 | 61 | for(ra=0;ra<0x1000;ra++) continue; 62 | 63 | The optimizer will replace that with this one assignment: 64 | 65 | ra = 0x1000; 66 | 67 | And actually since that value isnt used again, it is dead code the 68 | optimizer will likely remove that as well. 69 | 70 | One way to get around this is to make the loop variable volatile, this 71 | tells the compiler every time you use it grab it from and save it back 72 | to its home in ram. I prefer a different approach. I have a simple 73 | dummy function in assembly language, it simply returns. 74 | 75 | .globl dummy 76 | dummy: 77 | bx lr 78 | 79 | The assembly is outside the visibility of the optimizer as would 80 | anything basically not in the same file (llvm is a little different it 81 | might "see" those other objects and optimize across them, gnu wont). 82 | 83 | So by having that external function and by passing the loop variable 84 | to it. 85 | 86 | for(ra=0;ra<0x1000;ra++) dummy(ra); 87 | 88 | We force the compiler to actually implement this code and run that loop 89 | that many times. Dont need to declare the variable volatile. If 90 | uncomfortable with assembly langauge you could create a dummy function 91 | in a separately compiled file 92 | 93 | void dummy ( void ) 94 | { 95 | } 96 | 97 | Which produces the same code. 98 | 99 | 00000000 : 100 | 0: e12fff1e bx lr 101 | 102 | Some toolchains have the ability to see across objects when they 103 | optimize so you still have to be careful. I prefer the assembly approach 104 | to defeating the optimizer. 105 | 106 | So this program sets up the gpio to drive the LED. Uses the loop to kill 107 | some time, changes state of the LED, repeat forever. The blink rate 108 | will be the same for the same program. But compiler differences and 109 | options can cause one build to be different from another in the blink 110 | rate. It is not really deterministic, thus the desire to use timers in 111 | the examples that follow. If you change the number the loop counts to 112 | and re-build with the same tools, you should see a change in the 113 | blink rate. 114 | 115 | Note the Broadcom documentation uses addresses 0x7Exxxxxx for the 116 | peripherals. That is we assume the GPU's address space to access those 117 | things. The ARM window into that is to date either at 0x20xxxxxx or 118 | 0x3Fxxxxxx depending on the specific broadcom chip for that board type 119 | the pi zero uses 0x20xxxxxx so when you se 0x7Exxxxxx replace that 120 | 0x7E with 0x20. 121 | 122 | I normally dont leave the compiled output in the repository, but you 123 | may need it to compare with your results to see why for example mine 124 | works and yours doesnt, so I will leave these here for this example. 125 | 126 | 127 | -------------------------------------------------------------------------------- /blinker01/kernel.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwelch67/raspberrypi-zero/1e8bb7889d57c7bd07b8fb52f06345a5d5d3fa83/blinker01/kernel.img -------------------------------------------------------------------------------- /blinker01/memmap: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x10000 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | .bss : { *(.bss*) } > ram 11 | } 12 | -------------------------------------------------------------------------------- /blinker01/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------------- 3 | //------------------------------------------------------------------------- 4 | 5 | extern void PUT32 ( unsigned int, unsigned int ); 6 | extern unsigned int GET32 ( unsigned int ); 7 | extern void dummy ( unsigned int ); 8 | 9 | #define GPFSEL3 0x2020000C 10 | #define GPFSEL4 0x20200010 11 | #define GPSET1 0x20200020 12 | #define GPCLR1 0x2020002C 13 | 14 | //------------------------------------------------------------------------- 15 | int notmain ( void ) 16 | { 17 | unsigned int ra; 18 | 19 | ra=GET32(GPFSEL4); 20 | ra&=~(7<<21); 21 | ra|=1<<21; 22 | PUT32(GPFSEL4,ra); 23 | 24 | while(1) 25 | { 26 | PUT32(GPSET1,1<<(47-32)); 27 | for(ra=0;ra<0x100000;ra++) dummy(ra); 28 | PUT32(GPCLR1,1<<(47-32)); 29 | for(ra=0;ra<0x100000;ra++) dummy(ra); 30 | } 31 | 32 | return(0); 33 | } 34 | //------------------------------------------------------------------------- 35 | //------------------------------------------------------------------------- 36 | 37 | 38 | //------------------------------------------------------------------------- 39 | // 40 | // Copyright (c) 2015 David Welch dwelch@dwelch.com 41 | // 42 | // 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: 43 | // 44 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 45 | // 46 | // 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. 47 | // 48 | //------------------------------------------------------------------------- 49 | -------------------------------------------------------------------------------- /blinker01/notmain.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwelch67/raspberrypi-zero/1e8bb7889d57c7bd07b8fb52f06345a5d5d3fa83/blinker01/notmain.elf -------------------------------------------------------------------------------- /blinker01/notmain.list: -------------------------------------------------------------------------------- 1 | 2 | notmain.elf: file format elf32-littlearm 3 | 4 | 5 | Disassembly of section .text: 6 | 7 | 00008000 <_start>: 8 | 8000: e3a0d902 mov sp, #32768 ; 0x8000 9 | 8004: eb000005 bl 8020 10 | 11 | 00008008 : 12 | 8008: eafffffe b 8008 13 | 14 | 0000800c : 15 | 800c: e5801000 str r1, [r0] 16 | 8010: e12fff1e bx lr 17 | 18 | 00008014 : 19 | 8014: e5900000 ldr r0, [r0] 20 | 8018: e12fff1e bx lr 21 | 22 | 0000801c : 23 | 801c: e12fff1e bx lr 24 | 25 | 00008020 : 26 | 8020: e92d4010 push {r4, lr} 27 | 8024: e59f005c ldr r0, [pc, #92] ; 8088 28 | 8028: ebfffff9 bl 8014 29 | 802c: e3c0160e bic r1, r0, #14680064 ; 0xe00000 30 | 8030: e3811602 orr r1, r1, #2097152 ; 0x200000 31 | 8034: e59f004c ldr r0, [pc, #76] ; 8088 32 | 8038: ebfffff3 bl 800c 33 | 803c: e59f0048 ldr r0, [pc, #72] ; 808c 34 | 8040: e3a01902 mov r1, #32768 ; 0x8000 35 | 8044: ebfffff0 bl 800c 36 | 8048: e3a04000 mov r4, #0 37 | 804c: e1a00004 mov r0, r4 38 | 8050: e2844001 add r4, r4, #1 39 | 8054: ebfffff0 bl 801c 40 | 8058: e3540601 cmp r4, #1048576 ; 0x100000 41 | 805c: 1afffffa bne 804c 42 | 8060: e59f0028 ldr r0, [pc, #40] ; 8090 43 | 8064: e3a01902 mov r1, #32768 ; 0x8000 44 | 8068: ebffffe7 bl 800c 45 | 806c: e3a04000 mov r4, #0 46 | 8070: e1a00004 mov r0, r4 47 | 8074: e2844001 add r4, r4, #1 48 | 8078: ebffffe7 bl 801c 49 | 807c: e3540601 cmp r4, #1048576 ; 0x100000 50 | 8080: 1afffffa bne 8070 51 | 8084: eaffffec b 803c 52 | 8088: 20200010 eorcs r0, r0, r0, lsl r0 53 | 808c: 20200020 eorcs r0, r0, r0, lsr #32 54 | 8090: 2020002c eorcs r0, r0, ip, lsr #32 55 | 56 | Disassembly of section .ARM.attributes: 57 | 58 | 00000000 <.ARM.attributes>: 59 | 0: 00002a41 andeq r2, r0, r1, asr #20 60 | 4: 61656100 cmnvs r5, r0, lsl #2 61 | 8: 01006962 tsteq r0, r2, ror #18 62 | c: 00000020 andeq r0, r0, r0, lsr #32 63 | 10: 4d524105 ldfmie f4, [r2, #-20] ; 0xffffffec 64 | 14: 54347620 ldrtpl r7, [r4], #-1568 ; 0xfffff9e0 65 | 18: 08020600 stmdaeq r2, {r9, sl} 66 | 1c: 12010901 andne r0, r1, #16384 ; 0x4000 67 | 20: 15011404 strne r1, [r1, #-1028] ; 0xfffffbfc 68 | 24: 18031701 stmdane r3, {r0, r8, r9, sl, ip} 69 | 28: Address 0x0000000000000028 is out of bounds. 70 | 71 | 72 | Disassembly of section .comment: 73 | 74 | 00000000 <.comment>: 75 | 0: 3a434347 bcc 10d0d24 76 | 4: 35312820 ldrcc r2, [r1, #-2080]! ; 0xfffff7e0 77 | 8: 392e343a stmdbcc lr!, {r1, r3, r4, r5, sl, ip, sp} 78 | c: 732b332e ; instruction: 0x732b332e 79 | 10: 33326e76 teqcc r2, #1888 ; 0x760 80 | 14: 37373131 ; instruction: 0x37373131 81 | 18: 2029312d eorcs r3, r9, sp, lsr #2 82 | 1c: 2e392e34 mrccs 14, 1, r2, cr9, cr4, {1} 83 | 20: 30322033 eorscc r2, r2, r3, lsr r0 84 | 24: 35303531 ldrcc r3, [r0, #-1329]! ; 0xfffffacf 85 | 28: 28203932 stmdacs r0!, {r1, r4, r5, r8, fp, ip, sp} 86 | 2c: 72657270 rsbvc r7, r5, #112, 4 87 | 30: 61656c65 cmnvs r5, r5, ror #24 88 | 34: 00296573 eoreq r6, r9, r3, ror r5 89 | -------------------------------------------------------------------------------- /blinker01/notmain.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwelch67/raspberrypi-zero/1e8bb7889d57c7bd07b8fb52f06345a5d5d3fa83/blinker01/notmain.o -------------------------------------------------------------------------------- /blinker01/notmain.srec: -------------------------------------------------------------------------------- 1 | S00F00006E6F746D61696E2E737265631F 2 | S3150000800002D9A0E3050000EBFEFFFFEA001080E5C1 3 | S315000080101EFF2FE1000090E51EFF2FE11EFF2FE15E 4 | S3150000802010402DE95C009FE5F9FFFFEB0E16C0E35B 5 | S31500008030021681E34C009FE5F3FFFFEB48009FE546 6 | S315000080400219A0E3F0FFFFEB0040A0E30400A0E16B 7 | S31500008050014084E2F0FFFFEB010654E3FAFFFF1A4A 8 | S3150000806028009FE50219A0E3E7FFFFEB0040A0E32D 9 | S315000080700400A0E1014084E2E7FFFFEB010654E3C0 10 | S31500008080FAFFFF1AECFFFFEA100020202000202054 11 | S309000080902C0020207A 12 | S705000080007A 13 | -------------------------------------------------------------------------------- /blinker01/vectors.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwelch67/raspberrypi-zero/1e8bb7889d57c7bd07b8fb52f06345a5d5d3fa83/blinker01/vectors.o -------------------------------------------------------------------------------- /blinker01/vectors.s: -------------------------------------------------------------------------------- 1 | 2 | ;@ ------------------------------------------------------------------ 3 | ;@ ------------------------------------------------------------------ 4 | 5 | .globl _start 6 | _start: 7 | mov sp,#0x8000 8 | bl notmain 9 | hang: b hang 10 | 11 | .globl PUT32 12 | PUT32: 13 | str r1,[r0] 14 | bx lr 15 | 16 | .globl GET32 17 | GET32: 18 | ldr r0,[r0] 19 | bx lr 20 | 21 | .globl dummy 22 | dummy: 23 | bx lr 24 | 25 | ;@------------------------------------------------------------------------- 26 | ;@------------------------------------------------------------------------- 27 | 28 | 29 | ;@------------------------------------------------------------------------- 30 | ;@ 31 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 32 | ;@ 33 | ;@ 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: 34 | ;@ 35 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 36 | ;@ 37 | ;@ 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. 38 | ;@ 39 | ;@------------------------------------------------------------------------- 40 | -------------------------------------------------------------------------------- /blinker02/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | AOPS = --warn --fatal-warnings 6 | COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding 7 | 8 | all : kernel.img 9 | 10 | clean : 11 | rm -f *.o 12 | rm -f *.bin 13 | rm -f *.hex 14 | rm -f *.srec 15 | rm -f *.elf 16 | rm -f *.list 17 | rm -f *.img 18 | 19 | vectors.o : vectors.s 20 | $(ARMGNU)-as $(AOPS) vectors.s -o vectors.o 21 | 22 | notmain.o : notmain.c 23 | $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o 24 | 25 | notmain.elf : memmap vectors.o notmain.o 26 | $(ARMGNU)-ld vectors.o notmain.o -T memmap -o notmain.elf 27 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 28 | 29 | kernel.img : notmain.elf 30 | $(ARMGNU)-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 31 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 32 | 33 | -------------------------------------------------------------------------------- /blinker02/README: -------------------------------------------------------------------------------- 1 | 2 | See the top level README for information on where to find documentation 3 | for the raspberry pi and the ARM processor inside. Also find information 4 | on how to load and run these programs. 5 | 6 | This example is for the pi zero 7 | 8 | There is a free-running 64 bit timer, super easy to use, just read it. 9 | 10 | //0x01000000 17 seconds 11 | //0x00400000 4 seconds 12 | //#define TIMER_BIT 0x01000000 13 | #define TIMER_BIT 0x00400000 14 | 15 | There is a 250MHz system clock, my guess is this is divided by 256 to 16 | get 977KHz. 0x01000000 ticks would be 17.18 seconds, I am using a 17 | watch with a second hand to measure this. Seems plausible that is 18 | what is going on with this timer. 19 | 20 | Can change the TIMER_BIT to a different one to change the blink rate 21 | of the LED for example try: 22 | 23 | #define TIMER_BIT 0x00100000 24 | 25 | -------------------------------------------------------------------------------- /blinker02/memmap: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x1000 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | .bss : { *(.bss*) } > ram 11 | } 12 | -------------------------------------------------------------------------------- /blinker02/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------- 3 | //------------------------------------------------------------------- 4 | 5 | extern void PUT32 ( unsigned int, unsigned int ); 6 | extern unsigned int GET32 ( unsigned int ); 7 | extern void dummy ( unsigned int ); 8 | 9 | #define SYSTIMERCLO 0x20003004 10 | #define GPFSEL3 0x2020000C 11 | #define GPFSEL4 0x20200010 12 | #define GPSET1 0x20200020 13 | #define GPCLR1 0x2020002C 14 | 15 | //0x01000000 17 seconds 16 | //0x00400000 4 seconds 17 | //#define TIMER_BIT 0x01000000 18 | #define TIMER_BIT 0x00400000 19 | 20 | //------------------------------------------------------------------- 21 | int notmain ( void ) 22 | { 23 | unsigned int ra; 24 | 25 | ra=GET32(GPFSEL4); 26 | ra&=~(7<<21); 27 | ra|=1<<21; 28 | PUT32(GPFSEL4,ra); 29 | 30 | while(1) 31 | { 32 | PUT32(GPSET1,1<<(47-32)); 33 | while(1) 34 | { 35 | ra=GET32(SYSTIMERCLO); 36 | if((ra&=TIMER_BIT)==TIMER_BIT) break; 37 | } 38 | PUT32(GPCLR1,1<<(47-32)); 39 | while(1) 40 | { 41 | ra=GET32(SYSTIMERCLO); 42 | if((ra&=TIMER_BIT)==0) break; 43 | } 44 | } 45 | return(0); 46 | } 47 | //------------------------------------------------------------------- 48 | //------------------------------------------------------------------- 49 | 50 | //------------------------------------------------------------------- 51 | // 52 | // Copyright (c) 2012 David Welch dwelch@dwelch.com 53 | // 54 | // 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: 55 | // 56 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 57 | // 58 | // 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. 59 | // 60 | //------------------------------------------------------------------- 61 | -------------------------------------------------------------------------------- /blinker02/vectors.s: -------------------------------------------------------------------------------- 1 | 2 | ;@ ------------------------------------------------------------------ 3 | ;@ ------------------------------------------------------------------ 4 | 5 | .globl _start 6 | _start: 7 | mov sp,#0x8000 8 | bl notmain 9 | hang: b hang 10 | 11 | .globl PUT32 12 | PUT32: 13 | str r1,[r0] 14 | bx lr 15 | 16 | .globl GET32 17 | GET32: 18 | ldr r0,[r0] 19 | bx lr 20 | 21 | .globl dummy 22 | dummy: 23 | bx lr 24 | 25 | ;@ ------------------------------------------------------------------ 26 | ;@ ------------------------------------------------------------------ 27 | 28 | 29 | ;@------------------------------------------------------------------------- 30 | ;@ 31 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 32 | ;@ 33 | ;@ 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: 34 | ;@ 35 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 36 | ;@ 37 | ;@ 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. 38 | ;@ 39 | ;@------------------------------------------------------------------------- 40 | -------------------------------------------------------------------------------- /blinker03/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | AOPS = --warn --fatal-warnings 6 | COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding 7 | 8 | all : kernel.img 9 | 10 | clean : 11 | rm -f *.o 12 | rm -f *.bin 13 | rm -f *.hex 14 | rm -f *.srec 15 | rm -f *.elf 16 | rm -f *.list 17 | rm -f *.img 18 | 19 | vectors.o : vectors.s 20 | $(ARMGNU)-as $(AOPS) vectors.s -o vectors.o 21 | 22 | notmain.o : notmain.c 23 | $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o 24 | 25 | notmain.elf : memmap vectors.o notmain.o 26 | $(ARMGNU)-ld vectors.o notmain.o -T memmap -o notmain.elf 27 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 28 | 29 | kernel.img : notmain.elf 30 | $(ARMGNU)-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 31 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 32 | 33 | -------------------------------------------------------------------------------- /blinker03/README: -------------------------------------------------------------------------------- 1 | 2 | See the top level README for information on where to find documentation 3 | for the raspberry pi and the ARM processor inside. Also find information 4 | on how to load and run these programs. 5 | 6 | This example is for the pi zero 7 | 8 | This example uses the free running ARM timer, not the 64 bit system 9 | timer as in blinker02 but the so called ARM timer. In free running mode 10 | which is a little different from blinker04 which uses the timer mode. 11 | 12 | The system clock appears to come up at 250MHz as documented. 13 | 14 | Divide that by 250 to get 1Mhz on this free running ARM timer. 15 | 16 | PUT32(ARM_TIMER_CTL,0x00F90000); 17 | PUT32(ARM_TIMER_CTL,0x00F90200); 18 | 19 | 0xF9 = 250-1 20 | 21 | Then count to four million ticks between LED state changes and the led 22 | will change state every four seconds. 23 | 24 | Count to 20 million, 20 seconds. 25 | -------------------------------------------------------------------------------- /blinker03/memmap: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x1000 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | .bss : { *(.bss*) } > ram 11 | } 12 | -------------------------------------------------------------------------------- /blinker03/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------------- 3 | //------------------------------------------------------------------------- 4 | 5 | extern void PUT32 ( unsigned int, unsigned int ); 6 | extern unsigned int GET32 ( unsigned int ); 7 | extern void dummy ( unsigned int ); 8 | 9 | #define ARM_TIMER_LOD 0x2000B400 10 | #define ARM_TIMER_VAL 0x2000B404 11 | #define ARM_TIMER_CTL 0x2000B408 12 | #define ARM_TIMER_DIV 0x2000B41C 13 | #define ARM_TIMER_CNT 0x2000B420 14 | 15 | #define SYSTIMERCLO 0x20003004 16 | #define GPFSEL1 0x20200004 17 | #define GPSET0 0x2020001C 18 | #define GPCLR0 0x20200028 19 | #define GPFSEL3 0x2020000C 20 | #define GPFSEL4 0x20200010 21 | #define GPSET1 0x20200020 22 | #define GPCLR1 0x2020002C 23 | 24 | //#define TIMEOUT 20000000 25 | #define TIMEOUT 4000000 26 | 27 | //------------------------------------------------------------------------- 28 | int notmain ( void ) 29 | { 30 | unsigned int ra; 31 | unsigned int rb; 32 | 33 | ra=GET32(GPFSEL4); 34 | ra&=~(7<<21); 35 | ra|=1<<21; 36 | PUT32(GPFSEL4,ra); 37 | 38 | PUT32(ARM_TIMER_CTL,0x00F90000); 39 | PUT32(ARM_TIMER_CTL,0x00F90200); 40 | 41 | rb=GET32(ARM_TIMER_CNT); 42 | while(1) 43 | { 44 | PUT32(GPSET1,1<<(47-32)); 45 | while(1) 46 | { 47 | ra=GET32(ARM_TIMER_CNT); 48 | if((ra-rb)>=TIMEOUT) break; 49 | } 50 | rb+=TIMEOUT; 51 | PUT32(GPCLR1,1<<(47-32)); 52 | while(1) 53 | { 54 | ra=GET32(ARM_TIMER_CNT); 55 | if((ra-rb)>=TIMEOUT) break; 56 | } 57 | rb+=TIMEOUT; 58 | } 59 | return(0); 60 | } 61 | //------------------------------------------------------------------------- 62 | //------------------------------------------------------------------------- 63 | 64 | 65 | //------------------------------------------------------------------------- 66 | // 67 | // Copyright (c) 2012 David Welch dwelch@dwelch.com 68 | // 69 | // 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: 70 | // 71 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 72 | // 73 | // 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. 74 | // 75 | //------------------------------------------------------------------------- 76 | -------------------------------------------------------------------------------- /blinker03/vectors.s: -------------------------------------------------------------------------------- 1 | 2 | ;@------------------------------------------------------------------------- 3 | ;@------------------------------------------------------------------------- 4 | 5 | .globl _start 6 | _start: 7 | mov sp,#0x8000 8 | bl notmain 9 | hang: b hang 10 | 11 | .globl PUT32 12 | PUT32: 13 | str r1,[r0] 14 | bx lr 15 | 16 | .globl GET32 17 | GET32: 18 | ldr r0,[r0] 19 | bx lr 20 | 21 | .globl dummy 22 | dummy: 23 | bx lr 24 | 25 | ;@------------------------------------------------------------------------- 26 | ;@------------------------------------------------------------------------- 27 | 28 | ;@------------------------------------------------------------------------- 29 | ;@ 30 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 31 | ;@ 32 | ;@ 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: 33 | ;@ 34 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 35 | ;@ 36 | ;@ 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. 37 | ;@ 38 | ;@------------------------------------------------------------------------- 39 | -------------------------------------------------------------------------------- /blinker04/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | AOPS = --warn --fatal-warnings 6 | COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding 7 | 8 | all : kernel.img 9 | 10 | clean : 11 | rm -f *.o 12 | rm -f *.bin 13 | rm -f *.hex 14 | rm -f *.srec 15 | rm -f *.elf 16 | rm -f *.list 17 | rm -f *.img 18 | 19 | vectors.o : vectors.s 20 | $(ARMGNU)-as $(AOPS) vectors.s -o vectors.o 21 | 22 | notmain.o : notmain.c 23 | $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o 24 | 25 | notmain.elf : memmap vectors.o notmain.o 26 | $(ARMGNU)-ld vectors.o notmain.o -T memmap -o notmain.elf 27 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 28 | 29 | kernel.img : notmain.elf 30 | $(ARMGNU)-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 31 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 32 | 33 | -------------------------------------------------------------------------------- /blinker04/README: -------------------------------------------------------------------------------- 1 | 2 | See the top level README for information on where to find documentation 3 | for the raspberry pi and the ARM processor inside. Also find information 4 | on how to load and run these programs. 5 | 6 | This example is for the pi zero 7 | 8 | This example uses the ARM timer, not in free running mode like blinker03 9 | but the other mode. 10 | 11 | A few more typos in the datasheet. It is an SP804 not AP804 (page 196). 12 | Page 197, bit 1 32 bit counter not 23 bit counter. Page 198 neither 13 | the raw nor masked IRQ registers are at address 0x40C. 14 | 15 | So if you want to poll an arbitrary time with a free running timer you 16 | take a reference count, and then take a sample, wait for the difference 17 | between the sample and reference count. You have to know if it is an 18 | up or down counter. You can turn this timer into a free running timer 19 | by setting the load registers to all ones. What you can also do with 20 | this kind of timer that you cannot with a free runing timer is set the 21 | load registers to some number of ticks (minus 1) and it will roll over 22 | the counter at that rate. Often these kinds of timers have an interrupt 23 | as does this one. And you can poll the interrupt bit without having to 24 | actually configure an interrupt. This example sets the prescaler to 25 | divide by 250. The clock as running here is 250Mhz, so this takes it 26 | down to 1Mhz, 1000000 clocks per second. Now if we set the load registers 27 | to 4 million counts (minus 1) then every 4 million counts at 1 million 28 | per second is 4 seconds. Every 4 seconds the timer interrupt will fire. 29 | Which you can read in the raw irq (not masked) register. Once it is 30 | set you have to write anything to the clear interrupt register. If you 31 | were to set up an interrupt service routine, you would clear that 32 | interrupt in the interrupt handler. 33 | 34 | -------------------------------------------------------------------------------- /blinker04/memmap: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x1000 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | .bss : { *(.bss*) } > ram 11 | } 12 | -------------------------------------------------------------------------------- /blinker04/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------------- 3 | //------------------------------------------------------------------------- 4 | 5 | extern void PUT32 ( unsigned int, unsigned int ); 6 | extern unsigned int GET32 ( unsigned int ); 7 | extern void dummy ( unsigned int ); 8 | 9 | #define ARM_TIMER_LOD 0x2000B400 10 | #define ARM_TIMER_VAL 0x2000B404 11 | #define ARM_TIMER_CTL 0x2000B408 12 | #define ARM_TIMER_CLI 0x2000B40C 13 | #define ARM_TIMER_RIS 0x2000B410 14 | #define ARM_TIMER_MIS 0x2000B414 15 | #define ARM_TIMER_RLD 0x2000B418 16 | #define ARM_TIMER_DIV 0x2000B41C 17 | #define ARM_TIMER_CNT 0x2000B420 18 | 19 | #define SYSTIMERCLO 0x20003004 20 | #define GPFSEL1 0x20200004 21 | #define GPSET0 0x2020001C 22 | #define GPCLR0 0x20200028 23 | #define GPFSEL3 0x2020000C 24 | #define GPFSEL4 0x20200010 25 | #define GPSET1 0x20200020 26 | #define GPCLR1 0x2020002C 27 | 28 | //#define TIMEOUT 20000000 29 | #define TIMEOUT 4000000 30 | 31 | //------------------------------------------------------------------------- 32 | int notmain ( void ) 33 | { 34 | unsigned int ra; 35 | 36 | ra=GET32(GPFSEL4); 37 | ra&=~(7<<21); 38 | ra|=1<<21; 39 | PUT32(GPFSEL4,ra); 40 | 41 | //ra=GET32(GPFSEL3); 42 | //ra&=~(7<<15); 43 | //ra|=1<<15; 44 | //PUT32(GPFSEL3,ra); 45 | 46 | PUT32(ARM_TIMER_CTL,0x003E0000); 47 | PUT32(ARM_TIMER_LOD,TIMEOUT-1); 48 | PUT32(ARM_TIMER_RLD,TIMEOUT-1); 49 | PUT32(ARM_TIMER_DIV,0x000000F9); 50 | PUT32(ARM_TIMER_CLI,0); 51 | PUT32(ARM_TIMER_CTL,0x003E0082); 52 | 53 | while(1) 54 | { 55 | PUT32(GPSET1,1<<(47-32)); 56 | //PUT32(GPCLR1,1<<(35-32)); 57 | while(1) if(GET32(ARM_TIMER_RIS)) break; 58 | PUT32(ARM_TIMER_CLI,0); 59 | PUT32(GPCLR1,1<<(47-32)); 60 | //PUT32(GPSET1,1<<(35-32)); 61 | while(1) if(GET32(ARM_TIMER_RIS)) break; 62 | PUT32(ARM_TIMER_CLI,0); 63 | } 64 | return(0); 65 | } 66 | //------------------------------------------------------------------------- 67 | //------------------------------------------------------------------------- 68 | 69 | 70 | //------------------------------------------------------------------------- 71 | // 72 | // Copyright (c) 2012 David Welch dwelch@dwelch.com 73 | // 74 | // 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: 75 | // 76 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 77 | // 78 | // 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. 79 | // 80 | //------------------------------------------------------------------------- 81 | -------------------------------------------------------------------------------- /blinker04/vectors.s: -------------------------------------------------------------------------------- 1 | 2 | ;@------------------------------------------------------------------------- 3 | ;@------------------------------------------------------------------------- 4 | 5 | .globl _start 6 | _start: 7 | mov sp,#0x8000 8 | bl notmain 9 | hang: b hang 10 | 11 | .globl PUT32 12 | PUT32: 13 | str r1,[r0] 14 | bx lr 15 | 16 | .globl GET32 17 | GET32: 18 | ldr r0,[r0] 19 | bx lr 20 | 21 | .globl dummy 22 | dummy: 23 | bx lr 24 | 25 | ;@------------------------------------------------------------------------- 26 | ;@------------------------------------------------------------------------- 27 | 28 | ;@------------------------------------------------------------------------- 29 | ;@ 30 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 31 | ;@ 32 | ;@ 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: 33 | ;@ 34 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 35 | ;@ 36 | ;@ 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. 37 | ;@ 38 | ;@------------------------------------------------------------------------- 39 | -------------------------------------------------------------------------------- /blinker05/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | AOPS = --warn --fatal-warnings 6 | COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding 7 | 8 | all : kernel.img 9 | 10 | clean : 11 | rm -f *.o 12 | rm -f *.bin 13 | rm -f *.hex 14 | rm -f *.srec 15 | rm -f *.elf 16 | rm -f *.list 17 | rm -f *.img 18 | 19 | vectors.o : vectors.s 20 | $(ARMGNU)-as $(AOPS) vectors.s -o vectors.o 21 | 22 | notmain.o : notmain.c 23 | $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o 24 | 25 | notmain.elf : memmap vectors.o notmain.o 26 | $(ARMGNU)-ld vectors.o notmain.o -T memmap -o notmain.elf 27 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 28 | 29 | kernel.img : notmain.elf 30 | $(ARMGNU)-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 31 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 32 | 33 | -------------------------------------------------------------------------------- /blinker05/memmap: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x1000 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | .bss : { *(.bss*) } > ram 11 | } 12 | -------------------------------------------------------------------------------- /blinker05/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------- 3 | //------------------------------------------------------------------- 4 | 5 | extern void PUT32 ( unsigned int, unsigned int ); 6 | extern unsigned int GET32 ( unsigned int ); 7 | extern void dummy ( unsigned int ); 8 | extern void enable_irq ( void ); 9 | extern void enable_fiq ( void ); 10 | 11 | #define ARM_TIMER_LOD 0x2000B400 12 | #define ARM_TIMER_VAL 0x2000B404 13 | #define ARM_TIMER_CTL 0x2000B408 14 | #define ARM_TIMER_CLI 0x2000B40C 15 | #define ARM_TIMER_RIS 0x2000B410 16 | #define ARM_TIMER_MIS 0x2000B414 17 | #define ARM_TIMER_RLD 0x2000B418 18 | #define ARM_TIMER_DIV 0x2000B41C 19 | #define ARM_TIMER_CNT 0x2000B420 20 | 21 | #define SYSTIMERCLO 0x20003004 22 | #define GPFSEL1 0x20200004 23 | #define GPSET0 0x2020001C 24 | #define GPCLR0 0x20200028 25 | #define GPFSEL3 0x2020000C 26 | #define GPFSEL4 0x20200010 27 | #define GPSET1 0x20200020 28 | #define GPCLR1 0x2020002C 29 | 30 | #define IRQ_BASIC 0x2000B200 31 | #define IRQ_PEND1 0x2000B204 32 | #define IRQ_PEND2 0x2000B208 33 | #define IRQ_FIQ_CONTROL 0x2000B210 34 | #define IRQ_ENABLE_BASIC 0x2000B218 35 | #define IRQ_DISABLE_BASIC 0x2000B224 36 | 37 | volatile unsigned int icount; 38 | 39 | //------------------------------------------------------------------- 40 | void c_irq_handler ( void ) 41 | { 42 | icount++; 43 | if(icount&1) 44 | { 45 | PUT32(GPSET1,1<<(47-32)); 46 | } 47 | else 48 | { 49 | PUT32(GPCLR1,1<<(47-32)); 50 | } 51 | PUT32(ARM_TIMER_CLI,0); 52 | } 53 | //------------------------------------------------------------------- 54 | int notmain ( void ) 55 | { 56 | unsigned int ra; 57 | 58 | PUT32(IRQ_DISABLE_BASIC,1); 59 | 60 | ra=GET32(GPFSEL4); 61 | ra&=~(7<<21); 62 | ra|=1<<21; 63 | PUT32(GPFSEL4,ra); 64 | 65 | PUT32(GPSET1,1<<(47-32)); 66 | 67 | PUT32(ARM_TIMER_CTL,0x003E0000); 68 | PUT32(ARM_TIMER_LOD,1000000-1); 69 | PUT32(ARM_TIMER_RLD,1000000-1); 70 | PUT32(ARM_TIMER_DIV,0x000000F9); 71 | PUT32(ARM_TIMER_CLI,0); 72 | PUT32(ARM_TIMER_CTL,0x003E00A2); 73 | 74 | for(ra=0;ra<2;ra++) 75 | { 76 | PUT32(GPSET1,1<<(47-32)); 77 | while(1) if(GET32(ARM_TIMER_MIS)) break; 78 | PUT32(ARM_TIMER_CLI,0); 79 | PUT32(GPCLR1,1<<(47-32)); 80 | while(1) if(GET32(ARM_TIMER_MIS)) break; 81 | PUT32(ARM_TIMER_CLI,0); 82 | } 83 | 84 | PUT32(ARM_TIMER_CTL,0x003E0000); 85 | PUT32(ARM_TIMER_LOD,2000000-1); 86 | PUT32(ARM_TIMER_RLD,2000000-1); 87 | PUT32(ARM_TIMER_CLI,0); 88 | PUT32(IRQ_ENABLE_BASIC,1); 89 | PUT32(ARM_TIMER_CTL,0x003E00A2); 90 | for(ra=0;ra<3;ra++) 91 | { 92 | PUT32(GPSET1,1<<(47-32)); 93 | while(1) if(GET32(IRQ_BASIC)&1) break; 94 | PUT32(ARM_TIMER_CLI,0); 95 | PUT32(GPCLR1,1<<(47-32)); 96 | while(1) if(GET32(IRQ_BASIC)&1) break; 97 | PUT32(ARM_TIMER_CLI,0); 98 | } 99 | 100 | 101 | PUT32(ARM_TIMER_CTL,0x003E0000); 102 | PUT32(ARM_TIMER_LOD,500000-1); 103 | PUT32(ARM_TIMER_RLD,500000-1); 104 | PUT32(ARM_TIMER_CLI,0); 105 | icount=0; 106 | enable_irq(); 107 | PUT32(ARM_TIMER_CTL,0x003E00A2); 108 | PUT32(ARM_TIMER_CLI,0); 109 | while(1) continue; 110 | return(0); 111 | } 112 | //------------------------------------------------------------------- 113 | //------------------------------------------------------------------- 114 | 115 | //------------------------------------------------------------------- 116 | // 117 | // Copyright (c) 2012 David Welch dwelch@dwelch.com 118 | // 119 | // 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: 120 | // 121 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 122 | // 123 | // 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. 124 | // 125 | //------------------------------------------------------------------- 126 | -------------------------------------------------------------------------------- /blinker05/vectors.s: -------------------------------------------------------------------------------- 1 | 2 | ;@------------------------------------------------------------------------- 3 | ;@------------------------------------------------------------------------- 4 | 5 | .globl _start 6 | _start: 7 | ldr pc,reset_handler 8 | ldr pc,undefined_handler 9 | ldr pc,swi_handler 10 | ldr pc,prefetch_handler 11 | ldr pc,data_handler 12 | ldr pc,unused_handler 13 | ldr pc,irq_handler 14 | ldr pc,fiq_handler 15 | reset_handler: .word reset 16 | undefined_handler: .word hang 17 | swi_handler: .word hang 18 | prefetch_handler: .word hang 19 | data_handler: .word hang 20 | unused_handler: .word hang 21 | irq_handler: .word irq 22 | fiq_handler: .word hang 23 | 24 | reset: 25 | mov r0,#0x8000 26 | mov r1,#0x0000 27 | ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} 28 | stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} 29 | ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} 30 | stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} 31 | 32 | 33 | ;@ (PSR_IRQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) 34 | mov r0,#0xD2 35 | msr cpsr_c,r0 36 | mov sp,#0x8000 37 | 38 | ;@ (PSR_FIQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) 39 | mov r0,#0xD1 40 | msr cpsr_c,r0 41 | mov sp,#0x4000 42 | 43 | ;@ (PSR_SVC_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) 44 | mov r0,#0xD3 45 | msr cpsr_c,r0 46 | mov sp,#0x8000000 47 | 48 | ;@ SVC MODE, IRQ ENABLED, FIQ DIS 49 | ;@mov r0,#0x53 50 | ;@msr cpsr_c, r0 51 | 52 | bl notmain 53 | hang: b hang 54 | 55 | .globl PUT32 56 | PUT32: 57 | str r1,[r0] 58 | bx lr 59 | 60 | .globl GET32 61 | GET32: 62 | ldr r0,[r0] 63 | bx lr 64 | 65 | .globl dummy 66 | dummy: 67 | bx lr 68 | 69 | .globl enable_irq 70 | enable_irq: 71 | mrs r0,cpsr 72 | bic r0,r0,#0x80 73 | msr cpsr_c,r0 74 | bx lr 75 | 76 | irq: 77 | push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} 78 | bl c_irq_handler 79 | pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} 80 | subs pc,lr,#4 81 | 82 | ;@------------------------------------------------------------------------- 83 | ;@------------------------------------------------------------------------- 84 | 85 | ;@------------------------------------------------------------------------- 86 | ;@ 87 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 88 | ;@ 89 | ;@ 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: 90 | ;@ 91 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 92 | ;@ 93 | ;@ 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. 94 | ;@ 95 | ;@------------------------------------------------------------------------- 96 | 97 | -------------------------------------------------------------------------------- /bootloader.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwelch67/raspberrypi-zero/1e8bb7889d57c7bd07b8fb52f06345a5d5d3fa83/bootloader.img -------------------------------------------------------------------------------- /bootloader10/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding 6 | 7 | all : kernel.img 8 | 9 | clean : 10 | rm -f *.o 11 | rm -f *.bin 12 | rm -f *.hex 13 | rm -f *.elf 14 | rm -f *.list 15 | rm -f *.img 16 | 17 | vectors.o : vectors.s 18 | $(ARMGNU)-as vectors.s -o vectors.o 19 | 20 | notmain.o : notmain.c 21 | $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o 22 | 23 | periph.o : periph.c 24 | $(ARMGNU)-gcc $(COPS) -c periph.c -o periph.o 25 | 26 | kernel.img : loader vectors.o periph.o notmain.o 27 | $(ARMGNU)-ld vectors.o periph.o notmain.o -T loader -o notmain.elf 28 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 29 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 30 | 31 | -------------------------------------------------------------------------------- /bootloader10/README: -------------------------------------------------------------------------------- 1 | 2 | See the top level README for information on where to find documentation 3 | for the raspberry pi and the ARM processor inside. Also find information 4 | on how to load and run these programs. 5 | 6 | This example is for the pi zero, see other directories for other flavors 7 | of raspberry pi. 8 | 9 | This is a very simple bootloader. Instead of the sd dance (see 10 | top level README), this makes life a bit simpler and greatly reduces 11 | physical wear and tear on the sd card socket. Do the sd card dance one 12 | more time with this kernel.img. Get some sort of serial solution to 13 | connect a dumb termial program with the ability to download raw/ascii 14 | files. 15 | 16 | The pi zero does not come with pins, you will want/need some way to 17 | make the serial connection, if you can solder and get some header 18 | pins great. If not there are other ways, some pins can be shoved in 19 | rather than soldered. Or balanced if nothing else (stick them in and 20 | lean them to the side so they touch), just dont short anything out. 21 | 22 | On the sd card end of the board the P1 connector pins are like this, 23 | same as other raspberry pi boards, but span the whole length of the 24 | board rather than orentied more toward one corner than another. 25 | 26 | |SD | 12 27 | |CARD| 34 28 | 56 29 | 78 30 | 9. 31 | .. 32 | .. 33 | 34 | The pins we care about 35 | 36 | 2 37 | 4 38 | 6 39 | 8 TX out 40 | 10 RX in 41 | 42 | The pi TX goes to the uart RX and the pi RX to the uart TX. 43 | 44 | Here are some examples of 3.3V level uarts, you need 3.3V level not 5V 45 | definitely not RS-232C 46 | 47 | https://www.sparkfun.com/products/9873 48 | https://www.adafruit.com/products/954 49 | 50 | You can find these on ebay from china for a buck or two each with a 51 | jumper to select between 3.3V and 5V. 52 | 53 | This bootloader is expecting motorola s-record formatted data. 54 | 55 | en.wikipedia.org/wiki/SREC_(file_format) 56 | 57 | arm-whatever-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 58 | 59 | It is specifically expecting S3 records 60 | 61 | S00F00006E6F746D61696E2E737265631F 62 | S3150000800002D9A0E3050000EBFEFFFFEA001080E5C1 63 | S315000080101EFF2FE1000090E51EFF2FE11EFF2FE15E 64 | S3150000802010402DE9A4009FE5F9FFFFEB0E16C0E313 65 | S31500008030021681E394009FE5F3FFFFEB90009FE5B6 66 | S315000080400219A0E3F0FFFFEB0040A0E30400A0E16B 67 | S31500008050014084E2F0FFFFEB020754E3FAFFFF1A48 68 | S3150000806070009FE50219A0E3E7FFFFEB0040A0E3E5 69 | S315000080700400A0E1014084E2E7FFFFEB020754E3BE 70 | S31500008080FAFFFF1A48009FE50219A0E3DEFFFFEBA7 71 | S315000080900040A0E30400A0E1014084E2DEFFFFEB24 72 | S315000080A0020754E3FAFFFF1A28009FE50219A0E32E 73 | S315000080B0D5FFFFEB0040A0E30400A0E1014084E20D 74 | S315000080C0D5FFFFEB030654E3FAFFFF1ADAFFFFEAD8 75 | S311000080D0100020202C0020202000202082 76 | S705000080007A 77 | 78 | Not S1 records 79 | 80 | S00D000068656C6C6F2E7372656303 81 | S113800002D9A0E3050000EBFEFFFFEA001080E5C3 82 | S11380101EFF2FE1000090E51EFF2FE11EFF2FE160 83 | S113802010402DE9A4009FE5F9FFFFEB0E16C0E315 84 | S1138030021681E394009FE5F3FFFFEB90009FE5B8 85 | S11380400219A0E3F0FFFFEB0040A0E30400A0E16D 86 | S1138050014084E2F0FFFFEB020754E3FAFFFF1A4A 87 | S113806070009FE50219A0E3E7FFFFEB0040A0E3E7 88 | S11380700400A0E1014084E2E7FFFFEB020754E3C0 89 | S1138080FAFFFF1A48009FE50219A0E3DEFFFFEBA9 90 | S11380900040A0E30400A0E1014084E2DEFFFFEB26 91 | S11380A0020754E3FAFFFF1A28009FE50219A0E330 92 | S11380B0D5FFFFEB0040A0E30400A0E1014084E20F 93 | S11380C0D5FFFFEB030654E3FAFFFF1ADAFFFFEADA 94 | S10F80D0100020202C0020202000202084 95 | S90380007C 96 | 97 | It only supports S0, S3, and S7 records. You can certainly add more 98 | support. 99 | 100 | Using minicom you download by selecting ascii instead of xmodem 101 | or kermit or whatever. This just sends the file as is. If using 102 | some other terminal emulator you have to just figure it out. Or 103 | cut and paste it from an editor like the program above and paste 104 | it into your dumb terminal window. 105 | 106 | Minicom spawns other programs to do the downloads so there is or 107 | can be a dead period after downloading before minicom receives data 108 | so to deal with that once downloaded you press the letter g to go or 109 | run the program. This way you or at least I dont lose any characters 110 | from the downloaded program. 111 | 112 | I normally do not deliver binaries. In this case I have left the 113 | binary in the root directory as bootloader.img, copy this file to 114 | your sd card and name it kernel.img. 115 | 116 | Remove or rename a config.txt file on the sd card if you have one. 117 | 118 | There are a pair of holes on the board labelled RUN. If you are able 119 | to solder or find other solutions (there are pins that can be pushed 120 | into holes like this), you can put a momentary switch that when closed 121 | will reset the board, and released allow it to boot again. Then you 122 | can use this bootloader again by simply pressing the reset button. 123 | Much easier than power cycling the board every time (turning the power 124 | off, then on by unplugging the usb). 125 | 126 | These two lines in vectors.s determine the size of the programs this 127 | can handle 128 | 129 | First off 0x200000 is close to where this program begins so if you use 130 | this bootloader for larger programs you will overwrite the bootloader 131 | while running and crash. Make that number larger. 132 | 133 | .space 0x200000-0x8004,0 134 | 135 | If you approach this number 136 | 137 | skip: 138 | mov sp,#0x08000000 139 | 140 | Where the stack lives for this program, then you need to move that up 141 | as well. 142 | 143 | Oh, and this line too, this limits the overall size of the program 144 | if you run into this then just make it bigger as well. 145 | 146 | ram : ORIGIN = 0x8000, LENGTH = 0x1000000 147 | 148 | -------------------------------------------------------------------------------- /bootloader10/loader: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x1000000 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | .bss : { *(.bss*) } > ram 11 | } 12 | 13 | -------------------------------------------------------------------------------- /bootloader10/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | // 2 outer corner 3 | // 4 4 | // 6 5 | // 8 TX out 6 | // 10 RX in 7 | 8 | //extern void PUT32 ( unsigned int, unsigned int ); 9 | //extern void PUT16 ( unsigned int, unsigned int ); 10 | extern void PUT8 ( unsigned int, unsigned int ); 11 | //extern unsigned int GET32 ( unsigned int ); 12 | extern unsigned int GETPC ( void ); 13 | extern void BRANCHTO ( unsigned int ); 14 | //extern void dummy ( unsigned int ); 15 | 16 | extern void uart_init ( void ); 17 | extern void uart_send ( unsigned int ); 18 | extern unsigned int uart_recv ( void ); 19 | extern void hexstring ( unsigned int ); 20 | //extern void hexstrings ( unsigned int ); 21 | extern void uart_flush ( void ); 22 | 23 | extern void leds_off ( void ); 24 | 25 | unsigned int ctonib ( unsigned int c ) 26 | { 27 | if(c>0x39) c-=7; 28 | return(c&0xF); 29 | } 30 | 31 | int notmain ( void ) 32 | { 33 | unsigned int state; 34 | unsigned int ra; 35 | unsigned int type; 36 | unsigned int count; 37 | unsigned int sum; 38 | unsigned int entry; 39 | unsigned int addr; 40 | unsigned int data; 41 | 42 | //leds_off(); 43 | 44 | uart_init(); 45 | hexstring(0x12345678); 46 | hexstring(GETPC()); 47 | uart_send(0x0D); 48 | uart_send(0x0A); 49 | uart_send('S'); 50 | uart_send('R'); 51 | uart_send('E'); 52 | uart_send('C'); 53 | uart_send(0x0D); 54 | uart_send(0x0A); 55 | 56 | data=0; 57 | state=0; 58 | count=0; 59 | sum=0; 60 | addr=0; 61 | type=0; 62 | entry=0x00008000; 63 | while(1) 64 | { 65 | ra=uart_recv(); 66 | switch(state) 67 | { 68 | case 0: 69 | { 70 | if(ra=='S') 71 | { 72 | sum=0; 73 | state++; 74 | } 75 | if((ra=='g')||(ra=='G')) 76 | { 77 | hexstring(entry); 78 | uart_flush(); 79 | BRANCHTO(entry); 80 | } 81 | break; 82 | } 83 | case 1: 84 | { 85 | switch(ra) 86 | { 87 | case '0': 88 | { 89 | state=0; 90 | break; 91 | } 92 | case '3': 93 | { 94 | type=3; 95 | state++; 96 | break; 97 | } 98 | case '7': 99 | { 100 | type=7; 101 | state++; 102 | break; 103 | } 104 | default: 105 | { 106 | hexstring(ra); 107 | hexstring(0xBADBAD00); 108 | return(1); 109 | } 110 | } 111 | break; 112 | } 113 | 114 | case 2: 115 | { 116 | count=ctonib(ra); 117 | state++; 118 | break; 119 | } 120 | case 3: 121 | { 122 | count<<=4; 123 | count|=ctonib(ra); 124 | if(count<5) 125 | { 126 | hexstring(0xBADBAD01); 127 | return(1); 128 | } 129 | sum+=count&0xFF; 130 | addr=0; 131 | state++; 132 | break; 133 | } 134 | case 4: 135 | case 6: 136 | case 8: 137 | case 10: 138 | { 139 | addr<<=4; 140 | addr|=ctonib(ra); 141 | state++; 142 | break; 143 | } 144 | case 5: 145 | case 7: 146 | case 9: 147 | { 148 | count--; 149 | addr<<=4; 150 | addr|=ctonib(ra); 151 | sum+=addr&0xFF; 152 | state++; 153 | break; 154 | } 155 | case 11: 156 | { 157 | count--; 158 | addr<<=4; 159 | addr|=ctonib(ra); 160 | sum+=addr&0xFF; 161 | state++; 162 | break; 163 | } 164 | case 12: 165 | { 166 | data=ctonib(ra); 167 | state++; 168 | break; 169 | } 170 | case 13: 171 | { 172 | data<<=4; 173 | data|=ctonib(ra); 174 | sum+=data&0xFF; 175 | count--; 176 | if(count==0) 177 | { 178 | if(type==7) 179 | { 180 | entry=addr; 181 | } 182 | sum&=0xFF; 183 | if(sum!=0xFF) 184 | { 185 | hexstring(0xBADBAD02); 186 | return(1); 187 | } 188 | state=0; 189 | } 190 | else 191 | { 192 | PUT8(addr,data); 193 | addr++; 194 | state=12; 195 | } 196 | break; 197 | } 198 | } 199 | 200 | } 201 | return(0); 202 | } 203 | 204 | //------------------------------------------------------------------------- 205 | // 206 | // Copyright (c) 2014 David Welch dwelch@dwelch.com 207 | // 208 | // 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: 209 | // 210 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 211 | // 212 | // 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. 213 | // 214 | //------------------------------------------------------------------------- 215 | -------------------------------------------------------------------------------- /bootloader10/periph.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------------- 3 | //------------------------------------------------------------------------- 4 | 5 | #define PBASE 0x20000000 6 | 7 | extern void PUT32 ( unsigned int, unsigned int ); 8 | extern void PUT16 ( unsigned int, unsigned int ); 9 | extern void PUT8 ( unsigned int, unsigned int ); 10 | extern unsigned int GET32 ( unsigned int ); 11 | extern void dummy ( unsigned int ); 12 | 13 | #define ARM_TIMER_CTL (PBASE+0x0000B408) 14 | #define ARM_TIMER_CNT (PBASE+0x0000B420) 15 | 16 | #define GPFSEL1 (PBASE+0x00200004) 17 | #define GPFSEL3 (PBASE+0x0020000C) 18 | #define GPFSEL4 (PBASE+0x00200010) 19 | #define GPSET0 (PBASE+0x0020001C) 20 | #define GPCLR0 (PBASE+0x00200028) 21 | #define GPSET1 (PBASE+0x00200020) 22 | #define GPCLR1 (PBASE+0x2020002C) 23 | //#define GPPUD (PBASE+0x00200094) 24 | //#define GPPUDCLK0 (PBASE+0x00200098) 25 | 26 | #define AUX_ENABLES (PBASE+0x00215004) 27 | #define AUX_MU_IO_REG (PBASE+0x00215040) 28 | #define AUX_MU_IER_REG (PBASE+0x00215044) 29 | #define AUX_MU_IIR_REG (PBASE+0x00215048) 30 | #define AUX_MU_LCR_REG (PBASE+0x0021504C) 31 | #define AUX_MU_MCR_REG (PBASE+0x00215050) 32 | #define AUX_MU_LSR_REG (PBASE+0x00215054) 33 | #define AUX_MU_MSR_REG (PBASE+0x00215058) 34 | #define AUX_MU_SCRATCH (PBASE+0x0021505C) 35 | #define AUX_MU_CNTL_REG (PBASE+0x00215060) 36 | #define AUX_MU_STAT_REG (PBASE+0x00215064) 37 | #define AUX_MU_BAUD_REG (PBASE+0x00215068) 38 | 39 | //GPIO14 TXD0 and TXD1 40 | //GPIO15 RXD0 and RXD1 41 | 42 | //2 outer corner 43 | //4 44 | //6 ground 45 | //8 TX out 46 | //10 RX in 47 | 48 | //------------------------------------------------------------------------ 49 | unsigned int uart_lcr ( void ) 50 | { 51 | return(GET32(AUX_MU_LSR_REG)); 52 | } 53 | //------------------------------------------------------------------------ 54 | unsigned int uart_recv ( void ) 55 | { 56 | while(1) 57 | { 58 | if(GET32(AUX_MU_LSR_REG)&0x01) break; 59 | } 60 | return(GET32(AUX_MU_IO_REG)&0xFF); 61 | } 62 | //------------------------------------------------------------------------ 63 | unsigned int uart_check ( void ) 64 | { 65 | if(GET32(AUX_MU_LSR_REG)&0x01) return(1); 66 | return(0); 67 | } 68 | //------------------------------------------------------------------------ 69 | void uart_send ( unsigned int c ) 70 | { 71 | while(1) 72 | { 73 | if(GET32(AUX_MU_LSR_REG)&0x20) break; 74 | } 75 | PUT32(AUX_MU_IO_REG,c); 76 | } 77 | //------------------------------------------------------------------------ 78 | void uart_flush ( void ) 79 | { 80 | while(1) 81 | { 82 | if(GET32(AUX_MU_LSR_REG)&0x40) break; 83 | } 84 | } 85 | //------------------------------------------------------------------------ 86 | void hexstrings ( unsigned int d ) 87 | { 88 | //unsigned int ra; 89 | unsigned int rb; 90 | unsigned int rc; 91 | 92 | rb=32; 93 | while(1) 94 | { 95 | rb-=4; 96 | rc=(d>>rb)&0xF; 97 | if(rc>9) rc+=0x37; else rc+=0x30; 98 | uart_send(rc); 99 | if(rb==0) break; 100 | } 101 | uart_send(0x20); 102 | } 103 | //------------------------------------------------------------------------ 104 | void hexstring ( unsigned int d ) 105 | { 106 | hexstrings(d); 107 | uart_send(0x0D); 108 | uart_send(0x0A); 109 | } 110 | //------------------------------------------------------------------------ 111 | void uart_init ( void ) 112 | { 113 | unsigned int ra; 114 | 115 | PUT32(AUX_ENABLES,1); 116 | PUT32(AUX_MU_IER_REG,0); 117 | PUT32(AUX_MU_CNTL_REG,0); 118 | PUT32(AUX_MU_LCR_REG,3); 119 | PUT32(AUX_MU_MCR_REG,0); 120 | PUT32(AUX_MU_IER_REG,0); 121 | PUT32(AUX_MU_IIR_REG,0xC6); 122 | PUT32(AUX_MU_BAUD_REG,270); 123 | ra=GET32(GPFSEL1); 124 | ra&=~(7<<12); //gpio14 125 | ra|=2<<12; //alt5 126 | ra&=~(7<<15); //gpio15 127 | ra|=2<<15; //alt5 128 | PUT32(GPFSEL1,ra); 129 | //I wonder if we really need this 130 | //PUT32(GPPUD,0); 131 | //for(ra=0;ra<150;ra++) dummy(ra); 132 | //PUT32(GPPUDCLK0,(1<<14)|(1<<15)); 133 | //for(ra=0;ra<150;ra++) dummy(ra); 134 | //PUT32(GPPUDCLK0,0); 135 | PUT32(AUX_MU_CNTL_REG,3); 136 | } 137 | //------------------------------------------------------------------------ 138 | void timer_init ( void ) 139 | { 140 | //0xF9+1 = 250 141 | //250MHz/250 = 1MHz 142 | PUT32(ARM_TIMER_CTL,0x00F90000); 143 | PUT32(ARM_TIMER_CTL,0x00F90200); 144 | } 145 | //------------------------------------------------------------------------- 146 | unsigned int timer_tick ( void ) 147 | { 148 | return(GET32(ARM_TIMER_CNT)); 149 | } 150 | //------------------------------------------------------------------------- 151 | void leds_off ( void ) 152 | { 153 | unsigned int ra; 154 | 155 | ra=GET32(GPFSEL4); 156 | ra&=~(7<<21); 157 | ra|=1<<21; 158 | PUT32(GPFSEL4,ra); 159 | 160 | PUT32(GPSET1,1<<(47-32)); 161 | } 162 | //------------------------------------------------------------------------- 163 | 164 | //------------------------------------------------------------------------- 165 | // 166 | // Copyright (c) 2012 David Welch dwelch@dwelch.com 167 | // 168 | // 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: 169 | // 170 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 171 | // 172 | // 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. 173 | // 174 | //------------------------------------------------------------------------- 175 | -------------------------------------------------------------------------------- /bootloader10/vectors.s: -------------------------------------------------------------------------------- 1 | 2 | ;@------------------------------------------------------------------------- 3 | ;@------------------------------------------------------------------------- 4 | 5 | .globl _start 6 | _start: 7 | b skip 8 | 9 | .space 0x200000-0x8004,0 10 | 11 | skip: 12 | mov sp,#0x08000000 13 | bl notmain 14 | hang: b hang 15 | 16 | .globl PUT32 17 | PUT32: 18 | str r1,[r0] 19 | bx lr 20 | 21 | .globl PUT16 22 | PUT16: 23 | strh r1,[r0] 24 | bx lr 25 | 26 | .globl PUT8 27 | PUT8: 28 | strb r1,[r0] 29 | bx lr 30 | 31 | .globl GET32 32 | GET32: 33 | ldr r0,[r0] 34 | bx lr 35 | 36 | .globl GETPC 37 | GETPC: 38 | mov r0,lr 39 | bx lr 40 | 41 | .globl BRANCHTO 42 | BRANCHTO: 43 | bx r0 44 | 45 | .globl dummy 46 | dummy: 47 | bx lr 48 | 49 | 50 | ;@------------------------------------------------------------------------- 51 | ;@------------------------------------------------------------------------- 52 | 53 | 54 | ;@------------------------------------------------------------------------- 55 | ;@ 56 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 57 | ;@ 58 | ;@ 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: 59 | ;@ 60 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 61 | ;@ 62 | ;@ 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. 63 | ;@ 64 | ;@------------------------------------------------------------------------- 65 | -------------------------------------------------------------------------------- /bootstrap/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | AOPS = --warn --fatal-warnings 6 | COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding 7 | 8 | all : kernel.img 9 | 10 | clean : 11 | rm -f *.o 12 | rm -f *.bin 13 | rm -f *.srec 14 | rm -f *.elf 15 | rm -f *.list 16 | rm -f *.img 17 | 18 | start.o : start.s 19 | $(ARMGNU)-as $(AOPS) start.s -o start.o 20 | 21 | notmain.o : notmain.c 22 | $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o 23 | 24 | periph.o : periph.c 25 | $(ARMGNU)-gcc $(COPS) -c periph.c -o periph.o 26 | 27 | notmain.elf : memmap start.o periph.o notmain.o 28 | $(ARMGNU)-ld start.o periph.o notmain.o -T memmap -o notmain.elf 29 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 30 | 31 | kernel.img : notmain.elf 32 | $(ARMGNU)-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 33 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 34 | 35 | -------------------------------------------------------------------------------- /bootstrap/README: -------------------------------------------------------------------------------- 1 | 2 | See the top level README for information on where to find documentation 3 | for the raspberry pi and the ARM processor inside. Also find information 4 | on how to load and run these programs. 5 | 6 | This is a pi zero example 7 | 8 | Using a start.elf committed to the raspberry pi repo on 2017-06-13 9 | I wanted to examine the bootstrap placed by the GPU for the ARM before 10 | releasing reset on the ARM. I wasnt expecting this one to be all 11 | that interesting and it isnt, the code for the raspberry pi 2 and 12 | for the raspberry pi 3 is far more interesting a the cores are more 13 | complicated and multicore. But there still exists the possibility that 14 | the foundation may change the bootcode or other items in this area. 15 | 16 | I simply dumped the first 0x1000 bytes of memory which I had not 17 | otherwise touched. A number of ways to deal with it but an easy one is 18 | to just make a pseudo assembly program with the data: 19 | 20 | .word 0xE3A00000 21 | .word 0xE59F1004 22 | .word 0xE59F20E8 23 | .word 0xE59FF0E8 24 | .word 0x00000C42 25 | .word 0x00000000 26 | .word 0x00000000 27 | .word 0x00000000 28 | ... 29 | 30 | assemble then disassemble, we are relying here on the disassembler 31 | to disassemble data as well as instructions, so we place data but 32 | it disassembles them as instructions which was the goal. 33 | 34 | 35 | 00000000 <.text>: 36 | 0: e3a00000 mov r0, #0 37 | 4: e59f1004 ldr r1, [pc, #4] ; 10 <.text+0x10> 38 | 8: e59f20e8 ldr r2, [pc, #232] ; f8 <.text+0xf8> 39 | c: e59ff0e8 ldr pc, [pc, #232] ; fc <.text+0xfc> 40 | 10: 00000c42 41 | ... 42 | fc: 00008000 43 | 100: 00000005 44 | 104: 54410001 45 | 46 | google ATAG linux and find many hits on the topic 47 | 48 | For example 49 | 50 | www.simtec.co.uk/products/SWLINUX/files/booting_article.html 51 | 52 | This is important: 53 | 54 | The CPU must be in SVC (supervisor) mode with both IRQ and FIQ interrupts disabled. 55 | The MMU must be off, i.e. code running from physical RAM with no translated addressing. 56 | Data cache must be off 57 | Instruction cache may be either on or off 58 | CPU register 0 must be 0 59 | CPU register 1 must be the ARM Linux machine type 60 | CPU register 2 must be the physical address of the parameter list 61 | 62 | 63 | and this 64 | 65 | The list must be stored in RAM and placed in a region of memory where 66 | neither the kernel decompresser nor initrd manipulation will overwrite 67 | it. The recommended placement is in the first 16KiB of RAM, usually the 68 | start of physical RAM plus 0x100 (which avoids zero page exception 69 | vectors). 70 | 71 | I predate DTB stuff but have only slightly dabbled in embedded linux 72 | at this level. The 0x100 offset is a compile time option as are some 73 | other things and/or you just dont mess with it. 74 | 75 | Clearly we can see that they are loading 0x8000 into the PC that is 76 | how they run our program that was loaded at 0x8000. 77 | 78 | Before the pis were avaiable to the masses from the info around at the 79 | time the kernel.img was loaded at 0x0000 and would have needed to 80 | include this bootloader stuff. Normally you use redboot or u-boot 81 | or other to load the kernel image into memory and place the ATAGs/DTB 82 | and launch. Linux (for ARM) is as you can see extremely trivial to boot 83 | it does not require such massivly complicated bootloaders, those are 84 | just projects that have gotten out of control, feature creep. So 85 | it was nice in one respect to have the linux kernel image bundled 86 | with some bootstrap, but that was also unusual so by the time the 87 | rest of us could get boards they had changed it to what it is today. 88 | The GPU acts as the bootloader places the ATAGs and some bootstrap 89 | code to load r0,r1,r2 and branch to 0x8000. 90 | 91 | R2 is loaded with 0x00000000 so I assume that is what they add 0x100 92 | to to get at the atags. 93 | 94 | The ATAGs have this 0x5441xxxx pattern so I dumped those 95 | 96 | 00000104 54410001 97 | 00000118 54410002 98 | 00000128 54410009 99 | 100 | This is the data starting at offset 0x00000100 101 | 102 | 0x00000005 <--- how many words 103 | 0x54410001 <--- ATAG_CORE 104 | 0x00000000 105 | 0x00000000 106 | 0x00000000 107 | 0x00000004 <---- how many words 108 | 0x54410002 <---- ATAG_MEM 109 | 0x08000000 <---- size 110 | 0x00000000 <---- start 111 | 0x00000063 <---- how many words 112 | 0x54410009 <---- ATAG_CMDLINE 113 | 114 | The command line length lookes wrong to me but clearly it works so 115 | not going to worry about it. Interesting items in the command line 116 | 117 | vc_mem.mem_base=0xec00000 118 | vc_mem.mem_size=0x10000000 119 | 120 | See bootstrap.txt for a dump and disassembly of what I read out of 121 | memory. 122 | 123 | So the pi zero is advertised as having 512MBytes, which is 0x20000000 124 | ATAG_MEM appears to be saying you have 128MBytes (for ARM linux) starting 125 | at 0x00000000. And the GPU/VC has 256MBytes starting at 0x0EC00000. 126 | Is what it is...can be changed with config.txt if needed. 127 | 128 | Good information to know and you can have your program read these 129 | atags to find ATAG_MEM to know how deep into memory the GPU as of this 130 | boot is willing to let you go. You could wander into the GPUs data/code 131 | and crash it so tread lightly. 132 | 133 | This is a pi zero example, but when the same technique is used for the 134 | pi2 or pi3 you can see how they are "sorting the cores" I call it. My 135 | limited knowledge of ARM cores (just look at the various ARM TRM's) the 136 | edge of the core (where the chip vendor connects their logic) is a 137 | clock enable and a reset for each core in a multicore processor which 138 | means it is up to the vendor to decide how/when to release each core. 139 | I dont yet know if broadcom has individual core controls, but what 140 | we see is that all the cores seem to come up at or near the same time 141 | if you put your code at address zero on these chips and assume it is 142 | a uniprocessor, then the multiple cores will stomp on each other (try 143 | to print out the uart, one to four of them will write to the data 144 | register then start polling for an empty THR, then one or two will 145 | get a write in and so on, you see repeated characters). The ARM 146 | documentation is vague or actually just has a gaping hole, as to the 147 | values expected in the ID registers, so sorting the cores without 148 | a single threaded way to "see" what is going on is tricky, disassembling 149 | the raspberry pi placed bootstrap shows you how they sort the cores 150 | and then each lands in a loop polling a "mailbox" register waiting for 151 | it to contain a non-zero address indicating we want that core to 152 | start running code there. It also shows us for those platforms that 153 | they are putting the cores in HYP mode instead of SVC (which violates 154 | the ARM linux booting page I linked above but this has evolved since 155 | that page). 156 | 157 | But this is a pi zero example and you can see how crazy simple it is 158 | to boot linux, u-boot and redboot are gross overkill. 159 | -------------------------------------------------------------------------------- /bootstrap/bootstrap.txt: -------------------------------------------------------------------------------- 1 | 2 | 00000000 <.text>: 3 | 0: e3a00000 mov r0, #0 4 | 4: e59f1004 ldr r1, [pc, #4] ; 10 <.text+0x10> 5 | 8: e59f20e8 ldr r2, [pc, #232] ; f8 <.text+0xf8> 6 | c: e59ff0e8 ldr pc, [pc, #232] ; fc <.text+0xfc> 7 | 10: 00000c42 8 | ... 9 | fc: 00008000 10 | 100: 00000005 11 | 104: 54410001 12 | ... 13 | 114: 00000004 14 | 118: 54410002 15 | 11c: 08000000 16 | 120: 00000000 17 | 124: 00000063 18 | 128: 54410009 19 | 12c: 326d6362 20 | 130: 5f383037 21 | 134: 662e6266 22 | 23 | 24 | 25 | 26 | 27 | 28 | 00000000 00 00 a0 e3 04 10 9f e5 e8 20 9f e5 e8 f0 9f e5 |......... ......| 29 | 00000010 42 0c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |B...............| 30 | 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 31 | * 32 | 000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 |................| 33 | 00000100 05 00 00 00 01 00 41 54 00 00 00 00 00 00 00 00 |......AT........| 34 | 00000110 00 00 00 00 04 00 00 00 02 00 41 54 00 00 00 08 |..........AT....| 35 | 00000120 00 00 00 00 63 00 00 00 09 00 41 54 62 63 6d 32 |....c.....ATbcm2| 36 | 00000130 37 30 38 5f 66 62 2e 66 62 77 69 64 74 68 3d 36 |708_fb.fbwidth=6| 37 | 00000140 35 36 20 62 63 6d 32 37 30 38 5f 66 62 2e 66 62 |56 bcm2708_fb.fb| 38 | 00000150 68 65 69 67 68 74 3d 34 31 36 20 62 63 6d 32 37 |height=416 bcm27| 39 | 00000160 30 38 5f 66 62 2e 66 62 73 77 61 70 3d 31 20 64 |08_fb.fbswap=1 d| 40 | 00000170 6d 61 2e 64 6d 61 63 68 61 6e 73 3d 30 78 37 66 |ma.dmachans=0x7f| 41 | 00000180 33 35 20 62 63 6d 32 37 30 38 2e 62 6f 61 72 64 |35 bcm2708.board| 42 | 00000190 72 65 76 3d 30 78 39 30 30 30 39 32 20 62 63 6d |rev=0x900092 bcm| 43 | 000001a0 32 37 30 38 2e 73 65 72 69 61 6c 3d 30 78 33 37 |2708.serial=0x37| 44 | 000001b0 36 38 31 32 35 64 20 62 63 6d 32 37 30 38 2e 75 |68125d bcm2708.u| 45 | 000001c0 61 72 74 5f 63 6c 6f 63 6b 3d 34 38 30 30 30 30 |art_clock=480000| 46 | 000001d0 30 30 20 62 63 6d 32 37 30 38 2e 64 69 73 6b 5f |00 bcm2708.disk_| 47 | 000001e0 6c 65 64 5f 67 70 69 6f 3d 34 37 20 73 6d 73 63 |led_gpio=47 smsc| 48 | 000001f0 39 35 78 78 2e 6d 61 63 61 64 64 72 3d 42 38 3a |95xx.macaddr=B8:| 49 | 00000200 32 37 3a 45 42 3a 36 38 3a 31 32 3a 35 44 20 76 |27:EB:68:12:5D v| 50 | 00000210 63 5f 6d 65 6d 2e 6d 65 6d 5f 62 61 73 65 3d 30 |c_mem.mem_base=0| 51 | 00000220 78 65 63 30 30 30 30 30 20 76 63 5f 6d 65 6d 2e |xec00000 vc_mem.| 52 | 00000230 6d 65 6d 5f 73 69 7a 65 3d 30 78 31 30 30 30 30 |mem_size=0x10000| 53 | 00000240 30 30 30 20 20 63 6f 6e 73 6f 6c 65 3d 74 74 79 |000 console=tty| 54 | 00000250 41 4d 41 30 2c 31 31 35 32 30 30 20 6b 67 64 62 |AMA0,115200 kgdb| 55 | 00000260 6f 63 3d 74 74 79 41 4d 41 30 2c 31 31 35 32 30 |oc=ttyAMA0,11520| 56 | 00000270 30 20 63 6f 6e 73 6f 6c 65 3d 74 74 79 31 20 72 |0 console=tty1 r| 57 | 00000280 6f 6f 74 3d 2f 64 65 76 2f 6d 6d 63 62 6c 6b 30 |oot=/dev/mmcblk0| 58 | 00000290 70 32 20 72 6f 6f 74 66 73 74 79 70 65 3d 65 78 |p2 rootfstype=ex| 59 | 000002a0 74 34 20 72 6f 6f 74 77 61 69 74 00 51 55 55 55 |t4 rootwait.QUUU| 60 | -------------------------------------------------------------------------------- /bootstrap/memmap: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x1000 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | .bss : { *(.bss*) } > ram 11 | } 12 | 13 | -------------------------------------------------------------------------------- /bootstrap/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------- 3 | //------------------------------------------------------------------- 4 | 5 | // 2 outer corner sd card end 6 | // 4 7 | // 6 8 | // 8 TX out 9 | // 10 RX in 10 | 11 | extern void PUT32 ( unsigned int, unsigned int ); 12 | extern void PUT16 ( unsigned int, unsigned int ); 13 | extern void PUT8 ( unsigned int, unsigned int ); 14 | extern unsigned int GET32 ( unsigned int ); 15 | extern unsigned int GETPC ( void ); 16 | extern void dummy ( unsigned int ); 17 | extern unsigned int BRANCHTO ( unsigned int ); 18 | 19 | extern void uart_init ( void ); 20 | extern unsigned int uart_lcr ( void ); 21 | extern void uart_flush ( void ); 22 | extern void uart_send ( unsigned int ); 23 | extern unsigned int uart_recv ( void ); 24 | extern unsigned int uart_check ( void ); 25 | extern void hexstring ( unsigned int ); 26 | extern void hexstrings ( unsigned int ); 27 | extern void timer_init ( void ); 28 | extern unsigned int timer_tick ( void ); 29 | 30 | extern void timer_init ( void ); 31 | extern unsigned int timer_tick ( void ); 32 | 33 | //------------------------------------------------------------------- 34 | int notmain ( void ) 35 | { 36 | unsigned int ra; 37 | unsigned int rb; 38 | 39 | uart_init(); 40 | hexstring(0x12345678); 41 | hexstring(GETPC()); 42 | 43 | for(ra=0;ra<0x1000;ra+=4) 44 | { 45 | hexstring(GET32(ra)); 46 | } 47 | for(ra=0;ra<0x2000;ra+=4) 48 | { 49 | rb=GET32(ra); 50 | if((rb&0xFFFF0000)==0x54410000) 51 | { 52 | hexstrings(ra); hexstring(rb); 53 | } 54 | } 55 | return(0); 56 | } 57 | //------------------------------------------------------------------- 58 | //------------------------------------------------------------------- 59 | 60 | //------------------------------------------------------------------- 61 | // 62 | // Copyright (c) 2014 David Welch dwelch@dwelch.com 63 | // 64 | // 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: 65 | // 66 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 67 | // 68 | // 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. 69 | // 70 | //------------------------------------------------------------------- 71 | -------------------------------------------------------------------------------- /bootstrap/periph.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------- 3 | //------------------------------------------------------------------- 4 | 5 | #define PBASE 0x20000000 6 | 7 | extern void PUT32 ( unsigned int, unsigned int ); 8 | extern void PUT16 ( unsigned int, unsigned int ); 9 | extern void PUT8 ( unsigned int, unsigned int ); 10 | extern unsigned int GET32 ( unsigned int ); 11 | extern void dummy ( unsigned int ); 12 | 13 | #define ARM_TIMER_CTL (PBASE+0x0000B408) 14 | #define ARM_TIMER_CNT (PBASE+0x0000B420) 15 | 16 | #define GPFSEL1 (PBASE+0x00200004) 17 | #define GPSET0 (PBASE+0x0020001C) 18 | #define GPCLR0 (PBASE+0x00200028) 19 | #define GPPUD (PBASE+0x00200094) 20 | #define GPPUDCLK0 (PBASE+0x00200098) 21 | 22 | #define AUX_ENABLES (PBASE+0x00215004) 23 | #define AUX_MU_IO_REG (PBASE+0x00215040) 24 | #define AUX_MU_IER_REG (PBASE+0x00215044) 25 | #define AUX_MU_IIR_REG (PBASE+0x00215048) 26 | #define AUX_MU_LCR_REG (PBASE+0x0021504C) 27 | #define AUX_MU_MCR_REG (PBASE+0x00215050) 28 | #define AUX_MU_LSR_REG (PBASE+0x00215054) 29 | #define AUX_MU_MSR_REG (PBASE+0x00215058) 30 | #define AUX_MU_SCRATCH (PBASE+0x0021505C) 31 | #define AUX_MU_CNTL_REG (PBASE+0x00215060) 32 | #define AUX_MU_STAT_REG (PBASE+0x00215064) 33 | #define AUX_MU_BAUD_REG (PBASE+0x00215068) 34 | 35 | //GPIO14 TXD0 and TXD1 36 | //GPIO15 RXD0 and RXD1 37 | 38 | // 2 outer corner sd card end 39 | // 4 40 | // 6 41 | // 8 TX out 42 | // 10 RX in 43 | 44 | //------------------------------------------------------------------- 45 | unsigned int uart_lcr ( void ) 46 | { 47 | return(GET32(AUX_MU_LSR_REG)); 48 | } 49 | //------------------------------------------------------------------- 50 | unsigned int uart_recv ( void ) 51 | { 52 | while(1) 53 | { 54 | if(GET32(AUX_MU_LSR_REG)&0x01) break; 55 | } 56 | return(GET32(AUX_MU_IO_REG)&0xFF); 57 | } 58 | //------------------------------------------------------------------- 59 | unsigned int uart_check ( void ) 60 | { 61 | if(GET32(AUX_MU_LSR_REG)&0x01) return(1); 62 | return(0); 63 | } 64 | //------------------------------------------------------------------- 65 | void uart_send ( unsigned int c ) 66 | { 67 | while(1) 68 | { 69 | if(GET32(AUX_MU_LSR_REG)&0x20) break; 70 | } 71 | PUT32(AUX_MU_IO_REG,c); 72 | } 73 | //------------------------------------------------------------------- 74 | void uart_flush ( void ) 75 | { 76 | while(1) 77 | { 78 | if(GET32(AUX_MU_LSR_REG)&0x40) break; 79 | } 80 | } 81 | //------------------------------------------------------------------- 82 | void hexstrings ( unsigned int d ) 83 | { 84 | //unsigned int ra; 85 | unsigned int rb; 86 | unsigned int rc; 87 | 88 | rb=32; 89 | while(1) 90 | { 91 | rb-=4; 92 | rc=(d>>rb)&0xF; 93 | if(rc>9) rc+=0x37; else rc+=0x30; 94 | uart_send(rc); 95 | if(rb==0) break; 96 | } 97 | uart_send(0x20); 98 | } 99 | //------------------------------------------------------------------- 100 | void hexstring ( unsigned int d ) 101 | { 102 | hexstrings(d); 103 | uart_send(0x0D); 104 | uart_send(0x0A); 105 | } 106 | //------------------------------------------------------------------- 107 | void uart_init ( void ) 108 | { 109 | unsigned int ra; 110 | 111 | PUT32(AUX_ENABLES,1); 112 | PUT32(AUX_MU_IER_REG,0); 113 | PUT32(AUX_MU_CNTL_REG,0); 114 | PUT32(AUX_MU_LCR_REG,3); 115 | PUT32(AUX_MU_MCR_REG,0); 116 | PUT32(AUX_MU_IER_REG,0); 117 | PUT32(AUX_MU_IIR_REG,0xC6); 118 | PUT32(AUX_MU_BAUD_REG,270); 119 | ra=GET32(GPFSEL1); 120 | ra&=~(7<<12); //gpio14 121 | ra|=2<<12; //alt5 122 | ra&=~(7<<15); //gpio15 123 | ra|=2<<15; //alt5 124 | PUT32(GPFSEL1,ra); 125 | //should we care? 126 | //PUT32(GPPUD,0); 127 | //for(ra=0;ra<150;ra++) dummy(ra); 128 | //PUT32(GPPUDCLK0,(1<<14)|(1<<15)); 129 | //for(ra=0;ra<150;ra++) dummy(ra); 130 | //PUT32(GPPUDCLK0,0); 131 | PUT32(AUX_MU_CNTL_REG,3); 132 | } 133 | //------------------------------------------------------------------- 134 | void timer_init ( void ) 135 | { 136 | //0xF9+1 = 250 137 | //250MHz/250 = 1MHz 138 | PUT32(ARM_TIMER_CTL,0x00F90000); 139 | PUT32(ARM_TIMER_CTL,0x00F90200); 140 | } 141 | //------------------------------------------------------------------- 142 | unsigned int timer_tick ( void ) 143 | { 144 | return(GET32(ARM_TIMER_CNT)); 145 | } 146 | //------------------------------------------------------------------- 147 | //------------------------------------------------------------------- 148 | 149 | //------------------------------------------------------------------- 150 | // 151 | // Copyright (c) 2012 David Welch dwelch@dwelch.com 152 | // 153 | // 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: 154 | // 155 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 156 | // 157 | // 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. 158 | // 159 | //------------------------------------------------------------------- 160 | -------------------------------------------------------------------------------- /bootstrap/start.s: -------------------------------------------------------------------------------- 1 | 2 | ;@------------------------------------------------------------------- 3 | ;@------------------------------------------------------------------- 4 | 5 | .globl _start 6 | _start: 7 | b reset 8 | b hang 9 | b hang 10 | b hang 11 | b hang 12 | b hang 13 | b hang 14 | b hang 15 | 16 | reset: 17 | mov sp,#0x8000 18 | bl notmain 19 | hang: b hang 20 | 21 | .globl PUT32 22 | PUT32: 23 | str r1,[r0] 24 | bx lr 25 | 26 | .globl GET32 27 | GET32: 28 | ldr r0,[r0] 29 | bx lr 30 | 31 | .globl dummy 32 | dummy: 33 | bx lr 34 | 35 | .globl GETPC 36 | GETPC: 37 | mov r0,lr 38 | bx lr 39 | 40 | .globl BRANCHTO 41 | BRANCHTO: 42 | bx r0 43 | 44 | ;@------------------------------------------------------------------- 45 | ;@------------------------------------------------------------------- 46 | 47 | ;@------------------------------------------------------------------- 48 | ;@ 49 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 50 | ;@ 51 | ;@ 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: 52 | ;@ 53 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 54 | ;@ 55 | ;@ 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. 56 | ;@ 57 | ;@------------------------------------------------------------------- 58 | -------------------------------------------------------------------------------- /float01/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | AOPS = --warn --fatal-warnings -mcpu=arm1176jzf-s -march=armv6 -mfpu=vfp 6 | COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mhard-float -mfpu=vfp 7 | 8 | all : kernel.img 9 | 10 | clean : 11 | rm -f *.o 12 | rm -f *.bin 13 | rm -f *.srec 14 | rm -f *.elf 15 | rm -f *.list 16 | rm -f *.img 17 | 18 | start.o : start.s 19 | $(ARMGNU)-as $(AOPS) start.s -o start.o 20 | 21 | notmain.o : notmain.c 22 | $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o 23 | 24 | periph.o : periph.c 25 | $(ARMGNU)-gcc $(COPS) -c periph.c -o periph.o 26 | 27 | fun.o : fun.c 28 | $(ARMGNU)-gcc $(COPS) -c fun.c -o fun.o 29 | 30 | notmain.elf : memmap start.o fun.o periph.o notmain.o 31 | $(ARMGNU)-ld start.o fun.o periph.o notmain.o -T memmap -o notmain.elf 32 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 33 | 34 | kernel.img : notmain.elf 35 | $(ARMGNU)-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 36 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 37 | 38 | -------------------------------------------------------------------------------- /float01/README: -------------------------------------------------------------------------------- 1 | 2 | See the top level README for information on where to find documentation 3 | for the raspberry pi and the ARM processor inside. Also find information 4 | on how to load and run these programs. 5 | 6 | This is a floating point example for the pi zero. 7 | (special treat this example is not in my other raspberry pi repo) 8 | 9 | Perhaps I mentioned in a README never to mention floating point...anyway 10 | 11 | Many of the ARM cores that preceeded the ARM11 didnt have a floating 12 | point (nor divide) you did those things with a software library, actually 13 | gcclib contains those for you (as required since the C language should 14 | just work). So extra work is needed both in the command line options 15 | and in the bootstrap. 16 | 17 | What you may not know/understand is the floating point unit is just a 18 | coprocessor, like cp15 is. And the instructions actually map into 19 | the generic coprocessor instruction format, but they have made 20 | (historically a number of) pseudo instructions so you dont have to know 21 | that. And the current generation of floating point instructions 22 | syntax is different but make the same instructions as the 23 | prior generation syntax. Information you can confirm or deny on your 24 | own. 25 | 26 | So we have to tell the ARM to enable the floating point coprocessors 27 | 28 | ;@ enable fpu 29 | mrc p15, 0, r0, c1, c0, 2 30 | orr r0,r0,#0x300000 ;@ single precision 31 | orr r0,r0,#0xC00000 ;@ double precision 32 | mcr p15, 0, r0, c1, c0, 2 33 | mov r0,#0x40000000 34 | fmxr fpexc,r0 35 | 36 | before we can use them. 37 | 38 | And you can see in the Makefile compared to say the uart05 Makefile 39 | the additional items added to get the compiler to understand what core 40 | I have and what floating point instructions I want to use. 41 | 42 | As discussed in another README, perhaps blinker01, fun.c is in a 43 | separate file so that is in a separate optimization domain, by being 44 | separate they wont optimize out this program completely and simply 45 | return a value. I added more_fun() to demonstrate this 46 | 47 | prepare and call fun 48 | 49 | 8274: ed9f0a0c vldr s0, [pc, #48] ; 82ac 50 | 8278: e3a00c01 mov r0, #256 ; 0x100 51 | 827c: ebffff78 bl 8064 52 | 8280: ebffffb3 bl 8154 53 | 54 | prepare and call fun 55 | 56 | 8284: ed9f0a09 vldr s0, [pc, #36] ; 82b0 57 | 8288: e3a00c01 mov r0, #256 ; 0x100 58 | 828c: ebffff74 bl 8064 59 | 8290: ebffffaf bl 8154 60 | 61 | optimized out the call to more_fun, answer computed at compile time 62 | and simply printed out 63 | 64 | 8294: e3a00d06 mov r0, #384 ; 0x180 65 | 8298: ebffffad bl 8154 66 | 67 | same here, no actual floating point, resolved at compile time 68 | 69 | 829c: e3a00c03 mov r0, #768 ; 0x300 70 | 82a0: ebffffab bl 8154 71 | 72 | By using a separate file I can still use the optimizer and at the 73 | same time not have it optimize out the actual floating point 74 | instructions. 75 | 76 | 00008064 : 77 | 8064: ee070a90 vmov s15, r0 78 | 8068: eef87a67 vcvt.f32.u32 s15, s15 79 | 806c: ee270a80 vmul.f32 s0, s15, s0 80 | 8070: eefc7ac0 vcvt.u32.f32 s15, s0 81 | 8074: ee170a90 vmov r0, s15 82 | 8078: e12fff1e bx lr 83 | 84 | Note the calling convention here, normally we deal with r0-r3 and 85 | then stack stuff, when you build for hard float the floating point 86 | registers are used for parameters, need to remember that in case you 87 | use floating point and interrupts, you need to save the state of the 88 | machine. 89 | 90 | This is not enough 91 | 92 | irq: 93 | push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} 94 | bl c_irq_handler 95 | pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} 96 | subs pc,lr,#4 97 | 98 | And/or you need to insure you are not using floating point in your 99 | interrupt handler. 100 | 101 | A lot of work to multiply by 1.5 and 3.0 but I only needed to do one 102 | or two operations to prove to myself that the floating point unit is 103 | actually being used (as well as code being generated). 104 | 105 | 12345678 106 | 00000180 107 | 00000300 108 | 00000180 109 | 00000300 110 | -------------------------------------------------------------------------------- /float01/fun.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------- 3 | //------------------------------------------------------------------- 4 | 5 | unsigned int fun ( unsigned int u, float f ) 6 | { 7 | return(u*f); 8 | } 9 | 10 | //------------------------------------------------------------------- 11 | //------------------------------------------------------------------- 12 | 13 | 14 | //------------------------------------------------------------------- 15 | // 16 | // Copyright (c) 2012 David Welch dwelch@dwelch.com 17 | // 18 | // 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: 19 | // 20 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 21 | // 22 | // 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. 23 | // 24 | //------------------------------------------------------------------- 25 | 26 | -------------------------------------------------------------------------------- /float01/memmap: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x1000 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | .bss : { *(.bss*) } > ram 11 | } 12 | 13 | -------------------------------------------------------------------------------- /float01/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------- 3 | //------------------------------------------------------------------- 4 | 5 | // 2 outer corner sd card end 6 | // 4 7 | // 6 8 | // 8 TX out 9 | // 10 RX in 10 | 11 | extern void PUT32 ( unsigned int, unsigned int ); 12 | extern void PUT16 ( unsigned int, unsigned int ); 13 | extern void PUT8 ( unsigned int, unsigned int ); 14 | extern unsigned int GET32 ( unsigned int ); 15 | extern unsigned int GETPC ( void ); 16 | extern void dummy ( unsigned int ); 17 | extern unsigned int BRANCHTO ( unsigned int ); 18 | 19 | extern void uart_init ( void ); 20 | extern unsigned int uart_lcr ( void ); 21 | extern void uart_flush ( void ); 22 | extern void uart_send ( unsigned int ); 23 | extern unsigned int uart_recv ( void ); 24 | extern unsigned int uart_check ( void ); 25 | extern void hexstring ( unsigned int ); 26 | extern void hexstrings ( unsigned int ); 27 | extern void timer_init ( void ); 28 | extern unsigned int timer_tick ( void ); 29 | 30 | extern void timer_init ( void ); 31 | extern unsigned int timer_tick ( void ); 32 | 33 | unsigned int fun ( unsigned int u, float f ); 34 | 35 | //------------------------------------------------------------------- 36 | static unsigned int more_fun ( unsigned int u, float f ) 37 | { 38 | return(u*f); 39 | } 40 | //------------------------------------------------------------------- 41 | int notmain ( void ) 42 | { 43 | uart_init(); 44 | hexstring(0x12345678); 45 | 46 | hexstring(fun(0x100,1.5F)); 47 | hexstring(fun(0x100,3.0F)); 48 | hexstring(more_fun(0x100,1.5F)); 49 | hexstring(more_fun(0x100,3.0F)); 50 | 51 | return(0); 52 | } 53 | //------------------------------------------------------------------- 54 | //------------------------------------------------------------------- 55 | 56 | //------------------------------------------------------------------- 57 | // 58 | // Copyright (c) 2014 David Welch dwelch@dwelch.com 59 | // 60 | // 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: 61 | // 62 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 63 | // 64 | // 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. 65 | // 66 | //------------------------------------------------------------------- 67 | -------------------------------------------------------------------------------- /float01/periph.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------- 3 | //------------------------------------------------------------------- 4 | 5 | #define PBASE 0x20000000 6 | 7 | extern void PUT32 ( unsigned int, unsigned int ); 8 | extern void PUT16 ( unsigned int, unsigned int ); 9 | extern void PUT8 ( unsigned int, unsigned int ); 10 | extern unsigned int GET32 ( unsigned int ); 11 | extern void dummy ( unsigned int ); 12 | 13 | #define ARM_TIMER_CTL (PBASE+0x0000B408) 14 | #define ARM_TIMER_CNT (PBASE+0x0000B420) 15 | 16 | #define GPFSEL1 (PBASE+0x00200004) 17 | #define GPSET0 (PBASE+0x0020001C) 18 | #define GPCLR0 (PBASE+0x00200028) 19 | #define GPPUD (PBASE+0x00200094) 20 | #define GPPUDCLK0 (PBASE+0x00200098) 21 | 22 | #define AUX_ENABLES (PBASE+0x00215004) 23 | #define AUX_MU_IO_REG (PBASE+0x00215040) 24 | #define AUX_MU_IER_REG (PBASE+0x00215044) 25 | #define AUX_MU_IIR_REG (PBASE+0x00215048) 26 | #define AUX_MU_LCR_REG (PBASE+0x0021504C) 27 | #define AUX_MU_MCR_REG (PBASE+0x00215050) 28 | #define AUX_MU_LSR_REG (PBASE+0x00215054) 29 | #define AUX_MU_MSR_REG (PBASE+0x00215058) 30 | #define AUX_MU_SCRATCH (PBASE+0x0021505C) 31 | #define AUX_MU_CNTL_REG (PBASE+0x00215060) 32 | #define AUX_MU_STAT_REG (PBASE+0x00215064) 33 | #define AUX_MU_BAUD_REG (PBASE+0x00215068) 34 | 35 | //GPIO14 TXD0 and TXD1 36 | //GPIO15 RXD0 and RXD1 37 | 38 | // 2 outer corner sd card end 39 | // 4 40 | // 6 41 | // 8 TX out 42 | // 10 RX in 43 | 44 | //------------------------------------------------------------------- 45 | unsigned int uart_lcr ( void ) 46 | { 47 | return(GET32(AUX_MU_LSR_REG)); 48 | } 49 | //------------------------------------------------------------------- 50 | unsigned int uart_recv ( void ) 51 | { 52 | while(1) 53 | { 54 | if(GET32(AUX_MU_LSR_REG)&0x01) break; 55 | } 56 | return(GET32(AUX_MU_IO_REG)&0xFF); 57 | } 58 | //------------------------------------------------------------------- 59 | unsigned int uart_check ( void ) 60 | { 61 | if(GET32(AUX_MU_LSR_REG)&0x01) return(1); 62 | return(0); 63 | } 64 | //------------------------------------------------------------------- 65 | void uart_send ( unsigned int c ) 66 | { 67 | while(1) 68 | { 69 | if(GET32(AUX_MU_LSR_REG)&0x20) break; 70 | } 71 | PUT32(AUX_MU_IO_REG,c); 72 | } 73 | //------------------------------------------------------------------- 74 | void uart_flush ( void ) 75 | { 76 | while(1) 77 | { 78 | if(GET32(AUX_MU_LSR_REG)&0x40) break; 79 | } 80 | } 81 | //------------------------------------------------------------------- 82 | void hexstrings ( unsigned int d ) 83 | { 84 | //unsigned int ra; 85 | unsigned int rb; 86 | unsigned int rc; 87 | 88 | rb=32; 89 | while(1) 90 | { 91 | rb-=4; 92 | rc=(d>>rb)&0xF; 93 | if(rc>9) rc+=0x37; else rc+=0x30; 94 | uart_send(rc); 95 | if(rb==0) break; 96 | } 97 | uart_send(0x20); 98 | } 99 | //------------------------------------------------------------------- 100 | void hexstring ( unsigned int d ) 101 | { 102 | hexstrings(d); 103 | uart_send(0x0D); 104 | uart_send(0x0A); 105 | } 106 | //------------------------------------------------------------------- 107 | void uart_init ( void ) 108 | { 109 | unsigned int ra; 110 | 111 | PUT32(AUX_ENABLES,1); 112 | PUT32(AUX_MU_IER_REG,0); 113 | PUT32(AUX_MU_CNTL_REG,0); 114 | PUT32(AUX_MU_LCR_REG,3); 115 | PUT32(AUX_MU_MCR_REG,0); 116 | PUT32(AUX_MU_IER_REG,0); 117 | PUT32(AUX_MU_IIR_REG,0xC6); 118 | PUT32(AUX_MU_BAUD_REG,270); 119 | ra=GET32(GPFSEL1); 120 | ra&=~(7<<12); //gpio14 121 | ra|=2<<12; //alt5 122 | ra&=~(7<<15); //gpio15 123 | ra|=2<<15; //alt5 124 | PUT32(GPFSEL1,ra); 125 | //should we care? 126 | //PUT32(GPPUD,0); 127 | //for(ra=0;ra<150;ra++) dummy(ra); 128 | //PUT32(GPPUDCLK0,(1<<14)|(1<<15)); 129 | //for(ra=0;ra<150;ra++) dummy(ra); 130 | //PUT32(GPPUDCLK0,0); 131 | PUT32(AUX_MU_CNTL_REG,3); 132 | } 133 | //------------------------------------------------------------------- 134 | void timer_init ( void ) 135 | { 136 | //0xF9+1 = 250 137 | //250MHz/250 = 1MHz 138 | PUT32(ARM_TIMER_CTL,0x00F90000); 139 | PUT32(ARM_TIMER_CTL,0x00F90200); 140 | } 141 | //------------------------------------------------------------------- 142 | unsigned int timer_tick ( void ) 143 | { 144 | return(GET32(ARM_TIMER_CNT)); 145 | } 146 | //------------------------------------------------------------------- 147 | //------------------------------------------------------------------- 148 | 149 | //------------------------------------------------------------------- 150 | // 151 | // Copyright (c) 2012 David Welch dwelch@dwelch.com 152 | // 153 | // 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: 154 | // 155 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 156 | // 157 | // 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. 158 | // 159 | //------------------------------------------------------------------- 160 | -------------------------------------------------------------------------------- /float01/start.s: -------------------------------------------------------------------------------- 1 | 2 | ;@------------------------------------------------------------------- 3 | ;@------------------------------------------------------------------- 4 | 5 | .globl _start 6 | _start: 7 | b reset 8 | b hang 9 | b hang 10 | b hang 11 | b hang 12 | b hang 13 | b hang 14 | b hang 15 | 16 | reset: 17 | 18 | ;@ enable fpu 19 | mrc p15, 0, r0, c1, c0, 2 20 | orr r0,r0,#0x300000 ;@ single precision 21 | orr r0,r0,#0xC00000 ;@ double precision 22 | mcr p15, 0, r0, c1, c0, 2 23 | mov r0,#0x40000000 24 | fmxr fpexc,r0 25 | 26 | mov sp,#0x8000 27 | bl notmain 28 | hang: b hang 29 | 30 | .globl PUT32 31 | PUT32: 32 | str r1,[r0] 33 | bx lr 34 | 35 | .globl GET32 36 | GET32: 37 | ldr r0,[r0] 38 | bx lr 39 | 40 | .globl dummy 41 | dummy: 42 | bx lr 43 | 44 | .globl GETPC 45 | GETPC: 46 | mov r0,lr 47 | bx lr 48 | 49 | .globl BRANCHTO 50 | BRANCHTO: 51 | bx r0 52 | 53 | ;@------------------------------------------------------------------- 54 | ;@------------------------------------------------------------------- 55 | 56 | ;@------------------------------------------------------------------- 57 | ;@ 58 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 59 | ;@ 60 | ;@ 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: 61 | ;@ 62 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 63 | ;@ 64 | ;@ 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. 65 | ;@ 66 | ;@------------------------------------------------------------------- 67 | -------------------------------------------------------------------------------- /heartbeat/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | AOPS = --warn --fatal-warnings 6 | COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding 7 | 8 | all : kernel.img 9 | 10 | clean : 11 | rm -f *.o 12 | rm -f *.bin 13 | rm -f *.hex 14 | rm -f *.srec 15 | rm -f *.elf 16 | rm -f *.list 17 | rm -f *.img 18 | 19 | vectors.o : vectors.s 20 | $(ARMGNU)-as $(AOPS) vectors.s -o vectors.o 21 | 22 | notmain.o : notmain.c 23 | $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o 24 | 25 | notmain.elf : memmap vectors.o notmain.o 26 | $(ARMGNU)-ld vectors.o notmain.o -T memmap -o notmain.elf 27 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 28 | 29 | kernel.img : notmain.elf 30 | $(ARMGNU)-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 31 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 32 | 33 | -------------------------------------------------------------------------------- /heartbeat/README: -------------------------------------------------------------------------------- 1 | 2 | See the top level README for information on where to find documentation 3 | for the raspberry pi and the ARM processor inside. Also find information 4 | on how to load and run these programs. 5 | 6 | This is an LED blinker example for the pi zero, the source for the 7 | kernel.img binary in the root directory of this repo. 8 | 9 | The pi zero has one led that is tied to gpio 47. 10 | 11 | See blinker01 for more information. 12 | -------------------------------------------------------------------------------- /heartbeat/memmap: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x10000 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | .bss : { *(.bss*) } > ram 11 | } 12 | -------------------------------------------------------------------------------- /heartbeat/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------------- 3 | //------------------------------------------------------------------------- 4 | 5 | extern void PUT32 ( unsigned int, unsigned int ); 6 | extern unsigned int GET32 ( unsigned int ); 7 | extern void dummy ( unsigned int ); 8 | 9 | #define GPFSEL3 0x2020000C 10 | #define GPFSEL4 0x20200010 11 | #define GPSET1 0x20200020 12 | #define GPCLR1 0x2020002C 13 | 14 | //------------------------------------------------------------------------- 15 | int notmain ( void ) 16 | { 17 | unsigned int ra; 18 | 19 | ra=GET32(GPFSEL4); 20 | ra&=~(7<<21); 21 | ra|=1<<21; 22 | PUT32(GPFSEL4,ra); 23 | 24 | while(1) 25 | { 26 | PUT32(GPCLR1,1<<(47-32)); 27 | for(ra=0;ra<0x80000;ra++) dummy(ra); 28 | PUT32(GPSET1,1<<(47-32)); 29 | for(ra=0;ra<0x80000;ra++) dummy(ra); 30 | PUT32(GPCLR1,1<<(47-32)); 31 | for(ra=0;ra<0x80000;ra++) dummy(ra); 32 | PUT32(GPSET1,1<<(47-32)); 33 | for(ra=0;ra<0x300000;ra++) dummy(ra); 34 | } 35 | 36 | return(0); 37 | } 38 | //------------------------------------------------------------------------- 39 | //------------------------------------------------------------------------- 40 | 41 | 42 | //------------------------------------------------------------------------- 43 | // 44 | // Copyright (c) 2015 David Welch dwelch@dwelch.com 45 | // 46 | // 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: 47 | // 48 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 49 | // 50 | // 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. 51 | // 52 | //------------------------------------------------------------------------- 53 | -------------------------------------------------------------------------------- /heartbeat/vectors.s: -------------------------------------------------------------------------------- 1 | 2 | ;@ ------------------------------------------------------------------ 3 | ;@ ------------------------------------------------------------------ 4 | 5 | .globl _start 6 | _start: 7 | mov sp,#0x8000 8 | bl notmain 9 | hang: b hang 10 | 11 | .globl PUT32 12 | PUT32: 13 | str r1,[r0] 14 | bx lr 15 | 16 | .globl GET32 17 | GET32: 18 | ldr r0,[r0] 19 | bx lr 20 | 21 | .globl dummy 22 | dummy: 23 | bx lr 24 | 25 | ;@------------------------------------------------------------------------- 26 | ;@------------------------------------------------------------------------- 27 | 28 | 29 | ;@------------------------------------------------------------------------- 30 | ;@ 31 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 32 | ;@ 33 | ;@ 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: 34 | ;@ 35 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 36 | ;@ 37 | ;@ 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. 38 | ;@ 39 | ;@------------------------------------------------------------------------- 40 | -------------------------------------------------------------------------------- /kernel.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwelch67/raspberrypi-zero/1e8bb7889d57c7bd07b8fb52f06345a5d5d3fa83/kernel.img -------------------------------------------------------------------------------- /mmu/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | AOPS = --warn --fatal-warnings 6 | COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding 7 | 8 | all : kernel.img 9 | 10 | clean : 11 | rm -f *.o 12 | rm -f *.bin 13 | rm -f *.srec 14 | rm -f *.elf 15 | rm -f *.list 16 | rm -f *.img 17 | 18 | start.o : start.s 19 | $(ARMGNU)-as $(AOPS) start.s -o start.o 20 | 21 | notmain.o : notmain.c 22 | $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o 23 | 24 | periph.o : periph.c 25 | $(ARMGNU)-gcc $(COPS) -c periph.c -o periph.o 26 | 27 | notmain.elf : memmap start.o periph.o notmain.o 28 | $(ARMGNU)-ld start.o periph.o notmain.o -T memmap -o notmain.elf 29 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 30 | 31 | kernel.img : notmain.elf 32 | $(ARMGNU)-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 33 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 34 | 35 | -------------------------------------------------------------------------------- /mmu/memmap: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x100000 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | .bss : { *(.bss*) } > ram 11 | } 12 | 13 | -------------------------------------------------------------------------------- /mmu/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------- 3 | //------------------------------------------------------------------- 4 | 5 | // 2 outer corner sd card end 6 | // 4 7 | // 6 8 | // 8 TX out 9 | // 10 RX in 10 | 11 | extern void PUT32 ( unsigned int, unsigned int ); 12 | extern void PUT16 ( unsigned int, unsigned int ); 13 | extern unsigned int GET32 ( unsigned int ); 14 | 15 | extern void start_mmu ( unsigned int, unsigned int ); 16 | extern void stop_mmu ( void ); 17 | extern void invalidate_tlbs ( void ); 18 | extern void invalidate_caches ( void ); 19 | 20 | extern void uart_init ( void ); 21 | extern void uart_send ( unsigned int ); 22 | 23 | extern void hexstrings ( unsigned int ); 24 | extern void hexstring ( unsigned int ); 25 | 26 | unsigned int system_timer_low ( void ); 27 | 28 | #define MMUTABLEBASE 0x00004000 29 | 30 | //------------------------------------------------------------------- 31 | unsigned int mmu_section ( unsigned int vadd, unsigned int padd, unsigned int flags ) 32 | { 33 | unsigned int ra; 34 | unsigned int rb; 35 | unsigned int rc; 36 | 37 | ra=vadd>>20; 38 | rb=MMUTABLEBASE|(ra<<2); 39 | rc=(padd&0xFFF00000)|0xC00|flags|2; 40 | //hexstrings(rb); hexstring(rc); 41 | PUT32(rb,rc); 42 | return(0); 43 | } 44 | //------------------------------------------------------------------- 45 | unsigned int mmu_small ( unsigned int vadd, unsigned int padd, unsigned int flags, unsigned int mmubase ) 46 | { 47 | unsigned int ra; 48 | unsigned int rb; 49 | unsigned int rc; 50 | 51 | ra=vadd>>20; 52 | rb=MMUTABLEBASE|(ra<<2); 53 | rc=(mmubase&0xFFFFFC00)/*|(domain<<5)*/|1; 54 | //hexstrings(rb); hexstring(rc); 55 | PUT32(rb,rc); //first level descriptor 56 | ra=(vadd>>12)&0xFF; 57 | rb=(mmubase&0xFFFFFC00)|(ra<<2); 58 | rc=(padd&0xFFFFF000)|(0xFF0)|flags|2; 59 | //hexstrings(rb); hexstring(rc); 60 | PUT32(rb,rc); //second level descriptor 61 | return(0); 62 | } 63 | //------------------------------------------------------------------------ 64 | int notmain ( void ) 65 | { 66 | unsigned int ra; 67 | 68 | uart_init(); 69 | hexstring(0xDEADBEEF); 70 | 71 | PUT32(0x00045678,0x00045678); 72 | PUT32(0x00145678,0x00145678); 73 | PUT32(0x00245678,0x00245678); 74 | PUT32(0x00345678,0x00345678); 75 | 76 | PUT32(0x00346678,0x00346678); 77 | PUT32(0x00146678,0x00146678); 78 | 79 | PUT32(0x0AA45678,0x12345678); 80 | PUT32(0x0BB45678,0x12345678); 81 | PUT32(0x0CC45678,0x12345678); 82 | PUT32(0x0DD45678,0x12345678); 83 | 84 | hexstring(GET32(0x00045678)); 85 | hexstring(GET32(0x00145678)); 86 | hexstring(GET32(0x00245678)); 87 | hexstring(GET32(0x00345678)); 88 | uart_send(0x0D); uart_send(0x0A); 89 | 90 | for(ra=0;;ra+=0x00100000) 91 | { 92 | mmu_section(ra,ra,0x0000); 93 | if(ra==0xFFF00000) break; 94 | } 95 | 96 | //mmu_section(0x00000000,0x00000000,0x0000|8|4); 97 | //mmu_section(0x00100000,0x00100000,0x0000); 98 | //mmu_section(0x00200000,0x00200000,0x0000); 99 | //mmu_section(0x00300000,0x00300000,0x0000); 100 | //peripherals 101 | mmu_section(0x20000000,0x20000000,0x0000); //NOT CACHED! 102 | mmu_section(0x20200000,0x20200000,0x0000); //NOT CACHED! 103 | 104 | start_mmu(MMUTABLEBASE,0x00000001|0x1000|0x0004); //[23]=0 subpages enabled = legacy ARMv4,v5 and v6 105 | 106 | hexstring(GET32(0x00045678)); 107 | hexstring(GET32(0x00145678)); 108 | hexstring(GET32(0x00245678)); 109 | hexstring(GET32(0x00345678)); 110 | uart_send(0x0D); uart_send(0x0A); 111 | 112 | mmu_section(0x00100000,0x00300000,0x0000); 113 | mmu_section(0x00200000,0x00000000,0x0000); 114 | mmu_section(0x00300000,0x00100000,0x0000); 115 | invalidate_tlbs(); 116 | 117 | hexstring(GET32(0x00045678)); 118 | hexstring(GET32(0x00145678)); 119 | hexstring(GET32(0x00245678)); 120 | hexstring(GET32(0x00345678)); 121 | uart_send(0x0D); uart_send(0x0A); 122 | 123 | mmu_small(0x0AA45000,0x00145000,0,0x00000400); 124 | mmu_small(0x0BB45000,0x00245000,0,0x00000800); 125 | mmu_small(0x0CC45000,0x00345000,0,0x00000C00); 126 | mmu_small(0x0DD45000,0x00345000,0,0x00001000); 127 | mmu_small(0x0DD46000,0x00146000,0,0x00001000); 128 | //put these back 129 | mmu_section(0x00100000,0x00100000,0x0000); 130 | mmu_section(0x00200000,0x00200000,0x0000); 131 | mmu_section(0x00300000,0x00300000,0x0000); 132 | invalidate_tlbs(); 133 | 134 | hexstring(GET32(0x0AA45678)); 135 | hexstring(GET32(0x0BB45678)); 136 | hexstring(GET32(0x0CC45678)); 137 | uart_send(0x0D); uart_send(0x0A); 138 | 139 | hexstring(GET32(0x00345678)); 140 | hexstring(GET32(0x00346678)); 141 | hexstring(GET32(0x0DD45678)); 142 | hexstring(GET32(0x0DD46678)); 143 | uart_send(0x0D); uart_send(0x0A); 144 | 145 | //access violation. 146 | 147 | mmu_section(0x00100000,0x00100000,0x0020); 148 | invalidate_tlbs(); 149 | 150 | hexstring(GET32(0x00045678)); 151 | hexstring(GET32(0x00145678)); 152 | hexstring(GET32(0x00245678)); 153 | hexstring(GET32(0x00345678)); 154 | uart_send(0x0D); uart_send(0x0A); 155 | 156 | hexstring(0xDEADBEEF); 157 | 158 | return(0); 159 | } 160 | //------------------------------------------------------------------- 161 | //------------------------------------------------------------------- 162 | 163 | //------------------------------------------------------------------- 164 | // 165 | // Copyright (c) 2014 David Welch dwelch@dwelch.com 166 | // 167 | // 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: 168 | // 169 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 170 | // 171 | // 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. 172 | // 173 | //------------------------------------------------------------------- 174 | -------------------------------------------------------------------------------- /mmu/novectors.s: -------------------------------------------------------------------------------- 1 | 2 | 3 | .globl _start 4 | _start: 5 | ldr pc,add_handler_00 6 | ldr pc,add_handler_04 7 | ldr pc,add_handler_08 8 | ldr pc,add_handler_0C 9 | ldr pc,add_handler_10 10 | ldr pc,add_handler_14 11 | ldr pc,add_handler_18 12 | ldr pc,add_handler_1C 13 | add_handler_00: .word reset 14 | add_handler_04: .word handler_04 15 | add_handler_08: .word handler_08 16 | add_handler_0C: .word handler_0C 17 | add_handler_10: .word handler_10 18 | add_handler_14: .word handler_14 19 | add_handler_18: .word handler_18 20 | add_handler_1C: .word handler_1C 21 | 22 | reset: 23 | mov r0,#0x8000 24 | mov r1,#0x0000 25 | ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} 26 | stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} 27 | ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} 28 | stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} 29 | 30 | mov sp,#0x00100000 31 | mov r0,pc 32 | bl notmain 33 | hang: b hang 34 | 35 | 36 | 37 | handler_04: 38 | mov r0,#0x04 39 | b handler 40 | 41 | handler_08: 42 | mov r0,#0x08 43 | b handler 44 | 45 | handler_0C: 46 | mov r0,#0x0C 47 | b handler 48 | 49 | handler_10: 50 | mov r7,r0 51 | mov r0,#0x10 52 | ;@b handler 53 | b data_abort 54 | 55 | handler_14: 56 | mov r0,#0x14 57 | b handler 58 | 59 | handler_18: 60 | mov r0,#0x18 61 | b handler 62 | 63 | handler_1C: 64 | mov r0,#0x1C 65 | b handler 66 | 67 | 68 | handler: 69 | mov r4,lr 70 | mov sp,#0x00004000 71 | bl hexstring 72 | mov r0,r4 73 | bl hexstring 74 | b hang 75 | 76 | data_abort: 77 | mov r6,lr 78 | ldr r8,[r6,#-8] 79 | mrc p15,0,r4,c5,c0,0 ;@ data/combined 80 | mrc p15,0,r5,c5,c0,1 ;@ instruction 81 | mov sp,#0x00004000 82 | bl hexstring 83 | mov r0,r4 84 | bl hexstring 85 | mov r0,r5 86 | bl hexstring 87 | mov r0,r6 88 | bl hexstring 89 | mov r0,r8 90 | bl hexstring 91 | mov r0,r7 92 | bl hexstring 93 | b hang 94 | 95 | .globl PUT32 96 | PUT32: 97 | str r1,[r0] 98 | bx lr 99 | 100 | .globl GET32 101 | GET32: 102 | ldr r0,[r0] 103 | bx lr 104 | 105 | .globl dummy 106 | dummy: 107 | bx lr 108 | 109 | .globl start_mmu 110 | start_mmu: 111 | mov r2,#0 112 | mcr p15,0,r2,c7,c7,0 ;@ invalidate caches 113 | mcr p15,0,r2,c8,c7,0 ;@ invalidate tlb 114 | mcr p15,0,r2,c7,c10,4 ;@ DSB ?? 115 | 116 | mvn r2,#0 117 | bic r2,#0xC 118 | mcr p15,0,r2,c3,c0,0 ;@ domain 119 | 120 | mcr p15,0,r0,c2,c0,0 ;@ tlb base 121 | mcr p15,0,r0,c2,c0,1 ;@ tlb base 122 | 123 | mrc p15,0,r2,c1,c0,0 124 | orr r2,r2,r1 125 | mcr p15,0,r2,c1,c0,0 126 | 127 | bx lr 128 | 129 | .globl stop_mmu 130 | stop_mmu: 131 | mrc p15,0,r2,c1,c0,0 132 | bic r2,#0x1000 133 | bic r2,#0x0004 134 | bic r2,#0x0001 135 | mcr p15,0,r2,c1,c0,0 136 | bx lr 137 | 138 | .globl invalidate_tlbs 139 | invalidate_tlbs: 140 | mov r2,#0 141 | mcr p15,0,r2,c8,c7,0 ;@ invalidate tlb 142 | mcr p15,0,r2,c7,c10,4 ;@ DSB ?? 143 | bx lr 144 | 145 | 146 | 147 | ;@------------------------------------------------------------------------- 148 | ;@ 149 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 150 | ;@ 151 | ;@ 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: 152 | ;@ 153 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 154 | ;@ 155 | ;@ 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. 156 | ;@ 157 | ;@------------------------------------------------------------------------- 158 | -------------------------------------------------------------------------------- /mmu/periph.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------- 3 | //------------------------------------------------------------------- 4 | 5 | extern void PUT32 ( unsigned int, unsigned int ); 6 | extern void PUT16 ( unsigned int, unsigned int ); 7 | extern void PUT8 ( unsigned int, unsigned int ); 8 | extern unsigned int GET32 ( unsigned int ); 9 | extern void BRANCHTO ( unsigned int ); 10 | extern void dummy ( unsigned int ); 11 | 12 | #define SYSTIMERCLO (0x20003004) 13 | 14 | #define GPFSEL1 (0x20200004) 15 | #define GPSET0 (0x2020001C) 16 | #define GPCLR0 (0x20200028) 17 | #define GPPUD (0x20200094) 18 | #define GPPUDCLK0 (0x20200098) 19 | 20 | #define AUX_ENABLES (0x20215004) 21 | #define AUX_MU_IO_REG (0x20215040) 22 | #define AUX_MU_IER_REG (0x20215044) 23 | #define AUX_MU_IIR_REG (0x20215048) 24 | #define AUX_MU_LCR_REG (0x2021504C) 25 | #define AUX_MU_MCR_REG (0x20215050) 26 | #define AUX_MU_LSR_REG (0x20215054) 27 | #define AUX_MU_MSR_REG (0x20215058) 28 | #define AUX_MU_SCRATCH (0x2021505C) 29 | #define AUX_MU_CNTL_REG (0x20215060) 30 | #define AUX_MU_STAT_REG (0x20215064) 31 | #define AUX_MU_BAUD_REG (0x20215068) 32 | 33 | //GPIO14 TXD0 and TXD1 34 | //GPIO15 RXD0 and RXD1 35 | 36 | // 2 outer corner sd card end 37 | // 4 38 | // 6 39 | // 8 TX out 40 | // 10 RX in 41 | 42 | //------------------------------------------------------------------- 43 | unsigned int uart_lcr ( void ) 44 | { 45 | return(GET32(AUX_MU_LSR_REG)); 46 | } 47 | //------------------------------------------------------------------- 48 | unsigned int uart_recv ( void ) 49 | { 50 | while(1) 51 | { 52 | if(GET32(AUX_MU_LSR_REG)&0x01) break; 53 | } 54 | return(GET32(AUX_MU_IO_REG)&0xFF); 55 | } 56 | //------------------------------------------------------------------- 57 | unsigned int uart_check ( void ) 58 | { 59 | if(GET32(AUX_MU_LSR_REG)&0x01) return(1); 60 | return(0); 61 | } 62 | //------------------------------------------------------------------- 63 | void uart_send ( unsigned int c ) 64 | { 65 | while(1) 66 | { 67 | if(GET32(AUX_MU_LSR_REG)&0x20) break; 68 | } 69 | PUT32(AUX_MU_IO_REG,c); 70 | } 71 | //------------------------------------------------------------------- 72 | void uart_flush ( void ) 73 | { 74 | while(1) 75 | { 76 | if(GET32(AUX_MU_LSR_REG)&0x40) break; 77 | } 78 | } 79 | //------------------------------------------------------------------- 80 | void hexstrings ( unsigned int d ) 81 | { 82 | //unsigned int ra; 83 | unsigned int rb; 84 | unsigned int rc; 85 | 86 | rb=32; 87 | while(1) 88 | { 89 | rb-=4; 90 | rc=(d>>rb)&0xF; 91 | if(rc>9) rc+=0x37; else rc+=0x30; 92 | uart_send(rc); 93 | if(rb==0) break; 94 | } 95 | uart_send(0x20); 96 | } 97 | //------------------------------------------------------------------- 98 | void hexstring ( unsigned int d ) 99 | { 100 | hexstrings(d); 101 | uart_send(0x0D); 102 | uart_send(0x0A); 103 | } 104 | //------------------------------------------------------------------- 105 | void uart_init ( void ) 106 | { 107 | unsigned int ra; 108 | 109 | PUT32(AUX_ENABLES,1); 110 | PUT32(AUX_MU_IER_REG,0); 111 | PUT32(AUX_MU_CNTL_REG,0); 112 | PUT32(AUX_MU_LCR_REG,3); 113 | PUT32(AUX_MU_MCR_REG,0); 114 | PUT32(AUX_MU_IER_REG,0); 115 | PUT32(AUX_MU_IIR_REG,0xC6); 116 | PUT32(AUX_MU_BAUD_REG,270); 117 | ra=GET32(GPFSEL1); 118 | ra&=~(7<<12); //gpio14 119 | ra|=2<<12; //alt5 120 | ra&=~(7<<15); //gpio15 121 | ra|=2<<15; //alt5 122 | PUT32(GPFSEL1,ra); 123 | //should we care? 124 | //PUT32(GPPUD,0); 125 | //for(ra=0;ra<150;ra++) dummy(ra); 126 | //PUT32(GPPUDCLK0,(1<<14)|(1<<15)); 127 | //for(ra=0;ra<150;ra++) dummy(ra); 128 | //PUT32(GPPUDCLK0,0); 129 | PUT32(AUX_MU_CNTL_REG,3); 130 | } 131 | //------------------------------------------------------------------- 132 | unsigned int system_timer_low ( void ) 133 | { 134 | return(GET32(SYSTIMERCLO)); 135 | } 136 | //------------------------------------------------------------------- 137 | //------------------------------------------------------------------- 138 | 139 | //------------------------------------------------------------------- 140 | // 141 | // Copyright (c) 2012 David Welch dwelch@dwelch.com 142 | // 143 | // 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: 144 | // 145 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 146 | // 147 | // 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. 148 | // 149 | //------------------------------------------------------------------- 150 | -------------------------------------------------------------------------------- /mmu/start.s: -------------------------------------------------------------------------------- 1 | 2 | ;@------------------------------------------------------------------- 3 | ;@------------------------------------------------------------------- 4 | 5 | .globl _start 6 | _start: 7 | ldr pc,add_handler_00 8 | ldr pc,add_handler_04 9 | ldr pc,add_handler_08 10 | ldr pc,add_handler_0C 11 | ldr pc,add_handler_10 12 | ldr pc,add_handler_14 13 | ldr pc,add_handler_18 14 | ldr pc,add_handler_1C 15 | add_handler_00: .word reset 16 | add_handler_04: .word handler_04 17 | add_handler_08: .word handler_08 18 | add_handler_0C: .word handler_0C 19 | add_handler_10: .word handler_10 20 | add_handler_14: .word handler_14 21 | add_handler_18: .word handler_18 22 | add_handler_1C: .word handler_1C 23 | 24 | reset: 25 | mov r0,#0x8000 26 | mov r1,#0x0000 27 | ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} 28 | stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} 29 | ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} 30 | stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} 31 | 32 | mov sp,#0x00100000 33 | mov r0,pc 34 | bl notmain 35 | hang: b hang 36 | 37 | 38 | 39 | handler_04: 40 | mov r0,#0x04 41 | b handler 42 | 43 | handler_08: 44 | mov r0,#0x08 45 | b handler 46 | 47 | handler_0C: 48 | mov r0,#0x0C 49 | b handler 50 | 51 | handler_10: 52 | mov r7,r0 53 | mov r0,#0x10 54 | ;@b handler 55 | b data_abort 56 | 57 | handler_14: 58 | mov r0,#0x14 59 | b handler 60 | 61 | handler_18: 62 | mov r0,#0x18 63 | b handler 64 | 65 | handler_1C: 66 | mov r0,#0x1C 67 | b handler 68 | 69 | 70 | handler: 71 | mov r4,lr 72 | mov sp,#0x00004000 73 | bl hexstring 74 | mov r0,r4 75 | bl hexstring 76 | b hang 77 | 78 | data_abort: 79 | mov r6,lr 80 | ldr r8,[r6,#-8] 81 | mrc p15,0,r4,c5,c0,0 ;@ data/combined 82 | mrc p15,0,r5,c5,c0,1 ;@ instruction 83 | mov sp,#0x00004000 84 | bl hexstring 85 | mov r0,r4 86 | bl hexstring 87 | mov r0,r5 88 | bl hexstring 89 | mov r0,r6 90 | bl hexstring 91 | mov r0,r8 92 | bl hexstring 93 | mov r0,r7 94 | bl hexstring 95 | b hang 96 | 97 | .globl PUT32 98 | PUT32: 99 | str r1,[r0] 100 | bx lr 101 | 102 | .globl GET32 103 | GET32: 104 | ldr r0,[r0] 105 | bx lr 106 | 107 | .globl dummy 108 | dummy: 109 | bx lr 110 | 111 | .globl start_mmu 112 | start_mmu: 113 | mov r2,#0 114 | mcr p15,0,r2,c7,c7,0 ;@ invalidate caches 115 | mcr p15,0,r2,c8,c7,0 ;@ invalidate tlb 116 | mcr p15,0,r2,c7,c10,4 ;@ DSB ?? 117 | 118 | mvn r2,#0 119 | bic r2,#0xC 120 | mcr p15,0,r2,c3,c0,0 ;@ domain 121 | 122 | mcr p15,0,r0,c2,c0,0 ;@ tlb base 123 | mcr p15,0,r0,c2,c0,1 ;@ tlb base 124 | 125 | mrc p15,0,r2,c1,c0,0 126 | orr r2,r2,r1 127 | mcr p15,0,r2,c1,c0,0 128 | 129 | bx lr 130 | 131 | .globl stop_mmu 132 | stop_mmu: 133 | mrc p15,0,r2,c1,c0,0 134 | bic r2,#0x1000 135 | bic r2,#0x0004 136 | bic r2,#0x0001 137 | mcr p15,0,r2,c1,c0,0 138 | bx lr 139 | 140 | .globl invalidate_tlbs 141 | invalidate_tlbs: 142 | mov r2,#0 143 | mcr p15,0,r2,c8,c7,0 ;@ invalidate tlb 144 | mcr p15,0,r2,c7,c10,4 ;@ DSB ?? 145 | bx lr 146 | 147 | ;@------------------------------------------------------------------- 148 | ;@------------------------------------------------------------------- 149 | 150 | 151 | ;@------------------------------------------------------------------- 152 | ;@ 153 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 154 | ;@ 155 | ;@ 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: 156 | ;@ 157 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 158 | ;@ 159 | ;@ 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. 160 | ;@ 161 | ;@------------------------------------------------------------------- 162 | -------------------------------------------------------------------------------- /mysetup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwelch67/raspberrypi-zero/1e8bb7889d57c7bd07b8fb52f06345a5d5d3fa83/mysetup.png -------------------------------------------------------------------------------- /reset_switch1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwelch67/raspberrypi-zero/1e8bb7889d57c7bd07b8fb52f06345a5d5d3fa83/reset_switch1.jpg -------------------------------------------------------------------------------- /reset_switch2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwelch67/raspberrypi-zero/1e8bb7889d57c7bd07b8fb52f06345a5d5d3fa83/reset_switch2.jpg -------------------------------------------------------------------------------- /swi00/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | AOPS = --warn --fatal-warnings 6 | COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding 7 | 8 | all : kernel.img 9 | 10 | clean : 11 | rm -f *.o 12 | rm -f *.bin 13 | rm -f *.srec 14 | rm -f *.elf 15 | rm -f *.list 16 | rm -f *.img 17 | 18 | start.o : start.s 19 | $(ARMGNU)-as $(AOPS) start.s -o start.o 20 | 21 | notmain.o : notmain.c 22 | $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o 23 | 24 | periph.o : periph.c 25 | $(ARMGNU)-gcc $(COPS) -c periph.c -o periph.o 26 | 27 | notmain.elf : memmap start.o periph.o notmain.o 28 | $(ARMGNU)-ld start.o periph.o notmain.o -T memmap -o notmain.elf 29 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 30 | 31 | kernel.img : notmain.elf 32 | $(ARMGNU)-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 33 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 34 | 35 | -------------------------------------------------------------------------------- /swi00/README: -------------------------------------------------------------------------------- 1 | 2 | See the top level README for information on where to find documentation 3 | for the raspberry pi and the ARM processor inside. Also find information 4 | on how to load and run these programs. 5 | 6 | This is a simple swi call example 7 | 8 | -------------------------------------------------------------------------------- /swi00/memmap: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x1000 5 | } 6 | SECTIONS 7 | { 8 | .text : { *(.text*) } > ram 9 | .bss : { *(.bss*) } > ram 10 | } 11 | 12 | -------------------------------------------------------------------------------- /swi00/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | extern void uart_init ( void ); 3 | extern void hexstring ( unsigned int ); 4 | extern unsigned int myswicall ( unsigned int, unsigned int ); 5 | 6 | unsigned int my_swi_handler ( unsigned int a, unsigned int b ) 7 | { 8 | return(a+b); 9 | } 10 | 11 | int notmain ( void ) 12 | { 13 | uart_init(); 14 | hexstring(0x12345678); 15 | hexstring(myswicall(5,6)); 16 | return(0); 17 | } 18 | 19 | // 20 | // Copyright (c) 2014 David Welch dwelch@dwelch.com 21 | // 22 | // 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: 23 | // 24 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 25 | // 26 | // 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. 27 | // 28 | -------------------------------------------------------------------------------- /swi00/periph.c: -------------------------------------------------------------------------------- 1 | 2 | #define PBASE 0x20000000 3 | extern void PUT32 ( unsigned int, unsigned int ); 4 | extern unsigned int GET32 ( unsigned int ); 5 | #define GPFSEL1 (PBASE+0x00200004) 6 | #define AUX_ENABLES (PBASE+0x00215004) 7 | #define AUX_MU_IO_REG (PBASE+0x00215040) 8 | #define AUX_MU_IER_REG (PBASE+0x00215044) 9 | #define AUX_MU_IIR_REG (PBASE+0x00215048) 10 | #define AUX_MU_LCR_REG (PBASE+0x0021504C) 11 | #define AUX_MU_MCR_REG (PBASE+0x00215050) 12 | #define AUX_MU_LSR_REG (PBASE+0x00215054) 13 | #define AUX_MU_CNTL_REG (PBASE+0x00215060) 14 | #define AUX_MU_BAUD_REG (PBASE+0x00215068) 15 | 16 | //GPIO14 TXD0 and TXD1 17 | //GPIO15 RXD0 and RXD1 18 | 19 | // 2 outer corner sd card end 20 | // 4 21 | // 6 22 | // 8 TX out 23 | // 10 RX in 24 | 25 | static void uart_send ( unsigned int c ) 26 | { 27 | while(1) 28 | { 29 | if(GET32(AUX_MU_LSR_REG)&0x20) break; 30 | } 31 | PUT32(AUX_MU_IO_REG,c); 32 | } 33 | static void hexstrings ( unsigned int d ) 34 | { 35 | //unsigned int ra; 36 | unsigned int rb; 37 | unsigned int rc; 38 | 39 | rb=32; 40 | while(1) 41 | { 42 | rb-=4; 43 | rc=(d>>rb)&0xF; 44 | if(rc>9) rc+=0x37; else rc+=0x30; 45 | uart_send(rc); 46 | if(rb==0) break; 47 | } 48 | uart_send(0x20); 49 | } 50 | void hexstring ( unsigned int d ) 51 | { 52 | hexstrings(d); 53 | uart_send(0x0D); 54 | uart_send(0x0A); 55 | } 56 | void uart_init ( void ) 57 | { 58 | unsigned int ra; 59 | 60 | PUT32(AUX_ENABLES,1); 61 | PUT32(AUX_MU_IER_REG,0); 62 | PUT32(AUX_MU_CNTL_REG,0); 63 | PUT32(AUX_MU_LCR_REG,3); 64 | PUT32(AUX_MU_MCR_REG,0); 65 | PUT32(AUX_MU_IER_REG,0); 66 | PUT32(AUX_MU_IIR_REG,0xC6); 67 | PUT32(AUX_MU_BAUD_REG,270); 68 | ra=GET32(GPFSEL1); 69 | ra&=~(7<<12); //gpio14 70 | ra|=2<<12; //alt5 71 | ra&=~(7<<15); //gpio15 72 | ra|=2<<15; //alt5 73 | PUT32(GPFSEL1,ra); 74 | 75 | PUT32(AUX_MU_CNTL_REG,3); 76 | } 77 | 78 | 79 | // 80 | // Copyright (c) 2012 David Welch dwelch@dwelch.com 81 | // 82 | // 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: 83 | // 84 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 85 | // 86 | // 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. 87 | // 88 | 89 | -------------------------------------------------------------------------------- /swi00/start.s: -------------------------------------------------------------------------------- 1 | 2 | ;@------------------------------------------------------------------- 3 | ;@------------------------------------------------------------------- 4 | 5 | .globl _start 6 | _start: 7 | ldr pc,reset_handler 8 | ldr pc,undefined_handler 9 | ldr pc,swi_handler 10 | ldr pc,prefetch_handler 11 | ldr pc,data_handler 12 | ldr pc,unused_handler 13 | ldr pc,irq_handler 14 | ldr pc,fiq_handler 15 | reset_handler: .word reset 16 | undefined_handler: .word hang 17 | swi_handler: .word doswi 18 | prefetch_handler: .word hang 19 | data_handler: .word hang 20 | unused_handler: .word hang 21 | irq_handler: .word hang 22 | fiq_handler: .word hang 23 | 24 | .type reset,%function 25 | reset: 26 | mov r0,#0x8000 27 | mov r1,#0x0000 28 | ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} 29 | stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} 30 | ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} 31 | stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} 32 | mov sp,#0x8000 33 | bl notmain 34 | b hang 35 | .type hang,%function 36 | hang: b hang 37 | 38 | 39 | .type PUT32,%function 40 | .globl PUT32 41 | PUT32: 42 | str r1,[r0] 43 | bx lr 44 | 45 | .type GET32,%function 46 | .globl GET32 47 | GET32: 48 | ldr r0,[r0] 49 | bx lr 50 | 51 | .type myswicall,%function 52 | .globl myswicall 53 | myswicall: 54 | push {r3,lr} 55 | swi 0 56 | pop {r3,lr} 57 | bx lr 58 | 59 | .code 32 60 | .type doswi,%function 61 | doswi: 62 | push {r3,lr} 63 | bl my_swi_handler 64 | pop {r3,lr} 65 | movs pc,lr 66 | 67 | 68 | 69 | ;@------------------------------------------------------------------- 70 | ;@------------------------------------------------------------------- 71 | 72 | ;@------------------------------------------------------------------- 73 | ;@ 74 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 75 | ;@ 76 | ;@ 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: 77 | ;@ 78 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 79 | ;@ 80 | ;@ 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. 81 | ;@ 82 | ;@------------------------------------------------------------------- 83 | -------------------------------------------------------------------------------- /uart01/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | AOPS = --warn --fatal-warnings 6 | COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding 7 | 8 | all : kernel.img 9 | 10 | clean : 11 | rm -f *.o 12 | rm -f *.bin 13 | rm -f *.hex 14 | rm -f *.srec 15 | rm -f *.elf 16 | rm -f *.list 17 | rm -f *.img 18 | 19 | vectors.o : vectors.s 20 | $(ARMGNU)-as $(AOPS) vectors.s -o vectors.o 21 | 22 | notmain.o : notmain.c 23 | $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o 24 | 25 | notmain.elf : memmap vectors.o notmain.o 26 | $(ARMGNU)-ld vectors.o notmain.o -T memmap -o notmain.elf 27 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 28 | 29 | kernel.img : notmain.elf 30 | $(ARMGNU)-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 31 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 32 | 33 | -------------------------------------------------------------------------------- /uart01/README: -------------------------------------------------------------------------------- 1 | 2 | See the top level README for information on where to find documentation 3 | for the raspberry pi and the ARM processor inside. Also find information 4 | on how to load and run these programs. 5 | 6 | This is a simple uart example for the pi zero. 7 | 8 | Okay this was incredibly painful. I might have saved a few hours if 9 | was at the office with an oscilloscope, I eventually had to fashion 10 | something to look at the output using an mbed. 11 | 12 | The documentation for the chip has some glaring errors. The IER and 13 | IIR register descriptions are screwy. The one that killed me was 14 | the word length. The document says that the single bit controls 7 15 | bits per word vs 8 bits per word. And that bit 1 and some above 16 | do not do anything, they might on real 16550's but not here. Well 17 | that is wrong. If bits 1:0 are 00 you get 7 bits if bits 1:0 are 01 18 | you get 7 bits. You need bit 1 set to get 8 bits. 19 | 20 | See the top level README for information about connecting your host 21 | computer to the uart on the raspi. This is a tx only example. 22 | 23 | This example sets up the uart for 115200 baud, and blasts the characters 24 | 0123456701234567...forever as fast as it can. 25 | -------------------------------------------------------------------------------- /uart01/memmap: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x1000 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | .bss : { *(.bss*) } > ram 11 | } 12 | 13 | -------------------------------------------------------------------------------- /uart01/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------- 3 | //------------------------------------------------------------------- 4 | 5 | extern void PUT32 ( unsigned int, unsigned int ); 6 | extern unsigned int GET32 ( unsigned int ); 7 | extern void dummy ( unsigned int ); 8 | 9 | #define GPFSEL1 0x20200004 10 | #define GPSET0 0x2020001C 11 | #define GPCLR0 0x20200028 12 | #define GPPUD 0x20200094 13 | #define GPPUDCLK0 0x20200098 14 | 15 | #define AUX_ENABLES 0x20215004 16 | #define AUX_MU_IO_REG 0x20215040 17 | #define AUX_MU_IER_REG 0x20215044 18 | #define AUX_MU_IIR_REG 0x20215048 19 | #define AUX_MU_LCR_REG 0x2021504C 20 | #define AUX_MU_MCR_REG 0x20215050 21 | #define AUX_MU_LSR_REG 0x20215054 22 | #define AUX_MU_MSR_REG 0x20215058 23 | #define AUX_MU_SCRATCH 0x2021505C 24 | #define AUX_MU_CNTL_REG 0x20215060 25 | #define AUX_MU_STAT_REG 0x20215064 26 | #define AUX_MU_BAUD_REG 0x20215068 27 | 28 | //GPIO14 TXD0 and TXD1 29 | //GPIO15 RXD0 and RXD1 30 | //alt function 5 for uart1 31 | //alt function 0 for uart0 32 | 33 | //((250,000,000/115200)/8)-1 = 270 34 | 35 | int notmain ( void ) 36 | { 37 | unsigned int ra; 38 | 39 | PUT32(AUX_ENABLES,1); 40 | PUT32(AUX_MU_IER_REG,0); 41 | PUT32(AUX_MU_CNTL_REG,0); 42 | PUT32(AUX_MU_LCR_REG,3); 43 | PUT32(AUX_MU_MCR_REG,0); 44 | PUT32(AUX_MU_IER_REG,0); 45 | PUT32(AUX_MU_IIR_REG,0xC6); 46 | PUT32(AUX_MU_BAUD_REG,270); 47 | 48 | ra=GET32(GPFSEL1); 49 | ra&=~(7<<12); //gpio14 50 | ra|=2<<12; //alt5 51 | PUT32(GPFSEL1,ra); 52 | 53 | //should we care? 54 | //PUT32(GPPUD,0); 55 | //for(ra=0;ra<150;ra++) dummy(ra); 56 | //PUT32(GPPUDCLK0,(1<<14)); 57 | //for(ra=0;ra<150;ra++) dummy(ra); 58 | //PUT32(GPPUDCLK0,0); 59 | 60 | PUT32(AUX_MU_CNTL_REG,2); 61 | 62 | ra=0; 63 | while(1) 64 | { 65 | while(1) 66 | { 67 | if(GET32(AUX_MU_LSR_REG)&0x20) break; 68 | } 69 | PUT32(AUX_MU_IO_REG,0x30+(ra++&7)); 70 | } 71 | 72 | return(0); 73 | } 74 | //------------------------------------------------------------------- 75 | //------------------------------------------------------------------- 76 | 77 | //------------------------------------------------------------------- 78 | // 79 | // Copyright (c) 2012 David Welch dwelch@dwelch.com 80 | // 81 | // 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: 82 | // 83 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 84 | // 85 | // 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. 86 | // 87 | //------------------------------------------------------------------- 88 | -------------------------------------------------------------------------------- /uart01/vectors.s: -------------------------------------------------------------------------------- 1 | 2 | ;@------------------------------------------------------------------- 3 | ;@------------------------------------------------------------------- 4 | 5 | .globl _start 6 | _start: 7 | mov sp,#0x8000 8 | bl notmain 9 | hang: b hang 10 | 11 | .globl PUT32 12 | PUT32: 13 | str r1,[r0] 14 | bx lr 15 | 16 | .globl GET32 17 | GET32: 18 | ldr r0,[r0] 19 | bx lr 20 | 21 | .globl dummy 22 | dummy: 23 | bx lr 24 | 25 | ;@------------------------------------------------------------------- 26 | ;@ 27 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 28 | ;@ 29 | ;@ 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: 30 | ;@ 31 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 32 | ;@ 33 | ;@ 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. 34 | ;@ 35 | ;@------------------------------------------------------------------- 36 | -------------------------------------------------------------------------------- /uart02/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | AOPS = --warn --fatal-warnings 6 | COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding 7 | 8 | all : kernel.img 9 | 10 | clean : 11 | rm -f *.o 12 | rm -f *.bin 13 | rm -f *.hex 14 | rm -f *.srec 15 | rm -f *.elf 16 | rm -f *.list 17 | rm -f *.img 18 | 19 | vectors.o : vectors.s 20 | $(ARMGNU)-as $(AOPS) vectors.s -o vectors.o 21 | 22 | notmain.o : notmain.c 23 | $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o 24 | 25 | notmain.elf : memmap vectors.o notmain.o 26 | $(ARMGNU)-ld vectors.o notmain.o -T memmap -o notmain.elf 27 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 28 | 29 | kernel.img : notmain.elf 30 | $(ARMGNU)-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 31 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 32 | 33 | -------------------------------------------------------------------------------- /uart02/README: -------------------------------------------------------------------------------- 1 | See the top level README for information on where to find documentation 2 | for the raspberry pi and the ARM processor inside. Also find information 3 | on how to load and run these programs. 4 | 5 | This is a simple uart example for the pi zero. 6 | 7 | Based on uart01, this one enables the uart rxd1 receiver (gpio15). 8 | It starts by printing 12345678 then whatever you type on the terminal 9 | is echoed back. 10 | 11 | See the top level README file for information on how to connect the 12 | raspi uart to your host computer. 13 | 14 | Using a dumb terminal (minicom) 115200 board No parity 8 bits 1 stop 15 | bit, no flow control (might have to exit minicom and start again for 16 | the flow control setting to take). What you type on the dumb terminal 17 | comes back. 18 | -------------------------------------------------------------------------------- /uart02/memmap: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x1000 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | .bss : { *(.bss*) } > ram 11 | } 12 | 13 | -------------------------------------------------------------------------------- /uart02/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------- 3 | //------------------------------------------------------------------- 4 | 5 | extern void PUT32 ( unsigned int, unsigned int ); 6 | extern unsigned int GET32 ( unsigned int ); 7 | extern void dummy ( unsigned int ); 8 | 9 | #define GPFSEL1 0x20200004 10 | #define GPSET0 0x2020001C 11 | #define GPCLR0 0x20200028 12 | #define GPPUD 0x20200094 13 | #define GPPUDCLK0 0x20200098 14 | 15 | #define AUX_ENABLES 0x20215004 16 | #define AUX_MU_IO_REG 0x20215040 17 | #define AUX_MU_IER_REG 0x20215044 18 | #define AUX_MU_IIR_REG 0x20215048 19 | #define AUX_MU_LCR_REG 0x2021504C 20 | #define AUX_MU_MCR_REG 0x20215050 21 | #define AUX_MU_LSR_REG 0x20215054 22 | #define AUX_MU_MSR_REG 0x20215058 23 | #define AUX_MU_SCRATCH 0x2021505C 24 | #define AUX_MU_CNTL_REG 0x20215060 25 | #define AUX_MU_STAT_REG 0x20215064 26 | #define AUX_MU_BAUD_REG 0x20215068 27 | 28 | //GPIO14 TXD0 and TXD1 29 | //GPIO15 RXD0 and RXD1 30 | //alt function 5 for uart1 31 | //alt function 0 for uart0 32 | 33 | //((250,000,000/115200)/8)-1 = 270 34 | //------------------------------------------------------------------- 35 | void uart_putc ( unsigned int c ) 36 | { 37 | while(1) 38 | { 39 | if(GET32(AUX_MU_LSR_REG)&0x20) break; 40 | } 41 | PUT32(AUX_MU_IO_REG,c); 42 | } 43 | //------------------------------------------------------------------- 44 | void hexstrings ( unsigned int d ) 45 | { 46 | //unsigned int ra; 47 | unsigned int rb; 48 | unsigned int rc; 49 | 50 | rb=32; 51 | while(1) 52 | { 53 | rb-=4; 54 | rc=(d>>rb)&0xF; 55 | if(rc>9) rc+=0x37; else rc+=0x30; 56 | uart_putc(rc); 57 | if(rb==0) break; 58 | } 59 | uart_putc(0x20); 60 | } 61 | //------------------------------------------------------------------- 62 | void hexstring ( unsigned int d ) 63 | { 64 | hexstrings(d); 65 | uart_putc(0x0D); 66 | uart_putc(0x0A); 67 | } 68 | //------------------------------------------------------------------- 69 | int notmain ( unsigned int earlypc ) 70 | { 71 | unsigned int ra; 72 | 73 | PUT32(AUX_ENABLES,1); 74 | PUT32(AUX_MU_IER_REG,0); 75 | PUT32(AUX_MU_CNTL_REG,0); 76 | PUT32(AUX_MU_LCR_REG,3); 77 | PUT32(AUX_MU_MCR_REG,0); 78 | PUT32(AUX_MU_IER_REG,0); 79 | PUT32(AUX_MU_IIR_REG,0xC6); 80 | PUT32(AUX_MU_BAUD_REG,270); 81 | 82 | ra=GET32(GPFSEL1); 83 | ra&=~(7<<12); //gpio14 84 | ra|=2<<12; //alt5 85 | ra&=~(7<<15); //gpio15 86 | ra|=2<<15; //alt5 87 | PUT32(GPFSEL1,ra); 88 | 89 | //should we care? 90 | //PUT32(GPPUD,0); 91 | //for(ra=0;ra<150;ra++) dummy(ra); 92 | //PUT32(GPPUDCLK0,(1<<14)|(1<<15)); 93 | //for(ra=0;ra<150;ra++) dummy(ra); 94 | //PUT32(GPPUDCLK0,0); 95 | 96 | PUT32(AUX_MU_CNTL_REG,3); 97 | 98 | hexstring(0x12345678); 99 | hexstring(earlypc); 100 | 101 | while(1) 102 | { 103 | while(1) 104 | { 105 | if(GET32(AUX_MU_LSR_REG)&0x01) break; 106 | } 107 | ra=GET32(AUX_MU_IO_REG); 108 | //while(1) 109 | //{ 110 | //if(GET32(AUX_MU_LSR_REG)&0x20) break; 111 | //} 112 | PUT32(AUX_MU_IO_REG,ra); 113 | } 114 | 115 | return(0); 116 | } 117 | //------------------------------------------------------------------- 118 | //------------------------------------------------------------------- 119 | 120 | //------------------------------------------------------------------- 121 | // 122 | // Copyright (c) 2012 David Welch dwelch@dwelch.com 123 | // 124 | // 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: 125 | // 126 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 127 | // 128 | // 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. 129 | // 130 | //------------------------------------------------------------------- 131 | -------------------------------------------------------------------------------- /uart02/vectors.s: -------------------------------------------------------------------------------- 1 | 2 | .globl _start 3 | _start: 4 | mov sp,#0x8000 5 | mov r0,pc 6 | bl notmain 7 | hang: b hang 8 | 9 | .globl PUT32 10 | PUT32: 11 | str r1,[r0] 12 | bx lr 13 | 14 | .globl GET32 15 | GET32: 16 | ldr r0,[r0] 17 | bx lr 18 | 19 | .globl dummy 20 | dummy: 21 | bx lr 22 | 23 | 24 | ;@------------------------------------------------------------------------- 25 | ;@ 26 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 27 | ;@ 28 | ;@ 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: 29 | ;@ 30 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 31 | ;@ 32 | ;@ 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. 33 | ;@ 34 | ;@------------------------------------------------------------------------- 35 | -------------------------------------------------------------------------------- /uart03/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | AOPS = --warn --fatal-warnings 6 | COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding 7 | 8 | all : kernel.img 9 | 10 | clean : 11 | rm -f *.o 12 | rm -f *.bin 13 | rm -f *.hex 14 | rm -f *.srec 15 | rm -f *.elf 16 | rm -f *.list 17 | rm -f *.img 18 | 19 | vectors.o : vectors.s 20 | $(ARMGNU)-as $(AOPS) vectors.s -o vectors.o 21 | 22 | notmain.o : notmain.c 23 | $(ARMGNU)-gcc $(COPS) -c -mthumb notmain.c -o notmain.o 24 | 25 | notmain.elf : memmap vectors.o notmain.o 26 | $(ARMGNU)-ld vectors.o notmain.o -T memmap -o notmain.elf 27 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 28 | 29 | kernel.img : notmain.elf 30 | $(ARMGNU)-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 31 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 32 | 33 | -------------------------------------------------------------------------------- /uart03/README: -------------------------------------------------------------------------------- 1 | See the top level README for information on where to find documentation 2 | for the raspberry pi and the ARM processor inside. Also find information 3 | on how to load and run these programs. 4 | 5 | This is a simple uart example for the pi zero. 6 | 7 | Based on uart02, the difference is that this is primarily thumb code 8 | instead of ARM. ARM in this case meaning the traditional 32 bit 9 | instruction set and thumb meaning the traditional 16 bit instruction 10 | subset. 11 | 12 | Note this core does not support the thumb2 extensions. 13 | 14 | See the top level README for information on how to connect the raspi 15 | uart to your host computer. 16 | -------------------------------------------------------------------------------- /uart03/memmap: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x1000 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | .bss : { *(.bss*) } > ram 11 | } 12 | 13 | -------------------------------------------------------------------------------- /uart03/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------- 3 | //------------------------------------------------------------------- 4 | 5 | #define PBASE 0x20000000 6 | 7 | extern void PUT32 ( unsigned int, unsigned int ); 8 | extern unsigned int GET32 ( unsigned int ); 9 | extern void dummy ( unsigned int ); 10 | 11 | #define GPFSEL1 (PBASE+0x00200004) 12 | #define GPSET0 (PBASE+0x0020001C) 13 | #define GPCLR0 (PBASE+0x00200028) 14 | #define GPPUD (PBASE+0x00200094) 15 | #define GPPUDCLK0 (PBASE+0x00200098) 16 | 17 | #define AUX_ENABLES (PBASE+0x00215004) 18 | #define AUX_MU_IO_REG (PBASE+0x00215040) 19 | #define AUX_MU_IER_REG (PBASE+0x00215044) 20 | #define AUX_MU_IIR_REG (PBASE+0x00215048) 21 | #define AUX_MU_LCR_REG (PBASE+0x0021504C) 22 | #define AUX_MU_MCR_REG (PBASE+0x00215050) 23 | #define AUX_MU_LSR_REG (PBASE+0x00215054) 24 | #define AUX_MU_MSR_REG (PBASE+0x00215058) 25 | #define AUX_MU_SCRATCH (PBASE+0x0021505C) 26 | #define AUX_MU_CNTL_REG (PBASE+0x00215060) 27 | #define AUX_MU_STAT_REG (PBASE+0x00215064) 28 | #define AUX_MU_BAUD_REG (PBASE+0x00215068) 29 | 30 | //((250,000,000/115200)/8)-1 = 270 31 | //------------------------------------------------------------------- 32 | void uart_putc ( unsigned int c ) 33 | { 34 | while(1) 35 | { 36 | if(GET32(AUX_MU_LSR_REG)&0x20) break; 37 | } 38 | PUT32(AUX_MU_IO_REG,c); 39 | } 40 | //------------------------------------------------------------------- 41 | void hexstrings ( unsigned int d ) 42 | { 43 | //unsigned int ra; 44 | unsigned int rb; 45 | unsigned int rc; 46 | 47 | rb=32; 48 | while(1) 49 | { 50 | rb-=4; 51 | rc=(d>>rb)&0xF; 52 | if(rc>9) rc+=0x37; else rc+=0x30; 53 | uart_putc(rc); 54 | if(rb==0) break; 55 | } 56 | uart_putc(0x20); 57 | } 58 | //------------------------------------------------------------------- 59 | void hexstring ( unsigned int d ) 60 | { 61 | hexstrings(d); 62 | uart_putc(0x0D); 63 | uart_putc(0x0A); 64 | } 65 | //------------------------------------------------------------------- 66 | int notmain ( void ) 67 | { 68 | unsigned int ra; 69 | 70 | PUT32(AUX_ENABLES,1); 71 | PUT32(AUX_MU_IER_REG,0); 72 | PUT32(AUX_MU_CNTL_REG,0); 73 | PUT32(AUX_MU_LCR_REG,3); 74 | PUT32(AUX_MU_MCR_REG,0); 75 | PUT32(AUX_MU_IER_REG,0); 76 | PUT32(AUX_MU_IIR_REG,0xC6); 77 | PUT32(AUX_MU_BAUD_REG,270); 78 | 79 | ra=GET32(GPFSEL1); 80 | ra&=~(7<<12); //gpio14 81 | ra|=2<<12; //alt5 82 | ra&=~(7<<15); //gpio15 83 | ra|=2<<15; //alt5 84 | PUT32(GPFSEL1,ra); 85 | 86 | //should we care? 87 | //PUT32(GPPUD,0); 88 | //for(ra=0;ra<150;ra++) dummy(ra); 89 | //PUT32(GPPUDCLK0,(1<<14)|(1<<15)); 90 | //for(ra=0;ra<150;ra++) dummy(ra); 91 | //PUT32(GPPUDCLK0,0); 92 | 93 | PUT32(AUX_MU_CNTL_REG,3); 94 | 95 | hexstring(0x12345678); 96 | 97 | while(1) 98 | { 99 | while(1) 100 | { 101 | if(GET32(AUX_MU_LSR_REG)&0x01) break; 102 | } 103 | ra=GET32(AUX_MU_IO_REG); 104 | //while(1) 105 | //{ 106 | //if(GET32(AUX_MU_LSR_REG)&0x20) break; 107 | //} 108 | PUT32(AUX_MU_IO_REG,ra); 109 | } 110 | 111 | return(0); 112 | } 113 | //------------------------------------------------------------------- 114 | //------------------------------------------------------------------- 115 | 116 | //------------------------------------------------------------------- 117 | // 118 | // Copyright (c) 2012 David Welch dwelch@dwelch.com 119 | // 120 | // 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: 121 | // 122 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 123 | // 124 | // 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. 125 | // 126 | //------------------------------------------------------------------- 127 | -------------------------------------------------------------------------------- /uart03/vectors.s: -------------------------------------------------------------------------------- 1 | 2 | ;@------------------------------------------------------------------- 3 | ;@------------------------------------------------------------------- 4 | 5 | .globl _start 6 | _start: 7 | ldr sp,stack_start 8 | ldr r0,thumb_start_add 9 | bx r0 10 | 11 | stack_start: .word 0x8000 12 | thumb_start_add: .word thumb_start 13 | .word 0 14 | .word 0 15 | .word 0 16 | 17 | ;@------- 18 | 19 | .thumb 20 | .thumb_func 21 | thumb_start: 22 | bl notmain 23 | hang: b hang 24 | 25 | .thumb_func 26 | .globl PUT32 27 | PUT32: 28 | str r1,[r0] 29 | bx lr 30 | 31 | .thumb_func 32 | .globl GET32 33 | GET32: 34 | ldr r0,[r0] 35 | bx lr 36 | 37 | .thumb_func 38 | .globl dummy 39 | dummy: 40 | bx lr 41 | 42 | ;@------------------------------------------------------------------- 43 | ;@ 44 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 45 | ;@ 46 | ;@ 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: 47 | ;@ 48 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 49 | ;@ 50 | ;@ 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. 51 | ;@ 52 | ;@------------------------------------------------------------------- 53 | -------------------------------------------------------------------------------- /uart04/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | AOPS = --warn --fatal-warnings 6 | COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding 7 | 8 | all : kernel.img 9 | 10 | clean : 11 | rm -f *.o 12 | rm -f *.bin 13 | rm -f *.hex 14 | rm -f *.srec 15 | rm -f *.elf 16 | rm -f *.list 17 | rm -f *.img 18 | 19 | vectors.o : vectors.s 20 | $(ARMGNU)-as $(AOPS) vectors.s -o vectors.o 21 | 22 | notmain.o : notmain.c 23 | $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o 24 | 25 | notmain.elf : memmap vectors.o notmain.o 26 | $(ARMGNU)-ld vectors.o notmain.o -T memmap -o notmain.elf 27 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 28 | 29 | kernel.img : notmain.elf 30 | $(ARMGNU)-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 31 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 32 | 33 | -------------------------------------------------------------------------------- /uart04/README: -------------------------------------------------------------------------------- 1 | 2 | See the top level README for information on where to find documentation 3 | for the raspberry pi and the ARM processor inside. Also find information 4 | on how to load and run these programs. 5 | 6 | This is a simple uart example for the pi zero. 7 | 8 | Based on uart02 and blinker05. Like blinker05 this is a multi stage 9 | program killing three birds with one stone. First it uses polling 10 | of the interrupt status lines to show what happens to the registers, etc 11 | when an rx based interrupt occurs. Then it uses interrupt polling to 12 | receive characters rather than the uart status register. Then it 13 | enables the interrupts to the arm and uses an interrupt service routine 14 | to receive characters from the uart. 15 | 16 | As with other parts of this mini uart, the documentation has errors, 17 | bits that are marked as not used were required to make this work. When 18 | working with this mini uart also have as a reference a real 16550 manual 19 | if it doesnt work the way the BCM manual says, then pretend it is a 20 | real 16550 and see what happens. 21 | 22 | Note that the mini uart interrupt is not interrupt 57 uart_int, it is 23 | interrupt 29 aux_int. 24 | -------------------------------------------------------------------------------- /uart04/memmap: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x10000 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | .bss : { *(.bss*) } > ram 11 | } 12 | 13 | -------------------------------------------------------------------------------- /uart04/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------------- 3 | //------------------------------------------------------------------------- 4 | 5 | extern void PUT32 ( unsigned int, unsigned int ); 6 | extern unsigned int GET32 ( unsigned int ); 7 | extern void dummy ( unsigned int ); 8 | extern void enable_irq ( void ); 9 | extern void enable_fiq ( void ); 10 | 11 | #define GPFSEL1 0x20200004 12 | #define GPSET0 0x2020001C 13 | #define GPCLR0 0x20200028 14 | #define GPPUD 0x20200094 15 | #define GPPUDCLK0 0x20200098 16 | 17 | #define AUX_ENABLES 0x20215004 18 | #define AUX_MU_IO_REG 0x20215040 19 | #define AUX_MU_IER_REG 0x20215044 20 | #define AUX_MU_IIR_REG 0x20215048 21 | #define AUX_MU_LCR_REG 0x2021504C 22 | #define AUX_MU_MCR_REG 0x20215050 23 | #define AUX_MU_LSR_REG 0x20215054 24 | #define AUX_MU_MSR_REG 0x20215058 25 | #define AUX_MU_SCRATCH 0x2021505C 26 | #define AUX_MU_CNTL_REG 0x20215060 27 | #define AUX_MU_STAT_REG 0x20215064 28 | #define AUX_MU_BAUD_REG 0x20215068 29 | 30 | #define IRQ_BASIC 0x2000B200 31 | #define IRQ_PEND1 0x2000B204 32 | #define IRQ_PEND2 0x2000B208 33 | #define IRQ_FIQ_CONTROL 0x2000B210 34 | #define IRQ_ENABLE1 0x2000B210 35 | #define IRQ_ENABLE2 0x2000B214 36 | #define IRQ_ENABLE_BASIC 0x2000B218 37 | #define IRQ_DISABLE1 0x2000B21C 38 | #define IRQ_DISABLE2 0x2000B220 39 | #define IRQ_DISABLE_BASIC 0x2000B224 40 | 41 | 42 | //GPIO14 TXD0 and TXD1 43 | //GPIO15 RXD0 and RXD1 44 | //alt function 5 for uart1 45 | //alt function 0 for uart0 46 | 47 | //((250,000,000/115200)/8)-1 = 270 48 | //------------------------------------------------------------------------ 49 | void uart_init ( void ) 50 | { 51 | unsigned int ra; 52 | 53 | PUT32(AUX_ENABLES,1); 54 | PUT32(AUX_MU_IER_REG,0); 55 | PUT32(AUX_MU_CNTL_REG,0); 56 | PUT32(AUX_MU_LCR_REG,3); 57 | PUT32(AUX_MU_MCR_REG,0); 58 | PUT32(AUX_MU_IER_REG,0x5); //enable rx interrupts 59 | PUT32(AUX_MU_IIR_REG,0xC6); 60 | PUT32(AUX_MU_BAUD_REG,270); 61 | 62 | ra=GET32(GPFSEL1); 63 | ra&=~(7<<12); //gpio14 64 | ra|=2<<12; //alt5 65 | ra&=~(7<<15); //gpio15 66 | ra|=2<<15; //alt5 67 | PUT32(GPFSEL1,ra); 68 | 69 | //should we care? 70 | //PUT32(GPPUD,0); 71 | //for(ra=0;ra<150;ra++) dummy(ra); 72 | //PUT32(GPPUDCLK0,(1<<14)|(1<<15)); 73 | //for(ra=0;ra<150;ra++) dummy(ra); 74 | //PUT32(GPPUDCLK0,0); 75 | 76 | PUT32(AUX_MU_CNTL_REG,3); 77 | } 78 | //------------------------------------------------------------------------ 79 | void uart_putc ( unsigned int c ) 80 | { 81 | while(1) 82 | { 83 | if(GET32(AUX_MU_LSR_REG)&0x20) break; 84 | } 85 | PUT32(AUX_MU_IO_REG,c); 86 | } 87 | //------------------------------------------------------------------------ 88 | void hexstrings ( unsigned int d ) 89 | { 90 | //unsigned int ra; 91 | unsigned int rb; 92 | unsigned int rc; 93 | 94 | rb=32; 95 | while(1) 96 | { 97 | rb-=4; 98 | rc=(d>>rb)&0xF; 99 | if(rc>9) rc+=0x37; else rc+=0x30; 100 | uart_putc(rc); 101 | if(rb==0) break; 102 | } 103 | uart_putc(0x20); 104 | } 105 | //------------------------------------------------------------------------ 106 | void hexstring ( unsigned int d ) 107 | { 108 | hexstrings(d); 109 | uart_putc(0x0D); 110 | uart_putc(0x0A); 111 | } 112 | volatile unsigned int rxhead; 113 | volatile unsigned int rxtail; 114 | #define RXBUFMASK 0xFFF 115 | volatile unsigned char rxbuffer[RXBUFMASK+1]; 116 | //------------------------------------------------------------------------- 117 | void c_irq_handler ( void ) 118 | { 119 | unsigned int rb,rc; 120 | 121 | //an interrupt has occurred, find out why 122 | while(1) //resolve all interrupts to uart 123 | { 124 | rb=GET32(AUX_MU_IIR_REG); 125 | if((rb&1)==1) break; //no more interrupts 126 | if((rb&6)==4) 127 | { 128 | //receiver holds a valid byte 129 | rc=GET32(AUX_MU_IO_REG); //read byte from rx fifo 130 | rxbuffer[rxhead]=rc&0xFF; 131 | rxhead=(rxhead+1)&RXBUFMASK; 132 | } 133 | } 134 | 135 | } 136 | //------------------------------------------------------------------------ 137 | int notmain ( unsigned int earlypc ) 138 | { 139 | unsigned int ra; 140 | unsigned int rb; 141 | unsigned int rc; 142 | unsigned int rx; 143 | 144 | PUT32(IRQ_DISABLE1,1<<29); 145 | 146 | uart_init(); 147 | 148 | hexstring(0x12345678); 149 | for(ra=0;ra<20;ra++) hexstring(ra); 150 | hexstring(0x12345678); 151 | hexstring(earlypc); 152 | 153 | 154 | PUT32(IRQ_ENABLE1,1<<29); 155 | for(rx=0;rx<5;) 156 | { 157 | ra=GET32(IRQ_PEND1); 158 | if(ra&(1<<29)) 159 | { 160 | hexstrings(ra); 161 | hexstrings(GET32(AUX_MU_IIR_REG)); 162 | hexstring(GET32(AUX_MU_STAT_REG)); 163 | hexstring(GET32(AUX_MU_IO_REG)); 164 | hexstrings(GET32(IRQ_PEND1)); 165 | hexstrings(GET32(AUX_MU_IIR_REG)); 166 | hexstring(GET32(AUX_MU_STAT_REG)); 167 | rx++; 168 | } 169 | } 170 | hexstring(0x12345678); 171 | rxhead=rxtail; 172 | for(rx=0;rx<5;) 173 | { 174 | while(rxtail!=rxhead) 175 | { 176 | uart_putc(rxbuffer[rxtail]); 177 | rxtail=(rxtail+1)&RXBUFMASK; 178 | rx++; 179 | } 180 | ra=GET32(IRQ_PEND1); 181 | if(ra&(1<<29)) 182 | { 183 | //an interrupt has occurred, find out why 184 | while(1) //resolve all interrupts to uart 185 | { 186 | rb=GET32(AUX_MU_IIR_REG); 187 | if((rb&1)==1) break; //no more interrupts 188 | if((rb&6)==4) 189 | { 190 | //receiver holds a valid byte 191 | rc=GET32(AUX_MU_IO_REG); //read byte from rx fifo 192 | rxbuffer[rxhead]=rc&0xFF; 193 | rxhead=(rxhead+1)&RXBUFMASK; 194 | } 195 | } 196 | } 197 | } 198 | hexstring(0x12345678); 199 | enable_irq(); 200 | while(1) 201 | { 202 | while(rxtail!=rxhead) 203 | { 204 | uart_putc(rxbuffer[rxtail]); 205 | rxtail=(rxtail+1)&RXBUFMASK; 206 | rx++; 207 | } 208 | } 209 | return(0); 210 | } 211 | //------------------------------------------------------------------------- 212 | //------------------------------------------------------------------------- 213 | 214 | 215 | //------------------------------------------------------------------------- 216 | // 217 | // Copyright (c) 2012 David Welch dwelch@dwelch.com 218 | // 219 | // 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: 220 | // 221 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 222 | // 223 | // 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. 224 | // 225 | //------------------------------------------------------------------------- 226 | -------------------------------------------------------------------------------- /uart04/vectors.s: -------------------------------------------------------------------------------- 1 | 2 | ;@------------------------------------------------------------------- 3 | ;@------------------------------------------------------------------- 4 | 5 | .globl _start 6 | _start: 7 | ldr pc,reset_handler 8 | ldr pc,undefined_handler 9 | ldr pc,swi_handler 10 | ldr pc,prefetch_handler 11 | ldr pc,data_handler 12 | ldr pc,unused_handler 13 | ldr pc,irq_handler 14 | ldr pc,fiq_handler 15 | reset_handler: .word reset 16 | undefined_handler: .word hang 17 | swi_handler: .word hang 18 | prefetch_handler: .word hang 19 | data_handler: .word hang 20 | unused_handler: .word hang 21 | irq_handler: .word irq 22 | fiq_handler: .word hang 23 | 24 | reset: 25 | mov r0,#0x8000 26 | mov r1,#0x0000 27 | ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} 28 | stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} 29 | ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} 30 | stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} 31 | 32 | 33 | ;@ (PSR_IRQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) 34 | mov r0,#0xD2 35 | msr cpsr_c,r0 36 | mov sp,#0x8000 37 | 38 | ;@ (PSR_FIQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) 39 | mov r0,#0xD1 40 | msr cpsr_c,r0 41 | mov sp,#0x4000 42 | 43 | ;@ (PSR_SVC_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) 44 | mov r0,#0xD3 45 | msr cpsr_c,r0 46 | mov sp,#0x8000000 47 | 48 | ;@ SVC MODE, IRQ ENABLED, FIQ DIS 49 | ;@mov r0,#0x53 50 | ;@msr cpsr_c, r0 51 | 52 | bl notmain 53 | hang: b hang 54 | 55 | .globl PUT32 56 | PUT32: 57 | str r1,[r0] 58 | bx lr 59 | 60 | .globl GET32 61 | GET32: 62 | ldr r0,[r0] 63 | bx lr 64 | 65 | .globl dummy 66 | dummy: 67 | bx lr 68 | 69 | .globl enable_irq 70 | enable_irq: 71 | mrs r0,cpsr 72 | bic r0,r0,#0x80 73 | msr cpsr_c,r0 74 | bx lr 75 | 76 | irq: 77 | push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} 78 | bl c_irq_handler 79 | pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} 80 | subs pc,lr,#4 81 | 82 | ;@------------------------------------------------------------------- 83 | ;@------------------------------------------------------------------- 84 | 85 | ;@------------------------------------------------------------------- 86 | ;@ 87 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 88 | ;@ 89 | ;@ 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: 90 | ;@ 91 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 92 | ;@ 93 | ;@ 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. 94 | ;@ 95 | ;@------------------------------------------------------------------- 96 | 97 | -------------------------------------------------------------------------------- /uart05/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ARMGNU ?= arm-none-eabi 3 | #ARMGNU ?= arm-linux-gnueabi 4 | 5 | AOPS = --warn --fatal-warnings 6 | COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding 7 | 8 | all : kernel.img 9 | 10 | clean : 11 | rm -f *.o 12 | rm -f *.bin 13 | rm -f *.srec 14 | rm -f *.elf 15 | rm -f *.list 16 | rm -f *.img 17 | 18 | start.o : start.s 19 | $(ARMGNU)-as $(AOPS) start.s -o start.o 20 | 21 | notmain.o : notmain.c 22 | $(ARMGNU)-gcc $(COPS) -c notmain.c -o notmain.o 23 | 24 | periph.o : periph.c 25 | $(ARMGNU)-gcc $(COPS) -c periph.c -o periph.o 26 | 27 | notmain.elf : memmap start.o periph.o notmain.o 28 | $(ARMGNU)-ld start.o periph.o notmain.o -T memmap -o notmain.elf 29 | $(ARMGNU)-objdump -D notmain.elf > notmain.list 30 | 31 | kernel.img : notmain.elf 32 | $(ARMGNU)-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec 33 | $(ARMGNU)-objcopy notmain.elf -O binary kernel.img 34 | 35 | -------------------------------------------------------------------------------- /uart05/README: -------------------------------------------------------------------------------- 1 | 2 | See the top level README for information on where to find documentation 3 | for the raspberry pi and the ARM processor inside. Also find information 4 | on how to load and run these programs. 5 | 6 | This is a simple uart example for the pi zero. 7 | 8 | This is a skeleton for building generic uart based programs. 9 | 10 | Yes I did some self modifying code in there to make it easier to dump 11 | some registers of interest. In particular the MIDR (Main Identification 12 | Register). Which helps you figure out which ARM core you are using. 13 | The RPi 2 uses a Cortex-A7 r0p5 in the BCM2836, the predecessors to the 14 | RPi2 use an ARM1176JZF-S. The pi zero is an ARM11 as shown below. 15 | 16 | Raspberry Pi 2 17 | 18 | 00000000 410FC075 MIDR 19 | 00000001 84448003 CTR 20 | 00000002 00000000 TCMTR 21 | 00000003 00000000 TLBTR 22 | 00000004 410FC075 MIDR alias 23 | 00000005 80000F00 MPIDR 24 | 00000006 00000000 REVIDR 25 | 00000007 410FC075 MIDR alias 26 | 00000000 00001131 ID_PFR0 27 | 00000001 00011011 ID_PFR1 28 | 00000002 02010555 ID_DFR0 29 | 00000003 00000000 ID_AFR0 30 | 00000004 10101105 ID_MMFR0 31 | 00000005 40000000 MD_MMFR1 32 | 00000006 01240000 ID_MMFR2 33 | 00000007 02102211 ID_MMFR3 34 | 00000000 02101110 ID_ISAR0 * 35 | 00000001 13112111 ID_ISAR1 36 | 00000002 21232041 ID_ISAR2 37 | 00000003 11112131 ID_ISAR3 38 | 00000004 10011142 ID_ISAR4 39 | 00000005 00000000 ID_ISA45 40 | 41 | pizero rpi2 42 | 410FB767 410FC075 MRC p15, 0, r0, c0, c0, 0 43 | 1D152152 84448003 MRC p15, 0, r0, c0, c0, 1 44 | 00000000 00000000 MRC p15, 0, r0, c0, c0, 2 45 | 00000800 00000000 MRC p15, 0, r0, c0, c0, 3 46 | 410FB767 410FC075 MRC p15, 0, r0, c0, c0, 4 47 | 410FB767 80000F00 MRC p15, 0, r0, c0, c0, 5 48 | 410FB767 00000000 MRC p15, 0, r0, c0, c0, 6 49 | 410FB767 410FC075 MRC p15, 0, r0, c0, c0, 7 50 | 00000111 00001131 MRC p15, 0, r0, c0, c1, 0 51 | 00000011 00011011 MRC p15, 0, r0, c0, c1, 1 52 | 00000033 02010555 MRC p15, 0, r0, c0, c1, 2 53 | 00000000 00000000 MRC p15, 0, r0, c0, c1, 3 54 | 01130003 10101105 MRC p15, 0, r0, c0, c1, 4 55 | 10030302 40000000 MRC p15, 0, r0, c0, c1, 5 56 | 01222100 01240000 MRC p15, 0, r0, c0, c1, 6 57 | 00000000 02102211 MRC p15, 0, r0, c0, c1, 7 58 | 00140011 02101110 MRC p15, 0, r0, c0, c2, 0 59 | 12002111 13112111 MRC p15, 0, r0, c0, c2, 1 60 | 11231121 21232041 MRC p15, 0, r0, c0, c2, 2 61 | 01102131 11112131 MRC p15, 0, r0, c0, c2, 3 62 | 00001141 10011142 MRC p15, 0, r0, c0, c2, 4 63 | 00000000 00000000 MRC p15, 0, r0, c0, c2, 5 64 | -------------------------------------------------------------------------------- /uart05/memmap: -------------------------------------------------------------------------------- 1 | 2 | MEMORY 3 | { 4 | ram : ORIGIN = 0x8000, LENGTH = 0x1000 5 | } 6 | 7 | SECTIONS 8 | { 9 | .text : { *(.text*) } > ram 10 | .bss : { *(.bss*) } > ram 11 | } 12 | 13 | -------------------------------------------------------------------------------- /uart05/notmain.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------- 3 | //------------------------------------------------------------------- 4 | 5 | // 2 outer corner sd card end 6 | // 4 7 | // 6 8 | // 8 TX out 9 | // 10 RX in 10 | 11 | extern void PUT32 ( unsigned int, unsigned int ); 12 | extern void PUT16 ( unsigned int, unsigned int ); 13 | extern void PUT8 ( unsigned int, unsigned int ); 14 | extern unsigned int GET32 ( unsigned int ); 15 | extern unsigned int GETPC ( void ); 16 | extern void dummy ( unsigned int ); 17 | extern unsigned int BRANCHTO ( unsigned int ); 18 | 19 | extern void uart_init ( void ); 20 | extern unsigned int uart_lcr ( void ); 21 | extern void uart_flush ( void ); 22 | extern void uart_send ( unsigned int ); 23 | extern unsigned int uart_recv ( void ); 24 | extern unsigned int uart_check ( void ); 25 | extern void hexstring ( unsigned int ); 26 | extern void hexstrings ( unsigned int ); 27 | extern void timer_init ( void ); 28 | extern unsigned int timer_tick ( void ); 29 | 30 | extern void timer_init ( void ); 31 | extern unsigned int timer_tick ( void ); 32 | 33 | //------------------------------------------------------------------- 34 | int notmain ( void ) 35 | { 36 | unsigned int ra; 37 | uart_init(); 38 | hexstring(0x12345678); 39 | hexstring(GETPC()); 40 | 41 | //e12fff1e bx lr 42 | //ee100f10 mrc 15, 0, r0, cr0, cr0, {0} 43 | //ee100f30 mrc 15, 0, r0, cr0, cr0, {1} 44 | //ee100f50 mrc 15, 0, r0, cr0, cr0, {2} 45 | //ee100f70 mrc 15, 0, r0, cr0, cr0, {3} 46 | //ee100f90 mrc 15, 0, r0, cr0, cr0, {4} 47 | //ee100fb0 mrc 15, 0, r0, cr0, cr0, {5} 48 | //ee100fd0 mrc 15, 0, r0, cr0, cr0, {6} 49 | //ee100ff0 mrc 15, 0, r0, cr0, cr0, {7} 50 | //ee100f11 mrc 15, 0, r0, cr0, cr1, {0} 51 | //ee100f31 mrc 15, 0, r0, cr0, cr1, {1} 52 | //ee100f51 mrc 15, 0, r0, cr0, cr1, {2} 53 | //ee100f71 mrc 15, 0, r0, cr0, cr1, {3} 54 | //ee100f91 mrc 15, 0, r0, cr0, cr1, {4} 55 | //ee100fb1 mrc 15, 0, r0, cr0, cr1, {5} 56 | //ee100fd1 mrc 15, 0, r0, cr0, cr1, {6} 57 | //ee100ff1 mrc 15, 0, r0, cr0, cr1, {7} 58 | //ee100f12 mrc 15, 0, r0, cr0, cr2, {0} 59 | //ee100f32 mrc 15, 0, r0, cr0, cr2, {1} 60 | //ee100f52 mrc 15, 0, r0, cr0, cr2, {2} 61 | //ee100f72 mrc 15, 0, r0, cr0, cr2, {3} 62 | //ee100f92 mrc 15, 0, r0, cr0, cr2, {4} 63 | //ee100fb2 mrc 15, 0, r0, cr0, cr2, {5} 64 | //ee100fd2 mrc 15, 0, r0, cr0, cr2, {6} 65 | //ee100ff2 mrc 15, 0, r0, cr0, cr2, {7} 66 | for(ra=0;ra<8;ra++) 67 | { 68 | PUT32(0x4000,0xee100f10|(ra<<5)); 69 | PUT32(0x4004,0xe12fff1e); 70 | hexstrings(ra); 71 | hexstring(BRANCHTO(0x4000)); 72 | } 73 | for(ra=0;ra<8;ra++) 74 | { 75 | PUT32(0x4000,0xee100f11|(ra<<5)); 76 | PUT32(0x4004,0xe12fff1e); 77 | hexstrings(ra); 78 | hexstring(BRANCHTO(0x4000)); 79 | } 80 | for(ra=0;ra<8;ra++) 81 | { 82 | PUT32(0x4000,0xee100f12|(ra<<5)); 83 | PUT32(0x4004,0xe12fff1e); 84 | hexstrings(ra); 85 | hexstring(BRANCHTO(0x4000)); 86 | } 87 | return(0); 88 | } 89 | //------------------------------------------------------------------- 90 | //------------------------------------------------------------------- 91 | 92 | //------------------------------------------------------------------- 93 | // 94 | // Copyright (c) 2014 David Welch dwelch@dwelch.com 95 | // 96 | // 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: 97 | // 98 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 99 | // 100 | // 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. 101 | // 102 | //------------------------------------------------------------------- 103 | -------------------------------------------------------------------------------- /uart05/periph.c: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------- 3 | //------------------------------------------------------------------- 4 | 5 | #define PBASE 0x20000000 6 | 7 | extern void PUT32 ( unsigned int, unsigned int ); 8 | extern void PUT16 ( unsigned int, unsigned int ); 9 | extern void PUT8 ( unsigned int, unsigned int ); 10 | extern unsigned int GET32 ( unsigned int ); 11 | extern void dummy ( unsigned int ); 12 | 13 | #define ARM_TIMER_CTL (PBASE+0x0000B408) 14 | #define ARM_TIMER_CNT (PBASE+0x0000B420) 15 | 16 | #define GPFSEL1 (PBASE+0x00200004) 17 | #define GPSET0 (PBASE+0x0020001C) 18 | #define GPCLR0 (PBASE+0x00200028) 19 | #define GPPUD (PBASE+0x00200094) 20 | #define GPPUDCLK0 (PBASE+0x00200098) 21 | 22 | #define AUX_ENABLES (PBASE+0x00215004) 23 | #define AUX_MU_IO_REG (PBASE+0x00215040) 24 | #define AUX_MU_IER_REG (PBASE+0x00215044) 25 | #define AUX_MU_IIR_REG (PBASE+0x00215048) 26 | #define AUX_MU_LCR_REG (PBASE+0x0021504C) 27 | #define AUX_MU_MCR_REG (PBASE+0x00215050) 28 | #define AUX_MU_LSR_REG (PBASE+0x00215054) 29 | #define AUX_MU_MSR_REG (PBASE+0x00215058) 30 | #define AUX_MU_SCRATCH (PBASE+0x0021505C) 31 | #define AUX_MU_CNTL_REG (PBASE+0x00215060) 32 | #define AUX_MU_STAT_REG (PBASE+0x00215064) 33 | #define AUX_MU_BAUD_REG (PBASE+0x00215068) 34 | 35 | //GPIO14 TXD0 and TXD1 36 | //GPIO15 RXD0 and RXD1 37 | 38 | // 2 outer corner sd card end 39 | // 4 40 | // 6 41 | // 8 TX out 42 | // 10 RX in 43 | 44 | //------------------------------------------------------------------- 45 | unsigned int uart_lcr ( void ) 46 | { 47 | return(GET32(AUX_MU_LSR_REG)); 48 | } 49 | //------------------------------------------------------------------- 50 | unsigned int uart_recv ( void ) 51 | { 52 | while(1) 53 | { 54 | if(GET32(AUX_MU_LSR_REG)&0x01) break; 55 | } 56 | return(GET32(AUX_MU_IO_REG)&0xFF); 57 | } 58 | //------------------------------------------------------------------- 59 | unsigned int uart_check ( void ) 60 | { 61 | if(GET32(AUX_MU_LSR_REG)&0x01) return(1); 62 | return(0); 63 | } 64 | //------------------------------------------------------------------- 65 | void uart_send ( unsigned int c ) 66 | { 67 | while(1) 68 | { 69 | if(GET32(AUX_MU_LSR_REG)&0x20) break; 70 | } 71 | PUT32(AUX_MU_IO_REG,c); 72 | } 73 | //------------------------------------------------------------------- 74 | void uart_flush ( void ) 75 | { 76 | while(1) 77 | { 78 | if(GET32(AUX_MU_LSR_REG)&0x40) break; 79 | } 80 | } 81 | //------------------------------------------------------------------- 82 | void hexstrings ( unsigned int d ) 83 | { 84 | //unsigned int ra; 85 | unsigned int rb; 86 | unsigned int rc; 87 | 88 | rb=32; 89 | while(1) 90 | { 91 | rb-=4; 92 | rc=(d>>rb)&0xF; 93 | if(rc>9) rc+=0x37; else rc+=0x30; 94 | uart_send(rc); 95 | if(rb==0) break; 96 | } 97 | uart_send(0x20); 98 | } 99 | //------------------------------------------------------------------- 100 | void hexstring ( unsigned int d ) 101 | { 102 | hexstrings(d); 103 | uart_send(0x0D); 104 | uart_send(0x0A); 105 | } 106 | //------------------------------------------------------------------- 107 | void uart_init ( void ) 108 | { 109 | unsigned int ra; 110 | 111 | PUT32(AUX_ENABLES,1); 112 | PUT32(AUX_MU_IER_REG,0); 113 | PUT32(AUX_MU_CNTL_REG,0); 114 | PUT32(AUX_MU_LCR_REG,3); 115 | PUT32(AUX_MU_MCR_REG,0); 116 | PUT32(AUX_MU_IER_REG,0); 117 | PUT32(AUX_MU_IIR_REG,0xC6); 118 | PUT32(AUX_MU_BAUD_REG,270); 119 | ra=GET32(GPFSEL1); 120 | ra&=~(7<<12); //gpio14 121 | ra|=2<<12; //alt5 122 | ra&=~(7<<15); //gpio15 123 | ra|=2<<15; //alt5 124 | PUT32(GPFSEL1,ra); 125 | //should we care? 126 | //PUT32(GPPUD,0); 127 | //for(ra=0;ra<150;ra++) dummy(ra); 128 | //PUT32(GPPUDCLK0,(1<<14)|(1<<15)); 129 | //for(ra=0;ra<150;ra++) dummy(ra); 130 | //PUT32(GPPUDCLK0,0); 131 | PUT32(AUX_MU_CNTL_REG,3); 132 | } 133 | //------------------------------------------------------------------- 134 | void timer_init ( void ) 135 | { 136 | //0xF9+1 = 250 137 | //250MHz/250 = 1MHz 138 | PUT32(ARM_TIMER_CTL,0x00F90000); 139 | PUT32(ARM_TIMER_CTL,0x00F90200); 140 | } 141 | //------------------------------------------------------------------- 142 | unsigned int timer_tick ( void ) 143 | { 144 | return(GET32(ARM_TIMER_CNT)); 145 | } 146 | //------------------------------------------------------------------- 147 | //------------------------------------------------------------------- 148 | 149 | //------------------------------------------------------------------- 150 | // 151 | // Copyright (c) 2012 David Welch dwelch@dwelch.com 152 | // 153 | // 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: 154 | // 155 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 156 | // 157 | // 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. 158 | // 159 | //------------------------------------------------------------------- 160 | -------------------------------------------------------------------------------- /uart05/start.s: -------------------------------------------------------------------------------- 1 | 2 | ;@------------------------------------------------------------------- 3 | ;@------------------------------------------------------------------- 4 | 5 | .globl _start 6 | _start: 7 | b reset 8 | b hang 9 | b hang 10 | b hang 11 | b hang 12 | b hang 13 | b hang 14 | b hang 15 | 16 | reset: 17 | mov sp,#0x8000 18 | bl notmain 19 | hang: b hang 20 | 21 | .globl PUT32 22 | PUT32: 23 | str r1,[r0] 24 | bx lr 25 | 26 | .globl GET32 27 | GET32: 28 | ldr r0,[r0] 29 | bx lr 30 | 31 | .globl dummy 32 | dummy: 33 | bx lr 34 | 35 | .globl GETPC 36 | GETPC: 37 | mov r0,lr 38 | bx lr 39 | 40 | .globl BRANCHTO 41 | BRANCHTO: 42 | bx r0 43 | 44 | ;@------------------------------------------------------------------- 45 | ;@------------------------------------------------------------------- 46 | 47 | ;@------------------------------------------------------------------- 48 | ;@ 49 | ;@ Copyright (c) 2012 David Welch dwelch@dwelch.com 50 | ;@ 51 | ;@ 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: 52 | ;@ 53 | ;@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 54 | ;@ 55 | ;@ 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. 56 | ;@ 57 | ;@------------------------------------------------------------------- 58 | --------------------------------------------------------------------------------