[haiku-commits] haiku: hrev44755 - in src/system: kernel/arch/arm boot/arch/arm boot/platform/u-boot

  • From: ithamar.adema@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 5 Nov 2012 01:54:16 +0100 (CET)

hrev44755 adds 9 changesets to branch 'master'
old head: 9a31eef24ce61e8c420e76b9653f049332d513a5
new head: de4f3cf3a7e969666af6e78479fad1779116a014

----------------------------------------------------------------------------

03e2e07: bring back framebuffer support in haiku_loader on ARM/u-boot
  
  * General fixes to get the refactored framebuffer code to work
    (across all 3 supported architectures)
  * PXA (verdex) specific fixes to framebuffer code.
  
  Now properly displays the (greyed) icons on the framebuffer!
  
  Signed-off-by: Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>

457556c: Fix variable name in TRACE() statement
  
  Signed-off-by: Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>

b867e11: fix a TRACE() formatting string

d09e7b5: ARM: mark pages found in query as present

be7195d: ARM: add initial timer support.
  
  Currently hardcoded to PXA (verdex) support, needs SoC abstraction
  for seperating implementations, best done using FDT code as committed
  by Francois.

02081e0: ARM: Initial implementation of interrupt/exception handling.
  
  This contains both the common ARM(v5) vector handling as well as
  the PXA(verdex) specific interrupt controller code, to be seperated
  when ARM support for FDT is implemented.
  
  Functional enough to handle interrupts, needs work on KDL support.

f8b47f2: ARM: fixup interrupt enable/disable/restore functions

4fc1dad: ARM: add context switch implementation

