changeset 375:19eacf4f7270

Started on memory manager
author Windel Bouwman
date Sun, 23 Mar 2014 15:44:06 +0100
parents 72a3b646d543
children 1e951e71d3f1
files kernel/startup_a9.asm python/ppci/assembler.py python/ppci/target/arm/__init__.py python/ppci/target/arm/instructions.py test/setenv.sh test/testarmasm.py test/testemulation.py test/testsamples.py util/test_patterns.txt
diffstat 9 files changed, 87 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/kernel/startup_a9.asm	Fri Mar 21 15:27:18 2014 +0100
+++ b/kernel/startup_a9.asm	Sun Mar 23 15:44:06 2014 +0100
@@ -1,10 +1,46 @@
 
+
+interrupt_vector_table:
+ivt_reset: B start  ; 0x0 reset
+ivt_undef: B undef_handler  ; 0x4 undefined instruction
+ivt_svc: B undef_handler  ; 0x08 Supervisor call
+ivt_prefetch: B undef_handler ; 0x0C prefetch abort
+ivt_data: B undef_handler  ; 0x10 data abort
+ivt_hyptrap: B undef_handler ; 0x14 not used
+ivt_irq: B undef_handler  ; 0x18 IRQ
+ivt_fiq: B undef_handler  ; 0x18 FIQ
+
+
+start:
+
+; Setup TTBR1 (translation table base register)
+
+mov r0, 0
+mcr p15, 0, r0, c2, c0, 1 ; TTBR1
+mcr p15, 0, r0, c2, c0, 0 ; TTBR0
+
+; Prepare the TTBCR (translation table base control register)
+mov r0, 0x1  ; TBD: why set this to 1?
+mcr p15, 0, r0, c2, c0, 2
+
+; Enable the VMSA (Virtual memory system architecture):
+mrc p15, 0, r0, c1, c0, 0
+; TODO:
+; orr r0, r0, 0x1
+mcr p15, 0, r0, c1, c0, 0
+
+; Setup stack:
 mov sp, 0x30000
 BL kernel_start          ; Branch to main (this is actually in the interrupt vector)
 local_loop:
 B local_loop
 
 
+; Interrupt handlers:
+
+undef_handler:
+B undef_handler
+
 ; Called to identify the proc:
 archmem_pfr0:
 mrc p15, 0, r0, c0, c1, 0
--- a/python/ppci/assembler.py	Fri Mar 21 15:27:18 2014 +0100
+++ b/python/ppci/assembler.py	Sun Mar 23 15:44:06 2014 +0100
@@ -97,7 +97,7 @@
 
     def __init__(self, kws, instruction_rules, emit):
         # Construct a parser given a grammar:
