/trunk/kernel/arch/sparc64/include/boot/boot.h |
---|
75,6 → 75,7 |
* Must be in sync with bootinfo structure used by the boot loader. |
*/ |
typedef struct { |
uintptr_t physmem_start; |
taskmap_t taskmap; |
memmap_t memmap; |
ballocs_t ballocs; |
/trunk/kernel/arch/sparc64/include/trap/mmu.h |
---|
111,10 → 111,9 |
andncc %g1, %g2, %g3 ! get page address into %g3 |
bz 0f ! page address is zero |
or %g3, (TTE_CV|TTE_CP|TTE_P|TTE_W), %g2 ! 8K pages are the default (encoded as 0) |
mov 1, %g3 |
sllx %g3, TTE_V_SHIFT, %g3 |
or %g2, %g3, %g2 |
sethi %hi(kernel_8k_tlb_data_template), %g2 |
ldx [%g2 + %lo(kernel_8k_tlb_data_template)], %g2 |
or %g3, %g2, %g2 |
stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG ! identity map the kernel page |
retry |
/trunk/kernel/arch/sparc64/include/mm/page.h |
---|
48,9 → 48,11 |
#include <arch/types.h> |
#include <genarch/mm/page_ht.h> |
#define KA2PA(x) ((uintptr_t) (x)) |
#define PA2KA(x) ((uintptr_t) (x)) |
extern uintptr_t physmem_base; |
#define KA2PA(x) (((uintptr_t) (x)) + physmem_base) |
#define PA2KA(x) (((uintptr_t) (x)) - physmem_base) |
union page_address { |
uintptr_t address; |
struct { |
/trunk/kernel/arch/sparc64/src/start.S |
---|
44,17 → 44,19 |
.section K_TEXT_START, "ax" |
#define BSP_FLAG 1 |
/* |
* Here is where the kernel is passed control |
* from the boot loader. |
* Here is where the kernel is passed control from the boot loader. |
* |
* The registers are expected to be in this state: |
* - %o0 non-zero for the bootstrap processor, zero for application/secondary processors |
* - %o1 bootinfo structure address |
* - %o2 bootinfo structure size |
* - %o0 starting address of physical memory + bootstrap processor flag |
* bits 63...1: physical memory starting address / 2 |
* bit 0: non-zero on BSP processor, zero on AP processors |
* - %o1 bootinfo structure address (BSP only) |
* - %o2 bootinfo structure size (BSP only) |
* |
* Moreover, we depend on boot having established the |
* following environment: |
* Moreover, we depend on boot having established the following environment: |
* - TLBs are on |
* - identity mapping for the kernel image |
*/ |
61,9 → 63,31 |
.global kernel_image_start |
kernel_image_start: |
mov %o0, %l7 |
mov BSP_FLAG, %l0 |
and %o0, %l0, %l7 ! l7 <= bootstrap processor? |
andn %o0, %l0, %l6 ! l6 <= start of physical memory |
sethi %hi(physmem_base), %l5 |
stx %l6, [%l5 + %lo(physmem_base)] |
/* |
* Get bits 40:13 of physmem_base. |
*/ |
sethi %hi(mask_40_13), %l4 |
sethi %hi(physmem_base_40_13), %l3 |
ldx [%l4 + %lo(mask_40_13)], %l4 |
and %l6, %l4, %l5 ! l5 <= physmem_base[40:13] |
stx %l5, [%l3 + %lo(physmem_base_40_13)] |
/* |
* Prepare kernel 8K TLB data template. |
*/ |
sethi %hi(kernel_8k_tlb_data_template), %l4 |
ldx [%l4 + %lo(kernel_8k_tlb_data_template)], %l3 |
or %l3, %l5, %l3 |
stx %l3, [%l4 + %lo(kernel_8k_tlb_data_template)] |
/* |
* Setup basic runtime environment. |
*/ |
115,7 → 139,8 |
#define SET_TLB_DATA(r1, r2, imm) \ |
set TTE_CV | TTE_CP | TTE_P | LMA | imm, %r1; \ |
set PAGESIZE_4M, %r2; \ |
or %r1, %l5, %r1; \ |
mov PAGESIZE_4M, %r2; \ |
sllx %r2, TTE_SIZE_SHIFT, %r2; \ |
or %r1, %r2, %r1; \ |
mov 1, %r2; \ |
302,7 → 327,33 |
#define INITIAL_STACK_SIZE 1024 |
.align STACK_ALIGNMENT |
.space INITIAL_STACK_SIZE |
.space INITIAL_STACK_SIZE |
.align STACK_ALIGNMENT |
temporary_boot_stack: |
.space STACK_WINDOW_SAVE_AREA_SIZE |
.space STACK_WINDOW_SAVE_AREA_SIZE |
.data |
.align 8 |
.global physmem_base ! copy of the physical memory base address |
physmem_base: |
.quad 0 |
.global physmem_base_40_13 |
physmem_base_40_13: ! physmem_base & mask_40_13 |
.quad 0 |
.global mask_40_13 |
mask_40_13: ! constant with bits 40:13 set |
.quad (((1 << 41) - 1) & ~((1 << 13) - 1)) |
/* |
* This variable is used by the fast_data_MMU_miss trap handler. |
* It is initialized to reflect the starting address of physical |
* memory. |
*/ |
.global kernel_8k_tlb_data_template |
kernel_8k_tlb_data_template: |
.quad ((1 << TTE_V_SHIFT) | TTE_CV | TTE_CP | TTE_P | TTE_W) |
/trunk/boot/arch/sparc64/loader/ofwarch.h |
---|
30,10 → 30,12 |
#define BOOT_sparc64_OFWARCH_H_ |
#include "main.h" |
#include "types.h" |
#define OFW_ADDRESS_CELLS 2 |
#define OFW_SIZE_CELLS 2 |
extern int ofw_cpu(void); |
extern int ofw_get_physmem_start(uintptr_t *start); |
#endif |
/trunk/boot/arch/sparc64/loader/asm.S |
---|
1,5 → 1,6 |
# |
# Copyright (C) 2006 Martin Decky |
# Copyright (C) 2006 Jakub Jermar |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
/trunk/boot/arch/sparc64/loader/main.c |
---|
46,6 → 46,11 |
init_components(components); |
if (!ofw_get_physmem_start(&bootinfo.physmem_start)) { |
printf("Error: unable to get start of physical memory.\n"); |
halt(); |
} |
if (!ofw_memmap(&bootinfo.memmap)) { |
printf("Error: unable to get memory map, halting.\n"); |
halt(); |
57,7 → 62,8 |
} |
printf("\nSystem info\n"); |
printf(" memory: %dM\n", bootinfo.memmap.total>>20); |
printf(" memory: %dM starting at %P\n", |
bootinfo.memmap.total >> 20, bootinfo.physmem_start); |
printf("\nMemory statistics\n"); |
printf(" kernel entry point at %P\n", KERNEL_VIRTUAL_ADDRESS); |
65,7 → 71,8 |
unsigned int i; |
for (i = 0; i < COMPONENTS; i++) |
printf(" %P: %s image (size %d bytes)\n", components[i].start, components[i].name, components[i].size); |
printf(" %P: %s image (size %d bytes)\n", components[i].start, |
components[i].name, components[i].size); |
void * base = (void *) KERNEL_VIRTUAL_ADDRESS; |
unsigned int top = 0; |
93,9 → 100,10 |
printf("\nChecking for secondary processors..."); |
if (!ofw_cpu()) |
printf("Error: unable to get cpu properties\n"); |
printf("Error: unable to get CPU properties\n"); |
printf("done.\n"); |
printf("\nBooting the kernel...\n"); |
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, 1, &bootinfo, sizeof(bootinfo)); |
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, |
bootinfo.physmem_start | BSP_PROCESSOR, &bootinfo, sizeof(bootinfo)); |
} |
/trunk/boot/arch/sparc64/loader/asm.h |
---|
1,5 → 1,6 |
/* |
* Copyright (C) 2006 Martin Decky |
* Copyright (C) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
29,12 → 30,16 |
#ifndef BOOT_sparc64_ASM_H_ |
#define BOOT_sparc64_ASM_H_ |
#define PAGE_SIZE 8192 |
#define PAGE_WIDTH 13 |
#include "types.h" |
#include "main.h" |
#define PAGE_SIZE 8192 |
#define PAGE_WIDTH 13 |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void halt(void); |
extern void jump_to_kernel(void *entry, int bsp, void *bootinfo, unsigned int bootinfo_size) __attribute__((noreturn)); |
extern void jump_to_kernel(void *entry, uint64_t cfg, bootinfo_t *bootinfo, |
unsigned int bootinfo_size) __attribute__((noreturn)); |
#endif |
/trunk/boot/arch/sparc64/loader/main.h |
---|
38,6 → 38,9 |
#define TASKMAP_MAX_RECORDS 32 |
#define BSP_PROCESSOR 1 |
#define AP_PROCESSOR 0 |
typedef struct { |
void *addr; |
uint32_t size; |
49,6 → 52,7 |
} taskmap_t; |
typedef struct { |
uintptr_t physmem_start; |
taskmap_t taskmap; |
memmap_t memmap; |
ballocs_t ballocs; |
55,6 → 59,8 |
ofw_tree_node_t *ofw_root; |
} bootinfo_t; |
extern bootinfo_t bootinfo; |
extern void start(void); |
extern void bootstrap(void); |
/trunk/boot/arch/sparc64/loader/ofwarch.c |
---|
1,5 → 1,6 |
/* |
* Copyright (C) 2005 Martin Decky |
* Copyright (C) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
37,6 → 38,7 |
#include <string.h> |
#include <register.h> |
#include "main.h" |
#include "asm.h" |
void write(const char *str, const int len) |
{ |
85,7 → 87,9 |
/* |
* Start secondary processor. |
*/ |
(void) ofw_call("SUNW,start-cpu", 3, 1, NULL, node, KERNEL_VIRTUAL_ADDRESS, 0); |
(void) ofw_call("SUNW,start-cpu", 3, 1, NULL, node, |
KERNEL_VIRTUAL_ADDRESS, |
bootinfo.physmem_start | AP_PROCESSOR); |
} |
} |
} |
93,3 → 97,22 |
return cpus; |
} |
/** Get physical memory starting address. |
* |
* @param start Pointer to variable where the physical memory starting |
* address will be stored. |
* |
* @return Non-zero on succes, zero on failure. |
*/ |
int ofw_get_physmem_start(uintptr_t *start) |
{ |
uint32_t memreg[4]; |
if (ofw_get_property(ofw_memory, "reg", &memreg, sizeof(memreg)) <= 0) |
return 0; |
*start = (((uint64_t) memreg[0]) << 32) | memreg[1]; |
return 1; |
} |