/branches/sparc/kernel/generic/src/console/cmd.c |
---|
55,7 → 55,6 |
#include <symtab.h> |
#include <cpu.h> |
#include <mm/tlb.h> |
#include <arch/mm/tlb.h> |
#include <mm/frame.h> |
#include <main/version.h> |
#include <mm/slab.h> |
/branches/sparc/kernel/generic/src/mm/tlb.c |
---|
41,7 → 41,6 |
#include <mm/tlb.h> |
#include <mm/asid.h> |
#include <arch/mm/tlb.h> |
#include <smp/ipi.h> |
#include <synch/spinlock.h> |
#include <atomic.h> |
/branches/sparc/kernel/arch/sparc64/include/sun4v/hypercall.h |
---|
71,6 → 71,28 |
#define CONS_GETCHAR 0x60 |
#define CONS_PUTCHAR 0x61 |
/* return codes */ |
#define EOK 0 /**< Successful return */ |
#define ENOCPU 1 /**< Invalid CPU id */ |
#define ENORADDR 2 /**< Invalid real address */ |
#define ENOINTR 3 /**< Invalid interrupt id */ |
#define EBADPGSZ 4 /**< Invalid pagesize encoding */ |
#define EBADTSB 5 /**< Invalid TSB description */ |
#define EINVAL 6 /**< Invalid argument */ |
#define EBADTRAP 7 /**< Invalid function number */ |
#define EBADALIGN 8 /**< Invalid address alignment */ |
#define EWOULDBLOCK 9 /**< Cannot complete operation without blocking */ |
#define ENOACCESS 10 /**< No access to specified resource */ |
#define EIO 11 /**< I/O Error */ |
#define ECPUERROR 12 /**< CPU is in error state */ |
#define ENOTSUPPORTED 13 /**< Function not supported */ |
#define ENOMAP 14 /**< No mapping found */ |
#define ETOOMANY 15 /**< Too many items specified / limit reached */ |
#define ECHANNEL 16 /**< Invalid LDC channel */ |
#define EBUSY 17 /**< Operation failed as resource is otherwise busy */ |
/** |
* Performs a hyperfast hypervisor API call from the assembly language code. |
* Expects the registers %o1-%o4 are properly filled with the arguments of the |
114,7 → 136,7 |
__hypercall_fast(p1, p2, p3, p4, p5, function_number) |
/** |
* Performs a fast hypervisor API call. |
* Performs a fast hypervisor API call which can returns a value. |
* |
* @param p1 the 1st argument of the hypervisor API call |
* @param p2 the 2nd argument of the hypervisor API call |
122,10 → 144,14 |
* @param p4 the 4th argument of the hypervisor API call |
* @param p5 the 5th argument of the hypervisor API call |
* @param function_number function number of the call |
* @param ret1 pointer to an address where the return value |
* of the hypercall should be saved, or NULL |
* @return error status |
*/ |
static inline uint64_t |
__hypercall_fast(const uint64_t p1, const uint64_t p2, const uint64_t p3, |
const uint64_t p4, const uint64_t p5, const uint64_t function_number) |
__hypercall_fast_ret1(const uint64_t p1, const uint64_t p2, const uint64_t p3, |
const uint64_t p4, const uint64_t p5, const uint64_t function_number, |
uint64_t * const ret1) |
{ |
register uint64_t a6 asm("o5") = function_number; |
register uint64_t a1 asm("o0") = p1; |
142,10 → 168,32 |
: "memory" |
); |
if (ret1 != NULL) |
*ret1 = a2; |
return a1; |
} |
/** |
* Performs a fast hypervisor API call which return no value except for the |
* error status. |
* |
* @param p1 the 1st argument of the hypervisor API call |
* @param p2 the 2nd argument of the hypervisor API call |
* @param p3 the 3rd argument of the hypervisor API call |
* @param p4 the 4th argument of the hypervisor API call |
* @param p5 the 5th argument of the hypervisor API call |
* @param function_number function number of the call |
* @return error status |
*/ |
static inline uint64_t |
__hypercall_fast(const uint64_t p1, const uint64_t p2, const uint64_t p3, |
const uint64_t p4, const uint64_t p5, const uint64_t function_number) |
{ |
return __hypercall_fast_ret1(p1, p2, p3, p4, p5, function_number, |
NULL); |
} |
/** |
* Performs a hyperfast hypervisor API call. |
* |
* @param p1 the 1st argument of the hypervisor API call |
/branches/sparc/kernel/arch/sparc64/include/trap/sun4v/mmu.h |
---|
40,7 → 40,7 |
#include <arch/stack.h> |
#include <arch/sun4v/regdef.h> |
#include <arch/mm/tlb.h> |
#include <arch/mm/sun4v/tlb.h> |
#include <arch/mm/sun4v/mmu.h> |
#include <arch/mm/sun4v/tte.h> |
#include <arch/trap/regwin.h> |
/branches/sparc/kernel/arch/sparc64/include/trap/sun4u/mmu.h |
---|
39,8 → 39,8 |
#include <arch/stack.h> |
#include <arch/sun4u/regdef.h> |
#include <arch/mm/tlb.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <arch/mm/sun4u/mmu.h> |
#include <arch/mm/sun4u/tte.h> |
#include <arch/trap/regwin.h> |
/branches/sparc/kernel/arch/sparc64/include/mm/sun4u/tlb.h |
---|
46,6 → 46,9 |
#define DTLB_MAX_LOCKED_ENTRIES 16 |
#endif |
#define MEM_CONTEXT_KERNEL 0 |
#define MEM_CONTEXT_TEMP 1 |
/** Bit width of the TLB-locked portion of kernel address space. */ |
#define KERNEL_PAGE_WIDTH 22 /* 4M */ |
91,7 → 94,7 |
#include <arch/barrier.h> |
#include <arch/types.h> |
#include <arch/register.h> |
#include <arch/cpu.h> |
#include <arch/sun4u/cpu.h> |
union tlb_context_reg { |
uint64_t v; |
128,7 → 131,7 |
* In US3, I-MMU and D-MMU have different formats of the data |
* access register virtual address. In the corresponding |
* structures the member variable for the entry number is |
* called "local_tlb_entry" - it contrast with the "tlb_entry" |
* called "local_tlb_entry" - it contrasts with the "tlb_entry" |
* for the US data access register VA structure. The rationale |
* behind this is to prevent careless mistakes in the code |
* caused by setting only the entry number and not the TLB |
230,7 → 233,7 |
*/ |
/** |
* Determine the number od entries in the DMMU's small TLB. |
* Determine the number of entries in the DMMU's small TLB. |
*/ |
static inline uint16_t tlb_dsmall_size(void) |
{ |
238,7 → 241,7 |
} |
/** |
* Determine the number od entries in each DMMU's big TLB. |
* Determine the number of entries in each DMMU's big TLB. |
*/ |
static inline uint16_t tlb_dbig_size(void) |
{ |
246,7 → 249,7 |
} |
/** |
* Determine the number od entries in the IMMU's small TLB. |
* Determine the number of entries in the IMMU's small TLB. |
*/ |
static inline uint16_t tlb_ismall_size(void) |
{ |
254,7 → 257,7 |
} |
/** |
* Determine the number od entries in the IMMU's big TLB. |
* Determine the number of entries in the IMMU's big TLB. |
*/ |
static inline uint16_t tlb_ibig_size(void) |
{ |
310,7 → 313,8 |
* |
* @param entry TLB Entry index. |
* |
* @return Current value of specified IMMU TLB Data Access Register. |
* @return Current value of specified IMMU TLB Data Access |
* Register. |
*/ |
static inline uint64_t itlb_data_access_read(index_t entry) |
{ |
340,7 → 344,8 |
* |
* @param entry TLB Entry index. |
* |
* @return Current value of specified DMMU TLB Data Access Register. |
* @return Current value of specified DMMU TLB Data Access |
* Register. |
*/ |
static inline uint64_t dtlb_data_access_read(index_t entry) |
{ |
404,7 → 409,8 |
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG) |
* @param entry TLB Entry index. |
* |
* @return Current value of specified IMMU TLB Data Access Register. |
* @return Current value of specified IMMU TLB Data Access |
* Register. |
*/ |
static inline uint64_t itlb_data_access_read(int tlb, index_t entry) |
{ |
438,7 → 444,8 |
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG, TLB_DBIG) |
* @param entry TLB Entry index. |
* |
* @return Current value of specified DMMU TLB Data Access Register. |
* @return Current value of specified DMMU TLB Data Access |
* Register. |
*/ |
static inline uint64_t dtlb_data_access_read(int tlb, index_t entry) |
{ |
613,9 → 620,8 |
/** Perform IMMU TLB Demap Operation. |
* |
* @param type |
* Selects between context and page demap |
* (and entire MMU demap on US3). |
* @param type Selects between context and page demap (and entire MMU |
* demap on US3). |
* @param context_encoding Specifies which Context register has Context ID for |
* demap. |
* @param page Address which is on the page to be demapped. |
632,17 → 638,16 |
da.context = context_encoding; |
da.vpn = pg.vpn; |
asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); /* da.value is the |
* address within the |
* ASI */ |
/* da.value is the address within the ASI */ |
asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); |
flush_pipeline(); |
} |
/** Perform DMMU TLB Demap Operation. |
* |
* @param type |
* Selects between context and page demap |
* (and entire MMU demap on US3). |
* @param type Selects between context and page demap (and entire MMU |
* demap on US3). |
* @param context_encoding Specifies which Context register has Context ID for |
* demap. |
* @param page Address which is on the page to be demapped. |
659,19 → 664,19 |
da.context = context_encoding; |
da.vpn = pg.vpn; |
asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); /* da.value is the |
* address within the |
* ASI */ |
/* da.value is the address within the ASI */ |
asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); |
membar(); |
} |
extern void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate); |
extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate); |
extern void fast_data_access_protection(tlb_tag_access_reg_t tag , istate_t *istate); |
extern void fast_instruction_access_mmu_miss(unative_t, istate_t *); |
extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t, istate_t *); |
extern void fast_data_access_protection(tlb_tag_access_reg_t , istate_t *); |
extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable); |
extern void dtlb_insert_mapping(uintptr_t, uintptr_t, int, bool, bool); |
extern void dump_sfsr_and_sfar(void); |
extern void describe_mmu_fault(void); |
#endif /* !def __ASM__ */ |
/branches/sparc/kernel/arch/sparc64/include/cpu.h |
---|
35,22 → 35,6 |
#ifndef KERN_sparc64_CPU_H_ |
#define KERN_sparc64_CPU_H_ |
#define MANUF_FUJITSU 0x04 |
#define MANUF_ULTRASPARC 0x17 /**< UltraSPARC I, UltraSPARC II */ |
#define MANUF_SUN 0x3e |
#define IMPL_ULTRASPARCI 0x10 |
#define IMPL_ULTRASPARCII 0x11 |
#define IMPL_ULTRASPARCII_I 0x12 |
#define IMPL_ULTRASPARCII_E 0x13 |
#define IMPL_ULTRASPARCIII 0x14 |
#define IMPL_ULTRASPARCIII_PLUS 0x15 |
#define IMPL_ULTRASPARCIII_I 0x16 |
#define IMPL_ULTRASPARCIV 0x18 |
#define IMPL_ULTRASPARCIV_PLUS 0x19 |
#define IMPL_SPARC64V 0x5 |
#ifndef __ASM__ |
#include <arch/types.h> |
57,13 → 41,7 |
#include <typedefs.h> |
#include <arch/register.h> |
#include <arch/sun4u/regdef.h> |
#include <arch/asm.h> |
#include <arch/sun4u/arch.h> |
#ifdef CONFIG_SMP |
#include <arch/mm/cache.h> |
#endif |
typedef struct { |
uint32_t mid; /**< Processor ID as read from |
UPA_CONFIG/FIREPLANE_CONFIG. */ |
74,30 → 52,9 |
matches this value. */ |
} cpu_arch_t; |
/** |
* Reads the module ID (agent ID/CPUID) of the current CPU. |
*/ |
static inline uint32_t read_mid(void) |
{ |
uint64_t icbus_config = asi_u64_read(ASI_ICBUS_CONFIG, 0); |
icbus_config = icbus_config >> ICBUS_CONFIG_MID_SHIFT; |
#if defined (US) |
return icbus_config & 0x1f; |
#elif defined (US3) |
if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIII_I) |
return icbus_config & 0x1f; |
else |
return icbus_config & 0x3ff; |
#else |
panic("Not implemented for this architecture."); |
return 0; |
#endif |
} |
#endif |
#endif |
/** @} |
*/ |
/branches/sparc/kernel/arch/sparc64/include/drivers/tick.h |
---|
35,11 → 35,23 |
#ifndef KERN_sparc64_TICK_H_ |
#define KERN_sparc64_TICK_H_ |
#include <arch/asm.h> |
#include <arch/interrupt.h> |
/* mask of the "counter" field of the Tick register */ |
#define TICK_COUNTER_MASK (~(1l << 63)) |
extern void tick_init(void); |
extern void tick_interrupt(int n, istate_t *istate); |
/** |
* Reads the Tick register counter. |
*/ |
static inline uint64_t tick_counter_read(void) |
{ |
return TICK_COUNTER_MASK & tick_read(); |
} |
#endif |
/** @} |
/branches/sparc/kernel/arch/sparc64/include/cpu_family.h |
---|
39,6 → 39,7 |
#include <cpu.h> |
#include <arch/register.h> |
#include <arch/asm.h> |
#include <arch/sun4u/cpu.h> |
/** |
* Find the processor (sub)family. |
/branches/sparc/kernel/arch/sparc64/Makefile.inc |
---|
101,16 → 101,19 |
endif |
# common for sun4u and sun4v |
# sources which exist in two versions - one for sun4u and one for sun4v |
ARCH_SOURCES = \ |
arch/$(ARCH)/src/$(USARCH)/start.S \ |
arch/$(ARCH)/src/trap/$(USARCH)/trap_table.S \ |
arch/$(ARCH)/src/$(USARCH)/asm.S \ |
arch/$(ARCH)/src/$(USARCH)/sparc64.c |
arch/$(ARCH)/src/$(USARCH)/sparc64.c \ |
arch/$(ARCH)/src/mm/$(USARCH)/tlb.c \ |
arch/$(ARCH)/src/cpu/$(USARCH)/cpu.c |
# specific to machine type |
# sun4u-specific, not #ifdef'd yet in order to make the code compilable |
ARCH_SOURCES += \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/panic.S \ |
arch/$(ARCH)/src/console.c \ |
121,7 → 124,6 |
arch/$(ARCH)/src/mm/cache.S \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/proc/thread.c \ |
arch/$(ARCH)/src/trap/mmu.S \ |
144,7 → 146,7 |
ifeq ($(CONFIG_SMP),y) |
ARCH_SOURCES += \ |
arch/$(ARCH)/src/smp/ipi.c \ |
arch/$(ARCH)/src/smp/smp.c |
arch/$(ARCH)/src/smp/$(USARCH)/smp.c |
endif |
ifeq ($(CONFIG_TSB),y) |
/branches/sparc/kernel/arch/sparc64/src/sun4v/sparc64.c |
---|
56,13 → 56,6 |
/** Perform sparc64 specific initialization before main_bsp() is called. */ |
void arch_pre_main(void) |
{ |
/* |
* Initialize Niagara input/output driver. |
* This will be moved to arch_post_mm_init when the memory management |
* is finished for sun4v. |
*/ |
niagara_init(); |
/* Copy init task info. */ |
init.cnt = bootinfo.taskmap.count; |
71,13 → 64,10 |
for (i = 0; i < bootinfo.taskmap.count; i++) { |
init.tasks[i].addr = (uintptr_t) bootinfo.taskmap.tasks[i].addr; |
init.tasks[i].size = bootinfo.taskmap.tasks[i].size; |
printf("Task %d starts at %x and its size id %d.\n", i, init.tasks[i].addr, init.tasks[i].size); |
} |
/* Copy boot allocations info. */ |
ballocs.base = bootinfo.ballocs.base; |
ballocs.size = bootinfo.ballocs.size; |
ofw_tree_init(bootinfo.ofw_root); |
// md_init(); |
} |
/** Perform sparc64 specific initialization before mm is initialized. */ |
96,10 → 86,13 |
* But we only create 128 buckets. |
*/ |
irq_init(1 << 11, 128); |
} |
standalone_sparc64_console_init(); |
/* |
* Initialize Niagara input/output driver. |
*/ |
niagara_init(); |
} |
} |
void arch_post_cpu_init(void) |
{ |
/branches/sparc/kernel/arch/sparc64/src/sun4v/start.S |
---|
31,9 → 31,10 |
#include <arch/stack.h> |
#include <arch/sun4v/regdef.h> |
#include <arch/sun4v/hypercall.h> |
#include <arch/mm/pagesize.h> |
#include <arch/mm/sun4v/tte.h> |
#include <arch/mm/sun4v/mmu.h> |
#include <arch/mm/tlb.h> |
#include <arch/mm/sun4v/tlb.h> |
.register %g2, #scratch |
.register %g3, #scratch |
44,13 → 45,6 |
#define PHYSMEM_ADDR_SIZE 56 |
/* |
* SILO for an unknown reason loads the image to MAPPING_OFFSET + 0x4000 bytes |
* from the start of the physical memory. We pretend that the physical memory |
* starts MAPPING_OFFSET bytes further than it actually does. |
*/ |
#define MAPPING_OFFSET 0x400000 |
/* |
* Flags set in the TTE data entry mapping the kernel. |
*/ |
#ifdef CONFIG_VIRT_IDX_DCACHE |
119,10 → 113,6 |
sllx %l5, 13 + (63 - (PHYSMEM_ADDR_SIZE - 1)), %l5 |
srlx %l5, 63 - (PHYSMEM_ADDR_SIZE - 1), %l5 |
! pretend the physical memory starts further |
set MAPPING_OFFSET, %g2 |
add %l5, %g2, %l5 |
/* |
* Setup basic runtime environment. |
*/ |
/branches/sparc/kernel/arch/sparc64/src/console.c |
---|
52,7 → 52,7 |
#include <arch/asm.h> |
#include <arch/register.h> |
#include <proc/thread.h> |
#include <arch/mm/tlb.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <genarch/ofw/ofw_tree.h> |
#include <arch.h> |
#include <panic.h> |
/branches/sparc/kernel/arch/sparc64/src/trap/exception.c |
---|
34,8 → 34,8 |
*/ |
#include <arch/trap/exception.h> |
#include <arch/mm/tlb.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <arch/interrupt.h> |
#include <interrupt.h> |
#include <arch/asm.h> |
157,7 → 157,7 |
{ |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
dump_sfsr_and_sfar(); |
describe_mmu_fault(); |
panic("%s\n", __func__); |
} |
/branches/sparc/kernel/arch/sparc64/src/mm/as.c |
---|
33,8 → 33,9 |
*/ |
#include <arch/mm/as.h> |
#include <arch/mm/tlb.h> |
#include <arch/mm/pagesize.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <genarch/mm/page_ht.h> |
#include <genarch/mm/asid_fifo.h> |
#include <debug.h> |
/branches/sparc/kernel/arch/sparc64/src/mm/tsb.c |
---|
33,7 → 33,8 |
*/ |
#include <arch/mm/tsb.h> |
#include <arch/mm/tlb.h> |
#include <arch/mm/pagesize.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <arch/mm/page.h> |
#include <arch/barrier.h> |
#include <mm/as.h> |
/branches/sparc/kernel/arch/sparc64/src/mm/frame.c |
---|
56,6 → 56,8 |
uintptr_t start = bootinfo.memmap.zones[i].start; |
size_t size = bootinfo.memmap.zones[i].size; |
printf("Found a zone: start = %x, size = %d.\n", start, size); |
/* |
* The memmap is created by HelenOS boot loader. |
* It already contains no holes. |
/branches/sparc/kernel/arch/sparc64/src/mm/page.c |
---|
33,8 → 33,9 |
*/ |
#include <arch/mm/page.h> |
#include <arch/mm/tlb.h> |
#include <arch/mm/pagesize.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <genarch/mm/page_ht.h> |
#include <mm/frame.h> |
#include <arch/mm/frame.h> |
/branches/sparc/kernel/arch/sparc64/src/drivers/tick.c |
---|
53,10 → 53,10 |
interrupt_register(14, "tick_int", tick_interrupt); |
compare.int_dis = false; |
compare.tick_cmpr = CPU->arch.clock_frequency / HZ; |
compare.tick_cmpr = tick_counter_read() + |
CPU->arch.clock_frequency / HZ; |
CPU->arch.next_tick_cmpr = compare.tick_cmpr; |
tick_compare_write(compare.value); |
tick_write(0); |
#if defined (US3) |
/* disable STICK interrupts and clear any pending ones */ |
110,12 → 110,12 |
* about 812 years. If there was a 2GHz UltraSPARC computer, it would |
* overflow only in 146 years. |
*/ |
drift = tick_read() - CPU->arch.next_tick_cmpr; |
drift = tick_counter_read() - CPU->arch.next_tick_cmpr; |
while (drift > CPU->arch.clock_frequency / HZ) { |
drift -= CPU->arch.clock_frequency / HZ; |
CPU->missed_clock_ticks++; |
} |
CPU->arch.next_tick_cmpr = tick_read() + |
CPU->arch.next_tick_cmpr = tick_counter_read() + |
(CPU->arch.clock_frequency / HZ) - drift; |
tick_compare_write(CPU->arch.next_tick_cmpr); |
clock(); |
/branches/sparc/kernel/arch/sparc64/src/sun4u/start.S |
---|
28,13 → 28,13 |
#include <arch/arch.h> |
#include <arch/sun4u/arch.h> |
#include <arch/cpu.h> |
#include <arch/sun4u/cpu.h> |
#include <arch/sun4u/regdef.h> |
#include <arch/boot/boot.h> |
#include <arch/stack.h> |
#include <arch/mm/pagesize.h> |
#include <arch/mm/sun4u/mmu.h> |
#include <arch/mm/tlb.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <arch/mm/sun4u/tte.h> |
/branches/sparc/boot/arch/sparc64/loader/main.c |
---|
152,9 → 152,25 |
/** |
* Performs sun4u-specific initialization. The components are expected |
* to be already copied and boot allocator initialized. |
* |
* @param base kernel base virtual address |
* @param top virtual address above which the boot allocator |
* can make allocations |
*/ |
static void bootstrap_sun4u(void) |
static void bootstrap_sun4u(void *base, unsigned int top) |
{ |
void *balloc_base; |
/* |
* Claim and map the physical memory for the boot allocator. |
* Initialize the boot allocator. |
*/ |
balloc_base = base + ALIGN_UP(top, PAGE_SIZE); |
(void) ofw_claim_phys(bootinfo.physmem_start + balloc_base, |
BALLOC_MAX_SIZE); |
(void) ofw_map(balloc_base, balloc_base, BALLOC_MAX_SIZE, -1); |
balloc_init(&bootinfo.ballocs, (uintptr_t)balloc_base); |
printf("\nCanonizing OpenFirmware device tree..."); |
bootinfo.ofw_root = ofw_tree_build(); |
printf("done.\n"); |
177,12 → 193,35 |
*/ |
static void bootstrap_sun4v(void) |
{ |
/* |
* When SILO booted, the OBP had established a virtual to physical |
* memory mapping. This mapping is not an identity (because the |
* physical memory starts on non-zero address) - this is not |
* surprising. But! The mapping even does not map virtual address |
* 0 onto the starting address of the physical memory, but onto an |
* address which is 0x400000 bytes higher. The reason is that the |
* OBP had already used the memory just at the beginning of the |
* physical memory, so that memory cannot be used by SILO (nor |
* bootloader). As for now, we solve it by a nasty workaround: |
* we pretend that the physical memory starts 0x400000 bytes further |
* than it actually does (and hence pretend that the physical memory |
* is 0x400000 bytes smaller). Of course, the value 0x400000 will most |
* probably depend on the machine and OBP version (the workaround now |
* works on Simics). A solution would be to inspect the "available" |
* property of the "/memory" node to find out which parts of memory |
* are used by OBP and redesign the algorithm of copying |
* kernel/init tasks/ramdisk from the bootable image to memory |
* (which we must do anyway because of issues with claiming the memory |
* on Serengeti). |
*/ |
bootinfo.physmem_start += 0x400000; |
bootinfo.memmap.zones[0].start += 0x400000; |
bootinfo.memmap.zones[0].size -= 0x400000; |
} |
void bootstrap(void) |
{ |
void *base = (void *) KERNEL_VIRTUAL_ADDRESS; |
void *balloc_base; |
unsigned int top = 0; |
int i, j; |
317,19 → 356,9 |
memcpy(base, components[0].start, components[0].size); |
printf("done.\n"); |
/* |
* Claim and map the physical memory for the boot allocator. |
* Initialize the boot allocator. |
*/ |
balloc_base = base + ALIGN_UP(top, PAGE_SIZE); |
(void) ofw_claim_phys(bootinfo.physmem_start + balloc_base, |
BALLOC_MAX_SIZE); |
(void) ofw_map(balloc_base, balloc_base, BALLOC_MAX_SIZE, -1); |
balloc_init(&bootinfo.ballocs, (uintptr_t)balloc_base); |
/* perform architecture-specific initialization */ |
if (architecture == COMPATIBLE_SUN4U) { |
bootstrap_sun4u(); |
bootstrap_sun4u(base, top); |
} else if (architecture == COMPATIBLE_SUN4V) { |
bootstrap_sun4v(); |
} else { |