1 /* $Id: baget.c,v 1.1 1999/01/17 03:49:37 ralf Exp $
3 * baget.c: Baget low level stuff
5 * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
10 #include <linux/kernel.h>
12 #include <asm/system.h>
13 #include <asm/bootinfo.h>
14 #include <asm/mipsregs.h>
15 #include <asm/pgtable.h>
16 #include <asm/pgalloc.h>
18 #include <asm/baget/baget.h>
21 * Following code is based on routines from 'mm/vmalloc.c'
22 * Additional parameters ioaddr is needed to iterate across real I/O address.
24 static inline int alloc_area_pte(pte_t
* pte
, unsigned long address
,
25 unsigned long size
, unsigned long ioaddr
)
33 while (address
< end
) {
36 printk("kseg2_alloc_io: page already exists\n");
38 * For MIPS looks pretty to have transparent mapping
39 * for KSEG2 areas -- user can't access one, and no
40 * problems with virtual <--> physical translation.
42 page
= ioaddr
& PAGE_MASK
;
44 set_pte(pte
, __pte(page
| pgprot_val(PAGE_USERIO
) |
45 _PAGE_GLOBAL
| __READABLE
| __WRITEABLE
));
53 static inline int alloc_area_pmd(pmd_t
* pmd
, unsigned long address
,
54 unsigned long size
, unsigned long ioaddr
)
58 address
&= ~PGDIR_MASK
;
62 while (address
< end
) {
63 pte_t
* pte
= pte_alloc_kernel(pmd
, address
);
66 if (alloc_area_pte(pte
, address
, end
- address
, ioaddr
))
68 address
= (address
+ PMD_SIZE
) & PMD_MASK
;
75 int kseg2_alloc_io (unsigned long address
, unsigned long size
)
78 unsigned long end
= address
+ size
;
80 dir
= pgd_offset_k(address
);
82 while (address
< end
) {
86 pmd
= pmd_alloc_kernel(dir
, address
);
89 if (alloc_area_pmd(pmd
, address
, end
- address
, address
))
91 if (pgd_val(olddir
) != pgd_val(*dir
))
92 set_pgdir(address
, *dir
);
93 address
= (address
+ PGDIR_SIZE
) & PGDIR_MASK
;