Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2322 → Rev 2323

/branches/arm/boot/arch/arm32/loader/mm.h
26,6 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
 
/** @addtogroup arm32boot
* @{
*/
33,49 → 34,58
*/
 
 
#ifndef __MM_H__
#define __MM_H__
#ifndef BOOT_arm32__MM_H
#define BOOT_arm32__MM_H
 
 
#ifndef __ASM__
#include "types.h"
#endif
 
 
#define FRAME_WIDTH 12 /* 4KB frames */
#define FRAME_SIZE (1 << FRAME_WIDTH)
/** Frame width. */
#define FRAME_WIDTH 12 /* 4KB frames */
 
#define PAGE_WIDTH FRAME_WIDTH
#define PAGE_SIZE FRAME_SIZE
/** Frame size. */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
/** Page size in 2-level paging which is switched on later in the kernel initialization. */
#define PAGE_SIZE FRAME_SIZE
 
 
#ifndef __ASM__
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000)
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000)
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000)
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000)
#else
# define KA2PA(x) ((x) - 0x80000000)
# define PA2KA(x) ((x) + 0x80000000)
# define KA2PA(x) ((x) - 0x80000000)
# define PA2KA(x) ((x) + 0x80000000)
#endif
 
/** Number of entries in PTL0 */
#define PTL0_ENTRIES_ARCH (1<<12) /* 4096 */
 
/** Frames per 1MB section */
#define FRAMES_PER_SECTION ( ( 1 << 20 ) / FRAME_SIZE )
/** Number of entries in PTL0. */
#define PTL0_ENTRIES (1<<12) /* 4096 */
 
/** Converts adress to frame number */
#define ADDR2PFN( addr ) ( ((uintptr_t)(addr))>>FRAME_WIDTH )
/** Size of an entry in PTL0. */
#define PTL0_ENTRY_SIZE 4
 
/** Descriptor type that signs "section" page table entry
* (one-level paging with 1MB sized pages) */
#define PTE_DESCRIPTOR_SECTION 2
/** Number of frames per 1MB section. */
#define FRAMES_PER_SECTION ( ( 1 << 20 ) / FRAME_SIZE )
 
/** Access rights to page table: user-no access, kernel-read/write */
#define PTE_AP_USER_NO_KERNEL_RW 1
/** Returns number of frame the address belongs to. */
#define ADDR2PFN( addr ) ( ((uintptr_t)(addr)) >> FRAME_WIDTH )
 
/** Describes "section" page table entry (one-level paging with 1MB sized pages). */
#define PTE_DESCRIPTOR_SECTION 0x2
 
/** Page table access rights: user - no access, kernel - read/write. */
#define PTE_AP_USER_NO_KERNEL_RW 0x1
 
 
#ifndef __ASM__
 
 
/** Page table level 0 entry - "section" format (one-level paging, 1MB sized
* pages). Used only for booting the kernel. */
/** Page table level 0 entry - "section" format is used (one-level paging, 1MB sized
* pages). Used only while booting the kernel. */
typedef struct {
unsigned descriptor_type : 2;
unsigned bufferable : 1;
89,14 → 99,12
} __attribute__ ((packed)) pte_level0_section_t;
 
 
/** Page table that holds 1:1 mapping for booting the kernel. */
extern pte_level0_section_t page_table[PTL0_ENTRIES_ARCH];
/** Page table that holds 1:1 virtual to physical mapping used while booting the kernel. */
extern pte_level0_section_t page_table[PTL0_ENTRIES];
 
extern void mmu_start(void);
 
