Strict Standards: Declaration of action_plugin_importoldchangelog::register() should be compatible with DokuWiki_Action_Plugin::register($controller) in /DISK2/WWW/pavel-rimsky.cz/helenos/lib/plugins/importoldchangelog/action.php on line 8 Strict Standards: Declaration of action_plugin_importoldindex::register() should be compatible with DokuWiki_Action_Plugin::register($controller) in /DISK2/WWW/pavel-rimsky.cz/helenos/lib/plugins/importoldindex/action.php on line 0 Deprecated: Function split() is deprecated in /DISK2/WWW/pavel-rimsky.cz/helenos/inc/auth.php on line 154 Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /DISK2/WWW/pavel-rimsky.cz/helenos/inc/auth.php on line 456 Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /DISK2/WWW/pavel-rimsky.cz/helenos/inc/auth.php on line 456 Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /DISK2/WWW/pavel-rimsky.cz/helenos/inc/auth.php on line 453 Index: kernel/generic/include/synch/mutex.h =================================================================== --- kernel/generic/include/synch/mutex.h (revision 3396) +++ kernel/generic/include/synch/mutex.h (working copy) @@ -42,7 +42,7 @@ typedef enum { MUTEX_PASSIVE, MUTEX_ACTIVE -} mutex_type_t; +} mutex_type_t; // hmm. jaky je rozdil mezi aktivnim a pasivnim mutexem? typedef struct { mutex_type_t type; Index: kernel/generic/src/synch/mutex.c =================================================================== --- kernel/generic/src/synch/mutex.c (revision 3396) +++ kernel/generic/src/synch/mutex.c (working copy) @@ -48,7 +48,7 @@ void mutex_initialize(mutex_t *mtx, mutex_type_t type) { mtx->type = type; - semaphore_initialize(&mtx->sem, 1); + semaphore_initialize(&mtx->sem, 1); // inicializuje waitq a nastavi missed wakeups na 1 } /** Acquire mutex. Index: kernel/generic/src/synch/semaphore.c =================================================================== --- kernel/generic/src/synch/semaphore.c (revision 3396) +++ kernel/generic/src/synch/semaphore.c (working copy) @@ -51,17 +51,17 @@ */ void semaphore_initialize(semaphore_t *s, int val) { - ipl_t ipl; + ipl_t ipl; // interrupt priority level - waitq_initialize(&s->wq); + waitq_initialize(&s->wq); // inicializuje spinlock chranici waitq, inicializuje seznam (queue), nastavi missed wakeups na 0 - ipl = interrupts_disable(); + ipl = interrupts_disable(); // zakaze interrupty vynulovanim IE v PSTATE, zapamatuje si PSTATE spinlock_lock(&s->wq.lock); s->wq.missed_wakeups = val; spinlock_unlock(&s->wq.lock); - interrupts_restore(ipl); + interrupts_restore(ipl); // do PSTATE zapise zapamatovanou hodnotu } /** Semaphore down Index: kernel/generic/src/synch/waitq.c =================================================================== --- kernel/generic/src/synch/waitq.c (revision 3396) +++ kernel/generic/src/synch/waitq.c (working copy) @@ -65,7 +65,7 @@ void waitq_initialize(waitq_t *wq) { spinlock_initialize(&wq->lock, "waitq_lock"); - list_initialize(&wq->head); + list_initialize(&wq->head); // list_initialize je jako LIST_INITIALIZE, ale krabicku nevyrobi, jen ji nastavi ukazatele prev a next, aby ukazovaly na krabicku samotnou wq->missed_wakeups = 0; } Index: kernel/generic/src/main/main.c =================================================================== --- kernel/generic/src/main/main.c (revision 3396) +++ kernel/generic/src/main/main.c (working copy) @@ -192,8 +192,6 @@ /* Keep this the first thing. */ the_initialize(THE); - asm("sethi 0x40100, %g0"); - LOG(); version_print(); @@ -315,7 +313,7 @@ arch_pre_mm_init(); frame_init(); - page_init(); + page_init(); // zavola arch. specific inicializaci, ktera nastavi implementace "abstraktnich" page mapping operations na operace implementovane pomoci globalni hashmapy (operace: mapping insert, mapping remove, mapping find) tlb_init(); arch_post_mm_init(); Index: kernel/generic/src/mm/frame.c =================================================================== --- kernel/generic/src/mm/frame.c (revision 3396) +++ kernel/generic/src/mm/frame.c (working copy) @@ -158,6 +158,11 @@ * @param newzone New zone to be inserted into zone list. * @return Zone number on success, -1 on error. */ +// cili: v seznamu vsech zon jsou zony usporadany vzestupne dle BASE (zacatku) +// tato fce zatridi danou zonu do seznamu zon. Nejprve overi, ze je v seznamu zon +// jeste misto (seznam ma pevnou velikost). Pak najde misto v seznamu, kam +// zona patri, posune prvky, ktere maji byt za zonou, o 1 pozici dal, a na spravne +// misto zonu soupne. static int zones_add_zone(zone_t *newzone) { unsigned int i, j; @@ -209,6 +214,7 @@ * filled into the variable on success. * @return Pointer to locked zone containing frame. */ + // proleze seznam zon, najde tu, ktera obsahuje dany ramec static zone_t *find_zone_and_lock(pfn_t frame, unsigned int *pzone) { unsigned int i; @@ -257,6 +263,8 @@ * @param pzone Pointer to preferred zone or NULL, on return contains * zone number. */ + // proste: prolez vsechny zony a podivej se, ktera je schopna naalokovat 2^order + // pameti a ktera vyhovuje flagum "flags", tu mi zamcenou vrat. static zone_t * find_free_zone_and_lock(uint8_t order, int flags, unsigned int *pzone) { @@ -265,6 +273,8 @@ unsigned int hint = pzone ? *pzone : 0; /* Mask off flags that are not applicable. */ + // [bug] nemelo by tam byt ~FRAME_LOW_4_GiB ? + // ale treba ne, treba jsou temi masked-off flagy vsechny zbyvajici flagy flags &= FRAME_LOW_4_GiB; spinlock_lock(&zones.lock); @@ -822,8 +832,13 @@ z->base = start; z->count = count; + // vynulujeme tento flag, ale mozna ho hned v dalsim kroku zase nastavime /* Mask off flags that are calculated automatically. */ flags &= ~FRAME_LOW_4_GiB; + + // tady se zjisti, jestli zona bude obsahovat adresy nad 4 GiB + // zjisti se to tak, ze se podivame, jestli posledni ramec nepreleze pres 4 GiB + // 2^(32 - FRAME_WIDTH) je cislo prvniho ramce, ktery preleze 4 GiB /* Determine calculated flags. */ if (z->base + count < (1ULL << (32 - FRAME_WIDTH))) /* 4 GiB */ flags |= FRAME_LOW_4_GiB; @@ -837,20 +852,23 @@ * Compute order for buddy system, initialize */ max_order = fnzb(count); - z->buddy_system = (buddy_system_t *)&z[1]; + z->buddy_system = (buddy_system_t *)&z[1]; // struktura buddy systemu se nachazi tesne za strukturou popisujici zonu + // vytvorime buddy system, implementace "abstraktnich" funkci jsou uvedeny v zone_buddy_system_operations + // temto implementacim se bude predavat hodnota posl. parametru, tedy "(void *) z" buddy_system_create(z->buddy_system, max_order, &zone_buddy_system_operations, (void *) z); /* Allocate frames _after_ the conframe */ /* Check sizes */ z->frames = (frame_t *)((uint8_t *) z->buddy_system + - buddy_conf_size(max_order)); + buddy_conf_size(max_order)); // ...no a seznam framu se nachazi za strukturou buddy for (i = 0; i < count; i++) { - frame_initialize(&z->frames[i]); + frame_initialize(&z->frames[i]); // jen mu nastavi refcount na 1 a vynuluje jine konf. polozky } /* Stuffing frames */ + // oznacime vsechny ramce jako volne, tj. buddy system z nich muze alokovat for (i = 0; i < count; i++) { z->frames[i].refcount = 0; buddy_system_free(z->buddy_system, &z->frames[i].buddy_link); @@ -884,6 +902,9 @@ * zone_conf_size() amount of data. If the confframe is * inside the area, the zone free frame information is * modified not to include it. + * // vyznam toho tretiho parametru mi neni vubec jasny + * // asi to bude nejaky ramec obsahujici informace o cele zone + * // a cilem teto funkce je tento ramec vhodne posunout dal, aby nekolidoval s inicialnimi tasky, zasobnikem ani kernelem * * @return Zone number or -1 on error. */ @@ -903,6 +924,8 @@ /* If conframe is supposed to be inside our zone, then make sure * it does not span kernel & init */ + // zone_conf_size - rekne, kolik bude zabirat struktura popisujici zonu o velikosti count ramcu + // concount = pocet ramcu zony, ve kterych je ulozena konfigurace confcount = SIZE2FRAMES(zone_conf_size(count)); if (confframe >= start && confframe < start + count) { for (; confframe < start + count; confframe++) { @@ -946,7 +969,7 @@ /* If confdata in zone, mark as unavailable */ if (confframe >= start && confframe < start + count) for (i = confframe; i < confframe + confcount; i++) { - zone_mark_unavailable(z, i - z->base); + zone_mark_unavailable(z, i - z->base); // udela se to tak, ze se buddy systemu rekne, aby znedostupnovane ramce "naalokoval" } return znum; @@ -1158,11 +1181,11 @@ /** Initialize physical memory management. */ void frame_init(void) { - if (config.cpu_active == 1) { + if (config.cpu_active == 1) { // cpu_active nastavi main_bsp na 1 zones.count = 0; - spinlock_initialize(&zones.lock, "zones.lock"); + spinlock_initialize(&zones.lock, "zones.lock"); // vlastne zinicializuje prislusny semafor... mutex_initialize(&mem_avail_mtx, MUTEX_ACTIVE); - condvar_initialize(&mem_avail_cv); + condvar_initialize(&mem_avail_cv); // zinicializuje waitq patrici podminkove promenne } /* Tell the architecture to create some memory */ frame_arch_init(); Index: kernel/arch/sparc64/include/asm.h =================================================================== --- kernel/arch/sparc64/include/asm.h (revision 3396) +++ kernel/arch/sparc64/include/asm.h (working copy) @@ -202,10 +202,10 @@ * @return Old interrupt priority level. */ static inline ipl_t interrupts_disable(void) { - pstate_reg_t pstate; + pstate_reg_t pstate; // packed struktura zapouzdrujici vsechna pole registru uint64_t value; - value = pstate_read(); + value = pstate_read(); // implementovano presne tak, jak bys cekal pstate.value = value; pstate.ie = false; pstate_write(pstate.value); Index: kernel/arch/sparc64/include/mm/tte.h =================================================================== --- kernel/arch/sparc64/include/mm/tte.h (revision 3396) +++ kernel/arch/sparc64/include/mm/tte.h (working copy) @@ -74,10 +74,15 @@ unsigned size : 2; /**< Page size of this entry. */ unsigned nfo : 1; /**< No-Fault-Only. */ unsigned ie : 1; /**< Invert Endianness. */ - unsigned soft2 : 9; /**< Software defined field. */ + unsigned soft2 : 9; /**< Software defined field. */ // nahoru stejny +#if defined (US) unsigned diag : 9; /**< Diagnostic data. */ unsigned pfn : 28; /**< Physical Address bits, bits 40:13. */ - unsigned soft : 6; /**< Software defined field. */ +#elif defined (US3) + unsigned : 7; /**< Reserved. */ + unsigned pfn : 30; /**< Physical Address bits, bits 42:13 */ +#endif + unsigned soft : 6; /**< Software defined field. */ /// dolu stejny unsigned l : 1; /**< Lock. */ unsigned cp : 1; /**< Cacheable in physically indexed cache. */ unsigned cv : 1; /**< Cacheable in virtually indexed cache. */ Index: kernel/arch/sparc64/include/mm/tlb.h =================================================================== --- kernel/arch/sparc64/include/mm/tlb.h (revision 3396) +++ kernel/arch/sparc64/include/mm/tlb.h (working copy) @@ -32,6 +32,7 @@ /** @file */ + #ifndef KERN_sparc64_TLB_H_ #define KERN_sparc64_TLB_H_ @@ -61,6 +62,15 @@ #define TLB_DEMAP_SECONDARY 1 #define TLB_DEMAP_NUCLEUS 2 +/* there are more TLBs in one MMU on US3, their codes are defined here*/ +#if defined (US3) + #define TLB_DT16 0 + #define TLB_DT512_1 2 + #define TLB_DT512_2 3 + #define TLB_IT16 0 + #define TLB_IT128 2 +#endif + #define TLB_DEMAP_CONTEXT_SHIFT 4 /* TLB Tag Access shifts */ @@ -90,6 +100,9 @@ typedef tte_data_t tlb_data_t; /** I-/D-TLB Data Access Address in Alternate Space. */ + +#if defined (US) + union tlb_data_access_addr { uint64_t value; struct { @@ -98,9 +111,54 @@ unsigned : 3; } __attribute__ ((packed)); }; -typedef union tlb_data_access_addr tlb_data_access_addr_t; -typedef union tlb_data_access_addr tlb_tag_read_addr_t; +typedef union tlb_data_access_addr dtlb_data_access_addr_t; +typedef union tlb_data_access_addr dtlb_tag_read_addr_t; +typedef union tlb_data_access_addr itlb_data_access_addr_t; +typedef union tlb_data_access_addr itlb_tag_read_addr_t; +#elif defined (US3) + +/* + * On 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" + * for the US data access register structure. The racionale + * behind this is to prevent careless mistakes in the code + * caused by setting only the entry number and not the TLB + * number in the US3 code (when taking the code from US). + */ + +union dtlb_data_access_addr { + uint64_t value; + struct { + uint64_t : 45; + unsigned : 1; + unsigned tlb_number : 2; + unsigned : 4; + unsigned local_tlb_entry : 9; + unsigned : 3; + } __attribute__ ((packed)); +}; +typedef union dtlb_data_access_addr dtlb_data_access_addr_t; +typedef union dtlb_data_access_addr dtlb_tag_read_addr_t; + +union itlb_data_access_addr { + uint64_t value; + struct { + uint64_t : 45; + unsigned : 1; + unsigned tlb_number : 2; + unsigned : 6; + unsigned local_tlb_entry : 7; + unsigned : 3; + } __attribute__ ((packed)); +}; +typedef union itlb_data_access_addr itlb_data_access_addr_t; +typedef union itlb_data_access_addr itlb_tag_read_addr_t; + +#endif + /** I-/D-TLB Tag Read Register. */ union tlb_tag_read_reg { uint64_t value; @@ -182,6 +240,8 @@ flush_pipeline(); } +#if defined (US) + /** Read IMMU TLB Data Access Register. * * @param entry TLB Entry index. @@ -190,7 +250,7 @@ */ static inline uint64_t itlb_data_access_read(index_t entry) { - tlb_data_access_addr_t reg; + itlb_data_access_addr_t reg; reg.value = 0; reg.tlb_entry = entry; @@ -204,7 +264,7 @@ */ static inline void itlb_data_access_write(index_t entry, uint64_t value) { - tlb_data_access_addr_t reg; + itlb_data_access_addr_t reg; reg.value = 0; reg.tlb_entry = entry; @@ -220,7 +280,7 @@ */ static inline uint64_t dtlb_data_access_read(index_t entry) { - tlb_data_access_addr_t reg; + dtlb_data_access_addr_t reg; reg.value = 0; reg.tlb_entry = entry; @@ -234,7 +294,7 @@ */ static inline void dtlb_data_access_write(index_t entry, uint64_t value) { - tlb_data_access_addr_t reg; + dtlb_data_access_addr_t reg; reg.value = 0; reg.tlb_entry = entry; @@ -250,7 +310,7 @@ */ static inline uint64_t itlb_tag_read_read(index_t entry) { - tlb_tag_read_addr_t tag; + itlb_tag_read_addr_t tag; tag.value = 0; tag.tlb_entry = entry; @@ -265,13 +325,120 @@ */ static inline uint64_t dtlb_tag_read_read(index_t entry) { - tlb_tag_read_addr_t tag; + dtlb_tag_read_addr_t tag; tag.value = 0; tag.tlb_entry = entry; return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value); } +#elif defined (US3) + + +/** Read IMMU TLB Data Access Register. + * + * @param tlb TLB number (one of TLB_IT16 or TLB_IT128) + * @param entry TLB Entry index. + * + * @return Current value of specified IMMU TLB Data Access Register. + */ +static inline uint64_t itlb_data_access_read(int tlb, index_t entry) +{ + itlb_data_access_addr_t reg; + + reg.value = 0; + reg.tlb_number = tlb; + reg.local_tlb_entry = entry; + return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value); +} + +/** Write IMMU TLB Data Access Register. + * @param tlb TLB number (one of TLB_IT16 or TLB_IT128) + * @param entry TLB Entry index. + * @param value Value to be written. + */ +static inline void itlb_data_access_write(int tlb, index_t entry, uint64_t value) +{ + itlb_data_access_addr_t reg; + + reg.value = 0; + reg.tlb_number = tlb; + reg.local_tlb_entry = entry; + asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value); + flush_pipeline(); +} + +/** Read DMMU TLB Data Access Register. + * + * @param tlb TLB number (one of TLB_DT16, TLB_DT512_1, TLB_DT512_2) + * @param entry TLB Entry index. + * + * @return Current value of specified DMMU TLB Data Access Register. + */ +static inline uint64_t dtlb_data_access_read(int tlb, index_t entry) +{ + dtlb_data_access_addr_t reg; + + reg.value = 0; + reg.tlb_number = tlb; + reg.local_tlb_entry = entry; + return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value); +} + +/** Write DMMU TLB Data Access Register. + * + * @param tlb TLB number (one of TLB_DT16, TLB_DT512_1, TLB_DT512_2) + * @param entry TLB Entry index. + * @param value Value to be written. + */ +static inline void dtlb_data_access_write(int tlb, index_t entry, uint64_t value) +{ + dtlb_data_access_addr_t reg; + + reg.value = 0; + reg.tlb_number = tlb; + reg.local_tlb_entry = entry; + asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value); + membar(); +} + +/** Read IMMU TLB Tag Read Register. + * + * @param tlb TLB number (one of TLB_IT16 or TLB_IT128) + * @param entry TLB Entry index. + * + * @return Current value of specified IMMU TLB Tag Read Register. + */ +static inline uint64_t itlb_tag_read_read(int tlb, index_t entry) +{ + itlb_tag_read_addr_t tag; + + tag.value = 0; + tag.tlb_number = tlb; + tag.local_tlb_entry = entry; + return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value); +} + +/** Read DMMU TLB Tag Read Register. + * + * @param tlb TLB number (one of TLB_DT16, TLB_DT512_1, TLB_DT512_2) + * @param entry TLB Entry index. + * + * @return Current value of specified DMMU TLB Tag Read Register. + */ +static inline uint64_t dtlb_tag_read_read(int tlb, index_t entry) +{ + dtlb_tag_read_addr_t tag; + + tag.value = 0; + tag.tlb_number = tlb; + tag.local_tlb_entry = entry; + return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value); +} + +#endif + + /** Write IMMU TLB Tag Access Register. * * @param v Value to be written. Index: kernel/arch/sparc64/include/drivers/simics_output.h =================================================================== --- kernel/arch/sparc64/include/drivers/simics_output.h (revision 0) +++ kernel/arch/sparc64/include/drivers/simics_output.h (revision 0) @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2006 Pavel Rimsky + * 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 sparc64 + * @{ + */ +/** @file + */ + +#ifndef KERN_sparc64_SIMICS_OUTPUT_H_ +#define KERN_sparc64_SIMICS_OUTPUT_H_ + +extern void simics_output_init(void); + +#endif + +/** @} + */ \ No newline at end of file Index: kernel/arch/sparc64/Makefile.inc =================================================================== --- kernel/arch/sparc64/Makefile.inc (revision 3398) +++ kernel/arch/sparc64/Makefile.inc (working copy) @@ -114,7 +114,8 @@ arch/$(ARCH)/src/drivers/tick.c \ arch/$(ARCH)/src/drivers/kbd.c \ arch/$(ARCH)/src/drivers/scr.c \ - arch/$(ARCH)/src/drivers/pci.c + arch/$(ARCH)/src/drivers/pci.c \ + arch/$(ARCH)/src/drivers/simics_output.c ifeq ($(CONFIG_SMP),y) ARCH_SOURCES += \ Index: kernel/arch/sparc64/src/sparc64.c =================================================================== --- kernel/arch/sparc64/src/sparc64.c (revision 3396) +++ kernel/arch/sparc64/src/sparc64.c (working copy) @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +69,8 @@ ballocs.size = bootinfo.ballocs.size; ofw_tree_init(bootinfo.ofw_root); + + /**/ simics_output_init(); } /** Perform sparc64 specific initialization before mm is initialized. */ @@ -87,6 +90,7 @@ */ irq_init(1 << 11, 128); + //simics_output_init(); standalone_sparc64_console_init(); } } Index: kernel/arch/sparc64/src/mm/tlb.c =================================================================== --- kernel/arch/sparc64/src/mm/tlb.c (revision 3396) +++ kernel/arch/sparc64/src/mm/tlb.c (working copy) @@ -75,7 +75,9 @@ /* * Invalidate all non-locked DTLB and ITLB entries. */ + tlb_print(); tlb_invalidate_all(); + tlb_print(); /* * Clear both SFSRs. @@ -331,6 +333,26 @@ } } +/** Print TLB entry (for debugging purposes). + * + * The diag field has been left out in order to make this function more generic + * (there is no diag field on US3 architeture). + * + * @param i TLB entry number + * @param t TLB entry tag + * @param d TLB entry data + */ +static void print_tlb_entry(int i, tlb_tag_read_reg_t t, tlb_data_t d) +{ + printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, " + "ie=%d, soft2=%#x, pfn=%#x, soft=%#x, l=%d, " + "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn, + t.context, d.v, d.size, d.nfo, d.ie, d.soft2, + d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g); +} + +#if defined (US) + /** Print contents of both TLBs. */ void tlb_print(void) { @@ -342,28 +364,64 @@ for (i = 0; i < ITLB_ENTRY_COUNT; i++) { d.value = itlb_data_access_read(i); t.value = itlb_tag_read_read(i); - - printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, " - "ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, " - "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn, - t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag, - d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g); + print_tlb_entry(t, d); } printf("D-TLB contents:\n"); for (i = 0; i < DTLB_ENTRY_COUNT; i++) { d.value = dtlb_data_access_read(i); t.value = dtlb_tag_read_read(i); - - printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, " - "ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, " - "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn, - t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag, - d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g); + print_tlb_entry(t, d); } +} +#elif defined (US3) + +/** Print contents of all TLBs. */ +void tlb_print(void) +{ + int i; + tlb_data_t d; + tlb_tag_read_reg_t t; + + printf("IT16 contents:\n"); + for (i = 0; i < 16; i++) { + d.value = dtlb_data_access_read(TLB_IT16, i); + t.value = dtlb_tag_read_read(TLB_IT16, i); + print_tlb_entry(i, t, d); + } + + printf("IT128 contents:\n"); + for (i = 0; i < 128; i++) { + d.value = dtlb_data_access_read(TLB_IT128, i); + t.value = dtlb_tag_read_read(TLB_IT128, i); + print_tlb_entry(i, t, d); + } + + printf("DT16 contents:\n"); + for (i = 0; i < 16; i++) { + d.value = dtlb_data_access_read(TLB_DT16, i); + t.value = dtlb_tag_read_read(TLB_DT16, i); + print_tlb_entry(i, t, d); + } + + printf("DT512_1 contents:\n"); + for (i = 0; i < 512; i++) { + d.value = dtlb_data_access_read(TLB_DT512_1, i); + t.value = dtlb_tag_read_read(TLB_DT512_1, i); + print_tlb_entry(i, t, d); + } + + printf("DT512_2 contents:\n"); + for (i = 0; i < 512; i++) { + d.value = dtlb_data_access_read(TLB_DT512_2, i); + t.value = dtlb_tag_read_read(TLB_DT512_2, i); + print_tlb_entry(i, t, d); + } } +#endif + void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, const char *str) { @@ -419,10 +477,38 @@ dtlb_sfsr_write(0); } +#if defined (US3) +static void tlb_invalidate_entry(int tlb, index_t entry) +{ + tlb_data_t d; + tlb_tag_read_reg_t t; + + if (tlb == TLB_DT16 || tlb == TLB_DT512_1 || tlb == TLB_DT512_2) { + d.value = dtlb_data_access_read(tlb, entry); + if (!d.l || d.g) { + t.value = dtlb_tag_read_read(tlb, entry); + d.v = false; + dtlb_tag_access_write(t.value); + dtlb_data_access_write(tlb, entry, d.value); + } + } else if (tlb == TLB_IT16 || tlb == TLB_IT128) { + d.value = itlb_data_access_read(tlb, entry); + if (!d.l || d.g) { + t.value = itlb_tag_read_read(tlb, entry); + d.v = false; + itlb_tag_access_write(t.value); + itlb_data_access_write(tlb, entry, d.value); + } + } +} +#endif + /** Invalidate all unlocked ITLB and DTLB entries. */ void tlb_invalidate_all(void) { int i; + +#if defined (US) tlb_data_t d; tlb_tag_read_reg_t t; @@ -444,7 +530,7 @@ itlb_data_access_write(i, d.value); } } - + for (i = 0; i < DTLB_ENTRY_COUNT; i++) { d.value = dtlb_data_access_read(i); if (!d.l || d.g) { @@ -454,7 +540,22 @@ dtlb_data_access_write(i, d.value); } } - + +#elif defined (US3) + + for (i = 0; i < 16; i++) + tlb_invalidate_entry(TLB_IT16, i); + for (i = 0; i < 128; i++) + tlb_invalidate_entry(TLB_IT128, i); + for (i = 0; i < 16; i++) + tlb_invalidate_entry(TLB_DT16, i); + for (i = 0; i < 512; i++) + tlb_invalidate_entry(TLB_DT512_1, i); + for (i = 0; i < 512; i++) + tlb_invalidate_entry(TLB_DT512_2, i); + +#endif + } /** Invalidate all ITLB and DTLB entries that belong to specified ASID Index: kernel/arch/sparc64/src/mm/frame.c =================================================================== --- kernel/arch/sparc64/src/mm/frame.c (revision 3396) +++ kernel/arch/sparc64/src/mm/frame.c (working copy) @@ -48,21 +48,22 @@ */ void frame_arch_init(void) { + // co se tyce memory map, tak ta (na mem Serengeti) obsahuje jedinou zonu, + // ktera zacina na adrese 0 a je velka jako cela fyzicka pamet unsigned int i; pfn_t confdata; - if (config.cpu_active == 1) { for (i = 0; i < bootinfo.memmap.count; i++) { uintptr_t start = bootinfo.memmap.zones[i].start; size_t size = bootinfo.memmap.zones[i].size; - /* * The memmap is created by HelenOS boot loader. * It already contains no holes. */ - confdata = ADDR2PFN(start); - if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0)))) + // confdata je ramec (nachazejici se typicky v zone) obsahujici informace o zone + confdata = ADDR2PFN(start); // ADDR2FPN(addr) vrati (pfn_t) (addr >> FRAME_WIDTH), FRAME_WIDTH = 13 (8k) + if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0)))) // KA2PA pricte physmem_base confdata = ADDR2PFN(KA2PA(PFN2ADDR(2))); zone_create(ADDR2PFN(start), SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)), Index: kernel/arch/sparc64/src/drivers/simics_output.c =================================================================== --- kernel/arch/sparc64/src/drivers/simics_output.c (revision 0) +++ kernel/arch/sparc64/src/drivers/simics_output.c (revision 0) @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2006 Pavel Rimsky + * 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 sparc64 + * @{ + */ +/** + * @file + * @brief Routines for writing characters directly to Simics CLI. + * + */ + +#include +#include +#include +#include + +/** maximum number of characters stored before printed */ +#define BUFSIZE 512 + +/* %g2 will store a magic value used during initialization */ +asm (".register %g2, #scratch"); + +/* %g3 will store the address (to be passed to Simics) of the buffer */ +asm (".register %g3, #scratch"); + +/* lock protecting the character buffer */ +SPINLOCK_INITIALIZE(simics_buf_lock); + +static void simics_putchar(struct chardev * cd, char c); + +/** character device operations - only writing will be supported */ +static chardev_operations_t simics_stdout_ops = { + .suspend = NULL, + .resume = NULL, + .write = simics_putchar, + .read = NULL +}; + +/** Simics character device */ +chardev_t simics_stdout; + +/** + * buffer to which output characters are stored before they're printed by Simics + */ +static volatile char buffer[BUFSIZE]; + +/** Writes a single character to the Simics CLI. + * + * The character is not written immediately, but it is stored to the first free + * position in the buffer, waiting for Simics' Python routine to hang it up + * and print it. + */ +static void simics_putchar(struct chardev * cd, char c) +{ + /* the first free position in the buffer */ + static uint16_t current = 0; + + /* '\0' terminates a contiguous block of characters to be printed! */ + if (c == '\0') + return; + + /* wait till buffer is non-full and other processors aren't writing to it */ + while (1) { + while (buffer[current] != 0) + ; + if (spinlock_trylock(&simics_buf_lock)) + break; + } + + buffer[current] = c; + + current = (current + 1) % BUFSIZE; + membar(); + + spinlock_unlock(&simics_buf_lock); +} + +/** Initializes the Simics output. + * + * Passes the address of the buffer to the Simics' Python script and + * redirects kernel output to the Simics CLI. + */ +void simics_output_init(void) +{ + /* all buffer positions are free at the beginning */ + uint16_t i; + for (i = 0; i < BUFSIZE; i++) { + buffer[i] = '\0'; + } + + /* + * pass the address of the buffer to the Simics' Python script + * - write it to the %g3 register + * - write the magic value to the %g2 register + * (so that the script knows that the value in %g3 is valid) + * - loop until the value is read + * (the script notifies us by setting %g2 to 0) + */ + asm volatile ( + "or %0, 0, %%g3\n" + + "set 0x18273645, %%g2\n" + + "0: cmp %%g2, 0\n" + "bnz 0b\n" + "nop" + :: "r" (buffer) + ); + + /* redirect kernel output */ + chardev_initialize("simics_output", &simics_stdout, &simics_stdout_ops); + stdout = &simics_stdout; +} + +/** @} + */