diff --git a/litex/soc/cores/cpu/microwatt/core.py b/litex/soc/cores/cpu/microwatt/core.py index 9fd41ea00..22ce12d96 100644 --- a/litex/soc/cores/cpu/microwatt/core.py +++ b/litex/soc/cores/cpu/microwatt/core.py @@ -18,7 +18,7 @@ class Microwatt(CPU): data_width = 64 endianness = "little" gcc_triple = ("powerpc64le-linux") - linker_output_format = "elf64-powerpc64le" + linker_output_format = "elf64-powerpcle" io_regions = {0xc0000000: 0x10000000} # origin, length @property diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index 63c1f8ef0..6bafe6f1f 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -170,6 +170,8 @@ class SoCCore(Module): raise ValueError("Unsupported CPU type: {}".format(cpu_type)) # Declare the CPU self.submodules.cpu = cpu.CPUS[cpu_type](platform, self.cpu_variant) + if cpu_type == "microwatt": + self.add_constant("UART_POLLING", None) # Update Memory Map (if defined by CPU) self.soc_mem_map.update(self.cpu.mem_map) diff --git a/litex/soc/software/bios/boot-helper-microwatt.S b/litex/soc/software/bios/boot-helper-microwatt.S new file mode 100644 index 000000000..8dc226df0 --- /dev/null +++ b/litex/soc/software/bios/boot-helper-microwatt.S @@ -0,0 +1,4 @@ +.section .text, "ax", @progbits +.global boot_helper +boot_helper: + nop # FIXME diff --git a/litex/soc/software/bios/isr.c b/litex/soc/software/bios/isr.c index aa47caccd..68944072d 100644 --- a/litex/soc/software/bios/isr.c +++ b/litex/soc/software/bios/isr.c @@ -56,7 +56,9 @@ void isr(void) irqs = irq_pending() & irq_getmask(); +#ifndef UART_POLLING if(irqs & (1 << UART_INTERRUPT)) uart_isr(); +#endif } #endif diff --git a/litex/soc/software/bios/sdram.c b/litex/soc/software/bios/sdram.c index 652d9098f..712138d23 100644 --- a/litex/soc/software/bios/sdram.c +++ b/litex/soc/software/bios/sdram.c @@ -46,6 +46,8 @@ __attribute__((unused)) static void cdelay(int i) __asm__ volatile("nop"); #elif defined (__powerpc__) __asm__ volatile("nop"); +#elif defined (__microwatt__) + __asm__ volatile("nop"); #else #error Unsupported architecture #endif diff --git a/litex/soc/software/include/base/irq.h b/litex/soc/software/include/base/irq.h index 4bf6786c4..a9d1fecbe 100644 --- a/litex/soc/software/include/base/irq.h +++ b/litex/soc/software/include/base/irq.h @@ -56,6 +56,8 @@ static inline unsigned int irq_getie(void) return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0; #elif defined (__rocket__) return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0; +#elif defined (__microwatt__) + return 0; // FIXME #else #error Unsupported architecture #endif @@ -81,6 +83,8 @@ static inline void irq_setie(unsigned int ie) if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE); #elif defined (__rocket__) if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE); +#elif defined (__microwatt__) + // FIXME #else #error Unsupported architecture #endif @@ -108,6 +112,8 @@ static inline unsigned int irq_getmask(void) return mask; #elif defined (__rocket__) return csr_readl(PLIC_ENABLED) >> 1; +#elif defined (__microwatt__) + return 0; // FIXME #else #error Unsupported architecture #endif @@ -129,6 +135,8 @@ static inline void irq_setmask(unsigned int mask) asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask)); #elif defined (__rocket__) csr_writel(mask << 1, PLIC_ENABLED); +#elif defined (__microwatt__) + // FIXME #else #error Unsupported architecture #endif @@ -154,6 +162,8 @@ static inline unsigned int irq_pending(void) return pending; #elif defined (__rocket__) return csr_readl(PLIC_PENDING) >> 1; +#elif defined (__microwatt__) + return 0; // FIXME #else #error Unsupported architecture #endif diff --git a/litex/soc/software/libbase/crt0-microwatt.S b/litex/soc/software/libbase/crt0-microwatt.S new file mode 100644 index 000000000..0dd6f343b --- /dev/null +++ b/litex/soc/software/libbase/crt0-microwatt.S @@ -0,0 +1,102 @@ +/* Copyright 2013-2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define STACK_TOP 0xffff4000 + +#define FIXUP_ENDIAN \ + tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \ + b 191f; /* Skip trampoline if endian is good */ \ + .long 0xa600607d; /* mfmsr r11 */ \ + .long 0x01006b69; /* xori r11,r11,1 */ \ + .long 0x05009f42; /* bcl 20,31,$+4 */ \ + .long 0xa602487d; /* mflr r10 */ \ + .long 0x14004a39; /* addi r10,r10,20 */ \ + .long 0xa64b5a7d; /* mthsrr0 r10 */ \ + .long 0xa64b7b7d; /* mthsrr1 r11 */ \ + .long 0x2402004c; /* hrfid */ \ +191: + + +/* Load an immediate 64-bit value into a register */ +#define LOAD_IMM64(r, e) \ + lis r,(e)@highest; \ + ori r,r,(e)@higher; \ + rldicr r,r, 32, 31; \ + oris r,r, (e)@h; \ + ori r,r, (e)@l; + + .section ".head","ax" + + . = 0 +.global _start +_start: + FIXUP_ENDIAN + + /* setup stack */ + LOAD_IMM64(%r1, STACK_TOP - 0x100) + LOAD_IMM64(%r12, main) + mtctr %r12, + bctrl + ba 0 + + /* XXX: litedram init should not take exceptions, maybe we could get + * rid of these to save space, along with a core tweak to suppress + * exceptions in case they happen (just terminate ?) + */ + +#define EXCEPTION(nr) \ + .= nr; \ + b . + + /* More exception stubs */ + EXCEPTION(0x100) + EXCEPTION(0x200) + EXCEPTION(0x300) + EXCEPTION(0x380) + EXCEPTION(0x400) + EXCEPTION(0x480) + EXCEPTION(0x500) + EXCEPTION(0x600) + EXCEPTION(0x700) + EXCEPTION(0x800) + EXCEPTION(0x900) + EXCEPTION(0x980) + EXCEPTION(0xa00) + EXCEPTION(0xb00) + EXCEPTION(0xc00) + EXCEPTION(0xd00) + EXCEPTION(0xe00) + EXCEPTION(0xe20) + EXCEPTION(0xe40) + EXCEPTION(0xe60) + EXCEPTION(0xe80) + EXCEPTION(0xf00) + EXCEPTION(0xf20) + EXCEPTION(0xf40) + EXCEPTION(0xf60) + EXCEPTION(0xf80) +#if 0 + EXCEPTION(0x1000) + EXCEPTION(0x1100) + EXCEPTION(0x1200) + EXCEPTION(0x1300) + EXCEPTION(0x1400) + EXCEPTION(0x1500) + EXCEPTION(0x1600) +#endif + + .text + diff --git a/litex/soc/software/libbase/system.c b/litex/soc/software/libbase/system.c index bb15aad06..6e7bfafdf 100644 --- a/litex/soc/software/libbase/system.c +++ b/litex/soc/software/libbase/system.c @@ -56,6 +56,9 @@ void flush_cpu_icache(void) #elif defined (__rocket__) /* FIXME: do something useful here! */ asm volatile("nop"); +#elif defined (__microwatt__) + /* FIXME: do something useful here! */ + asm volatile("nop"); #else #error Unsupported architecture #endif @@ -101,6 +104,9 @@ void flush_cpu_dcache(void) #elif defined (__rocket__) /* FIXME: do something useful here! */ asm volatile("nop"); +#elif defined (__microwatt__) + /* FIXME: do something useful here! */ + asm volatile("nop"); #else #error Unsupported architecture #endif