de4f3cf: ARM: only warn if unknown memory types are being mapped.
  
  This is a workaround for missing writecombine & friends support. Needs
  proper fixing, but too many other things to do atm to focus on that...

                          [ Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

14 files changed, 473 insertions(+), 142 deletions(-)
.../boot/arch/arm/arch_framebuffer_920.cpp       |  11 +-
.../boot/arch/arm/arch_framebuffer_omap3.cpp     |  11 +-
.../boot/arch/arm/arch_framebuffer_pxa.cpp       |  31 +--
src/system/boot/platform/u-boot/video.cpp        |  19 +-
src/system/kernel/arch/arm/Jamfile               |   2 +-
src/system/kernel/arch/arm/arch_asm.S            |  23 ++-
src/system/kernel/arch/arm/arch_exceptions.S     | 176 ++++++++++++++++
src/system/kernel/arch/arm/arch_int.cpp          | 206 +++++++++++++------
src/system/kernel/arch/arm/arch_thread.cpp       |  61 ++++--
src/system/kernel/arch/arm/arch_timer.cpp        |  63 +++++-
src/system/kernel/arch/arm/arch_vm.cpp           |   6 +-
.../paging/32bit/ARMVMTranslationMap32Bit.cpp    |   2 +
src/system/kernel/arch/x86/arch_thread.cpp       |   2 +-
src/system/kernel/vm/VMKernelAddressSpace.cpp    |   2 +-

############################################################################

Commit:      03e2e071fd006ea8d8fe0ca0fd9e909aa42ce4ea
URL:         http://cgit.haiku-os.org/haiku/commit/?id=03e2e07
Author:      Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>
Date:        Sat Nov  3 04:01:10 2012 UTC

bring back framebuffer support in haiku_loader on ARM/u-boot

* General fixes to get the refactored framebuffer code to work
  (across all 3 supported architectures)
* PXA (verdex) specific fixes to framebuffer code.

Now properly displays the (greyed) icons on the framebuffer!

Signed-off-by: Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>

----------------------------------------------------------------------------

diff --git a/src/system/boot/arch/arm/arch_framebuffer_920.cpp 
b/src/system/boot/arch/arm/arch_framebuffer_920.cpp
index ee2125d..c9762e5 100644
--- a/src/system/boot/arch/arm/arch_framebuffer_920.cpp
+++ b/src/system/boot/arch/arm/arch_framebuffer_920.cpp
@@ -21,16 +21,19 @@
 
 class ArchFBArm920 : public ArchFramebuffer {
 public:
-                                                       ArchFBArm920(addr_t 
base);
-                                                       ~ArchFBArm920();
+                                                       ArchFBArm920(addr_t 
base)
+                                                               : 
ArchFramebuffer(base) {}
+                                                       ~ArchFBArm920() {}
                        status_t                Init();
                        status_t                Probe();
                        status_t                SetDefaultMode();
                        status_t                SetVideoMode(int width, int 
height, int depth);
 };
 
-ArchFBArm920 *arch_get_fb_arm_920(addr_t base);
-
+extern "C" ArchFramebuffer *arch_get_fb_arm_920(addr_t base)
+{
+       return new ArchFBArm920(base);
+}
 
 status_t
 ArchFBArm920::Init()
diff --git a/src/system/boot/arch/arm/arch_framebuffer_omap3.cpp 
b/src/system/boot/arch/arm/arch_framebuffer_omap3.cpp
index 03e38b2..976cace 100644
--- a/src/system/boot/arch/arm/arch_framebuffer_omap3.cpp
+++ b/src/system/boot/arch/arm/arch_framebuffer_omap3.cpp
@@ -40,15 +40,20 @@ extern "C" addr_t mmu_map_physical_memory(addr_t 
physicalAddress, size_t size,
 
 class ArchFBArmOmap3 : public ArchFramebuffer {
 public:
-                                                       ArchFBArmOmap3(addr_t 
base);
-                                                       ~ArchFBArmOmap3();
+                                                       ArchFBArmOmap3(addr_t 
base)
+                                                               : 
ArchFramebuffer(base) {}
+                                                       ~ArchFBArmOmap3() {}
+
                        status_t                Init();
                        status_t                Probe();
                        status_t                SetDefaultMode();
                        status_t                SetVideoMode(int width, int 
height, int depth);
 };
 
-ArchFBArmOmap3 *arch_get_fb_arm_omap3(addr_t base);
+extern "C" ArchFramebuffer *arch_get_fb_arm_omap3(addr_t base)
+{
+       return new ArchFBArmOmap3(base);
+}
 
 
 //     #pragma mark -
diff --git a/src/system/boot/arch/arm/arch_framebuffer_pxa.cpp 
b/src/system/boot/arch/arm/arch_framebuffer_pxa.cpp
index 1bcc304..9c2048b 100644
--- a/src/system/boot/arch/arm/arch_framebuffer_pxa.cpp
+++ b/src/system/boot/arch/arm/arch_framebuffer_pxa.cpp
@@ -32,15 +32,19 @@ extern "C" addr_t mmu_map_physical_memory(addr_t 
physicalAddress, size_t size,
 
 class ArchFBArmPxa270 : public ArchFramebuffer {
 public:
-                                                       ArchFBArmPxa270(addr_t 
base);
-                                                       ~ArchFBArmPxa270();
+                                                       ArchFBArmPxa270(addr_t 
base)
+                                                               : 
ArchFramebuffer(base) {}
+                                                       ~ArchFBArmPxa270() {}
                        status_t                Init();
                        status_t                Probe();
                        status_t                SetDefaultMode();
                        status_t                SetVideoMode(int width, int 
height, int depth);
 };
 
-ArchFBArmPxa270 *arch_get_fb_arm_pxa270(addr_t base);
+extern "C" ArchFramebuffer *arch_get_fb_arm_pxa270(addr_t base)
+{
+       return new ArchFBArmPxa270(base);
+}
 
 
 //  #pragma mark -
@@ -97,8 +101,13 @@ dprintf("error %08x\n", err);
        struct pxa27x_lcd_dma_descriptor *dma;
 
        // check if LCD controller is enabled
-       if (!(read_io_32(LCCR0) | 0x00000001))
+       if (!(read_io_32(LCCR0) & 0x00000001)) {
+               // not enabled, so return suggested mode
+               gKernelArgs.frame_buffer.depth = 32;
+               gKernelArgs.frame_buffer.width = 640;
+               gKernelArgs.frame_buffer.height = 480;
                return B_NO_INIT;
+       }
 
        pixelFormat = bppCode = read_io_32(LCCR3);
        bppCode = ((bppCode >> 26) & 0x08) | ((bppCode >> 24) & 0x07);
@@ -126,7 +135,7 @@ dprintf("error %08x\n", err);
                        return B_ERROR;
        }
 
-       gKernelArgs.frame_buffer.physical_buffer.start = (dma->fdadr & ~0x0f);
+       gKernelArgs.frame_buffer.physical_buffer.start = (dma->fsadr & ~0x0f);
        gKernelArgs.frame_buffer.width = (read_io_32(LCCR1) & ((1 << 10) - 1)) 
+ 1;
        gKernelArgs.frame_buffer.height = (read_io_32(LCCR2) & ((1 << 10) - 1)) 
+ 1;
        gKernelArgs.frame_buffer.bytes_per_row = gKernelArgs.frame_buffer.width
@@ -150,12 +159,6 @@ ArchFBArmPxa270::SetVideoMode(int width, int height, int 
depth)
 
        void *fb;
        uint32 fbSize = width * height * depth / 8;
-       //fb = malloc(800 * 600 * 4 + 16 - 1);
-       //fb = (void *)(((uint32)fb) & ~(0x0f));
-       //fb = scratch - 800;
-       //fb = (void *)0xa0000000;
-
-//     fBase = scratch - 800;
 
        fb = (void*)fBase;
 
@@ -168,8 +171,8 @@ ArchFBArmPxa270::SetVideoMode(int width, int height, int 
depth)
 
        // if not already enabled, set a default mode
        if (!(read_io_32(LCCR0) & 0x00000001)) {
-               int bpp = 0x09; // 24 bpp
-               int pdfor = 0x3; // Format 4: RGB888 (no alpha bit)
+               int bpp;
+               int pdfor;
                dprintf("Setting video mode\n");
                switch (depth) {
                        case 4:
@@ -201,7 +204,7 @@ ArchFBArmPxa270::SetVideoMode(int width, int height, int 
depth)
                dumpr(LCCR3);
                dumpr(LCCR4);
        } else
-               return EALREADY; // for now
+               return B_OK; // assume we're already setup
 
        // clear the video memory
        memset((void *)fb, 0, fbSize);
diff --git a/src/system/boot/platform/u-boot/video.cpp 
b/src/system/boot/platform/u-boot/video.cpp
index d3767f9..f7c4c72 100644
--- a/src/system/boot/platform/u-boot/video.cpp
+++ b/src/system/boot/platform/u-boot/video.cpp
@@ -14,6 +14,7 @@
 #include <boot/platform/generic/video.h>
 #include <util/list.h>
 #include <drivers/driver_settings.h>
+#include <board_config.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -76,14 +77,10 @@ platform_blit4(addr_t frameBuffer, const uint8 *data, 
uint16 width,
 extern "C" void
 platform_switch_to_logo(void)
 {
-       CALLED();
        // in debug mode, we'll never show the logo
        if ((platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) != 0)
                return;
 
-       //XXX: not yet, DISABLED
-       return;
-
        status_t err;
 
        if (gFramebuffer != NULL) {
@@ -95,30 +92,28 @@ platform_switch_to_logo(void)
 
                err = video_display_splash(gFramebuffer->Base());
        }
-       #warning U-Boot:TODO
 }
 
 
 extern "C" void
 platform_switch_to_text_mode(void)
 {
-       CALLED();
-       #warning U-Boot:TODO
 }
 
 
 extern "C" status_t
 platform_init_video(void)
 {
-       CALLED();
-
 #ifdef __ARM__
        #if defined(BOARD_CPU_ARM920T)
+               extern ArchFramebuffer *arch_get_fb_arm_920(addr_t base);
                gFramebuffer = arch_get_fb_arm_920(0x88000000);
        #elif defined(BOARD_CPU_OMAP3)
+               extern ArchFramebuffer *arch_get_fb_arm_omap3(addr_t base);
                gFramebuffer = arch_get_fb_arm_omap3(0x88000000);
        #elif defined(BOARD_CPU_PXA270)
-               gFramebuffer = arch_get_fb_arm_pxa270(0xA4000000);
+               ArchFramebuffer *arch_get_fb_arm_pxa270(addr_t base);
+               gFramebuffer = arch_get_fb_arm_pxa270(0xA3000000);
        #endif
 #endif
 
@@ -127,9 +122,5 @@ platform_init_video(void)
                gFramebuffer->Init();
        }
 
-       //XXX for testing
-       //platform_switch_to_logo();
-       //return arch_probe_video_mode();
-
        return B_OK;
 }

############################################################################

Commit:      457556ca122af2fb035a9792325f99e48494701d
URL:         http://cgit.haiku-os.org/haiku/commit/?id=457556c
Author:      Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>
Date:        Sat Nov  3 12:22:08 2012 UTC

Fix variable name in TRACE() statement

Signed-off-by: Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>

----------------------------------------------------------------------------

diff --git a/src/system/kernel/vm/VMKernelAddressSpace.cpp 
b/src/system/kernel/vm/VMKernelAddressSpace.cpp
index efaa473..9b5c5c2 100644
--- a/src/system/kernel/vm/VMKernelAddressSpace.cpp
+++ b/src/system/kernel/vm/VMKernelAddressSpace.cpp
@@ -151,7 +151,7 @@ VMKernelAddressSpace::CreateArea(const char* name, uint32 
wiring,
 void
 VMKernelAddressSpace::DeleteArea(VMArea* _area, uint32 allocationFlags)
 {
-       TRACE("VMKernelAddressSpace::DeleteArea(%p)\n", area);
+       TRACE("VMKernelAddressSpace::DeleteArea(%p)\n", _area);
 
        VMKernelArea* area = static_cast<VMKernelArea*>(_area);
        object_cache_delete(fAreaObjectCache, area);

############################################################################

Commit:      b867e1156e0b3396628f1f82231fc5ebae85426a
URL:         http://cgit.haiku-os.org/haiku/commit/?id=b867e11
Author:      Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>
Date:        Mon Nov  5 00:14:58 2012 UTC

fix a TRACE() formatting string

----------------------------------------------------------------------------

diff --git a/src/system/kernel/arch/x86/arch_thread.cpp 
b/src/system/kernel/arch/x86/arch_thread.cpp
index 69ca734..93cf266 100644
--- a/src/system/kernel/arch/x86/arch_thread.cpp
+++ b/src/system/kernel/arch/x86/arch_thread.cpp
@@ -317,7 +317,7 @@ arch_thread_init_kthread_stack(Thread* thread, void* 
_stack, void* _stackTop,
 {
        addr_t* stackTop = (addr_t*)_stackTop;
 
-       TRACE(("arch_thread_init_kthread_stack: stack top %p, function %, data: 
"
+       TRACE(("arch_thread_init_kthread_stack: stack top %p, function %p, 
data: "
                "%p\n", stackTop, function, data));
 
        // push the function argument, a pointer to the data

############################################################################

Commit:      d09e7b5b90b86793a6f44d90e5ccc86c1bcbfffe
URL:         http://cgit.haiku-os.org/haiku/commit/?id=d09e7b5
Author:      Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>
Date:        Mon Nov  5 00:33:26 2012 UTC

ARM: mark pages found in query as present

----------------------------------------------------------------------------

diff --git 
a/src/system/kernel/arch/arm/paging/32bit/ARMVMTranslationMap32Bit.cpp 
b/src/system/kernel/arch/arm/paging/32bit/ARMVMTranslationMap32Bit.cpp
index d822caf..2d19cb8 100644
--- a/src/system/kernel/arch/arm/paging/32bit/ARMVMTranslationMap32Bit.cpp
+++ b/src/system/kernel/arch/arm/paging/32bit/ARMVMTranslationMap32Bit.cpp
@@ -594,6 +594,8 @@ ARMVMTranslationMap32Bit::Query(addr_t va, phys_addr_t 
*_physical,
                | ((entry & ARM_PTE_PRESENT) != 0 ? PAGE_PRESENT : 0);
 #else
        *_flags = B_KERNEL_WRITE_AREA | B_KERNEL_READ_AREA;
+       if (*_physical != 0)
+               *_flags |= PAGE_PRESENT;
 #endif
        pinner.Unlock();
 

############################################################################

Commit:      be7195d0f79a82a419cc06e4fc5b40e5dccf36a2
URL:         http://cgit.haiku-os.org/haiku/commit/?id=be7195d
Author:      Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>
Date:        Mon Nov  5 00:34:25 2012 UTC

ARM: add initial timer support.

Currently hardcoded to PXA (verdex) support, needs SoC abstraction
for seperating implementations, best done using FDT code as committed
by Francois.

----------------------------------------------------------------------------

diff --git a/src/system/kernel/arch/arm/arch_timer.cpp 
b/src/system/kernel/arch/arm/arch_timer.cpp
index 7224c90..2bda040 100644
--- a/src/system/kernel/arch/arm/arch_timer.cpp
+++ b/src/system/kernel/arch/arm/arch_timer.cpp
@@ -1,9 +1,10 @@
 /*
- * Copyright 2007, Haiku Inc. All rights reserved.
+ * Copyright 2007-2012, Haiku Inc. All rights reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
  *             FranÃois Revol <revol@xxxxxxx>
+ *              Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>
  *
  * Copyright 2001, Travis Geiselbrecht. All rights reserved.
  * Distributed under the terms of the NewOS License.
@@ -16,30 +17,72 @@
 
 #include <timer.h>
 #include <arch/timer.h>
-//#include <arch_platform.h>
+#include <arch/cpu.h>
+
+#define PXA_TIMERS_PHYS_BASE   0x40A00000
+#define PXA_TIMERS_SIZE                0x000000C0
+#define PXA_TIMERS_INTERRUPT   7 /* OST_4_11 */
+
+#define PXA_OSSR               0x05
+#define PXA_OIER               0x07
+#define PXA_OSCR4              0x10
+#define PXA_OSMR4              0x20
+#define PXA_OMCR4              0x30
+
+#define TRACE(x)       //dprintf x
+
+static area_id sPxaTimersArea;
+static uint32 *sPxaTimersBase;
+
+
+static int32
+pxa_timer_interrupt(void *data)
+{
+       int32 ret = timer_interrupt();
+        sPxaTimersBase[PXA_OSSR] |= (1 << 4);
+
+        return ret;
+}
 
 
 void
 arch_timer_set_hardware_timer(bigtime_t timeout)
 {
-       #warning ARM:WRITEME
-       // M68KPlatform::Default()->SetHardwareTimer(timeout);
+       TRACE(("arch_timer_set_hardware_timer(%lld): %p\n", timeout, 
sPxaTimersBase));
+
+       if (sPxaTimersBase) {
+               sPxaTimersBase[PXA_OIER] |= (1 << 4);
+               sPxaTimersBase[PXA_OMCR4] = 4; // set to exactly single 
milisecond resolution
+               sPxaTimersBase[PXA_OSMR4] = timeout;
+               sPxaTimersBase[PXA_OSCR4] = 0; // start counting from 0 again
+       }
 }
 
 
 void
 arch_timer_clear_hardware_timer()
 {
-       #warning ARM:WRITEME
-       // M68KPlatform::Default()->ClearHardwareTimer();
+       TRACE(("arch_timer_clear_hardware_timer: %p\n", sPxaTimersBase));
+
+       if (sPxaTimersBase) {
+               sPxaTimersBase[PXA_OMCR4] = 0; // disable our timer
+               sPxaTimersBase[PXA_OIER] &= ~(4 << 1);
+       }
 }
 
 
 int
 arch_init_timer(kernel_args *args)
 {
-       #warning ARM:WRITEME
-       // M68KPlatform::Default()->InitTimer(args);
-       return 0;
-}
+       sPxaTimersArea = map_physical_memory("pxa_timers", PXA_TIMERS_PHYS_BASE,
+               PXA_TIMERS_SIZE, 0, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 
(void**)&sPxaTimersBase);
 
+       if (sPxaTimersArea < 0)
+               return sPxaTimersArea;
+
+       sPxaTimersBase[PXA_OMCR4] = 0; // disable our timer
+
+       install_io_interrupt_handler(PXA_TIMERS_INTERRUPT, 
&pxa_timer_interrupt, NULL, 0);
+
+       return B_OK;
+}

############################################################################

Commit:      02081e0950d201a246c8adb86a92a8bb65e28490
URL:         http://cgit.haiku-os.org/haiku/commit/?id=02081e0
Author:      Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>
Date:        Mon Nov  5 00:36:41 2012 UTC

ARM: Initial implementation of interrupt/exception handling.

This contains both the common ARM(v5) vector handling as well as
the PXA(verdex) specific interrupt controller code, to be seperated
when ARM support for FDT is implemented.

Functional enough to handle interrupts, needs work on KDL support.

----------------------------------------------------------------------------

diff --git a/src/system/kernel/arch/arm/Jamfile 
b/src/system/kernel/arch/arm/Jamfile
index 13a56e4..68124ed 100644
--- a/src/system/kernel/arch/arm/Jamfile
+++ b/src/system/kernel/arch/arm/Jamfile
@@ -17,7 +17,7 @@ KernelMergeObject kernel_arch_arm.o :
        arch_debug_console.cpp
        arch_debug.cpp
        arch_elf.cpp
-#      arch_exceptions.S
+       arch_exceptions.S
        arch_int.cpp
        arch_platform.cpp
        arch_real_time_clock.cpp
diff --git a/src/system/kernel/arch/arm/arch_exceptions.S 
b/src/system/kernel/arch/arm/arch_exceptions.S
new file mode 100644
index 0000000..cffb1f8
--- /dev/null
+++ b/src/system/kernel/arch/arm/arch_exceptions.S
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2012, Haiku Inc. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>
+ *
+ */
+
+#include <asm_defs.h>
+
+       .text
+
+.globl _vectors_start
+_vectors_start:
+        ldr            pc, _arm_reset  
+        ldr             pc, _arm_undefined
+        ldr             pc, _arm_syscall
+        ldr             pc, _arm_prefetch_abort
+        ldr             pc, _arm_data_abort
+        ldr             pc, _arm_reserved
+        ldr             pc, _arm_irq
+        ldr             pc, _arm_fiq
+
+_arm_reset:
+       .word           arm_reserved // actually reset, but not used when mapped
+_arm_undefined: 
+       .word           arm_undefined
+_arm_syscall:
+       .word           arm_syscall
+_arm_prefetch_abort:
+       .word           arm_prefetch_abort
+_arm_data_abort:
+       .word           arm_data_abort
+_arm_reserved:
+       .word           arm_reserved
+_arm_irq:       
+       .word           arm_irq
+_arm_fiq:       
+       .word           arm_fiq 
+.globl _vectors_end
+_vectors_end:
+
+
+       .rept   64
+       .word   0xaabbccdd      
+       .endr
+abort_stack:
+       .word   .
+
+FUNCTION(arm_undefined):
+       stmfd   sp!, { r0-r12, r14 }
+       sub             sp, sp, #12
+       mov             r0, sp
+       mrs             r1, spsr
+       stmia   r0, { r1, r13-r14 }
+       b               arch_arm_undefined
+       b               .
+
+FUNCTION(arm_syscall):
+       stmfd   sp!, { r0-r12, r14 }
+       sub             sp, sp, #12
+       mov             r0, sp
+       mrs             r1, spsr
+       stmia   r0, { r1, r13-r14 }
+       b               arch_arm_syscall
+       b               .
+       
+FUNCTION(arm_prefetch_abort):
+       ldr     sp, abort_stack
+       stmfd   sp!, { r0-r12, r14 }
+       sub             sp, sp, #12
+       mov             r0, sp
+       mrs             r1, spsr
+       stmia   r0, { r1, r13-r14 }
+       b               arch_arm_prefetch_abort
+       b               .
+
+FUNCTION(arm_data_abort):
+       ldr     sp, abort_stack
+       /* XXX only deals with interrupting supervisor mode */
+
+       /* save r4-r6 and use as a temporary place to save while we switch into 
supervisor mode */
+       stmia   r13, { r4-r6 }
+       mov     r4, r13
+       sub     r5, lr, #8
+       mrs     r6, spsr
+
+       /* move into supervisor mode. irq/fiq disabled */
+       msr     cpsr_c, #0x13
+
+       /* save the return address */
+       stmfd   sp!, { r5 }
+
+       /* save C trashed regs, supervisor lr */
+       stmfd   sp!, { r0-r3, r12, lr }
+
+       /* save spsr */
+       stmfd   sp!, { r6 }
+
+       /* restore r4-r6 */
+       ldmia   r4, { r4-r6 }
+
+       /* call into higher level code */
+        mrc     p15, 0, r2, c5, c0, 0           @ get FSR
+        mrc     p15, 0, r3, c6, c0, 0           @ get FAR
+       sub     sp, sp, #20
+       mov     r0, sp /* iframe */
+       stmia   r0, { r6,r2,r3,r4,r5 }
+       bl      arch_arm_data_abort
+       add     sp, sp, #20
+
+       /* restore spsr */
+       ldmfd   sp!, { r0 }
+       msr     spsr_cxsf, r0
+
+       /* restore back to where we came from */
+       ldmfd   sp!, { r0-r3, r12, lr, pc }^
+
+FUNCTION(arm_reserved):
+       b       .
+       
+FUNCTION(arm_irq):
+       ldr     sp, abort_stack
+       /* XXX only deals with interrupting supervisor mode */
+
+       /* save r4-r6 and use as a temporary place to save while we switch into 
supervisor mode */
+       stmia   r13, { r4-r6 }
+       mov     r4, r13
+       sub     r5, lr, #4
+       mrs     r6, spsr
+
+       /* move into supervisor mode. irq/fiq disabled */
+       msr     cpsr_c, #(3<<6 | 0x13)
+
+       /* save the return address */
+       stmfd   sp!, { r5 }
+
+       /* save C trashed regs, supervisor lr */
+       stmfd   sp!, { r0-r3, r12, lr }
+
+       /* save spsr */
+       stmfd   sp!, { r6 }
+
+       /* restore r4-r6 */
+       ldmia   r4, { r4-r6 }
+
+       /* call into higher level code */
+       mov     r0, sp /* iframe */
+       bl      arch_arm_irq
+
+       /* restore spsr */
+       ldmfd   sp!, { r0 }
+       msr     spsr_cxsf, r0
+
+       /* restore back to where we came from */
+       ldmfd   sp!, { r0-r3, r12, lr, pc }^
+
+.bss
+.align 2
+       .global irq_save_spot
+irq_save_spot:
+       .word   0       /* r4 */
+       .word   0       /* r5 */
+       .word   0       /* r6 */
+       
+.text
+FUNCTION(arm_fiq):
+       ldr     sp, abort_stack
+       sub     lr, lr, #4
+       stmfd   sp!, { r0-r3, r12, lr }
+
+       bl      arch_arm_fiq
+       
+       ldmfd   sp!, { r0-r3, r12, pc }^
+
diff --git a/src/system/kernel/arch/arm/arch_int.cpp 
b/src/system/kernel/arch/arm/arch_int.cpp
index 1337705..97a735a 100644
--- a/src/system/kernel/arch/arm/arch_int.cpp
+++ b/src/system/kernel/arch/arm/arch_int.cpp
@@ -1,11 +1,12 @@
 /*
- * Copyright 2003-2010, Haiku Inc. All rights reserved.
+ * Copyright 2003-2012, Haiku Inc. All rights reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
  *             Axel DÃrfler <axeld@xxxxxxxxxxxxxxxx>
  *             Ingo Weinhold <bonefish@xxxxxxxxxxxxxxx>
  *             FranÃois Revol <revol@xxxxxxx>
+ *              Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>
  *
  * Copyright 2001, Travis Geiselbrecht. All rights reserved.
  * Distributed under the terms of the NewOS License.
@@ -30,27 +31,35 @@
 #include <string.h>
 
 
-//#define TRACE_ARCH_INT
+#define TRACE_ARCH_INT
 #ifdef TRACE_ARCH_INT
 #      define TRACE(x) dprintf x
 #else
 #      define TRACE(x) ;
 #endif
 
-/*typedef void (*m68k_exception_handler)(void);
-#define M68K_EXCEPTION_VECTOR_COUNT 256
-#warning M68K: align on 4 ?
-//m68k_exception_handler gExceptionVectors[M68K_EXCEPTION_VECTOR_COUNT];
-m68k_exception_handler *gExceptionVectors;
+#define VECTORPAGE_SIZE                64
+#define USER_VECTOR_ADDR_LOW   0x00000000
+#define USER_VECTOR_ADDR_HIGH  0xffff0000
 
-// defined in arch_exceptions.S
-extern "C" void __m68k_exception_noop(void);
-extern "C" void __m68k_exception_common(void);
-*/
-extern int __irqvec_start;
-extern int __irqvec_end;
+#define PXA_INTERRUPT_PHYS_BASE        0x40D00000
+#define PXA_INTERRUPT_SIZE     0x00000034
 
-//extern"C" void m68k_exception_tail(void);
+#define PXA_ICIP       0x00
+#define PXA_ICMR       0x01
+#define PXA_ICFP       0x03
+#define PXA_ICMR2      0x28
+
+static area_id sPxaInterruptArea;
+static uint32 *sPxaInterruptBase;
+
+extern int _vectors_start;
+extern int _vectors_end;
+
+static area_id sVectorPageArea;
+static void *sVectorPageAddress;
+static area_id sUserVectorPageArea;
+static void *sUserVectorPageAddress;
 
 // current fault handler
 addr_t gFaultHandler;
@@ -59,35 +68,48 @@ addr_t gFaultHandler;
 // threads yet.
 struct iframe_stack gBootFrameStack;
 
-// interrupt controller interface (initialized
-// in arch_int_init_post_device_manager())
-//static struct interrupt_controller_module_info *sPIC;
-//static void *sPICCookie;
+
+uint32
+mmu_read_c1()
+{
+       uint32 controlReg = 0;
+       asm volatile("MRC p15, 0, %[c1out], c1, c0, 0":[c1out] "=r" 
(controlReg));
+       return controlReg;
+}
+
+
+void
+mmu_write_c1(uint32 value)
+{
+       asm volatile("MCR p15, 0, %[c1in], c1, c0, 0"::[c1in] "r" (value));
+}
 
 
 void
 arch_int_enable_io_interrupt(int irq)
 {
-       #warning ARM WRITEME
-       //if (!sPIC)
-       //      return;
+       TRACE(("arch_int_enable_io_interrupt(%d)\n", irq));
 
-       // TODO: I have no idea, what IRQ type is appropriate.
-       //sPIC->enable_io_interrupt(sPICCookie, irq, IRQ_TYPE_LEVEL);
-//     M68KPlatform::Default()->EnableIOInterrupt(irq);
+       if (irq <= 31) {
+               sPxaInterruptBase[PXA_ICMR] |= 1 << irq;
+               return;
+       }
+
+       sPxaInterruptBase[PXA_ICMR2] |= 1 << (irq - 32);
 }
 
 
 void
 arch_int_disable_io_interrupt(int irq)
 {
-       #warning ARM WRITEME
+       TRACE(("arch_int_disable_io_interrupt(%d)\n", irq));
 
-       //if (!sPIC)
-       //      return;
+       if (irq <= 31) {
+               sPxaInterruptBase[PXA_ICMR] &= ~(1 << irq);
+               return;
+       }
 
-       //sPIC->disable_io_interrupt(sPICCookie, irq);
-//     M68KPlatform::Default()->DisableIOInterrupt(irq);
+       sPxaInterruptBase[PXA_ICMR2] &= ~(1 << (irq - 32));
 }
 
 
@@ -97,60 +119,67 @@ arch_int_disable_io_interrupt(int irq)
 static void
 print_iframe(struct iframe *frame)
 {
-       #if 0
-       dprintf("r0-r3:   0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", frame->r0, 
frame->r1,
-               frame->r2, frame->r3);
-       dprintf("r4-r7:   0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", frame->r4, 
frame->r5,
-               frame->r6, frame->r7);
-       dprintf("r8-r11:  0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", frame->r8, 
frame->r9,
-               frame->r10, frame->r11);
-       dprintf("r12-r15: 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", frame->r12, 
frame->r13,
-               frame->a6, frame->a7);
-       dprintf("      pc 0x%08lx         sr 0x%08lx\n", frame->pc, frame->sr);
-       #endif
-
-       #warning ARM WRITEME
 }
 
 
 status_t
 arch_int_init(kernel_args *args)
 {
-       #if 0
-       status_t err;
-       addr_t vbr;
-       int i;
-
-       gExceptionVectors = (m68k_exception_handler *)args->arch_args.vir_vbr;
-
-       /* fill in the vector table */
-       for (i = 0; i < M68K_EXCEPTION_VECTOR_COUNT; i++)
-               gExceptionVectors[i] = &__m68k_exception_common;
-
-       vbr = args->arch_args.phys_vbr;
-       /* point VBR to the new table */
-       asm volatile  ("movec %0,%%vbr" : : "r"(vbr):);
-       #endif
-       #warning ARM WRITEME
+       // see if high vectors are enabled
+       if (mmu_read_c1() & (1<<13))
+               dprintf("High vectors already enabled\n");
+       else {
+               mmu_write_c1(mmu_read_c1() | (1<<13));
+
+               if (!(mmu_read_c1() & (1<<13)))
+                       dprintf("Unable to enable high vectors!\n");
+               else
+                       dprintf("Enabled high vectors\n");
+       }
 
        return B_OK;
 }
 
-
 status_t
 arch_int_init_post_vm(kernel_args *args)
 {
-       status_t err;
-       // err = M68KPlatform::Default()->InitPIC(args);
-       #warning ARM WRITEME
+       // create a read/write kernel area
+       sVectorPageArea = create_area("vectorpage", (void 
**)&sVectorPageAddress,
+               B_ANY_ADDRESS, VECTORPAGE_SIZE, B_FULL_LOCK,
+               B_KERNEL_WRITE_AREA | B_KERNEL_READ_AREA);
+
+       if (sVectorPageArea < 0)
+               panic("vector page could not be created!");
+
+       // clone it at a fixed address with user read/only permissions
+       sUserVectorPageAddress = (addr_t*)USER_VECTOR_ADDR_HIGH;
+       sUserVectorPageArea = clone_area("user_vectorpage",
+               (void **)&sUserVectorPageAddress, B_EXACT_ADDRESS,
+               B_READ_AREA | B_EXECUTE_AREA, sVectorPageArea);
+
+       if (sUserVectorPageArea < 0)
+               panic("user vector page @ %p could not be created (%lx)!", 
sVectorPageAddress, sUserVectorPageArea);
+
+       // copy vectors into the newly created area
+       memcpy(sVectorPageAddress, &_vectors_start, VECTORPAGE_SIZE);
+
+       sPxaInterruptArea = map_physical_memory("pxa_intc", 
PXA_INTERRUPT_PHYS_BASE,
+               PXA_INTERRUPT_SIZE, 0, B_KERNEL_READ_AREA | 
B_KERNEL_WRITE_AREA, (void**)&sPxaInterruptBase);
+
+       if (sPxaInterruptArea < 0)
+               return sPxaInterruptArea;
 
-       return err;
+       sPxaInterruptBase[PXA_ICMR] = 0;
+       sPxaInterruptBase[PXA_ICMR2] = 0;
+
+       return B_OK;
 }
 
 
 status_t
 arch_int_init_io(kernel_args* args)
 {
+       TRACE(("arch_int_init_io(%p)\n", args));
        return B_OK;
 }
 
@@ -158,8 +187,53 @@ arch_int_init_io(kernel_args* args)
 status_t
 arch_int_init_post_device_manager(struct kernel_args *args)
 {
-       // no PIC found
-       panic("arch_int_init_post_device_manager(): Found no supported PIC!");
-
        return B_ENTRY_NOT_FOUND;
 }
+
+
+extern "C" void arch_arm_undefined(struct iframe *iframe)
+{
+       panic("Undefined instruction!");
+}
+
+extern "C" void arch_arm_syscall(struct iframe *iframe)
+{
+       panic("Software interrupt!\n");
+}
+
+extern "C" void arch_arm_data_abort(struct iframe *iframe)
+{
+       addr_t newip;
+       status_t res = vm_page_fault(iframe->r2 /* FAR */, iframe->r4 /* lr */,
+               true /* TODO how to determine read/write? */,
+               false /* only kernelspace for now */,
+               &newip);
+
+       if (res != B_HANDLED_INTERRUPT) {
+               panic("Data Abort: %08x %08x %08x %08x (res=%lx)", iframe->r0 
/* spsr */, 
+                       iframe->r1 /* FSR */, iframe->r2 /* FAR */,
+                       iframe->r4 /* lr */,
+                       res);
+       } else {
+               //panic("vm_page_fault was ok (%08lx/%08lx)!", iframe->r2 /* 
FAR */, iframe->r0 /* spsr */);
+       }
+}
+
+extern "C" void arch_arm_prefetch_abort(struct iframe *iframe)
+{
+       panic("Prefetch Abort: %08x %08x %08x", iframe->r0, iframe->r1, 
iframe->r2);
+}
+
+extern "C" void arch_arm_irq(struct iframe *iframe)
+{
+       for (int i=0; i < 32; i++)
+               if (sPxaInterruptBase[PXA_ICIP] & (1 << i))
+                       int_io_interrupt_handler(i, true);
+}
+
+extern "C" void arch_arm_fiq(struct iframe *iframe)
+{
+       for (int i=0; i < 32; i++)
+               if (sPxaInterruptBase[PXA_ICIP] & (1 << i))
+                       dprintf("arch_arm_fiq: help me, FIQ %d was triggered 
but no FIQ support!\n", i);
+}

############################################################################

Commit:      f8b47f2b2a56299562a6264662957a82bec57b13
URL:         http://cgit.haiku-os.org/haiku/commit/?id=f8b47f2
Author:      Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>
Date:        Mon Nov  5 00:39:52 2012 UTC

ARM: fixup interrupt enable/disable/restore functions

----------------------------------------------------------------------------

diff --git a/src/system/kernel/arch/arm/arch_asm.S 
b/src/system/kernel/arch/arm/arch_asm.S
index c34511e..c417a91 100644
--- a/src/system/kernel/arch/arm/arch_asm.S
+++ b/src/system/kernel/arch/arm/arch_asm.S
@@ -27,8 +27,8 @@ FUNCTION_END(arch_int_enable_interrupts)
  */
 FUNCTION(arch_int_disable_interrupts):
         mrs     r0, cpsr
-        orr     r0, r0, #(1<<7)
-        msr     cpsr_c, r0
+        orr     r1, r0, #(1<<7)
+        msr     cpsr_c, r1
         bx      lr
 FUNCTION_END(arch_int_disable_interrupts)
 
@@ -37,8 +37,8 @@ FUNCTION_END(arch_int_disable_interrupts)
  */
 FUNCTION(arch_int_restore_interrupts):
        mrs     r1, cpsr
-       orr     r0,r0, #(1<<7)
-       bic     r1, r1,#(1<<7) 
+       and     r0, r0, #(1<<7)
+       bic     r1, r1, #(1<<7) 
         orr     r1, r1, r0
         msr     cpsr_c, r1
        bx      lr
@@ -49,10 +49,19 @@ FUNCTION_END(arch_int_restore_interrupts)
 FUNCTION(arch_int_are_interrupts_enabled):
         mrs     r0, cpsr
         and     r0, r0, #(1<<7)                /*read the I bit*/
-       cmp     r0,#0
-       moveq   r0,#1
-       movne   r0,#0
+       cmp     r0, #0
+       moveq   r0, #1
+       movne   r0, #0
        bx      lr
 FUNCTION_END(arch_int_are_interrupts_enabled)
 
 
+/* void arm_context_switch(struct arch_thread* oldState,
+       struct arch_thread* newState); */
+FUNCTION(arm_context_switch):
+       stmfd   sp!, { r0-r12, lr }
+       str     sp, [r0]
+       ldr     sp, [r1]
+       ldmfd   sp!, { r0-r12, lr }
+       bx      lr
+FUNCTION_END(arm_context_switch)

############################################################################

Commit:      4fc1dadd583e79fcc8e3c40d28726b9c20f478c8
URL:         http://cgit.haiku-os.org/haiku/commit/?id=4fc1dad
Author:      Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>
Date:        Mon Nov  5 00:41:05 2012 UTC

ARM: add context switch implementation

----------------------------------------------------------------------------

diff --git a/src/system/kernel/arch/arm/arch_thread.cpp 
b/src/system/kernel/arch/arm/arch_thread.cpp
index 3d3d38c..2ae92ae 100644
--- a/src/system/kernel/arch/arm/arch_thread.cpp
+++ b/src/system/kernel/arch/arm/arch_thread.cpp
@@ -20,13 +20,20 @@
 #include <boot/stage2.h>
 #include <kernel.h>
 #include <thread.h>
+#include <tls.h>
 #include <vm/vm_types.h>
 #include <vm/VMAddressSpace.h>
 #include <arch_vm.h>
-//#include <arch/vm_translation_map.h>
+#include <arch/vm_translation_map.h>
 
 #include <string.h>
 
+#define TRACE_ARCH_THREAD
+#ifdef TRACE_ARCH_THREAD
+#      define TRACE(x) dprintf x
+#else
+#      define TRACE(x) ;
+#endif
 
 // Valid initial arch_thread state. We just memcpy() it when initializing
 // a new thread structure.
@@ -67,35 +74,53 @@ void
 arch_thread_init_kthread_stack(Thread* thread, void* _stack, void* _stackTop,
        void (*function)(void*), const void* data)
 {
-#warning ARM:WRITEME
+       addr_t* stackTop = (addr_t*)_stackTop;
+
+       TRACE(("arch_thread_init_kthread_stack(%s): stack top %p, function %p, 
data: "
+               "%p\n", thread->name, stackTop, function, data));
+
+       // push the function address -- that's the return address used after the
+       // context switch (lr/r14 register)
+       *--stackTop = (addr_t)function;
+
+       // simulate storing registers r1-r12
+       for (int i = 1; i <= 12; i++)
+               *--stackTop = 0;
+
+       // push the function argument as r0
+       *--stackTop = (addr_t)data;
+
+       // save the stack position
+       thread->arch_info.sp = stackTop;
 }
 
 
 status_t
 arch_thread_init_tls(Thread *thread)
 {
-       // TODO: Implement!
-       return B_OK;
+       uint32 tls[TLS_USER_THREAD_SLOT + 1];
+
+       thread->user_local_storage = thread->user_stack_base
+               + thread->user_stack_size;
+
+       // initialize default TLS fields
+       memset(tls, 0, sizeof(tls));
+       tls[TLS_BASE_ADDRESS_SLOT] = thread->user_local_storage;
+       tls[TLS_THREAD_ID_SLOT] = thread->id;
+       tls[TLS_USER_THREAD_SLOT] = (addr_t)thread->user_thread;
+
+       return user_memcpy((void *)thread->user_local_storage, tls, 
sizeof(tls));
 }
 
+extern "C" void arm_context_switch(void *from, void *to);
 
 void
 arch_thread_context_switch(Thread *from, Thread *to)
 {
-       #if 0
-       addr_t newPageDirectory;
-
-       newPageDirectory = (addr_t)m68k_next_page_directory(from, to);
-
-       if ((newPageDirectory % B_PAGE_SIZE) != 0)
-               panic("arch_thread_context_switch: bad pgdir 0x%lx\n",
-                       newPageDirectory);
-       #warning M68K: export from arch_vm.c
-       m68k_set_pgdir(newPageDirectory);
-       m68k_context_switch(&from->arch_info.sp, to->arch_info.sp);
-       #endif
-
-       #warning ARM:WRITEME
+       TRACE(("arch_thread_context_switch: %p(%s/%p) -> %p(%s/%p)\n",
+               from, from->name, from->arch_info.sp, to, to->name, 
to->arch_info.sp));
+       arm_context_switch(&from->arch_info, &to->arch_info);
+       TRACE(("arch_thread_context_switch %p %p\n", to, from));
 }
 
 

############################################################################

Revision:    hrev44755
Commit:      de4f3cf3a7e969666af6e78479fad1779116a014
URL:         http://cgit.haiku-os.org/haiku/commit/?id=de4f3cf
Author:      Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>
Date:        Mon Nov  5 00:41:50 2012 UTC

ARM: only warn if unknown memory types are being mapped.

This is a workaround for missing writecombine & friends support. Needs
proper fixing, but too many other things to do atm to focus on that...

----------------------------------------------------------------------------

diff --git a/src/system/kernel/arch/arm/arch_vm.cpp 
b/src/system/kernel/arch/arm/arch_vm.cpp
index 340ae78..bdde3ce 100644
--- a/src/system/kernel/arch/arm/arch_vm.cpp
+++ b/src/system/kernel/arch/arm/arch_vm.cpp
@@ -97,8 +97,8 @@ arch_vm_unset_memory_type(VMArea *area)
 status_t
 arch_vm_set_memory_type(VMArea *area, phys_addr_t physicalBase, uint32 type)
 {
-       if (type == 0)
-               return B_OK;
+       if (type != 0)
+               dprintf("%s: undefined type %lx!\n", __PRETTY_FUNCTION__, type);
 
-       return B_ERROR;
+       return B_OK;
 }


Other related posts:

  • » [haiku-commits] haiku: hrev44755 - in src/system: kernel/arch/arm boot/arch/arm boot/platform/u-boot - ithamar . adema