You can subscribe to this list here.
2004 |
Jan
|
Feb
(24) |
Mar
(48) |
Apr
(16) |
May
(10) |
Jun
(12) |
Jul
|
Aug
(9) |
Sep
(3) |
Oct
|
Nov
|
Dec
(14) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(5) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2006 |
Jan
(32) |
Feb
(18) |
Mar
(17) |
Apr
(19) |
May
(6) |
Jun
(7) |
Jul
|
Aug
|
Sep
(6) |
Oct
(5) |
Nov
|
Dec
|
2008 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Stephen M. W. <bre...@us...> - 2008-03-04 20:05:39
|
Update of /cvsroot/trion/htdocs In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv12372 Modified Files: community.php Log Message: Removed wiki and forum links die to spammage. Index: community.php =================================================================== RCS file: /cvsroot/trion/htdocs/community.php,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** community.php 7 Sep 2006 20:29:55 -0000 1.1 --- community.php 4 Mar 2008 20:05:42 -0000 1.2 *************** *** 10,15 **** <ul> <li><a href="http://sourceforge.net/projects/trion/">SourceForge</a></li> ! <li><a href="phpBB2">Forum</a></li> ! <li><a href="wiki">Wiki</a></li> <li>IRC: irc.freenode.net #trion</li> </ul> --- 10,15 ---- <ul> <li><a href="http://sourceforge.net/projects/trion/">SourceForge</a></li> ! <!-- <li><a href="phpBB2">Forum</a></li> --> ! <!-- <li><a href="wiki">Wiki</a></li> --> <li>IRC: irc.freenode.net #trion</li> </ul> |
From: Daniel R. <co...@us...> - 2006-10-19 17:50:51
|
Update of /cvsroot/trion/trion v0.2/object In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv12544 Modified Files: list.cpp list.hpp std_types.hpp tree.cpp tree.hpp Added Files: allocator.cpp allocator.hpp physical_memory.cpp physical_memory.hpp virtual_memory.cpp virtual_memory.hpp Removed Files: pager.cpp pager.hpp phys_allocator.cpp phys_allocator.hpp Log Message: no message --- pager.hpp DELETED --- --- NEW FILE: virtual_memory.hpp --- // ----------------------------------------------------------------------- // virtual_memory.hpp - 4kb virtual memory allocator // // Author(s) : // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. 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. // 3. Neither the name of the Trion Development Group nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT // OWNER OR CONTRIBUTORS 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. // ----------------------------------------------------------------------- #ifndef __OBJECTS__VIRTUAL_ALLOCATOR__ #define __OBJECTS__VIRTUAL_ALLOCATOR__ #include <std_types.hpp> struct memory_node { u32b address, length; memory_node* next, *prev; }; class iterator { private: memory_node* node; public: iterator(memory_node* initial_node); bool operator==(iterator compare); bool operator!=(iterator compare); iterator& operator++(); iterator operator++(int); iterator& operator--(); iterator operator--(int); memory_node* operator->(); memory_node* operator*(); }; class memory_pool { private: memory_node* node_list; public: memory_pool(u32b initial_area, u16b number_pages = 1); memory_node* AllocateNode(); memory_node* DelocateNode(memory_node* node); }; class memory_list { private: memory_node* node_list; memory_pool pool; public: memory_list(u32b virtual_base); iterator CreateNode(u32b base, u32b size = 0); iterator DeleteNode(iterator it); iterator Search(u32b minimum_size); }; class virtual_memory { private: memory_list list; public: virtual_memory(u32b initial_area); u32b AllocatePage(u16b number_pages = 1); void DelocatePage(u32b base_address, u16b number_pages = 1); }; virtual_memory& InitializeVirtAllocator(u32b initial_area); virtual_memory& virt_allocator(); #endif --- NEW FILE: virtual_memory.cpp --- // ----------------------------------------------------------------------- // virtual_memory.cpp - 4kb virtual memory allocator // // Author(s) : // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. 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. // 3. Neither the name of the Trion Development Group nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT // OWNER OR CONTRIBUTORS 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. // ----------------------------------------------------------------------- #include <virtual_memory.hpp> #include <physical_memory.hpp> #include <std_types.hpp> #include <cpu_node.hpp> #include <console.hpp> #include <mmu.hpp> iterator::iterator(memory_node* initial_node) : node(initial_node) {} bool iterator::operator==(iterator compare) { return (this->node == compare.node) ? true : false; } bool iterator::operator!=(iterator compare) { return (this->node != compare.node) ? true : false; } iterator& iterator::operator++() { node = node->next; return *this; } iterator iterator::operator++(int) { return iterator(node->next); } iterator& iterator::operator--() { node = node->prev; return *this; } iterator iterator::operator--(int) { return iterator(node->prev); } memory_node* iterator::operator->() { return node; } memory_node* iterator::operator*() { return node; } memory_pool::memory_pool(u32b initial_area, u16b number_pages) { // Use the first n pages to create a pool of empty nodes for(u16b i=0; i < number_pages; i++) { u32b phys_address = phys_allocator().AllocatePage(); u32b virt_address = initial_area + 4096*i; Node(Memory)(virt_address) = map_item(phys_address); } // Append all empty nodes to our internal node list node_list = reinterpret_cast<memory_node*>(initial_area); node_list->prev = node_list->next = 0; for(u16b i=1; i < (number_pages*4096)/(sizeof(memory_node)); i++) { memory_node* node = reinterpret_cast<memory_node*>(initial_area); node[i].next = node_list; node[i].prev = 0; node_list = node_list->prev = node+i; } } memory_node* memory_pool::AllocateNode() { Assert(node_list!= 0, "Virtual memory manager ran out of list nodes"); memory_node* node = node_list; node_list = node->next; if(node_list != 0) node_list->prev = 0; return node; } memory_node* memory_pool::DelocateNode(memory_node* node) { node->next = node_list; node->prev = 0; return node_list = node_list->prev = node; } memory_list::memory_list(u32b virtual_base) : pool(virtual_base), node_list(0) { // Initialize the list by inserting a node for the 512 MiB of kernel-space memory_node* node = node_list = pool.AllocateNode(); node->prev = node->next = 0; node->address = virtual_base + 4096; node->length = 0x1FFFF000; } iterator memory_list::CreateNode(u32b base, u32b size) { // Insert a node into the sorted list (without further checks) iterator current(node_list); while(base > current->address) current++; memory_node* node = pool.AllocateNode(); iterator next_node = current; iterator prev_node = current--; if(prev_node != 0 && next_node != 0) { prev_node->next = node; next_node->prev = node; node->prev = *prev_node; node->next = *next_node; } else { next_node->prev = node; node->next = *next_node; node->prev = 0; node_list = node; } return iterator(node); } iterator memory_list::DeleteNode(iterator it) { iterator next_node = it++; iterator prev_node = it--; if(prev_node != 0 && next_node != 0) { prev_node->next = it->next; next_node->prev = it->prev; } else { node_list = *next_node; next_node->prev = 0; } pool.DelocateNode(*it); return next_node; } iterator memory_list::Search(u32b minimum_size) { iterator current(node_list); while(current != 0 && minimum_size > current->length) current++; return current; } virtual_memory::virtual_memory(u32b initial_area) : list(initial_area) {} u32b virtual_memory::AllocatePage(u16b number_pages) { u32b minimum_size = 4096*number_pages; iterator node = list.Search(minimum_size); Assert(node != 0, "Virtual memory manager couldn't allocate page"); u32b address = node->address; node->address += minimum_size; node->length -= minimum_size; if(node->length == 0) list.DeleteNode(node); return address; } void virtual_memory::DelocatePage(u32b base_address, u16b number_pages) { iterator current = list.CreateNode(base_address, 4096*number_pages); iterator next = current++; iterator prev = current--; if(prev != 0 && current->address == prev->address + prev->length) { current->address = prev->address; current->length += prev->length; list.DeleteNode(prev); } if(next != 0 && current->address + current->length == next->address) { current->length += next->length; list.DeleteNode(next); } } u08b virtual_memory_reserved[sizeof(virtual_memory)]; virtual_memory& InitializeVirtAllocator(u32b initial_area) { new (virtual_memory_reserved) virtual_memory(initial_area); return reinterpret_cast<virtual_memory&>(virtual_memory_reserved); } virtual_memory& virt_allocator() { return reinterpret_cast<virtual_memory&>(virtual_memory_reserved); } --- NEW FILE: physical_memory.cpp --- // ----------------------------------------------------------------------- // physical_memory.cpp - 4kb physical memory allocator // // Author(s) : // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. 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. // 3. Neither the name of the Trion Development Group nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT // OWNER OR CONTRIBUTORS 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. // ----------------------------------------------------------------------- #include <physical_memory.hpp> #include <console.hpp> physical_memory::physical_memory(u32b heap_begin) { // Initialize the stack with sequential addresses for(u08b i=0; i<16; i++) stack[i] = heap_begin + 4096*i; stack_pointer = 0, stack_underflow = 16; // first and last+1 element } u32b physical_memory::AllocatePage() { Assert(stack_pointer != stack_underflow, "Physical allocator ran out of memory"); return stack[stack_pointer++]; } void physical_memory::DelocatePage(u32b base_address) { stack[--stack_pointer] = base_address; } u08b physical_memory_reserved[sizeof(physical_memory)]; physical_memory& phys_allocator() { return reinterpret_cast<physical_memory&>(physical_memory_reserved); } physical_memory& InitializePhysAllocator(u32b initial_area) { new (physical_memory_reserved) physical_memory(initial_area); return reinterpret_cast<physical_memory&>(physical_memory_reserved); } --- NEW FILE: physical_memory.hpp --- // ----------------------------------------------------------------------- // physical_memory.hpp - 4kb physical memory allocator // // Author(s) : // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. 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. // 3. Neither the name of the Trion Development Group nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT // OWNER OR CONTRIBUTORS 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. // ----------------------------------------------------------------------- #ifndef __OBJECTS__PHYSICAL_ALLOCATOR__ #define __OBJECTS__PHYSICAL_ALLOCATOR__ #include <std_types.hpp> class physical_memory { private: u16b stack_pointer, stack_underflow; u32b stack[16]; public: physical_memory(u32b initial_area); u32b AllocatePage(); void DelocatePage(u32b base_address); }; physical_memory& InitializePhysAllocator(u32b initial_area); physical_memory& phys_allocator(); #endif Index: tree.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/object/tree.cpp,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** tree.cpp 7 Jan 2006 16:39:38 -0000 1.1.1.1 --- tree.cpp 19 Oct 2006 17:50:47 -0000 1.2 *************** *** 9,13 **** // ----------------------------------------------------------------------- ! // Copyright (C) 2003, Trion Development Group Members // All rights reserved. // --- 9,13 ---- // ----------------------------------------------------------------------- ! // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // Index: list.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/object/list.cpp,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** list.cpp 7 Jan 2006 16:39:36 -0000 1.1.1.1 --- list.cpp 19 Oct 2006 17:50:47 -0000 1.2 *************** *** 9,13 **** // ----------------------------------------------------------------------- ! // Copyright (C) 2003, Trion Development Group Members // All rights reserved. // --- 9,13 ---- // ----------------------------------------------------------------------- ! // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // Index: std_types.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/object/std_types.hpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** std_types.hpp 24 Jun 2006 15:01:46 -0000 1.3 --- std_types.hpp 19 Oct 2006 17:50:47 -0000 1.4 *************** *** 78,81 **** --- 78,96 ---- }; + /** Allow a 64bit wide bitfield to be accessed like an ordinary long integer */ + template<class T> struct bf64 + { + private: + union { u64b integer; T bitfield; }; + + public: + bf64(u64b value) : integer(value) {}; // Allows initialization with an integer + + operator u64b() { return integer; } // Default conversation to an integer + operator T&() { return bitfield; } // Conversation to the bitfield type + + T* operator->() { return &bitfield; } // Access to the members of the bitfield + }; + /** Some very basic operations to initialize and copy memory ranges */ template<class T> void memset(T* begin, T* end, const T& value) Index: list.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/object/list.hpp,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** list.hpp 7 Jan 2006 16:39:37 -0000 1.1.1.1 --- list.hpp 19 Oct 2006 17:50:47 -0000 1.2 *************** *** 9,13 **** // ----------------------------------------------------------------------- ! // Copyright (C) 2003, Trion Development Group Members // All rights reserved. // --- 9,13 ---- // ----------------------------------------------------------------------- ! // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // *************** *** 38,74 **** // ----------------------------------------------------------------------- ! #ifndef __OBJECT_CLASSES__LIST__ ! #define __OBJECT_CLASSES__LIST__ ! #include <pager.hpp> ! template<typename TYPE> struct Listnode { ! Listnode* prev, *next; ! ! TYPE data; }; ! template<typename TYPE> class list { private: ! void* object; ! void* first_used, *last_used; ! int number_used; ! iterator GetPrevNode(iterator it); ! iterator GetNextNode(iterator it); public: ! list(int max_nodes, void* object = 0); ~list(); ! bool InsertNode(iterator it); ! bool RemoveNode(iterator it); ! TYPE* GetNode(iterator it); ! iterator Find(bool (*function_pointer) (TYPE*)); }; --- 38,107 ---- // ----------------------------------------------------------------------- ! #ifndef __OBJECTS__LIST__ ! #define __OBJECTS__LIST__ ! #include <std_types.hpp> ! template<class TYPE> struct list_node { ! list_node* next, *prev; ! TYPE node_data; }; ! template<class TYPE> class iterator { + typedef list_node<TYPE> node; + private: ! node* element_pointer; ! public: ! iterator(node* element); ! iterator(); ! bool operator==(iterator it); ! bool operator!=(iterator it); ! ! TYPE& operator* (); ! TYPE* operator->(); ! ! iterator& operator++(); ! iterator operator++(int t); ! ! iterator& operator--(); ! iterator operator--(int t); ! }; ! ! template<class TYPE, class ALLOC = allocator<TYPE> > ! class list ! { ! typedef list_node<TYPE> node; ! ! private: ! node* first_element, *last_element; ! u32b number_elements; public: ! list(); ~list(); ! iterator begin(); ! iterator end(); ! TYPE& front(); ! TYPE& back(); ! void push_front(TYPE& node); ! void push_back (TYPE& node); ! ! void pop_front(); ! void pop_back(); ! ! iterator insert(iterator position, TYPE& value); ! ! iterator erase(iterator position); ! iterator erase(iterator first, iterator last); ! ! u32b size(); }; Index: tree.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/object/tree.hpp,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** tree.hpp 7 Jan 2006 16:39:38 -0000 1.1.1.1 --- tree.hpp 19 Oct 2006 17:50:47 -0000 1.2 *************** *** 9,13 **** // ----------------------------------------------------------------------- ! // Copyright (C) 2003, Trion Development Group Members // All rights reserved. // --- 9,13 ---- // ----------------------------------------------------------------------- ! // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // *************** *** 38,43 **** // ----------------------------------------------------------------------- ! #ifndef __OBJECT_CLASSES__TREE__ ! #define __OBJECT_CLASSES__TREE__ #include <pager.hpp> --- 38,43 ---- // ----------------------------------------------------------------------- ! #ifndef __OBJECTS__TREE__ ! #define __OBJECTS__TREE__ #include <pager.hpp> --- phys_allocator.cpp DELETED --- --- phys_allocator.hpp DELETED --- --- NEW FILE: allocator.cpp --- // ----------------------------------------------------------------------- // allocator.hpp - 4kb allocator for kernel objects // // Author(s) : // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. 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. // 3. Neither the name of the Trion Development Group nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT // OWNER OR CONTRIBUTORS 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. // ----------------------------------------------------------------------- #include <allocator.hpp> --- NEW FILE: allocator.hpp --- // ----------------------------------------------------------------------- // allocator.hpp - 4kb allocator for kernel objects // // Author(s) : // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. 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. // 3. Neither the name of the Trion Development Group nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT // OWNER OR CONTRIBUTORS 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. // ----------------------------------------------------------------------- #ifndef __OBJECTS__ALLOCATOR__ #define __OBJECTS__ALLOCATOR__ #include <physical_memory.hpp> #include <virtual_memory.hpp> #include <std_types.hpp> struct object_header { u32b available_slots; u32b block_address[0x3fe]; object_header* next; }; template<class TYPE> struct allocator_node { allocator_node* next, *prev; TYPE node_data; }; template<class TYPE> class allocator { typedef allocator_node<TYPE> node; private: static object_header* header; static node* available_nodes; static u32b number_available; bool AppendHeaderBlock(); bool RemoveHeaderBlock(); bool AppendNodeBlock(); bool RemoveNodeBlock(); public: allocator(); ~allocator(); TYPE* Allocate(u32b number = 1); void Delocate(TYPE* object, u32b number = 1); }; #endif --- pager.cpp DELETED --- |
From: Daniel R. <co...@us...> - 2006-10-19 17:49:29
|
Update of /cvsroot/trion/trion v0.2/loader In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv12036 Added Files: multiboot.cpp multiboot.hpp Log Message: no message --- NEW FILE: multiboot.hpp --- // ----------------------------------------------------------------------- // multiboot.hpp - Parser class for the multiboot-table created by GRUB // // Author(s) : // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. 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. // 3. Neither the name of the Trion Development Group nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT // OWNER OR CONTRIBUTORS 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. // ----------------------------------------------------------------------- #ifndef __LOADER__MULTIBOOT_HPP__ #define __LOADER__MULTIBOOT_HPP__ #include <std_types.hpp> struct multiboot_info { struct present_flags { bool memory_amount : 1; bool boot_device : 1; bool command_line : 1; bool module_table : 1; bool elf_headers : 1; bool memory_table : 1; bool drive_table : 1; bool config_table : 1; bool loader_name : 1; bool apm_table : 1; bool vbe_info : 1; u32b : 21; } flags; u32b memory_lower; u32b memory_upper; u32b boot_device; char* command_line; u32b number_modules; void* modules_address; struct elf { u32b number_entries; u32b size_entry; void* section_table; void* string_table; }; u32b memory_map_length; void* memory_map_address; u32b drives_length; void* drives_address; void* config_table; char* loader_name; void* apm_table; struct vbe { void* control_info; void* mode_info; u32b mode_number; u32b interface_segment; u32b interface_offset; u32b interface_length; }; }; struct module_entry { u32b module_start; u32b module_end; char* string; u32b reserved; }; struct memory_entry { u32b size; u32b base_address_low; u32b base_address_high; u32b length_low; u32b length_high; u32b type; }; struct range { private: u32b base_address; u32b length; public: range(u32b base, u32b size) : base_address(base), length(size){} u32b BaseAddress() { return base_address; } u32b Length() { return length; } }; class multiboot_detect { private: multiboot_info* table; vRange* table_window; // Both functions return physical addresses u32b GetFirstModule(); u32b GetFirstMemory(); u32b GetNextMemory(memory_entry* current); // Returns an offset public: multiboot_detect(u32b magic, u32b multiboot_table); // Memory Interface u32b GetTotalAmountMemory(); range GetMemoryChunk(u32 minimum_size); // Module Interface u16b GetNumberModules(); range GetModuleAddress(u16b number); }; multiboot_detect& InitializeMultiboot(u32b magic, u32b table); multiboot_detect& multiboot(); #endif --- NEW FILE: multiboot.cpp --- // ----------------------------------------------------------------------- // multiboot.cpp - Parser class for the multiboot-table created by GRUB // // Author(s) : // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. 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. // 3. Neither the name of the Trion Development Group nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT // OWNER OR CONTRIBUTORS 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. // ----------------------------------------------------------------------- #include <multiboot.hpp> #include <heap_manager.hpp> #include <console.hpp> |
From: Daniel R. <co...@us...> - 2006-10-19 17:48:56
|
Update of /cvsroot/trion/trion v0.2/loader In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv11615 Modified Files: console.cpp console.hpp entry.asm heap_manager.cpp heap_manager.hpp main.cpp Log Message: no message Index: main.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/main.cpp,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** main.cpp 24 Jun 2006 15:01:32 -0000 1.19 --- main.cpp 19 Oct 2006 17:48:52 -0000 1.20 *************** *** 41,96 **** #include <console.hpp> #include <heap_manager.hpp> ! #include <mp_detect.hpp> ! #include <hal_object.hpp> #include <mmu.hpp> - #include <idt.hpp> - #include <exception.hpp> - #include <apic_local.hpp> - #include <timer.hpp> - #include <irq.hpp> - #include <ipi.hpp> - #include <cpu_info.hpp> ! #include <gdt.hpp> ! #include <ports.hpp> ! #include <systemcall.hpp> ! #include <task_context.hpp> ! ! extern "C" u32b user_main() { ! asm("mov %ss, %eax\n" "mov %eax, %ds\n" "mov %eax, %es\n" ! "mov %eax, %fs\n" "mov %eax, %gs\n"); ! ! // Print a red 'A' in the upper-left corner of the screen ! char* vidmem = reinterpret_cast<char*>(0x2000); ! vidmem[(80+78)*2 + 0] = 'A'; ! vidmem[(80+78)*2 + 1] = 4; ! // Demonstrate the systemcall-mechanism ! asm("mov $(syscall_return - 0xE0000000), %edx\n" ! "push %ebp\n" ! "mov %esp, %ecx\n" ! "sysenter\n" ! "syscall_return: pop %ebp"); ! vidmem[(160+78)*2 + 0] = 'B'; ! vidmem[(160+78)*2 + 1] = 4; ! // Try accessing some I/O ports by moving the x86 hardware cursor ! asm("mov $0x0f, %al\n" "mov $0x3d4, %dx\n" "out %al, %dx\n"); ! asm("mov $0x9e, %al\n" "mov $0x3d5, %dx\n" "out %al, %dx\n"); ! asm("mov $0x0e, %al\n" "mov $0x3d4, %dx\n" "out %al, %dx\n"); ! asm("mov $0x00, %al\n" "mov $0x3d5, %dx\n" "out %al, %dx\n"); ! while(true); // Waiting for IRQs } ! extern "C" int main(u32b image_size, u32b processor, u32b magic, void* grub) ! { ! static u32b number_processors; if(processor == 0) --- 41,118 ---- #include <console.hpp> + #include <virtual_memory.hpp> + #include <physical_memory.hpp> + #include <heap_manager.hpp> ! // #include <mp_detect.hpp> ! #include <cpu_node.hpp> #include <mmu.hpp> ! extern "C" int main(u32b processor, u32b phys_addr, u32b virt_addr, u32b magic, u32b grub) { ! if(processor == 0) ! { ! // Enabling the console early allows us to print debug info during the start-up phase ! InitializeConsole(virt_addr - 4096); ! cout().ClearScreen(); ! cout() << "Welcome to Trion v0.2" << endl; ! CreateBspNode(); // Spawn local classes for the boot-strap processor ! // Initialize global memory management ! InitializePhysAllocator(phys_addr); ! InitializeVirtAllocator(virt_addr); ! InitializeHeapManager(); ! // Activate hyperthreading and boot all application processors ! } } ! /* ! node().memory(0x1000) = map(0x1000).Global().PAT(7); ! node().memory(0x1000) = map(0x1000) | map::Global() | map::PAT(7); ! node().memory(0x1000) = Physical(0x10000) | Global() | PAT(7); ! ! bool global = node().memory(0x1000).Global(); ! bool global = Global(node().memory(0x1000)); ! ! node(memory)(0x1000); ! */ ! ! // bool global = node(memory)[0x1000].Global(); ! // node(memory)[0x1000] = map(0x1000) | map::Global() | PAT(7); ! ! /* ! static u32b number_processors = 0; ! ! if(processor == 0) ! { ! // Create the global memory manager objects ! CreateVirtualAllocator(0xE0000000 + image_size + 0x2000); ! CreatePhysicalAllocator(0x00100000 + image_size + 0x5000); ! ! CreateHeapManager(0xE0000000 + image_size + 0x1000); ! ! // Enable the console and print a welcome message ! CreateConsole(); ! ! cout().ClearScreen(); ! cout() << "Welcome to Trion v0.2" << endl; ! ! // Spawn a set of local classes for this processor ! ! // Activate hyperthreading and boot all application processors ! } ! else ! { ! // ap_flag |= 2; // Indicates that the hal is fully initialized, next AP may get started ! ! while(true) asm("hlt"); ! } ! } if(processor == 0) *************** *** 191,192 **** --- 213,215 ---- } } + */ Index: console.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/console.cpp,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** console.cpp 24 Jun 2006 15:01:32 -0000 1.10 --- console.cpp 19 Oct 2006 17:48:52 -0000 1.11 *************** *** 39,113 **** #include <console.hpp> - #include <hal_object.hpp> - char console::itoa_buffer[] = {'0', 'x', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; const char endl = '\n'; ! console::console() { ! window = heap().CreateObject<vRange>(0xB8000); ! x86_console = static_cast<u08b*>(window->GetVirtualBase()); ! x_offset = y_offset = 0; } ! void console::Clear() { ! EnterMutex(); ! memset(x86_console, &x86_console[80*50], u08b(0)); ! x_offset = y_offset = 0; ! ExitMutex(); } console& console::operator<<(const char* string) { ! EnterMutex(); ! u16b index = 0; ! while(true) { ! while(y_offset < 25) { ! while(x_offset < 80) { ! if(string[index] != 0) // Print text until the zero-termination is reached ! { ! if(string[index] == '\n') ! { ! x_offset=80; ! } ! else ! { ! x86_console[y_offset*160+x_offset*2+0] = string[index]; ! x86_console[y_offset*160+x_offset*2+1] = 9; ! x_offset++; ! } ! index++; ! } ! else ! { ! ExitMutex(); ! return *this; ! } } ! ! // End of line - next line ! x_offset = 0; ! y_offset++; } - - // End of the screen - move up one line - u16b source = 160; - u16b dest = 0; - - while(dest < 160*24) x86_console[dest++] = x86_console[source++]; - while(dest < 160*25) x86_console[dest++] = 0; - - x_offset = 0; - y_offset--; } - - ExitMutex(); return *this; } --- 39,88 ---- #include <console.hpp> const char endl = '\n'; ! console::console(u32b video_memory) { ! x86_console = reinterpret_cast<u16b*>(video_memory); ! ! SetPosition(0,0); // Upper left corner ! SetColour(0x900); // Dark Blue } ! void console::SetPosition(u08b x_position, u08b y_position) { ! if(x_position < 80 && y_position < 25) ! position = y_position*80 + x_position; ! } ! void console::ScrollScreen() ! { ! u16b* line00 = &x86_console[80*00], *line01 = &x86_console[80*01]; ! u16b* line24 = &x86_console[80*24], *line25 = &x86_console[80*25]; ! memcopy(line01, line25, line00); // Move up by a line ! memset (line24, line25, u16b(0)); // Clear the last line } console& console::operator<<(const char* string) { ! CriticalSection section(&mtx); ! for(u16b i=0; string[i] != 0; i++) { ! if(string[i] == '\n') { ! position = ((position + 79)/80)*80; ! } ! else ! { ! if(position == 2000) { ! SetPosition(0, 24); ! ScrollScreen(); } ! x86_console[position++] = u16b(string[i]) | colour; } } return *this; } *************** *** 115,132 **** console& console::operator<<(u32b number) { ! EnterMutex(); ! u08b base = 16; for(u08b index = sizeof(itoa_buffer)-3; index > 1; index--) { ! char digit = number%base; ! number = number/base; itoa_buffer[index] = (digit < 10) ? digit + '0' : digit - 10 + 'a'; } ! ExitMutex(); ! ! operator<<(itoa_buffer); ! return *this; } --- 90,103 ---- console& console::operator<<(u32b number) { ! char digit, itoa_buffer[12] = {'0', 'x', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; for(u08b index = sizeof(itoa_buffer)-3; index > 1; index--) { ! digit = number%16; ! number = number/16; itoa_buffer[index] = (digit < 10) ? digit + '0' : digit - 10 + 'a'; } ! return cout() << itoa_buffer; } *************** *** 134,145 **** { char dummy[] = { character , 0}; ! operator<<(dummy); ! return *this; } ! char console_reserved[sizeof(console)]; ! console& cout() { ! return (reinterpret_cast<console&>(console_reserved)); } --- 105,141 ---- { char dummy[] = { character , 0}; ! return cout() << dummy; } ! void console::SetColour(u16b screen_colour) ! { ! colour = screen_colour; ! } ! void console::ClearScreen() { ! CriticalSection section(&mtx); ! ! memset(x86_console, &x86_console[80*25], u16b(0)); ! position = 0; } + + void Assert(bool condition, const char* string) + { + if(!condition) + { + cout().SetColour(0xC00); + cout() << string; + + while(true); + } + } + + u08b console_reserved[sizeof(console)]; + console& cout() { return reinterpret_cast<console&>(console_reserved); } + + console& InitializeConsole(u32b video_memory) + { + new (console_reserved) console(video_memory); + return reinterpret_cast<console&>(console_reserved); + }; Index: console.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/console.hpp,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** console.hpp 24 Jun 2006 15:01:32 -0000 1.8 --- console.hpp 19 Oct 2006 17:48:52 -0000 1.9 *************** *** 42,69 **** #include <std_types.hpp> - #include <heap_manager.hpp> #include <mutex.hpp> ! class console : private mutex { private: ! u08b x_offset, y_offset; ! u08b* x86_console; ! ! vRange* window; ! static char itoa_buffer[12]; public: ! console(); ! ! void Clear(); console& operator<<(const char* string); console& operator<<(char character); ! console& operator<<(u32b number); }; ! extern char console_reserved[]; console& cout(); --- 42,70 ---- #include <std_types.hpp> #include <mutex.hpp> ! void Assert(bool condition, const char* string); ! ! class console { private: ! u16b* x86_console, position, colour; ! mutex mtx; ! void SetPosition(u08b x_position, u08b y_position); ! void ScrollScreen(); public: ! console(u32b video_memory); console& operator<<(const char* string); console& operator<<(char character); ! console& operator<<(u32b number); ! ! void SetColour(u16b screen_colour); ! void ClearScreen(); }; ! console& InitializeConsole(u32b video_memory); console& cout(); Index: heap_manager.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/heap_manager.hpp,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** heap_manager.hpp 24 Jun 2006 15:01:32 -0000 1.9 --- heap_manager.hpp 19 Oct 2006 17:48:52 -0000 1.10 *************** *** 42,70 **** #include <std_types.hpp> - #include <hal_object.hpp> - - extern "C" u32b heap_address; - extern "C" u32b sizeof_hobject_cpp; - - class memory_stack - { - private: - u32b stack[32]; - u16b stack_pointer, stack_underflow; - - public: - memory_stack(u32b heap_begin); - - u32b AllocatePage(); - void DelocatePage(u32b base_address); - }; class vRange { private: ! u32b page_base, page_size; public: ! vRange(u32b physical_base); ~vRange(); --- 42,53 ---- #include <std_types.hpp> class vRange { private: ! u32b range_base, range_size; public: ! vRange(u32b physical_base, u32b number_pages = 1); ~vRange(); *************** *** 77,107 **** private: u32b memory_base, memory_left; - - u32b GetStackBase(); void RefreshWindow(); public: ! heap_manager(u32b initial_heap); void* AllocateMemory(u32b size_bytes); void AllocateMpStack(); - - template<class T, class P> T* heap_manager::CreateObject(P parameter) - { return reinterpret_cast<T*>(new (AllocateMemory(sizeof(T))) T(parameter)); } - - template<class T> T* heap_manager::CreateObject() - { return reinterpret_cast<T*>(new (AllocateMemory(sizeof(T))) T()); } - - hal_object* CreateHalObject(u08b processor); }; ! extern char heap_manager_reserved[]; heap_manager& heap(); ! extern char virt_allocator_reserved[]; ! extern char phys_allocator_reserved[]; ! memory_stack& virtual_allocator(); ! memory_stack& physical_allocator(); #endif --- 60,86 ---- private: u32b memory_base, memory_left; void RefreshWindow(); public: ! heap_manager(); void* AllocateMemory(u32b size_bytes); void AllocateMpStack(); }; ! heap_manager& InitializeHeapManager(); heap_manager& heap(); ! template<class T, class P> T& CreateObject(P parameter) ! { ! void* memory = heap().AllocateMemory(sizeof(T)); ! return *(new (memory) T(parameter)); ! } ! template<class T> T& CreateObject() ! { ! void* memory = heap().AllocateMemory(sizeof(T)); ! return *(new (memory) T()); ! } #endif Index: heap_manager.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/heap_manager.cpp,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** heap_manager.cpp 24 Jun 2006 15:01:32 -0000 1.12 --- heap_manager.cpp 19 Oct 2006 17:48:52 -0000 1.13 *************** *** 40,114 **** #include <heap_manager.hpp> ! #include <mmu.hpp> ! #include <console.hpp> ! memory_stack::memory_stack(u32b heap_begin) ! { ! // Initialize the stack with sequential addresses ! for(u08b i=0; i<32; i++) stack[i] = heap_begin + 4096*i; ! stack_pointer = 0; // first element ! stack_underflow = 32; // last + 1 ! } ! u32b memory_stack::AllocatePage() ! { ! if(stack_pointer == stack_underflow) ! { ! cout() << "Panic: Ran out of virtual memory"; ! while(true); ! } ! return stack[stack_pointer++]; ! } ! void memory_stack::DelocatePage(u32b base_address) { ! stack[--stack_pointer] = base_address; ! } ! vRange::vRange(u32b physical_base) ! { ! page_base = virtual_allocator().AllocatePage(); ! page_size = 4096; ! get_hal_object()(memory)(page_base) = memory_mapper::kernel_mode(physical_base); } vRange::~vRange() { ! get_hal_object()(memory)(page_base) -= map_item(0).Present(); ! virtual_allocator().DelocatePage(page_base); ! } ! ! void* vRange::GetVirtualBase() ! { ! return reinterpret_cast<void*>(page_base); ! } ! ! u32b vRange::GetLength() ! { ! return page_size; ! } ! heap_manager::heap_manager(u32b initial_heap) ! { ! memory_base = initial_heap; ! memory_left = 4096 - sizeof_hobject_cpp; } ! u32b heap_manager::GetStackBase() ! { ! u32b stack_base(0); ! asm("mov %%esp, %%eax" : "=a"(stack_base)); ! return (stack_base + 0xfff) &0xfffff000; ! } void heap_manager::RefreshWindow() { ! u32b phys_page = physical_allocator().AllocatePage(); ! u32b virt_page = virtual_allocator().AllocatePage(); ! get_hal_object()(memory)(virt_page) = memory_mapper::kernel_mode(phys_page); memory_base = virt_page; --- 40,84 ---- #include <heap_manager.hpp> ! #include <physical_memory.hpp> ! #include <virtual_memory.hpp> ! #include <console.hpp> ! #include <cpu_node.hpp> ! #include <mmu.hpp> ! extern "C" u32b stack_address; ! vRange::vRange(u32b physical_base, u32b number_pages) { ! range_base = virt_allocator().AllocatePage(number_pages); ! range_size = 4096*number_pages; ! Assert(range_base < 0xE0400000, "vRange passed the 4 MiB mark"); ! for(u32b i=0; i < number_pages; i++, physical_base += 4096, range_base += 4096) ! Node(Memory)(range_base) = map_item(physical_base); } vRange::~vRange() { ! virt_allocator().DelocatePage(range_base, range_size/4096); ! for(u32b i=0; i < range_size/4096; i++, range_base += 4096) ! Node(Memory)(range_base) = map_item(0); } ! void* vRange::GetVirtualBase() { return reinterpret_cast<void*>(range_base); } ! u32b vRange::GetLength() { return range_size; } ! heap_manager::heap_manager() : memory_base(0), memory_left(0) {} void heap_manager::RefreshWindow() { ! u32b phys_page = phys_allocator().AllocatePage(); ! u32b virt_page = virt_allocator().AllocatePage(); ! Assert(virt_page < 0xE0400000, "HeapManager passed 4 MiB mark"); ! Node(Memory)(virt_page) = map_item(phys_page); memory_base = virt_page; *************** *** 118,137 **** void* heap_manager::AllocateMemory(u32b size_bytes) { // Aligning the allocation size increases performance size_bytes = (size_bytes + 7) &0xFFFFFFF8; - if(size_bytes > 4096) - { - cout() << "Panic: heap-manager doesn't support allocations > 4096 byte"; - while(true); - } if(memory_left < size_bytes) RefreshWindow(); - void* tmp = reinterpret_cast<void*>(memory_base); - memory_base += size_bytes; memory_left -= size_bytes; ! return tmp; } --- 88,103 ---- void* heap_manager::AllocateMemory(u32b size_bytes) { + Assert(size_bytes <= 4096, "HeapManager can't allocate chunks greater than 4096 bytes"); + // Aligning the allocation size increases performance size_bytes = (size_bytes + 7) &0xFFFFFFF8; if(memory_left < size_bytes) RefreshWindow(); memory_base += size_bytes; memory_left -= size_bytes; ! ! return reinterpret_cast<void*>(memory_base - size_bytes); } *************** *** 139,175 **** { // Allocate a new page for the stack & map it in ! u32b phys_page = physical_allocator().AllocatePage(); ! u32b virt_page = virtual_allocator().AllocatePage(); ! ! get_hal_object()(memory)(virt_page) = memory_mapper::kernel_mode(phys_page); ! ! heap_address = virt_page + 4096; // Variable used by the loader ! } ! hal_object* heap_manager::CreateHalObject(u08b processor) ! { ! u32b hal_location = GetStackBase() - sizeof_hobject_cpp; ! new ((void*)hal_location) hal_object(processor, GetStackBase()); ! return reinterpret_cast<hal_object*>(hal_location); } char heap_manager_reserved[sizeof(heap_manager)]; ! char virt_allocator_reserved[sizeof(memory_stack)]; ! char phys_allocator_reserved[sizeof(memory_stack)]; ! ! heap_manager& heap() ! { ! return (reinterpret_cast<heap_manager&>(heap_manager_reserved)); ! } ! ! memory_stack& virtual_allocator() ! { ! return (reinterpret_cast<memory_stack&>(virt_allocator_reserved)); ! } ! memory_stack& physical_allocator() { ! return (reinterpret_cast<memory_stack&>(phys_allocator_reserved)); } --- 105,123 ---- { // Allocate a new page for the stack & map it in ! u32b phys_page = phys_allocator().AllocatePage(); ! u32b virt_page = virt_allocator().AllocatePage(); ! Node(Memory)(virt_page) = map_item(phys_page); ! stack_address = virt_page + 4096; // Use by the ASM code to setup the kernel stack } char heap_manager_reserved[sizeof(heap_manager)]; ! heap_manager& heap() { return reinterpret_cast<heap_manager&>(heap_manager_reserved); } ! heap_manager& InitializeHeapManager() { ! new (heap_manager_reserved) heap_manager(); ! return reinterpret_cast<heap_manager&>(heap_manager_reserved); } Index: entry.asm =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/entry.asm,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** entry.asm 24 Jun 2006 15:01:32 -0000 1.12 --- entry.asm 19 Oct 2006 17:48:52 -0000 1.13 *************** *** 40,53 **** extern main ; C++ entrypoint (loader/main.cpp) ! extern kernel_start ; Defined in the linker script extern kernel_end ; Always aligned to the next 4096 bytes boundary ! global heap_address ; Holds current heap address global cpu_id ; Number of the current processor ! global ap_code_start ; Helps relocating the entrypoint later ! global ap_code_end ; to boot the application cpus ! ! global sizeof_hobject_cpp section .text --- 40,51 ---- extern main ; C++ entrypoint (loader/main.cpp) ! extern kernel_start ; Symbols defined in the linker script extern kernel_end ; Always aligned to the next 4096 bytes boundary ! global stack_address ; Holds current stack address for APs global cpu_id ; Number of the current processor ! global ap_code_start ; Helps relocating the entrypoint later, ! global ap_code_end ; when booting the application processors section .text *************** *** 69,80 **** pepper equ 0xDFFF8000 ; As the kernel is linked to an address in high memory ! salt equ 0xDFF00000 ; all symboles have to be fixed until paging gets enabled: ! ; pepper = ap bootup (0x8000), salt = bsp code (0x100000) ! ; Addresses of the system tables relative to the current heap pointer ! stack_addr equ -(4096*1) ; The current cpu's stack gets created here ! hpagetable equ -(4096*2) ; High memory pagetable (0xE0000000) ! ipagetable equ -(4096*3) ; Idempotential pt needed for boot-up ! pagedirect equ -(4096*4) ; Initial pagedirectory ; Flags for the paging structures --- 67,77 ---- pepper equ 0xDFFF8000 ; As the kernel is linked to an address in high memory ! salt equ 0xDFF00000 ; all symboles must get fixed until paging is enabled: ! ; Addresses of the system tables relative to the end of the kernel image ! ipagetable equ 4096*3 - 0x10000 ; Idempotential page-table needed for boot-up ! hpagetable equ 4096*2 - 0x10000 ; High memory pagetable (0xE0000000) ! pagedirect equ 4096*1 - 0x10000 ; Initial pagedirectory ! boot_stack equ 4096*0 - 0x10000 ; The boot processor's stack ; Flags for the paging structures *************** *** 82,162 **** USER_MODE equ 7 ; ring3 | present | read&write - sizeof_hobject_asm equ 32*4 ; Assumed size (needed for memory reservation) - sizeof_hobject_cpp dd 32*4 - bsp_entrypoint: ! ; Set up a stack and reserve some memory for the hal-object ! mov esp, [heap_address - salt] ! add esp, stack_addr + 4096 ! sub esp, sizeof_hobject_asm ! ! ; Push the information passed to us by GRUB on the stack ! mov ecx, [cpu_id - salt] ! mov edx, kernel_end ! sub edx, kernel_start push ebx ; pointer to grub multiboot structure push eax ; magic - 0x2BADB002 - push ecx ; cpu# - push edx ; length of the kernel image - - ; Clear the region that will be used for the paging structures - xor eax, eax - mov edi, [heap_address - salt] - add edi, pagedirect - mov ecx, 1024*3 - rep stosd ! ; Map kernel to higher memory region ! mov edi, [heap_address - salt] ! add edi, pagedirect + 3584 ! mov eax, [heap_address - salt] ! add eax, hpagetable + SUPERVISOR ! stosd ! mov edi, [heap_address - salt] ! add edi, hpagetable ! mov eax, kernel_start - salt + SUPERVISOR ! mov edx, kernel_end sub edx, kernel_start - mov ecx, 12 - shr edx, cl ; eax = kernel_start | 3, edi = hpagetable - mov ecx, edx ; ecx = numbers of pages occupied by the nucleus stosd add eax, 4096 ! loop $-6 ! ; Append a page for the stack and another one for the heap at the end of the kernel ! mov eax, [heap_address - salt] ! add eax, stack_addr + SUPERVISOR stosd ! mov eax, [heap_address - salt] ! add eax, 0x00000000 + SUPERVISOR stosd ; Map the current code idempotentially ! mov edi, [heap_address - salt] ! add edi, pagedirect ! mov eax, [heap_address - salt] ! add eax, ipagetable + SUPERVISOR ! stosd ! mov edi, [heap_address - salt] ! add edi, ipagetable + 1024 ! mov eax, kernel_start - salt + SUPERVISOR ! stosd ! ; Allow the paging structs to be accessed though the last 4mb of the address-space ! mov edi, [heap_address - salt] ! add edi, pagedirect + 4092 ! mov eax, [heap_address - salt] ! add eax, pagedirect + SUPERVISOR ! stosd ; Enable paging ! mov eax, [heap_address - salt] ! add eax, pagedirect mov cr3, eax --- 79,134 ---- USER_MODE equ 7 ; ring3 | present | read&write bsp_entrypoint: ! ; Set up a stack and store the GRUB information on it ! mov eax, (kernel_end - salt) + boot_stack + 4096 ! mov esp, eax + push eax ; reserved memory for the node object pointer push ebx ; pointer to grub multiboot structure push eax ; magic - 0x2BADB002 ! ; Map kernel to higher memory region (3.5 GiB and above) ! mov ebx, (kernel_end - salt) + pagedirect + 3584 ! mov eax, (kernel_end - salt) + hpagetable + SUPERVISOR ! mov [ebx], eax ! mov edi, (kernel_end - salt) + hpagetable ! mov eax, (kernel_start - salt) + SUPERVISOR ! mov edx, kernel_end - 0x10000 sub edx, kernel_start + map_kernel: stosd + add eax, 4096 ! sub edx, 4096 ! test edx, edx ! jne map_kernel ! ! ; Append a page for the stack ! mov eax, (kernel_end - salt) + boot_stack + SUPERVISOR stosd ! ; Reserve another page for the console ! mov eax, 0xB8000 + SUPERVISOR stosd ; Map the current code idempotentially ! mov ebx, (kernel_end - salt) + pagedirect ! mov eax, (kernel_end - salt) + ipagetable + SUPERVISOR ! mov [ebx], eax ! mov ebx, (kernel_end - salt) + ipagetable + 1024 ! mov eax, (kernel_start - salt) + SUPERVISOR ! mov [ebx], eax ! ; Allow the paging structs to be accessed though the last 4 MiB of the address-space ! mov ebx, (kernel_end - salt) + pagedirect + 4092 ! mov eax, (kernel_end - salt) + pagedirect + SUPERVISOR ! mov [ebx], eax ; Enable paging ! mov eax, (kernel_end - salt) + pagedirect mov cr3, eax *************** *** 179,189 **** bsp_paging: ; Prepare the stack for virtual addressing ! mov eax, [heap_address] ! add eax, salt - 12288 mov ebp, eax ! sub eax, 16 + sizeof_hobject_asm mov esp, eax ! inc dword [cpu_id] call main ; Call the C++ entry point --- 151,164 ---- bsp_paging: ; Prepare the stack for virtual addressing ! mov eax, kernel_end + boot_stack + 4096 - 4 mov ebp, eax ! sub eax, 8 mov esp, eax ! push dword kernel_end - 0x10000 + 8192 ! push dword kernel_end - 0x10000 - salt + 12288 ! ! push dword [cpu_id] ! inc dword [cpu_id] call main ; Call the C++ entry point *************** *** 201,205 **** mov ds, ax ! lgdt [ap_gdt_selector - ap_code_start] ; Auto-relocatable since cs=ds, and AP's start at EIP=0 mov eax, cr0 --- 176,180 ---- mov ds, ax ! lgdt [ap_gdt_selector - ap_code_start] ; Auto-relocatable as CS=DS and APs start at IP=0 mov eax, cr0 *************** *** 217,222 **** ap_gdt_selector: ! dw (gdt_end - gdt_start) - 1 ! dd gdt_start - salt ap_code_end: --- 192,197 ---- ap_gdt_selector: ! dw (gdt_end - gdt_start) - 1 ! dd gdt_start - salt ap_code_end: *************** *** 225,229 **** bits 32 ap_pmode: ! mov eax, kernel_end - salt mov cr3, eax --- 200,204 ---- bits 32 ap_pmode: ! mov eax, (kernel_end - salt) + pagedirect mov cr3, eax *************** *** 238,257 **** ap_paging: ; Prepare the stack for virtual addressing ! mov eax, [heap_address] mov esp, eax - sub eax, sizeof_hobject_asm mov ebp, eax ! xor eax, eax ! mov ebx, [cpu_id] ! mov ecx, kernel_end ! sub ecx, kernel_start ! inc dword [cpu_id] ! push eax ; pointer to grub multiboot structure = 0 ! push eax ; magic = 0 ! push ebx ; cpu# ! push ecx ; length of the kernel image call main ; Call the C++ entry point --- 213,226 ---- ap_paging: ; Prepare the stack for virtual addressing ! mov eax, [stack_address] ! sub eax, 4 mov esp, eax mov ebp, eax ! mov eax, [cpu_id] inc dword [cpu_id] ! sub esp, 16 ; skip 4 parameters ! push eax ; cpu number call main ; Call the C++ entry point *************** *** 262,267 **** section .data ! heap_address dd (kernel_end - salt) + 4096*4 ; Holds address of the stack-end, initially ! cpu_id dd 0x0000000 ; kernel_end + sizeof(paging_structures + stack) gdt_selector: --- 231,236 ---- section .data ! stack_address dd 0 ; Holds address of AP's stack area (initialized by C++ kernel) ! cpu_id dd 0 gdt_selector: |
From: Daniel R. <co...@us...> - 2006-10-19 17:48:40
|
Update of /cvsroot/trion/trion v0.2/hal In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv11597 Modified Files: mmu.cpp mmu.hpp mutex.cpp mutex.hpp Log Message: no message Index: mmu.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/mmu.cpp,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** mmu.cpp 24 Jun 2006 15:00:02 -0000 1.7 --- mmu.cpp 19 Oct 2006 17:48:34 -0000 1.8 *************** *** 40,59 **** #include <mmu.hpp> ! map_item::map_item(u32b init): entry(init), zero_tables(true) {} ! map_item::map_item(bf32<page_structure> init) : entry(init) {} ! ! map_item& map_item::Physical(u32b address) { ! entry->physical = address >> 12; ! return *this; } ! map_item& map_item::Write() { entry->read_write = true; return *this; } ! map_item& map_item::UserMode() { entry->user_mode = true; return *this; } ! map_item& map_item::Pages4MB() { entry->PAT2 = true; return *this; } ! map_item& map_item::Global() { entry->global = true; return *this; } ! map_item& map_item::Present() { entry->present = true; return *this; } ! map_item& map_item::PAT(u08b number) { entry->PAT0 = number &0x01; --- 40,62 ---- #include <mmu.hpp> ! map_item::map_item(u32b physical) : entry(0) { ! if(physical != 0) ! { ! entry->physical = physical >> 12; ! entry->present = entry->read_write = true; ! } } ! u32b map_item::Physical() { return entry->physical << 12; } ! u08b map_item::Caching () { return entry->PAT0 << 0 | entry->PAT1 << 1 | entry->PAT2 << 2; } ! bool map_item::Modify() { return entry->read_write; } ! bool map_item::Global() { return entry->global; } ! bool map_item::Kernel() { return entry->user_mode; } ! ! map_item& map_item::Physical(u32b address) { entry->physical = address >> 12; return *this; } ! ! map_item& map_item::Caching (u08b number) { entry->PAT0 = number &0x01; *************** *** 64,245 **** } ! map_item& map_item::operator()(u32b physical) ! { ! Physical(physical); ! return *this; ! } ! map_target::map_target(u16b table, u16b page, bool page_table) { table_number = table; page_number = page; - - is_table = page_table; } ! void map_target::InvalidatePage(u32b address) { ! asm("invlpg (%%eax)" : : "a"(address)); } ! map_target& map_target::operator[](u32b index) ! { ! page_number = index; ! is_table = false; ! return *this; ! } ! map_target& map_target::operator=(map_item item) { ! u32b* table_map = reinterpret_cast<u32b*>(0xFFFFF000); ! u32b* page_map = reinterpret_cast<u32b*>(0xFFC00000); ! ! if(is_table) { ! // Insert the new page-table entry ! bf32<page_structure> entry = item.entry; ! entry->present = true; ! table_map[table_number] = entry; - - // Clear the table if required - if(item.zero_tables) - { - u32b first = table_number*4096; - memset(&page_map[first], &page_map[first+1024], u32b(0)); - } } else { ! // Insert the new page entry ! bf32<page_structure> entry = item.entry; ! entry->present = true; ! page_map[table_number*1024 + page_number] = entry; - - // Remove the old mapping from the TLB - InvalidatePage((table_number*1024 + page_number)*4096); } - return *this; } ! map_target& map_target::operator=(map_target target) { ! u32b* table_map = reinterpret_cast<u32b*>(0xFFFFF000); ! u32b* page_map = reinterpret_cast<u32b*>(0xFFC00000); ! ! if(is_table) { ! map_item flags = bf32<page_structure>(table_map[target.table_number]); ! flags.zero_tables = false; ! operator=(flags); } else { ! map_item flags = bf32<page_structure>(page_map[target.table_number*1024 + target.page_number]); ! operator=(flags); } - return *this; } ! map_target& map_target::operator+=(map_item item) ! { ! // Set additional flags for an existing page/page_table ! u32b* table_map = reinterpret_cast<u32b*>(0xFFFFF000); ! u32b* page_map = reinterpret_cast<u32b*>(0xFFC00000); ! if(is_table) ! { ! u32b entry = table_map[table_number]; ! entry |= item.entry; ! table_map[table_number] = entry; ! } ! else { ! u32b entry = page_map[table_number*1024 + page_number]; ! entry |= item.entry; ! page_map[table_number*1024 + page_number] = entry; ! } ! return *this; ! } ! map_target& map_target::operator-=(map_item item) ! { ! // Clear certain flags of an existing page/page_table ! u32b* table_map = reinterpret_cast<u32b*>(0xFFFFF000); ! u32b* page_map = reinterpret_cast<u32b*>(0xFFC00000); ! if(is_table) ! { ! u32b entry = table_map[table_number]; ! entry &= ~item.entry; ! table_map[table_number] = entry; } else { ! u32b entry = page_map[table_number*1024 + page_number]; ! entry &= ~item.entry; ! page_map[table_number*1024 + page_number] = entry; ! } ! return *this; ! } ! ! memory_mapper::memory_mapper(u32b directory) ! { ! if(directory != 0) pagedirectory = directory; // Access an exsisting page-directory ! ! // TODO - Create a new directory if required ! // TODO - Add support for extended PAT entries ! // TODO - Ensure multiprocessor TLB synchronisation ! } ! ! map_item memory_mapper::user_mode(u32b physical) { return map_item(0).Physical(physical).UserMode().Write();} ! map_item memory_mapper::user_read(u32b physical) { return map_item(0).Physical(physical).UserMode(); } ! ! map_item memory_mapper::kernel_mode(u32b physical) { return map_item(0).Physical(physical).Global().Write(); } ! map_item memory_mapper::kernel_read(u32b physical) { return map_item(0).Physical(physical).Global(); } ! map_item memory_mapper::device_regs(u32b physical) { return map_item(0).Physical(physical).PAT(3).Write(); } ! ! u32b* memory_mapper::CreateDirtyMap(u32b* map, u32b virtual_base, u32b number_pages) ! { ! u32b* page_map = reinterpret_cast<u32b*>(0xFFC00000); ! u32b page_base = virtual_base >> 12; ! ! for(u32b i=page_base; i < (page_base + number_pages); i++) ! { ! bf32<page_structure> entry = page_map[i]; ! ! u32b index = i/32; // Index of the dword within the map ! u08b offset = i%32; // Bit offset in the dword ! ! map[index] |= entry->dirty << offset; } - return map; } ! u32b* memory_mapper::CreateAccessedMap(u32b* map, u32b virtual_base, u32b number_pages) ! { ! u32b* page_map = reinterpret_cast<u32b*>(0xFFC00000); ! u32b page_base = virtual_base >> 12; ! ! for(u32b i=page_base; i < (page_base + number_pages); i++) ! { ! bf32<page_structure> entry = page_map[i]; ! ! u32b index = i/32; // Index of the dword within the map ! u08b offset = i%32; // Bit offset in the dword ! map[index] |= entry->accessed << offset; ! } ! return map; ! } ! map_target memory_mapper::operator[](u32b index) ! { ! return map_target(index, 0, true); ! } ! map_target memory_mapper::operator()(u32b address) ! { ! return map_target(address >> 22, (address >> 12)%1024, false); ! } --- 67,145 ---- } ! map_item& map_item::Modify(bool set) { entry->read_write = set; return *this; } ! map_item& map_item::Global(bool set) { entry->global = set; return *this; } ! map_item& map_item::Kernel(bool set) { entry->user_mode = set; return *this; } ! map_target::map_target(u16b table, u16b page) : page_table(true) { table_number = table; page_number = page; } ! map_target::map_target(u32b virtual_address) : page_table(false) { ! table_number = virtual_address >> 22; ! page_number = (virtual_address >> 12) % 1024; } ! void map_target::InvalidatePage(u32b address) { asm("invlpg (%0)" : : "r"(address)); } ! void map_target::SetMapping(u32b entry) { ! if(page_table == true) { ! u32b* table_map = reinterpret_cast<u32b*>(0xFFFFF000); table_map[table_number] = entry; } else { ! u32b* page_map = reinterpret_cast<u32b*>(0xFFC00000); page_map[table_number*1024 + page_number] = entry; } } ! u32b map_target::GetMapping() { ! if(page_table == true) { ! u32b* table_map = reinterpret_cast<u32b*>(0xFFFFF000); ! return table_map[table_number]; } else { ! u32b* page_map = reinterpret_cast<u32b*>(0xFFC00000); ! return page_map[table_number*1024 + page_number]; } } ! map_item map_target::operator->() { return map_item(bf32<page_structure>(GetMapping())); } ! void map_target::operator=(map_item item) ! { ! if(page_table == true) { ! u32b* page_map = reinterpret_cast<u32b*>(0xFFC00000); ! SetMapping(item.entry); ! // Initialize the page-table with all zeroes ! u32b first = table_number*1024; ! u32b last = table_number*1024 + 1024; ! memset(&page_map[first], &page_map[last], u32b(0)); } else { ! SetMapping(item.entry); ! InvalidatePage((table_number*1024 + page_number)*4096); } } ! void map_target::operator+=(map_item item) { SetMapping(GetMapping() | item.entry); } ! void map_target::operator-=(map_item item) { SetMapping(GetMapping() & ~item.entry); } ! memory_mapper::memory_mapper(u32b directory) : pagedirectory(directory) {} ! map_target memory_mapper::operator[](u32b index) { return map_target(index, 0); } ! map_target memory_mapper::operator()(u32b address) { return map_target(address); } ! void memory_mapper::SetPageDirectory(u32b directory) { asm("mov %0, %%cr3" : : "r"(directory)); } Index: mmu.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/mmu.hpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** mmu.hpp 24 Jun 2006 15:00:02 -0000 1.5 --- mmu.hpp 19 Oct 2006 17:48:34 -0000 1.6 *************** *** 48,56 **** bool read_write : 1; bool user_mode : 1; ! bool PAT0 : 1; ! bool PAT1 : 1; bool accessed : 1; bool dirty : 1; ! bool PAT2 : 1; // 4MB pages bit for page-tables bool global : 1; bool : 3; --- 48,56 ---- bool read_write : 1; bool user_mode : 1; ! u08b PAT0 : 1; ! u08b PAT1 : 1; bool accessed : 1; bool dirty : 1; ! u08b PAT2 : 1; bool global : 1; bool : 3; *************** *** 60,84 **** class map_item { - private: friend class map_target; - bf32<page_structure> entry; ! bool zero_tables; // Set by default, must get uncheck before copying tables public: ! explicit map_item(u32b init = 0); ! map_item(bf32<page_structure> init); - // Modifiers to set additional flags map_item& Physical(u32b address); ! map_item& Write(); ! map_item& UserMode(); ! map_item& Pages4MB(); ! map_item& PAT(u08b number); ! map_item& Global(); ! map_item& Present(); ! // More convenient way of assigning an address ! map_item& operator()(u32b physical); }; --- 60,84 ---- class map_item { friend class map_target; ! private: bf32<page_structure> entry; public: ! map_item(bf32<page_structure> init) : entry(init) {} ! map_item(u32b physical=0); ! ! u32b Physical(); ! u08b Caching (); map_item& Physical(u32b address); ! map_item& Caching (u08b pat_number); ! bool Modify(); ! bool Global(); ! bool Kernel(); ! ! map_item& Modify(bool set = true); ! map_item& Global(bool set = true); ! map_item& Kernel(bool set = true); }; *************** *** 87,132 **** private: u16b table_number, page_number; ! bool is_table; void InvalidatePage(u32b address); public: ! map_target(u16b table, u16b page, bool page_table); ! map_target& operator[](u32b index); ! map_target& operator=(map_item item); // Assigns map_items to paging structures ! map_target& operator=(map_target target); // Allows the copying of pages/page-tables ! map_target& operator+=(map_item item); // Add or remove certain flags of the page ! map_target& operator-=(map_item item); }; class memory_mapper { ! private: ! u32b pagedirectory; // Physical address of the page-directory public: ! memory_mapper(u32b directory = 0); ! ~memory_mapper(); ! ! // Standard flag combinations that are often needed ! static map_item user_mode(u32b physical); ! static map_item user_read(u32b physical); ! ! static map_item kernel_mode(u32b physical); ! static map_item kernel_read(u32b physical); ! ! static map_item device_regs(u32b physical); ! ! // Dirty and accessed bits may be required by some user-mode pager ! u32b* CreateDirtyMap(u32b* map, u32b virtual_base, u32b number_pages); ! u32b* CreateAccessedMap(u32b* map, u32b virtual_base, u32b number_pages); ! u32b GetPageDirectory() { return pagedirectory; } // Used in conjunction with task_context ! map_target operator[](u32b index); // 2D access -> page_table : page_index ! map_target operator()(u32b address); // pages only -> absolute address }; --- 87,120 ---- private: u16b table_number, page_number; ! bool page_table; void InvalidatePage(u32b address); + void SetMapping(u32b entry); + u32b GetMapping(); + public: ! map_target(u16b table, u16b page); ! map_target(u32b virtual_address); ! map_item operator->(); ! void operator+=(map_item item); ! void operator-=(map_item item); ! void operator =(map_item item); }; class memory_mapper { ! private: u32b pagedirectory; public: ! memory_mapper(u32b directory = 0); ! map_target operator()(u32b address); // Page reference by virtual address ! map_target operator[](u32b index); // Table access by indexing the directory ! void SetPageDirectory(u32b directory); }; Index: mutex.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/mutex.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** mutex.cpp 24 Jun 2006 15:00:02 -0000 1.6 --- mutex.cpp 19 Oct 2006 17:48:34 -0000 1.7 *************** *** 42,46 **** mutex::mutex() { ! key = 0; } --- 42,46 ---- mutex::mutex() { ! key = 0; } *************** *** 62,67 **** } ! void mutex::ExitMutex() { asm("movl $0, %[key] \n" : : [key] "m" (key)); } --- 62,78 ---- } ! void mutex::LeaveMutex() { asm("movl $0, %[key] \n" : : [key] "m" (key)); } + + CriticalSection::CriticalSection(mutex* key) + { + mutex_key = key; + mutex_key->EnterMutex(); + } + + CriticalSection::~CriticalSection() + { + mutex_key->LeaveMutex(); + } Index: mutex.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/mutex.hpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** mutex.hpp 24 Jun 2006 15:00:03 -0000 1.6 --- mutex.hpp 19 Oct 2006 17:48:34 -0000 1.7 *************** *** 46,50 **** { private: ! volatile u32b key; public: --- 46,50 ---- { private: ! volatile u32b key; public: *************** *** 53,57 **** void EnterMutex(); ! void ExitMutex(); }; --- 53,67 ---- void EnterMutex(); ! void LeaveMutex(); ! }; ! ! class CriticalSection ! { ! private: ! mutex* mutex_key; ! ! public: ! CriticalSection(mutex* key); ! ~CriticalSection(); }; |
From: Daniel R. <co...@us...> - 2006-10-19 17:48:18
|
Update of /cvsroot/trion/trion v0.2 In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv11578 Modified Files: ldscript makefile Log Message: no message Index: ldscript =================================================================== RCS file: /cvsroot/trion/trion v0.2/ldscript,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ldscript 5 Apr 2006 17:10:28 -0000 1.4 --- ldscript 19 Oct 2006 17:48:14 -0000 1.5 *************** *** 1,13 **** SECTIONS { ! . = 0xE0000000; ! ! kernel_start = .; ! ! .text : AT(ADDR(.text) - 0xDFF00000) { *(.text) - *(.rodata*) - *(.gnu.linkonce*) } --- 1,9 ---- SECTIONS { ! .text 0xE0000000 : AT(ADDR(.text) - 0xDFF00000) { + kernel_start = ALIGN(0x1000); + *(.text) } *************** *** 15,28 **** { *(.data*) } .bss : AT(ADDR(.bss) - 0xDFF00000) { - *(.bss*) *(.comment*) ! } ! . = ALIGN(0x1000); ! kernel_end = .; } --- 11,25 ---- { *(.data*) + *(.rodata*) } .bss : AT(ADDR(.bss) - 0xDFF00000) { *(.comment*) ! *(.bss*) ! . = ALIGN(0x1000) + 0x10000; ! kernel_end = ALIGN(0x1000); ! } } Index: makefile =================================================================== RCS file: /cvsroot/trion/trion v0.2/makefile,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** makefile 24 Jun 2006 14:58:59 -0000 1.15 --- makefile 19 Oct 2006 17:48:15 -0000 1.16 *************** *** 40,82 **** AS = nasm ! CC = i686-elf-gcc -I ./hal/ -I ./loader/ -I ./object/ ! RM = rm -f LD = i686-elf-ld AFLAGS = -f elf ! CFLAGS = -Iinclude -fno-builtin -nostdlib -nostdinc -fno-rtti \ ! -fno-exceptions -nostartfiles -s -Wno-pmf-conversions # -Wall -W -pedantic -O3 -finline -march=pentium3 - LDFLAGS = -T ldscript -Map Trion.map CSRCS = loader/main.cpp \ loader/console.cpp \ ! loader/heap_manager.cpp \ ! loader/mp_detect.cpp \ ! hal/cpu_info.cpp \ ! hal/hal_object.cpp \ ! hal/systemcall.cpp \ ! hal/interrupt_stub.cpp \ ! hal/interrupt.cpp \ ! hal/idt.cpp \ ! hal/gdt.cpp \ ! hal/exception.cpp \ ! hal/task_context.cpp \ hal/mmu.cpp \ - hal/ports.cpp \ hal/mutex.cpp \ ! hal/apic_local.cpp \ ! hal/apic_io.cpp \ ! hal/timer.cpp \ ! hal/irq.cpp \ ! hal/ipi.cpp COBJS = $(CSRCS:.cpp=.o) CHDRS = $(CSCRS:.cpp=.hpp) ! ASRCS = hal/interrupt_stub_code.asm \ ! hal/systemcall_stub_code.asm ! AOBJS = $(ASRCS:.asm=.o) --- 40,69 ---- AS = nasm ! CC = i686-elf-gcc LD = i686-elf-ld + ST = i686-elf-strip + RM = rm AFLAGS = -f elf ! CFLAGS = -Iinclude -fno-builtin -nostdlib -nostdinc -fno-rtti \ ! -fno-exceptions -nostartfiles -s -Wno-pmf-conversions \ ! -I ./hal/ -I ./loader/ \ ! -I ./object/ -I ./executive/ # -Wall -W -pedantic -O3 -finline -march=pentium3 LDFLAGS = -T ldscript -Map Trion.map CSRCS = loader/main.cpp \ loader/console.cpp \ ! executive/cpu_node.cpp \ hal/mmu.cpp \ hal/mutex.cpp \ ! loader/heap_manager.cpp \ ! object/virtual_memory.cpp \ ! object/physical_memory.cpp COBJS = $(CSRCS:.cpp=.o) CHDRS = $(CSCRS:.cpp=.hpp) ! ASRCS = hal/interrupt_stub_code.asm AOBJS = $(ASRCS:.asm=.o) *************** *** 87,90 **** --- 74,78 ---- $(OUTPUT): loader/entry.o $(COBJS) $(AOBJS) $(LD) $(LDFLAGS) loader/entry.o $(COBJS) $(AOBJS) -o $(OUTPUT) + $(ST) --strip-all nucleus.elf .cpp.o: $(CHDRS) *************** *** 95,97 **** clean: ! $(RM) loader/entry.o $(COBJS) $(AOBJS) --- 83,85 ---- clean: ! $(RM) -f loader/entry.o $(COBJS) $(AOBJS) |
From: Stephen M. W. <bre...@us...> - 2006-09-08 14:02:02
|
Update of /cvsroot/trion/htdocs/images In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv30638 Modified Files: logo0.png Log Message: Made background transparent. Index: logo0.png =================================================================== RCS file: /cvsroot/trion/htdocs/images/logo0.png,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 Binary files /tmp/cvsTWcfQw and /tmp/cvsfvU1jx differ |
From: Stephen M. W. <bre...@us...> - 2006-09-07 20:31:01
|
Update of /cvsroot/trion/htdocs In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv16764 Modified Files: downloads.php Added Files: community.php Log Message: Merged recent onsite changes into CVS. Index: downloads.php =================================================================== RCS file: /cvsroot/trion/htdocs/downloads.php,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** downloads.php 13 Jan 2006 18:21:06 -0000 1.2 --- downloads.php 7 Sep 2006 20:29:55 -0000 1.3 *************** *** 16,20 **** <td class="data">Kernel Architecture</td> <td class="data">This document contains a schema showing the kernel architecture.</td> ! <td class="data"><a href="downloads/arch.pdf">Download</a></td> </tr> <tr> --- 16,20 ---- <td class="data">Kernel Architecture</td> <td class="data">This document contains a schema showing the kernel architecture.</td> ! <td class="data"><a href="http://trion.cvs.sourceforge.net/*checkout*/trion/docs/trion%20design%20draft.pdf?revision=1.1">Download</a></td> </tr> <tr> --- NEW FILE: community.php --- <?php include('include/header.php'); trionHeader(); ?> <!-- Here comes the actual content --> <div id="content"> <br/> <h1>The Trion Community</h1> <div id="genericlist"> <ul> <li><a href="http://sourceforge.net/projects/trion/">SourceForge</a></li> <li><a href="phpBB2">Forum</a></li> <li><a href="wiki">Wiki</a></li> <li>IRC: irc.freenode.net #trion</li> </ul> </div> <?php include('templates/footer.php'); ?> |
From: Stephen M. W. <bre...@us...> - 2006-09-07 20:30:04
|
Update of /cvsroot/trion/htdocs/styles In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv16764/styles Modified Files: general.css Log Message: Merged recent onsite changes into CVS. Index: general.css =================================================================== RCS file: /cvsroot/trion/htdocs/styles/general.css,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** general.css 24 Jan 2006 18:19:22 -0000 1.4 --- general.css 7 Sep 2006 20:29:56 -0000 1.5 *************** *** 179,185 **** position: absolute; top: 0px; ! left: 10%; ! right: 10%; ! width: 80%; z-index: 1; background-color: #ffffff; --- 179,185 ---- position: absolute; top: 0px; ! left: 5%; ! right: 5%; ! width: 90%; z-index: 1; background-color: #ffffff; |
From: Stephen M. W. <bre...@us...> - 2006-09-07 20:30:01
|
Update of /cvsroot/trion/htdocs/include In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv16764/include Modified Files: header.php Log Message: Merged recent onsite changes into CVS. Index: header.php =================================================================== RCS file: /cvsroot/trion/htdocs/include/header.php,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** header.php 25 Mar 2006 18:07:42 -0000 1.3 --- header.php 7 Sep 2006 20:29:56 -0000 1.4 *************** *** 27,35 **** <li><img src="images/blankbar1.png" width="28" height="26" alt="menu"/></li> <li><a href="index.php">Home</a></li> ! <li><a href="construct.php">About</a></li> ! <li><a href="downloads.php">Downloads</a></li> ! <li><a href="construct.php">Forum</a></li> <li><a href="construct.php">Documentation</a></li> ! <li><a href="http://sourceforge.net/projects/trion/">SourceForge</a></li> <li><img src="images/blankbar2.png" width="34" height="26" alt="menu"/></li> </ul> --- 27,34 ---- <li><img src="images/blankbar1.png" width="28" height="26" alt="menu"/></li> <li><a href="index.php">Home</a></li> ! <li><a href="downloads.php">Get Trion</a></li> ! <li><a href="community.php">Community</a></li> <li><a href="construct.php">Documentation</a></li> ! <li><a href="construct.php">About</a></li> <li><img src="images/blankbar2.png" width="34" height="26" alt="menu"/></li> </ul> |
From: Stephen M. W. <bre...@us...> - 2006-09-07 19:44:30
|
Update of /cvsroot/trion/htdocs/images In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv30240 Added Files: favicon.ico Log Message: Added new icon. --- NEW FILE: favicon.ico --- (This appears to be a binary file; contents omitted.) |
From: Stephen M. W. <bre...@us...> - 2006-09-01 16:29:41
|
Update of /cvsroot/trion/htdocs/images In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv21283 Added Files: logo0.png Log Message: New file. --- NEW FILE: logo0.png --- (This appears to be a binary file; contents omitted.) |
From: Daniel R. <co...@us...> - 2006-06-24 15:01:50
|
Update of /cvsroot/trion/trion v0.2/object In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv2339 Modified Files: std_types.hpp Log Message: no message Index: std_types.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/object/std_types.hpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** std_types.hpp 23 Feb 2006 12:26:40 -0000 1.2 --- std_types.hpp 24 Jun 2006 15:01:46 -0000 1.3 *************** *** 9,13 **** // ----------------------------------------------------------------------- ! // Copyright (C) 2003, Trion Development Group Members // All rights reserved. // --- 9,13 ---- // ----------------------------------------------------------------------- ! // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // *************** *** 41,73 **** #define __STANDARD_DATA_TYPE_DEFINITIONS__ ! typedef long unsigned int size_t; ! typedef unsigned char uchar; ! typedef unsigned short ushort; ! typedef unsigned int uint; ! typedef unsigned long ulong; ! #ifndef __SIZE_TYPE__ ! #define __SIZE_TYPE__ long unsigned int ! #endif ! typedef __SIZE_TYPE__ size_t; ! /** Placement new operator. Used to construct objects at reserved memory locations. */ ! inline void *operator new(size_t, void *place) throw() { return place; } ! /** Placement new operator for arrays. Used to construct arrays of objects at reserved memory locations. */ inline void *operator new[](size_t, void *place) throw() { return place; } ! /** Delete operator. Used to call destructors. */ inline void operator delete (void*, void*) throw() { } - - /** Delete operator for array. Used to call destructors. */ inline void operator delete[](void*, void*) throw() { } ! void* operator new(size_t count) throw(); ! void* operator new[](size_t count) throw(); ! void operator delete(void* pointer) throw(); ! void operator delete[](void* pointer) throw(); #endif --- 41,91 ---- #define __STANDARD_DATA_TYPE_DEFINITIONS__ ! typedef unsigned char u08b; ! typedef signed char s08b; ! typedef unsigned short u16b; ! typedef signed short s16b; ! typedef unsigned int u32b; ! typedef signed int s32b; ! typedef unsigned long long u64b; ! typedef signed long long s64b; ! typedef long unsigned int size_t; ! /** Placement new operators, used to construct (arrays of) objects at reserved memory locations. */ ! inline void *operator new (size_t, void *place) throw() { return place; } inline void *operator new[](size_t, void *place) throw() { return place; } ! /** Placement delete operators, used to call destructors for (arrays of) objects. */ inline void operator delete (void*, void*) throw() { } inline void operator delete[](void*, void*) throw() { } ! /** Allow a 32bit wide bitfield to be accessed like an ordinary integer */ ! template<class T> struct bf32 ! { ! private: ! union { u32b integer; T bitfield; }; ! ! public: ! bf32(u32b value) : integer(value) {}; // Allows initialization with an integer ! ! operator u32b() { return integer; } // Default conversation to an integer ! operator T&() { return bitfield; } // Conversation to the bitfield type ! ! T* operator->() { return &bitfield; } // Access to the members of the bitfield ! }; ! ! /** Some very basic operations to initialize and copy memory ranges */ ! template<class T> void memset(T* begin, T* end, const T& value) ! { ! while(begin != end) *(begin++) = value; ! } ! ! template<class T> void memcopy(T* begin, T* end, T* destination) ! { ! while(begin != end) *(destination++) = *(begin++); ! } #endif |
Update of /cvsroot/trion/trion v0.2/loader In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv2298 Modified Files: console.cpp console.hpp entry.asm heap_manager.cpp heap_manager.hpp main.cpp mp_detect.cpp mp_detect.hpp Removed Files: pmode.asm Log Message: no message Index: main.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/main.cpp,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** main.cpp 2 Jun 2006 21:11:21 -0000 1.18 --- main.cpp 24 Jun 2006 15:01:32 -0000 1.19 *************** *** 38,71 **** // ----------------------------------------------------------------------- ! #include "../object/std_types.hpp" ! #include "console.hpp" ! ! #include "heap_manager.hpp" ! #include "mp_detect.hpp" ! ! #include "../hal/hal_object.hpp" ! #include "../hal/cpu_info.hpp" ! #include "../hal/mmu.hpp" ! #include "../hal/idt.hpp" ! #include "../hal/exception.hpp" ! #include "../hal/apic_local.hpp" ! #include "../hal/timer.hpp" ! #include "../hal/irq.hpp" ! #include "../hal/ipi.hpp" ! #include "../hal/systemcall.hpp" ! #include "../hal/task_context.hpp" ! hal_object* boot_hal; ! extern "C" void user_main() { ! asm("mov %ss, %eax\n" ! "mov %eax, %ds\n" ! "mov %eax, %es\n" ! "mov %eax, %fs\n" ! "mov %eax, %gs\n" ! ); // Print a red 'A' in the upper-left corner of the screen --- 38,66 ---- // ----------------------------------------------------------------------- ! #include <std_types.hpp> ! #include <console.hpp> ! #include <heap_manager.hpp> ! #include <mp_detect.hpp> ! #include <hal_object.hpp> ! #include <mmu.hpp> ! #include <idt.hpp> ! #include <exception.hpp> ! #include <apic_local.hpp> ! #include <timer.hpp> ! #include <irq.hpp> ! #include <ipi.hpp> ! #include <cpu_info.hpp> ! #include <gdt.hpp> ! #include <ports.hpp> ! #include <systemcall.hpp> ! #include <task_context.hpp> ! extern "C" u32b user_main() { ! asm("mov %ss, %eax\n" "mov %eax, %ds\n" "mov %eax, %es\n" ! "mov %eax, %fs\n" "mov %eax, %gs\n"); // Print a red 'A' in the upper-left corner of the screen *************** *** 85,94 **** vidmem[(160+78)*2 + 1] = 4; ! while(true); // Wait for IRQs } ! extern "C" int main(uint image_size, uint processor, uint magic, void* grub) { ! uint number_processors; if(processor == 0) --- 80,96 ---- vidmem[(160+78)*2 + 1] = 4; ! // Try accessing some I/O ports by moving the x86 hardware cursor ! asm("mov $0x0f, %al\n" "mov $0x3d4, %dx\n" "out %al, %dx\n"); ! asm("mov $0x9e, %al\n" "mov $0x3d5, %dx\n" "out %al, %dx\n"); ! ! asm("mov $0x0e, %al\n" "mov $0x3d4, %dx\n" "out %al, %dx\n"); ! asm("mov $0x00, %al\n" "mov $0x3d5, %dx\n" "out %al, %dx\n"); ! ! while(true); // Waiting for IRQs } ! extern "C" int main(u32b image_size, u32b processor, u32b magic, void* grub) { ! static u32b number_processors; if(processor == 0) *************** *** 96,106 **** number_processors = 1; ! // Create the global heap-manager class object ! new (heap_manager_reserved) heap_manager(); ! new (cpu_info_reserved) cpu_info(); ! // Spawn an instance of the mmu class ! hal_object* hal = boot_hal = heap().CreateHalObject(processor); ! hal->memory = new (heap().AllocateMemory(sizeof(mmu))) mmu(0xE0000000 + image_size); // Create a console object to be able to print debug messages --- 98,112 ---- number_processors = 1; ! // Create the global heap-manager object ! new (virt_allocator_reserved) memory_stack(0xE0000000 + image_size + 0x2000); ! new (phys_allocator_reserved) memory_stack(0x00100000 + image_size + 0x5000); ! new (heap_manager_reserved) heap_manager(0xE0000000 + image_size + 0x1000); ! // Create a new hal-object instance ! heap().CreateHalObject(processor); ! hal_object& hal = get_hal_object(); ! ! // Spawn an instance of the memory-mapper class ! hal.set_memory(heap().CreateObject<memory_mapper>(0x00100000 + image_size)); // Create a console object to be able to print debug messages *************** *** 111,132 **** // Enable the IDT and activate exception handling ! hal->vector = new (heap().AllocateMemory(sizeof(idt))) idt(); ! hal->faults = new (heap().AllocateMemory(sizeof(exception))) exception(); // Initialize the local APIC and enable all I/O APICs mp_detect* multi = new (mp_detect_reserved) mp_detect(); ! hal->lapic = new (heap().AllocateMemory(sizeof(local_apic))) local_apic(); ! hal->clock = new (heap().AllocateMemory(sizeof(timer))) timer(); ! hal->inter = new (heap().AllocateMemory(sizeof(ipi))) ipi(); new (irq_logic_reserved) irq_logic(); // Prepare everything for user-mode ! hal->context = new (heap().AllocateMemory(sizeof(task_context))) task_context(); ! hal->syscall = new (heap().AllocateMemory(sizeof(systemcall))) systemcall(); // Enable hyperthreading and try to boot all application processors ! number_processors += multi->EnableHyperthreading(); ! number_processors += multi->BootAllProcessors(); cout() << endl << "All " << number_processors << " processors have been booted" << endl; --- 117,142 ---- // Enable the IDT and activate exception handling ! hal.set_idt(heap().CreateObject<idt_table>()); ! hal.set_exceptions(heap().CreateObject<exception>()); // Initialize the local APIC and enable all I/O APICs mp_detect* multi = new (mp_detect_reserved) mp_detect(); ! ! hal.set_info(heap().CreateObject<cpu_info>()); ! hal.set_lapic(heap().CreateObject<local_apic>()); ! hal.set_timer(heap().CreateObject<apic_timer>()); ! hal.set_ipi(heap().CreateObject<cpu_messages>()); new (irq_logic_reserved) irq_logic(); // Prepare everything for user-mode ! hal.set_gdt(heap().CreateObject<gdt_table>()); ! hal.set_context(heap().CreateObject<task_context>()); ! hal.set_syscall(heap().CreateObject<systemcall>()); ! hal.set_port(heap().CreateObject<port_protect>()); // Enable hyperthreading and try to boot all application processors ! multi->EnableHyperthreading(); ! multi->BootAllProcessors(); cout() << endl << "All " << number_processors << " processors have been booted" << endl; *************** *** 136,171 **** // Install a small user-task for testing purposes ! hal->memory->CreatePageTable(0x00000000, 0x8000, mmu::USER_MODE | mmu::READ_WRITE); ! hal->memory->MapPage((void*)0x00000000, 0x100000, mmu::USER_MODE | mmu::READ_WRITE); // user-mode code ! hal->memory->MapPage((void*)0x00001000, 0x10000, mmu::USER_MODE | mmu::READ_WRITE); // stack space ! hal->memory->MapPage((void*)0x00002000, 0xB8000, mmu::USER_MODE | mmu::READ_WRITE); // video memory ! uint task_entry = (uint)&user_main - 0xE0000000; // Switch to the user-mode code ! hal->syscall->InvokeUserTask(task_entry, 0x2000); } else { ap_flag |= 1; // Indicates that the processor has been booted ! cout() << "An application processor was booted (# "<< processor << ")" << endl; // Spawn an instance of all hal classes.. ! hal_object* hal = boot_hal = heap().CreateHalObject(processor); ! hal->memory = new (heap().AllocateMemory(sizeof(mmu))) mmu(0xE0000000 + image_size); ! hal->vector = new (heap().AllocateMemory(sizeof(idt))) idt(); ! hal->faults = new (heap().AllocateMemory(sizeof(exception))) exception(); ! hal->lapic = new (heap().AllocateMemory(sizeof(local_apic))) local_apic(); ! hal->clock = new (heap().AllocateMemory(sizeof(timer))) timer(); ! hal->inter = new (heap().AllocateMemory(sizeof(ipi))) ipi(); ! number_processors += multiprocessor().EnableHyperthreading(); ap_flag |= 2; // Indicates that the hal is fully initialized, next AP may get started - asm("sti"); while(true) asm("hlt"); } --- 146,191 ---- // Install a small user-task for testing purposes ! hal(memory)[0] = memory_mapper::user_mode(0x8000); // Create a new page-table ! hal(memory)[0][0] = memory_mapper::user_mode(0x100000); // User Code ! hal(memory)[0][1] = memory_mapper::user_mode(0x10000); // Stack Space ! hal(memory)[0][2] = memory_mapper::user_mode(0xB8000); // Video Memory ! u32b task_entry = (u32b)&user_main - 0xE0000000; ! ! // Create a port bitmap for the task and enable the required ports ! hal(port).EnablePort<u08b>(0x3d4); ! hal(port).EnablePort<u08b>(0x3d5); ! ! hal(context).SetPortMap(hal(port).GetPortMap()); // Switch to the user-mode code ! hal(syscall).InvokeUserTask(task_entry, 0x2000); } else { ap_flag |= 1; // Indicates that the processor has been booted ! ! number_processors++; // Spawn an instance of all hal classes.. ! heap().CreateHalObject(processor); ! hal_object& hal = get_hal_object(); ! hal.set_memory(heap().CreateObject<memory_mapper>(0x00100000 + image_size)); ! hal.set_idt(heap().CreateObject<idt_table>()); ! hal.set_exceptions(heap().CreateObject<exception>()); ! hal.set_lapic(heap().CreateObject<local_apic>()); ! hal.set_timer(heap().CreateObject<apic_timer>()); ! hal.set_ipi(heap().CreateObject<cpu_messages>()); ! hal.set_gdt(heap().CreateObject<gdt_table>()); ! hal.set_context(heap().CreateObject<task_context>()); ! hal.set_syscall(heap().CreateObject<systemcall>()); ! hal.set_port(heap().CreateObject<port_protect>()); ap_flag |= 2; // Indicates that the hal is fully initialized, next AP may get started while(true) asm("hlt"); } --- pmode.asm DELETED --- Index: mp_detect.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/mp_detect.hpp,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** mp_detect.hpp 22 May 2006 15:19:08 -0000 1.10 --- mp_detect.hpp 24 Jun 2006 15:01:32 -0000 1.11 *************** *** 41,56 **** #define __LOADER__MP_DETECT__ ! #include "../object/std_types.hpp" ! #include "../hal/hal_object.hpp" ! #include "heap_manager.hpp" struct SmpFloatingPointer { ! unsigned long Magic; ! unsigned long Table; ! unsigned char Length; ! unsigned char Version; ! unsigned char Checksum; ! unsigned char Feature[5]; }__attribute__ ((__packed__)); --- 41,56 ---- #define __LOADER__MP_DETECT__ ! #include <std_types.hpp> ! #include <heap_manager.hpp> ! #include <hal_object.hpp> struct SmpFloatingPointer { ! u32b Magic; ! u32b Table; ! u08b Length; ! u08b Version; ! u08b Checksum; ! u08b Feature[5]; }__attribute__ ((__packed__)); *************** *** 58,74 **** struct SmpConfigTable { ! unsigned long Magic; ! unsigned short BaseLength; ! unsigned char Version; ! unsigned char Checksum; ! unsigned char OemString[8]; ! unsigned char ProductString[12]; ! unsigned long OemTable; ! unsigned short OemLength; ! unsigned short EntryCount; ! unsigned long LocalApic; ! unsigned short ExtendedLength; ! unsigned char ExtendedChecksum; ! unsigned char Reserved; }__attribute__ ((__packed__)); --- 58,74 ---- struct SmpConfigTable { ! u32b Magic; ! u16b BaseLength; ! u08b Version; ! u08b Checksum; ! u08b OemString[8]; ! u08b ProductString[12]; ! u32b OemTable; ! u16b OemLength; ! u16b EntryCount; ! u32b LocalApic; ! u16b ExtendedLength; ! u08b ExtendedChecksum; ! u08b Reserved; }__attribute__ ((__packed__)); *************** *** 76,80 **** struct SmpConfigEntry { ! unsigned char Type; }__attribute__((__packed__)); --- 76,80 ---- struct SmpConfigEntry { ! u08b Type; }__attribute__((__packed__)); *************** *** 82,91 **** struct SmpConfigCPU : SmpConfigEntry { ! unsigned char LocalApicID; ! unsigned char LocalApicVersion; ! unsigned char Flags; ! unsigned long Signature; ! unsigned long Features; ! unsigned long Reserved[2]; }__attribute__ ((packed)); --- 82,91 ---- struct SmpConfigCPU : SmpConfigEntry { ! u08b LocalApicID; ! u08b LocalApicVersion; ! u08b Flags; ! u32b Signature; ! u32b Features; ! u32b Reserved[2]; }__attribute__ ((packed)); *************** *** 93,98 **** struct SmpConfigBus : SmpConfigEntry { ! unsigned char BusID; ! unsigned char TypeString[6]; } __attribute__ ((packed)); --- 93,98 ---- struct SmpConfigBus : SmpConfigEntry { ! u08b BusID; ! char TypeString[6]; } __attribute__ ((packed)); *************** *** 100,107 **** struct SmpConfigIOApic : SmpConfigEntry { ! unsigned char ApicID; ! unsigned char ApicVersion; ! unsigned char Flags; ! unsigned long BaseAddr; }__attribute__ ((packed)); --- 100,107 ---- struct SmpConfigIOApic : SmpConfigEntry { ! u08b ApicID; ! u08b ApicVersion; ! u08b Flags; ! u32b BaseAddr; }__attribute__ ((packed)); *************** *** 109,118 **** struct SmpConfigInterrupt : SmpConfigEntry { ! unsigned char IntType; ! unsigned short Flags; ! unsigned char SourceID; ! unsigned char SourceIRQ; ! unsigned char DestID; ! unsigned char DestIRQ; }__attribute__ ((packed)); --- 109,118 ---- struct SmpConfigInterrupt : SmpConfigEntry { ! u08b IntType; ! u16b Flags; ! u08b SourceID; ! u08b SourceIRQ; ! u08b DestID; ! u08b DestIRQ; }__attribute__ ((packed)); *************** *** 132,136 **** private: ! uint entry, last_entry; SmpConfigEntry* address; --- 132,136 ---- private: ! u16b entry, last_entry; SmpConfigEntry* address; *************** *** 145,149 **** bool operator!=(iterator it); ! iterator operator++(int t); SmpConfigEntry* operator*(); --- 145,150 ---- bool operator!=(iterator it); ! iterator& operator++(); ! iterator operator++(int t); SmpConfigEntry* operator*(); *************** *** 154,168 **** private: SmpConfigEntry* config_table; ! uint entry_count, apic_address; vRange* window; ! void RelocateEntrypoint(uint relocation_address); ! uint GetCMOSValue(uint address); ! uint DetectFloatingPointer(uint start_address, uint length); bool CheckBootstrap(iterator cpu); bool CheckDisabled (iterator cpu); ! uint GetLocalApicID(iterator cpu); public: --- 155,170 ---- private: SmpConfigEntry* config_table; ! u32b entry_count, apic_address; vRange* window; ! void RelocateEntrypoint(u32b relocation_address); ! u16b GetCMOSValue(u32b address); ! ! u32b DetectFloatingPointer(u32b start_address, u32b length); bool CheckBootstrap(iterator cpu); bool CheckDisabled (iterator cpu); ! u08b GetLocalApicID(iterator cpu); public: *************** *** 173,182 **** iterator end(); - uint GetNumberEntries(entry_type type); - bool BootProcessor(iterator cpu); - uint BootAllProcessors(); ! uint EnableHyperthreading(); }; --- 175,184 ---- iterator end(); bool BootProcessor(iterator cpu); ! u08b BootAllProcessors(); ! u08b EnableHyperthreading(); ! ! u08b GetNumberEntries(entry_type type); }; *************** *** 184,188 **** mp_detect& multiprocessor(); ! extern volatile uint ap_flag; #endif --- 186,190 ---- mp_detect& multiprocessor(); ! extern volatile u32b ap_flag; #endif Index: mp_detect.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/mp_detect.cpp,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** mp_detect.cpp 22 May 2006 15:19:08 -0000 1.12 --- mp_detect.cpp 24 Jun 2006 15:01:32 -0000 1.13 *************** *** 38,59 **** // ----------------------------------------------------------------------- ! #include "mp_detect.hpp" ! #include "console.hpp" ! #include "../hal/timer.hpp" ! #include "../hal/ipi.hpp" ! #include "../hal/cpu_info.hpp" ! extern "C" unsigned char ap_code_start[]; ! extern "C" unsigned char ap_code_end[]; ! volatile uint ap_flag; mp_detect::mp_detect() { // Get possible locations of the multiprocessor floating pointer from the CMOS ! uint ebda = GetCMOSValue(0x40E) << 4; ! uint lastK = GetCMOSValue(0x413) << 10; ! uint bios = 0x000F0000; // Relocate the entrypoint to a lower address so that it can be reached from real-mode --- 38,60 ---- // ----------------------------------------------------------------------- ! #include <mp_detect.hpp> ! #include <console.hpp> ! #include <hal_object.hpp> ! #include <cpu_info.hpp> ! #include <timer.hpp> ! #include <ipi.hpp> ! extern "C" u32b ap_code_start[]; ! extern "C" u32b ap_code_end[]; ! volatile u32b ap_flag; mp_detect::mp_detect() { // Get possible locations of the multiprocessor floating pointer from the CMOS ! u32b ebda = GetCMOSValue(0x40E) << 4; ! u32b lastK = GetCMOSValue(0x413) << 10; ! u32b bios = 0x000F0000; // Relocate the entrypoint to a lower address so that it can be reached from real-mode *************** *** 61,66 **** // Search for the multiprocessor floating pointer ! uint table(0); ! uint address = (ebda) ? ebda : lastK; table = DetectFloatingPointer(address, 0x400); --- 62,67 ---- // Search for the multiprocessor floating pointer ! u32b table(0); ! u32b address = (ebda) ? ebda : lastK; table = DetectFloatingPointer(address, 0x400); *************** *** 69,73 **** if(table && !config_table) { ! cout() << "Standard multiprocessor configuration " << reinterpret_cast<uint>(table) << endl; cout() << " will be used" << endl << endl; --- 70,74 ---- if(table && !config_table) { ! cout() << "Standard multiprocessor configuration " << reinterpret_cast<u32b>(table) << endl; cout() << " will be used" << endl << endl; *************** *** 79,92 **** { cout() << "A multiprocessor configuration table was detected "; ! cout() << "at address " << reinterpret_cast<uint>(table) << endl << endl; ! uint table_base = reinterpret_cast<uint>(table) &0xFFFFF000; ! uint table_offset = reinterpret_cast<uint>(table) &0x00000FFF; ! // Map the configuration table statically in ! window = new (heap().AllocateMemory(sizeof(vRange))) vRange(table_base); ! uint virt_address = reinterpret_cast<uint>(window->GetVirtualBase()); ! // Gather the neccessary information from the config table SmpConfigTable* vtable = reinterpret_cast<SmpConfigTable*>(virt_address + table_offset); entry_count = vtable->EntryCount; --- 80,93 ---- { cout() << "A multiprocessor configuration table was detected "; ! cout() << "at address " << reinterpret_cast<u32b>(table) << endl << endl; ! u32b table_base = reinterpret_cast<u32b>(table) &0xFFFFF000; ! u32b table_offset = reinterpret_cast<u32b>(table) &0x00000FFF; ! // Map the configuration table statically ! window = heap().CreateObject<vRange>(table_base); ! u32b virt_address = reinterpret_cast<u32b>(window->GetVirtualBase()); ! // Gather the neccessary information from the configuration table SmpConfigTable* vtable = reinterpret_cast<SmpConfigTable*>(virt_address + table_offset); entry_count = vtable->EntryCount; *************** *** 109,162 **** } ! void mp_detect::RelocateEntrypoint(uint relocation_address) { vRange virt_range(relocation_address); ! uint virt_address = reinterpret_cast<uint>(virt_range.GetVirtualBase()); ! for(uint i = 0; i < (uint)ap_code_end - (uint)ap_code_start; i++) ! ((uchar*)virt_address)[i] = ap_code_start[i]; } ! uint mp_detect::GetCMOSValue(uint address) { vRange virt_range(0); ! uint virt_address = reinterpret_cast<uint>(virt_range.GetVirtualBase()); ! return *(reinterpret_cast<ushort*>(virt_address + address)); } ! uint mp_detect::DetectFloatingPointer(uint start_address, uint length) { ! uint pbase = start_address &0xFFFFF000; ! uint offset = start_address &0xFFF; ! uint pages = (length + offset + 0xFFF)/4096; ! for(uint i=0; i<pages; i++) { vRange virt_range(pbase + i*4096); ! ulong* vpage = static_cast<ulong*>(virt_range.GetVirtualBase()); ! for(int j=0; j<1024; j+=4) { ! if(vpage[j] == '_PM_') { // Calculate the checksume of the structure ! uchar checksum = 0x00000000; ! uchar* mp_float = reinterpret_cast<uchar*>(&vpage[j]); ! for(int k=0; k<16; k++) checksum += mp_float[k]; if(checksum == 0) { ! if(vpage[j+1]) // Return a pointer to the configuration table if available { ! config_table = reinterpret_cast<SmpConfigEntry*>(vpage[j+1]); ! return vpage[j+1]; } ! else // Return the number of the standard configuration used { config_table = 0; ! return vpage[j+3] &0xFF; } } --- 110,168 ---- } ! void mp_detect::RelocateEntrypoint(u32b relocation_address) { vRange virt_range(relocation_address); ! u32b* virt_address = static_cast<u32b*>(virt_range.GetVirtualBase()); ! u16b length = reinterpret_cast<u32b>(ap_code_end) - reinterpret_cast<u32b>(ap_code_start); ! memcopy(ap_code_start, &ap_code_start[length], virt_address); } ! u16b mp_detect::GetCMOSValue(u32b address) { vRange virt_range(0); ! u32b virt_address = reinterpret_cast<u32b>(virt_range.GetVirtualBase()); ! return *reinterpret_cast<u16b*>(virt_address + address); } ! u32b mp_detect::DetectFloatingPointer(u32b start_address, u32b length) { ! u32b pbase = start_address &0xFFFFF000; ! u32b offset = start_address &0xFFF; ! u16b pages = (length + offset + 0xFFF)/4096; ! ! for(u16b i=0; i<pages; i++) { vRange virt_range(pbase + i*4096); ! u32b* vpage = static_cast<u32b*>(virt_range.GetVirtualBase()); ! for(u16b j=0; j<1024; j+=4) { ! SmpFloatingPointer* fp = reinterpret_cast<SmpFloatingPointer*>(&vpage[j]); ! ! if(fp->Magic == '_PM_') { // Calculate the checksume of the structure ! u08b checksum = 0x00; ! u08b* mp_float = reinterpret_cast<u08b*>(fp); ! for(u08b k=0; k<16; k++) checksum += mp_float[k]; if(checksum == 0) { ! if(fp->Table) { ! // Return a pointer to the configuration table if available ! config_table = reinterpret_cast<SmpConfigEntry*>(fp->Table); ! return fp->Table; } ! else { + // Return the number of the standard configuration used config_table = 0; ! return fp->Feature[0]; } } *************** *** 174,178 **** iterator it; it.address = config_table; ! it.entry = 0; it.last_entry = entry_count - 1; --- 180,184 ---- iterator it; it.address = config_table; ! it.entry = 0; it.last_entry = entry_count - 1; *************** *** 199,210 **** } ! uint mp_detect::GetNumberEntries(entry_type type) { ! uint counter = 0; ! ! for(iterator it = begin(type); it != end(); it++) ! { ! counter++; ! } return counter; } --- 205,212 ---- } ! u08b mp_detect::GetNumberEntries(entry_type type) { ! u08b counter = 0; ! for(iterator it = begin(type); it != end(); ++it) counter++; return counter; } *************** *** 220,224 **** } ! uint mp_detect::GetLocalApicID(iterator cpu) { return (static_cast<SmpConfigCPU*>(*cpu)->LocalApicID); --- 222,226 ---- } ! u08b mp_detect::GetLocalApicID(iterator cpu) { return (static_cast<SmpConfigCPU*>(*cpu)->LocalApicID); *************** *** 227,243 **** bool mp_detect::BootProcessor(iterator cpu) { ! heap().AllocateApStack(); ap_flag = 0; ! uint apic_id = GetLocalApicID(cpu); ! boot_hal->inter->SendInitIPI (apic_id); ! boot_hal->inter->SendStartupIPI(apic_id); ! boot_hal->inter->SendStartupIPI(apic_id); ! boot_hal->clock->SetTimer(timer_id(current), 0x1000000); // Check if the processor responds - if so, wait until it finished booting ! while(boot_hal->clock->GetTimer(timer_id(current)) > 0 && !(ap_flag &1)); while(ap_flag &1 && !(ap_flag &2)); --- 229,247 ---- bool mp_detect::BootProcessor(iterator cpu) { ! heap().AllocateMpStack(); ap_flag = 0; ! hal_object& hal = get_hal_object(); ! u08b apic_id = GetLocalApicID(cpu); ! // Start the INIT-SIPI-SIPI sequence ! hal(ipi).SendInitIPI(apic_id); ! hal(ipi).SendStartupIPI(apic_id); ! // hal(ipi).SendStartupIPI(apic_id); NOTE Caused problems on bochs when AP halts immediately ! hal(timer).SetTimer(timer_id(current), 0x1000000); // Check if the processor responds - if so, wait until it finished booting ! while(hal(timer).GetTimer(timer_id(current)) > 0 && !(ap_flag &1)); while(ap_flag &1 && !(ap_flag &2)); *************** *** 245,269 **** } ! uint mp_detect::BootAllProcessors() { ! bool result = true; ! uint num_cpu = 0; ! for(iterator entry = begin(TYPE_CPU); entry != end(); entry++) { if(!CheckBootstrap(entry) && !CheckDisabled(entry)) { ! result &= BootProcessor(entry); num_cpu++; } } ! return (result) ? num_cpu : 0; } ! uint mp_detect::EnableHyperthreading() { ! uint processors = 0; ! if(info().GetProcessorInfo().hyper_threading) { // On hyperthreading CPUs the APIC ID is split into two parts: package ID and logical ID --- 249,272 ---- } ! u08b mp_detect::BootAllProcessors() { ! u08b num_cpu = 0; ! for(iterator entry = begin(TYPE_CPU); entry != end(); ++entry) { if(!CheckBootstrap(entry) && !CheckDisabled(entry)) { ! BootProcessor(entry); num_cpu++; } } ! return num_cpu; } ! u08b mp_detect::EnableHyperthreading() { ! u08b processors = 0; ! if(get_hal_object()(info).GetProcessorInfo().hyper_threading) { // On hyperthreading CPUs the APIC ID is split into two parts: package ID and logical ID *************** *** 271,299 **** // the number of logical processors per physical package: log2(logical_per_package) // Get the number of logical processors per physical CPU ! uint number_logical = ((info().cpuid<cpu_info::EBX>(1) >> 16) &0xff); ! uint current_logical = boot_hal->lapic->GetPhysicalID() &(number_logical-1); if(current_logical++ == 0) // Primary CPU is always booted first { ! for(uint i = current_logical; i < number_logical; i++) { // Cyle through the logical processors and send an SIPI-SIPI_INIT sequence to each of them ! heap().AllocateApStack(); ap_flag = 0; ! uint apic_id = (boot_hal->lapic->GetPhysicalID() &(0xffffffff - (number_logical-1))) | i; ! boot_hal->inter->SendInitIPI (apic_id); ! boot_hal->inter->SendStartupIPI(apic_id); ! boot_hal->inter->SendStartupIPI(apic_id); ! boot_hal->clock->SetTimer(timer_id(current), 0x1000000); // Check if the processor responds - if so, wait until it finished booting ! while(boot_hal->clock->GetTimer(timer_id(current)) > 0 && !(ap_flag &1)); while(ap_flag &1 && !(ap_flag &2)); ! if(ap_flag) processors++; } } --- 274,305 ---- // the number of logical processors per physical package: log2(logical_per_package) + hal_object& hal = get_hal_object(); + // Get the number of logical processors per physical CPU ! u08b number_logical = ((get_hal_object()(info).cpuid<cpu_info::EBX>(1) >> 16) &0xff); ! u08b current_logical = hal(lapic).GetPhysicalID() &(number_logical-1); if(current_logical++ == 0) // Primary CPU is always booted first { ! for(u08b i=current_logical; i<number_logical; i++) { // Cyle through the logical processors and send an SIPI-SIPI_INIT sequence to each of them ! heap().AllocateMpStack(); ap_flag = 0; ! u08b apic_id = (hal(lapic).GetPhysicalID() &(0xffffffff - (number_logical-1))) | i; ! // Start the INIT-SIPI-SIPI sequence ! hal(ipi).SendInitIPI(apic_id); ! hal(ipi).SendStartupIPI(apic_id); ! // hal(ipi).SendStartupIPI(apic_id); NOTE Caused problems on bochs when AP halts immediately ! hal(timer).SetTimer(timer_id(current), 0x1000000); // Check if the processor responds - if so, wait until it finished booting ! while(hal(timer).GetTimer(timer_id(current)) > 0 && !(ap_flag &1)); while(ap_flag &1 && !(ap_flag &2)); ! processors++; } } *************** *** 310,315 **** iterator::iterator(const iterator& it) { ! address = it.address; ! entry = it.entry; last_entry = it.last_entry; } --- 316,321 ---- iterator::iterator(const iterator& it) { ! address = it.address; ! entry = it.entry; last_entry = it.last_entry; } *************** *** 318,332 **** { this->address = address; ! last_entry = entry = 0; } SmpConfigEntry* iterator::GetNext(SmpConfigEntry* current) { ! uchar* tmp = reinterpret_cast<uchar*>(current) + 8; ! ! if(current->Type == TYPE_CPU) ! { ! tmp += sizeof(SmpConfigCPU) - 8; ! } return reinterpret_cast<SmpConfigEntry*>(tmp); } --- 324,334 ---- { this->address = address; ! last_entry = entry = 0; } SmpConfigEntry* iterator::GetNext(SmpConfigEntry* current) { ! // CPU items are 20byte long, all others are 8bytes ! u08b* tmp = (current->Type == TYPE_CPU) ? (u08b*)current + 20 : (u08b*)current + 8; return reinterpret_cast<SmpConfigEntry*>(tmp); } *************** *** 334,348 **** bool iterator::operator==(iterator it) { ! return (entry == it.entry) ? true : false; } bool iterator::operator!=(iterator it) { ! return (entry != it.entry) ? true : false; } ! iterator iterator::operator++(int t) { ! uchar type = address->Type; while(entry <= last_entry) --- 336,350 ---- bool iterator::operator==(iterator it) { ! return entry == it.entry; } bool iterator::operator!=(iterator it) { ! return entry != it.entry; } ! iterator& iterator::operator++() { ! u08b type = address->Type; while(entry <= last_entry) *************** *** 357,360 **** --- 359,378 ---- } + iterator iterator::operator++(int t) + { + iterator temp = *this; + u08b type = address->Type; + + while(entry <= last_entry) + { + address = GetNext(address); + entry++; + + if(address->Type == type) + break; + } + return temp; + } + SmpConfigEntry* iterator::operator*() { Index: console.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/console.cpp,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** console.cpp 5 Apr 2006 17:12:56 -0000 1.9 --- console.cpp 24 Jun 2006 15:01:32 -0000 1.10 *************** *** 3,7 **** // // Author(s) : ! // Date : DD/MM/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net --- 3,7 ---- // // Author(s) : ! // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net *************** *** 38,52 **** // ----------------------------------------------------------------------- ! #include "console.hpp" ! #include "../hal/hal_object.hpp" ! #include "heap_manager.hpp" ! #include "../hal/mmu.hpp" ! char console::itoa_buffer[] = {'0', 'x', 0, 0, 0, 0, 0, 0, 0, 0, 0}; const char endl = '\n'; console::console() { ! x86_console = reinterpret_cast<uchar*>(heap().CreatePhysicalWindow(0xB8000)); x_offset = y_offset = 0; } --- 38,51 ---- // ----------------------------------------------------------------------- ! #include <console.hpp> ! #include <hal_object.hpp> ! char console::itoa_buffer[] = {'0', 'x', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; const char endl = '\n'; console::console() { ! window = heap().CreateObject<vRange>(0xB8000); ! x86_console = static_cast<u08b*>(window->GetVirtualBase()); x_offset = y_offset = 0; } *************** *** 56,62 **** EnterMutex(); ! for(int i=0; i<80*50; i++) ! x86_console[i] = 0; ! x_offset = y_offset = 0; --- 55,59 ---- EnterMutex(); ! memset(x86_console, &x86_console[80*50], u08b(0)); x_offset = y_offset = 0; *************** *** 67,71 **** { EnterMutex(); ! int index = 0; while(true) --- 64,68 ---- { EnterMutex(); ! u16b index = 0; while(true) *************** *** 83,87 **** else { ! x86_console[y_offset*160+x_offset*2] = string[index]; x86_console[y_offset*160+x_offset*2+1] = 9; x_offset++; --- 80,84 ---- else { ! x86_console[y_offset*160+x_offset*2+0] = string[index]; x86_console[y_offset*160+x_offset*2+1] = 9; x_offset++; *************** *** 97,112 **** // End of line - next line ! x_offset=0; y_offset++; } // End of the screen - move up one line ! int source = 160; ! int dest = 0; ! while(dest < 160*24) ! x86_console[dest++] = x86_console[source++]; ! while(dest < 160*25) ! x86_console[dest++] = 0; x_offset = 0; --- 94,107 ---- // End of line - next line ! x_offset = 0; y_offset++; } // End of the screen - move up one line ! u16b source = 160; ! u16b dest = 0; ! while(dest < 160*24) x86_console[dest++] = x86_console[source++]; ! while(dest < 160*25) x86_console[dest++] = 0; x_offset = 0; *************** *** 118,127 **** } ! console& console::operator<<(uint number) { EnterMutex(); ! int base = 16; ! for(int index = sizeof(itoa_buffer)-2; index > 1; index--) { char digit = number%base; --- 113,122 ---- } ! console& console::operator<<(u32b number) { EnterMutex(); ! u08b base = 16; ! for(u08b index = sizeof(itoa_buffer)-3; index > 1; index--) { char digit = number%base; *************** *** 138,144 **** console& console::operator<<(char character) { ! short buffer = character; ! operator<<(reinterpret_cast<const char*>(&buffer)); ! return *this; } --- 133,138 ---- console& console::operator<<(char character) { ! char dummy[] = { character , 0}; ! operator<<(dummy); return *this; } Index: console.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/console.hpp,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** console.hpp 5 Apr 2006 17:12:56 -0000 1.7 --- console.hpp 24 Jun 2006 15:01:32 -0000 1.8 *************** *** 41,55 **** #define __LOADER__CONSOLE__ ! #include "../object/std_types.hpp" ! #include "../hal/mutex.hpp" ! class console : mutex { private: ! uchar* x86_console; ! uchar x_offset; ! uchar y_offset; ! static char itoa_buffer[11]; public: --- 41,57 ---- #define __LOADER__CONSOLE__ ! #include <std_types.hpp> ! #include <heap_manager.hpp> ! #include <mutex.hpp> ! class console : private mutex { private: ! u08b x_offset, y_offset; ! u08b* x86_console; ! vRange* window; ! ! static char itoa_buffer[12]; public: *************** *** 60,64 **** console& operator<<(const char* string); console& operator<<(char character); ! console& operator<<(uint number); }; --- 62,66 ---- console& operator<<(const char* string); console& operator<<(char character); ! console& operator<<(u32b number); }; Index: heap_manager.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/heap_manager.hpp,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** heap_manager.hpp 2 Jun 2006 21:11:21 -0000 1.8 --- heap_manager.hpp 24 Jun 2006 15:01:32 -0000 1.9 *************** *** 41,85 **** #define __LOADER__HEAP_MANAGER__ ! #include "../object/std_types.hpp" ! #include "../hal/hal_object.hpp" ! extern "C" uint heap_address; class vRange { private: ! void* page_base; ! uint page_size; public: ! vRange(uint physical_base, uint number_pages = 1); ~vRange(); void* GetVirtualBase(); ! uint GetLength(); }; class heap_manager { - friend class vRange; - private: ! uint memory_base, memory_offset, memory_size; ! uint vspace_base, vspace_offset, vspace_size; ! uint vrange_base, pageframe; ! void* AllocateVirtualSpace(uint number_pages); ! void DelocateVirtualSpace(void* address, uint number_pages); public: ! heap_manager(); ! ~heap_manager(); ! void AllocateApStack(); ! hal_object* CreateHalObject(uint processor_number); ! void* AllocateMemory(uint size_bytes); ! void* CreatePhysicalWindow(uint physical_base, uint number_pages = 1); }; --- 41,97 ---- #define __LOADER__HEAP_MANAGER__ ! #include <std_types.hpp> ! #include <hal_object.hpp> ! extern "C" u32b heap_address; ! extern "C" u32b sizeof_hobject_cpp; ! ! class memory_stack ! { ! private: ! u32b stack[32]; ! u16b stack_pointer, stack_underflow; ! ! public: ! memory_stack(u32b heap_begin); ! ! u32b AllocatePage(); ! void DelocatePage(u32b base_address); ! }; class vRange { private: ! u32b page_base, page_size; public: ! vRange(u32b physical_base); ~vRange(); void* GetVirtualBase(); ! u32b GetLength(); }; class heap_manager { private: ! u32b memory_base, memory_left; ! u32b GetStackBase(); ! void RefreshWindow(); public: ! heap_manager(u32b initial_heap); ! void* AllocateMemory(u32b size_bytes); ! void AllocateMpStack(); ! template<class T, class P> T* heap_manager::CreateObject(P parameter) ! { return reinterpret_cast<T*>(new (AllocateMemory(sizeof(T))) T(parameter)); } ! template<class T> T* heap_manager::CreateObject() ! { return reinterpret_cast<T*>(new (AllocateMemory(sizeof(T))) T()); } ! ! hal_object* CreateHalObject(u08b processor); }; *************** *** 87,89 **** --- 99,107 ---- heap_manager& heap(); + extern char virt_allocator_reserved[]; + extern char phys_allocator_reserved[]; + + memory_stack& virtual_allocator(); + memory_stack& physical_allocator(); + #endif Index: heap_manager.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/heap_manager.cpp,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** heap_manager.cpp 2 Jun 2006 21:11:21 -0000 1.11 --- heap_manager.cpp 24 Jun 2006 15:01:32 -0000 1.12 *************** *** 38,219 **** // ----------------------------------------------------------------------- ! #include "heap_manager.hpp" ! #include "../hal/mmu.hpp" ! #include "console.hpp" ! vRange::vRange(uint physical_base, uint number_pages) { ! page_base = heap().AllocateVirtualSpace(number_pages); ! page_size = number_pages; ! for(uint i=0; i<page_size; i++) ! { ! uint current_page = reinterpret_cast<uint>(page_base) + i*1024; ! boot_hal->memory->MapPage(reinterpret_cast<void*>(current_page), physical_base + i*4096); ! } } ! vRange::~vRange() { ! for(uint i=0; i<page_size; i++) { ! uint current_page = reinterpret_cast<uint>(page_base) + i*1024; ! boot_hal->memory->UmapPage(reinterpret_cast<void*>(current_page)); } ! heap().DelocateVirtualSpace(page_base, page_size); } ! void* vRange::GetVirtualBase() { ! return page_base; } ! uint vRange::GetLength() { ! return page_size*4096; } ! heap_manager::heap_manager() { ! pageframe = heap_address + 4096; ! ! memory_base = heap_address + 0xDFF00000 - 12288; ! memory_offset = 0; ! memory_size = 4096; ! ! vspace_base = vspace_size = vspace_offset = 0; ! vrange_base = 0xE0000000 + 4096*1024; } ! heap_manager::~heap_manager() { ! // TODO - Pass control to the object allocator } ! void heap_manager::AllocateApStack() // Has to be called for each AP to update the ASM heap-pointer { ! heap_address = reinterpret_cast<uint>(CreatePhysicalWindow(0x00000000)) + 4096; ! boot_hal->memory->MapPage(reinterpret_cast<void*>(heap_address), pageframe); ! ! pageframe += 4192; } ! hal_object* heap_manager::CreateHalObject(uint processor_number) { ! uchar* hal_reserved = static_cast<uchar*>(AllocateMemory(sizeof(hal_object))); ! ! // Initialize the hal-object structure with all zeroes ! for(uint i=0; i < sizeof(hal_object); i++) ! hal_reserved[i] = 0x00; ! // Fill in the structure's header ! uint stack_base = 0x00000000; asm("mov %%esp, %%eax" : "=a"(stack_base)); - stack_base = (stack_base + 0xfff) &0xfffff000; ! hal_object* hal = reinterpret_cast<hal_object*>(hal_reserved); ! hal->processor_number = processor_number; ! hal->kernel_stack_base = stack_base; ! ! return hal; } ! void* heap_manager::AllocateVirtualSpace(uint number_pages) { ! uint length = number_pages*4096; ! ! uint memory = memory_base + memory_size; ! uint address = vspace_base + vspace_size; ! ! uint hi_grow = (memory > address) ? memory : address; ! if(vrange_base - length < hi_grow) ! { ! cout() << "Panic: Too many objects created (loader/heap_manager -> AllocateVirtualSpace)"; ! while(true); ! } ! vrange_base -= length; ! return reinterpret_cast<void*>(vrange_base); } ! void heap_manager::DelocateVirtualSpace(void* address, uint number_pages) { ! if(reinterpret_cast<uint>(address) != vrange_base) { ! cout() << "Panic: Memory leak detected (loader/heap_manager -> DelocateVirtualSpace)"; while(true); } ! vrange_base += number_pages*4096; } ! void* heap_manager::AllocateMemory(uint size_bytes) { ! // All objects will be created on a 8byte aligned addresses to speed up memory access ! uint align = ((memory_base + memory_offset + 7) &0xFFFFFFF8) - (memory_base + memory_offset); ! ! while(size_bytes + align > memory_size - memory_offset) ! { ! if(memory_base > vspace_base) ! { ! boot_hal->memory->MapPage((void*)(memory_base + memory_size), pageframe); ! ! memory_size += 4096; ! pageframe += 4096; ! } ! else ! { ! // Jump over the virtual memory section.. ! memory_base = vspace_base + vspace_size; ! memory_size = memory_offset = align = 0; ! } ! if(memory_base + memory_size > vrange_base) ! { ! cout() << "Panic: Too many objects created (/loader/heap_manager -> AllocateMemory)"; ! while(true); ! } ! } ! memory_offset += size_bytes + align; ! return reinterpret_cast<void*>(memory_base + memory_offset - size_bytes); } ! void* heap_manager::CreatePhysicalWindow(uint physical_base, uint number_pages) { ! uint length = number_pages*4096; ! ! for(uint i=0; length > vspace_size - vspace_offset; i++) ! { ! if(vspace_base > memory_base) ! { ! void* window_address = reinterpret_cast<void*>(vspace_base + vspace_size); ! boot_hal->memory->MapPage(window_address, physical_base, 0x10); ! ! vspace_size += 4096; ! physical_base += 4096; ! } ! else ! { ! vspace_base = memory_base + memory_size; ! vspace_offset = vspace_size = 0; ! } ! ! if(vspace_base + vspace_size > vrange_base) ! { ! cout() << "Panic: Too many objects created (/loader/heap_manager -> ReserveVirtualSpace)"; ! while(true); ! } ! } ! vspace_offset += length; ! return reinterpret_cast<void*>(vspace_base + vspace_offset - length); } char heap_manager_reserved[sizeof(heap_manager)]; heap_manager& heap() { return (reinterpret_cast<heap_manager&>(heap_manager_reserved)); } --- 38,175 ---- // ----------------------------------------------------------------------- ! #include <heap_manager.hpp> ! #include <mmu.hpp> ! #include <console.hpp> ! ! memory_stack::memory_stack(u32b heap_begin) { ! // Initialize the stack with sequential addresses ! for(u08b i=0; i<32; i++) stack[i] = heap_begin + 4096*i; ! stack_pointer = 0; // first element ! stack_underflow = 32; // last + 1 } ! u32b memory_stack::AllocatePage() { ! if(stack_pointer == stack_underflow) { ! cout() << "Panic: Ran out of virtual memory"; ! while(true); } ! return stack[stack_pointer++]; } ! void memory_stack::DelocatePage(u32b base_address) { ! stack[--stack_pointer] = base_address; } ! vRange::vRange(u32b physical_base) { ! page_base = virtual_allocator().AllocatePage(); ! page_size = 4096; ! ! get_hal_object()(memory)(page_base) = memory_mapper::kernel_mode(physical_base); } ! vRange::~vRange() { ! get_hal_object()(memory)(page_base) -= map_item(0).Present(); ! virtual_allocator().DelocatePage(page_base); } ! void* vRange::GetVirtualBase() { ! return reinterpret_cast<void*>(page_base); } ! u32b vRange::GetLength() { ! return page_size; } ! heap_manager::heap_manager(u32b initial_heap) { ! memory_base = initial_heap; ! memory_left = 4096 - sizeof_hobject_cpp; ! } ! u32b heap_manager::GetStackBase() ! { ! u32b stack_base(0); asm("mov %%esp, %%eax" : "=a"(stack_base)); ! return (stack_base + 0xfff) &0xfffff000; } ! void heap_manager::RefreshWindow() { ! u32b phys_page = physical_allocator().AllocatePage(); ! u32b virt_page = virtual_allocator().AllocatePage(); ! get_hal_object()(memory)(virt_page) = memory_mapper::kernel_mode(phys_page); ! memory_base = virt_page; ! memory_left = 4096; } ! void* heap_manager::AllocateMemory(u32b size_bytes) { ! // Aligning the allocation size increases performance ! size_bytes = (size_bytes + 7) &0xFFFFFFF8; ! ! if(size_bytes > 4096) { ! cout() << "Panic: heap-manager doesn't support allocations > 4096 byte"; while(true); } + if(memory_left < size_bytes) + RefreshWindow(); ! void* tmp = reinterpret_cast<void*>(memory_base); ! ! memory_base += size_bytes; ! memory_left -= size_bytes; ! return tmp; } ! void heap_manager::AllocateMpStack() { ! // Allocate a new page for the stack & map it in ! u32b phys_page = physical_allocator().AllocatePage(); ! u32b virt_page = virtual_allocator().AllocatePage(); ! get_hal_object()(memory)(virt_page) = memory_mapper::kernel_mode(phys_page); ! heap_address = virt_page + 4096; // Variable used by the loader } ! hal_object* heap_manager::CreateHalObject(u08b processor) { ! u32b hal_location = GetStackBase() - sizeof_hobject_cpp; ! new ((void*)hal_location) hal_object(processor, GetStackBase()); ! return reinterpret_cast<hal_object*>(hal_location); } char heap_manager_reserved[sizeof(heap_manager)]; + char virt_allocator_reserved[sizeof(memory_stack)]; + char phys_allocator_reserved[sizeof(memory_stack)]; + heap_manager& heap() { return (reinterpret_cast<heap_manager&>(heap_manager_reserved)); } + + memory_stack& virtual_allocator() + { + return (reinterpret_cast<memory_stack&>(virt_allocator_reserved)); + } + + memory_stack& physical_allocator() + { + return (reinterpret_cast<memory_stack&>(phys_allocator_reserved)); + } Index: entry.asm =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/entry.asm,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** entry.asm 2 Jun 2006 21:11:21 -0000 1.11 --- entry.asm 24 Jun 2006 15:01:32 -0000 1.12 *************** *** 49,52 **** --- 49,54 ---- global ap_code_end ; to boot the application cpus + global sizeof_hobject_cpp + section .text bits 32 *************** *** 80,87 **** USER_MODE equ 7 ; ring3 | present | read&write bsp_entrypoint: ! ; Set up a stack and push the information passed to us by GRUB on it mov esp, [heap_address - salt] add esp, stack_addr + 4096 mov ecx, [cpu_id - salt] mov edx, kernel_end --- 82,95 ---- USER_MODE equ 7 ; ring3 | present | read&write + sizeof_hobject_asm equ 32*4 ; Assumed size (needed for memory reservation) + sizeof_hobject_cpp dd 32*4 + bsp_entrypoint: ! ; Set up a stack and reserve some memory for the hal-object mov esp, [heap_address - salt] add esp, stack_addr + 4096 + sub esp, sizeof_hobject_asm + + ; Push the information passed to us by GRUB on the stack mov ecx, [cpu_id - salt] mov edx, kernel_end *************** *** 120,124 **** loop $-6 ! ; Append a pages for the stack and another one for idt & hal at the end of the kernel mov eax, [heap_address - salt] add eax, stack_addr + SUPERVISOR --- 128,132 ---- loop $-6 ! ; Append a page for the stack and another one for the heap at the end of the kernel mov eax, [heap_address - salt] add eax, stack_addr + SUPERVISOR *************** *** 174,178 **** add eax, salt - 12288 mov ebp, eax ! sub eax, 16 mov esp, eax --- 182,186 ---- add eax, salt - 12288 mov ebp, eax ! sub eax, 16 + sizeof_hobject_asm mov esp, eax *************** *** 190,195 **** cld ! push cs ! pop ds lgdt [ap_gdt_selector - ap_code_start] ; Auto-relocatable since cs=ds, and AP's start at EIP=0 --- 198,203 ---- cld ! mov ax, cs ! mov ds, ax lgdt [ap_gdt_selector - ap_code_start] ; Auto-relocatable since cs=ds, and AP's start at EIP=0 *************** *** 232,235 **** --- 240,244 ---- mov eax, [heap_address] mov esp, eax + sub eax, sizeof_hobject_asm mov ebp, eax |
Update of /cvsroot/trion/trion v0.2/hal In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv1331 Modified Files: apic_io.cpp apic_io.hpp apic_local.cpp apic_local.hpp cpu_info.cpp cpu_info.hpp exception.cpp exception.hpp hal_object.hpp idt.cpp idt.hpp interrupt.cpp interrupt.hpp interrupt_stub.cpp interrupt_stub.hpp interrupt_stub_code.asm ipi.cpp ipi.hpp irq.cpp irq.hpp mmu.cpp mmu.hpp mutex.cpp mutex.hpp ports.cpp ports.hpp systemcall.cpp systemcall.hpp systemcall_stub_code.asm task_context.cpp task_context.hpp timer.cpp timer.hpp Added Files: gdt.cpp gdt.hpp hal_object.cpp Log Message: no message --- NEW FILE: gdt.hpp --- // ----------------------------------------------------------------------- // gdt.hpp - Allows new entries to be added to the gdt // // Author(s) : // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. 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. // 3. Neither the name of the Trion Development Group nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT // OWNER OR CONTRIBUTORS 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. // ----------------------------------------------------------------------- #ifndef __HAL__GDT__ #define __HAL__GDT__ #include <std_types.hpp> struct gdt_register { u16b limit; u32b* base; }__attribute__((__packed__)); struct gdt_entry_lo { u16b limit0 : 16; u16b base0 : 16; }; struct gdt_entry_hi { u08b base1 : 8; enum descriptor_type { data_read = 0, data_write = 2, execute = 8, task_segment = 9 } type : 5; u08b ring : 2; bool present : 1; u08b limit1 : 4; u08b : 2; bool size32bit : 1; bool granularity : 1; u08b base2 : 8; }; class gdt_table { private: u32b* gdt_pointer; u08b gdt_limit; public: gdt_table(); ~gdt_table(); // Creation of a new gdt entry in a free slot, entry number is returned u08b CreateDescriptor(gdt_entry_hi::descriptor_type type, u32b base, u32b length); void RemoveDescriptor(u08b descriptor_number); // Alter an already existing descriptor entry void SetDescriptorType(u08b descriptor_number, gdt_entry_hi::descriptor_type type); void SetDescriptorBase(u08b descriptor_number, u32b base); void SetDescriptorLimit(u08b descriptor_number, u32b limit); u08b GetNumberEntries(); }; #endif Index: hal_object.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/hal_object.hpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** hal_object.hpp 2 Jun 2006 21:10:17 -0000 1.6 --- hal_object.hpp 24 Jun 2006 15:00:02 -0000 1.7 *************** *** 41,60 **** #define __HAL__HAL_OBJECT__ struct hal_object { ! uint processor_number; ! uint kernel_stack_base; ! class idt* vector; ! class local_apic* lapic; ! class exception* faults; ! class ipi* inter; ! class timer* clock; ! class mmu* memory; ! class systemcall* syscall; ! class task_context* context; }; ! // Points to the hal object of the processor that currently boots ! extern hal_object* boot_hal; // - BSP may use it until BootAllProcessors() gets called ! // - APs can depend on it until they set the boot_complete flag #endif --- 41,120 ---- #define __HAL__HAL_OBJECT__ + #include <std_types.hpp> + struct hal_object { ! private: ! class local_apic* p_lapic; ! class cpu_info* p_info; ! class exception* p_exceptions; ! class apic_timer* p_timer; ! class systemcall* p_syscall; ! class idt_table* p_idt; ! class gdt_table* p_gdt; ! ! class cpu_messages* p_ipi; ! class memory_mapper* p_memory; ! class port_protect* p_port; ! class task_context* p_context; ! ! u32b cpu_id, stack; ! ! public: ! hal_object(u32b processor, u32b stack_base) : cpu_id(processor), stack(stack_base) {} ! ! template<class R> R& operator()(R& (*function)()) { return (*function)(); } ! ! // Methodes to access the hal_object classes ! inline local_apic& m_lapic() { return *p_lapic; } ! inline cpu_info& m_info() { return *p_info; } ! inline exception& m_exceptions() { return *p_exceptions; } ! inline apic_timer& m_timer() { return *p_timer; } ! inline systemcall& m_syscall() { return *p_syscall; } ! ! inline idt_table& m_idt() { return *p_idt; } ! inline gdt_table& m_gdt() { return *p_gdt; } ! ! inline cpu_messages& m_ipi() { return *p_ipi; } ! inline memory_mapper& m_memory() { return *p_memory; } ! inline port_protect& m_port() { return *p_port; } ! inline task_context& m_context() { return *p_context; } ! ! // Methods to set the hal-class pointers ! inline void set_lapic(local_apic* p) { p_lapic = p; } ! inline void set_info(cpu_info* p) { p_info = p; } ! inline void set_exceptions(exception* p) { p_exceptions = p; } ! inline void set_timer(apic_timer* p) { p_timer = p; } ! inline void set_syscall(systemcall* p) { p_syscall = p; } ! ! inline void set_idt(idt_table* p) { p_idt = p; } ! inline void set_gdt(gdt_table* p) { p_gdt = p; } ! ! inline void set_ipi(cpu_messages* p) { p_ipi = p; } ! inline void set_memory(memory_mapper* p) { p_memory = p; } ! inline void set_port(port_protect* p) { p_port = p; } ! inline void set_context(task_context* p) { p_context = p; } ! ! // Methods to read-out processor specific information ! inline u32b GetProcessorID() { return cpu_id; } ! inline u32b GetStackBase() { return stack; } }; ! ! extern hal_object& get_hal_object(); ! ! extern local_apic& lapic(); ! extern cpu_info& info(); ! extern exception& exceptions(); ! extern apic_timer& timer(); ! extern systemcall& syscall(); ! ! extern idt_table& idt(); ! extern gdt_table& gdt(); ! ! extern cpu_messages& ipi(); ! extern memory_mapper& memory(); ! extern port_protect& port(); ! extern task_context& context(); ! #endif Index: mmu.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/mmu.hpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** mmu.hpp 2 Jun 2006 21:10:18 -0000 1.4 --- mmu.hpp 24 Jun 2006 15:00:02 -0000 1.5 *************** *** 41,79 **** #define __HAL__MMU__ ! #include "../object/std_types.hpp" ! extern "C" void invalidatePage(uint); ! class mmu { private: ! uint pagedirectory; ! static const uint ENTRY_ACCESSED = 32; ! static const uint ENTRY_DIRTY = 64; public: ! mmu(uint directory = 0); ! ~mmu(); ! void CreatePageTable(void* virtual_base, uint phys_table_address, uint flags = 3); ! bool PagetableExists(void* virtual_base); ! void RemovePageTable(void* virtual_base); ! void MapPage(void* virtual_address, uint phys_address, uint flags = 3); ! void UmapPage(void* virtual_address); ! void* CreateDirtyMap(void* map, void* virtual_base, uint number_entries); ! void* CreateAccessedMap(void* map, void* virtual_base, uint number_entries, bool tables = false); ! uint GetPageDirectory(); ! static const uint GLOBAL_PAGE = 256; ! static const uint CACHE_DISABLED = 16; ! static const uint WRITE_THROUGH = 8; ! static const uint USER_MODE = 4; ! static const uint KERNEL_MODE = 0; ! static const uint READ_WRITE = 2; ! static const uint READ_ONLY = 0; }; --- 41,132 ---- #define __HAL__MMU__ ! #include <std_types.hpp> ! struct page_structure ! { ! bool present : 1; ! bool read_write : 1; ! bool user_mode : 1; ! bool PAT0 : 1; ! bool PAT1 : 1; ! bool accessed : 1; ! bool dirty : 1; ! bool PAT2 : 1; // 4MB pages bit for page-tables ! bool global : 1; ! bool : 3; ! u32b physical : 20; ! }; ! class map_item { private: ! friend class map_target; ! bf32<page_structure> entry; ! bool zero_tables; // Set by default, must get uncheck before copying tables public: ! explicit map_item(u32b init = 0); ! map_item(bf32<page_structure> init); ! // Modifiers to set additional flags ! map_item& Physical(u32b address); ! map_item& Write(); ! map_item& UserMode(); ! map_item& Pages4MB(); ! map_item& PAT(u08b number); ! map_item& Global(); ! map_item& Present(); ! // More convenient way of assigning an address ! map_item& operator()(u32b physical); ! }; ! class map_target ! { ! private: ! u16b table_number, page_number; ! bool is_table; ! void InvalidatePage(u32b address); ! public: ! map_target(u16b table, u16b page, bool page_table); ! ! map_target& operator[](u32b index); ! ! map_target& operator=(map_item item); // Assigns map_items to paging structures ! map_target& operator=(map_target target); // Allows the copying of pages/page-tables ! ! map_target& operator+=(map_item item); // Add or remove certain flags of the page ! map_target& operator-=(map_item item); ! }; ! ! class memory_mapper ! { ! private: ! u32b pagedirectory; // Physical address of the page-directory ! ! public: ! memory_mapper(u32b directory = 0); ! ~memory_mapper(); ! ! // Standard flag combinations that are often needed ! static map_item user_mode(u32b physical); ! static map_item user_read(u32b physical); ! ! static map_item kernel_mode(u32b physical); ! static map_item kernel_read(u32b physical); ! ! static map_item device_regs(u32b physical); ! ! // Dirty and accessed bits may be required by some user-mode pager ! u32b* CreateDirtyMap(u32b* map, u32b virtual_base, u32b number_pages); ! u32b* CreateAccessedMap(u32b* map, u32b virtual_base, u32b number_pages); ! ! u32b GetPageDirectory() { return pagedirectory; } // Used in conjunction with task_context ! ! map_target operator[](u32b index); // 2D access -> page_table : page_index ! map_target operator()(u32b address); // pages only -> absolute address }; Index: systemcall.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/systemcall.hpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** systemcall.hpp 2 Jun 2006 21:10:18 -0000 1.2 --- systemcall.hpp 24 Jun 2006 15:00:03 -0000 1.3 *************** *** 41,45 **** #define __HAL__SYSTEMCALL__ ! #include "../object/std_types.hpp" struct message_register --- 41,45 ---- #define __HAL__SYSTEMCALL__ ! #include <std_types.hpp> struct message_register *************** *** 47,51 **** // htask sender_receiver; void* message_pointer; ! uint message_length; bool asynchronous; --- 47,51 ---- // htask sender_receiver; void* message_pointer; ! u32b message_length; bool asynchronous; *************** *** 54,72 **** }; class systemcall { private: ! static const uint SYSENTER_CS_MSR = 0x174; ! static const uint SYSENTER_ESP_MSR = 0x175; ! static const uint SYSENTER_EIP_MSR = 0x176; ! void PatchAddress(void* stub_base, uint offset, uint value); ! void PatchRelativeCall(void* stub_base, uint offset, void* handler); public: systemcall(); ! void SystemcallDispatcher(message_register* msg, uint* esp, uint eip); ! void InvokeUserTask(uint instruction_pointer, uint stack_pointer); }; --- 54,82 ---- }; + struct instruction + { + u08b opcode; + u32b address; + + }__attribute__((__packed__)); + class systemcall { private: ! typedef void (systemcall::*method)(message_register*); ! typedef void (*flat)(systemcall*, message_register*); ! instruction* GetInstruction(u16b offset); ! ! void PatchRelativeCall(instruction* opcode, flat handler); ! flat ExtractRelativeCall(instruction* opcode); ! ! u32b stub_code; // Points to the beginning of this instance's stub-code public: systemcall(); ! void SystemcallDispatcher(message_register* msg, u32b esp, u32b eip); ! void InvokeUserTask(u32b instruction_pointer, u32b stack_pointer); }; Index: exception.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/exception.cpp,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** exception.cpp 2 Jun 2006 21:10:17 -0000 1.9 --- exception.cpp 24 Jun 2006 15:00:02 -0000 1.10 *************** *** 38,43 **** // ----------------------------------------------------------------------- ! #include "exception.hpp" ! #include "../loader/console.hpp" bool exception::error_code_map[] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1}; --- 38,43 ---- // ----------------------------------------------------------------------- ! #include <exception.hpp> ! #include <console.hpp> bool exception::error_code_map[] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1}; *************** *** 47,54 **** { // Install a standard handler for exceptions and reserved interrupts ! for(uint i=0; i<=32; i++) ! { ! AddReserved(i, this, (method)&exception::ReservedInterrupt); ! } // Overwrite std-handler for the most important exceptions --- 47,51 ---- { // Install a standard handler for exceptions and reserved interrupts ! for(u08b i=0; i<32; i++) AddReserved(i, this, (method)&exception::ReservedInterrupt); // Overwrite std-handler for the most important exceptions *************** *** 57,69 **** // Enable the APIC error interrupt and assign a vector to it ! uint apic_error_vector = 255 - 0; ! lapic_lvt lvt = GetLVT(lapic_reg(LVTERR)); ! lvt.masked = false; ! lvt.vector = apic_error_vector; ! SetLVT(lapic_reg(LVTERR), lvt); // Assign a vector to the spurious interupt ! uint spurious_vector = 255 - 1; WriteRegister(lapic_reg(SIVR), ReadRegister(lapic_reg(SIVR)) | spurious_vector); --- 54,66 ---- // Enable the APIC error interrupt and assign a vector to it ! u08b apic_error_vector = 255 - 0; ! bf32<lapic_lvt> lvt = ReadRegister(lapic_reg(LVTERR)); ! lvt->masked = false; ! lvt->vector = apic_error_vector; ! WriteRegister(lapic_reg(LVTERR), lvt); // Assign a vector to the spurious interupt ! u08b spurious_vector = 255 - 1; WriteRegister(lapic_reg(SIVR), ReadRegister(lapic_reg(SIVR)) | spurious_vector); *************** *** 92,107 **** } ! bool exception::AddHandler(uint number, exception* p_class, method handler) { interrupt::AddHandler(number, false, p_class, handler, error_code_map[number], trap_gate_map[number]); } ! bool exception::AddReserved(uint number, exception* p_class, method handler) { interrupt::AddHandler(number, true, p_class, handler, false, false); } ! void exception::InterruptConstructor(hal_object* hal, uchar interrupt_number, uint* esp) { if(handler_running) { --- 89,105 ---- } ! bool exception::AddHandler(u08b number, exception* p_class, method handler) { interrupt::AddHandler(number, false, p_class, handler, error_code_map[number], trap_gate_map[number]); } ! bool exception::AddReserved(u08b number, exception* p_class, method handler) { interrupt::AddHandler(number, true, p_class, handler, false, false); } ! void exception::InterruptEntrypoint(u08b interrupt_number, flat handler, u32b esp) { + // Forbid nested exception handlers if(handler_running) { *************** *** 111,133 **** handler_running = true; exception_number = interrupt_number; ! error_code = 0; ! general_regs = reinterpret_cast<general_registers*>(&esp[1]); ! segment_regs = reinterpret_cast<segment_registers*>(&esp[9]); if(exception_number <= 0x20 && error_code_map[exception_number]) { ! segment_regs = reinterpret_cast<segment_registers*>(&esp[10]); error_code++; } ! } ! void exception::InterruptDestructor(hal_object* hal, uchar interrupt_number, uint* esp) ! { handler_running = false; } ! void exception::DivideByZero(hal_object* hal) { cout() << endl << "Panic: An divide-by-zero exception was reported" << endl; --- 109,132 ---- handler_running = true; + // Collect all necessary information for the handler exception_number = interrupt_number; ! error_code = 0; ! u32b* stack_pointer = reinterpret_cast<u32b*>(esp); ! general_regs = reinterpret_cast<general_registers*>(&stack_pointer[1]); ! segment_regs = reinterpret_cast<segment_registers*>(&stack_pointer[9]); if(exception_number <= 0x20 && error_code_map[exception_number]) { ! segment_regs = reinterpret_cast<segment_registers*>(&stack_pointer[10]); error_code++; } ! (*handler)(this); //Call the interrupt service routine ! // Clean-up handler_running = false; } ! void exception::DivideByZero() { cout() << endl << "Panic: An divide-by-zero exception was reported" << endl; *************** *** 137,145 **** } ! void exception::PageFault(hal_object* hal) { ! // Get the address causing the exception from cr2 ! uint fault_address(0); ! asm("movl %%cr2, %%eax" : "=a"(fault_address)); cout() << endl << "Panic: A pagefault was reported (" << fault_address << ")" << endl; --- 136,143 ---- } ! void exception::PageFault() { ! // Get the address that caused the exception from cr2 ! u32b fault_address(0); asm("movl %%cr2, %%eax" : "=a"(fault_address)); cout() << endl << "Panic: A pagefault was reported (" << fault_address << ")" << endl; *************** *** 149,153 **** } ! uint exception::GetApicErrorCode() { // Write to the register to update it, then read it out --- 147,151 ---- } ! u32b exception::GetApicErrorCode() { // Write to the register to update it, then read it out *************** *** 158,167 **** void exception::ClearApicErrorCode() { ! // Two sucessive writes clear the error register WriteRegister(lapic_reg(ESR), 0); WriteRegister(lapic_reg(ESR), 0); } ! void exception::ApicError(hal_object* hal) { cout() << "Panic: A local APIC error was reported (" << GetApicErrorCode() << ")"; --- 156,165 ---- void exception::ClearApicErrorCode() { ! // Two sucessive writes clear the error-register WriteRegister(lapic_reg(ESR), 0); WriteRegister(lapic_reg(ESR), 0); } ! void exception::ApicError() { cout() << "Panic: A local APIC error was reported (" << GetApicErrorCode() << ")"; *************** *** 169,173 **** } ! void exception::SpuriousInterrupt(hal_object* hal) { cout() << "Panic: A spurious interrupt was reported"; --- 167,171 ---- } ! void exception::SpuriousInterrupt() { cout() << "Panic: A spurious interrupt was reported"; *************** *** 175,179 **** } ! void exception::ReservedInterrupt(hal_object* hal) { cout() << endl << "Panic: An unknown exception was reported ("; --- 173,177 ---- } ! void exception::ReservedInterrupt() { cout() << endl << "Panic: An unknown exception was reported ("; --- NEW FILE: hal_object.cpp --- // ----------------------------------------------------------------------- // hal_object.cpp - Contains pointers to all of the CPU's hal objects // // Author(s) : // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. 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. // 3. Neither the name of the Trion Development Group nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT // OWNER OR CONTRIBUTORS 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. // ----------------------------------------------------------------------- #include <hal_object.hpp> extern const u32b sizeof_hobject_cpp; hal_object& get_hal_object() { // Calculate the location of the hal-object u32b stack_base (0); asm("mov %%esp, %%eax" : "=a"(stack_base)); u32b hal = ((stack_base + 0xfff) &0xfffff000) - sizeof_hobject_cpp; return *reinterpret_cast<hal_object*>(hal); } local_apic& lapic() { return get_hal_object().m_lapic(); } cpu_info& info() { return get_hal_object().m_info(); } exception& exceptions() { return get_hal_object().m_exceptions(); } apic_timer& timer() { return get_hal_object().m_timer(); } systemcall& syscall() { return get_hal_object().m_syscall(); } idt_table& idt() { return get_hal_object().m_idt(); } gdt_table& gdt() { return get_hal_object().m_gdt(); } cpu_messages& ipi() { return get_hal_object().m_ipi(); } memory_mapper& memory() { return get_hal_object().m_memory(); } port_protect& port() { return get_hal_object().m_port(); } task_context& context() { return get_hal_object().m_context(); } Index: task_context.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/task_context.hpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** task_context.hpp 2 Jun 2006 21:10:18 -0000 1.1 --- task_context.hpp 24 Jun 2006 15:00:03 -0000 1.2 *************** *** 41,72 **** #define __HAL__TASK_CONTEXT__ ! #include "../object/std_types.hpp" ! #include "mmu.hpp" ! #include "ports.hpp" struct task_switch_segment { ! uint prev_task; ! ! uint esp0, ss0; ! uint esp1, ss1; ! uint esp2, ss2; ! uint cr3, eip, eflags; ! uint eax, ecx, edx, ebx; ! uint esp, ebp, esi, edi; ! uint es, cs, ss, ds, fs, gs; ! uint ldt_selector; ! ushort debug_trap, io_map; ! } __attribute__((__packed__)); ! struct gdt_register ! { ! ushort limit; ! uint base; } __attribute__((__packed__)); --- 41,66 ---- #define __HAL__TASK_CONTEXT__ ! #include <std_types.hpp> struct task_switch_segment { ! task_switch_segment(); ! task_switch_segment(u08b stack_selector, u32b stack_pointer, u16b io_bitmap); ! u32b prev_task; ! u32b esp0, ss0; ! u32b esp1, ss1; ! u32b esp2, ss2; ! u32b cr3, eip, eflags; ! u32b eax, ecx, edx, ebx; ! u32b esp, ebp, esi, edi; ! u32b es, cs, ss, ds, fs, gs; ! u32b ldt_selector; ! u16b debug_trap, io_map; } __attribute__((__packed__)); *************** *** 75,92 **** { private: ! task_switch_segment tss; ! ! void InitializeTaskSegment(uint stack_descriptor, uint stack_pointer); ! uint FindAvailableGDTSlot(); ! void CreateTaskDescriptor(uint gdt_slot); ! void SetTaskRegister(uint descriptor_number); ! void SetKernelStack(uint stack_pointer); public: task_context(); ! void SetPageDirectory(mmu* context); ! void SetPortMap(ports* context); }; --- 69,83 ---- { private: ! task_switch_segment default_task_segment; ! u08b descriptor; ! void SetTaskDescriptor(task_switch_segment* task_segment, bool port_bitmap); ! void SetTaskRegister(u08b descriptor_number); public: task_context(); ! void SetPageDirectory(u32b* page_directory); ! void SetPortMap(u32b* port_bitmap = 0); }; Index: timer.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/timer.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** timer.cpp 5 Apr 2006 17:12:00 -0000 1.3 --- timer.cpp 24 Jun 2006 15:00:03 -0000 1.4 *************** *** 38,143 **** // ----------------------------------------------------------------------- ! #include "timer.hpp" ! #include "../loader/console.hpp" ! timer::timer() : local_apic() { SetTimerDiv(timer_div(TDR_8)); } ! timer::~timer() { } ! uchar timer::GetTimerVector(void) { ! return GetLVT(lapic_reg(LVTT)).vector; } ! void timer::SetTimerVector(uchar vector) { ! lapic_lvt lvt = GetLVT(lapic_reg(LVTT)); ! lvt.vector = vector; ! SetLVT(lapic_reg(LVTT), lvt); } ! uchar timer::GetTimerDiv(void) { ! return ReadRegister(lapic_reg(TDCR)) &0x0b; } ! void timer::SetTimerDiv(timer_div div) { WriteRegister(lapic_reg(TDCR), div); } ! uint timer::GetInitialCount(void) { return ReadRegister(lapic_reg(TIC)); } ! uint timer::GetCurrentCount(void) { return ReadRegister(lapic_reg(TCC)); } ! void timer::StartPeriodicTimer(uint ticks, bool interrupt) { // asm volatile ("cli"); ! lapic_lvt lvt = GetLVT(lapic_reg(LVTT)); if(interrupt) { ! lvt.periodic = true; ! lvt.masked = false; } else { ! lvt.periodic = true; ! lvt.masked = true; } ! SetLVT(lapic_reg(LVTT), lvt); WriteRegister(lapic_reg(TIC), ticks); // asm volatile ("sti"); } ! void timer::StopPeriodicTimer(void) { // asm volatile ("cli"); ! lapic_lvt lvt = GetLVT(lapic_reg(LVTT)); ! lvt.periodic = false; ! lvt.masked = true; ! SetLVT(lapic_reg(LVTT), lvt); // asm volatile ("sti"); } ! void timer::TimerShot(uint ticks, bool interrupt) { // asm volatile ("cli"); ! lapic_lvt lvt = GetLVT(lapic_reg(LVTT)); if(interrupt) { ! lvt.periodic = false; ! lvt.masked = false; } else { ! lvt.periodic = false; ! lvt.masked = true; } ! SetLVT(lapic_reg(LVTT), lvt); WriteRegister(lapic_reg(TIC), ticks); // asm volatile ("sti"); } ! bool timer::TimerPending(void) { ! return GetLVT(lapic_reg(LVTT)).pending; } ! void timer::SetTimer(timer_id timer, uint ticks) { if(timer == current) --- 38,145 ---- // ----------------------------------------------------------------------- ! #include <timer.hpp> ! #include <console.hpp> ! apic_timer::apic_timer() : local_apic() { SetTimerDiv(timer_div(TDR_8)); } ! apic_timer::~apic_timer() { } ! u08b apic_timer::GetTimerVector() { ! bf32<lapic_lvt> lvt = ReadRegister(lapic_reg(LVTT)); ! return lvt->vector; } ! void apic_timer::SetTimerVector(u08b vector) { ! bf32<lapic_lvt> lvt = ReadRegister(lapic_reg(LVTT)); ! lvt->vector = vector; ! WriteRegister(lapic_reg(LVTT), lvt); } ! u08b apic_timer::GetTimerDiv() { ! return timer_div(ReadRegister(lapic_reg(TDCR)) &0x0b); } ! void apic_timer::SetTimerDiv(timer_div div) { WriteRegister(lapic_reg(TDCR), div); } ! u32b apic_timer::GetInitialCount() { return ReadRegister(lapic_reg(TIC)); } ! u32b apic_timer::GetCurrentCount() { return ReadRegister(lapic_reg(TCC)); } ! void apic_timer::StartPeriodicTimer(u32b ticks, bool interrupt) { // asm volatile ("cli"); ! bf32<lapic_lvt> lvt = ReadRegister(lapic_reg(LVTT)); if(interrupt) { ! lvt->periodic = true; ! lvt->masked = false; } else { ! lvt->periodic = true; ! lvt->masked = true; } ! WriteRegister(lapic_reg(LVTT), lvt); WriteRegister(lapic_reg(TIC), ticks); // asm volatile ("sti"); } ! void apic_timer::StopPeriodicTimer() { // asm volatile ("cli"); ! bf32<lapic_lvt> lvt = ReadRegister(lapic_reg(LVTT)); ! lvt->periodic = false; ! lvt->masked = true; ! WriteRegister(lapic_reg(LVTT), lvt); // asm volatile ("sti"); } ! void apic_timer::TimerShot(u32b ticks, bool interrupt) { // asm volatile ("cli"); ! bf32<lapic_lvt> lvt = ReadRegister(lapic_reg(LVTT)); if(interrupt) { ! lvt->periodic = false; ! lvt->masked = false; } else { ! lvt->periodic = false; ! lvt->masked = true; } ! WriteRegister(lapic_reg(LVTT), lvt); WriteRegister(lapic_reg(TIC), ticks); // asm volatile ("sti"); } ! bool apic_timer::TimerPending() { ! bf32<lapic_lvt> lvt = ReadRegister(lapic_reg(LVTT)); ! return lvt->pending; } ! void apic_timer::SetTimer(timer_id timer, u32b ticks) { if(timer == current) *************** *** 151,155 **** } ! uint timer::GetTimer(timer_id timer) { if(timer == current) --- 153,157 ---- } ! u32b apic_timer::GetTimer(timer_id timer) { if(timer == current) Index: apic_local.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/apic_local.hpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** apic_local.hpp 22 May 2006 15:18:48 -0000 1.6 --- apic_local.hpp 24 Jun 2006 15:00:02 -0000 1.7 *************** *** 41,45 **** #define __HAL__APIC_LOCAL__ ! #include "../object/std_types.hpp" /** --- 41,46 ---- #define __HAL__APIC_LOCAL__ ! #include <std_types.hpp> ! #include <heap_manager.hpp> /** *************** *** 52,57 **** struct lapic_lvt { ! uchar vector : 8; ! enum delivery_mode { fixed = 0, --- 53,58 ---- struct lapic_lvt { ! u08b vector : 8; ! enum delivery_mode { fixed = 0, *************** *** 61,91 **** ExtInt = 7 ! } delivery : 3; ! bool : 1; ! bool pending : 1; ! bool pin_polarity : 1; ! bool remote_irr : 1; ! bool level : 1; ! bool masked : 1; ! bool periodic : 1; ! uint : 14; }; struct lapic_esr { ! bool send_checksum : 1; ! bool rcv_checksum : 1; ! bool send_accept : 1; ! bool rcv_accept : 1; ! bool : 1; ! bool send_illegal_vec : 1; ! bool rcv_illegal_vec : 1; ! bool illegal_reg : 1; ! uint : 24; }; struct lapic_icr { ! uchar vector : 8; enum { --- 62,92 ---- ExtInt = 7 ! } delivery : 3; ! bool : 1; ! bool pending : 1; ! bool pin_polarity : 1; ! bool remote_irr : 1; ! bool level : 1; ! bool masked : 1; ! bool periodic : 1; ! u32b : 14; }; struct lapic_esr { ! bool snd_checksum : 1; ! bool rcv_checksum : 1; ! bool snd_accept : 1; ! bool rcv_accept : 1; ! bool : 1; ! bool snd_illegal_vec : 1; ! bool rcv_illegal_vec : 1; ! bool illegal_reg : 1; ! u32b : 24; }; struct lapic_icr { ! u08b vector : 8; enum { *************** *** 103,107 **** bool assert : 1; bool level : 1; ! uchar : 2; enum { --- 104,108 ---- bool assert : 1; bool level : 1; ! u08b : 2; enum { *************** *** 112,116 **** } dest_shorthand : 2; ! uint : 12; }; --- 113,117 ---- } dest_shorthand : 2; ! u32b : 12; }; *************** *** 118,122 **** { private: ! static ulong* base; /**< Holds the virtual base-address of the APIC's memory mapped registers */ protected: --- 119,124 ---- { private: ! static volatile u32b* base; /**< Holds the virtual base-address of the APIC's memory mapped registers */ ! static vRange* window; protected: *************** *** 153,186 **** }; ! inline void WriteRegister(lapic_reg reg, uint data) { base[reg] = data; } ! inline uint ReadRegister (lapic_reg reg) { return base[reg]; } ! ! inline void SetLVT(lapic_reg reg, lapic_lvt lvt) { *(reinterpret_cast<lapic_lvt*>(&base[reg])) = lvt; } ! inline void SetESR(lapic_esr esr) { *(reinterpret_cast<lapic_esr*>(&base[lapic_reg(ESR)])) = esr; } ! inline void SetICR(lapic_icr icr) { *(reinterpret_cast<lapic_icr*>(&base[lapic_reg(ICR0)])) = icr; } ! ! inline lapic_lvt GetLVT(lapic_reg reg) { return *(reinterpret_cast<lapic_lvt*>(&base[reg])); } ! inline lapic_esr GetESR() { return *(reinterpret_cast<lapic_esr*>(&base[lapic_reg(ESR)])); } ! inline lapic_icr GetICR() { return *(reinterpret_cast<lapic_icr*>(&base[lapic_reg(ICR0)])); } public: local_apic(); ! uchar GetPhysicalID(); ! void SetPhysicalID(uchar id); ! uchar GetLogicalID(); ! void SetLogicalID(uchar id); ! uchar GetVersion(); ! uchar GetMaxLVT(); ! // protected: ! void SetPriority(uchar priority); ! void EnableApic(); ! void DisableApic(); ! void SignalEOI(); }; --- 155,180 ---- }; ! inline void WriteRegister(lapic_reg reg, u32b data) { base[reg] = data; } ! inline u32b ReadRegister (lapic_reg reg) { return base[reg]; } public: local_apic(); ! u08b GetPhysicalID(); ! u08b GetLogicalID(); ! u08b GetVersion(); ! u08b GetMaxLVT(); ! protected: ! void SetPhysicalID(u08b id); ! void SetLogicalID(u08b id); ! void SetPriority(u08b priority); ! void EnableApic(); ! void DisableApic(); ! void SignalEOI(); }; Index: exception.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/exception.hpp,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** exception.hpp 2 Jun 2006 21:10:17 -0000 1.8 --- exception.hpp 24 Jun 2006 15:00:02 -0000 1.9 *************** *** 41,54 **** #define __HAL__EXCEPTION__ ! #include "../object/std_types.hpp" ! #include "hal_object.hpp" ! #include "interrupt.hpp" struct segment_registers { ! uint eip, cs; ! uint eflags; ! uint esp, ss; }__attribute__ ((__packed__)); --- 41,54 ---- #define __HAL__EXCEPTION__ ! #include <std_types.hpp> ! #include <hal_object.hpp> ! #include <interrupt.hpp> struct segment_registers { ! u32b eip, cs; ! u32b eflags; ! u32b esp, ss; }__attribute__ ((__packed__)); *************** *** 56,61 **** struct general_registers { ! uint edi, esi, ebp, ignore; ! uint ebx, edx, ecx, eax; }__attribute__ ((__packed__)); --- 56,61 ---- struct general_registers { ! u32b edi, esi, ebp, ignore; ! u32b ebx, edx, ecx, eax; }__attribute__ ((__packed__)); *************** *** 74,78 **** illegal_register = 128 }; - static bool error_code_map[32], trap_gate_map[32]; --- 74,77 ---- *************** *** 80,96 **** general_registers* general_regs; ! uint exception_number, error_code; bool handler_running; void PrintAllRegisters(); ! uint GetApicErrorCode(); void ClearApicErrorCode(); ! bool AddHandler (uint number, exception* p_class, method handler); ! bool AddReserved(uint number, exception* p_class, method handler); ! void InterruptConstructor(hal_object* hal, uchar interrupt_number, uint* esp); ! void InterruptDestructor (hal_object* hal, uchar interrupt_number, uint* esp); public: --- 79,94 ---- general_registers* general_regs; ! u32b exception_number, error_code; bool handler_running; void PrintAllRegisters(); ! u32b GetApicErrorCode(); void ClearApicErrorCode(); ! bool AddHandler(u08b number, exception* p_class, method handler); ! bool AddReserved(u08b number, exception* p_class, method handler); ! void InterruptEntrypoint(u08b interrupt_number, flat handler, u32b esp); public: *************** *** 98,108 **** ~exception(); ! void DivideByZero(hal_object* hal); ! void PageFault(hal_object* hal); ! void ApicError(hal_object* hal); ! void SpuriousInterrupt(hal_object* hal); ! void ReservedInterrupt(hal_object* hal); }; --- 96,106 ---- ~exception(); ! void DivideByZero(); ! void PageFault(); ! void ApicError(); ! void SpuriousInterrupt(); ! void ReservedInterrupt(); }; Index: timer.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/timer.hpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** timer.hpp 5 Apr 2006 17:12:00 -0000 1.3 --- timer.hpp 24 Jun 2006 15:00:03 -0000 1.4 *************** *** 41,91 **** #define __HAL__TIMER__ ! #include "../object/std_types.hpp" ! #include "apic_local.hpp" enum timer_div { ! TDR_1 = 0x0b, /**< Divide by 1 */ ! TDR_2 = 0x00, /**< Divide by 2 */ ! TDR_4 = 0x01, /**< Divide by 4 */ ! TDR_8 = 0x02, /**< Divide by 8 */ ! TDR_16 = 0x03, /**< Divide by 16 */ ! TDR_32 = 0x08, /**< Divide by 32 */ ! TDR_64 = 0x09, /**< Divide by 64 */ TDR_128 = 0x0a /**< Divide by 128 */ }; ! enum timer_id ! { ! current, ! next ! }; ! class timer : public local_apic { private: ! uchar GetTimerVector(void); ! void SetTimerVector(uchar vector); ! uchar GetTimerDiv(void); ! void SetTimerDiv(timer_div div); ! uint GetInitialCount(void); ! uint GetCurrentCount(void); ! void StartPeriodicTimer(uint ticks, bool interrupt); ! void StopPeriodicTimer(void); ! void TimerShot(uint ticks, bool interrupt); ! bool TimerPending(void); ! uint ntimer; public: ! timer(); ! ~timer(); ! void SetTimer(timer_id timer, uint ticks); ! uint GetTimer(timer_id timer); void TimerEvent(); --- 41,87 ---- #define __HAL__TIMER__ ! #include <std_types.hpp> ! #include <apic_local.hpp> enum timer_div { ! TDR_1 = 0x0b, /**< Divide by 1 */ ! TDR_2 = 0x00, /**< Divide by 2 */ ! TDR_4 = 0x01, /**< Divide by 4 */ ! TDR_8 = 0x02, /**< Divide by 8 */ ! TDR_16 = 0x03, /**< Divide by 16 */ ! TDR_32 = 0x08, /**< Divide by 32 */ ! TDR_64 = 0x09, /**< Divide by 64 */ TDR_128 = 0x0a /**< Divide by 128 */ }; ! enum timer_id { current, next }; ! class apic_timer : public local_apic { private: ! u08b GetTimerVector(); ! void SetTimerVector(u08b vector); ! u08b GetTimerDiv(); ! void SetTimerDiv(timer_div div); ! u32b GetInitialCount(); ! u32b GetCurrentCount(); ! void StartPeriodicTimer(u32b ticks, bool interrupt); ! void StopPeriodicTimer(); ! void TimerShot(u32b ticks, bool interrupt); ! bool TimerPending(); ! u32b ntimer; public: ! apic_timer(); ! ~apic_timer(); ! void SetTimer(timer_id timer, u32b ticks); ! u32b GetTimer(timer_id timer); void TimerEvent(); Index: idt.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/idt.hpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** idt.hpp 2 Jun 2006 21:10:18 -0000 1.4 --- idt.hpp 24 Jun 2006 15:00:02 -0000 1.5 *************** *** 41,69 **** #define __HAL__IDT__ ! #include "../object/std_types.hpp" struct idt_register { ! ushort limit; ! uint base; }__attribute__((__packed__)); ! extern "C" void reloadIDTR(idt_register* selector); ! class idt { private: ! uint* idt_pointer; ! uint idt_limit; public: ! idt(uint max_entries = 256); ! ~idt(); ! bool SetTableEntry(uint interrupt_number, void* stub, bool trap_gate); ! void* GetTableEntry(uint interrupt_number); ! uint GetNumberEntries() { return idt_limit; } }; --- 41,91 ---- #define __HAL__IDT__ ! #include <std_types.hpp> struct idt_register { ! u16b limit; ! u32b* base; }__attribute__((__packed__)); ! struct idt_entry_lo ! { ! u16b offset0 : 16; ! u16b selector : 16; ! }; ! struct idt_entry_hi ! { ! u08b : 8; ! enum ! { ! trap_gate = 7, ! interrupt = 6 ! ! } type : 3; ! bool size32bit : 1; ! bool : 1; ! u08b ring : 2; ! bool present : 1; ! u16b offset1 : 16; ! }; ! ! class idt_table { private: ! u32b* idt_pointer; ! u16b idt_limit; ! ! void ReloadIDTR(idt_register* idtr); public: ! idt_table(u16b max_entries = 256); ! ~idt_table(); ! bool SetInterruptHandler(u08b interrupt_number, void* stub_code, bool trap_gate); ! void* GetInterruptHandler(u08b interrupt_number); ! u16b GetNumberEntries(); }; Index: irq.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/irq.cpp,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** irq.cpp 2 Jun 2006 21:10:18 -0000 1.7 --- irq.cpp 24 Jun 2006 15:00:02 -0000 1.8 *************** *** 38,64 **** // ----------------------------------------------------------------------- ! #include "irq.hpp" ! #include "ports.hpp" ! #include "hal_object.hpp" ! #include "../loader/heap_manager.hpp" ! #include "../loader/console.hpp" ! irq_logic::irq_logic() : instance(0) { InitializeLegacyPIC(); // Detect how many I/O APICs are installed on the system ! uint number_devices = multiprocessor().GetNumberEntries(TYPE_IO_APIC); device_table = static_cast<irq_dev*>(heap().AllocateMemory(number_devices*sizeof(irq_dev))); ! uint counter = 0; // Walk through the multiprocessor table and initialize any I/O APIC found ! for(iterator it = multiprocessor().begin(TYPE_IO_APIC); it != multiprocessor().end(); it++) { ! device_table[counter] = InitializeIOApic(it); ! counter++; ! cout() << "Detected an I/O APIC by searching the multiprocessor table" << endl; } --- 38,62 ---- // ----------------------------------------------------------------------- ! #include <irq.hpp> ! #include <ports.hpp> ! #include <hal_object.hpp> ! #include <heap_manager.hpp> ! #include <console.hpp> ! irq_logic::irq_logic() : handler_running(false) { InitializeLegacyPIC(); // Detect how many I/O APICs are installed on the system ! u08b number_devices = multiprocessor().GetNumberEntries(TYPE_IO_APIC); device_table = static_cast<irq_dev*>(heap().AllocateMemory(number_devices*sizeof(irq_dev))); ! u08b counter = 0; // Walk through the multiprocessor table and initialize any I/O APIC found ! for(iterator it = multiprocessor().begin(TYPE_IO_APIC); it != multiprocessor().end(); ++it) { ! device_table[counter++] = InitializeIOApic(it); cout() << "Detected an I/O APIC by searching the multiprocessor table" << endl; } *************** *** 100,106 **** // Install necessary interrupt handlers ! for(uint i=0, k=255-32; i<number_devices; i++) { ! for(uint j=0; j < device_table[i].number_irqs; j++) { AddHandler(k, false, this, (method)&irq_logic::DispatchIRQ, false, false); --- 98,104 ---- // Install necessary interrupt handlers ! for(u08b i=0, k=255-32; i<number_devices; i++) { ! for(u08b j=0; j < device_table[i].number_irqs; j++) { AddHandler(k, false, this, (method)&irq_logic::DispatchIRQ, false, false); *************** *** 113,146 **** { // Before we can diable the ISA PIC we first have to initialize it ! WritePort<BYTE>(0x20, 0x11); // Initialize (16), ICW4 needed (1) ! WritePort<BYTE>(0xA0, 0x11); ! WritePort<BYTE>(0x21, 255-39); // vector offset master PIC ! WritePort<BYTE>(0xA1, 255-47); // vector offset slave PIC ! WritePort<BYTE>(0x21, 4); // IRQ #2 used for cascading ! WritePort<BYTE>(0xA1, 2); // Set slave ID ! WritePort<BYTE>(0x21, 1); // x86 mode, no auto EOI, etc ! WritePort<BYTE>(0xA1, 1); // Now mask all of its IRQs ! WritePort<BYTE>(0x21, 0xfb); // IRQs 00-07 ! WritePort<BYTE>(0xA1, 0xff); // IRQs 08-15 } ! uint irq_logic::DetectSystemBus(uint bus_number) { // In the multiprocessor tables the buses are described by a 6 character ASCII string, // we'll chop the string to a 32bit value, so that it fits into an ordinary dword ! for(iterator it = multiprocessor().begin(TYPE_BUS); it != multiprocessor().end(); it++) { if(static_cast<SmpConfigBus*>(*it)->BusID == bus_number) { ! uchar* string = static_cast<SmpConfigBus*>(*it)->TypeString; ! uint hash = 0; ! for(uint i=0; i<4; i++) { hash <<= 8; --- 111,144 ---- { // Before we can diable the ISA PIC we first have to initialize it ! WritePort<u08b>(0x20, 0x11); // Initialize (16), ICW4 needed (1) ! WritePort<u08b>(0xA0, 0x11); ! WritePort<u08b>(0x21, 255-39); // vector offset master PIC ! WritePort<u08b>(0xA1, 255-47); // vector offset slave PIC ! WritePort<u08b>(0x21, 4); // IRQ #2 used for cascading ! WritePort<u08b>(0xA1, 2); // Set slave ID ! WritePort<u08b>(0x21, 1); // x86 mode, no auto EOI, etc ! WritePort<u08b>(0xA1, 1); // Now mask all of its IRQs ! WritePort<u08b>(0x21, 0xfb); // IRQs 00-07 ! WritePort<u08b>(0xA1, 0xff); // IRQs 08-15 } ! u32b irq_logic::DetectSystemBus(u08b bus_number) { // In the multiprocessor tables the buses are described by a 6 character ASCII string, // we'll chop the string to a 32bit value, so that it fits into an ordinary dword ! for(iterator it = multiprocessor().begin(TYPE_BUS); it != multiprocessor().end(); ++it) { if(static_cast<SmpConfigBus*>(*it)->BusID == bus_number) { ! char* string = static_cast<SmpConfigBus*>(*it)->TypeString; ! u32b hash(0); ! for(u08b i=0; i<4; i++) { hash <<= 8; *************** *** 156,176 **** { // Spawn an new instance of the APIC class for this device ! uint base_address = static_cast<SmpConfigIOApic*>(*it)->BaseAddr; ! irq_dev* dev = new (heap().AllocateMemory(sizeof(irq_dev))) irq_dev(); ! io_apic* apic = new (heap().AllocateMemory(sizeof(io_apic))) io_apic(base_address); // Populate the APIC's IRQ redirection entries with default values ! for(uint i=0; i <= apic->GetMaxRedirect(); i++) { ! bool irq_type = (i > 15) ? true : false; apic->SetInterruptType(i, irq_type, irq_type, ioapic_int::lowest); ! apic->SetInterruptReceiver(i, 0xff, 255-32 - i, true); } ! uint counter = 0; // Parse the multiprocessor table for the actual IRQ mappings ! for(iterator assign = multiprocessor().begin(TYPE_IO_ASSIGN); assign != multiprocessor().end(); assign++) { SmpConfigInterrupt* irq = static_cast<SmpConfigInterrupt*>(*assign); --- 154,174 ---- { // Spawn an new instance of the APIC class for this device ! u32b base_address = static_cast<SmpConfigIOApic*>(*it)->BaseAddr; ! irq_dev* dev = heap().CreateObject<irq_dev>(); ! io_apic* apic = heap().CreateObject<io_apic>(base_address); // Populate the APIC's IRQ redirection entries with default values ! for(u08b i=0; i <= apic->GetMaxRedirect(); i++) { ! bool irq_type = i > 15; apic->SetInterruptType(i, irq_type, irq_type, ioapic_int::lowest); ! apic->SetInterruptReceiver(i, 0xff, 255-32-i, true); } ! u08b counter = 0; // Parse the multiprocessor table for the actual IRQ mappings ! for(iterator assign = multiprocessor().begin(TYPE_IO_ASSIGN); assign != multiprocessor().end(); ++assign) { SmpConfigInterrupt* irq = static_cast<SmpConfigInterrupt*>(*assign); *************** *** 188,201 **** case ISA: { ! polarity = edge_level = false; // High polarity, Edge triggered break; } - case PCI: { ! polarity = edge_level = true; // Low polarity, Level triggered break; } - default: { --- 186,197 ---- case ISA: { ! polarity = edge_level = false; // High polarity, Edge triggered break; } case PCI: { ! polarity = edge_level = true; // Low polarity, Level triggered break; } default: { *************** *** 206,213 **** } apic->SetInterruptType(irq->DestIRQ, polarity, edge_level, ioapic_int::lowest); ! apic->SetInterruptReceiver(irq->DestIRQ, 0xff, 255-32 - irq->DestIRQ, true); } counter++; } // Store the collected information in a irq_dev class dev->legacy_pic = false; --- 202,210 ---- } apic->SetInterruptType(irq->DestIRQ, polarity, edge_level, ioapic_int::lowest); ! apic->SetInterruptReceiver(irq->DestIRQ, 0xff, 255-32-irq->DestIRQ, true); } counter++; } + // Store the collected information in a irq_dev class dev->legacy_pic = false; *************** *** 219,268 **** } ! void irq_logic::EnableIRQ(uint number) { ! uint device_number = 0; ! uint current_max = device_table[device_number].number_irqs; ! while(current_max < number) ! { ! current_max += device_table[++device_number].number_irqs; ! } ! uint irq_number = device_table[device_number].number_irqs - (current_max - number); if(device_table[device_number].legacy_pic) { ! uint irq_mask = ~(1 << irq_number); ! WritePort<BYTE>(0x21, ReadPort<BYTE>(0x21) &(irq_mask)); ! WritePort<BYTE>(0xA1, ReadPort<BYTE>(0xA1) &(irq_mask >> 8)); ! } ! else ! { ! device_table[device_number].apic->MaskInterrupt(irq_number, false); } } ! void irq_logic::DisableIRQ(uint number) { ! uint device_number = 0; ! uint current_max = device_table[device_number].number_irqs; ! while(current_max < number) ! { ! current_max += device_table[++device_number].number_irqs; ! } ! uint irq_number = device_table[device_number].number_irqs - (current_max - number); if(device_table[device_number].legacy_pic) { ! uint irq_mask = 1 << irq_number; ! WritePort<BYTE>(0x21, ReadPort<BYTE>(0x21) | (irq_mask)); ! WritePort<BYTE>(0xA1, ReadPort<BYTE>(0xA1) | (irq_mask >> 8)); ! } ! else ! { ! device_table[device_number].apic->MaskInterrupt(irq_number, true); } } --- 216,253 ---- } ! void irq_logic::EnableIRQ(u08b number) { ! u08b device_number = 0; ! u08b current_max = device_table[device_number].number_irqs; ! while(current_max < number) current_max += device_table[++device_number].number_irqs; ! u08b irq_number = device_table[device_number].number_irqs - (current_max - number); if(device_table[device_number].legacy_pic) { ! u08b irq_mask = ~(1 << irq_number); ! WritePort<u08b>(0x21, ReadPort<u08b>(0x21) &(irq_mask)); ! WritePort<u08b>(0xA1, ReadPort<u08b>(0xA1) &(irq_mask >> 8)); } + else device_table[device_number].apic->MaskInterrupt(irq_number, false); } ! void irq_logic::DisableIRQ(u08b number) { ! u08b device_number = 0; ! u08b current_max = device_table[device_number].number_irqs; ! while(current_max < number) current_max += device_table[++device_number].number_irqs; ! u08b irq_number = device_table[device_number].number_irqs - (current_max - number); if(device_table[device_number].legacy_pic) { ! u08b irq_mask = 1 << irq_number; ! WritePort<u08b>(0x21, ReadPort<u08b>(0x21) | (irq_mask)); ! WritePort<u08b>(0xA1, ReadPort<u08b>(0xA1) | (irq_mask >> 8)); } + else device_table[device_number].apic->MaskInterrupt(irq_number, true); } *************** *** 271,298 **** if(device_table[0].legacy_pic) { ! WritePort<BYTE>(0x20, 0x20); ! WritePort<BYTE>(0xA0, 0x20); } } ! void irq_logic::InterruptConstructor(hal_object* hal, uchar interrupt_number, uint* esp) { ! if(instance != 0) { cout() << "Panic: Nested IRQs aren't yet supported" << endl; while(true); } ! instance = reinterpret_cast<irq_data*>(0xFFFFFFFF); ! } ! void irq_logic::InterruptDestructor(hal_object* hal, uchar interrupt_number, uint* esp) ! { ! (device_table[0].legacy_pic) ? this->SignalEOI() : hal->lapic->SignalEOI(); ! instance = reinterpret_cast<irq_data*>(0x00000000); } ! void irq_logic::DispatchIRQ(hal_object* hal) { ! cout() << (char) ReadPort<BYTE>(0x60); } --- 256,284 ---- if(device_table[0].legacy_pic) { ! WritePort<u08b>(0x20, 0x20); ! WritePort<u08b>(0xA0, 0x20); } + local_apic::SignalEOI(); } ! void irq_logic::InterruptEntrypoint(u08b interrupt_number, flat handler, u32b esp) { ! ! if(handler_running) { cout() << "Panic: Nested IRQs aren't yet supported" << endl; while(true); } ! handler_running = true; ! (*handler)(this); // Call the actual handler ! ! SignalEOI(); ! handler_running = false; } ! void irq_logic::DispatchIRQ() { ! cout() << (char)ReadPort<u08b>(0x60); } Index: interrupt_stub.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/interrupt_stub.hpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** interrupt_stub.hpp 2 Jun 2006 21:10:18 -0000 1.2 --- interrupt_stub.hpp 24 Jun 2006 15:00:02 -0000 1.3 *************** *** 41,77 **** #define __HAL__INTERRUPT_STUB__ ! #include "../object/std_types.hpp" ! #include "hal_object.hpp" ! #include "interrupt.hpp" ! typedef void (*func)(interrupt*, hal_object*); class interrupt_stub { private: ! void PatchAddress (uint offset, uint value); ! uint ExtractAddress(uint offset); ! void PatchRelativeCall (uint offset, void* stub); ! void* ExtractRelativeCall(uint offset); ! void* stub_code; public: ! interrupt_stub(void* stub_address = 0); ! ! void* GetStubAddress() { return stub_code; } ! void SetHandler(interrupt* instance, func construct, func handler, func destruct); ! func GetHandlerFunction(); ! interrupt* GetHandlerObject(); ! void SetHalObject(hal_object* hal); ! hal_object* GetHalObject(); ! void SetInterruptNumber(uint number); ! uint GetInterruptNumber(); ! void SetErrorCode(bool error_code); bool GetErrorCode(); }; --- 41,79 ---- #define __HAL__INTERRUPT_STUB__ ! #include <std_types.hpp> ! #include <interrupt.hpp> ! typedef void (*func)(interrupt*); ! ! struct instruction ! { ! u08b opcode; ! u32b address; ! ! }__attribute__((__packed__)); class interrupt_stub { private: ! instruction* GetInstruction(u16b offset); ! void PatchRelativeCall(instruction* opcode, func handler); ! func ExtractRelativeCall(instruction* opcode); ! u32b stub_code; // Points to the beginning of this instance's stub-code public: ! interrupt_stub(u32b stub_address = 0); ! void* GetStubAddress(); ! void SetHandler(interrupt* instance, func entrypoint, func handler); ! void SetInterruptNumber(u08b number); ! void SetErrorCode(bool error_code); ! interrupt* GetHandlerObject(); ! func GetHandlerFunction(); ! u08b GetInterruptNumber(); bool GetErrorCode(); }; Index: apic_io.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/apic_io.hpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** apic_io.hpp 22 May 2006 15:18:48 -0000 1.6 --- apic_io.hpp 24 Jun 2006 15:00:02 -0000 1.7 *************** *** 41,45 **** #define __HAL__APIC_IO__ ! #include "../object/std_types.hpp" /** --- 41,46 ---- #define __HAL__APIC_IO__ ! #include <std_types.hpp> ! #include <heap_manager.hpp> /** *************** *** 52,56 **** struct ioapic_int { ! uchar vector : 8; enum delivery_mode { --- 53,57 ---- struct ioapic_int { ! u08b vector : 8; enum delivery_mode { *************** *** 69,73 **** bool level : 1; bool masked : 1; ! uint : 15; }; --- 70,74 ---- bool level : 1; bool masked : 1; ! u32b : 15... [truncated message content] |
From: Daniel R. <co...@us...> - 2006-06-24 14:59:06
|
Update of /cvsroot/trion/trion v0.2 In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv851 Modified Files: makefile nucleus.elf Log Message: no message Index: nucleus.elf =================================================================== RCS file: /cvsroot/trion/trion v0.2/nucleus.elf,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 Binary files /tmp/cvsI4z5Uu and /tmp/cvszNS4fM differ Index: makefile =================================================================== RCS file: /cvsroot/trion/trion v0.2/makefile,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** makefile 2 Jun 2006 21:04:26 -0000 1.14 --- makefile 24 Jun 2006 14:58:59 -0000 1.15 *************** *** 40,44 **** AS = nasm ! CC = i686-elf-gcc RM = rm -f LD = i686-elf-ld --- 40,44 ---- AS = nasm ! CC = i686-elf-gcc -I ./hal/ -I ./loader/ -I ./object/ RM = rm -f LD = i686-elf-ld *************** *** 56,63 **** --- 56,65 ---- loader/mp_detect.cpp \ hal/cpu_info.cpp \ + hal/hal_object.cpp \ hal/systemcall.cpp \ hal/interrupt_stub.cpp \ hal/interrupt.cpp \ hal/idt.cpp \ + hal/gdt.cpp \ hal/exception.cpp \ hal/task_context.cpp \ *************** *** 75,80 **** ASRCS = hal/interrupt_stub_code.asm \ ! hal/systemcall_stub_code.asm \ ! loader/pmode.asm AOBJS = $(ASRCS:.asm=.o) --- 77,81 ---- ASRCS = hal/interrupt_stub_code.asm \ ! hal/systemcall_stub_code.asm AOBJS = $(ASRCS:.asm=.o) |
From: Daniel R. <co...@us...> - 2006-06-02 22:48:17
|
Update of /cvsroot/trion/trion v0.2/loader In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv13366 Modified Files: entry.asm heap_manager.cpp heap_manager.hpp main.cpp Log Message: no message Index: main.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/main.cpp,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** main.cpp 22 May 2006 15:19:08 -0000 1.17 --- main.cpp 2 Jun 2006 21:11:21 -0000 1.18 *************** *** 51,74 **** #include "../hal/exception.hpp" #include "../hal/apic_local.hpp" - #include "../hal/apic_error.hpp" #include "../hal/timer.hpp" #include "../hal/irq.hpp" #include "../hal/ipi.hpp" hal_object* boot_hal; extern "C" int main(uint image_size, uint processor, uint magic, void* grub) { ! uint number_processors = 0x01; if(processor == 0) { ! // Create the global heap-manager class new (heap_manager_reserved) heap_manager(); new (cpu_info_reserved) cpu_info(); // Spawn an instance of the mmu class ! hal_object* hal = boot_hal = heap().CreateHalObject(); ! hal->memory = new (heap().AllocateMemory(sizeof(mmu))) mmu(); // Create a console object to be able to print debug messages --- 51,106 ---- #include "../hal/exception.hpp" #include "../hal/apic_local.hpp" #include "../hal/timer.hpp" #include "../hal/irq.hpp" #include "../hal/ipi.hpp" + #include "../hal/systemcall.hpp" + #include "../hal/task_context.hpp" + hal_object* boot_hal; + extern "C" void user_main() + { + asm("mov %ss, %eax\n" + "mov %eax, %ds\n" + "mov %eax, %es\n" + "mov %eax, %fs\n" + "mov %eax, %gs\n" + ); + + // Print a red 'A' in the upper-left corner of the screen + char* vidmem = reinterpret_cast<char*>(0x2000); + + vidmem[(80+78)*2 + 0] = 'A'; + vidmem[(80+78)*2 + 1] = 4; + + // Demonstrate the systemcall-mechanism + asm("mov $(syscall_return - 0xE0000000), %edx\n" + "push %ebp\n" + "mov %esp, %ecx\n" + "sysenter\n" + "syscall_return: pop %ebp"); + + vidmem[(160+78)*2 + 0] = 'B'; + vidmem[(160+78)*2 + 1] = 4; + + while(true); // Wait for IRQs + } + extern "C" int main(uint image_size, uint processor, uint magic, void* grub) { ! uint number_processors; if(processor == 0) { ! number_processors = 1; ! ! // Create the global heap-manager class object new (heap_manager_reserved) heap_manager(); new (cpu_info_reserved) cpu_info(); // Spawn an instance of the mmu class ! hal_object* hal = boot_hal = heap().CreateHalObject(processor); ! hal->memory = new (heap().AllocateMemory(sizeof(mmu))) mmu(0xE0000000 + image_size); // Create a console object to be able to print debug messages *************** *** 79,94 **** // Enable the IDT and activate exception handling ! hal->vector = new (heap().AllocateMemory(sizeof(idt))) idt(); ! hal->faults = new (heap().AllocateMemory(sizeof(exception))) exception(); ! // Initialize the local APIC and activate all I/O APICs mp_detect* multi = new (mp_detect_reserved) mp_detect(); ! hal->lapic = new (heap().AllocateMemory(sizeof(local_apic))) local_apic(); ! hal->error = new (heap().AllocateMemory(sizeof(apic_error))) apic_error(); ! hal->clock = new (heap().AllocateMemory(sizeof(timer))) timer(); ! hal->inter = new (heap().AllocateMemory(sizeof(ipi))) ipi(); new (irq_logic_reserved) irq_logic(); // Enable hyperthreading and try to boot all application processors number_processors += multi->EnableHyperthreading(); --- 111,129 ---- // Enable the IDT and activate exception handling ! hal->vector = new (heap().AllocateMemory(sizeof(idt))) idt(); ! hal->faults = new (heap().AllocateMemory(sizeof(exception))) exception(); ! // Initialize the local APIC and enable all I/O APICs mp_detect* multi = new (mp_detect_reserved) mp_detect(); ! hal->lapic = new (heap().AllocateMemory(sizeof(local_apic))) local_apic(); ! hal->clock = new (heap().AllocateMemory(sizeof(timer))) timer(); ! hal->inter = new (heap().AllocateMemory(sizeof(ipi))) ipi(); new (irq_logic_reserved) irq_logic(); + // Prepare everything for user-mode + hal->context = new (heap().AllocateMemory(sizeof(task_context))) task_context(); + hal->syscall = new (heap().AllocateMemory(sizeof(systemcall))) systemcall(); + // Enable hyperthreading and try to boot all application processors number_processors += multi->EnableHyperthreading(); *************** *** 96,106 **** cout() << endl << "All " << number_processors << " processors have been booted" << endl; - cout() << "You may now type something:" << endl << endl ; ! // Enable the keyboard interrupts and wait for IRQs ! irq().EnableIRQ(1); ! asm("sti"); ! while(true) asm("hlt"); } else --- 131,149 ---- cout() << endl << "All " << number_processors << " processors have been booted" << endl; ! // Unmask the keyboard IRQ ! irq().EnableIRQ(0x01); ! // Install a small user-task for testing purposes ! hal->memory->CreatePageTable(0x00000000, 0x8000, mmu::USER_MODE | mmu::READ_WRITE); ! ! hal->memory->MapPage((void*)0x00000000, 0x100000, mmu::USER_MODE | mmu::READ_WRITE); // user-mode code ! hal->memory->MapPage((void*)0x00001000, 0x10000, mmu::USER_MODE | mmu::READ_WRITE); // stack space ! hal->memory->MapPage((void*)0x00002000, 0xB8000, mmu::USER_MODE | mmu::READ_WRITE); // video memory ! ! uint task_entry = (uint)&user_main - 0xE0000000; ! ! // Switch to the user-mode code ! hal->syscall->InvokeUserTask(task_entry, 0x2000); } else *************** *** 110,121 **** // Spawn an instance of all hal classes.. ! hal_object* hal = boot_hal = heap().CreateHalObject(); ! hal->memory = new (heap().AllocateMemory(sizeof(mmu))) mmu(); hal->vector = new (heap().AllocateMemory(sizeof(idt))) idt(); hal->faults = new (heap().AllocateMemory(sizeof(exception))) exception(); hal->lapic = new (heap().AllocateMemory(sizeof(local_apic))) local_apic(); - hal->error = new (heap().AllocateMemory(sizeof(apic_error))) apic_error(); hal->clock = new (heap().AllocateMemory(sizeof(timer))) timer(); hal->inter = new (heap().AllocateMemory(sizeof(ipi))) ipi(); --- 153,163 ---- // Spawn an instance of all hal classes.. ! hal_object* hal = boot_hal = heap().CreateHalObject(processor); ! hal->memory = new (heap().AllocateMemory(sizeof(mmu))) mmu(0xE0000000 + image_size); hal->vector = new (heap().AllocateMemory(sizeof(idt))) idt(); hal->faults = new (heap().AllocateMemory(sizeof(exception))) exception(); hal->lapic = new (heap().AllocateMemory(sizeof(local_apic))) local_apic(); hal->clock = new (heap().AllocateMemory(sizeof(timer))) timer(); hal->inter = new (heap().AllocateMemory(sizeof(ipi))) ipi(); Index: heap_manager.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/heap_manager.hpp,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** heap_manager.hpp 5 Apr 2006 17:12:56 -0000 1.7 --- heap_manager.hpp 2 Jun 2006 21:11:21 -0000 1.8 *************** *** 78,82 **** void AllocateApStack(); ! hal_object* CreateHalObject(); void* AllocateMemory(uint size_bytes); --- 78,82 ---- void AllocateApStack(); ! hal_object* CreateHalObject(uint processor_number); void* AllocateMemory(uint size_bytes); Index: entry.asm =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/entry.asm,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** entry.asm 5 Apr 2006 17:12:56 -0000 1.10 --- entry.asm 2 Jun 2006 21:11:21 -0000 1.11 *************** *** 270,274 **** dd 0x00cf9A00 ! ; 0x10 - Kernel data segment ; data, ring0, base: 0x00000000, limit: 4GB dd 0x0000ffff --- 270,274 ---- dd 0x00cf9A00 ! ; 0x10 - Kernel data/stack segment ; data, ring0, base: 0x00000000, limit: 4GB dd 0x0000ffff *************** *** 281,285 **** ; 0x20 - User data/stack segment ! ; data, ring0, base: 0x00000000, limit: 4GB dd 0x0000ffff dd 0x00cff200 --- 281,285 ---- ; 0x20 - User data/stack segment ! ; data, ring3, base: 0x00000000, limit: 4GB dd 0x0000ffff dd 0x00cff200 Index: heap_manager.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/heap_manager.cpp,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** heap_manager.cpp 22 May 2006 15:19:08 -0000 1.10 --- heap_manager.cpp 2 Jun 2006 21:11:21 -0000 1.11 *************** *** 99,110 **** } ! hal_object* heap_manager::CreateHalObject() { ! uchar* hal = static_cast<uchar*>(AllocateMemory(sizeof(hal_object))); for(uint i=0; i < sizeof(hal_object); i++) ! hal[i] = 0x00; ! return reinterpret_cast<hal_object*>(hal); } --- 99,120 ---- } ! hal_object* heap_manager::CreateHalObject(uint processor_number) { ! uchar* hal_reserved = static_cast<uchar*>(AllocateMemory(sizeof(hal_object))); + // Initialize the hal-object structure with all zeroes for(uint i=0; i < sizeof(hal_object); i++) ! hal_reserved[i] = 0x00; ! // Fill in the structure's header ! uint stack_base = 0x00000000; ! asm("mov %%esp, %%eax" : "=a"(stack_base)); ! stack_base = (stack_base + 0xfff) &0xfffff000; ! ! hal_object* hal = reinterpret_cast<hal_object*>(hal_reserved); ! hal->processor_number = processor_number; ! hal->kernel_stack_base = stack_base; ! ! return hal; } |
Update of /cvsroot/trion/trion v0.2/hal In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv12831 Modified Files: cpu_info.cpp cpu_info.hpp exception.cpp exception.hpp hal_object.hpp idt.cpp idt.hpp interrupt.cpp interrupt.hpp interrupt_stub.cpp interrupt_stub.hpp interrupt_stub_code.asm irq.cpp irq.hpp mmu.cpp mmu.hpp ports.hpp systemcall.cpp systemcall.hpp Added Files: systemcall_stub_code.asm task_context.cpp task_context.hpp Removed Files: apic_error.cpp apic_error.hpp Log Message: no message Index: hal_object.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/hal_object.hpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** hal_object.hpp 22 May 2006 15:18:49 -0000 1.5 --- hal_object.hpp 2 Jun 2006 21:10:17 -0000 1.6 *************** *** 43,53 **** struct hal_object { ! class idt* vector; ! class local_apic* lapic; ! class apic_error* error; ! class exception* faults; ! class ipi* inter; ! class timer* clock; ! class mmu* memory; }; // Points to the hal object of the processor that currently boots --- 43,57 ---- struct hal_object { ! uint processor_number; ! uint kernel_stack_base; ! ! class idt* vector; ! class local_apic* lapic; ! class exception* faults; ! class ipi* inter; ! class timer* clock; ! class mmu* memory; ! class systemcall* syscall; ! class task_context* context; }; // Points to the hal object of the processor that currently boots --- apic_error.hpp DELETED --- Index: mmu.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/mmu.hpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** mmu.hpp 25 Mar 2006 16:56:25 -0000 1.3 --- mmu.hpp 2 Jun 2006 21:10:18 -0000 1.4 *************** *** 48,59 **** { private: static const uint ENTRY_ACCESSED = 32; static const uint ENTRY_DIRTY = 64; - uint pagedirectory; - public: ! void* InitializeDirectory(void* page_directory); ! void SwitchContext(uint phys_page_directory); void CreatePageTable(void* virtual_base, uint phys_table_address, uint flags = 3); --- 48,59 ---- { private: + uint pagedirectory; + static const uint ENTRY_ACCESSED = 32; static const uint ENTRY_DIRTY = 64; public: ! mmu(uint directory = 0); ! ~mmu(); void CreatePageTable(void* virtual_base, uint phys_table_address, uint flags = 3); *************** *** 67,70 **** --- 67,72 ---- void* CreateAccessedMap(void* map, void* virtual_base, uint number_entries, bool tables = false); + uint GetPageDirectory(); + static const uint GLOBAL_PAGE = 256; static const uint CACHE_DISABLED = 16; *************** *** 77,79 **** #endif - --- 79,80 ---- Index: systemcall.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/systemcall.hpp,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** systemcall.hpp 7 Jan 2006 16:39:33 -0000 1.1.1.1 --- systemcall.hpp 2 Jun 2006 21:10:18 -0000 1.2 *************** *** 9,13 **** // ----------------------------------------------------------------------- ! // Copyright (C) 2003, Trion Development Group Members // All rights reserved. // --- 9,13 ---- // ----------------------------------------------------------------------- ! // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // *************** *** 41,51 **** #define __HAL__SYSTEMCALL__ struct message_register { ! htask receiver; ! void* message; ! int message_length; ! bool asynchronious; message_register* next, *prev; --- 41,53 ---- #define __HAL__SYSTEMCALL__ + #include "../object/std_types.hpp" + struct message_register { ! // htask sender_receiver; ! void* message_pointer; ! uint message_length; ! bool asynchronous; message_register* next, *prev; *************** *** 54,60 **** class systemcall { public: ! void Dispatcher(message_register* msg); ! int IPC(htask sender, message_register* msg); }; --- 56,72 ---- class systemcall { + private: + static const uint SYSENTER_CS_MSR = 0x174; + static const uint SYSENTER_ESP_MSR = 0x175; + static const uint SYSENTER_EIP_MSR = 0x176; + + void PatchAddress(void* stub_base, uint offset, uint value); + void PatchRelativeCall(void* stub_base, uint offset, void* handler); + public: ! systemcall(); ! ! void SystemcallDispatcher(message_register* msg, uint* esp, uint eip); ! void InvokeUserTask(uint instruction_pointer, uint stack_pointer); }; Index: exception.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/exception.cpp,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** exception.cpp 22 May 2006 15:18:49 -0000 1.8 --- exception.cpp 2 Jun 2006 21:10:17 -0000 1.9 *************** *** 1,4 **** // ----------------------------------------------------------------------- ! // exception.cpp - CPU exception handler // // Author(s) : --- 1,4 ---- // ----------------------------------------------------------------------- ! // exception.cpp - Handler for exception, spurious interrupts and APIC errors // // Author(s) : *************** *** 41,54 **** #include "../loader/console.hpp" ! bool exception::error_code_map[] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, ! 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; ! bool exception::trap_gate_map [] = {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; exception::exception() { ! for(uint i=0; i<0x100; i++) { - // Install a standard handler for all 256 interrupts AddReserved(i, this, (method)&exception::ReservedInterrupt); } --- 41,52 ---- #include "../loader/console.hpp" ! bool exception::error_code_map[] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1}; ! bool exception::trap_gate_map [] = {0, 0, 0, 1, 1}; exception::exception() { ! // Install a standard handler for exceptions and reserved interrupts ! for(uint i=0; i<=32; i++) { AddReserved(i, this, (method)&exception::ReservedInterrupt); } *************** *** 58,61 **** --- 56,75 ---- AddHandler(0xE, this, (method)&exception::PageFault); + // Enable the APIC error interrupt and assign a vector to it + uint apic_error_vector = 255 - 0; + + lapic_lvt lvt = GetLVT(lapic_reg(LVTERR)); + lvt.masked = false; + lvt.vector = apic_error_vector; + SetLVT(lapic_reg(LVTERR), lvt); + + // Assign a vector to the spurious interupt + uint spurious_vector = 255 - 1; + WriteRegister(lapic_reg(SIVR), ReadRegister(lapic_reg(SIVR)) | spurious_vector); + + // Install our two APIC error-handlers + interrupt::AddHandler(apic_error_vector, false, this, (method) &exception::ApicError, false, false); + interrupt::AddHandler(spurious_vector, false, this, (method) &exception::SpuriousInterrupt, false, false); + handler_running = false; } *************** *** 65,77 **** cout() << "eax " << general_regs->eax << " "; cout() << "esi " << general_regs->esi << " "; ! cout() << "cs " << segment_regs->cs << endl; cout() << "ebx " << general_regs->ebx << " "; cout() << "edi " << general_regs->edi << " "; ! cout() << "ss " << segment_regs->ss << endl; cout() << "ecx " << general_regs->ecx << " "; cout() << "ebp " << general_regs->ebp << endl; cout() << "edx " << general_regs->edx << " "; cout() << "esp " << segment_regs->esp << " "; ! cout() << "eflags " << segment_regs->eflags << endl << endl; } --- 79,93 ---- cout() << "eax " << general_regs->eax << " "; cout() << "esi " << general_regs->esi << " "; ! cout() << "cs " << segment_regs->cs << " "; ! cout() << "eflags " << segment_regs->eflags << endl; cout() << "ebx " << general_regs->ebx << " "; cout() << "edi " << general_regs->edi << " "; ! cout() << "ss " << segment_regs->ss << " "; ! cout() << "error " << error_code << endl; cout() << "ecx " << general_regs->ecx << " "; cout() << "ebp " << general_regs->ebp << endl; cout() << "edx " << general_regs->edx << " "; cout() << "esp " << segment_regs->esp << " "; ! cout() << "eip " << segment_regs->eip << endl << endl; } *************** *** 90,94 **** if(handler_running) { ! cout() << endl << "Panic: Exception in exception handler" << endl; while(true); } --- 106,110 ---- if(handler_running) { ! cout() << endl << "Panic: Exception in exception handler"; while(true); } *************** *** 98,108 **** error_code = 0; ! general_regs = reinterpret_cast<general_registers*>(&esp[0]); ! segment_regs = reinterpret_cast<segment_registers*>(&esp[8]); ! if(error_code_map[exception_number]) { ! error_code = esp[8]; ! segment_regs = reinterpret_cast<segment_registers*>(&esp[9]); } } --- 114,124 ---- error_code = 0; ! general_regs = reinterpret_cast<general_registers*>(&esp[1]); ! segment_regs = reinterpret_cast<segment_registers*>(&esp[9]); ! if(exception_number <= 0x20 && error_code_map[exception_number]) { ! segment_regs = reinterpret_cast<segment_registers*>(&esp[10]); ! error_code++; } } *************** *** 118,129 **** PrintAllRegisters(); ! ! // general_regs->edx = 0; ! // general_regs->edi = 0x2BADB002; } void exception::PageFault(hal_object* hal) { ! cout() << endl << "Panic: A pagefault was reported" << endl; PrintAllRegisters(); --- 134,147 ---- PrintAllRegisters(); ! while(true); } void exception::PageFault(hal_object* hal) { ! // Get the address causing the exception from cr2 ! uint fault_address(0); ! asm("movl %%cr2, %%eax" : "=a"(fault_address)); ! ! cout() << endl << "Panic: A pagefault was reported (" << fault_address << ")" << endl; PrintAllRegisters(); *************** *** 131,134 **** --- 149,178 ---- } + uint exception::GetApicErrorCode() + { + // Write to the register to update it, then read it out + WriteRegister(lapic_reg(ESR), 0); + return ReadRegister(lapic_reg(ESR)); + } + + void exception::ClearApicErrorCode() + { + // Two sucessive writes clear the error register + WriteRegister(lapic_reg(ESR), 0); + WriteRegister(lapic_reg(ESR), 0); + } + + void exception::ApicError(hal_object* hal) + { + cout() << "Panic: A local APIC error was reported (" << GetApicErrorCode() << ")"; + while(true); + } + + void exception::SpuriousInterrupt(hal_object* hal) + { + cout() << "Panic: A spurious interrupt was reported"; + while(true); + } + void exception::ReservedInterrupt(hal_object* hal) { --- NEW FILE: task_context.hpp --- // ----------------------------------------------------------------------- // task_context - Allows the task context to be set-up // // Author(s) : // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. 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. // 3. Neither the name of the Trion Development Group nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT // OWNER OR CONTRIBUTORS 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. // ----------------------------------------------------------------------- #ifndef __HAL__TASK_CONTEXT__ #define __HAL__TASK_CONTEXT__ #include "../object/std_types.hpp" #include "mmu.hpp" #include "ports.hpp" struct task_switch_segment { uint prev_task; uint esp0, ss0; uint esp1, ss1; uint esp2, ss2; uint cr3, eip, eflags; uint eax, ecx, edx, ebx; uint esp, ebp, esi, edi; uint es, cs, ss, ds, fs, gs; uint ldt_selector; ushort debug_trap, io_map; } __attribute__((__packed__)); struct gdt_register { ushort limit; uint base; } __attribute__((__packed__)); class task_context { private: task_switch_segment tss; void InitializeTaskSegment(uint stack_descriptor, uint stack_pointer); uint FindAvailableGDTSlot(); void CreateTaskDescriptor(uint gdt_slot); void SetTaskRegister(uint descriptor_number); void SetKernelStack(uint stack_pointer); public: task_context(); void SetPageDirectory(mmu* context); void SetPortMap(ports* context); }; #endif Index: exception.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/exception.hpp,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** exception.hpp 22 May 2006 15:18:49 -0000 1.7 --- exception.hpp 2 Jun 2006 21:10:17 -0000 1.8 *************** *** 1,4 **** // ----------------------------------------------------------------------- ! // exception.hpp - CPU exception handler // // Author(s) : --- 1,4 ---- // ----------------------------------------------------------------------- ! // exception.hpp - Handler for exception, spurious interrupts and APIC errors // // Author(s) : *************** *** 64,67 **** --- 64,78 ---- { private: + enum apic_errors + { + send_checksum = 1, + receive_checksum = 2, + send_accept = 4, + receive_accept = 8, + send_vector = 32, + receive_vector = 64, + illegal_register = 128 + }; + static bool error_code_map[32], trap_gate_map[32]; *************** *** 74,77 **** --- 85,91 ---- void PrintAllRegisters(); + uint GetApicErrorCode(); + void ClearApicErrorCode(); + bool AddHandler (uint number, exception* p_class, method handler); bool AddReserved(uint number, exception* p_class, method handler); *************** *** 87,90 **** --- 101,107 ---- void PageFault(hal_object* hal); + void ApicError(hal_object* hal); + void SpuriousInterrupt(hal_object* hal); + void ReservedInterrupt(hal_object* hal); }; Index: idt.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/idt.hpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** idt.hpp 5 Apr 2006 17:12:00 -0000 1.3 --- idt.hpp 2 Jun 2006 21:10:18 -0000 1.4 *************** *** 43,47 **** #include "../object/std_types.hpp" ! struct idt_selector { ushort limit; --- 43,47 ---- #include "../object/std_types.hpp" ! struct idt_register { ushort limit; *************** *** 50,54 **** }__attribute__((__packed__)); ! extern "C" void reloadIDTR(idt_selector* selector); class idt --- 50,54 ---- }__attribute__((__packed__)); ! extern "C" void reloadIDTR(idt_register* selector); class idt --- apic_error.cpp DELETED --- Index: irq.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/irq.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** irq.cpp 22 May 2006 15:18:49 -0000 1.6 --- irq.cpp 2 Jun 2006 21:10:18 -0000 1.7 *************** *** 116,121 **** WritePort<BYTE>(0xA0, 0x11); ! WritePort<BYTE>(0x21, 255-47); // vector offset master PIC ! WritePort<BYTE>(0xA1, 255-39); // vector offset slave PIC WritePort<BYTE>(0x21, 4); // IRQ #2 used for cascading --- 116,121 ---- WritePort<BYTE>(0xA0, 0x11); ! WritePort<BYTE>(0x21, 255-39); // vector offset master PIC ! WritePort<BYTE>(0xA1, 255-47); // vector offset slave PIC WritePort<BYTE>(0x21, 4); // IRQ #2 used for cascading *************** *** 126,130 **** // Now mask all of its IRQs ! WritePort<BYTE>(0x21, 0xff); // IRQs 00-07 WritePort<BYTE>(0xA1, 0xff); // IRQs 08-15 } --- 126,130 ---- // Now mask all of its IRQs ! WritePort<BYTE>(0x21, 0xfb); // IRQs 00-07 WritePort<BYTE>(0xA1, 0xff); // IRQs 08-15 } *************** *** 210,214 **** counter++; } - // Store the collected information in a irq_dev class dev->legacy_pic = false; --- 210,213 ---- *************** *** 233,238 **** if(device_table[device_number].legacy_pic) { ! uint irq_mask = ~(1 << irq_number); ! WritePort<BYTE>(0x21, ReadPort<BYTE>(0x21) &(irq_mask)); WritePort<BYTE>(0xA1, ReadPort<BYTE>(0xA1) &(irq_mask >> 8)); --- 232,237 ---- if(device_table[device_number].legacy_pic) { ! uint irq_mask = ~(1 << irq_number); ! WritePort<BYTE>(0x21, ReadPort<BYTE>(0x21) &(irq_mask)); WritePort<BYTE>(0xA1, ReadPort<BYTE>(0xA1) &(irq_mask >> 8)); *************** *** 257,261 **** if(device_table[device_number].legacy_pic) { ! uint irq_mask = 1 << irq_number; WritePort<BYTE>(0x21, ReadPort<BYTE>(0x21) | (irq_mask)); --- 256,260 ---- if(device_table[device_number].legacy_pic) { ! uint irq_mask = 1 << irq_number; WritePort<BYTE>(0x21, ReadPort<BYTE>(0x21) | (irq_mask)); *************** *** 268,272 **** } ! void irq_logic::SignalEOI(uint number) { if(device_table[0].legacy_pic) --- 267,271 ---- } ! void irq_logic::SignalEOI() { if(device_table[0].legacy_pic) *************** *** 289,293 **** void irq_logic::InterruptDestructor(hal_object* hal, uchar interrupt_number, uint* esp) { ! (device_table[0].legacy_pic) ? this->SignalEOI(interrupt_number) : hal->lapic->SignalEOI(); instance = reinterpret_cast<irq_data*>(0x00000000); } --- 288,292 ---- void irq_logic::InterruptDestructor(hal_object* hal, uchar interrupt_number, uint* esp) { ! (device_table[0].legacy_pic) ? this->SignalEOI() : hal->lapic->SignalEOI(); instance = reinterpret_cast<irq_data*>(0x00000000); } Index: interrupt_stub.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/interrupt_stub.hpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** interrupt_stub.hpp 5 Apr 2006 17:12:00 -0000 1.1 --- interrupt_stub.hpp 2 Jun 2006 21:10:18 -0000 1.2 *************** *** 50,61 **** { private: ! void* stub_code; ! ! void PatchAddress(uint offset, uint value); uint ExtractAddress(uint offset); ! void PatchRelativeCall(uint offset, void* stub); void* ExtractRelativeCall(uint offset); public: interrupt_stub(void* stub_address = 0); --- 50,61 ---- { private: ! void PatchAddress (uint offset, uint value); uint ExtractAddress(uint offset); ! void PatchRelativeCall (uint offset, void* stub); void* ExtractRelativeCall(uint offset); + void* stub_code; + public: interrupt_stub(void* stub_address = 0); *************** *** 63,76 **** void* GetStubAddress() { return stub_code; } ! void SetHandler(interrupt* instance, func construct, func handler, func destruct); ! func GetHandlerFunction(); ! interrupt* GetHandlerObject(); ! ! void SetInterruptNumber(uint number); ! uint GetInterruptNumber(); void SetHalObject(hal_object* hal); hal_object* GetHalObject(); void SetErrorCode(bool error_code); bool GetErrorCode(); --- 63,76 ---- void* GetStubAddress() { return stub_code; } ! void SetHandler(interrupt* instance, func construct, func handler, func destruct); ! func GetHandlerFunction(); ! interrupt* GetHandlerObject(); void SetHalObject(hal_object* hal); hal_object* GetHalObject(); + void SetInterruptNumber(uint number); + uint GetInterruptNumber(); + void SetErrorCode(bool error_code); bool GetErrorCode(); --- NEW FILE: systemcall_stub_code.asm --- ; ------------------------------------------------------------------------ ; systemcall_stub_code.asm - Entrypoint for SYSENTER/SYSEXIT systemcalls ; ; Author(s) : Daniel Raffler ; Date : DD/MM/2006 ; Version : 0.2.0 ; Home Page : http://trion.sourceforge.net ; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------ ; Copyright (C) 2006, Trion Development Group Members ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are ; met: ; ; 1. Redistributions of source code must retain the above copyright ; notice, this list of conditions and the following disclaimer. ; 2. 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. ; 3. Neither the name of the Trion Development Group nor the names of its ; contributors may be used to endorse or promote products derived from ; this software without specific prior written permission. ; ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT ; OWNER OR CONTRIBUTORS 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. ; ------------------------------------------------------------------------ section .text bits 32 global SystemcallEntrypoint global SystemcallReturnpoint ; Note that the two systemcall procedure do not work as a call/return pair. Normally ; a systemcall leads to a server being scheduled, which will then process the ; caller's request. It's thus at least uncommon that control is returned again to ; the caller immediately after the nucleus has finished its job. align 8 SystemcallEntrypoint: mov ebx, 0x10 ; Switch to kernel-mode selectors mov ds, bx mov es, bx mov fs, bx mov gs, bx push edx ; EDX holds the ring3 return EIP set by the user-mode stub code push ecx ; Ring3 stack-pointer is stored in the ECX register push eax ; Pushes a pointer to the message-register structure on the stack push dword 0 ; Move class pointer to the stack (hidden parameter) call dword $+5 ; Call the responsible C++ systemcall handler align 8 SystemcallReturnpoint: pop eax ; Get rid of the caller's return-address pop edx ; Pop the ring3 instruction-pointer off the stack pop ecx ; Pushed stack-pointer gets re-assigned to ESP by SYSEXIT mov eax, 0 ; Will be patched with the processor number mov ebx, 0x23 ; Restore user-mode selectors mov ds, bx mov es, bx mov fs, bx mov gs, bx dw 0x350f ; Returns to the calling ring3 procedure (The data-vodoo is needed as ; NASM doesn't seem to encode the sysexit instruction correctly..) Index: cpu_info.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/cpu_info.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** cpu_info.cpp 22 May 2006 15:18:48 -0000 1.2 --- cpu_info.cpp 2 Jun 2006 21:10:17 -0000 1.3 *************** *** 49,53 **** { uint low, high; ! asm("rdmsr":"=d"(high),"=a"(low):"c"(number)); return low; } --- 49,53 ---- { uint low, high; ! asm volatile("rdmsr":"=d"(high),"=a"(low):"c"(number)); return low; } *************** *** 56,72 **** { uint low, high; ! asm("rdmsr":"=d"(high),"=a"(low):"c"(number)); return high; } void cpu_info::ModifyLoMSR(uint number, uint mask, uint data) { uint low, high; ! asm("rdmsr":"=d"(high),"=a"(low):"c"(number)); low &= mask; low |= data; ! asm("wrmsr": :"d"(high),"a"(low),"c"(number)); } --- 56,82 ---- { uint low, high; ! asm volatile("rdmsr":"=d"(high),"=a"(low):"c"(number)); return high; } + void cpu_info::WriteLoMSR(uint number, uint data) + { + asm volatile("wrmsr": :"d"(0),"a"(data),"c"(number)); + } + + void cpu_info::WriteHiMSR(uint number, uint data) + { + asm volatile("wrmsr": :"d"(data),"a"(0),"c"(number)); + } + void cpu_info::ModifyLoMSR(uint number, uint mask, uint data) { uint low, high; ! asm volatile("rdmsr":"=d"(high),"=a"(low):"c"(number)); low &= mask; low |= data; ! asm volatile("wrmsr": :"d"(high),"a"(low),"c"(number)); } *************** *** 74,83 **** { uint low, high; ! asm("rdmsr":"=d"(high),"=a"(low):"c"(number)); high &= mask; high |= data; ! asm("wrmsr": :"d"(high),"a"(low),"c"(number)); } --- 84,93 ---- { uint low, high; ! asm volatile("rdmsr":"=d"(high),"=a"(low):"c"(number)); high &= mask; high |= data; ! asm volatile("wrmsr": :"d"(high),"a"(low),"c"(number)); } Index: interrupt_stub.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/interrupt_stub.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** interrupt_stub.cpp 5 Apr 2006 17:12:00 -0000 1.1 --- interrupt_stub.cpp 2 Jun 2006 21:10:18 -0000 1.2 *************** *** 80,85 **** { uint* dest = reinterpret_cast<uint*>(reinterpret_cast<uint>(stub_code) + offset + 1); ! uint value = (uint)((int)((uint)handler &0xFFFFFF) - (int)(((uint)dest + 4) &0xFFFFFF)); ! dest[0] = value; } --- 80,84 ---- { uint* dest = reinterpret_cast<uint*>(reinterpret_cast<uint>(stub_code) + offset + 1); ! *dest = (uint)((int)((uint)handler &0xFFFFFF) - (int)(((uint)dest + 4) &0xFFFFFF)); } *************** *** 88,92 **** // Extracts and returns the destination field of a relative "call dword address" instruction int* dest = reinterpret_cast<int*>(reinterpret_cast<uint>(stub_code) + offset + 1); ! int value = dest[0]; uint addr = (uint)((int)((uint)dest &0xFFFFFF) + 4 + value); --- 87,91 ---- // Extracts and returns the destination field of a relative "call dword address" instruction int* dest = reinterpret_cast<int*>(reinterpret_cast<uint>(stub_code) + offset + 1); ! int value = *dest; uint addr = (uint)((int)((uint)dest &0xFFFFFF) + 4 + value); *************** *** 150,162 **** if(error_code) { ! // Copy "add esp, 4" and "iret" instructions ! for(uint i=offset; i < (offset+7); i++) ! dest[i] = source[i]; ! } ! else ! { ! // Only append an "iret" to the end of the stub ! dest[offset] = 0xCF; } } --- 149,161 ---- if(error_code) { ! // Copy the "add esp, 4" instructions ! for(uint i=0; i < 6; i++) ! { ! dest[offset++] = source[offset]; ! } } + + // Append an "iret" at the end of the stub + dest[offset] = 0xCF; } Index: mmu.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/mmu.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** mmu.cpp 25 Mar 2006 16:56:25 -0000 1.5 --- mmu.cpp 2 Jun 2006 21:10:18 -0000 1.6 *************** *** 40,50 **** #include "mmu.hpp" ! void* mmu::InitializeDirectory(void* page_directory) ! { ! return 0; ! } ! ! void mmu::SwitchContext(uint phys_page_directory) { } --- 40,51 ---- #include "mmu.hpp" ! mmu::mmu(uint directory) { + if(pagedirectory != 0) + { + // This instance is used to access an exsisting directory + pagedirectory = directory; + } + // TODO - Create a new directory for the task } *************** *** 109,119 **** } ! void* mmu::CreateDirtyMap(void* map, void* virtual_base, uint number_entries) ! { ! return 0; ! } ! ! void* mmu::CreateAccessedMap(void* map, void* virtual_base, uint number_entries, bool tables) { ! return 0; } --- 110,115 ---- } ! uint mmu::GetPageDirectory() { ! return pagedirectory; } Index: interrupt.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/interrupt.hpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** interrupt.hpp 22 May 2006 15:18:49 -0000 1.3 --- interrupt.hpp 2 Jun 2006 21:10:18 -0000 1.4 *************** *** 58,77 **** }; ! // [ Interrupt Map ] ! // ! // 240 to 255 <16>: APIC errors, spurious interrupts, etc ! // 224 to 239 <16>: Local vectors (apic timer, thermal sensor, etc) ! // 160 to 223 <64>: Harware IRQs ! // .... ! // 000 to 031 <32>: Exceptions ! // ! // priority = vector_number/16, numerical higher -> more important ! // ! // - For interrupts that have the same interrupt-priority level, ! // the highest vector number wins ! // - Exceptions aren't delivered by the local apic, hardcoded vectors ! // don't imply a certain priority ! // - Hardware IRQs are mapped upside down (IRQ0 = 255, IRQ1 = 254, etc) ! // to enforce the intended priorities #endif --- 58,79 ---- }; ! /** ! * [ Interrupt Map ] ! * ! * 240 to 255 <16>: APIC errors, spurious interrupts, etc ! * 224 to 239 <16>: Local vectors (apic timer, thermal sensor, etc) ! * 160 to 223 <64>: Harware IRQs ! * .... ! * 000 to 031 <32>: Exceptions ! * ! * priority = vector_number/16, numerical higher -> more important ! * ! * - For interrupts that have the same interrupt-priority level, ! * the highest vector number wins ! * - Exceptions aren't delivered by the local apic, hardcoded vectors ! * don't imply a certain priority ! * - Hardware IRQs are mapped upside down (IRQ0 = 255, IRQ1 = 254, etc) ! * to enforce the intended priorities ! */ #endif Index: idt.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/idt.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** idt.cpp 22 May 2006 15:18:49 -0000 1.4 --- idt.cpp 2 Jun 2006 21:10:17 -0000 1.5 *************** *** 51,55 **** // Reload the IDTR to activate the IDT ! idt_selector idtr; idtr.base = reinterpret_cast<uint>(idt_pointer); idtr.limit = idt_limit*8 - 1; --- 51,55 ---- // Reload the IDTR to activate the IDT ! idt_register idtr; idtr.base = reinterpret_cast<uint>(idt_pointer); idtr.limit = idt_limit*8 - 1; Index: irq.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/irq.hpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** irq.hpp 22 May 2006 15:18:49 -0000 1.6 --- irq.hpp 2 Jun 2006 21:10:18 -0000 1.7 *************** *** 47,51 **** #include "mutex.hpp" ! #include "exception.hpp" // register structures are defined there for the moment.. struct irq_data --- 47,51 ---- #include "mutex.hpp" ! #include "exception.hpp" // cpu register structures are defined there for the moment.. struct irq_data *************** *** 92,96 **** void DisableIRQ(uint number); ! void SignalEOI (uint number); }; --- 92,96 ---- void DisableIRQ(uint number); ! void SignalEOI(); }; Index: ports.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/ports.hpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ports.hpp 22 May 2006 15:18:49 -0000 1.3 --- ports.hpp 2 Jun 2006 21:10:18 -0000 1.4 *************** *** 49,56 **** public: ! static void SwitchAccessMap(void* port_map); bool EnablePort (ushort port_number); bool DisablePort(ushort port_number); }; --- 49,59 ---- public: ! ports(); ! ~ports(); bool EnablePort (ushort port_number); bool DisablePort(ushort port_number); + + void* GetPortMap() {return port_map; } }; *************** *** 58,69 **** template<port_size t> uint ReadPort(ushort port_number); ! template<> inline uint ReadPort<BYTE> (ushort p){ uchar r; asm("inb %%dx,%%al ":"=a"(r):"dN"(p)); return r;} ! template<> inline uint ReadPort<WORD> (ushort p) {ushort r; asm("inw %%dx,%%ax ":"=a"(r):"dN"(p)); return r;} ! template<> inline uint ReadPort<DWORD>(ushort p) {uint r; asm("ind %%dx,%%eax":"=a"(r):"dN"(p)); return r;} template<port_size t> void WritePort(ushort port_number, uint value); ! template<> inline void WritePort<BYTE> (ushort p, uint v) {asm("outb %%al, %%dx": :"dN"(p), "a"(v));} ! template<> inline void WritePort<WORD> (ushort p, uint v) {asm("outw %%ax, %%dx": :"dN"(p), "a"(v));} ! template<> inline void WritePort<DWORD>(ushort p, uint v) {asm("outd %%eax,%%dx": :"dN"(p), "a"(v));} #endif --- 61,78 ---- template<port_size t> uint ReadPort(ushort port_number); ! template<> ! inline uint ReadPort<BYTE> (ushort p) {uchar r; asm volatile("inb %%dx,%%al ":"=a"(r):"dN"(p)); return r;} ! template<> ! inline uint ReadPort<WORD> (ushort p) {ushort r; asm volatile("inw %%dx,%%ax ":"=a"(r):"dN"(p)); return r;} ! template<> ! inline uint ReadPort<DWORD>(ushort p) {uint r; asm volatile("ind %%dx,%%eax":"=a"(r):"dN"(p)); return r;} template<port_size t> void WritePort(ushort port_number, uint value); ! template<> ! inline void WritePort<BYTE> (ushort p, uint v) {asm volatile("outb %%al, %%dx": :"dN"(p), "a"(v));} ! template<> ! inline void WritePort<WORD> (ushort p, uint v) {asm volatile("outw %%ax, %%dx": :"dN"(p), "a"(v));} ! template<> ! inline void WritePort<DWORD>(ushort p, uint v) {asm volatile("outd %%eax,%%dx": :"dN"(p), "a"(v));} #endif Index: interrupt_stub_code.asm =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/interrupt_stub_code.asm,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** interrupt_stub_code.asm 5 Apr 2006 17:12:00 -0000 1.1 --- interrupt_stub_code.asm 2 Jun 2006 21:10:18 -0000 1.2 *************** *** 49,65 **** align 4 InterruptStubStart: - pusha ! mov ax, 0x10 ! mov ds, ax ! mov es, ax ! mov fs, ax ! mov gs, ax InterruptCallPatch: push dword esp ; Store a copy of the stack-pointer on the stack push dword 0 ; Push the interrupt number on the stack push dword 0 ; Push a pointer to this cpu's hal_object ! push dword 0 ; Move class pointer to the stack (hiddden parameter) call dword $+5 ; Call the C++ interrupt constructor --- 49,70 ---- align 4 InterruptStubStart: ! pusha ; Store current general purpose registers ! ! mov eax, ds ; Save the current selectors on the stack ! push eax ! ! mov eax, 0x10 ; Switch to kernel-mode selectors ! mov ds, ax ! mov es, ax ! mov fs, ax ! mov gs, ax InterruptCallPatch: + push dword esp ; Store a copy of the stack-pointer on the stack push dword 0 ; Push the interrupt number on the stack push dword 0 ; Push a pointer to this cpu's hal_object ! push dword 0 ; Move class pointer to the stack (hidden parameter) call dword $+5 ; Call the C++ interrupt constructor *************** *** 69,83 **** add dword esp, 16 ; Remove all parameters from the stack ! mov ax, 0x10 ! mov ds, ax ! mov es, ax ! mov fs, ax ! mov gs, ax ! popa InterruptReturnPatch: ! add dword esp, 4 ; Get rid of the error-code on the stack ! iret align 4 --- 74,89 ---- add dword esp, 16 ; Remove all parameters from the stack ! pop eax ; Restore original selectors ! mov ds, ax ! mov es, ax ! mov fs, ax ! mov gs, ax ! popa ; Restore general purpose registers InterruptReturnPatch: ! ! add dword esp, 4 ; Get rid of the error-code on the stack ! iret ; Return to the interrupted task align 4 Index: systemcall.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/systemcall.cpp,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** systemcall.cpp 7 Jan 2006 16:39:33 -0000 1.1.1.1 --- systemcall.cpp 2 Jun 2006 21:10:18 -0000 1.2 *************** *** 9,13 **** // ----------------------------------------------------------------------- ! // Copyright (C) 2003, Trion Development Group Members // All rights reserved. // --- 9,13 ---- // ----------------------------------------------------------------------- ! // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // *************** *** 38,40 **** // ----------------------------------------------------------------------- ! #include <systemcall.hpp> \ No newline at end of file --- 38,114 ---- // ----------------------------------------------------------------------- ! #include "systemcall.hpp" ! ! #include "../loader/console.hpp" ! #include "../loader/heap_manager.hpp" ! #include "hal_object.hpp" ! #include "cpu_info.hpp" ! ! extern "C" void SystemcallEntrypoint(); ! extern "C" void SystemcallReturnpoint(uint, uint); ! ! systemcall::systemcall() ! { ! // Check if the SEP mechanism is supported (CPUID) ! if(!info().GetProcessorInfo().sysenter) ! { ! cout() << "Your system doesn't meet the minimum requirements (SYSENTER)" << endl; ! while(true); ! } ! ! /** Note that the following extraction of a plain function pointer from a member function pointer ! * is not compliant with the C++ standard, but rather bases on an GNU gcc extention to the ! * language. On any other system it will thus cause an error at compile-time. ! * The compiler flag -Wno-pmf-conversions enables the extention, refere to the gcc man pages for ! * more detailed information. ! */ ! ! typedef void (systemcall::*method)(message_register*); ! typedef void (*flat) (systemcall*, message_register*); ! ! flat flat_dispatcher = (flat)(this->*(&systemcall::SystemcallDispatcher)); ! ! // Create a new systemcall stub for our processor ! uint size = reinterpret_cast<uint>(SystemcallReturnpoint) - reinterpret_cast<uint>(SystemcallEntrypoint); ! void* stub = heap().AllocateMemory(size); ! ! uint* source = (uint*) SystemcallEntrypoint; ! uint* dest = static_cast<uint*>(stub); ! ! for(uint i=0; i < size/4; i++) ! dest[i] = source[i]; ! ! // Patch the just created systemcall stub ! PatchAddress(stub, 0x24, boot_hal->processor_number); ! PatchAddress(stub, 0x14, reinterpret_cast<uint>(this)); ! PatchRelativeCall(stub, 0x19, (void*) flat_dispatcher); ! ! // Initialize the SEP MSRs with standard values ! info().WriteLoMSR(SYSENTER_EIP_MSR, reinterpret_cast<uint>(stub)); ! info().WriteLoMSR(SYSENTER_CS_MSR, 0x08); ! info().WriteLoMSR(SYSENTER_ESP_MSR, boot_hal->kernel_stack_base); ! } ! ! void systemcall::PatchAddress(void* stub_base, uint offset, uint value) ! { ! *reinterpret_cast<uint*>(reinterpret_cast<uint>(stub_base) + offset + 1) = value; ! } ! ! void systemcall::PatchRelativeCall(void* stub_base, uint offset, void* handler) ! { ! uint* dest = reinterpret_cast<uint*>(reinterpret_cast<uint>(stub_base) + offset + 1); ! *dest = (uint)((int)((uint)handler &0xFFFFFF) - (int)(((uint)dest + 4) &0xFFFFFF)); ! } ! ! void systemcall::SystemcallDispatcher(message_register* msg, uint* esp, uint eip) ! { ! cout() << "Executed a systemcall" << endl << endl; ! asm("sti"); ! ! InvokeUserTask(eip, reinterpret_cast<uint>(esp)); ! } ! ! void systemcall::InvokeUserTask(uint instruction_pointer, uint stack_pointer) ! { ! SystemcallReturnpoint(instruction_pointer, stack_pointer); ! } Index: cpu_info.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/cpu_info.hpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** cpu_info.hpp 22 May 2006 15:18:48 -0000 1.2 --- cpu_info.hpp 2 Jun 2006 21:10:17 -0000 1.3 *************** *** 91,94 **** --- 91,97 ---- uint ReadHiMSR(uint number); + void WriteLoMSR(uint number, uint data); + void WriteHiMSR(uint number, uint data); + void ModifyLoMSR(uint number, uint mask, uint data); void ModifyHiMSR(uint number, uint mask, uint data); --- NEW FILE: task_context.cpp --- // ----------------------------------------------------------------------- // task_context - Allows the task context to be set-up // // Author(s) : // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. 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. // 3. Neither the name of the Trion Development Group nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT // OWNER OR CONTRIBUTORS 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. // ----------------------------------------------------------------------- #include "task_context.hpp" #include "../loader/console.hpp" #include "hal_object.hpp" gdt_register gdtr; task_context::task_context() { // As the stack-pointer is obtained from the TSS on inter privilege-level // interrupts, we need to install at least one TSS descriptor per CPU asm("sgdt gdtr"); // Obtain the GDT's base address uint tss_slot = FindAvailableGDTSlot(); InitializeTaskSegment(0x10, boot_hal->kernel_stack_base); CreateTaskDescriptor(tss_slot); SetTaskRegister(tss_slot); } void task_context::InitializeTaskSegment(uint stack_descriptor, uint stack_pointer) { uint* tss_pointer = reinterpret_cast<uint*>(&tss); for(uint i=0; i<sizeof(tss)/4;i++) tss_pointer[i] = 0; tss.prev_task = tss.ldt_selector = 0; tss.debug_trap = tss.io_map = 0; tss.ss0 = stack_descriptor; tss.esp0 = stack_pointer; } uint task_context::FindAvailableGDTSlot() { uint* gdt_pointer = reinterpret_cast<uint*>(gdtr.base); for(uint i=3; i < (gdtr.limit + 1)/8; i += 2) { if((gdt_pointer[i] &0x8000) == 0) // Check the present flag return i/2; } } void task_context::CreateTaskDescriptor(uint gdt_slot) { uint* gdt_pointer = reinterpret_cast<uint*>(gdtr.base); uint tss_address = reinterpret_cast<uint>(&tss); gdt_pointer[gdt_slot*2 + 0] = (tss_address << 16) | 0x67; gdt_pointer[gdt_slot*2 + 1] = (tss_address >> 16) &0xFF | 0x808900 | (tss_address &0xFF000000); } void task_context::SetTaskRegister(uint descriptor_number) { asm("ltr %%ax" : : "a"(descriptor_number*8)); } void task_context::SetKernelStack(uint stack_pointer) { tss.esp0 = stack_pointer; } void task_context::SetPageDirectory(mmu* context) { asm("movl %%eax, %%cr3" : : "a"(context->GetPageDirectory())); } void task_context::SetPortMap(ports* context) { tss.io_map = reinterpret_cast<uint>(context->GetPortMap()); } Index: interrupt.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/interrupt.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** interrupt.cpp 22 May 2006 15:18:49 -0000 1.3 --- interrupt.cpp 2 Jun 2006 21:10:18 -0000 1.4 *************** *** 72,88 **** void* current = boot_hal->vector->GetTableEntry(i); ! if(current != 0) ! { ! interrupt_stub stub(current); ! if(stub.GetHandlerFunction() == flat_handler && stub.GetHandlerObject() == p_class && ! stub.GetHalObject() == boot_hal && stub.GetErrorCode() == error) { ! if(number == stub.GetInterruptNumber() || ignore == true) ! { ! // Use the already existing interrupt stub (sharing saves memory) ! boot_hal->vector->SetTableEntry(number, stub.GetStubAddress(), trap); ! return true; ! } } } --- 72,85 ---- void* current = boot_hal->vector->GetTableEntry(i); ! interrupt_stub stub(current); ! if(stub.GetHandlerFunction() == flat_handler && stub.GetHandlerObject() == p_class && ! stub.GetHalObject() == boot_hal && stub.GetErrorCode() == error) ! { ! if(number == stub.GetInterruptNumber() || ignore == true) { ! // Use the already existing interrupt stub (sharing saves memory) ! boot_hal->vector->SetTableEntry(number, stub.GetStubAddress(), trap); ! return true; } } |
From: Daniel R. <co...@us...> - 2006-06-02 21:04:30
|
Update of /cvsroot/trion/trion v0.2 In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv10146 Modified Files: makefile Log Message: no message Index: makefile =================================================================== RCS file: /cvsroot/trion/trion v0.2/makefile,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** makefile 22 May 2006 15:17:59 -0000 1.13 --- makefile 2 Jun 2006 21:04:26 -0000 1.14 *************** *** 56,68 **** loader/mp_detect.cpp \ hal/cpu_info.cpp \ hal/interrupt_stub.cpp \ hal/interrupt.cpp \ hal/idt.cpp \ hal/exception.cpp \ hal/mmu.cpp \ hal/ports.cpp \ hal/mutex.cpp \ hal/apic_local.cpp \ - hal/apic_error.cpp \ hal/apic_io.cpp \ hal/timer.cpp \ --- 56,69 ---- loader/mp_detect.cpp \ hal/cpu_info.cpp \ + hal/systemcall.cpp \ hal/interrupt_stub.cpp \ hal/interrupt.cpp \ hal/idt.cpp \ hal/exception.cpp \ + hal/task_context.cpp \ hal/mmu.cpp \ hal/ports.cpp \ hal/mutex.cpp \ hal/apic_local.cpp \ hal/apic_io.cpp \ hal/timer.cpp \ *************** *** 73,78 **** CHDRS = $(CSCRS:.cpp=.hpp) ! ASRCS = loader/pmode.asm \ ! hal/interrupt_stub_code.asm AOBJS = $(ASRCS:.asm=.o) --- 74,80 ---- CHDRS = $(CSCRS:.cpp=.hpp) ! ASRCS = hal/interrupt_stub_code.asm \ ! hal/systemcall_stub_code.asm \ ! loader/pmode.asm AOBJS = $(ASRCS:.asm=.o) |
From: Daniel R. <co...@us...> - 2006-05-22 15:19:15
|
Update of /cvsroot/trion/trion v0.2/loader In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv9144 Modified Files: heap_manager.cpp main.cpp mp_detect.cpp mp_detect.hpp Log Message: no message Index: mp_detect.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/mp_detect.hpp,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** mp_detect.hpp 13 Apr 2006 20:06:00 -0000 1.9 --- mp_detect.hpp 22 May 2006 15:19:08 -0000 1.10 *************** *** 140,143 **** --- 140,144 ---- iterator(); iterator(const iterator& it); + iterator(SmpConfigEntry* address); bool operator==(iterator it); *************** *** 176,179 **** --- 177,182 ---- bool BootProcessor(iterator cpu); uint BootAllProcessors(); + + uint EnableHyperthreading(); }; Index: main.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/main.cpp,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** main.cpp 30 Apr 2006 19:21:57 -0000 1.16 --- main.cpp 22 May 2006 15:19:08 -0000 1.17 *************** *** 51,54 **** --- 51,55 ---- #include "../hal/exception.hpp" #include "../hal/apic_local.hpp" + #include "../hal/apic_error.hpp" #include "../hal/timer.hpp" #include "../hal/irq.hpp" *************** *** 59,62 **** --- 60,65 ---- extern "C" int main(uint image_size, uint processor, uint magic, void* grub) { + uint number_processors = 0x01; + if(processor == 0) { *************** *** 65,75 **** new (cpu_info_reserved) cpu_info(); ! // Spawn an instance of all hal classes.. hal_object* hal = boot_hal = heap().CreateHalObject(); ! hal->memory = new (heap().AllocateMemory(sizeof(mmu))) mmu(); ! hal->int_vec = new (heap().AllocateMemory(sizeof(idt))) idt(); ! hal->faults = new (heap().AllocateMemory(sizeof(exception))) exception(); ! // Create a console object to print debug messages new (console_reserved) console(); --- 68,76 ---- new (cpu_info_reserved) cpu_info(); ! // Spawn an instance of the mmu class hal_object* hal = boot_hal = heap().CreateHalObject(); ! hal->memory = new (heap().AllocateMemory(sizeof(mmu))) mmu(); ! // Create a console object to be able to print debug messages new (console_reserved) console(); *************** *** 77,107 **** cout() << "Welcome to Trion v0.2" << endl; ! // Initialize I/O Apics and boot all application processors mp_detect* multi = new (mp_detect_reserved) mp_detect(); hal->lapic = new (heap().AllocateMemory(sizeof(local_apic))) local_apic(); hal->clock = new (heap().AllocateMemory(sizeof(timer))) timer(); hal->inter = new (heap().AllocateMemory(sizeof(ipi))) ipi(); - hal->ireq = new (heap().AllocateMemory(sizeof(irq_logic))) irq_logic(); - uint num_cpu = multi->BootAllProcessors(); - - cout() << endl << "All " << num_cpu << " processors have been booted" << endl; - // cout() << "You may now type something:" << endl << endl ; ! cout() << endl << "Checking whether the local APIC works: "; ! boot_hal->clock->SetTimer(timer_id(current), 0x1000000); ! while(boot_hal->clock->GetTimer(timer_id(current)) == 0); ! while(boot_hal->clock->GetTimer(timer_id(current)) != 0); ! cout() << "yep" << endl << endl; ! cout() << "Test if there's a standard I/O APIC:" << endl; ! io_apic check(0xfec00000); ! cout() << "APIC ID: " << (uint) check.GetApicID() << endl; ! cout() << "Version: " << (uint) check.GetVersion() << endl; ! cout() << "Max Red: " << (uint) check.GetMaxRedirect() << endl; ! // Enable interrupts and wait for IRQs ! // asm("sti"); while(true) asm("hlt"); } --- 78,105 ---- cout() << "Welcome to Trion v0.2" << endl; ! // Enable the IDT and activate exception handling ! hal->vector = new (heap().AllocateMemory(sizeof(idt))) idt(); ! hal->faults = new (heap().AllocateMemory(sizeof(exception))) exception(); ! ! // Initialize the local APIC and activate all I/O APICs mp_detect* multi = new (mp_detect_reserved) mp_detect(); hal->lapic = new (heap().AllocateMemory(sizeof(local_apic))) local_apic(); + hal->error = new (heap().AllocateMemory(sizeof(apic_error))) apic_error(); hal->clock = new (heap().AllocateMemory(sizeof(timer))) timer(); hal->inter = new (heap().AllocateMemory(sizeof(ipi))) ipi(); ! new (irq_logic_reserved) irq_logic(); ! // Enable hyperthreading and try to boot all application processors ! number_processors += multi->EnableHyperthreading(); ! number_processors += multi->BootAllProcessors(); ! cout() << endl << "All " << number_processors << " processors have been booted" << endl; ! cout() << "You may now type something:" << endl << endl ; ! // Enable the keyboard interrupts and wait for IRQs ! irq().EnableIRQ(1); ! asm("sti"); while(true) asm("hlt"); } *************** *** 115,126 **** hal->memory = new (heap().AllocateMemory(sizeof(mmu))) mmu(); ! hal->int_vec = new (heap().AllocateMemory(sizeof(idt))) idt(); hal->faults = new (heap().AllocateMemory(sizeof(exception))) exception(); hal->lapic = new (heap().AllocateMemory(sizeof(local_apic))) local_apic(); hal->clock = new (heap().AllocateMemory(sizeof(timer))) timer(); hal->inter = new (heap().AllocateMemory(sizeof(ipi))) ipi(); - // hal->ireq = new (heap().AllocateMemory(sizeof(irq_logic))) irq_logic(); ! ap_flag |= 2; // Indicates that the hal is fully initialized, next AP may be started } } --- 113,130 ---- hal->memory = new (heap().AllocateMemory(sizeof(mmu))) mmu(); ! hal->vector = new (heap().AllocateMemory(sizeof(idt))) idt(); hal->faults = new (heap().AllocateMemory(sizeof(exception))) exception(); + hal->lapic = new (heap().AllocateMemory(sizeof(local_apic))) local_apic(); + hal->error = new (heap().AllocateMemory(sizeof(apic_error))) apic_error(); hal->clock = new (heap().AllocateMemory(sizeof(timer))) timer(); hal->inter = new (heap().AllocateMemory(sizeof(ipi))) ipi(); ! number_processors += multiprocessor().EnableHyperthreading(); ! ! ap_flag |= 2; // Indicates that the hal is fully initialized, next AP may get started ! ! asm("sti"); ! while(true) asm("hlt"); } } Index: mp_detect.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/mp_detect.cpp,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** mp_detect.cpp 20 Apr 2006 18:54:01 -0000 1.11 --- mp_detect.cpp 22 May 2006 15:19:08 -0000 1.12 *************** *** 43,46 **** --- 43,47 ---- #include "../hal/timer.hpp" #include "../hal/ipi.hpp" + #include "../hal/cpu_info.hpp" extern "C" unsigned char ap_code_start[]; *************** *** 230,235 **** uint apic_id = GetLocalApicID(cpu); - boot_hal->inter->SendInitIPI(apic_id); boot_hal->inter->SendStartupIPI(apic_id); boot_hal->inter->SendStartupIPI(apic_id); --- 231,236 ---- uint apic_id = GetLocalApicID(cpu); + boot_hal->inter->SendInitIPI (apic_id); boot_hal->inter->SendStartupIPI(apic_id); boot_hal->inter->SendStartupIPI(apic_id); *************** *** 247,251 **** { bool result = true; ! uint num_cpu = 1; for(iterator entry = begin(TYPE_CPU); entry != end(); entry++) --- 248,252 ---- { bool result = true; ! uint num_cpu = 0; for(iterator entry = begin(TYPE_CPU); entry != end(); entry++) *************** *** 260,263 **** --- 261,305 ---- } + uint mp_detect::EnableHyperthreading() + { + uint processors = 0; + + if(info().GetProcessorInfo().hyper_threading) + { + // On hyperthreading CPUs the APIC ID is split into two parts: package ID and logical ID + // The logical ID field are the lower n bytes of the APIC ID, its actual size depends on + // the number of logical processors per physical package: log2(logical_per_package) + + // Get the number of logical processors per physical CPU + uint number_logical = ((info().cpuid<cpu_info::EBX>(1) >> 16) &0xff); + uint current_logical = boot_hal->lapic->GetPhysicalID() &(number_logical-1); + + if(current_logical++ == 0) // Primary CPU is always booted first + { + for(uint i = current_logical; i < number_logical; i++) + { + // Cyle through the logical processors and send an SIPI-SIPI_INIT sequence to each of them + heap().AllocateApStack(); + ap_flag = 0; + + uint apic_id = (boot_hal->lapic->GetPhysicalID() &(0xffffffff - (number_logical-1))) | i; + + boot_hal->inter->SendInitIPI (apic_id); + boot_hal->inter->SendStartupIPI(apic_id); + boot_hal->inter->SendStartupIPI(apic_id); + + boot_hal->clock->SetTimer(timer_id(current), 0x1000000); + + // Check if the processor responds - if so, wait until it finished booting + while(boot_hal->clock->GetTimer(timer_id(current)) > 0 && !(ap_flag &1)); + while(ap_flag &1 && !(ap_flag &2)); + + if(ap_flag) processors++; + } + } + } + return processors; + } + iterator::iterator() { *************** *** 273,276 **** --- 315,324 ---- } + iterator::iterator(SmpConfigEntry* address) + { + this->address = address; + last_entry = entry = 0; + } + SmpConfigEntry* iterator::GetNext(SmpConfigEntry* current) { Index: heap_manager.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/loader/heap_manager.cpp,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** heap_manager.cpp 30 Apr 2006 19:21:57 -0000 1.9 --- heap_manager.cpp 22 May 2006 15:19:08 -0000 1.10 *************** *** 101,105 **** hal_object* heap_manager::CreateHalObject() { ! return reinterpret_cast<hal_object*>(AllocateMemory(sizeof(hal_object))); } --- 101,110 ---- hal_object* heap_manager::CreateHalObject() { ! uchar* hal = static_cast<uchar*>(AllocateMemory(sizeof(hal_object))); ! ! for(uint i=0; i < sizeof(hal_object); i++) ! hal[i] = 0x00; ! ! return reinterpret_cast<hal_object*>(hal); } |
From: Daniel R. <co...@us...> - 2006-05-22 15:18:56
|
Update of /cvsroot/trion/trion v0.2/hal In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv8777 Modified Files: apic_io.cpp apic_io.hpp apic_local.cpp apic_local.hpp cpu_info.cpp cpu_info.hpp exception.cpp exception.hpp hal_object.hpp idt.cpp interrupt.cpp interrupt.hpp irq.cpp irq.hpp mutex.cpp mutex.hpp ports.hpp Added Files: apic_error.cpp apic_error.hpp Log Message: no message Index: exception.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/exception.hpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** exception.hpp 5 Apr 2006 17:12:00 -0000 1.6 --- exception.hpp 22 May 2006 15:18:49 -0000 1.7 *************** *** 42,73 **** #include "../object/std_types.hpp" #include "hal_object.hpp" #include "interrupt.hpp" ! enum register_id { ! EAX = 7, EBX = 4, ECX = 6, EDX = 5, ! ESI = 1, EDI = 0, ESP = 12, EBP = 2, ! CS = 10, EIP = 9, SS = 13, ! EFLAGS = 11, ERROR_CODE = 8 ! }; class exception : public interrupt { private: - uint exception_number; - bool error_code, handler_running; - uint* stack_pointer; - static bool error_code_map[32], trap_gate_map[32]; ! void PrintAllRegisters(); ! void SetRegisterValue(register_id reg, uint value); ! uint GetRegisterValue(register_id reg); ! void ChangeReturnAddress(ushort selector, uint offset); ! void ChangeStackAddress (ushort selector, uint offset); bool AddHandler (uint number, exception* p_class, method handler); --- 42,76 ---- #include "../object/std_types.hpp" + #include "hal_object.hpp" #include "interrupt.hpp" ! struct segment_registers { ! uint eip, cs; ! uint eflags; ! uint esp, ss; ! }__attribute__ ((__packed__)); ! ! struct general_registers ! { ! uint edi, esi, ebp, ignore; ! uint ebx, edx, ecx, eax; ! ! }__attribute__ ((__packed__)); class exception : public interrupt { private: static bool error_code_map[32], trap_gate_map[32]; ! segment_registers* segment_regs; ! general_registers* general_regs; ! uint exception_number, error_code; ! bool handler_running; ! void PrintAllRegisters(); bool AddHandler (uint number, exception* p_class, method handler); Index: cpu_info.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/cpu_info.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** cpu_info.cpp 30 Apr 2006 19:21:34 -0000 1.1 --- cpu_info.cpp 22 May 2006 15:18:48 -0000 1.2 *************** *** 42,46 **** cpu_flags cpu_info::GetProcessorInfo() { ! uint ret = cpuid<EAX>(0x01); return *reinterpret_cast<cpu_flags*>(&ret); } --- 42,46 ---- cpu_flags cpu_info::GetProcessorInfo() { ! uint ret = cpuid<EDX>(0x01); return *reinterpret_cast<cpu_flags*>(&ret); } Index: ports.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/ports.hpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ports.hpp 13 Apr 2006 20:02:49 -0000 1.2 --- ports.hpp 22 May 2006 15:18:49 -0000 1.3 *************** *** 58,66 **** template<port_size t> uint ReadPort(ushort port_number); ! template<> inline uint ReadPort<BYTE> (ushort p) {uchar r; asm("inb %%dx,%%al ":"=a"(r):"dN"(p)); return r;} template<> inline uint ReadPort<WORD> (ushort p) {ushort r; asm("inw %%dx,%%ax ":"=a"(r):"dN"(p)); return r;} template<> inline uint ReadPort<DWORD>(ushort p) {uint r; asm("ind %%dx,%%eax":"=a"(r):"dN"(p)); return r;} ! template<port_size t> void WritePort(ushort port_number, uint data); template<> inline void WritePort<BYTE> (ushort p, uint v) {asm("outb %%al, %%dx": :"dN"(p), "a"(v));} template<> inline void WritePort<WORD> (ushort p, uint v) {asm("outw %%ax, %%dx": :"dN"(p), "a"(v));} --- 58,66 ---- template<port_size t> uint ReadPort(ushort port_number); ! template<> inline uint ReadPort<BYTE> (ushort p){ uchar r; asm("inb %%dx,%%al ":"=a"(r):"dN"(p)); return r;} template<> inline uint ReadPort<WORD> (ushort p) {ushort r; asm("inw %%dx,%%ax ":"=a"(r):"dN"(p)); return r;} template<> inline uint ReadPort<DWORD>(ushort p) {uint r; asm("ind %%dx,%%eax":"=a"(r):"dN"(p)); return r;} ! template<port_size t> void WritePort(ushort port_number, uint value); template<> inline void WritePort<BYTE> (ushort p, uint v) {asm("outb %%al, %%dx": :"dN"(p), "a"(v));} template<> inline void WritePort<WORD> (ushort p, uint v) {asm("outw %%ax, %%dx": :"dN"(p), "a"(v));} Index: cpu_info.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/cpu_info.hpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** cpu_info.hpp 30 Apr 2006 19:21:34 -0000 1.1 --- cpu_info.hpp 22 May 2006 15:18:48 -0000 1.2 *************** *** 81,85 **** class cpu_info { ! private: enum register_id { EAX, EBX, ECX, EDX }; template<register_id r> uint cpuid(uint function); --- 81,85 ---- class cpu_info { ! public: enum register_id { EAX, EBX, ECX, EDX }; template<register_id r> uint cpuid(uint function); *************** *** 103,117 **** template<> inline uint cpu_info::cpuid<cpu_info::EBX>(uint f) { ! uint r; asm("cpuid":"=b"(r):"a"(f):"%eax","%ecx","%edx"); return r; } template<> inline uint cpu_info::cpuid<cpu_info::ECX>(uint f) { ! uint r; asm("cpuid":"=c"(r):"a"(f):"%eax","%ebx","%edx"); return r; } template<> inline uint cpu_info::cpuid<cpu_info::EDX>(uint f) { ! uint r; asm("cpuid":"=d"(r):"a"(f):"%eax","%ebx","%ecx"); return r; } --- 103,117 ---- template<> inline uint cpu_info::cpuid<cpu_info::EBX>(uint f) { ! uint r; asm("cpuid":"=b"(r):"a"(f):"%ecx","%edx"); return r; } template<> inline uint cpu_info::cpuid<cpu_info::ECX>(uint f) { ! uint r; asm("cpuid":"=c"(r):"a"(f):"%ebx","%edx"); return r; } template<> inline uint cpu_info::cpuid<cpu_info::EDX>(uint f) { ! uint r; asm("cpuid":"=d"(r):"a"(f):"%ebx","%ecx"); return r; } Index: hal_object.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/hal_object.hpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** hal_object.hpp 7 Apr 2006 17:15:53 -0000 1.4 --- hal_object.hpp 22 May 2006 15:18:49 -0000 1.5 *************** *** 43,52 **** struct hal_object { ! class exception* faults; ! class idt* int_vec; class local_apic* lapic; class ipi* inter; class timer* clock; - class irq_logic* ireq; class mmu* memory; }; --- 43,52 ---- struct hal_object { ! class idt* vector; class local_apic* lapic; + class apic_error* error; + class exception* faults; class ipi* inter; class timer* clock; class mmu* memory; }; --- NEW FILE: apic_error.hpp --- // ----------------------------------------------------------------------- // apic_error.cpp - Handles local apic errors and spurious interrupts // // Author(s) : // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. 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. // 3. Neither the name of the Trion Development Group nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT // OWNER OR CONTRIBUTORS 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. // ----------------------------------------------------------------------- #ifndef __HAL__APIC_ERROR__ #define __HAL__APIC_ERROR__ #include "../object/std_types.hpp" #include "interrupt.hpp" class apic_error : public interrupt { private: void InterruptConstructor(hal_object* hal, uchar interrupt_number, uint* esp); void InterruptDestructor (hal_object* hal, uchar interrupt_number, uint* esp); enum error_types { send_checksum = 1, receive_checksum = 2, send_accept = 4, receive_accept = 8, send_vector = 32, receive_vector = 64, illegal_register = 128 }; uint GetErrorCode(); void ClearErrorRegister(); public: apic_error(); void InterruptError(hal_object* hal); void SpuriousInterrupt(hal_object* hal); }; #endif Index: apic_io.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/apic_io.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** apic_io.cpp 13 Apr 2006 20:00:50 -0000 1.4 --- apic_io.cpp 22 May 2006 15:18:48 -0000 1.5 *************** *** 45,49 **** io_apic::io_apic(uint phys_address) { ! if(phys_address == 0xFEC00000) // First IO APIC in the system { page_base = static_cast<uint*>(heap().CreatePhysicalWindow(0xfec00000)); --- 45,49 ---- io_apic::io_apic(uint phys_address) { ! if(page_base == 0) // First IO APIC in the system { page_base = static_cast<uint*>(heap().CreatePhysicalWindow(0xfec00000)); *************** *** 79,86 **** { ioapic_int interrupt = {0}; ! interrupt.pin_polarity = polarity; ! interrupt.level = level; ! interrupt.mode = mode; ! interrupt.masked = true; SetInterruptFlags(number, interrupt); --- 79,86 ---- { ioapic_int interrupt = {0}; ! interrupt.pin_polarity = polarity; ! interrupt.level = level; ! interrupt.delivery = mode; ! interrupt.masked = true; SetInterruptFlags(number, interrupt); --- NEW FILE: apic_error.cpp --- // ----------------------------------------------------------------------- // apic_error.cpp - Handles local apic errors and spurious interrupts // // Author(s) : // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. 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. // 3. Neither the name of the Trion Development Group nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT // OWNER OR CONTRIBUTORS 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. // ----------------------------------------------------------------------- #include "apic_error.hpp" #include "../loader/console.hpp" apic_error::apic_error() { // Enable the error-interrupt and assign a vector to it uint apic_error_vector = 255 - 0; lapic_lvt lvt = GetLVT(lapic_reg(LVTERR)); lvt.masked = false; lvt.vector = apic_error_vector; SetLVT(lapic_reg(LVTERR), lvt); // Assign a vector to the spurious interupt uint spurious_vector = 255 - 1; WriteRegister(lapic_reg(SIVR), ReadRegister(lapic_reg(SIVR)) | spurious_vector); // Install our two error-handling interrupts AddHandler(apic_error_vector, false, this, (method) &apic_error::InterruptError, false, false); AddHandler(spurious_vector, false, this, (method) &apic_error::SpuriousInterrupt, false, false); ClearErrorRegister(); } void apic_error::InterruptConstructor(hal_object* hal, uchar interrupt_number, uint* esp) { } void apic_error::InterruptDestructor(hal_object* hal, uchar interrupt_number, uint* esp) { } uint apic_error::GetErrorCode() { // Write to the register to update it, then read it out WriteRegister(lapic_reg(ESR), 0); return ReadRegister(lapic_reg(ESR)); } void apic_error::ClearErrorRegister() { // Two sucessive writes clear the error register WriteRegister(lapic_reg(ESR), 0); WriteRegister(lapic_reg(ESR), 0); } void apic_error::InterruptError(hal_object* hal) { cout() << "Panic: A local APIC error was reported (" << GetErrorCode() << ")" << endl; while(true); } void apic_error::SpuriousInterrupt(hal_object* hal) { cout() << "Panic: A spurious interrupt was reported" << endl; while(true); } Index: irq.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/irq.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** irq.cpp 30 Apr 2006 19:21:34 -0000 1.5 --- irq.cpp 22 May 2006 15:18:49 -0000 1.6 *************** *** 41,132 **** #include "ports.hpp" #include "hal_object.hpp" #include "../loader/console.hpp" ! irq_logic::irq_logic() : handler_running(false) { ! if(boot_hal->lapic->GetPhysicalID() == 0) { ! DisableLegacyPIC(); ! // Detect which buses are installed on the system ! uint number_buses = multiprocessor().GetNumberEntries(TYPE_BUS); ! uint* bus_table = static_cast<uint*>(heap().AllocateMemory(number_buses*sizeof(uint))); ! DetectSystemBuses(bus_table); ! // Walk trough the multiprocessor table and initialize any I/O Apic found ! uint number_apics = multiprocessor().GetNumberEntries(TYPE_IO_APIC); ! apic_table = static_cast<io_apic**>(heap().AllocateMemory(number_apics*sizeof(io_apic*))); ! uint counter = 0; ! for(iterator it = multiprocessor().begin(TYPE_IO_APIC); it != multiprocessor().end(); it++) { ! apic_table[counter] = InitializeIOApic(it, bus_table); ! counter++; } ! // EnableIRQ(1); // Unmask the keyboard IRQ } // Install necessary interrupt handlers ! for(uint i=0x20; i<0x38; i++) { ! AddHandler(i, false, this, (method)&irq_logic::DispatchIRQ, false, false); } } ! void irq_logic::DisableLegacyPIC() { // Before we can diable the ISA PIC we first have to initialize it ! WritePort<BYTE>(0x20, 0x11); // Initialize (16), ICW4 needed (1) WritePort<BYTE>(0xA0, 0x11); ! WritePort<BYTE>(0x21, 0x00); // vector offset master PIC ! WritePort<BYTE>(0xA1, 0x00); // vector offset slave PIC ! WritePort<BYTE>(0x21, 4); // IRQ #2 used for cascading ! WritePort<BYTE>(0xA1, 2); // Set slave ID ! WritePort<BYTE>(0x21, 1); // x86 mode, no auto EOI, etc WritePort<BYTE>(0xA1, 1); // Now mask all of its IRQs ! WritePort<BYTE>(0x21, 0xff); // IRQs 00-07 ! WritePort<BYTE>(0xA1, 0xff); // IRQs 08-15 } ! uint irq_logic::DetectSystemBuses(uint* bus_table) { // In the multiprocessor tables the buses are described by a 6 character ASCII string, // we'll chop the string to a 32bit value, so that it fits into an ordinary dword - uint counter = 0; for(iterator it = multiprocessor().begin(TYPE_BUS); it != multiprocessor().end(); it++) { ! uchar* string = static_cast<SmpConfigBus*>(*it)->TypeString; ! uint buffer = 0; ! ! for(uint i=0; i < 4; i++) { ! buffer <<= 8; ! buffer += string[i]; } - bus_table[counter++] = buffer; } ! return counter; } ! io_apic* irq_logic::InitializeIOApic(iterator it, uint* bus_table) { ! // Spawn an new instance of the apic class for this I/O Apic uint base_address = static_cast<SmpConfigIOApic*>(*it)->BaseAddr; io_apic* apic = new (heap().AllocateMemory(sizeof(io_apic))) io_apic(base_address); ! // Populate the Apic's IRQ redirection entries with default values for(uint i=0; i <= apic->GetMaxRedirect(); i++) { bool irq_type = (i > 15) ? true : false; ! apic->SetInterruptType(i, irq_type, irq_type, ioapic_int::fixed); ! apic->SetInterruptReceiver(i, 0, 0x20 + i, false); } uint counter = 0; --- 41,171 ---- #include "ports.hpp" #include "hal_object.hpp" + #include "../loader/heap_manager.hpp" #include "../loader/console.hpp" ! irq_logic::irq_logic() : instance(0) { ! InitializeLegacyPIC(); ! ! // Detect how many I/O APICs are installed on the system ! uint number_devices = multiprocessor().GetNumberEntries(TYPE_IO_APIC); ! ! device_table = static_cast<irq_dev*>(heap().AllocateMemory(number_devices*sizeof(irq_dev))); ! uint counter = 0; ! ! // Walk through the multiprocessor table and initialize any I/O APIC found ! for(iterator it = multiprocessor().begin(TYPE_IO_APIC); it != multiprocessor().end(); it++) { ! device_table[counter] = InitializeIOApic(it); ! counter++; ! cout() << "Detected an I/O APIC by searching the multiprocessor table" << endl; ! } ! if(number_devices == 0) ! { ! // Some uniprocessor systems don't support the multiprocessor standard although they do ! // have an I/O APIC. If the APIC isn't reported, we might just have to probe for it.. ! io_apic probe(0xfec00000); ! ! if(probe.GetVersion() >= 0x10 && probe.GetVersion() <= 0x20) // sanity check { ! device_table = static_cast<irq_dev*>(heap().AllocateMemory(sizeof(irq_dev))); ! ! SmpConfigIOApic dummy; ! dummy.Type = TYPE_IO_APIC; ! dummy.ApicID = 2; ! dummy.BaseAddr = 0xfec00000; ! ! device_table[0] = InitializeIOApic(iterator(&dummy)); ! number_devices++; ! ! cout() << "Detected an I/O APIC by probing for it" << endl; } ! } ! ! if(number_devices == 0) ! { ! // No APIC found, will use ISA PIC legacy node ! device_table = static_cast<irq_dev*>(heap().AllocateMemory(sizeof(irq_dev))); ! device_table[0].legacy_pic = true; ! device_table[0].number_irqs = 0x10; ! ! number_devices++; ! ! cout() << "Using ISA PIC legacy mode" << endl; } // Install necessary interrupt handlers ! for(uint i=0, k=255-32; i<number_devices; i++) { ! for(uint j=0; j < device_table[i].number_irqs; j++) ! { ! AddHandler(k, false, this, (method)&irq_logic::DispatchIRQ, false, false); ! k--; ! } } } ! void irq_logic::InitializeLegacyPIC() { // Before we can diable the ISA PIC we first have to initialize it ! WritePort<BYTE>(0x20, 0x11); // Initialize (16), ICW4 needed (1) WritePort<BYTE>(0xA0, 0x11); ! WritePort<BYTE>(0x21, 255-47); // vector offset master PIC ! WritePort<BYTE>(0xA1, 255-39); // vector offset slave PIC ! WritePort<BYTE>(0x21, 4); // IRQ #2 used for cascading ! WritePort<BYTE>(0xA1, 2); // Set slave ID ! WritePort<BYTE>(0x21, 1); // x86 mode, no auto EOI, etc WritePort<BYTE>(0xA1, 1); // Now mask all of its IRQs ! WritePort<BYTE>(0x21, 0xff); // IRQs 00-07 ! WritePort<BYTE>(0xA1, 0xff); // IRQs 08-15 } ! uint irq_logic::DetectSystemBus(uint bus_number) { // In the multiprocessor tables the buses are described by a 6 character ASCII string, // we'll chop the string to a 32bit value, so that it fits into an ordinary dword for(iterator it = multiprocessor().begin(TYPE_BUS); it != multiprocessor().end(); it++) { ! if(static_cast<SmpConfigBus*>(*it)->BusID == bus_number) { ! uchar* string = static_cast<SmpConfigBus*>(*it)->TypeString; ! uint hash = 0; ! ! for(uint i=0; i<4; i++) ! { ! hash <<= 8; ! hash += string[i]; ! } ! return hash; } } ! return 0; } ! irq_dev irq_logic::InitializeIOApic(iterator it) { ! // Spawn an new instance of the APIC class for this device uint base_address = static_cast<SmpConfigIOApic*>(*it)->BaseAddr; + + irq_dev* dev = new (heap().AllocateMemory(sizeof(irq_dev))) irq_dev(); io_apic* apic = new (heap().AllocateMemory(sizeof(io_apic))) io_apic(base_address); ! // Populate the APIC's IRQ redirection entries with default values for(uint i=0; i <= apic->GetMaxRedirect(); i++) { bool irq_type = (i > 15) ? true : false; ! apic->SetInterruptType(i, irq_type, irq_type, ioapic_int::lowest); ! apic->SetInterruptReceiver(i, 0xff, 255-32 - i, true); } uint counter = 0; *************** *** 145,221 **** if(!polarity || !edge_level) // Try default values { ! switch(bus_table[irq->SourceID]) { case ISA: polarity = edge_level = false; // High polarity, Edge triggered break; case PCI: polarity = edge_level = true; // Low polarity, Level triggered break; default: ! cout() << "Panic: Unknown bus type (/hal/irg.cpp -> InitializeIOApic)" << endl; while(true); } } ! apic->SetInterruptType(irq->DestIRQ, polarity, edge_level, (ioapic_int::delivery_mode)irq->IntType); ! apic->SetInterruptReceiver(irq->DestIRQ, 0, 0x20 + irq->DestIRQ, false); } counter++; } ! return apic; } void irq_logic::EnableIRQ(uint number) { ! uint current_max = apic_table[0]->GetMaxRedirect(); ! uint apic_number = 0; while(current_max < number) { ! current_max += apic_table[++apic_number]->GetMaxRedirect(); } ! uint irq_number = apic_table[apic_number]->GetMaxRedirect() - (current_max - number); ! apic_table[apic_number]->MaskInterrupt(irq_number, false); } void irq_logic::DisableIRQ(uint number) { ! uint current_max = apic_table[0]->GetMaxRedirect(); ! uint apic_number = 0; while(current_max < number) { ! current_max += apic_table[++apic_number]->GetMaxRedirect(); } ! uint irq_number = apic_table[apic_number]->GetMaxRedirect() - (current_max - number); ! apic_table[apic_number]->MaskInterrupt(irq_number, true); } void irq_logic::InterruptConstructor(hal_object* hal, uchar interrupt_number, uint* esp) { ! if(handler_running) { ! cout() << endl << "Panic: Nested IRQs aren't yet supported (/hal/irq.cpp)" << endl; while(true); } ! ! irq_number = interrupt_number; ! stack_pointer = esp; ! ! handler_running = true; } ! void irq_logic::InterruptDestructor (hal_object* hal, uchar interrupt_number, uint* esp) { ! handler_running = false; ! SignalEOI(); } void irq_logic::DispatchIRQ(hal_object* hal) { ! cout() << (char)ReadPort<BYTE>(0x60); } --- 184,305 ---- if(!polarity || !edge_level) // Try default values { ! switch(DetectSystemBus(irq->SourceID)) { case ISA: + { polarity = edge_level = false; // High polarity, Edge triggered break; + } case PCI: + { polarity = edge_level = true; // Low polarity, Level triggered break; + } default: ! { ! cout() << "Panic: Unknown bus type (/hal/irq.cpp -> InitializeIOApic)" << endl; while(true); + } } } ! apic->SetInterruptType(irq->DestIRQ, polarity, edge_level, ioapic_int::lowest); ! apic->SetInterruptReceiver(irq->DestIRQ, 0xff, 255-32 - irq->DestIRQ, true); } counter++; } ! ! // Store the collected information in a irq_dev class ! dev->legacy_pic = false; ! dev->number_irqs = apic->GetMaxRedirect(); ! dev->device_id = apic->GetApicID(); ! dev->apic = apic; ! ! return *dev; } void irq_logic::EnableIRQ(uint number) { ! uint device_number = 0; ! uint current_max = device_table[device_number].number_irqs; while(current_max < number) { ! current_max += device_table[++device_number].number_irqs; } + uint irq_number = device_table[device_number].number_irqs - (current_max - number); ! if(device_table[device_number].legacy_pic) ! { ! uint irq_mask = ~(1 << irq_number); ! ! WritePort<BYTE>(0x21, ReadPort<BYTE>(0x21) &(irq_mask)); ! WritePort<BYTE>(0xA1, ReadPort<BYTE>(0xA1) &(irq_mask >> 8)); ! } ! else ! { ! device_table[device_number].apic->MaskInterrupt(irq_number, false); ! } } void irq_logic::DisableIRQ(uint number) { ! uint device_number = 0; ! uint current_max = device_table[device_number].number_irqs; while(current_max < number) { ! current_max += device_table[++device_number].number_irqs; } + uint irq_number = device_table[device_number].number_irqs - (current_max - number); ! if(device_table[device_number].legacy_pic) ! { ! uint irq_mask = 1 << irq_number; ! ! WritePort<BYTE>(0x21, ReadPort<BYTE>(0x21) | (irq_mask)); ! WritePort<BYTE>(0xA1, ReadPort<BYTE>(0xA1) | (irq_mask >> 8)); ! } ! else ! { ! device_table[device_number].apic->MaskInterrupt(irq_number, true); ! } ! } ! ! void irq_logic::SignalEOI(uint number) ! { ! if(device_table[0].legacy_pic) ! { ! WritePort<BYTE>(0x20, 0x20); ! WritePort<BYTE>(0xA0, 0x20); ! } } void irq_logic::InterruptConstructor(hal_object* hal, uchar interrupt_number, uint* esp) { ! if(instance != 0) { ! cout() << "Panic: Nested IRQs aren't yet supported" << endl; while(true); } ! instance = reinterpret_cast<irq_data*>(0xFFFFFFFF); } ! void irq_logic::InterruptDestructor(hal_object* hal, uchar interrupt_number, uint* esp) { ! (device_table[0].legacy_pic) ? this->SignalEOI(interrupt_number) : hal->lapic->SignalEOI(); ! instance = reinterpret_cast<irq_data*>(0x00000000); } void irq_logic::DispatchIRQ(hal_object* hal) { ! cout() << (char) ReadPort<BYTE>(0x60); ! } ! ! char irq_logic_reserved[sizeof(irq_logic)]; ! ! irq_logic& irq() ! { ! return (reinterpret_cast<irq_logic&>(irq_logic_reserved)); } Index: exception.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/exception.cpp,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** exception.cpp 13 Apr 2006 20:03:47 -0000 1.7 --- exception.cpp 22 May 2006 15:18:49 -0000 1.8 *************** *** 46,54 **** 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; ! exception::exception() : interrupt() { ! for(uint i=0; i<256; i++) { ! // Install standard handler for all 255 interrupts AddReserved(i, this, (method)&exception::ReservedInterrupt); } --- 46,54 ---- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; ! exception::exception() { ! for(uint i=0; i<0x100; i++) { ! // Install a standard handler for all 256 interrupts AddReserved(i, this, (method)&exception::ReservedInterrupt); } *************** *** 63,105 **** void exception::PrintAllRegisters() { ! cout() << "eax " << GetRegisterValue(register_id(EAX)) << " "; ! cout() << "esi " << GetRegisterValue(register_id(ESI)) << " "; ! cout() << "cs " << GetRegisterValue(register_id(CS )) << endl; ! cout() << "ebx " << GetRegisterValue(register_id(EBX)) << " "; ! cout() << "edi " << GetRegisterValue(register_id(EDI)) << " "; ! cout() << "ss " << GetRegisterValue(register_id(SS )) << endl; ! cout() << "ecx " << GetRegisterValue(register_id(ECX)) << " "; ! cout() << "ebp " << GetRegisterValue(register_id(EBP)) << endl; ! cout() << "edx " << GetRegisterValue(register_id(EDX)) << " "; ! cout() << "esp " << GetRegisterValue(register_id(ESP)) << " "; ! cout() << "eflags " << GetRegisterValue(register_id(EFLAGS)) << endl << endl; ! } ! ! void exception::SetRegisterValue(register_id reg, uint value) ! { ! if(reg > 10 && !error_code) ! reg = register_id(reg + 1); ! ! stack_pointer[reg] = value; ! } ! ! uint exception::GetRegisterValue(register_id reg) ! { ! if(reg > 10 && !error_code) ! reg = register_id(reg + 1); ! ! return stack_pointer[reg]; ! } ! ! void exception::ChangeReturnAddress(ushort selector, uint offset) ! { ! SetRegisterValue(register_id(CS), selector); ! SetRegisterValue(register_id(EIP), offset); ! } ! ! void exception::ChangeStackAddress(ushort selector, uint offset) ! { ! SetRegisterValue(register_id(SS), selector); ! SetRegisterValue(register_id(ESP), offset); } --- 63,77 ---- void exception::PrintAllRegisters() { ! cout() << "eax " << general_regs->eax << " "; ! cout() << "esi " << general_regs->esi << " "; ! cout() << "cs " << segment_regs->cs << endl; ! cout() << "ebx " << general_regs->ebx << " "; ! cout() << "edi " << general_regs->edi << " "; ! cout() << "ss " << segment_regs->ss << endl; ! cout() << "ecx " << general_regs->ecx << " "; ! cout() << "ebp " << general_regs->ebp << endl; ! cout() << "edx " << general_regs->edx << " "; ! cout() << "esp " << segment_regs->esp << " "; ! cout() << "eflags " << segment_regs->eflags << endl << endl; } *************** *** 121,130 **** while(true); } exception_number = interrupt_number; ! error_code = error_code_map[exception_number]; ! stack_pointer = esp; ! handler_running = true; } --- 93,109 ---- while(true); } + handler_running = true; exception_number = interrupt_number; ! error_code = 0; ! general_regs = reinterpret_cast<general_registers*>(&esp[0]); ! segment_regs = reinterpret_cast<segment_registers*>(&esp[8]); ! ! if(error_code_map[exception_number]) ! { ! error_code = esp[8]; ! segment_regs = reinterpret_cast<segment_registers*>(&esp[9]); ! } } *************** *** 140,145 **** PrintAllRegisters(); ! SetRegisterValue(register_id(EDX), 0); ! SetRegisterValue(register_id(EDI), 0x2BADB002); } --- 119,124 ---- PrintAllRegisters(); ! // general_regs->edx = 0; ! // general_regs->edi = 0x2BADB002; } *************** *** 154,158 **** void exception::ReservedInterrupt(hal_object* hal) { ! cout() << endl << "Panic: An unknown exception was reported ("; cout() << exception_number << ")" << endl; --- 133,137 ---- void exception::ReservedInterrupt(hal_object* hal) { ! cout() << endl << "Panic: An unknown exception was reported ("; cout() << exception_number << ")" << endl; Index: apic_io.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/apic_io.hpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** apic_io.hpp 30 Apr 2006 19:21:33 -0000 1.5 --- apic_io.hpp 22 May 2006 15:18:48 -0000 1.6 *************** *** 62,66 **** ExtInt = 7 ! } mode : 3; bool dest_logical : 1; bool pending : 1; --- 62,66 ---- ExtInt = 7 ! } delivery : 3; bool dest_logical : 1; bool pending : 1; Index: apic_local.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/apic_local.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** apic_local.cpp 30 Apr 2006 19:21:33 -0000 1.5 --- apic_local.cpp 22 May 2006 15:18:48 -0000 1.6 *************** *** 39,42 **** --- 39,43 ---- #include "apic_local.hpp" + #include "../loader/heap_manager.hpp" #include "mmu.hpp" *************** *** 50,63 **** local_apic::local_apic() { ! // Check if the processor has a local APIC if(!info().GetProcessorInfo().apic_available) { ! // cout() << "Panic: No local APIC detected" << endl; - only uncomment if exception in main.cpp is disabled while(true); } - // Make sure that its also hardware enabled - info().ModifyLoMSR(0x1B, ~0x800, 0x800); - // Get the local APIC's base address from the MSR uint address = info().ReadLoMSR(0x1B) &0xFFFFF000; --- 51,67 ---- local_apic::local_apic() { ! if(boot_hal->lapic != 0) ! return; ! ! // Make sure that the local APIC is hardware enabled ! info().ModifyLoMSR(0x1B, ~0x800, 0x800); ! ! // Check if it's (now) reported by CPUID if(!info().GetProcessorInfo().apic_available) { ! cout() << "Your system doesn't meet the minimum requirements (local APIC)" << endl; while(true); } // Get the local APIC's base address from the MSR uint address = info().ReadLoMSR(0x1B) &0xFFFFF000; *************** *** 71,77 **** WriteRegister(lapic_reg(DFR), 0xffffffff); SetLogicalID(1 << GetPhysicalID()); } ! uchar local_apic::GetPhysicalID(void) { return (ReadRegister(lapic_reg(ID)) >> 24) &0x0f; --- 75,83 ---- WriteRegister(lapic_reg(DFR), 0xffffffff); SetLogicalID(1 << GetPhysicalID()); + + SetPriority(0x00); } ! uchar local_apic::GetPhysicalID() { return (ReadRegister(lapic_reg(ID)) >> 24) &0x0f; *************** *** 83,92 **** } ! uchar local_apic::GetVersion(void) ! { ! return ReadRegister(lapic_reg(VERSION)) &0xff; ! } ! ! uchar local_apic::GetLogicalID(void) { return ReadRegister(lapic_reg(LDR)) >> 24; --- 89,93 ---- } ! uchar local_apic::GetLogicalID() { return ReadRegister(lapic_reg(LDR)) >> 24; *************** *** 98,140 **** } ! void local_apic::EnableApic(void) ! { ! WriteRegister(lapic_reg(SIVR), ReadRegister(lapic_reg(SIVR)) | 0x00000100); ! } ! ! void local_apic::DisableApic(void) ! { ! WriteRegister(lapic_reg(SIVR), ReadRegister(lapic_reg(SIVR)) & 0xfffffeff); ! } ! ! /* ! void local_apic::SetErrorVector(unsigned char vector) { ! base[REG_LVTERR] = (base[REG_LVTERR] & 0xffffff00) | vector; } ! void local_apic::MaskError(void) { ! base[REG_LVTERR] |= LVT_MASKED; } ! void local_apic::UnmaskError(void) { ! base[REG_LVTERR] &= ~LVT_MASKED; } ! const int local_apic::ErrorPending(void) { ! return(base[REG_LVTERR] & INT_PENDING); } ! const unsigned int local_apic::GetErrorStatus(void) { ! return(base[REG_ESR]); } ! void local_apic::ClearError(void) { ! WriteRegister(lapic_reg(ESR), 0); } - */ --- 99,129 ---- } ! uchar local_apic::GetVersion() { ! return ReadRegister(lapic_reg(VERSION)) &0xff; } ! uchar local_apic::GetMaxLVT() { ! return (ReadRegister(lapic_reg(VERSION)) << 16) &0xff; } ! void local_apic::SetPriority(uchar priority) { ! WriteRegister(lapic_reg(TPR), priority); } ! void local_apic::EnableApic() { ! WriteRegister(lapic_reg(SIVR), ReadRegister(lapic_reg(SIVR)) | 0x00000100); } ! void local_apic::DisableApic() { ! WriteRegister(lapic_reg(SIVR), ReadRegister(lapic_reg(SIVR)) & 0xfffffeff); } ! void local_apic::SignalEOI() { ! WriteRegister(lapic_reg(EOI), 0); } Index: interrupt.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/interrupt.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** interrupt.cpp 7 Apr 2006 17:15:53 -0000 1.2 --- interrupt.cpp 22 May 2006 15:18:49 -0000 1.3 *************** *** 48,52 **** bool interrupt::AddHandler(uint number, bool ignore, interrupt* p_class, method handler, bool error, bool trap) { ! if(number + 1 > boot_hal->int_vec->GetNumberEntries()) return false; --- 48,52 ---- bool interrupt::AddHandler(uint number, bool ignore, interrupt* p_class, method handler, bool error, bool trap) { ! if(number + 1 > boot_hal->vector->GetNumberEntries()) return false; *************** *** 67,74 **** flat flat_destructor = (flat)(p_class->*destructor); ! for(uint i=0; i < boot_hal->int_vec->GetNumberEntries(); i++) { // Seach the IDT for an appropriate interrupt stub ! void* current = boot_hal->int_vec->GetTableEntry(i); if(current != 0) --- 67,74 ---- flat flat_destructor = (flat)(p_class->*destructor); ! for(uint i=0; i < boot_hal->vector->GetNumberEntries(); i++) { // Seach the IDT for an appropriate interrupt stub ! void* current = boot_hal->vector->GetTableEntry(i); if(current != 0) *************** *** 76,80 **** interrupt_stub stub(current); ! if(stub.GetHandlerFunction() == flat_handler && stub.GetHandlerObject() == p_class && stub.GetHalObject() == boot_hal && stub.GetErrorCode() == error) { --- 76,80 ---- interrupt_stub stub(current); ! if(stub.GetHandlerFunction() == flat_handler && stub.GetHandlerObject() == p_class && stub.GetHalObject() == boot_hal && stub.GetErrorCode() == error) { *************** *** 82,86 **** { // Use the already existing interrupt stub (sharing saves memory) ! boot_hal->int_vec->SetTableEntry(number, stub.GetStubAddress(), trap); return true; } --- 82,86 ---- { // Use the already existing interrupt stub (sharing saves memory) ! boot_hal->vector->SetTableEntry(number, stub.GetStubAddress(), trap); return true; } *************** *** 97,101 **** stub->SetErrorCode(error); ! boot_hal->int_vec->SetTableEntry(number, stub->GetStubAddress(), trap); return true; } --- 97,101 ---- stub->SetErrorCode(error); ! boot_hal->vector->SetTableEntry(number, stub->GetStubAddress(), trap); return true; } *************** *** 103,107 **** bool interrupt::RemoveHandler(uint number) { ! boot_hal->int_vec->SetTableEntry(number, 0, false); // Marks entry as unused return true; } --- 103,107 ---- bool interrupt::RemoveHandler(uint number) { ! boot_hal->vector->SetTableEntry(number, 0, false); // Marks entry as unused return true; } *************** *** 118,124 **** while(true); } - - void interrupt::SignalEOI() - { - WriteRegister(lapic_reg(EOI), 0); - } --- 118,119 ---- Index: interrupt.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/interrupt.hpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** interrupt.hpp 7 Apr 2006 17:15:53 -0000 1.2 --- interrupt.hpp 22 May 2006 15:18:49 -0000 1.3 *************** *** 45,49 **** #include "apic_local.hpp" ! class interrupt : local_apic { private: --- 45,49 ---- #include "apic_local.hpp" ! class interrupt : public local_apic { private: *************** *** 56,63 **** virtual bool AddHandler(uint number, bool ignore, interrupt* p_class, method handler, bool error, bool trap); virtual bool RemoveHandler(uint number); - - void SignalEOI(); }; #endif --- 56,78 ---- virtual bool AddHandler(uint number, bool ignore, interrupt* p_class, method handler, bool error, bool trap); virtual bool RemoveHandler(uint number); }; + // [ Interrupt Map ] + // + // 240 to 255 <16>: APIC errors, spurious interrupts, etc + // 224 to 239 <16>: Local vectors (apic timer, thermal sensor, etc) + // 160 to 223 <64>: Harware IRQs + // .... + // 000 to 031 <32>: Exceptions + // + // priority = vector_number/16, numerical higher -> more important + // + // - For interrupts that have the same interrupt-priority level, + // the highest vector number wins + // - Exceptions aren't delivered by the local apic, hardcoded vectors + // don't imply a certain priority + // - Hardware IRQs are mapped upside down (IRQ0 = 255, IRQ1 = 254, etc) + // to enforce the intended priorities + #endif Index: idt.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/idt.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** idt.cpp 5 Apr 2006 17:12:00 -0000 1.3 --- idt.cpp 22 May 2006 15:18:49 -0000 1.4 *************** *** 69,76 **** uchar attributes = (trap_gate) ? 0x6F : 0x6E; ! if(stub != 0) ! { ! attributes |= 0x80; // Set the present flag ! } idt_pointer[interrupt_number*2 + 0] = (reinterpret_cast<uint>(stub) &0x0000FFFF) | (0x08 << 16); --- 69,73 ---- uchar attributes = (trap_gate) ? 0x6F : 0x6E; ! if(stub != 0) attributes |= 0x80; // Set the present flag idt_pointer[interrupt_number*2 + 0] = (reinterpret_cast<uint>(stub) &0x0000FFFF) | (0x08 << 16); Index: apic_local.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/apic_local.hpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** apic_local.hpp 30 Apr 2006 19:21:34 -0000 1.5 --- apic_local.hpp 22 May 2006 15:18:48 -0000 1.6 *************** *** 52,57 **** struct lapic_lvt { ! uchar vector : 8; ! enum { fixed = 0, --- 52,57 ---- struct lapic_lvt { ! uchar vector : 8; ! enum delivery_mode { fixed = 0, *************** *** 61,73 **** ExtInt = 7 ! } delivery_mode : 3; ! bool : 1; ! bool pending : 1; ! bool pin_polarity : 1; ! bool remote_irr : 1; ! bool level : 1; ! bool masked : 1; ! bool periodic : 1; ! uint : 14; }; --- 61,73 ---- ExtInt = 7 ! } delivery : 3; ! bool : 1; ! bool pending : 1; ! bool pin_polarity : 1; ! bool remote_irr : 1; ! bool level : 1; ! bool masked : 1; ! bool periodic : 1; ! uint : 14; }; *************** *** 126,130 **** VERSION = 0x0030/4, /**< Local APIC version */ TPR = 0x0080/4, /**< Task priority register */ ! AOR = 0x0090/4, /**< Arbitration priority register */ PPR = 0x00a0/4, /**< Processor priority register */ --- 126,130 ---- VERSION = 0x0030/4, /**< Local APIC version */ TPR = 0x0080/4, /**< Task priority register */ ! APR = 0x0090/4, /**< Arbitration priority register */ PPR = 0x00a0/4, /**< Processor priority register */ *************** *** 154,161 **** inline void WriteRegister(lapic_reg reg, uint data) { base[reg] = data; } ! inline uint ReadRegister(lapic_reg reg) { return base[reg]; } inline void SetLVT(lapic_reg reg, lapic_lvt lvt) { *(reinterpret_cast<lapic_lvt*>(&base[reg])) = lvt; } ! inline void SetESR(lapic_esr esr) { *(reinterpret_cast<lapic_esr*>(&base[lapic_reg(ESR)])) = esr; } inline void SetICR(lapic_icr icr) { *(reinterpret_cast<lapic_icr*>(&base[lapic_reg(ICR0)])) = icr; } --- 154,161 ---- inline void WriteRegister(lapic_reg reg, uint data) { base[reg] = data; } ! inline uint ReadRegister (lapic_reg reg) { return base[reg]; } inline void SetLVT(lapic_reg reg, lapic_lvt lvt) { *(reinterpret_cast<lapic_lvt*>(&base[reg])) = lvt; } ! inline void SetESR(lapic_esr esr) { *(reinterpret_cast<lapic_esr*>(&base[lapic_reg(ESR)])) = esr; } inline void SetICR(lapic_icr icr) { *(reinterpret_cast<lapic_icr*>(&base[lapic_reg(ICR0)])) = icr; } *************** *** 165,180 **** public: ! local_apic(void); ! uchar GetPhysicalID(void); void SetPhysicalID(uchar id); ! uchar GetLogicalID(void); void SetLogicalID(uchar id); ! uchar GetVersion(void); ! void EnableApic(void); ! void DisableApic(void); }; --- 165,186 ---- public: ! local_apic(); ! uchar GetPhysicalID(); void SetPhysicalID(uchar id); ! uchar GetLogicalID(); void SetLogicalID(uchar id); ! uchar GetVersion(); ! uchar GetMaxLVT(); ! // protected: ! void SetPriority(uchar priority); ! ! void EnableApic(); ! void DisableApic(); ! ! void SignalEOI(); }; Index: mutex.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/mutex.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** mutex.cpp 5 Apr 2006 17:12:00 -0000 1.4 --- mutex.cpp 22 May 2006 15:18:49 -0000 1.5 *************** *** 51,59 **** void mutex::EnterMutex(void) { ! asm volatile ("start: \n" ! "cli \n" "lock btsl $0, %[key] \n" "jnc ready \n" - /*"sti \n"*/ "jmp start \n" "ready:" : : [key] "m" (key)); --- 51,58 ---- void mutex::EnterMutex(void) { ! asm("start: \n" "lock btsl $0, %[key] \n" + "pause \n" // Replace me with a more fancy MONITOR/MWAIT algorithm.. "jnc ready \n" "jmp start \n" "ready:" : : [key] "m" (key)); *************** *** 62,66 **** void mutex::ExitMutex(void) { ! asm volatile ("movl $0, %[key] \n" ! /*"sti"*/ : : [key] "m" (key)); } --- 61,64 ---- void mutex::ExitMutex(void) { ! asm("movl $0, %[key] \n" : : [key] "m" (key)); } Index: mutex.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/mutex.hpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** mutex.hpp 5 Apr 2006 17:12:00 -0000 1.4 --- mutex.hpp 22 May 2006 15:18:49 -0000 1.5 *************** *** 43,55 **** class mutex { ! private: ! volatile unsigned long key; ! public: ! mutex(void); ! ~mutex(void); ! void EnterMutex(void); ! void ExitMutex(void); }; --- 43,55 ---- class mutex { ! private: ! volatile unsigned long key; ! public: ! mutex(void); ! ~mutex(void); ! void EnterMutex(void); ! void ExitMutex(void); }; Index: irq.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/irq.hpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** irq.hpp 13 Apr 2006 20:00:51 -0000 1.5 --- irq.hpp 22 May 2006 15:18:49 -0000 1.6 *************** *** 41,71 **** #define __HAL__IRQ_LOGIC__ - //#include <task.hpp> #include "../object/std_types.hpp" #include "../loader/mp_detect.hpp" #include "interrupt.hpp" #include "apic_io.hpp" ! class irq_logic : public interrupt { ! private: ! // static htask dispatch_table[16][10]; ! uint irq_number; ! uint* stack_pointer; ! bool handler_running; static const uint ISA = 0x49534120; static const uint PCI = 0x50434920; ! io_apic** apic_table; ! void DisableLegacyPIC(); ! uint DetectSystemBuses(uint* bus_table); ! io_apic* InitializeIOApic(iterator it, uint* bus_table); void InterruptConstructor(hal_object* hal, uchar interrupt_number, uint* esp); void InterruptDestructor (hal_object* hal, uchar interrupt_number, uint* esp); public: irq_logic(); --- 41,89 ---- #define __HAL__IRQ_LOGIC__ #include "../object/std_types.hpp" #include "../loader/mp_detect.hpp" #include "interrupt.hpp" #include "apic_io.hpp" + #include "mutex.hpp" ! #include "exception.hpp" // register structures are defined there for the moment.. ! ! struct irq_data { ! segment_registers* segment_regs; ! general_registers* general_regs; ! uint irq_number; ! ! irq_data* next; ! }; + struct irq_dev + { + bool legacy_pic; + uint number_irqs, device_id; + + io_apic* apic; + }; + + class irq_logic : public interrupt, public mutex + { + private: static const uint ISA = 0x49534120; static const uint PCI = 0x50434920; ! irq_data* instance; ! irq_dev* device_table; ! void InitializeLegacyPIC(); ! uint DetectSystemBus(uint bus_number); ! ! irq_dev InitializeIOApic(iterator it); void InterruptConstructor(hal_object* hal, uchar interrupt_number, uint* esp); void InterruptDestructor (hal_object* hal, uchar interrupt_number, uint* esp); + void DispatchIRQ(hal_object* hal); + public: irq_logic(); *************** *** 74,79 **** void DisableIRQ(uint number); ! void DispatchIRQ(hal_object* hal); }; #endif --- 92,100 ---- void DisableIRQ(uint number); ! void SignalEOI (uint number); }; + extern char irq_logic_reserved[]; + irq_logic& irq(); + #endif |
From: Daniel R. <co...@us...> - 2006-05-22 15:18:11
|
Update of /cvsroot/trion/trion v0.2 In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv8397 Modified Files: makefile nucleus.elf Log Message: no message Index: nucleus.elf =================================================================== RCS file: /cvsroot/trion/trion v0.2/nucleus.elf,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 Binary files /tmp/cvsN2vPgb and /tmp/cvsqt9GD2 differ Index: makefile =================================================================== RCS file: /cvsroot/trion/trion v0.2/makefile,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** makefile 30 Apr 2006 19:20:59 -0000 1.12 --- makefile 22 May 2006 15:17:59 -0000 1.13 *************** *** 47,51 **** CFLAGS = -Iinclude -fno-builtin -nostdlib -nostdinc -fno-rtti \ -fno-exceptions -nostartfiles -s -Wno-pmf-conversions ! #-Wall -W -pedantic -O3 -finline -march=pentium3 LDFLAGS = -T ldscript -Map Trion.map --- 47,52 ---- CFLAGS = -Iinclude -fno-builtin -nostdlib -nostdinc -fno-rtti \ -fno-exceptions -nostartfiles -s -Wno-pmf-conversions ! # -Wall -W -pedantic -O3 -finline -march=pentium3 ! LDFLAGS = -T ldscript -Map Trion.map *************** *** 63,66 **** --- 64,68 ---- hal/mutex.cpp \ hal/apic_local.cpp \ + hal/apic_error.cpp \ hal/apic_io.cpp \ hal/timer.cpp \ |
From: Stephen M. W. <bre...@us...> - 2006-05-09 15:37:53
|
Update of /cvsroot/trion/htdocs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3604 Added Files: community.php Log Message: Created a separate community node. --- NEW FILE: community.php --- <?php include('include/header.php'); trionHeader(); ?> <!-- Here comes the actual content --> <div id="content"> <br/> <h1>The Trion Community</h1> <div id="genericlist"> <ul> <li><a href="http://sourceforge.net/projects/trion/">SourceForge</a></li> <li><a href="phpBB2">Forum</a></li> <li>IRC: irc.freenode.net #trion</li> </ul> </div> <?php include('templates/footer.php'); ?> |
From: Stephen M. W. <bre...@us...> - 2006-05-09 15:36:17
|
Update of /cvsroot/trion/htdocs/include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3604/include Modified Files: header.php Log Message: Created a separate community node. Index: header.php =================================================================== RCS file: /cvsroot/trion/htdocs/include/header.php,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** header.php 25 Mar 2006 18:07:42 -0000 1.3 --- header.php 9 May 2006 15:35:16 -0000 1.4 *************** *** 27,35 **** <li><img src="images/blankbar1.png" width="28" height="26" alt="menu"/></li> <li><a href="index.php">Home</a></li> ! <li><a href="construct.php">About</a></li> ! <li><a href="downloads.php">Downloads</a></li> ! <li><a href="construct.php">Forum</a></li> <li><a href="construct.php">Documentation</a></li> ! <li><a href="http://sourceforge.net/projects/trion/">SourceForge</a></li> <li><img src="images/blankbar2.png" width="34" height="26" alt="menu"/></li> </ul> --- 27,34 ---- <li><img src="images/blankbar1.png" width="28" height="26" alt="menu"/></li> <li><a href="index.php">Home</a></li> ! <li><a href="downloads.php">Get Trion</a></li> ! <li><a href="community.php">Community</a></li> <li><a href="construct.php">Documentation</a></li> ! <li><a href="construct.php">About</a></li> <li><img src="images/blankbar2.png" width="34" height="26" alt="menu"/></li> </ul> |
From: Stephen M. W. <bre...@us...> - 2006-05-08 17:05:50
|
Update of /cvsroot/trion/htdocs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30917 Modified Files: downloads.php Log Message: Made current v0.2 design document available for download. Index: downloads.php =================================================================== RCS file: /cvsroot/trion/htdocs/downloads.php,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** downloads.php 13 Jan 2006 18:21:06 -0000 1.2 --- downloads.php 8 May 2006 14:44:28 -0000 1.3 *************** *** 16,20 **** <td class="data">Kernel Architecture</td> <td class="data">This document contains a schema showing the kernel architecture.</td> ! <td class="data"><a href="downloads/arch.pdf">Download</a></td> </tr> <tr> --- 16,20 ---- <td class="data">Kernel Architecture</td> <td class="data">This document contains a schema showing the kernel architecture.</td> ! <td class="data"><a href="http://cvs.sourceforge.net/viewcvs.py/trion/docs/trion%20design%20draft.pdf?rev=1.1&view=auto">Download</a></td> </tr> <tr> |