# HG changeset patch # User Windel Bouwman # Date 1394877394 -3600 # Node ID c05ab629976acb431dd7a4a4dad85f8067dcdc5a # Parent 614a7f6d4d4dee57781eab46a821979ddfdcd580 Added CPUID for arm diff -r 614a7f6d4d4d -r c05ab629976a kernel/arch/vexpressA9.c3 --- a/kernel/arch/vexpressA9.c3 Fri Mar 14 16:18:54 2014 +0100 +++ b/kernel/arch/vexpressA9.c3 Sat Mar 15 10:56:34 2014 +0100 @@ -1,10 +1,16 @@ module arch; + function void init() { // putc(65) } +function int pfr0(); +function int pfr1(); +function int mmfr0(); +function int mpuir(); + function void putc(int c) { var int *UART0DR; diff -r 614a7f6d4d4d -r c05ab629976a kernel/qemutst.sh --- a/kernel/qemutst.sh Fri Mar 14 16:18:54 2014 +0100 +++ b/kernel/qemutst.sh Sat Mar 15 10:56:34 2014 +0100 @@ -2,20 +2,7 @@ set -e -echo "quit" | socat stdio stdio - -echo "Trying to run test on stellaris qemu machine" - # -S means halt at start: qemu-system-arm -M vexpress-a9 -m 128M -kernel kernel_arm.bin \ -serial stdio -s -#sleep 1 - -# Send quit to the monitor application -#echo "quit" | socat stdio UNIX-CONNECT:vm.sock - -#echo "Output from terminal:" -#cat output.txt -#echo "" - diff -r 614a7f6d4d4d -r c05ab629976a kernel/src/kernel.c3 --- a/kernel/src/kernel.c3 Fri Mar 14 16:18:54 2014 +0100 +++ b/kernel/src/kernel.c3 Sat Mar 15 10:56:34 2014 +0100 @@ -10,16 +10,24 @@ function void start() { arch.init(); + io.println("Welcome to lcfos!"); + io.print_int(0x1337); io.print_int(0x1338); io.print2("Test: ", 0x13); var int a; - for (a = 0; a < 10; a = a + 1) + for (a = 0; a < 2; a = a + 1) { - io.print2("a = ", a); + //io.print2("a = ", a); } + + io.print2("PFR0 = ", arch.pfr0()); + io.print2("PFR1 = ", arch.pfr1()); + io.print2("MMFR0 = ", arch.mmfr0()); + io.print2("MPUIR = ", arch.mpuir()); + // process.init(); //memory:init(); diff -r 614a7f6d4d4d -r c05ab629976a kernel/startup_a9.asm --- a/kernel/startup_a9.asm Fri Mar 14 16:18:54 2014 +0100 +++ b/kernel/startup_a9.asm Sat Mar 15 10:56:34 2014 +0100 @@ -3,3 +3,22 @@ BL kernel_start ; Branch to main (this is actually in the interrupt vector) local_loop: B local_loop + + +; Called to identify the proc: +arch_pfr0: +mrc p15, 0, r0, c0, c1, 0 +mov pc, lr + +arch_pfr1: +mrc p15, 0, r0, c0, c1, 1 +mov pc, lr + +arch_mmfr0: +mrc p15, 0, r0, c0, c1, 4 +mov pc, lr + + +arch_mpuir: +mrc p15, 0, r0, c0, c0, 4 +mov pc, lr diff -r 614a7f6d4d4d -r c05ab629976a python/ppci/c3/codegenerator.py --- a/python/ppci/c3/codegenerator.py Fri Mar 14 16:18:54 2014 +0100 +++ b/python/ppci/c3/codegenerator.py Sat Mar 15 10:56:34 2014 +0100 @@ -40,12 +40,15 @@ self.funcMap = {} self.m = ir.Module(pkg.name) try: - for s in pkg.innerScope.Functions: + # Only generate function if function contains a body: + real_functions = list(filter(lambda f: f.body, pkg.innerScope.Functions)) + #real_functions = list(filter(None, pkg.innerScope.Functions)) + for s in real_functions: f = self.newFunction(s.name) self.funcMap[s] = f for v in pkg.innerScope.Variables: self.varMap[v] = self.newTemp() - for s in pkg.innerScope.Functions: + for s in real_functions: self.gen_function(s) except SemanticError as e: self.error(e.msg, e.loc) diff -r 614a7f6d4d4d -r c05ab629976a python/ppci/c3/parser.py --- a/python/ppci/c3/parser.py Fri Mar 14 16:18:54 2014 +0100 +++ b/python/ppci/c3/parser.py Sat Mar 15 10:56:34 2014 +0100 @@ -80,7 +80,7 @@ def parseTopLevel(self): if self.Peak == 'function': - self.parseFunctionDef() + self.parse_function_def() elif self.Peak == 'var': self.parseVarDef() # TODO handle variable initialization @@ -188,7 +188,7 @@ break self.Consume(';') - def parseFunctionDef(self): + def parse_function_def(self): loc = self.Consume('function').loc returntype = self.parse_type_spec() fname = self.Consume('ID').val @@ -211,7 +211,11 @@ self.Consume(')') paramtypes = [p.typ for p in parameters] f.typ = FunctionType(paramtypes, returntype) - f.body = self.parseCompound() + if self.Peak == ';': + self.Consume(';') + f.body = None + else: + f.body = self.parseCompound() self.currentPart = savePart def parse_if(self): diff -r 614a7f6d4d4d -r c05ab629976a python/ppci/c3/visitor.py --- a/python/ppci/c3/visitor.py Fri Mar 14 16:18:54 2014 +0100 +++ b/python/ppci/c3/visitor.py Sat Mar 15 10:56:34 2014 +0100 @@ -24,7 +24,8 @@ for s in node.declarations: self.do(s) self.do(node.typ) - self.do(node.body) + if node.body: + self.do(node.body) elif type(node) is Compound: for s in node.statements: self.do(s) diff -r 614a7f6d4d4d -r c05ab629976a python/ppci/target/arm/__init__.py --- a/python/ppci/target/arm/__init__.py Fri Mar 14 16:18:54 2014 +0100 +++ b/python/ppci/target/arm/__init__.py Sat Mar 15 10:56:34 2014 +0100 @@ -8,6 +8,7 @@ from .instructions import Lsr1, Lsl1, And1, Sub1 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 .selector import ArmInstructionSelector from .frame import ArmFrame @@ -75,6 +76,8 @@ self.add_keyword('mov') self.add_instruction(['mov', 'reg', ',', 'imm32'], lambda rhs: Mov(rhs[1], rhs[3])) + self.add_instruction(['mov', 'reg', ',', 'reg'], + lambda rhs: Mov(rhs[1], rhs[3])) self.add_keyword('cmp') self.add_instruction(['cmp', 'reg', ',', 'imm32'], @@ -169,3 +172,25 @@ self.add_rule('reg_or_range', ['reg', '-', 'reg'], lambda rhs: register_range(rhs[0], rhs[2])) + + # Add MCR and MRC (co-processor) + for i in range(16): + creg = 'c{}'.format(i) + self.add_keyword(creg) + self.add_rule('coreg', [creg], i) + + for i in range(8, 16): + px = 'p{}'.format(i) + self.add_keyword(px) + # Ran into trouble when using i inside lambda function: + # When using inside lambda (as a closure), i is bound to the latest + # value (15) + self.add_rule('coproc', [px], i) + + self.add_keyword('mcr') + self.add_instruction(['mcr', 'coproc', ',', 'imm3', ',', 'reg', ',', 'coreg', ',', 'coreg', ',', 'imm3'], + lambda rhs: Mcr(rhs[1], rhs[3], rhs[5], rhs[7], rhs[9], rhs[11])) + + self.add_keyword('mrc') + self.add_instruction(['mrc', 'coproc', ',', 'imm3', ',', 'reg', ',', 'coreg', ',', 'coreg', ',', 'imm3'], + lambda rhs: Mrc(rhs[1], rhs[3], rhs[5], rhs[7], rhs[9], rhs[11])) diff -r 614a7f6d4d4d -r c05ab629976a python/ppci/target/arm/instructions.py --- a/python/ppci/target/arm/instructions.py Fri Mar 14 16:18:54 2014 +0100 +++ b/python/ppci/target/arm/instructions.py Sat Mar 15 10:56:34 2014 +0100 @@ -495,3 +495,36 @@ self.token[16:23] = 0b0011111 self.token[24:28] = 0b0101 return self.token.encode() + + +class McrBase(ArmInstruction): + """ Mov arm register to coprocessor register """ + def __init__(self, coproc, opc1, rt, crn, crm, opc2): + super().__init__() + self.coproc = coproc + self.opc1 = opc1 + self.rt = rt + self.crn = crn + self.crm = crm + self.opc2 = opc2 + + def encode(self): + self.token[0:4] = self.crm + self.token[4] = 1 + self.token[5:8] = self.opc2 + self.token[8:12] = self.coproc + self.token[12:16] = self.rt.num + self.token[16:20] = self.crn + self.token[20] = self.b20 + self.token[21:24] = self.opc1 + self.token[24:28] = 0b1110 + self.token.cond = AL + return self.token.encode() + + +class Mcr(McrBase): + b20 = 0 + + +class Mrc(McrBase): + b20 = 1 diff -r 614a7f6d4d4d -r c05ab629976a python/ppci/target/basetarget.py --- a/python/ppci/target/basetarget.py Fri Mar 14 16:18:54 2014 +0100 +++ b/python/ppci/target/basetarget.py Sat Mar 15 10:56:34 2014 +0100 @@ -1,3 +1,4 @@ +import types from ppci import CompilerError """ @@ -124,7 +125,12 @@ self.add_rule('instruction', rhs, f) def add_rule(self, lhs, rhs, f): - self.assembler_rules.append((lhs, rhs, f)) + if type(f) is int: + f2 = lambda x: f + else: + f2 = f + assert type(f2) is types.FunctionType + self.assembler_rules.append((lhs, rhs, f2)) def lower_frame_to_stream(self, frame, outs): """ Lower instructions from frame to output stream """ diff -r 614a7f6d4d4d -r c05ab629976a test/testarmasm.py --- a/test/testarmasm.py Fri Mar 14 16:18:54 2014 +0100 +++ b/test/testarmasm.py Sat Mar 15 10:56:34 2014 +0100 @@ -25,6 +25,14 @@ self.feed('mov sp, 0x6000') self.check('06daa0e3') + def testMovReg(self): + self.feed('mov r3, sp') + self.feed('mov pc, lr') + self.feed('mov pc, r2') + self.feed('mov sp, r4') + self.feed('mov r5, r6') + self.check('0d30a0e1 0ef0a0e1 02f0a0e1 04d0a0e1 0650a0e1') + def testAdd2(self): self.feed('add r12, r11, 300') self.check('4bcf8be2') @@ -120,6 +128,17 @@ 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') + self.feed('mcr p14, 0, r1, c8, c7, 0') + self.check('101f02ee 171e08ee') + + def testMrc(self): + self.feed('mrc p15, 0, r1, c2, c0, 0') + self.feed('mrc p14, 0, r1, c8, c7, 0') + self.check('101f12ee 171e18ee') + if __name__ == '__main__': unittest.main() diff -r 614a7f6d4d4d -r c05ab629976a test/testsamples.py --- a/test/testsamples.py Fri Mar 14 16:18:54 2014 +0100 +++ b/test/testsamples.py Sat Mar 15 10:56:34 2014 +0100 @@ -23,19 +23,21 @@ function void start() { var int i; - for (i=0;i<10;i++) + for (i=0; i<10; i++) { - io.print("A"); + io.print2("A = ", i); } } """ - self.do(snippet, "AAAAAAAAAA") + res = "".join("A = 0x{0:08X}\n".format(a) for a in range(10)) + self.do(snippet, res) class TestSamplesOnVexpress(unittest.TestCase, Samples): def do(self, src, expected_output): runner = TaskRunner() recipe_loader = RecipeLoader(runner) + print(expected_output) return # TODO: improve recipe loading?? recipe_loader.load_dict({ @@ -54,3 +56,5 @@ res = runQemu() self.assertEqual(expected_output, res) +if __name__ == '__main__': + unittest.main() diff -r 614a7f6d4d4d -r c05ab629976a util/test_patterns.txt --- a/util/test_patterns.txt Fri Mar 14 16:18:54 2014 +0100 +++ b/util/test_patterns.txt Sat Mar 15 10:56:34 2014 +0100 @@ -4,6 +4,10 @@ mov sp, #0x6000 === mov r3, sp +mov pc, lr +mov pc, r2 +mov sp, r4 +mov r5, r6 === yield === @@ -46,3 +50,10 @@ === and r9, r0, r2 and r4, r8, r6 +=== +mcr p15, 0, r1, c2, c0, 0 +mcr p14, 0, r1, c8, c7, 0 +=== +mrc p15, 0, r1, c2, c0, 0 +mrc p14, 0, r1, c8, c7, 0 +