Mercurial > lcfOS
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')