summaryrefslogtreecommitdiff
path: root/roms/SLOF/clients/net-snk/kernel/init.c
blob: 1c78adc022813e99923309fe553c8f34e4d4e6c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/******************************************************************************
 * Copyright (c) 2004, 2008 IBM Corporation
 * All rights reserved.
 * This program and the accompanying materials
 * are made available under the terms of the BSD License
 * which accompanies this distribution, and is available at
 * http://www.opensource.org/licenses/bsd-license.php
 *
 * Contributors:
 *     IBM Corporation - initial implementation
 *****************************************************************************/

#include <stdint.h>
#include <string.h>
#include <stdlib.h> /* malloc */
#include <of.h>
#include <pci.h>
#include <kernel.h>
#include <cpu.h>
#include <fileio.h>
#include <ioctl.h> /* ioctl */
#include "modules.h"

/* Application entry point .*/
extern int _start(unsigned char *arg_string, long len);
extern int main(int, char**);
int _start_kernel(unsigned long p0, unsigned long p1);
void * malloc_aligned(size_t size, int align);

unsigned long exception_stack_frame;

snk_fileio_t fd_array[FILEIO_MAX];

extern uint64_t tb_freq;

int glue_init(snk_kernel_t *, unsigned int *, size_t, size_t);
void glue_release(void);

static char save_vector[0x4000];
extern char _lowmem_start;
extern char _lowmem_end;
extern char __client_start;
extern char __client_end;

snk_kernel_t snk_kernel_interface = {
	.version          = 1,
	.print            = printk,
	.us_delay         = udelay,
	.ms_delay         = mdelay,
	.k_malloc         = malloc,
	.k_malloc_aligned = malloc_aligned,
	.k_free           = free,
	.strcmp           = strcmp,
	.snk_call         = main,
	.k_open           = open,
	.k_close          = close,
	.k_read           = read,
	.k_write          = write,
	.k_ioctl          = ioctl,
	.modules_remove   = rmmod_by_type,
	.modules_load     = insmod_by_type,
};

void *
malloc_aligned(size_t size, int align)
{
	unsigned long p = (unsigned long) malloc(size + align - 1);
	p = p + align - 1;
	p = p & ~(align - 1);

	return (void *) p;
}

static void
copy_exception_vectors(void)
{
	char *dest;
	char *src;
	int len;

	dest = save_vector;
	src = (char *) 0x200;
	len = &_lowmem_end - &_lowmem_start;
	memcpy(dest, src, len);

	dest = (char *) 0x200;
	src = &_lowmem_start;
	memcpy(dest, src, len);
	flush_cache(dest, len);
}

static void
restore_exception_vectors(void)
{
	char *dest;
	char *src;
	int len;

	dest = (char *) 0x200;
	src = save_vector;
	len = &_lowmem_end - &_lowmem_start;
	memcpy(dest, src, len);
	flush_cache(dest, len);
}

int
_start_kernel(unsigned long p0, unsigned long p1)
{
	int rc;
	unsigned int timebase;

	/* initialize all file descriptor by marking them as empty */
	for(rc=0; rc<FILEIO_MAX; ++rc) {
		fd_array[rc].type = FILEIO_TYPE_EMPTY;
		fd_array[rc].idx  = rc;
	}

	/* this is step is e.g. resposible to initialize file descriptor 0 and 1 for STDIO */
	rc = glue_init(&snk_kernel_interface, &timebase, (size_t)(unsigned long)&__client_start,
	               (size_t)(unsigned long)&__client_end - (size_t)(unsigned long)&__client_start);
	if(rc < 0)
		return -1;

	tb_freq = (uint64_t) timebase;
	copy_exception_vectors();
	modules_init();
	rc = _start((unsigned char *) p0, p1);
	modules_term();
	restore_exception_vectors();

	glue_release();
	return rc;
}


void
exception_forward(void)
{
	restore_exception_vectors();
	undo_exception();
}