/** Starts the MMU - initializes page table and enables paging. */
void mmu_start(void);
 
 
/** Enables paging. */
static inline void enable_paging()
{
107,17 → 115,14
// behave as a client of domains
"ldr r0, =0x55555555 \n"
"mcr p15, 0, r0, c3, c0, 0 \n"
 
// current settings
"mrc p15, 0, r0, c1, c0, 0 \n"
/* TODO: talk to Alf why needed
// mask to disable aligment checks; system & rom bit set to 0 (has no
// special effect)
"ldr r1, =0xfffffe8f \n"
"and r0, r0, r1 \n"
*/
 
// mask to enable paging
"ldr r1, =0x00000001 \n"
"orr r0, r0, r1 \n"
 
// store settings
"mcr p15, 0, r0, c1, c0, 0 \n"
:
127,17 → 132,20
}
 
 
/** Sets the address of level 0 page table.
* \param pt pointer to the page table to set
/** Sets the address of level 0 page table to CP15 register 2.
*
* @param pt Address of a page table to set.
*/
static inline void set_ptl0_address(pte_level0_section_t* pt)
{
asm volatile ( "mcr p15, 0, %0, c2, c0, 0 \n"
asm volatile (
"mcr p15, 0, %0, c2, c0, 0 \n"
:
: "r"(pt)
);
}
 
 
#endif
#endif
/branches/arm/boot/arch/arm32/loader/asm.S
36,50 → 36,50
bic r3, r3, #3
cmp r1, r3
stmdb sp!, {r4, lr}
beq case_4
case_1:
beq 4f
1:
cmp r2, #0
movne ip, #0
beq case_3
case_2:
beq 3f
2:
ldrb r3, [ip, r1]
strb r3, [ip, r0]
add ip, ip, #1
cmp ip, r2
bne case_2
case_3:
bne 2b
3:
mov r0, r1
ldmia sp!, {r4, pc}
case_4:
4:
add r3, r0, #3
bic r3, r3, #3
cmp r0, r3
bne case_1
bne 1b
movs r4, r2, lsr #2
moveq lr, r4
beq case_6
beq 6f
mov lr, #0
mov ip, lr
case_5:
5:
ldr r3, [ip, r1]
add lr, lr, #1
cmp lr, r4
str r3, [ip, r0]
add ip, ip, #4
bne case_5
case_6:
bne 5b
6:
ands r4, r2, #3
beq case_3
beq 3b
mov r3, lr, lsl #2
add r0, r3, r0
add ip, r3, r1
mov r2, #0
case_7:
7:
ldrb r3, [r2, ip]
strb r3, [r2, r0]
add r2, r2, #1
cmp r2, r4
bne case_7
b case_3
bne 7b
b 3b
 
 
/branches/arm/boot/arch/arm32/loader/boot.S
42,9 → 42,11
bx r0
 
 
# align for start of page
# place page_table to PT section
.section PT
 
# make place for first level page table
# make place for PTL0 page table
page_table:
.skip PTL0_ENTRIES_ARCH * 4
.skip PTL0_ENTRIES * PTL0_ENTRY_SIZE
 
 
/branches/arm/boot/arch/arm32/loader/main.c
26,6 → 26,14
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
 
/** @addtogroup arm32boot
* @{
*/
/** @file
*/
 
 
#include "main.h"
#include "asm.h"
#include "_components.h"
33,8 → 41,10
 
#include "mm.h"
 
#define KERNEL_VIRTUAL_ADDRESS 0x80150000
/** Kernel entry point address. */
#define KERNEL_VIRTUAL_ADDRESS 0x80200000
 
 
char *release = RELEASE;
 
#ifdef REVISION
49,7 → 59,8
char *timestamp = "";
#endif
 
/** Print version information. */
 
/** Prints bootloader version information. */
static void version_print(void)
{
printf("HelenOS ARM32 Bootloader\nRelease %s%s%s\nCopyright (c) 2007 HelenOS project\n",
56,7 → 67,7
release, revision, timestamp);
}
 
/** Copies all images to #KERNEL_VIRTUAL_ADDRESS and jumps there. */
/** Copies all images (kernel + user tasks) to #KERNEL_VIRTUAL_ADDRESS and jumps there. */
void bootstrap(void)
{
mmu_start();
97,3 → 108,6
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, &bootinfo, sizeof(bootinfo));
}
 
/** @}
*/
 
/branches/arm/boot/arch/arm32/loader/asm.h
26,12 → 26,39
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef __ASM_H__
#define __ASM_H__
 
/** @addtogroup arm32boot
* @{
*/
/** @file
*/
 
 
#ifndef BOOT_arm32_ASM_H
#define BOOT_arm32_ASM_H
 
 
/** Copies #cnt bytes from #dst to #src.
*
* @param dst Destination address.
* @param src Source address.
* @param cnt Count of bytes to be copied.
*/
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt))
 
/*void memcpy(void *dst, void *src, int cnt);*/
 
/** Jumps to the kernel.
*
* @param entry Kernel entry point address.
* @param bootinfo Structure holding information about loaded tasks.
* @param bootinto_size Size of the #bootinfo structure.
*/
void jump_to_kernel(void *entry, void *bootinfo, unsigned int bootinfo_size) __attribute__((noreturn));
 
 
#endif
 
 
/** @}
*/
 
/branches/arm/boot/arch/arm32/loader/main.h
26,29 → 26,54
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef __MAIN_H__
#define __MAIN_H__
 
