~vdupras/duskos

520657b8def87ce2a9aee2822728982618e43ebf — Virgil Dupras 6 days ago 8b9d796
rpi: kernel runs on actual hardware

My rpi is a model 1B+, not a 1A+, but it works.
2 files changed, 23 insertions(+), 15 deletions(-)

M Makefile
M fs/xcomp/arm/rpi/kernel.fs
M Makefile => Makefile +2 -1
@@ 47,7 47,8 @@ rpi.img: dusk $(ALLSRCS)

.PHONY: rpirun
rpirun: rpi.img
	qemu-system-arm -M raspi1ap -serial stdio -display none -kernel rpi.img
	qemu-system-arm -M raspi1ap -serial stdio -display none \
		-device loader,addr=0x8000,file=rpi.img

.PHONY: run
run: dusk

M fs/xcomp/arm/rpi/kernel.fs => fs/xcomp/arm/rpi/kernel.fs +21 -14
@@ 1,6 1,6 @@
?f<< /asm/arm.fs

\ For RPI model 1A
\ For RPI model 1
$20000000 const MMIO_BASE
$200000 const GPIO_BASE
$94 const GPPUD


@@ 25,10 25,14 @@ $84 const UART0_ITIP
$88 const UART0_ITOP
$8c const UART0_TDR

: delay, ( ncycles -- )
  mov) r0 rd) swap ( ncycles ) i) ,)
  pc sub) r0 rd) r0 rn) 1 i) f) ,) ( pc ) abs>rel b) ne) ,) ;

: values ( n -- ) for 0 value next ;
2 values lblemit lblmsg

$10000 to binstart
$8000 to binstart
0 align4 here to org
forward b) ,)
pc to lblmsg ," Hello World!\0" 0 align4


@@ 36,34 40,37 @@ pc to lblemit \ r0=char
  pc
    ldr) r1 rd) r7 rn) UART0_FR +i) ,)
    tst) r1 rn) $20 i) f) ,)
    b) ne) ,)
    abs>rel b) ne) ,)
  str) r0 rd) r7 rn) UART0_DR +i) ,)
  mov) rPC rd) rLR rm) ,)
forward!
mov) r0 rd) MMIO_BASE i) ,) \ r0 = MMIO_BASE
add) r8 rd) r0 rn) GPIO_BASE i) ,) \ r8 = GPIO_BASE
mov) rSP rd) binstart i) ,)
mov) r9 rd) MMIO_BASE i) ,) \ r9 = MMIO_BASE
add) r8 rd) r9 rn) GPIO_BASE i) ,) \ r8 = GPIO_BASE
add) r7 rd) r8 rn) UART0_BASE i) ,) \ r7 = UART0_BASE
\ Disable UART0
mov) r1 rd) 0 i) ,) str) r1 rd) r7 rn) UART0_CR +i) ,)
\ Disable pull up/down for all GPIO pins & delay for 150 cycles.
( r1=0 ) str) r1 rd) r8 rn) GPPUD +i) ,)
\ TODO: add delay
150 delay,
\ Disable pull up/down for pin 14,15 & delay for 150 cycles.
mov) r1 rd) $c000 i) ,) str) r1 rd) r8 rn) GPPUDCLK0 +i) ,)
\ TODO: add delay
\ Write 0 to GPPUDCLK0 to make it take effect.
mov) r1 rd) 0 i) ,) str) r1 rd) r8 rn) GPPUDCLK0 +i) ,)
150 delay,
\ Write 0 to GPPUD and GPPUDCLK0 to make it take effect.
mov) r1 rd) 0 i) ,)
str) r1 rd) r8 rn) GPPUD +i) ,)
str) r1 rd) r8 rn) GPPUDCLK0 +i) ,)
\ Clear pending interrupts.
mov) r1 rd) $700 i) ,) add) r1 rd) r1 rn) $ff i) ,)
str) r1 rd) r7 rn) UART0_ICR +i) ,)
\ Set integer & fractional part of baud rate.
\ UART_CLOCK on rpi1 is 48Mhz
\ Divider = UART_CLOCK/(16 * Baud)
\ Fraction part register = (Fractional part * 64) + 0.5
\ Fraction part register = 64th of the unit
\ Baud = 115200.
\ Divider = 3000000 / (16 * 115200) = 1.627 = ~1.
mov) r1 rd) 1 i) ,) str) r1 rd) r7 rn) UART0_IBRD +i) ,)
\ Fractional part register = (.627 * 64) + 0.5 = 40.6 = ~40.
mov) r1 rd) 40 i) ,) str) r1 rd) r7 rn) UART0_FBRD +i) ,)
\ Divider = 48000000 / (16 * 115200) = 26.042
mov) r1 rd) 26 i) ,) str) r1 rd) r7 rn) UART0_IBRD +i) ,)
mov) r1 rd) 3 i) ,) str) r1 rd) r7 rn) UART0_FBRD +i) ,)
\ Enable FIFO & 8 bit data transmission (1 stop bit, no parity).
mov) r1 rd) $70 i) ,) str) r1 rd) r7 rn) UART0_LCRH +i) ,)
\ Mask all interrupts.