From 6ffa7b067ca60a689334f0af0b2aeaeae532e0f2 Mon Sep 17 00:00:00 2001 From: Andrzej Flis Date: Sat, 12 Mar 2016 19:26:26 +0100 Subject: [PATCH] Add patches from Peter Welch --- .../tty/tty/arch/earmv6hf/rpi_serial.h | 2 +- minix/drivers/tty/tty/arch/earmv6hf/rs232.c | 8 +- minix/kernel/arch/earmv6hf/atags.h | 105 ++++++++++++++++++ minix/kernel/arch/earmv6hf/bsp/rpi/rpi_intr.c | 19 ++++ .../kernel/arch/earmv6hf/bsp/rpi/rpi_timer.c | 23 +++- .../earmv6hf/bsp/rpi/rpi_timer_registers.h | 3 + minix/kernel/arch/earmv6hf/include/cpufunc.h | 2 +- minix/kernel/arch/earmv6hf/klib.S | 6 +- minix/kernel/arch/earmv6hf/memory.c | 2 +- minix/kernel/arch/earmv6hf/mpx.S | 6 +- minix/kernel/arch/earmv6hf/pg_utils.c | 2 +- minix/kernel/arch/earmv6hf/pre_init.c | 37 ++++++ 12 files changed, 202 insertions(+), 13 deletions(-) create mode 100644 minix/kernel/arch/earmv6hf/atags.h diff --git a/minix/drivers/tty/tty/arch/earmv6hf/rpi_serial.h b/minix/drivers/tty/tty/arch/earmv6hf/rpi_serial.h index 78def4b67..ee52d274a 100644 --- a/minix/drivers/tty/tty/arch/earmv6hf/rpi_serial.h +++ b/minix/drivers/tty/tty/arch/earmv6hf/rpi_serial.h @@ -3,7 +3,7 @@ #define RPI_UART_BASE 0x20201000 /* UART1 physical address */ -#define UART011_FR_TXFF 0x020 /* Transmit-hold-register empty */ +#define UART011_FR_TXFE 0x080 /* Transmit-hold-register empty */ #define UART011_FR_RXFE 0x010 #define RPI_UART_MSR_CTS 0x10 /* Current Clear to Send */ diff --git a/minix/drivers/tty/tty/arch/earmv6hf/rs232.c b/minix/drivers/tty/tty/arch/earmv6hf/rs232.c index 23bd4e414..e2eb24152 100644 --- a/minix/drivers/tty/tty/arch/earmv6hf/rs232.c +++ b/minix/drivers/tty/tty/arch/earmv6hf/rs232.c @@ -53,13 +53,13 @@ #define istop(rs) \ (serial_out((rs), UART011_CR, UART011_CR_OUT2|UART011_CR_DTR), \ (rs)->idevready = FALSE) -/* Macro to tell if device is ready. The rs->cts field is set to UART_MSR_CTS +/* Macro to tell if device is ready. The rs->cts field is set to UART011_FR_CTS * if CLOCAL is in effect for a line without a CTS wire. */ -#define devready(rs) ((serial_in(rs, UART011_FR) | rs->cts) & UART011_FR_CTS) +#define devready(rs) (((serial_in(rs, UART011_FR) | rs->cts) & UART011_FR_CTS) ? ODEVREADY : 0) /* Macro to tell if transmitter is ready. */ -#define txready(rs) (serial_in(rs, UART011_FR) & UART011_FR_TXFF) +#define txready(rs) (serial_in(rs, UART011_FR) & UART011_FR_TXFE) /* RS232 device structure, one per device. */ typedef struct rs232 { @@ -119,7 +119,7 @@ typedef struct uart_port { } uart_port_t; static uart_port_t rpi_ports[] = { - { RPI_UART_BASE , 72 }, /* UART0 */ + { RPI_UART_BASE , 57 }, /* UART0 */ { 0, 0 }, { 0, 0 }, { 0, 0 } diff --git a/minix/kernel/arch/earmv6hf/atags.h b/minix/kernel/arch/earmv6hf/atags.h new file mode 100644 index 000000000..bef303bd9 --- /dev/null +++ b/minix/kernel/arch/earmv6hf/atags.h @@ -0,0 +1,105 @@ +/* atags.h */ + +#ifndef _ATAGS_H +#define _ATAGS_H + +#define ATAG_CORE 0x54410001 +#define ATAG_MEM 0x54410002 +#define ATAG_VIDEOTEXT 0x54410003 +#define ATAG_RAMDISK 0x54410004 +#define ATAG_INITRD2 0x54420005 +#define ATAG_SERIAL 0x54410006 +#define ATAG_REVISION 0x54410007 +#define ATAG_VIDEOLFB 0x54410008 +#define ATAG_CMDLINE 0x54410009 +#define ATAG_NONE 0x00000000 + +/* structures for each atag */ +struct atag_header { + u32_t size; /* length of tag in words including this header */ + u32_t tag; /* tag type */ +}; + +struct atag_core { + u32_t flags; + u32_t pagesize; + u32_t rootdev; +}; + +struct atag_mem { + u32_t size; + u32_t start; +}; + +struct atag_videotext { + u8_t x; + u8_t y; + u16_t video_page; + u8_t video_mode; + u8_t video_cols; + u16_t video_ega_bx; + u8_t video_lines; + u8_t video_isvga; + u16_t video_points; +}; + +struct atag_ramdisk { + u32_t flags; + u32_t size; + u32_t start; +}; + +struct atag_initrd2 { + u32_t start; + u32_t size; +}; + +struct atag_serialnr { + u32_t low; + u32_t high; +}; + +struct atag_revision { + u32_t rev; +}; + +struct atag_videolfb { + u16_t lfb_width; + u16_t lfb_height; + u16_t lfb_depth; + u16_t lfb_linelength; + u32_t lfb_base; + u32_t lfb_size; + u8_t red_size; + u8_t red_pos; + u8_t green_size; + u8_t green_pos; + u8_t blue_size; + u8_t blue_pos; + u8_t rsvd_size; + u8_t rsvd_pos; +}; + +struct atag_cmdline { + char cmdline[1]; +}; + +struct atag { + struct atag_header hdr; + union { + struct atag_core core; + struct atag_mem mem; + struct atag_videotext videotext; + struct atag_ramdisk ramdisk; + struct atag_initrd2 initrd2; + struct atag_serialnr serialnr; + struct atag_revision revision; + struct atag_videolfb videolfb; + struct atag_cmdline cmdline; + } u; +}; + +#define tag_next(t) ((struct atag *)((u32_t *)(t) + (t)->hdr.size)) +#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2) + +#endif /* _ATAGS_H */ diff --git a/minix/kernel/arch/earmv6hf/bsp/rpi/rpi_intr.c b/minix/kernel/arch/earmv6hf/bsp/rpi/rpi_intr.c index 7bcbf2ed3..5f61d8559 100644 --- a/minix/kernel/arch/earmv6hf/bsp/rpi/rpi_intr.c +++ b/minix/kernel/arch/earmv6hf/bsp/rpi/rpi_intr.c @@ -15,6 +15,11 @@ #define NR_BANKS 3 +#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" : : "r" (0) : "memory") +#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory") +#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0) : "memory") +#define barrier() dsb(); isb() + static struct rpi_intr { vir_bytes base; @@ -51,6 +56,8 @@ void check_irq_pending(u32_t irq_num) { u32_t handle = FALSE; + barrier(); + /* Check the appropriate hardware register, depending on the IRQ number. */ if ( irq_num >= 0x40 ) { @@ -83,6 +90,8 @@ void check_irq_pending(u32_t irq_num) * the handler function. As far as we can tell, it cannot be cleared * directly through the interrupt controller. */ } + + dmb(); } /* @@ -104,6 +113,8 @@ void bsp_irq_handle(void) { u32_t bank; + barrier(); + for ( bank = 0; bank < NR_BANKS; bank++ ) { u32_t mask = bcm2835_enabled_irqs[bank]; @@ -118,6 +129,8 @@ void bsp_irq_handle(void) void bsp_irq_unmask(int irq) { + dmb(); + if ( irq < 0x20 ) //gpu0: 0-31 { mmio_write( rpi_intr.base + RPI_INTCPS_MIR_CLEAR0, ( 1 << irq ) ); @@ -133,10 +146,14 @@ void bsp_irq_unmask(int irq) mmio_write( rpi_intr.base + RPI_INTCPS_MIR_CLEAR_BASIC, ( 1 << ( irq - 0x40 ) ) ); bcm2835_enabled_irqs[2] |= ( 1 << ( irq - 0x40 ) ); } + + barrier(); } void bsp_irq_mask(const int irq) { + dmb(); + if ( irq < 0x20 ) { mmio_write( ( rpi_intr.base + RPI_INTCPS_MIR_SET0 ), ( 1 << irq ) ); @@ -152,5 +169,7 @@ void bsp_irq_mask(const int irq) mmio_write( ( rpi_intr.base + RPI_INTCPS_MIR_SET_BASIC ), ( 1 << ( irq - 0x40 ) ) ); bcm2835_enabled_irqs[2] &= ~( 1 << ( irq - 0x40 ) ); } + + barrier(); } diff --git a/minix/kernel/arch/earmv6hf/bsp/rpi/rpi_timer.c b/minix/kernel/arch/earmv6hf/bsp/rpi/rpi_timer.c index 6facf261c..8aed3565b 100644 --- a/minix/kernel/arch/earmv6hf/bsp/rpi/rpi_timer.c +++ b/minix/kernel/arch/earmv6hf/bsp/rpi/rpi_timer.c @@ -20,6 +20,7 @@ static irq_hook_t rpi_timer_hook; static u32_t counts_per_hz = ~0; static u64_t high_frc; +static int rpi_timer_init_ok = 0; struct rpi_timer_registers; struct bcm2835_timer @@ -31,14 +32,18 @@ struct bcm2835_timer struct rpi_timer_registers { + vir_bytes STCS; vir_bytes STCLO; + vir_bytes STCHI; vir_bytes STC3; }; static struct rpi_timer_registers regs_v1 = { + .STCS = BCM2835_STIMER_CS, .STCLO = BCM2835_STIMER_CLO, - .STC3 = BCM2835_STIMER_C3, + .STCHI = BCM2835_STIMER_CHI, + .STC3 = BCM2835_STIMER_C3 }; static struct bcm2835_timer rpi_timer = { .base = BCM2835_STIMER_BASE, @@ -75,10 +80,12 @@ bsp_timer_init(unsigned freq) kern_phys_map_ptr(timer->base, ARM_PAGE_SIZE, VMMF_UNCACHED | VMMF_WRITE, &timer_phys_map, (vir_bytes) & timer->base); + mmio_write( timer->base + timer->regs->STCS, BCM2835_STIMER_M3 ); stclo = mmio_read( timer->base + timer->regs->STCLO ); stclo += counts_per_hz; mmio_write( timer->base + timer->regs->STC3, stclo ); frclock_init(); + rpi_timer_init_ok = 1; } } @@ -92,8 +99,22 @@ void bsp_timer_int_handler() { u32_t stclo; + mmio_write( timer->base + timer->regs->STCS , BCM2835_STIMER_M3 ); stclo = mmio_read( timer->base + timer->regs->STCLO ); stclo += counts_per_hz; mmio_write( timer->base + timer->regs->STC3, stclo ); } +void +read_tsc_64(u64_t* t) +{ + u32_t stclo, stchi; + if (rpi_timer_init_ok) { + stclo = mmio_read( timer->base + timer->regs->STCLO ); + stchi = mmio_read( timer->base + timer->regs->STCHI ); + *t = ((u64_t)stchi << 32) | (u64_t)stclo; + } else { + *t = (u64_t) 0; + } +} + diff --git a/minix/kernel/arch/earmv6hf/bsp/rpi/rpi_timer_registers.h b/minix/kernel/arch/earmv6hf/bsp/rpi/rpi_timer_registers.h index 7b7e5e001..c8b474abc 100644 --- a/minix/kernel/arch/earmv6hf/bsp/rpi/rpi_timer_registers.h +++ b/minix/kernel/arch/earmv6hf/bsp/rpi/rpi_timer_registers.h @@ -8,8 +8,11 @@ #define BCM2835_STIMER_BASE 0x20003000 /* System Timer */ /* General-purpose timer registers */ +#define BCM2835_STIMER_CS 0x00 /* System Timer Control/Status */ #define BCM2835_STIMER_CLO 0x04 /* System Timer Counter Lower 32 bits */ +#define BCM2835_STIMER_CHI 0x08 /* System Timer Counter Higher 32 bits */ #define BCM2835_STIMER_C3 0x18 /* System Timer Compare 3 */ +#define BCM2835_STIMER_M3 (1 << BCM2835_INT_TIMER3) #define RPI_WDT_BASE 0x20100000 /* watchdog timer */ #define RPI_PM_RSTC 0x1c diff --git a/minix/kernel/arch/earmv6hf/include/cpufunc.h b/minix/kernel/arch/earmv6hf/include/cpufunc.h index 0dd23d9bc..599f9f50c 100644 --- a/minix/kernel/arch/earmv6hf/include/cpufunc.h +++ b/minix/kernel/arch/earmv6hf/include/cpufunc.h @@ -153,7 +153,7 @@ static inline void dcache_maint(int type){ if (type == 1) { // invalidate caches - asm volatile ("mcr p15, 0, %0, c7, c7, 0" :: "r" (0) : "memory"); + asm volatile ("mcr p15, 0, %0, c7, c14, 0" :: "r" (0) : "memory"); //invalidate tlb asm volatile ("mcr p15, 0, %0, c8, c7, 0" :: "r" (0) : "memory"); //mcr p15,0,r2,c8,c7,0 ;@ invalidate tlb diff --git a/minix/kernel/arch/earmv6hf/klib.S b/minix/kernel/arch/earmv6hf/klib.S index 60b5046e3..13b066268 100644 --- a/minix/kernel/arch/earmv6hf/klib.S +++ b/minix/kernel/arch/earmv6hf/klib.S @@ -96,12 +96,14 @@ ENTRY(__user_copy_msg_pointer_failure) ENTRY(intr_enable) ENTRY(interrupts_enable) - dsb + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 /* dsb */ cpsie if bx lr ENTRY(intr_disable) ENTRY(interrupts_disable) - dsb + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 /* dsb */ cpsid if bx lr diff --git a/minix/kernel/arch/earmv6hf/memory.c b/minix/kernel/arch/earmv6hf/memory.c index e8648897c..7f4042eb4 100644 --- a/minix/kernel/arch/earmv6hf/memory.c +++ b/minix/kernel/arch/earmv6hf/memory.c @@ -101,7 +101,7 @@ static phys_bytes createpde( pdeval = pr->p_seg.p_ttbr_v[ARM_VM_PDE(linaddr)]; } else { /* Requested address is physical. Make up the PDE entry. */ - assert (linaddr >= PHYS_MEM_BEGIN && linaddr <= PHYS_MEM_END); + assert (linaddr >= PHYS_MEM_BEGIN && linaddr < kinfo.mem_high_phys ); /* memory */ pdeval = (linaddr & ARM_VM_SECTION_MASK) diff --git a/minix/kernel/arch/earmv6hf/mpx.S b/minix/kernel/arch/earmv6hf/mpx.S index c7371e988..dcfead2f5 100644 --- a/minix/kernel/arch/earmv6hf/mpx.S +++ b/minix/kernel/arch/earmv6hf/mpx.S @@ -151,7 +151,8 @@ irq_entry_from_user: add sp, sp, #4 pop {fp} /* caller proc ptr. */ - dsb /* data synchronization barrier. */ + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 /* dsb */ b _C_LABEL(switch_to_user) @@ -162,7 +163,8 @@ irq_entry_from_kernel: /* call handler */ bl _C_LABEL(bsp_irq_handle) /* bsp_irq_handle(void). */ - /* data synchronization barrier */ dsb + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 /* dsb */ pop {r0-r12, lr} rfeia sp! diff --git a/minix/kernel/arch/earmv6hf/pg_utils.c b/minix/kernel/arch/earmv6hf/pg_utils.c index ee41c7225..d77579824 100644 --- a/minix/kernel/arch/earmv6hf/pg_utils.c +++ b/minix/kernel/arch/earmv6hf/pg_utils.c @@ -173,7 +173,7 @@ void pg_identity(kinfo_t *cbi) phys = i * ARM_SECTION_SIZE; /* mark mormal memory as cacheable. TODO: fix hard coded values */ - if (phys >= PHYS_MEM_BEGIN && phys <= PHYS_MEM_END) { + if (phys >= PHYS_MEM_BEGIN && phys < cbi->mem_high_phys) { pagedir[i] = phys | flags | ARM_VM_SECTION_CACHED; } else { pagedir[i] = phys | flags | ARM_VM_SECTION_DEVICE; diff --git a/minix/kernel/arch/earmv6hf/pre_init.c b/minix/kernel/arch/earmv6hf/pre_init.c index d97ff0c97..730173555 100644 --- a/minix/kernel/arch/earmv6hf/pre_init.c +++ b/minix/kernel/arch/earmv6hf/pre_init.c @@ -17,6 +17,7 @@ #include "bsp_serial.h" #include "glo.h" #include +#include "atags.h" #if USE_SYSDEBUG #define MULTIBOOT_VERBOSE 1 @@ -187,6 +188,41 @@ int overlaps(multiboot_module_t *mod, int n, int cmp_mod) multiboot_module_t mb_modlist[MB_MODS_NR]; multiboot_memory_map_t mb_memmap; +#define ATAG_START 0x00000100 /* physical memory address */ + +static void probe_atags(void) +{ +struct atag *tp; +int done = 0; + + tp = (struct atag *) ATAG_START; + if (tp->hdr.tag == ATAG_CORE) { + while (!done) { + tp = tag_next(tp); + switch (tp->hdr.tag) { + case ATAG_MEM: + mb_memmap.mm_length = tp->u.mem.size; + mb_memmap.mm_base_addr = tp->u.mem.start; + break; + case ATAG_CMDLINE: + case ATAG_VIDEOTEXT: + case ATAG_RAMDISK: + case ATAG_INITRD2: + case ATAG_SERIAL: + case ATAG_REVISION: + case ATAG_VIDEOLFB: + break; + case ATAG_NONE: + done = 1; + break; + default: + done = 1; + break; + } + } + } +} + void setup_mbi(multiboot_info_t *mbi, char *bootargs) { memset(mbi, 0, sizeof(*mbi)); @@ -213,6 +249,7 @@ void setup_mbi(multiboot_info_t *mbi, char *bootargs) mb_memmap.mm_base_addr = MB_MMAP_START; mb_memmap.mm_length = MB_MMAP_SIZE; mb_memmap.type = MULTIBOOT_MEMORY_AVAILABLE; + probe_atags(); } void get_parameters(kinfo_t *cbi, char *bootargs)