/** Align to the nearest higher address.
/** @addtogroup arm32boot
* @{
*/
/** @file
*/
 
 
#ifndef BOOT_arm32_MAIN_H
#define BOOT_arm32_MAIN_H
 
 
/** Aligns to the nearest higher address.
*
* @param addr Address or size to be aligned.
* @param addr Address or number to be aligned.
* @param align Size of alignment, must be power of 2.
*/
#define ALIGN_UP(addr, align) (((addr) + ((align) - 1)) & ~((align) - 1))
 
/** Maximum number of tasks in the #bootinfo_t structure. */
#define TASKMAP_MAX_RECORDS 32
 
 
/** Structure holding information about single loaded task. */
typedef struct {
/** Address where the task was placed. */
void *addr;
/** Size of the task binary. */
unsigned int size;
} task_t;
 
 
/** Structure holding information about loaded tasks. */
typedef struct {
/** Number of loaded tasks. */
unsigned int cnt;
/** Array of loaded tasks. */
task_t tasks[TASKMAP_MAX_RECORDS];
} bootinfo_t;
 
 
/** Run when the CPU is switched on. */
extern void start(void);
 
extern void bootstrap(void);
 
#endif
 
/** @}
*/
 
/branches/arm/boot/arch/arm32/loader/mm.c
26,6 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
 
/** @addtogroup arm32boot
* @{
*/
32,17 → 33,19
/** @file
*/
 
 
#include "mm.h"
 
 
/** Initializes section page table entry.
/** Initializes "section" page table entry.
*
* Will be readable/writable by kernel with no access from user mode.
* Will belong to domain 0. No cache or buffering is enabled.
*
* \param pte page table entry to set
* \param frame first frame in the section (frame number)
* \note If frame is not 1MB aligned, first lower 1MB aligned frame will be used.
* @param pte Section entry to initialize.
* @param frame First frame in the section (frame number).
*
* @note If #frame is not 1MB aligned, first lower 1MB aligned frame will be used.
*/
static void init_pte_level0_section(pte_level0_section_t* pte, unsigned frame)
{
58,23 → 61,27
}
 
 
/** Initializes page table used while booting the kernel. */
static void init_page_table(void)
{
int i;
const unsigned int first_kernel_section = ADDR2PFN(PA2KA(0)) / FRAMES_PER_SECTION;
 
const unsigned int first_kernel_section = ADDR2PFN(PA2KA(0)) / FRAMES_PER_SECTION;
// create 1:1 mapping virtual-physical (in lower 2GB)
for(i = 0; i < first_kernel_section; i++) {
// create 1:1 virtual-physical mapping (in lower 2GB)
for (i = 0; i < first_kernel_section; i++) {
init_pte_level0_section(&page_table[i], i * FRAMES_PER_SECTION);
}
 
// create kernel mapping (in upper 2GB), physical addresses starting from 0
for(i = first_kernel_section; i < PTL0_ENTRIES_ARCH; i++) {
// create 1:1 virtual-physical mapping in kernel space (upper 2GB),
// physical addresses start from 0
for (i = first_kernel_section; i < PTL0_ENTRIES; i++) {
init_pte_level0_section(&page_table[i], (i - first_kernel_section) * FRAMES_PER_SECTION);
}
}
 
 
/** Starts the MMU - initializes page table and enables paging.
*/
void mmu_start() {
init_page_table();
set_ptl0_address(page_table);
81,6 → 88,7
enable_paging();
}
 
 
/** @}
*/
/branches/arm/boot/arch/arm32/loader/types.h
26,9 → 26,18
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef TYPES_H__
#define TYPES_H__
 
/** @addtogroup arm32boot
* @{
*/
/** @file
*/
 
 
#ifndef BOOT_arm32_TYPES_H
#define BOOT_arm32_TYPES_H
 
 
#include <gentypes.h>
 
typedef signed char int8_t;
41,4 → 50,10
typedef uint32_t uintptr_t;
typedef uint32_t unative_t;
 
 
#endif
 
 
/** @}
*/
 
/branches/arm/boot/arch/arm32/loader/print/gxemul.c
0,0 → 1,69
/*
* Copyright (c) 2007 Michal Kebrt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
 
/** @addtogroup arm32boot
* @{
*/
/** @file
*/
 
 
#include <printf.h>
 
 
/** Address where characters to be printed are expected. */
#define PUTC_ADDRESS 0x10000000
 
 
/** Prints a character to the console.
*
* @param ch Character to be printed.
*/
static void putc(char ch)
{
*((volatile char *)PUTC_ADDRESS) = ch;
}
 
 
/** Prints a string to the console.
*
* @param str String to be printed.
* @param len Number of characters to be printed.
*/
void write(const char *str, const int len)
{
int i;
for (i = 0; i < len; ++i) {
putc(str[i]);
}
}
 
/** @}
*/