changeset 352:899ae3aea803

First kernel run for vexpressA9
author Windel Bouwman
date Sun, 09 Mar 2014 11:55:55 +0100
parents 62803b073d11
children b8ad45b3a573
files kernel/arch/vexpressA9.c3 kernel/arm.yaml kernel/kernel.c3 kernel/make.sh kernel/recipe.yaml kernel/startup_a9.asm kernel/thumb.yaml python/ppci/target/arm/__init__.py python/ppci/target/arm/arm.brg python/ppci/target/arm/instructions.py python/ppci/target/arm/selector.py python/ppci/target/arm/token.py readme.rst test/testarmasm.py test/testemulation.py test/testzcc.py util/test_patterns.txt
diffstat 17 files changed, 158 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/arch/vexpressA9.c3	Sun Mar 09 11:55:55 2014 +0100
@@ -0,0 +1,13 @@
+module arch;
+
+function void init()
+{
+    var int *UART0DR;
+    UART0DR = cast<int*>(0x10009000); // UART0 DR register
+    *UART0DR = 0x65;
+}
+
+function void halt()
+{
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/arm.yaml	Sun Mar 09 11:55:55 2014 +0100
@@ -0,0 +1,21 @@
+
+link:
+  inputs:
+    - assemble:
+       source: startup_a9.asm
+       machine: arm
+    - compile:
+       sources: [kernel.c3, syscall.c3, schedule.c3, 'arch/vexpressA9.c3']
+       includes: [memory.c3, process.c3]
+       machine: arm
+       output: kernel.elf2
+    - compile:
+       sources: [memory.c3, process.c3]
+       includes: [kernel.c3, syscall.c3, schedule.c3, 'arch/vexpressA9.c3']
+       machine: arm
+       output: kernel.elf2
+  layout:
+     code: 0x60010000
+     data: 0x60020000
+  output: kernel_arm.bin
+
--- a/kernel/kernel.c3	Sat Mar 08 16:46:51 2014 +0100
+++ b/kernel/kernel.c3	Sun Mar 09 11:55:55 2014 +0100
@@ -8,9 +8,7 @@
 // Main entry point of the kernel:
 function void start()
 {
-   var int* UART0DR;
-   UART0DR = cast<int*>(0x10009000); // UART0 Data register
-   *UART0DR = 72;
+    arch.init()
 
     process.init();
     //memory:init();
--- a/kernel/make.sh	Sat Mar 08 16:46:51 2014 +0100
+++ b/kernel/make.sh	Sun Mar 09 11:55:55 2014 +0100
@@ -1,3 +1,5 @@
 #!/bin/bash
 
-../python/zcc.py recipe recipe.yaml
+../python/zcc.py recipe thumb.yaml
+
+../python/zcc.py recipe arm.yaml
--- a/kernel/recipe.yaml	Sat Mar 08 16:46:51 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-
-link:
-  inputs:
-    - assemble:
-       source: startup_a9.asm
-       machine: thumb
-    - compile:
-       sources: [memory.c3, kernel.c3, syscall.c3, process.c3, schedule.c3, arch_arm.c3]
-       includes: []
-       machine: thumb
-       output: kernel.elf2
-  layout:
-     code: 0x10000
-     data: 0x20000000
-  output: kernel.bin
-
--- a/kernel/startup_a9.asm	Sat Mar 08 16:46:51 2014 +0100
+++ b/kernel/startup_a9.asm	Sun Mar 09 11:55:55 2014 +0100
@@ -1,6 +1,5 @@
 
-; DCD 0x20000678  ; Setup stack pointer
-DCD 0x06daa0e3 ; mov sp, #0x60 << 8
-DCD 0x60010009  ; Reset vector, jump to address 8
-B kernel_start          ; Branch to main (this is actually in the interrupt vector)
-
+mov sp, 0x30000
+BL kernel_start          ; Branch to main (this is actually in the interrupt vector)
+local_loop:
+B local_loop
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/thumb.yaml	Sun Mar 09 11:55:55 2014 +0100
@@ -0,0 +1,21 @@
+
+link:
+  inputs:
+    - assemble:
+       source: startup_m3.asm
+       machine: thumb
+    - compile:
+       sources: [kernel.c3, syscall.c3, schedule.c3, arch_arm.c3]
+       includes: [memory.c3, process.c3]
+       machine: thumb
+       output: kernel.elf2
+    - compile:
+       sources: [memory.c3, process.c3]
+       includes: [kernel.c3, syscall.c3, schedule.c3, arch_arm.c3]
+       machine: thumb
+       output: kernel.elf2
+  layout:
+     code: 0x10000
+     data: 0x20000000
+  output: kernel_thumb.bin
+
--- a/python/ppci/target/arm/__init__.py	Sat Mar 08 16:46:51 2014 +0100
+++ b/python/ppci/target/arm/__init__.py	Sun Mar 09 11:55:55 2014 +0100
@@ -4,8 +4,8 @@
 from ..arm.registers import R8, R9, R10, R11, R12, SP, LR, PC
 from ..arm.registers import register_range
 
-from .instructions import Dcd, Mov, Add, Sub, Orr1, Mul, Mov2
-from .instructions import B, Bl, Ble, Bgt, Beq, Blt
+from .instructions import Dcd, Mov, Add, Sub, Orr1, Mul, Mov2, Add1
+from .instructions import B, Bl, Ble, Bgt, Beq, Blt, Cmp, Cmp2
 from .instructions import Push, Pop, Str, Ldr, Ldr3, Str1, Ldr1
 from .selector import ArmInstructionSelector
 from .frame import ArmFrame
@@ -21,6 +21,8 @@
         self.add_lowering(Str1, lambda im: Str1(im.src[1], im.src[0], im.others[0]))
         self.add_lowering(Ldr1, lambda im: Ldr1(im.dst[0], im.src[0], im.others[0]))
         self.add_lowering(Mov2, lambda im: Mov2(im.dst[0], im.src[0]))
+        self.add_lowering(Cmp2, lambda im: Cmp2(im.src[0], im.src[1]))
+        self.add_lowering(Add1, lambda im: Add1(im.dst[0], im.src[0], im.src[1]))
 
     def make_parser(self):
         # Assembly grammar:
@@ -66,6 +68,13 @@
         self.add_instruction(['mov', 'reg', ',', 'imm32'],
                 lambda rhs: Mov(rhs[1], rhs[3]))
 
+        self.add_keyword('cmp')
+        self.add_instruction(['cmp', 'reg', ',', 'imm32'],
+                lambda rhs: Cmp(rhs[1], rhs[3]))
+        self.add_instruction(['cmp', 'reg', ',', 'reg'],
+                lambda rhs: Cmp(rhs[1], rhs[3]))
+
+        # Arithmatic:
         self.add_keyword('add')
         self.add_instruction(['add', 'reg', ',', 'reg', ',', 'imm32'],
                 lambda rhs: Add(rhs[1], rhs[3], rhs[5]))
--- a/python/ppci/target/arm/arm.brg	Sat Mar 08 16:46:51 2014 +0100
+++ b/python/ppci/target/arm/arm.brg	Sun Mar 09 11:55:55 2014 +0100
@@ -14,9 +14,12 @@
 reg: SUBI32(reg, reg) 2 (. d = self.newTmp(); self.emit(Sub1, dst=[d], src=[$1, $2]); return d .)
 reg: SUBI32(reg, reg) 2 (. d = self.newTmp(); self.emit(Sub1, dst=[d], src=[$1, $2]); return d .)
 reg: MEMI32(ADDI32(reg, cn)) 2 (. d = self.newTmp(); self.emit(Ldr1, dst=[d], src=[$1], others=[$2]); return d .)
+reg: MEMI32(reg) 2 (. d = self.newTmp(); self.emit(Ldr1, dst=[d], src=[$1], others=[0]); return d .)
 
 
 cn: CONSTI32 0 (. return $$.value .)
 
 reg: CONSTI32         3 (. d = self.newTmp(); ln = self.selector.frame.addConstant($$.value); self.emit(Ldr3, dst=[d], others=[ln]); return d .)
 reg: REGI32           1 (. return $$.value .)
+
+reg: CALL             1 (. return self.selector.munchCall($$.value) .)
--- a/python/ppci/target/arm/instructions.py	Sat Mar 08 16:46:51 2014 +0100
+++ b/python/ppci/target/arm/instructions.py	Sun Mar 09 11:55:55 2014 +0100
@@ -64,9 +64,6 @@
         self.token.cond = AL
         return self.token.encode()
 
-    def relocations(self):
-        return []
-
     def __repr__(self):
         return 'Mov {}, {}'.format(self.reg, self.imm)
 
@@ -91,6 +88,53 @@
         return 'MOV {}, {}'.format(self.rd, self.rm)
 
 
+def Cmp(*args):
+    if len(args) == 2:
+        if isinstance(args[1], int):
+            return Cmp1(*args)
+        elif isinstance(args[1], ArmRegister):
+            return Cmp2(*args)
+    raise Exception()
+
+
+class Cmp1(ArmInstruction):
+    """ CMP Rn, imm """
+    def __init__(self, reg, imm):
+        super().__init__()
+        assert type(imm) is int
+        self.reg = reg
+        self.imm = imm
+
+    def encode(self):
+        self.token[0:12] = encode_imm32(self.imm)
+        self.token.Rn = self.reg.num
+        self.token[20:28] = 0b00110101
+        self.token.cond = AL
+        return self.token.encode()
+
+    def __repr__(self):
+        return 'CMP {}, {}'.format(self.reg, self.imm)
+
+
+class Cmp2(ArmInstruction):
+    """ CMP Rn, Rm """
+    def __init__(self, rn, rm):
+        super().__init__()
+        self.rn = rn
+        self.rm = rm
+
+    def encode(self):
+        self.token.Rn = self.rn.num
+        self.token.Rm = self.rm.num
+        self.token[7:16] = 0
+        self.token[20:28] = 0b10101
+        self.token.cond = AL
+        return self.token.encode()
+
+    def __repr__(self):
+        return 'CMP {}, {}'.format(self.rn, self.rm)
+
+
 def Add(*args):
     if len(args) == 3 and isinstance(args[0], ArmRegister) and \
             isinstance(args[1], ArmRegister):
@@ -109,6 +153,7 @@
             return Sub2(args[0], args[1], args[2])
     raise Exception()
 
+
 def Mul(*args):
     return Mul1(args[0], args[1], args[2])
 
@@ -243,6 +288,8 @@
 class Blt(BranchBase):
     cond = LT
 
+class Bne(BranchBase):
+    cond = NE
 
 # Memory:
 
--- a/python/ppci/target/arm/selector.py	Sat Mar 08 16:46:51 2014 +0100
+++ b/python/ppci/target/arm/selector.py	Sun Mar 09 11:55:55 2014 +0100
@@ -2,7 +2,7 @@
 from ppci.irmach import AbstractInstruction as makeIns
 from ppci.ir2tree import makeTree
 from .instructions import Str1, Mov2
-from .instructions import B, Bl, Blt, Bgt, Beq
+from .instructions import B, Bl, Blt, Bgt, Beq, Bne, Cmp2
 import pyburg
 from ..basetarget import Nop
 from ..instructionselector import InstructionSelector
@@ -75,7 +75,7 @@
         elif isinstance(s, ir.CJump):
             a = self.munchExpr(s.a)
             b = self.munchExpr(s.b)
-            self.emit(Cmp, src=[a, b])
+            self.emit(Cmp2, src=[a, b])
             ntgt = self.targets[s.lab_no]
             ytgt = self.targets[s.lab_yes]
             jmp_ins = makeIns(B(ir.label_name(s.lab_no)), jumps=[ntgt])
--- a/python/ppci/target/arm/token.py	Sat Mar 08 16:46:51 2014 +0100
+++ b/python/ppci/target/arm/token.py	Sun Mar 09 11:55:55 2014 +0100
@@ -10,6 +10,7 @@
     S = bit_range(20, 21)
     Rd = bit_range(12, 16)
     Rn = bit_range(16, 20)
+    Rm = bit_range(0, 4)
 
     def encode(self):
         return u32(self.bit_value)
--- a/readme.rst	Sat Mar 08 16:46:51 2014 +0100
+++ b/readme.rst	Sun Mar 09 11:55:55 2014 +0100
@@ -60,9 +60,13 @@
 
 .. image:: https://drone.io/bitbucket.org/windel/lcfos/status.png
 
+https://drone.io/bitbucket.org/windel/lcfos
+
+Repository metrics:
+
 .. image:: https://www.ohloh.net/p/lcfos/widgets/project_thin_badge.gif
 
+http://www.ohloh.net/p/lcfos
+
 
-https://drone.io/bitbucket.org/windel/lcfos
 
-
--- a/test/testarmasm.py	Sat Mar 08 16:46:51 2014 +0100
+++ b/test/testarmasm.py	Sun Mar 09 11:55:55 2014 +0100
@@ -83,6 +83,11 @@
         self.feed('dcd 0x12345566')
         self.check('04509fe5 00b09fe5 04a01fe5 66553412')
 
+    def testCmp(self):
+        self.feed('cmp r4, r11')
+        self.feed('cmp r5, 0x50000')
+        self.check('0b0054e1 050855e3')
+
     def testSequence1(self):
         self.feed('sub r4,r5,23')
         self.feed('blt x')
--- a/test/testemulation.py	Sat Mar 08 16:46:51 2014 +0100
+++ b/test/testemulation.py	Sun Mar 09 11:55:55 2014 +0100
@@ -74,6 +74,13 @@
         data = self.runQemu('../examples/qemu_a9_hello/hello.bin', machine='vexpress-a9')
         self.assertEqual('Hello worle', data)
 
+    def testKernelVexpressA9(self):
+        """ Build vexpress cortex-A9 binary and emulate it """
+        recipe = os.path.join(testdir, '..', 'kernel', 'arm.yaml')
+        self.buildRecipe(recipe)
+        data = self.runQemu('../kernel/kernel_arm.bin', machine='vexpress-a9')
+        self.assertEqual('e', data[0])
+
 
 if __name__ == '__main__':
     unittest.main()
--- a/test/testzcc.py	Sat Mar 08 16:46:51 2014 +0100
+++ b/test/testzcc.py	Sun Mar 09 11:55:55 2014 +0100
@@ -54,9 +54,14 @@
         arg_list.append('thumb')
         self.callZcc(arg_list)
 
-    def testKernel(self):
+    def testThumbKernel(self):
         """ Build kernel using zcc: """
-        recipe = relpath('..', 'kernel', 'recipe.yaml')
+        recipe = relpath('..', 'kernel', 'thumb.yaml')
+        self.buildRecipe(recipe)
+
+    def testArmKernel(self):
+        """ Build kernel using zcc: """
+        recipe = relpath('..', 'kernel', 'arm.yaml')
         self.buildRecipe(recipe)
 
     @unittest.skip('Too difficult to fix')
--- a/util/test_patterns.txt	Sat Mar 08 16:46:51 2014 +0100
+++ b/util/test_patterns.txt	Sun Mar 09 11:55:55 2014 +0100
@@ -25,3 +25,6 @@
 ldr r10, lab1
 lab1:
 .word 0x12345566
+===
+cmp r4, r11
+cmp r5, #0x50000