- add code to detect pci interfaces

- code restructuring
- remove some typos in debug messages



git-svn-id: http://svn.lfbs.rwth-aachen.de/svn/scc/trunk/MetalSVM@42 315a16e6-25f9-4109-90ae-ca3045a26c18
This commit is contained in:
stefan 2010-08-05 11:53:02 +00:00
parent 5d139a1519
commit 7294c47c98
16 changed files with 2108 additions and 48 deletions

View file

@ -26,7 +26,7 @@
extern "C" {
#endif
#ifdef USE_KEYBOARD
#ifdef CONFIG_KEYBOARD
void keyboard_init(void);
#endif

View file

@ -21,7 +21,7 @@
#include <metalsvm/stddef.h>
#ifdef USE_MULTIBOOT
#ifdef CONFIG_MULTIBOOT
/*
* MetalSVM is able to use Multiboot (http://www.gnu.org/software/grub/manual/multiboot/),

View file

@ -0,0 +1,34 @@
/*
* Copyright 2010 Stefan Lankes, Chair for Operating Systems,
* RWTH Aachen University
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of MetalSVM.
*/
#ifndef __ARCH_PCI_H__
#define __ARCH_PCI_H__
#ifdef __cplusplus
extern "C" {
#endif
int pci_init(void);
int print_pci_adapters(void);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -20,6 +20,11 @@
#ifndef __ARCH_PROCESSOR_H__
#define __ARCH_PROCESSOR_H__
#include <metalsvm/stddef.h>
#ifdef CONFIG_PCI
#include <asm/pci.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -40,7 +45,14 @@ static inline uint64_t rdtsc()
void gdt_install(void);
#define system_init gdt_install
inline static int system_init(void)
{
gdt_install();
#ifdef CONFIG_PCI
pci_init();
#endif
return 0;
}
#ifdef __cplusplus
}

View file

@ -26,7 +26,7 @@
extern "C" {
#endif
#ifdef USE_VGA
#ifdef CONFIG_VGA
void vga_init(void);
int vga_puts(const char *text);

View file

@ -1,4 +1,4 @@
C_source = gdt.c idt.c isrs.c irq.c vga.c kb.c timer.c multiboot.c
C_source = gdt.c idt.c isrs.c irq.c vga.c kb.c timer.c multiboot.c pci.c
ASM_source = schedule.asm
OBJS += $(patsubst %.c, %.o, $(filter %.c, $(C_source)))

View file

@ -22,7 +22,7 @@
#include <asm/kb.h>
#include <asm/irq.h>
#ifdef USE_KEYBOARD
#ifdef CONFIG_KEYBOARD
/*
* KBDUS means US Keyboard Layout. This is a scancode table

View file

@ -19,8 +19,7 @@
#include <metalsvm/stddef.h>
#ifdef USE_MULTIBOOT
#ifdef CONFIG_MULTIBOOT
#include <asm/multiboot.h>
/*
@ -29,10 +28,11 @@
*/
multiboot_info_t* mb_info = NULL;
#endif
void multiboot_init(void* mb)
{
#ifdef CONFIG_MULTIBOOT
mb_info = (multiboot_info_t*) mb;
}
#endif
}

165
arch/x86/kernel/pci.c Normal file
View file

@ -0,0 +1,165 @@
/*
* Copyright 2010 Stefan Lankes, Chair for Operating Systems,
* RWTH Aachen University
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of MetalSVM.
*/
#include <metalsvm/stdio.h>
#include <metalsvm/string.h>
#include <asm/irqflags.h>
#include <asm/io.h>
#ifdef CONFIG_PCI
#include <asm/pci.h>
#include "pcihdr.h"
/*
* PCI configuration registers
*/
#define PCI_CFID 0x00 /* Configuration ID */
#define PCI_CFCS 0x04 /* Configurtion Command/Status */
#define PCI_CFRV 0x08 /* Configuration Revision */
#define PCI_CFLT 0x0c /* Configuration Latency Timer */
#define PCI_CBIO 0x10 /* Configuration Base IO Address */
#define PCI_CBMA 0x14 /* Configuration Base Memory Address */
#define PCI_CFIT 0x3c /* Configuration Interrupt */
#define PCI_CFDA 0x40 /* Configuration Driver Area */
#define PHYS_IO_MEM_START 0
#define PCI_MEM 0
#define PCI_INTA 0
#define PCI_NSLOTS 22
#define PCI_NBUS 0
#define PCI_CONF_ADDR_REG 0xcf8
#define PCI_CONF_FRWD_REG 0xcf8
#define PCI_CONF_DATA_REG 0xcfc
#define PCI_IO_CONF_START 0xc000
#define MAX_BUS 16
#define MAX_SLOTS 32
static int mechanism = 0;
static int initialized = 0;
static int adapters[MAX_BUS][MAX_SLOTS];
static void pci_conf_write(int bus, int slot, int off, int val)
{
if (mechanism == 1) {
outportl(PCI_CONF_FRWD_REG, bus);
outportl(PCI_CONF_ADDR_REG, 0xf0);
outportl(PCI_IO_CONF_START | (slot << 8) | off, val);
} else {
outportl(PCI_CONF_ADDR_REG,
(0x80000000 | (bus << 16) | (slot << 11) | off));
outportl(PCI_CONF_DATA_REG, val);
}
}
static int pci_conf_read(int bus, int slot, int off)
{
unsigned int data = -1;
outportl(PCI_CONF_ADDR_REG,
(0x80000000 | (bus << 16) | (slot << 11) | off));
data = inportl(PCI_CONF_DATA_REG);
if ((data == 0xffffffff) && (slot < 0x10)) {
outportl(PCI_CONF_FRWD_REG, bus);
outportl(PCI_CONF_ADDR_REG, 0xf0);
data = inportl(PCI_IO_CONF_START | (slot << 8) | off);
if (data == 0xffffffff)
return (data);
if (!mechanism)
mechanism = 1;
} else if (!mechanism)
mechanism = 2;
return (data);
}
static int pci_what_irq(int bus, int slot, int intx)
{
return pci_conf_read(bus, slot, PCI_CFIT) & 0xff;
}
static int find_pci_adapters(void)
{
int slot, bus;
if (initialized)
return 0;
initialized = 1;
for (bus = 0; bus < MAX_BUS; bus++)
for (slot = 0; slot < MAX_SLOTS; slot++)
adapters[bus][slot] = pci_conf_read(bus, slot, PCI_CFID);
return 0;
}
int pci_init(void)
{
memset(adapters, -1, MAX_BUS*MAX_SLOTS*sizeof(int));
return find_pci_adapters();
}
int print_pci_adapters(void)
{
int slot, bus;
int i, counter = 0;
if (!initialized)
return -1;
for (bus = 0; bus < MAX_BUS; bus++) {
for (slot = 0; slot < MAX_SLOTS; slot++) {
if (adapters[bus][slot] != -1) {
counter++;
kprintf("%d) Vendor ID: 0x%x Device Id: 0x%x\n",
counter, adapters[bus][slot] & 0xffff,
(adapters[bus][slot] & 0xffff0000) >> 16);
for (i = 0; i < PCI_VENTABLE_LEN; i++) {
if ((adapters[bus][slot] & 0xffff) ==
(int)PciVenTable[i].VenId)
kprintf("\tVendor is %s\n",
PciVenTable[i].VenShort);
}
for (i = 0; i < PCI_DEVTABLE_LEN; i++) {
if ((adapters[bus][slot] & 0xffff) ==
(int)PciDevTable[i].VenId) {
if (((adapters[bus][slot] & 0xffff0000) >> 16) ==
PciDevTable[i].DevId) {
kprintf
("\tChip: %s ChipDesc: %s\n",
PciDevTable[i].Chip,
PciDevTable[i].ChipDesc);
}
}
}
}
}
}
return 0;
}
#endif

1837
arch/x86/kernel/pcihdr.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -24,6 +24,7 @@
#include <metalsvm/processor.h>
#include <asm/irq.h>
#include <asm/irqflags.h>
#include <asm/vga.h>
/*
* This will keep track of how many ticks that the system
@ -41,7 +42,7 @@ void schedule_entry(void);
*/
static void timer_handler(struct regs *r)
{
//unsigned int tmp;
/*unsigned int tmp;*/
/* Increment our 'tick counter' */
timer_ticks++;
@ -52,7 +53,7 @@ static void timer_handler(struct regs *r)
*/
/*tmp = (unsigned int) (timer_ticks & 0xFFFFFFFF);
if (tmp % TIMER_FREQ == 0) {
kputs("One second has passed\n");
vga_puts("One second has passed\n");
}*/
if (current_task && !(current_task->ip)) {

View file

@ -20,7 +20,7 @@
#include <metalsvm/string.h>
#include <asm/vga.h>
#ifdef USE_VGA
#ifdef CONFIG_VGA
/*
* These define our textpointer, our background and foreground

View file

@ -42,14 +42,11 @@ extern "C" {
*/
#define BITMAP_SIZE 1048576
#define USE_LWIP
//#undef USE_LWIP
#define USE_VGA
//#undef USE_VGA
#define USE_KEYBOARD
//#undef USE_KEYBOARD
#define USE_MULTIBOOT
//#undef USE_MULTIBOOT
//#define CONFIG_PCI
#define CONFIG_LWIP
#define CONFIG_VGA
#define CONFIG_KEYBOARD
#define CONFIG_MULTIBOOT
#define BUILTIN_EXPECT(exp, b) __builtin_expect((exp), (b))
//#define BUILTIN_EXPECT(exp, b) (exp)

View file

@ -27,7 +27,10 @@
#include <metalsvm/mailbox.h>
#include <asm/irq.h>
#include <asm/kb.h>
#ifdef USE_LWIP
#ifdef CONFIG_PCI
#include <asm/pci.h>
#endif
#ifdef CONFIG_LWIP
#include <lwip/sys.h>
#include <lwip/stats.h>
#include <lwip/udp.h>
@ -42,6 +45,9 @@ static sem_t consuming, producing;
static mailbox_t mbox;
static int val = 0;
extern const void kernel_start;
extern const void kernel_end;
void* STDCALL consumer(void* arg)
{
int i;
@ -116,7 +122,7 @@ void* STDCALL join_test(void* arg)
return NULL;
}
#ifdef USE_LWIP
#ifdef CONFIG_LWIP
void* STDCALL lwip_task(void* arg)
{
struct netif netif;
@ -166,7 +172,7 @@ void* STDCALL lwip_task(void* arg)
int main(void)
{
tid_t id1, id2, id3;
#ifdef USE_LWIP
#ifdef CONFIG_LWIP
tid_t lwip_id;
#endif
@ -174,7 +180,7 @@ int main(void)
irq_init();
koutput_init();
timer_init();
#ifdef USE_KEYBOARD
#ifdef CONFIG_KEYBOARD
keyboard_init();
#endif
mmu_init();
@ -183,12 +189,16 @@ int main(void)
irq_enable();
kprintf("Here is MetalSVM %s\n", METALSVM_VERSION);
kprintf("Kernel starts at %p and ends at %p\n", &kernel_start, &kernel_end);
detect_cpu_frequency();
kprintf("Processor frequency: %d MHz\n", get_cpu_frequency()/1000000);
kprintf("Total memory: %u MBytes\n", atomic_size_read(&total_memory)/(1024*1024));
kprintf("Current allocated memory: %u KBytes\n", atomic_size_read(&total_allocated_memory)/1024);
kprintf("Current available memory: %u MBytes\n", atomic_size_read(&total_available_memory)/(1024*1024));
#ifdef CONFIG_PCI
print_pci_adapters();
#endif
timer_set_frequency(TIMER_FREQ);
@ -196,8 +206,10 @@ int main(void)
sem_init(&consuming, 0);
mailbox_init(&mbox);
#ifdef USE_LWIP
create_kernel_task(&lwip_id, lwip_task, NULL, 0);
sleep(5);
#ifdef CONFIG_LWIP
//create_kernel_task(&lwip_id, lwip_task, NULL, 0);
#endif
create_kernel_task(&id1, foo, "Hello from foo1\n", 8192);

View file

@ -21,7 +21,7 @@
#include <metalsvm/string.h>
#include <metalsvm/stdarg.h>
#include <metalsvm/spinlocks.h>
#ifdef USE_VGA
#ifdef CONFIG_VGA
#include <asm/vga.h>
#endif
@ -31,7 +31,7 @@ static spinlock_t kio_lock = SPINLOCK_INIT;
int koutput_init(void)
{
#ifdef USE_VGA
#ifdef CONFIG_VGA
vga_init();
#endif
memset(kmessages, 0, sizeof(unsigned char)*KMSG_SIZE);
@ -45,7 +45,7 @@ int kputchar(int c)
spinlock_lock(&kio_lock);
kmessages[kmsg_counter++ % KMSG_SIZE] = c;
#ifdef USE_VGA
#ifdef CONFIG_VGA
ret = vga_putchar(c);
#endif
spinlock_unlock(&kio_lock);
@ -60,7 +60,7 @@ int kputs(const char *str)
spinlock_lock(&kio_lock);
for(i=0; str[i] != '\0'; i++)
kmessages[kmsg_counter++ % KMSG_SIZE] = str[i];
#ifdef USE_VGA
#ifdef CONFIG_VGA
i = vga_puts(str);
#endif
spinlock_unlock(&kio_lock);

View file

@ -22,7 +22,7 @@
#include <metalsvm/mmu.h>
#include <metalsvm/spinlocks.h>
#include <metalsvm/time.h>
#ifdef USE_MULTIBOOT
#ifdef CONFIG_MULTIBOOT
#include <asm/multiboot.h>
#endif
@ -40,7 +40,7 @@ atomic_size_t total_available_memory = 0;
extern const void kernel_start;
extern const void kernel_end;
inline static int page_used(unsigned int i)
inline static int page_marked(unsigned int i)
{
unsigned int index = i / 8;
unsigned int mod = i % 8;
@ -48,25 +48,28 @@ inline static int page_used(unsigned int i)
return (bitmap[index] & (1 << mod));
}
inline static int page_unused(unsigned int i)
inline static int page_unmarked(unsigned int i)
{
return !page_used(i);
return !page_marked(i);
}
inline static void page_marked(unsigned int i)
inline static void page_set_mark(unsigned int i)
{
unsigned int index = i / 8;
unsigned int mod = i % 8;
//if (page_marked(i))
// kprintf("page %u is alread marked\n", i);
bitmap[index] = bitmap[index] | (1 << mod);
}
inline static void page_unmarked(unsigned int i)
inline static void page_clear_mark(unsigned int i)
{
unsigned int index = i / 8;
unsigned int mod = i % 8;
if (page_unused(i))
if (page_unmarked(i))
kprintf("page %u is already unmarked\n", i);
bitmap[index] = bitmap[index] & ~(1 << mod);
@ -80,7 +83,7 @@ int mmu_init(void)
/* set whole address space as occupied */
memset(bitmap, 0xFF, sizeof(uint8_t)*BITMAP_SIZE);
#ifdef USE_MULTIBOOT
#ifdef CONFIG_MULTIBOOT
if (mb_info && (mb_info->flags & (1 << (6)))) {
multiboot_memory_map_t* mmap = (multiboot_memory_map_t*) mb_info->mmap_addr;
multiboot_memory_map_t* mmap_end = (void*) ((size_t) mb_info->mmap_addr + mb_info->mmap_length);
@ -92,7 +95,7 @@ int mmu_init(void)
size_t end_addr = addr + mmap->len;
while (addr < end_addr) {
page_unmarked(addr / PAGE_SIZE);
page_clear_mark(addr / PAGE_SIZE);
addr += PAGE_SIZE;
atomic_size_add(&total_memory, PAGE_SIZE);
atomic_size_add(&total_available_memory, PAGE_SIZE);
@ -102,8 +105,7 @@ int mmu_init(void)
}
} else {
kputs("Unable to initialize the memory management subsystem\n");
sleep(5);
return -1;
while(1) ;
}
#else
#error Currently, MetalSVM needs multiboot!
@ -116,7 +118,7 @@ int mmu_init(void)
/* set kernel space as used */
for(i=(size_t) &kernel_start / PAGE_SIZE; i < (size_t) &kernel_end / PAGE_SIZE; i++)
page_marked(i);
page_set_mark(i);
alloc_start = (unsigned int) (&kernel_end) / PAGE_SIZE + 1;
@ -140,7 +142,7 @@ static void* task_malloc(task_t* task, size_t sz)
spinlock_lock(&bitmap_lock);
i = alloc_start;
next_try:
while((k < BITMAP_SIZE) && page_used(i)) {
while((k < BITMAP_SIZE) && page_marked(i)) {
k++;
i = (i+1) % BITMAP_SIZE;
}
@ -149,7 +151,7 @@ next_try:
goto oom;
for(j=1; (j<npages) && (i+j < BITMAP_SIZE) && (k < BITMAP_SIZE); j++, k++) {
if (page_used(i+j)) {
if (page_marked(i+j)) {
i = (i+j) % BITMAP_SIZE;
goto next_try;
}
@ -164,11 +166,11 @@ next_try:
goto oom;
ret = (unsigned char*) (i*PAGE_SIZE);
kprintf("alloc: ret %p, i = %d, j = %di, npages = %d\n", ret, i, j, npages);
kprintf("alloc: ret %p, i = %d, j = %d, npages = %d\n", ret, i, j, npages);
for(l=i; l<i+j; l++)
page_marked(l);
page_set_mark(l);
alloc_start = i+j-1;
alloc_start = i+j;
atomic_size_add(&total_allocated_memory, npages*PAGE_SIZE);
atomic_size_sub(&total_available_memory, npages*PAGE_SIZE);
if (task)