-        tokens2 = ['ID', 'NUMBER', ',', '[', ']', ':', '+', '-', '*',
+        tokens2 = ['ID', 'NUMBER', ',', '[', ']', ':', '+', '-', '*', '=',
                    pyyacc.EPS, 'COMMENT', '{', '}',
                    pyyacc.EOF, 'val32', 'val16', 'val12', 'val8', 'val5', 'val3']
         tokens2.extend(kws)
@@ -119,57 +119,17 @@
             self.add_rule(prod, rhs, f)
 
         #g.add_production('instruction', [])
-        g.add_production('expression', ['term'], lambda x: x)
-        g.add_production('expression', ['expression', 'addop', 'term'], self.p_binop)
-        g.add_production('addop', ['-'], lambda x: x.val)
-        g.add_production('addop', ['+'], lambda x: x.val)
-        g.add_production('mulop', ['*'], lambda x: x.val)
-        g.add_production('term', ['factor'], lambda x: x)
-        g.add_production('term', ['term', 'mulop', 'factor'], self.p_binop)
-        g.add_production('factor', ['ID'], lambda name: ASymbol(name.val))
-        g.add_production('factor', ['NUMBER'], lambda num: ANumber(int(num.val)))
         g.start_symbol = 'asmline'
         self.emit = emit
         self.p = g.generate_parser()
         # print('length of table:', len(self.p.action_table))
 
     # Parser handlers:
-    def p_ins_1(self, opc, ops):
-        ins = AInstruction(opc, ops)
-        self.emit(ins)
-
-    def p_ins_2(self, opc):
-        self.p_ins_1(opc, [])
-
-    def p_operands_1(self, op1):
-        return [op1]
-
-    def p_operands_2(self, ops, comma, op2):
-        assert type(ops) is list
-        ops.append(op2)
-        return ops
-
-    def p_listitems_1(self, li1):
-        return [li1]
-
-    def p_listitems_2(self, lis, comma, li2):
-        assert type(lis) is list
-        lis.append(li2)
-        return lis
-
-    def p_list_op(self, brace_open, lst, brace_close):
-        return AUnop('{}', lst)
-
-    def p_mem_op(self, brace_open, exp, brace_close):
-        return AUnop('[]', exp)
 
     def p_label(self, lname, cn):
         lab = Label(lname.val)
         self.emit(lab)
 
-    def p_binop(self, exp1, op, exp2):
-        return ABinop(op, exp1, exp2)
-
     def parse(self, lexer):
         self.p.parse(lexer)
 
--- a/python/ppci/target/arm/__init__.py	Fri Mar 21 15:27:18 2014 +0100
+++ b/python/ppci/target/arm/__init__.py	Sun Mar 23 15:44:06 2014 +0100
@@ -9,6 +9,7 @@
 from .instructions import B, Bl, Ble, Bgt, Beq, Blt, Cmp, Cmp2
 from .instructions import Push, Pop, Str, Ldr, Ldr3, Str1, Ldr1, Adr
 from .instructions import Mcr, Mrc
+from .instructions import LdrPseudo
 from .selector import ArmInstructionSelector
 from .frame import ArmFrame
 
@@ -154,6 +155,10 @@
         self.add_instruction(['ldr', 'reg', ',', 'ID'],
             lambda rhs: Ldr(rhs[1], rhs[3].val))
 
+        # This is a pseudo instruction:
+        self.add_instruction(['ldr', 'reg', ',', '=', 'ID'],
+            lambda rhs: LdrPseudo(rhs[1], rhs[4].val))
+
         self.add_keyword('str')
         self.add_instruction(['str', 'reg', ',', '[', 'reg', ',', 'imm8', ']'],
             lambda rhs: Str(rhs[1], rhs[4], rhs[6]))
@@ -165,6 +170,7 @@
         self.add_instruction(['adr', 'reg', ',', 'ID'],
             lambda rhs: Adr(rhs[1], rhs[3].val))
 
+
         # Register list grammar:
         self.add_rule('reg_list', ['{', 'reg_list_inner', '}'],
             lambda rhs: rhs[1])
--- a/python/ppci/target/arm/instructions.py	Fri Mar 21 15:27:18 2014 +0100
+++ b/python/ppci/target/arm/instructions.py	Sun Mar 23 15:44:06 2014 +0100
@@ -406,6 +406,10 @@
     raise Exception()
 
 
+def LdrPseudo(rt, lab):
+    """ Ldr rt, =lab ==> ldr rt, [pc, offset in litpool] ... dcd lab """
+    return Ldr(rt, R0)
+
 def Str(*args):
     if len(args) == 3 and isinstance(args[1], ArmRegister):
         return Str1(*args)
--- a/test/setenv.sh	Fri Mar 21 15:27:18 2014 +0100
+++ b/test/setenv.sh	Sun Mar 23 15:44:06 2014 +0100
@@ -2,5 +2,3 @@
 
 export PYTHONPATH=$PYTHONPATH:`pwd`/../python
 
-export TESTEMU=1
-
--- a/test/testarmasm.py	Fri Mar 21 15:27:18 2014 +0100
+++ b/test/testarmasm.py	Sun Mar 23 15:44:06 2014 +0100
@@ -15,7 +15,7 @@
         self.obj = ObjectFile()
         self.ostream = BinaryOutputStream(self.obj)
         self.ostream.select_section('.text')
-        self.a = a #Assembler(target=self.t)
+        self.a = a
 
     def testMovImm(self):
         self.feed('mov r4, 100')
@@ -106,6 +106,23 @@
         self.feed('dcd 0x12345566')
         self.check('04509fe5 00b09fe5 04a01fe5 66553412')
 
+    def testAdr(self):
+        self.feed('adr r5, cval')
+        self.feed('adr r9, cval')
+        self.feed('adr r8, cval')
+        self.feed('cval:')
+        self.feed('adr r11, cval')
+        self.feed('adr r12, cval')
+        self.feed('adr r1, cval')
+        self.check('04508fe2 00908fe2 04804fe2 08b04fe2 0cc04fe2 10104fe2')
+
+    @unittest.skip('Too hard')
+    def testLdrLabelAddress(self):
+        self.feed('ldr r8, =a')
+        self.feed('a:')
+        self.feed('dcd 6677')
+        self.check('00801fe5 151a0000 04000000')
+
     def testCmp(self):
         self.feed('cmp r4, r11')
         self.feed('cmp r5, 0x50000')
@@ -118,16 +135,6 @@
         self.feed('mul r4,r5,r2')
         self.check('174045e2 ffffffba 950204e0')
 
-    def testAdr(self):
-        self.feed('adr r5, cval')
-        self.feed('adr r9, cval')
-        self.feed('adr r8, cval')
-        self.feed('cval:')
-        self.feed('adr r11, cval')
-        self.feed('adr r12, cval')
-        self.feed('adr r1, cval')
-        self.check('04508fe2 00908fe2 04804fe2 08b04fe2 0cc04fe2 10104fe2')
-
     def testMcr(self):
         """ Test move coprocessor register from arm register """
         self.feed('mcr p15, 0, r1, c2, c0, 0')
--- a/test/testemulation.py	Fri Mar 21 15:27:18 2014 +0100
+++ b/test/testemulation.py	Sun Mar 23 15:44:06 2014 +0100
@@ -4,6 +4,7 @@
 import subprocess
 import socket
 import time
+import shutil
 
 from testzcc import ZccBaseTestCase
 
@@ -16,9 +17,18 @@
     except OSError:
         pass
 
+qemu_app = 'qemu-system-arm'
+
+def has_qemu():
+    """ Determines if qemu is possible """
+    return bool(shutil.which(qemu_app))
+
+
 def runQemu(kernel, machine='lm3s811evb'):
     """ Runs qemu on a given kernel file """
 
+    if not has_qemu():
+        return ''
     tryrm('qemucontrol.sock')
     tryrm('qemuserial.sock')
 
@@ -32,7 +42,7 @@
     qemu_serial_serve.bind('qemuserial.sock')
     qemu_serial_serve.listen(0)
 
-    args = ['qemu-system-arm', '-M', machine, '-m', '16M',
+    args = [qemu_app, '-M', machine, '-m', '16M',
         '-nographic',
         '-kernel', kernel,
         '-monitor', 'unix:qemucontrol.sock',
@@ -86,8 +96,8 @@
 class EmulationTestCase(ZccBaseTestCase):
     """ Tests the compiler driver """
     def setUp(self):
-        if 'TESTEMU' not in os.environ:
-            self.skipTest('Not running emulation tests')
+        if not has_qemu():
+            self.skipTest('Not running Qemu test')
 
     def testM3Bare(self):
         """ Build bare m3 binary and emulate it """
--- a/test/testsamples.py	Fri Mar 21 15:27:18 2014 +0100
+++ b/test/testsamples.py	Sun Mar 23 15:44:06 2014 +0100
@@ -1,7 +1,7 @@
 import unittest
 import os
 import io
-from testemulation import runQemu
+from testemulation import runQemu, has_qemu
 from testzcc import relpath
 from ppci.tasks import TaskRunner
 from ppci.buildtasks import Assemble, Compile, Link
@@ -115,6 +115,10 @@
 
 
 class TestSamplesOnVexpress(unittest.TestCase, Samples):
+    def setUp(self):
+        if not has_qemu():
+            self.skipTest('Not running qemu tests')
+
     def do(self, src, expected_output):
         # Construct binary file from snippet:
         o1 = ObjectFile()
--- a/util/test_patterns.txt	Fri Mar 21 15:27:18 2014 +0100
+++ b/util/test_patterns.txt	Sun Mar 23 15:44:06 2014 +0100
@@ -11,7 +11,7 @@
 ===
 yield
 ===
-push {r11,r5,r4,lr}
+push {r4, r5, r11, lr}
 ===
 pop {r4,r5,r6}
 ===
@@ -42,8 +42,6 @@
 adr r1, cval
 pop {r2}
 ===
-adr r3, pc, #1024
-===
 lsl r11, r5, r3
 lsl r4, r8, r6
 ===
@@ -59,7 +57,7 @@
 mrc p15, 0, r1, c2, c0, 0
 mrc p14, 0, r1, c8, c7, 0
 ===
-; mov sp, =a
-; a:
-; .word 0
+ldr r8, =a
+a:
+.word 6677